Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / netidmgr_plugin / afsconfigdlg.c
blob9adc7b37401ae2aaf020ca2a311a04c11e393ebc
1 /*
2 * Copyright (c) 2005,2006 Secure Endpoints Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
25 /* $Id$ */
27 #include<afscred.h>
28 #include<kherror.h>
29 #include<khuidefs.h>
30 #include<commctrl.h>
31 #include<help/afsplhlp.h>
32 #include<htmlhelp.h>
34 /* disable the 'name was marked as deprecated' warnings. These get
35 issued for Str?Cat? and Str?Cpy? functions. We don't use those
36 anyway. */
37 #pragma warning(push)
38 #pragma warning(disable: 4995)
39 #include<shlwapi.h>
40 #include<shlobj.h>
41 #pragma warning(pop)
43 #include<assert.h>
45 typedef struct tag_afs_ids_dlg_data {
46 khui_config_init_data cfg;
48 khm_boolean afs_enabled;
49 } afs_ids_dlg_data;
51 INT_PTR CALLBACK
52 afs_cfg_ids_proc(HWND hwnd,
53 UINT uMsg,
54 WPARAM wParam,
55 LPARAM lParam) {
57 afs_ids_dlg_data * d = NULL;
59 switch(uMsg) {
60 case WM_INITDIALOG:
62 khm_int32 t = 1;
64 d = PMALLOC(sizeof(*d));
65 ZeroMemory(d, sizeof(*d));
67 #pragma warning(push)
68 #pragma warning(disable: 4244)
69 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
70 #pragma warning(pop)
72 d->cfg = *((khui_config_init_data *) lParam);
74 khc_read_int32(csp_params, L"AFSEnabled", &t);
76 d->afs_enabled = !!t;
78 CheckDlgButton(hwnd, IDC_CFG_OBTAIN,
79 (d->afs_enabled)? BST_CHECKED: BST_UNCHECKED);
81 return FALSE;
83 case WM_DESTROY:
85 d = (afs_ids_dlg_data *) (LONG_PTR)
86 GetWindowLongPtr(hwnd, DWLP_USER);
88 if (d != NULL) {
89 PFREE(d);
90 SetWindowLongPtr(hwnd, DWLP_USER, 0);
93 return TRUE;
95 case WM_COMMAND:
97 d = (afs_ids_dlg_data *) (LONG_PTR)
98 GetWindowLongPtr(hwnd, DWLP_USER);
100 if (d == NULL)
101 return FALSE;
103 if (wParam == MAKEWPARAM(IDC_CFG_OBTAIN, BN_CLICKED)) {
104 d->afs_enabled =
105 (IsDlgButtonChecked(hwnd, IDC_CFG_OBTAIN) ==
106 BST_CHECKED);
107 khui_cfg_set_flags_inst(&d->cfg, KHUI_CNFLAG_MODIFIED,
108 KHUI_CNFLAG_MODIFIED);
109 return TRUE;
112 return FALSE;
114 case KHUI_WM_CFG_NOTIFY:
116 d = (afs_ids_dlg_data *) (LONG_PTR)
117 GetWindowLongPtr(hwnd, DWLP_USER);
119 if (d == NULL)
120 return FALSE;
122 if (HIWORD(wParam) == WMCFG_APPLY) {
123 khm_int32 t;
125 if (KHM_FAILED(khc_read_int32(csp_params,
126 L"AFSEnabled", &t)) ||
127 !!t != !!d->afs_enabled) {
128 khc_write_int32(csp_params, L"AFSEnabled",
129 !!d->afs_enabled);
131 khui_cfg_set_flags_inst(&d->cfg,
132 KHUI_CNFLAG_APPLIED,
133 KHUI_CNFLAG_APPLIED |
134 KHUI_CNFLAG_MODIFIED);
135 } else {
136 khui_cfg_set_flags_inst(&d->cfg,
138 KHUI_CNFLAG_MODIFIED);
142 return TRUE;
145 return FALSE;
148 INT_PTR CALLBACK
149 afs_cfg_id_proc(HWND hwnd,
150 UINT uMsg,
151 WPARAM wParam,
152 LPARAM lParam) {
154 switch(uMsg) {
156 case WM_INITDIALOG:
158 INT_PTR rv;
159 afs_dlg_data * d;
160 wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
161 khm_size cb;
163 rv = afs_dlg_proc(hwnd, uMsg, wParam, 0);
165 d = (afs_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
166 #ifdef DEBUG
167 assert(d != NULL);
168 #endif
169 if (d == NULL)
170 return rv;
172 d->cfg = *((khui_config_init_data *) lParam);
174 idname[0] = L'\0';
175 cb = sizeof(idname);
176 khui_cfg_get_name(d->cfg.ctx_node, idname, &cb);
178 d->ident = NULL;
179 kcdb_identity_create(idname, 0, &d->ident);
181 #ifdef DEBUG
182 assert(d->ident);
183 #endif
185 d->config_dlg = TRUE;
187 afs_cred_get_identity_creds(&d->creds, d->ident, &d->afs_enabled);
189 afs_dlg_proc(hwnd, KHUI_WM_NC_NOTIFY,
190 MAKEWPARAM(0, WMNC_DIALOG_SETUP), 0);
192 return rv;
194 break; /* not reached */
196 case WM_DESTROY:
198 afs_dlg_data * d;
200 d = (afs_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
201 #ifdef DEBUG
202 assert(d && d->ident);
203 #endif
204 if (d && d->ident) {
205 kcdb_identity_release(d->ident);
208 return afs_dlg_proc(hwnd, uMsg, wParam, lParam);
210 break; /* not reached */
212 case KHUI_WM_CFG_NOTIFY:
214 afs_dlg_data * d;
216 d = (afs_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
218 if (d == NULL)
219 return TRUE;
221 if (HIWORD(wParam) == WMCFG_APPLY) {
222 afs_cred_write_ident_data(d);
225 return TRUE;
227 default:
228 return afs_dlg_proc(hwnd, uMsg, wParam, lParam);
232 static void
233 set_service_status(HWND hwnd) {
234 static DWORD wait_start = 0;
235 DWORD status = 0;
236 DWORD wait_hint = 0;
237 unsigned int i;
238 wchar_t status_strings_csv[1024];
239 wchar_t status_strings_ms[1024];
240 khm_size cb;
241 wchar_t *t;
243 GetServiceStatus(NULL,
244 TRANSARCAFSDAEMON,
245 &status, &wait_hint);
247 LoadString(hResModule, IDS_CFG_SVCSTATUS,
248 status_strings_csv, ARRAYLENGTH(status_strings_csv));
250 cb = sizeof(status_strings_ms);
251 csv_to_multi_string(status_strings_ms, &cb, status_strings_csv);
253 for(i=0, t = status_strings_ms; t && *t && *t != L' ';
254 t = multi_string_next(t), i++) {
255 if (i == status)
256 break;
259 if (!t || !*t)
260 t = status_strings_ms; /* the first one is "unknown". */
262 SetDlgItemText(hwnd, IDC_CFG_STATUS, t);
264 if (status != SERVICE_RUNNING) {
265 HWND hw;
267 hw = GetDlgItem(hwnd, IDC_CFG_STOP);
268 if (hw == GetFocus())
269 SetFocus(GetNextDlgTabItem(hwnd, hw, FALSE));
271 EnableWindow(hw, FALSE);
272 } else {
273 EnableWindow(GetDlgItem(hwnd, IDC_CFG_STOP), TRUE);
276 if (status != SERVICE_STOPPED &&
277 status != SERVICE_PAUSED) {
278 HWND hw;
280 hw = GetDlgItem(hwnd, IDC_CFG_START);
281 if (hw == GetFocus())
282 SetFocus(GetNextDlgTabItem(hwnd, hw, FALSE));
284 EnableWindow(hw, FALSE);
285 } else {
286 EnableWindow(GetDlgItem(hwnd, IDC_CFG_START), TRUE);
289 if (status == SERVICE_START_PENDING ||
290 status == SERVICE_STOP_PENDING) {
291 HWND hw;
292 DWORD now;
293 int progress;
295 hw = GetDlgItem(hwnd, IDC_CFG_PROGRESS);
296 #ifdef DEBUG
297 assert(hw);
298 #endif
299 if (!IsWindowVisible(hw))
300 ShowWindow(hw, SW_SHOW);
302 if (wait_start == 0)
303 wait_start = GetTickCount();
305 now = GetTickCount();
307 if (now + wait_hint != wait_start)
308 progress = (now - wait_start) * 100 /
309 (now + wait_hint - wait_start);
310 else
311 progress = 0;
313 SendMessage(hw, PBM_SETPOS, progress, 0);
315 SetTimer(hwnd, 1, 500, NULL);
316 } else {
317 HWND hw;
319 hw = GetDlgItem(hwnd, IDC_CFG_PROGRESS);
320 #ifdef DEBUG
321 assert(hw);
322 #endif
323 wait_start = 0;
324 if (IsWindowVisible(hw))
325 ShowWindow(hw, SW_HIDE);
329 void
330 afs_cfg_show_last_error(HWND hwnd, wchar_t * prefix, DWORD code) {
331 DWORD r;
332 wchar_t * err_desc = NULL;
333 wchar_t title[64];
334 wchar_t msg[1024];
335 wchar_t tmp[128];
337 r = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
338 FORMAT_MESSAGE_IGNORE_INSERTS |
339 FORMAT_MESSAGE_FROM_SYSTEM,
340 NULL,
341 code,
343 (LPWSTR) &err_desc,
345 NULL);
347 if (r == 0 || err_desc == NULL)
348 return;
350 LoadString(hResModule, IDS_PLUGIN_DESC,
351 title, ARRAYLENGTH(title));
352 if (prefix == NULL)
353 tmp[0] = L'\0';
354 else if (IS_INTRESOURCE(prefix))
355 LoadString(hResModule, (UINT)(UINT_PTR) prefix,
356 tmp, ARRAYLENGTH(tmp));
357 else
358 StringCbCopy(tmp, sizeof(tmp), prefix);
360 StringCbPrintf(msg, sizeof(msg), L"%s%s",
361 tmp, err_desc);
363 MessageBox(hwnd, msg, title, MB_OK | MB_APPLMODAL);
365 LocalFree(err_desc);
368 #define SCNAME_AFSCREDS L"AFS Credentials.lnk"
370 BOOL
371 afs_cfg_get_afscreds_shortcut(wchar_t * wpath) {
372 HRESULT hr;
373 BOOL shortcut_found = FALSE;
375 hr = SHGetFolderPath(NULL, CSIDL_COMMON_STARTUP,
376 NULL, SHGFP_TYPE_CURRENT,
377 wpath);
378 if (FAILED(hr))
379 goto _noshortcut;
381 if (!PathAppend(wpath, SCNAME_AFSCREDS)) {
382 goto _noshortcut;
385 if (PathFileExists(wpath)) {
386 shortcut_found = TRUE;
389 _noshortcut:
391 return shortcut_found;
394 INT_PTR CALLBACK
395 afs_cfg_main_proc(HWND hwnd,
396 UINT uMsg,
397 WPARAM wParam,
398 LPARAM lParam) {
399 switch(uMsg) {
400 case WM_INITDIALOG:
402 wchar_t imagepath[MAX_PATH];
403 wchar_t blockname[MAX_PATH];
404 HKEY service_key;
405 LONG l;
406 DWORD cb;
407 DWORD dummy;
408 LPVOID ver_info;
409 wchar_t * value;
411 struct LANGANDCODEPATH {
412 WORD wLanguage;
413 WORD wCodePage;
414 } *translations;
416 #pragma warning(push)
417 #pragma warning(disable: 4244)
418 SetWindowLongPtr(hwnd, DWLP_USER, (DWORD_PTR) lParam);
419 #pragma warning(pop)
421 /* Try to figure out if afscreds.exe is on the startup
422 group for all users. */
424 khm_handle csp_afscred = NULL;
425 khm_int32 disable = FALSE;
427 if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME,
429 &csp_afscred))) {
431 khc_read_int32(csp_afscred, L"Disableafscreds",
432 &disable);
434 khc_close_space(csp_afscred);
437 if (!disable) {
438 CheckDlgButton(hwnd, IDC_CFG_STARTAFSCREDS,
439 BST_UNCHECKED);
440 } else {
441 CheckDlgButton(hwnd, IDC_CFG_STARTAFSCREDS,
442 BST_CHECKED);
446 l = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
447 L"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon",
449 KEY_READ,
450 &service_key);
452 if (l != ERROR_SUCCESS)
453 goto _set_status;
455 cb = sizeof(imagepath);
456 l = RegQueryValueEx(service_key,
457 L"ImagePath",
458 NULL, NULL,
459 (LPBYTE) imagepath,
460 (DWORD *)&cb);
461 if (l != ERROR_SUCCESS)
462 goto _close_key;
464 PathUnquoteSpaces(imagepath);
466 dummy = 1;
467 cb = GetFileVersionInfoSize(imagepath, &dummy);
468 if (cb == 0 || dummy)
469 goto _close_key;
471 ver_info = malloc(cb);
472 #ifdef DEBUG
473 assert(ver_info);
474 #endif
475 if (!ver_info)
476 goto _close_key;
478 if (!GetFileVersionInfo(imagepath,
479 0, cb, ver_info))
480 goto _free_buffer;
482 cb = 0;
483 if (!VerQueryValue(ver_info,
484 L"\\VarFileInfo\\Translation",
485 (LPVOID*) &translations,
486 (PUINT)&cb) ||
487 cb == 0)
488 goto _free_buffer;
490 StringCbPrintf(blockname, sizeof(blockname),
491 L"\\StringFileInfo\\%04x%04x\\FileVersion",
492 translations[0].wLanguage,
493 translations[0].wCodePage);
495 if (!VerQueryValue(ver_info,
496 blockname,
497 (LPVOID*) &value,
498 (PUINT)&cb) ||
499 cb == 0)
500 goto _free_buffer;
502 SetDlgItemText(hwnd, IDC_CFG_VERSION, value);
504 StringCbPrintf(blockname, sizeof(blockname),
505 L"\\StringFileInfo\\%04x%04x\\CompanyName",
506 translations[0].wLanguage,
507 translations[0].wCodePage);
509 if (!VerQueryValue(ver_info,
510 blockname,
511 (LPVOID*) &value,
512 (PUINT)&cb) ||
513 cb == 0)
514 goto _free_buffer;
516 SetDlgItemText(hwnd, IDC_CFG_COMPANY, value);
518 _free_buffer:
519 free(ver_info);
520 _close_key:
521 RegCloseKey(service_key);
522 _set_status:
523 set_service_status(hwnd);
525 return FALSE;
527 case WM_COMMAND:
528 switch(wParam) {
529 case MAKEWPARAM(IDC_CFG_STOP, BN_CLICKED):
531 DWORD r;
533 r = ServiceControl(NULL, TRANSARCAFSDAEMON, SERVICE_STOPPED);
535 if (r)
536 afs_cfg_show_last_error(hwnd,
537 MAKEINTRESOURCE(IDS_CFG_CANTSTOP),
539 else
540 set_service_status(hwnd);
542 break;
544 case MAKEWPARAM(IDC_CFG_START,BN_CLICKED):
546 DWORD r;
547 r = ServiceControl(NULL, TRANSARCAFSDAEMON, SERVICE_RUNNING);
549 if (r)
550 afs_cfg_show_last_error(hwnd,
551 MAKEINTRESOURCE(IDS_CFG_CANTSTART),
553 else
554 set_service_status(hwnd);
556 break;
558 case MAKEWPARAM(IDC_CFG_CPL, BN_CLICKED):
559 if (32 >= (LRESULT) ShellExecute (NULL, NULL,
560 L"AFS_CONFIG.EXE", NULL,
561 NULL, SW_SHOW)) {
562 MessageBox(NULL,
563 L"Can't find file AFS_CONFIG.EXE",
564 L"Error", MB_OK);
566 break;
568 case MAKEWPARAM(IDC_CFG_STARTAFSCREDS, BN_CLICKED):
570 khui_config_node node;
572 node = (khui_config_node) (DWORD_PTR)
573 GetWindowLongPtr(hwnd, DWLP_USER);
575 if (node != NULL) {
576 khui_cfg_set_flags(node,
577 KHUI_CNFLAG_MODIFIED,
578 KHUI_CNFLAG_MODIFIED);
581 break;
583 return TRUE;
585 case KHUI_WM_CFG_NOTIFY:
587 if (HIWORD(wParam) == WMCFG_APPLY) {
588 wchar_t wpath[MAX_PATH];
589 int dlg_state;
590 khui_config_node node;
591 khm_handle csp_afscred = NULL;
592 khm_int32 disable = FALSE;
594 node = (khui_config_node) (DWORD_PTR)
595 GetWindowLongPtr(hwnd, DWLP_USER);
597 #ifdef DEBUG
598 assert(node != NULL);
599 #endif
600 if (node == NULL)
601 break;
603 kmm_get_plugin_config(AFS_PLUGIN_NAME, KHM_PERM_WRITE,
604 &csp_afscred);
606 if (csp_afscred)
607 khc_read_int32(csp_afscred, L"Disableafscreds",
608 &disable);
610 dlg_state = IsDlgButtonChecked(hwnd, IDC_CFG_STARTAFSCREDS);
612 if (!!disable !=
613 (dlg_state == BST_CHECKED)) {
614 if (csp_afscred)
615 khc_write_int32(csp_afscred,
616 L"Disableafscreds",
617 (dlg_state == BST_CHECKED));
619 khui_cfg_set_flags(node,
620 KHUI_CNFLAG_APPLIED,
621 KHUI_CNFLAG_MODIFIED |
622 KHUI_CNFLAG_APPLIED);
623 } else {
624 khui_cfg_set_flags(node, 0,
625 KHUI_CNFLAG_MODIFIED);
628 if (dlg_state == BST_CHECKED &&
629 afs_cfg_get_afscreds_shortcut(wpath)) {
631 DeleteFile(wpath);
635 return TRUE;
637 case WM_TIMER:
638 if (wParam == 1) {
639 KillTimer(hwnd, 1);
640 set_service_status(hwnd);
642 break;
644 case WM_DESTROY:
645 return FALSE;
647 case WM_HELP:
649 static const DWORD ctx_help[] = {
650 IDC_CFG_STATUS, IDH_SVCSTATUS,
651 IDC_CFG_STOP, IDH_SVCSTOP,
652 IDC_CFG_START, IDH_SVCSTART,
653 IDC_CFG_VERSION, IDH_SVCVERSION,
654 IDC_CFG_COMPANY, IDH_SVCCOMPANY,
655 IDC_CFG_CPL, IDH_SVCCPL,
656 IDC_CFG_STARTAFSCREDS, IDH_STARTAFSCREDS,
660 LPHELPINFO hlp;
662 hlp = (LPHELPINFO) lParam;
664 if (hlp->iContextType != HELPINFO_WINDOW)
665 break;
667 afs_html_help(hlp->hItemHandle, L"::/popups_cfg.txt",
668 HH_TP_HELP_WM_HELP, (DWORD_PTR) ctx_help);
670 return TRUE;
672 return FALSE;