summaryrefslogtreecommitdiffstats
path: root/src/windows/lib/gic.c
blob: fe586c6fceff21abb116bd692b4b6fc6e48d08c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
 * Copyright (C) 1997 Cygnus Solutions.
 *
 * Author:  Michael Graff
 */

#include <windows.h>
#include <windowsx.h>

#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "krb5.h"

#include "vardlg.h"
#include "gic.h"

/*
 * Steps performed:
 *
 *   1)  Create the dialog with all the windows we will need
 *	 later.  This is done by calling vardlg_build() from
 *	 gic_prompter().
 *
 *   2)  Run the dialog from within gic_prompter().  If the return
 *	 value of the dialog is -1 or IDCANCEL, return an error.
 *	 Otherwise, return success.
 *
 *   3)  From within the dialog initialization code, call
 *	 vardlg_config(), which will:
 *
 *	a)  Set all the label strings in all the entry labels and
 *	    the banner.
 *
 *	b)  Set the maximum input lengths on the entry fields.
 *
 *	c)  Calculate the size of the text used within the banner.
 *
 *	d)  Calculate the longest string of text used as a label.
 *
 *	e)  Resize each label and each entry within the dialog
 *	    to "look nice."
 *
 *	f)  Place the OK and perhaps the Cancel buttons at the bottom
 *	    of the dialog.
 *
 *   4)  When the OK button is clicked, copy all the values from the
 *	 input fields and store them in the pointers we are given.
 *	 Also, set the actual lengths to what we collected from the
 *	 entries.  Finally, call EndDialog(IDOK) to end the dialog.
 */

/*
 * Yes, a global.  It is a PITA to not use them in windows.
 */
gic_data *gd;


/*
 * initialize the dialog
 */
static BOOL
gic_dialog_init(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
	vardlg_config(hwnd, gd->width, gd->banner, gd->num_prompts,
		gd->prompts, (WORD)(gd->id));

	return FALSE;
}

/*
 * process dialog "commands"
 */
static void
gic_dialog_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
{

	int n;
	WORD id;

	/*
	 * We are only interested in button clicks, and then only of
	 * type IDOK or IDCANCEL.
	 */
	if (codeNotify != BN_CLICKED)
		return;
	if (cid != IDOK && cid != IDCANCEL)
		return;

	/*
	 * If we are canceled, wipe all the fields and return IDCANCEL.
	 */
	if (cid == IDCANCEL) {
		EndDialog(hwnd, IDCANCEL);
		return;
	}

	/*
	 * must be IDOK...
	 */
	id = (gd->id + 2);
	for (n = 0 ; n < gd->num_prompts ; n++) {
		Edit_GetText(GetDlgItem(hwnd, id), gd->prompts[n].reply->data,
			gd->prompts[n].reply->length);
		gd->prompts[n].reply->length = (unsigned)strlen(gd->prompts[n].reply->data);
		id += 2;
	}

	EndDialog(hwnd, IDOK);
}

/*
 * The dialog callback.
 */
static INT_PTR CALLBACK
gic_dialog(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) {
		HANDLE_MSG(hwnd, WM_INITDIALOG, gic_dialog_init);

		HANDLE_MSG(hwnd, WM_COMMAND, gic_dialog_command);
	}

	return FALSE;
}


/*
 * All the disgusting code to use the get_init_creds() functions in a
 * broken environment
 */
krb5_error_code KRB5_CALLCONV
gic_prompter(krb5_context ctx, void *data, const char *name,
	     const char *banner, int num_prompts, krb5_prompt prompts[])
{
	int       rc;
	void     *dlg;

	gd = data;

	gd->banner = banner;
	gd->num_prompts = num_prompts;
	gd->prompts = prompts;
	if (gd->width == 0)
		gd->width = 450;

	dlg = vardlg_build((WORD)(gd->width), name, gd->banner,
			   (WORD)num_prompts, prompts, (WORD)(gd->id));

	rc = DialogBoxIndirect(gd->hinstance, (LPDLGTEMPLATE)dlg, gd->hwnd, gic_dialog);

	if (rc != IDOK)
		return 1;

	return 0;
}