[MSGINA]
[reactos.git] / reactos / dll / win32 / msgina / gui.c
1 /*
2 * PROJECT: ReactOS msgina.dll
3 * FILE: dll/win32/msgina/gui.c
4 * PURPOSE: ReactOS Logon GINA DLL
5 * PROGRAMMER: Hervé Poussineau (hpoussin@reactos.org)
6 */
7
8 #include "msgina.h"
9
10 typedef struct _DISPLAYSTATUSMSG
11 {
12 PGINA_CONTEXT Context;
13 HDESK hDesktop;
14 DWORD dwOptions;
15 PWSTR pTitle;
16 PWSTR pMessage;
17 HANDLE StartupEvent;
18 } DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG;
19
20 static BOOL
21 GUIInitialize(
22 IN OUT PGINA_CONTEXT pgContext)
23 {
24 TRACE("GUIInitialize(%p)\n", pgContext);
25 return TRUE;
26 }
27
28 static INT_PTR CALLBACK
29 StatusMessageWindowProc(
30 IN HWND hwndDlg,
31 IN UINT uMsg,
32 IN WPARAM wParam,
33 IN LPARAM lParam)
34 {
35 UNREFERENCED_PARAMETER(wParam);
36
37 switch (uMsg)
38 {
39 case WM_INITDIALOG:
40 {
41 PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam;
42 if (!msg)
43 return FALSE;
44
45 msg->Context->hStatusWindow = hwndDlg;
46
47 if (msg->pTitle)
48 SetWindowTextW(hwndDlg, msg->pTitle);
49 SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, msg->pMessage);
50 SetEvent(msg->StartupEvent);
51 return TRUE;
52 }
53 }
54 return FALSE;
55 }
56
57 static DWORD WINAPI
58 StartupWindowThread(LPVOID lpParam)
59 {
60 HDESK hDesk;
61 PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam;
62
63 /* When SetThreadDesktop is called the system closes the desktop handle when needed
64 so we have to create a new handle because this handle may still be in use by winlogon */
65 if (!DuplicateHandle ( GetCurrentProcess(),
66 msg->hDesktop,
67 GetCurrentProcess(),
68 (HANDLE*)&hDesk,
69 0,
70 FALSE,
71 DUPLICATE_SAME_ACCESS))
72 {
73 HeapFree(GetProcessHeap(), 0, lpParam);
74 return FALSE;
75 }
76
77 if(!SetThreadDesktop(hDesk))
78 {
79 HeapFree(GetProcessHeap(), 0, lpParam);
80 return FALSE;
81 }
82
83 DialogBoxParam(
84 hDllInstance,
85 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG),
86 GetDesktopWindow(),
87 StatusMessageWindowProc,
88 (LPARAM)lpParam);
89
90 HeapFree(GetProcessHeap(), 0, lpParam);
91 return TRUE;
92 }
93
94 static BOOL
95 GUIDisplayStatusMessage(
96 IN PGINA_CONTEXT pgContext,
97 IN HDESK hDesktop,
98 IN DWORD dwOptions,
99 IN PWSTR pTitle,
100 IN PWSTR pMessage)
101 {
102 PDISPLAYSTATUSMSG msg;
103 HANDLE Thread;
104 DWORD ThreadId;
105
106 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage);
107
108 if (!pgContext->hStatusWindow)
109 {
110 msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG));
111 if(!msg)
112 return FALSE;
113
114 msg->Context = pgContext;
115 msg->dwOptions = dwOptions;
116 msg->pTitle = pTitle;
117 msg->pMessage = pMessage;
118 msg->hDesktop = hDesktop;
119
120 msg->StartupEvent = CreateEventW(
121 NULL,
122 TRUE,
123 FALSE,
124 NULL);
125
126 if (!msg->StartupEvent)
127 return FALSE;
128
129 Thread = CreateThread(
130 NULL,
131 0,
132 StartupWindowThread,
133 (PVOID)msg,
134 0,
135 &ThreadId);
136 if (Thread)
137 {
138 CloseHandle(Thread);
139 WaitForSingleObject(msg->StartupEvent, INFINITE);
140 CloseHandle(msg->StartupEvent);
141 return TRUE;
142 }
143
144 return FALSE;
145 }
146
147 if (pTitle)
148 SetWindowTextW(pgContext->hStatusWindow, pTitle);
149
150 SetDlgItemTextW(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage);
151
152 return TRUE;
153 }
154
155 static BOOL
156 GUIRemoveStatusMessage(
157 IN PGINA_CONTEXT pgContext)
158 {
159 if (pgContext->hStatusWindow)
160 {
161 EndDialog(pgContext->hStatusWindow, 0);
162 pgContext->hStatusWindow = NULL;
163 }
164
165 return TRUE;
166 }
167
168 static INT_PTR CALLBACK
169 EmptyWindowProc(
170 IN HWND hwndDlg,
171 IN UINT uMsg,
172 IN WPARAM wParam,
173 IN LPARAM lParam)
174 {
175 UNREFERENCED_PARAMETER(hwndDlg);
176 UNREFERENCED_PARAMETER(uMsg);
177 UNREFERENCED_PARAMETER(wParam);
178 UNREFERENCED_PARAMETER(lParam);
179
180 return FALSE;
181 }
182
183 static VOID
184 GUIDisplaySASNotice(
185 IN OUT PGINA_CONTEXT pgContext)
186 {
187 TRACE("GUIDisplaySASNotice()\n");
188
189 /* Display the notice window */
190 pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
191 pgContext->hDllInstance,
192 MAKEINTRESOURCEW(IDD_NOTICE_DLG),
193 GetDesktopWindow(),
194 EmptyWindowProc,
195 (LPARAM)NULL);
196 }
197
198 /* Get the text contained in a textbox. Allocates memory in pText
199 * to contain the text. Returns TRUE in case of success */
200 static BOOL
201 GetTextboxText(
202 IN HWND hwndDlg,
203 IN INT TextboxId,
204 OUT LPWSTR *pText)
205 {
206 LPWSTR Text;
207 int Count;
208
209 Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId));
210 Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR));
211 if (!Text)
212 return FALSE;
213 if (Count != GetWindowTextW(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1))
214 {
215 HeapFree(GetProcessHeap(), 0, Text);
216 return FALSE;
217 }
218 *pText = Text;
219 return TRUE;
220 }
221
222
223 static
224 BOOL
225 DoChangePassword(HWND hwndDlg)
226 {
227 return FALSE;
228 }
229
230
231 static INT_PTR CALLBACK
232 ChangePasswordDialogProc(
233 IN HWND hwndDlg,
234 IN UINT uMsg,
235 IN WPARAM wParam,
236 IN LPARAM lParam)
237 {
238 PGINA_CONTEXT pgContext;
239
240 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
241
242 switch (uMsg)
243 {
244 case WM_INITDIALOG:
245 pgContext = (PGINA_CONTEXT)lParam;
246 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
247
248 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, pgContext->UserName);
249 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_ADDSTRING, 0, (LPARAM)pgContext->Domain);
250 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_SETCURSEL, 0, 0);
251 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD));
252 return TRUE;
253
254 case WM_COMMAND:
255 switch (LOWORD(wParam))
256 {
257 case IDOK:
258 if (DoChangePassword(hwndDlg))
259 {
260 EndDialog(hwndDlg, TRUE);
261 }
262 else
263 {
264 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NULL);
265 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NULL);
266 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD));
267 }
268 return TRUE;
269
270 case IDCANCEL:
271 EndDialog(hwndDlg, FALSE);
272 return TRUE;
273 }
274 break;
275
276 case WM_CLOSE:
277 EndDialog(hwndDlg, FALSE);
278 return TRUE;
279 }
280
281 return FALSE;
282 }
283
284
285 static VOID
286 OnInitSecurityDlg(HWND hwnd,
287 PGINA_CONTEXT pgContext)
288 {
289 WCHAR Buffer1[256];
290 WCHAR Buffer2[256];
291 WCHAR Buffer3[256];
292 WCHAR Buffer4[512];
293
294 LoadStringW(pgContext->hDllInstance, IDS_LOGONMSG, Buffer1, 256);
295
296 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
297 wsprintfW(Buffer4, Buffer1, Buffer2);
298
299 SetDlgItemTextW(hwnd, IDC_LOGONMSG, Buffer4);
300
301 LoadStringW(pgContext->hDllInstance, IDS_LOGONDATE, Buffer1, 256);
302
303 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
304 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer2, 256);
305
306 GetTimeFormatW(LOCALE_USER_DEFAULT, 0,
307 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer3, 256);
308
309 wsprintfW(Buffer4, Buffer1, Buffer2, Buffer3);
310
311 SetDlgItemTextW(hwnd, IDC_LOGONDATE, Buffer4);
312
313 if (pgContext->bAutoAdminLogon == TRUE)
314 EnableWindow(GetDlgItem(hwnd, IDC_LOGOFF), FALSE);
315 }
316
317
318 static BOOL
319 OnChangePassword(
320 IN HWND hwnd,
321 IN PGINA_CONTEXT pgContext)
322 {
323 INT res;
324
325 FIXME("OnChangePassword()\n");
326
327 res = pgContext->pWlxFuncs->WlxDialogBoxParam(
328 pgContext->hWlx,
329 pgContext->hDllInstance,
330 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD),
331 hwnd,
332 ChangePasswordDialogProc,
333 (LPARAM)pgContext);
334
335 FIXME("Result: %x\n", res);
336
337 return FALSE;
338 }
339
340
341 static INT_PTR CALLBACK
342 LogOffDialogProc(
343 IN HWND hwndDlg,
344 IN UINT uMsg,
345 IN WPARAM wParam,
346 IN LPARAM lParam)
347 {
348 switch (uMsg)
349 {
350 case WM_INITDIALOG:
351 return TRUE;
352
353 case WM_COMMAND:
354 switch (LOWORD(wParam))
355 {
356 case IDYES:
357 EndDialog(hwndDlg, IDYES);
358 return TRUE;
359
360 case IDNO:
361 EndDialog(hwndDlg, IDNO);
362 return TRUE;
363 }
364 break;
365
366 case WM_CLOSE:
367 EndDialog(hwndDlg, IDNO);
368 return TRUE;
369 }
370
371 return FALSE;
372 }
373
374
375 static
376 INT
377 OnLogOff(
378 IN HWND hwndDlg,
379 IN PGINA_CONTEXT pgContext)
380 {
381 return pgContext->pWlxFuncs->WlxDialogBoxParam(
382 pgContext->hWlx,
383 pgContext->hDllInstance,
384 MAKEINTRESOURCEW(IDD_LOGOFF_DLG),
385 hwndDlg,
386 LogOffDialogProc,
387 (LPARAM)pgContext);
388 }
389
390
391 static INT_PTR CALLBACK
392 LoggedOnWindowProc(
393 IN HWND hwndDlg,
394 IN UINT uMsg,
395 IN WPARAM wParam,
396 IN LPARAM lParam)
397 {
398 PGINA_CONTEXT pgContext;
399
400 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
401
402 switch (uMsg)
403 {
404 case WM_INITDIALOG:
405 {
406 pgContext = (PGINA_CONTEXT)lParam;
407 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
408
409 OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam);
410 SetFocus(GetDlgItem(hwndDlg, IDNO));
411 return TRUE;
412 }
413
414 case WM_COMMAND:
415 {
416 switch (LOWORD(wParam))
417 {
418 case IDC_LOCK:
419 EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA);
420 return TRUE;
421 case IDC_LOGOFF:
422 if (OnLogOff(hwndDlg, pgContext) == IDYES)
423 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF);
424 return TRUE;
425 case IDC_SHUTDOWN:
426 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
427 return TRUE;
428 case IDC_CHANGEPWD:
429 if (OnChangePassword(hwndDlg, pgContext))
430 EndDialog(hwndDlg, WLX_SAS_ACTION_PWD_CHANGED);
431 return TRUE;
432 case IDC_TASKMGR:
433 EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST);
434 return TRUE;
435 case IDCANCEL:
436 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
437 return TRUE;
438 }
439 break;
440 }
441 case WM_CLOSE:
442 {
443 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
444 return TRUE;
445 }
446 }
447
448 return FALSE;
449 }
450
451 static INT
452 GUILoggedOnSAS(
453 IN OUT PGINA_CONTEXT pgContext,
454 IN DWORD dwSasType)
455 {
456 INT result;
457
458 TRACE("GUILoggedOnSAS()\n");
459
460 if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL)
461 {
462 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
463 * close itself thanks to the use of WlxDialogBoxParam */
464 return WLX_SAS_ACTION_NONE;
465 }
466
467 pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon(
468 pgContext->hWlx);
469
470 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
471 pgContext->hWlx,
472 pgContext->hDllInstance,
473 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG),
474 GetDesktopWindow(),
475 LoggedOnWindowProc,
476 (LPARAM)pgContext);
477
478 if (result < WLX_SAS_ACTION_LOGON ||
479 result > WLX_SAS_ACTION_SWITCH_CONSOLE)
480 {
481 result = WLX_SAS_ACTION_NONE;
482 }
483
484 if (result == WLX_SAS_ACTION_NONE)
485 {
486 pgContext->pWlxFuncs->WlxSwitchDesktopToUser(
487 pgContext->hWlx);
488 }
489
490 return result;
491 }
492
493 static INT_PTR CALLBACK
494 LoggedOutWindowProc(
495 IN HWND hwndDlg,
496 IN UINT uMsg,
497 IN WPARAM wParam,
498 IN LPARAM lParam)
499 {
500 PGINA_CONTEXT pgContext;
501
502 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
503
504 switch (uMsg)
505 {
506 case WM_INITDIALOG:
507 {
508 /* FIXME: take care of NoDomainUI */
509 pgContext = (PGINA_CONTEXT)lParam;
510 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
511
512 if (pgContext->bDontDisplayLastUserName == FALSE)
513 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
514
515 if (pgContext->bDisableCAD == TRUE)
516 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
517
518 if (pgContext->bShutdownWithoutLogon == FALSE)
519 EnableWindow(GetDlgItem(hwndDlg, IDC_SHUTDOWN), FALSE);
520
521 SetFocus(GetDlgItem(hwndDlg, pgContext->bDontDisplayLastUserName ? IDC_USERNAME : IDC_PASSWORD));
522
523 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
524 return TRUE;
525 }
526 case WM_PAINT:
527 {
528 PAINTSTRUCT ps;
529 HDC hdc;
530 if (pgContext->hBitmap)
531 {
532 hdc = BeginPaint(hwndDlg, &ps);
533 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
534 EndPaint(hwndDlg, &ps);
535 }
536 return TRUE;
537 }
538 case WM_DESTROY:
539 {
540 DeleteObject(pgContext->hBitmap);
541 return TRUE;
542 }
543 case WM_COMMAND:
544 {
545 switch (LOWORD(wParam))
546 {
547 case IDOK:
548 {
549 LPWSTR UserName = NULL, Password = NULL;
550 INT result = WLX_SAS_ACTION_NONE;
551
552 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
553 break;
554 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
555 DoLoginTasks(pgContext, UserName, NULL, Password))
556 {
557 pgContext->Password = HeapAlloc(GetProcessHeap(),
558 HEAP_ZERO_MEMORY,
559 (wcslen(Password) + 1) * sizeof(WCHAR));
560 if (pgContext->Password != NULL)
561 wcscpy(pgContext->Password, Password);
562
563 result = WLX_SAS_ACTION_LOGON;
564 }
565 HeapFree(GetProcessHeap(), 0, UserName);
566 HeapFree(GetProcessHeap(), 0, Password);
567 EndDialog(hwndDlg, result);
568 return TRUE;
569 }
570 case IDCANCEL:
571 {
572 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
573 return TRUE;
574 }
575 case IDC_SHUTDOWN:
576 {
577 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
578 return TRUE;
579 }
580 }
581 break;
582 }
583 }
584
585 return FALSE;
586 }
587
588 static INT
589 GUILoggedOutSAS(
590 IN OUT PGINA_CONTEXT pgContext)
591 {
592 int result;
593
594 TRACE("GUILoggedOutSAS()\n");
595
596 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
597 pgContext->hWlx,
598 pgContext->hDllInstance,
599 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG),
600 GetDesktopWindow(),
601 LoggedOutWindowProc,
602 (LPARAM)pgContext);
603 if (result >= WLX_SAS_ACTION_LOGON &&
604 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
605 {
606 WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
607 return result;
608 }
609
610 WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
611 return WLX_SAS_ACTION_NONE;
612 }
613
614
615 static VOID
616 SetLockMessage(HWND hwnd,
617 INT nDlgItem,
618 PGINA_CONTEXT pgContext)
619 {
620 WCHAR Buffer1[256];
621 WCHAR Buffer2[256];
622 WCHAR Buffer3[512];
623
624 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, 256);
625
626 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
627 wsprintfW(Buffer3, Buffer1, Buffer2);
628
629 SetDlgItemTextW(hwnd, nDlgItem, Buffer3);
630 }
631
632
633 static
634 BOOL
635 DoUnlock(
636 IN HWND hwndDlg,
637 IN PGINA_CONTEXT pgContext,
638 OUT LPINT Action)
639 {
640 WCHAR Buffer1[256];
641 WCHAR Buffer2[256];
642 LPWSTR UserName = NULL;
643 LPWSTR Password = NULL;
644 BOOL res = FALSE;
645
646 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
647 return FALSE;
648
649 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password))
650 {
651 if (UserName != NULL && Password != NULL &&
652 wcscmp(UserName, pgContext->UserName) == 0 &&
653 wcscmp(Password, pgContext->Password) == 0)
654 {
655 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
656 res = TRUE;
657 }
658 else if (wcscmp(UserName, pgContext->UserName) == 0 &&
659 wcscmp(Password, pgContext->Password) != 0)
660 {
661 /* Wrong Password */
662 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, 256);
663 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
664 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
665 }
666 else
667 {
668 /* Wrong user name */
669 if (DoAdminUnlock(UserName, NULL, Password))
670 {
671 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
672 res = TRUE;
673 }
674 else
675 {
676 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, 256);
677 wsprintfW(Buffer2, Buffer1, pgContext->Domain, pgContext->UserName);
678 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
679 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
680 }
681 }
682 }
683
684 if (UserName != NULL)
685 HeapFree(GetProcessHeap(), 0, UserName);
686
687 if (Password != NULL)
688 HeapFree(GetProcessHeap(), 0, Password);
689
690 return res;
691 }
692
693
694 static
695 INT_PTR
696 CALLBACK
697 UnlockWindowProc(
698 IN HWND hwndDlg,
699 IN UINT uMsg,
700 IN WPARAM wParam,
701 IN LPARAM lParam)
702 {
703 PGINA_CONTEXT pgContext;
704 INT result = WLX_SAS_ACTION_NONE;
705
706 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
707
708 switch (uMsg)
709 {
710 case WM_INITDIALOG:
711 pgContext = (PGINA_CONTEXT)lParam;
712 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
713
714 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
715
716 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
717 SetFocus(GetDlgItem(hwndDlg, IDC_PASSWORD));
718
719 if (pgContext->bDisableCAD == TRUE)
720 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
721
722 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
723 return TRUE;
724
725 case WM_PAINT:
726 {
727 PAINTSTRUCT ps;
728 HDC hdc;
729 if (pgContext->hBitmap)
730 {
731 hdc = BeginPaint(hwndDlg, &ps);
732 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
733 EndPaint(hwndDlg, &ps);
734 }
735 return TRUE;
736 }
737 case WM_DESTROY:
738 DeleteObject(pgContext->hBitmap);
739 return TRUE;
740
741 case WM_COMMAND:
742 switch (LOWORD(wParam))
743 {
744 case IDOK:
745 if (DoUnlock(hwndDlg, pgContext, &result))
746 EndDialog(hwndDlg, result);
747 return TRUE;
748
749 case IDCANCEL:
750 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
751 return TRUE;
752 }
753 break;
754 }
755
756 return FALSE;
757 }
758
759
760 static INT
761 GUILockedSAS(
762 IN OUT PGINA_CONTEXT pgContext)
763 {
764 int result;
765
766 TRACE("GUILockedSAS()\n");
767
768 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
769 pgContext->hWlx,
770 pgContext->hDllInstance,
771 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
772 GetDesktopWindow(),
773 UnlockWindowProc,
774 (LPARAM)pgContext);
775 if (result >= WLX_SAS_ACTION_LOGON &&
776 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
777 {
778 WARN("GUILockedSAS() returns 0x%x\n", result);
779 return result;
780 }
781
782 WARN("GUILockedSAS() failed (0x%x)\n", result);
783 return WLX_SAS_ACTION_NONE;
784 }
785
786
787 static INT_PTR CALLBACK
788 LockedWindowProc(
789 IN HWND hwndDlg,
790 IN UINT uMsg,
791 IN WPARAM wParam,
792 IN LPARAM lParam)
793 {
794 PGINA_CONTEXT pgContext;
795
796 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
797
798 switch (uMsg)
799 {
800 case WM_INITDIALOG:
801 {
802 pgContext = (PGINA_CONTEXT)lParam;
803 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
804
805 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
806 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
807 return TRUE;
808 }
809 case WM_PAINT:
810 {
811 PAINTSTRUCT ps;
812 HDC hdc;
813 if (pgContext->hBitmap)
814 {
815 hdc = BeginPaint(hwndDlg, &ps);
816 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
817 EndPaint(hwndDlg, &ps);
818 }
819 return TRUE;
820 }
821 case WM_DESTROY:
822 {
823 DeleteObject(pgContext->hBitmap);
824 return TRUE;
825 }
826 }
827
828 return FALSE;
829 }
830
831
832 static VOID
833 GUIDisplayLockedNotice(
834 IN OUT PGINA_CONTEXT pgContext)
835 {
836 TRACE("GUIdisplayLockedNotice()\n");
837
838 pgContext->pWlxFuncs->WlxDialogBoxParam(
839 pgContext->hWlx,
840 pgContext->hDllInstance,
841 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
842 GetDesktopWindow(),
843 LockedWindowProc,
844 (LPARAM)pgContext);
845 }
846
847 GINA_UI GinaGraphicalUI = {
848 GUIInitialize,
849 GUIDisplayStatusMessage,
850 GUIRemoveStatusMessage,
851 GUIDisplaySASNotice,
852 GUILoggedOnSAS,
853 GUILoggedOutSAS,
854 GUILockedSAS,
855 GUIDisplayLockedNotice,
856 };