#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "krb5.h"
#include "vardlg.h"
static unsigned char dlg[DLG_BUF];
static int
ADD_WORD(unsigned char *p, WORD w)
{
*((WORD *)p) = w;
return 2;
}
static int
ADD_DWORD(unsigned char *p, DWORD dw)
{
*((DWORD *)p) = dw;
return 4;
}
static int
ADD_UNICODE_STRING(unsigned char *p, const char *s)
{
WORD *w;
int i;
int len;
w = (WORD *)p;
len = strlen(s) + 1;
for (i = 0 ; i < len ; i++)
*w++ = *s++;
return (len * 2);
}
#define DWORD_ALIGN(p) { while ((DWORD)p % 4) *p++ = 0x00; }
static int
ADD_DLGTEMPLATE(unsigned char *dlg, short x, short y, short cx, short cy,
const char *caption, const char *fontname, WORD fontsize,
WORD n)
{
unsigned char *p;
DLGTEMPLATE dlt;
p = dlg;
dlt.style = (DS_MODALFRAME | WS_POPUP);
if (caption != NULL)
dlt.style |= WS_CAPTION;
if (fontname != NULL)
dlt.style |= DS_SETFONT;
dlt.dwExtendedStyle = 0;
dlt.cdit = n;
dlt.x = x;
dlt.y = y;
dlt.cx = cx;
dlt.cy = cy;
memcpy(p, &dlt, sizeof(dlt));
p += sizeof(dlt);
p += ADD_WORD(p, 0x0000);
p += ADD_WORD(p, 0x0000);
if (caption != NULL)
p += ADD_UNICODE_STRING(p, caption);
else
p += ADD_WORD(p, 0x0000);
if (fontname != NULL) {
p += ADD_WORD(p, fontsize);
p += ADD_UNICODE_STRING(p, fontname);
}
DWORD_ALIGN(p);
return (p - dlg);
}
static int
ADD_DLGITEM(unsigned char *dlg, short x, short y, short cx, short cy,
const char *label, WORD id, WORD type, DWORD style)
{
unsigned char *p;
DLGITEMTEMPLATE dit;
p = dlg;
dit.style = style;
dit.dwExtendedStyle = 0;
dit.x = x;
dit.y = y;
dit.cx = cx;
dit.cy = cy;
dit.id = id;
memcpy(p, &dit, sizeof(dit));
p += sizeof(dit);
p += ADD_WORD(p, 0xffff);
p += ADD_WORD(p, type);
p += ADD_UNICODE_STRING(p, label);
p += ADD_WORD(p, 0x0000);
DWORD_ALIGN(p);
return (p - dlg);
}
#define ADD_DLGITEM_defpushbutton(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010001);
#define ADD_DLGITEM_pushbutton(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0080, 0x50010000);
#define ADD_DLGITEM_left_static(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020000);
#define ADD_DLGITEM_centered_static(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020001);
#define ADD_DLGITEM_right_static(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0082, 0x50020002);
#define ADD_DLGITEM_entry(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x50810080);
#define ADD_DLGITEM_hidden_entry(a, b, c, d, e, f, g) \
ADD_DLGITEM((a), (b), (c), (d), (e), (f), (g), 0x0081, 0x508100a0);
void *
vardlg_build(WORD cx, const char *name, const char *banner,
WORD n, krb5_prompt prompts[], WORD id)
{
unsigned char *p;
WORD i;
p = dlg;
if (cx < MIN_WIDTH)
cx = MIN_WIDTH;
if (cx > MAX_WIDTH)
cx = MAX_WIDTH;
p += ADD_DLGTEMPLATE(p, 0, 0, cx, 0, name ?
strlen(name) < 30 ? name : "Kerberos V5" :
"Kerberos V5",
"MS Sans Serif", 8,
(WORD)(n * 2 + 3));
p += ADD_DLGITEM_left_static(p, 0, 0, 0, 0, "", id++);
for (i = 0 ; i < n ; i++) {
p += ADD_DLGITEM_right_static(p, 0, 0, 0, 0, "", id++);
if (prompts[i].hidden) {
p += ADD_DLGITEM_hidden_entry(p, 0, 0, 0, 0, "", id++);
} else {
p += ADD_DLGITEM_entry(p, 0, 0, 0, 0, "", id++);
}
}
p += ADD_DLGITEM_defpushbutton(p, 0, 0, 0, 0,
"OK", IDOK);
if (n != 0)
p += ADD_DLGITEM_pushbutton(p, 0, 0, 0, 0,
"Cancel", IDCANCEL);
return dlg;
}
#define SPACE_Y 4
#define SPACE_X 4
#define ENTRY_PX 120
#define BUTTON_PX 70
#define BUTTON_PY 30
void
vardlg_config(HWND hwnd, WORD width, const char *banner, WORD num_prompts,
krb5_prompt *prompts, WORD id)
{
int n;
WORD cid;
HDC hdc;
SIZE csize;
SIZE maxsize;
LONG cx, cy;
LONG ccx, ccy;
LONG space_x, space_y;
LONG max_x, max_y;
LONG banner_y;
RECT rect;
int done;
const char *p;
Static_SetText(GetDlgItem(hwnd, id), banner);
cid = (id + 1);
for (n = 0 ; n < num_prompts ; n++) {
Static_SetText(GetDlgItem(hwnd, cid), prompts[n].prompt);
cid++;
Edit_SetText(GetDlgItem(hwnd, cid), "");
Edit_LimitText(GetDlgItem(hwnd, cid), prompts[n].reply->length);
cid++;
}
maxsize.cx = maxsize.cy = 0;
cid = (id + 1);
hdc = GetDC(GetDlgItem(hwnd, cid));
for (n = 0 ; n < num_prompts ; n++) {
GetTextExtentPoint32(hdc, prompts[n].prompt, strlen(prompts[n].prompt), &csize);
if (csize.cx > maxsize.cx)
maxsize.cx = csize.cx;
if (csize.cy > maxsize.cy)
maxsize.cy = csize.cy;
}
#if 0
rect.left = 0;
rect.top = 0;
rect.right = maxsize.cx;
rect.bottom = maxsize.cy;
MapDialogRect(hwnd, &rect);
max_x = rect.right;
max_y = rect.bottom;
#else
max_x = maxsize.cx;
max_y = (long)(((double)maxsize.cy) * 1.5);
#endif
rect.left = 0;
rect.top = 0;
rect.right = SPACE_X;
rect.bottom = SPACE_Y;
MapDialogRect(hwnd, &rect);
space_x = rect.right;
space_y = rect.bottom;
cx = max_x + ENTRY_PX + (space_x * 3);
cy = (max_y + space_y) * num_prompts;
SetWindowPos(hwnd, HWND_TOPMOST,
0, 0,
cx + 10, cy + 30,
SWP_NOMOVE);
SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM,
space_x, space_y,
(cx - space_x * 2), max_y,
0);
done = 0;
p = banner;
banner_y = 0;
do {
int nFit;
int pDx[128];
hdc = GetDC(GetDlgItem(hwnd, id));
GetTextExtentExPoint(hdc, p, strlen(p), cx, &nFit,
pDx, &csize);
banner_y += csize.cy;
p += nFit;
} while (*p != 0);
banner_y += space_y;
SetWindowPos(GetDlgItem(hwnd, id), HWND_BOTTOM,
space_x, space_y,
(cx - space_x * 2), banner_y,
0);
cy += banner_y + BUTTON_PY + (space_y * 3);
SetWindowPos(hwnd, HWND_TOPMOST,
0, 0,
cx + 10, cy + 30,
SWP_NOMOVE);
cid = (id + 1);
ccy = banner_y + (space_y * 2);
ccx = max_x + (space_x * 2);
for (n = 0 ; n < num_prompts ; n++) {
SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM,
space_x, ccy,
max_x, max_y, 0);
cid++;
SetWindowPos(GetDlgItem(hwnd, cid), HWND_BOTTOM,
ccx, ccy,
ENTRY_PX, max_y - 3, 0);
cid++;
ccy += (max_y + space_y);
}
if (num_prompts == 0) {
SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM,
(cx / 2), cy - space_y - BUTTON_PY,
BUTTON_PX, BUTTON_PY, 0);
} else {
SetWindowPos(GetDlgItem(hwnd, IDOK), HWND_BOTTOM,
space_x, cy - space_y - BUTTON_PY,
BUTTON_PX, BUTTON_PY, 0);
SetWindowPos(GetDlgItem(hwnd, IDCANCEL), HWND_BOTTOM,
cx - space_x - BUTTON_PX, cy - space_y - BUTTON_PY,
BUTTON_PX, BUTTON_PY, 0);
}
return;
}