1e1a3bf0aa748df810c889297bacc6dfe4fd0bcf
[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 INT_PTR CALLBACK
224 ChangePasswordDialogProc(
225 IN HWND hwndDlg,
226 IN UINT uMsg,
227 IN WPARAM wParam,
228 IN LPARAM lParam)
229 {
230 switch (uMsg)
231 {
232 case WM_INITDIALOG:
233 FIXME("ChangePasswordDialogProc: WM_INITDLG\n");
234 return TRUE;
235
236 case WM_COMMAND:
237 switch (LOWORD(wParam))
238 {
239 case IDOK:
240 EndDialog(hwndDlg, TRUE);
241 return TRUE;
242
243 case IDCANCEL:
244 EndDialog(hwndDlg, FALSE);
245 return TRUE;
246 }
247 break;
248
249 case WM_CLOSE:
250 EndDialog(hwndDlg, FALSE);
251 return TRUE;
252 }
253
254 return FALSE;
255 }
256
257
258 static VOID
259 OnInitSecurityDlg(HWND hwnd,
260 PGINA_CONTEXT pgContext)
261 {
262 WCHAR Buffer1[256];
263 WCHAR Buffer2[256];
264 WCHAR Buffer3[256];
265 WCHAR Buffer4[512];
266
267 LoadStringW(pgContext->hDllInstance, IDS_LOGONMSG, Buffer1, 256);
268
269 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
270 wsprintfW(Buffer4, Buffer1, Buffer2);
271
272 SetDlgItemTextW(hwnd, IDC_LOGONMSG, Buffer4);
273
274 LoadStringW(pgContext->hDllInstance, IDS_LOGONDATE, Buffer1, 256);
275
276 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
277 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer2, 256);
278
279 GetTimeFormatW(LOCALE_USER_DEFAULT, 0,
280 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer3, 256);
281
282 wsprintfW(Buffer4, Buffer1, Buffer2, Buffer3);
283
284 SetDlgItemTextW(hwnd, IDC_LOGONDATE, Buffer4);
285
286 if (pgContext->bAutoAdminLogon == TRUE)
287 EnableWindow(GetDlgItem(hwnd, IDC_LOGOFF), FALSE);
288 }
289
290
291 static BOOL
292 OnChangePassword(
293 IN HWND hwnd,
294 IN PGINA_CONTEXT pgContext)
295 {
296 INT res;
297
298 FIXME("OnChangePassword()\n");
299
300 res = pgContext->pWlxFuncs->WlxDialogBoxParam(
301 pgContext->hWlx,
302 pgContext->hDllInstance,
303 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD),
304 hwnd,
305 ChangePasswordDialogProc,
306 (LPARAM)pgContext);
307
308 FIXME("Result: %x\n", res);
309
310 return FALSE;
311 }
312
313
314 static INT_PTR CALLBACK
315 LogOffDialogProc(
316 IN HWND hwndDlg,
317 IN UINT uMsg,
318 IN WPARAM wParam,
319 IN LPARAM lParam)
320 {
321 switch (uMsg)
322 {
323 case WM_INITDIALOG:
324 return TRUE;
325
326 case WM_COMMAND:
327 switch (LOWORD(wParam))
328 {
329 case IDYES:
330 EndDialog(hwndDlg, IDYES);
331 return TRUE;
332
333 case IDNO:
334 EndDialog(hwndDlg, IDNO);
335 return TRUE;
336 }
337 break;
338
339 case WM_CLOSE:
340 EndDialog(hwndDlg, IDNO);
341 return TRUE;
342 }
343
344 return FALSE;
345 }
346
347
348 static
349 INT
350 OnLogOff(
351 IN HWND hwndDlg,
352 IN PGINA_CONTEXT pgContext)
353 {
354 return pgContext->pWlxFuncs->WlxDialogBoxParam(
355 pgContext->hWlx,
356 pgContext->hDllInstance,
357 MAKEINTRESOURCEW(IDD_LOGOFF_DLG),
358 hwndDlg,
359 LogOffDialogProc,
360 (LPARAM)pgContext);
361 }
362
363
364 static INT_PTR CALLBACK
365 LoggedOnWindowProc(
366 IN HWND hwndDlg,
367 IN UINT uMsg,
368 IN WPARAM wParam,
369 IN LPARAM lParam)
370 {
371 PGINA_CONTEXT pgContext;
372
373 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
374
375 switch (uMsg)
376 {
377 case WM_INITDIALOG:
378 {
379 pgContext = (PGINA_CONTEXT)lParam;
380 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
381
382 OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam);
383 SetFocus(GetDlgItem(hwndDlg, IDNO));
384 return TRUE;
385 }
386
387 case WM_COMMAND:
388 {
389 switch (LOWORD(wParam))
390 {
391 case IDC_LOCK:
392 EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA);
393 return TRUE;
394 case IDC_LOGOFF:
395 if (OnLogOff(hwndDlg, pgContext) == IDYES)
396 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF);
397 return TRUE;
398 case IDC_SHUTDOWN:
399 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
400 return TRUE;
401 case IDC_CHANGEPWD:
402 if (OnChangePassword(hwndDlg, pgContext))
403 EndDialog(hwndDlg, WLX_SAS_ACTION_PWD_CHANGED);
404 return TRUE;
405 case IDC_TASKMGR:
406 EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST);
407 return TRUE;
408 case IDCANCEL:
409 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
410 return TRUE;
411 }
412 break;
413 }
414 case WM_CLOSE:
415 {
416 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
417 return TRUE;
418 }
419 }
420
421 return FALSE;
422 }
423
424 static INT
425 GUILoggedOnSAS(
426 IN OUT PGINA_CONTEXT pgContext,
427 IN DWORD dwSasType)
428 {
429 INT result;
430
431 TRACE("GUILoggedOnSAS()\n");
432
433 if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL)
434 {
435 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
436 * close itself thanks to the use of WlxDialogBoxParam */
437 return WLX_SAS_ACTION_NONE;
438 }
439
440 pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon(
441 pgContext->hWlx);
442
443 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
444 pgContext->hWlx,
445 pgContext->hDllInstance,
446 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG),
447 GetDesktopWindow(),
448 LoggedOnWindowProc,
449 (LPARAM)pgContext);
450
451 if (result < WLX_SAS_ACTION_LOGON ||
452 result > WLX_SAS_ACTION_SWITCH_CONSOLE)
453 {
454 result = WLX_SAS_ACTION_NONE;
455 }
456
457 if (result == WLX_SAS_ACTION_NONE)
458 {
459 pgContext->pWlxFuncs->WlxSwitchDesktopToUser(
460 pgContext->hWlx);
461 }
462
463 return result;
464 }
465
466 static INT_PTR CALLBACK
467 LoggedOutWindowProc(
468 IN HWND hwndDlg,
469 IN UINT uMsg,
470 IN WPARAM wParam,
471 IN LPARAM lParam)
472 {
473 PGINA_CONTEXT pgContext;
474
475 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
476
477 switch (uMsg)
478 {
479 case WM_INITDIALOG:
480 {
481 /* FIXME: take care of NoDomainUI */
482 pgContext = (PGINA_CONTEXT)lParam;
483 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
484
485 if (pgContext->bDontDisplayLastUserName == FALSE)
486 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
487
488 if (pgContext->bDisableCAD == TRUE)
489 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
490
491 if (pgContext->bShutdownWithoutLogon == FALSE)
492 EnableWindow(GetDlgItem(hwndDlg, IDC_SHUTDOWN), FALSE);
493
494 SetFocus(GetDlgItem(hwndDlg, pgContext->bDontDisplayLastUserName ? IDC_USERNAME : IDC_PASSWORD));
495
496 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
497 return TRUE;
498 }
499 case WM_PAINT:
500 {
501 PAINTSTRUCT ps;
502 HDC hdc;
503 if (pgContext->hBitmap)
504 {
505 hdc = BeginPaint(hwndDlg, &ps);
506 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
507 EndPaint(hwndDlg, &ps);
508 }
509 return TRUE;
510 }
511 case WM_DESTROY:
512 {
513 DeleteObject(pgContext->hBitmap);
514 return TRUE;
515 }
516 case WM_COMMAND:
517 {
518 switch (LOWORD(wParam))
519 {
520 case IDOK:
521 {
522 LPWSTR UserName = NULL, Password = NULL;
523 INT result = WLX_SAS_ACTION_NONE;
524
525 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
526 break;
527 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
528 DoLoginTasks(pgContext, UserName, NULL, Password))
529 {
530 pgContext->Password = HeapAlloc(GetProcessHeap(),
531 HEAP_ZERO_MEMORY,
532 (wcslen(Password) + 1) * sizeof(WCHAR));
533 if (pgContext->Password != NULL)
534 wcscpy(pgContext->Password, Password);
535
536 result = WLX_SAS_ACTION_LOGON;
537 }
538 HeapFree(GetProcessHeap(), 0, UserName);
539 HeapFree(GetProcessHeap(), 0, Password);
540 EndDialog(hwndDlg, result);
541 return TRUE;
542 }
543 case IDCANCEL:
544 {
545 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
546 return TRUE;
547 }
548 case IDC_SHUTDOWN:
549 {
550 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
551 return TRUE;
552 }
553 }
554 break;
555 }
556 }
557
558 return FALSE;
559 }
560
561 static INT
562 GUILoggedOutSAS(
563 IN OUT PGINA_CONTEXT pgContext)
564 {
565 int result;
566
567 TRACE("GUILoggedOutSAS()\n");
568
569 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
570 pgContext->hWlx,
571 pgContext->hDllInstance,
572 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG),
573 GetDesktopWindow(),
574 LoggedOutWindowProc,
575 (LPARAM)pgContext);
576 if (result >= WLX_SAS_ACTION_LOGON &&
577 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
578 {
579 WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
580 return result;
581 }
582
583 WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
584 return WLX_SAS_ACTION_NONE;
585 }
586
587
588 static VOID
589 SetLockMessage(HWND hwnd,
590 INT nDlgItem,
591 PGINA_CONTEXT pgContext)
592 {
593 WCHAR Buffer1[256];
594 WCHAR Buffer2[256];
595 WCHAR Buffer3[512];
596
597 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, 256);
598
599 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
600 wsprintfW(Buffer3, Buffer1, Buffer2);
601
602 SetDlgItemTextW(hwnd, nDlgItem, Buffer3);
603 }
604
605
606 static
607 BOOL
608 DoUnlock(
609 IN HWND hwndDlg,
610 IN PGINA_CONTEXT pgContext,
611 OUT LPINT Action)
612 {
613 WCHAR Buffer1[256];
614 WCHAR Buffer2[256];
615 LPWSTR UserName = NULL;
616 LPWSTR Password = NULL;
617 BOOL res = FALSE;
618
619 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
620 return FALSE;
621
622 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password))
623 {
624 if (UserName != NULL && Password != NULL &&
625 wcscmp(UserName, pgContext->UserName) == 0 &&
626 wcscmp(Password, pgContext->Password) == 0)
627 {
628 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
629 res = TRUE;
630 }
631 else if (wcscmp(UserName, pgContext->UserName) == 0 &&
632 wcscmp(Password, pgContext->Password) != 0)
633 {
634 /* Wrong Password */
635 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, 256);
636 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
637 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
638 }
639 else
640 {
641 /* Wrong user name */
642 if (DoAdminUnlock(UserName, NULL, Password))
643 {
644 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
645 res = TRUE;
646 }
647 else
648 {
649 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, 256);
650 wsprintfW(Buffer2, Buffer1, pgContext->Domain, pgContext->UserName);
651 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
652 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
653 }
654 }
655 }
656
657 if (UserName != NULL)
658 HeapFree(GetProcessHeap(), 0, UserName);
659
660 if (Password != NULL)
661 HeapFree(GetProcessHeap(), 0, Password);
662
663 return res;
664 }
665
666
667 static
668 INT_PTR
669 CALLBACK
670 UnlockWindowProc(
671 IN HWND hwndDlg,
672 IN UINT uMsg,
673 IN WPARAM wParam,
674 IN LPARAM lParam)
675 {
676 PGINA_CONTEXT pgContext;
677 INT result = WLX_SAS_ACTION_NONE;
678
679 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
680
681 switch (uMsg)
682 {
683 case WM_INITDIALOG:
684 pgContext = (PGINA_CONTEXT)lParam;
685 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
686
687 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
688
689 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
690 SetFocus(GetDlgItem(hwndDlg, IDC_PASSWORD));
691
692 if (pgContext->bDisableCAD == TRUE)
693 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
694
695 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
696 return TRUE;
697
698 case WM_PAINT:
699 {
700 PAINTSTRUCT ps;
701 HDC hdc;
702 if (pgContext->hBitmap)
703 {
704 hdc = BeginPaint(hwndDlg, &ps);
705 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
706 EndPaint(hwndDlg, &ps);
707 }
708 return TRUE;
709 }
710 case WM_DESTROY:
711 DeleteObject(pgContext->hBitmap);
712 return TRUE;
713
714 case WM_COMMAND:
715 switch (LOWORD(wParam))
716 {
717 case IDOK:
718 if (DoUnlock(hwndDlg, pgContext, &result))
719 EndDialog(hwndDlg, result);
720 return TRUE;
721
722 case IDCANCEL:
723 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
724 return TRUE;
725 }
726 break;
727 }
728
729 return FALSE;
730 }
731
732
733 static INT
734 GUILockedSAS(
735 IN OUT PGINA_CONTEXT pgContext)
736 {
737 int result;
738
739 TRACE("GUILockedSAS()\n");
740
741 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
742 pgContext->hWlx,
743 pgContext->hDllInstance,
744 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
745 GetDesktopWindow(),
746 UnlockWindowProc,
747 (LPARAM)pgContext);
748 if (result >= WLX_SAS_ACTION_LOGON &&
749 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
750 {
751 WARN("GUILockedSAS() returns 0x%x\n", result);
752 return result;
753 }
754
755 WARN("GUILockedSAS() failed (0x%x)\n", result);
756 return WLX_SAS_ACTION_NONE;
757 }
758
759
760 static INT_PTR CALLBACK
761 LockedWindowProc(
762 IN HWND hwndDlg,
763 IN UINT uMsg,
764 IN WPARAM wParam,
765 IN LPARAM lParam)
766 {
767 PGINA_CONTEXT pgContext;
768
769 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
770
771 switch (uMsg)
772 {
773 case WM_INITDIALOG:
774 {
775 pgContext = (PGINA_CONTEXT)lParam;
776 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
777
778 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
779 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
780 return TRUE;
781 }
782 case WM_PAINT:
783 {
784 PAINTSTRUCT ps;
785 HDC hdc;
786 if (pgContext->hBitmap)
787 {
788 hdc = BeginPaint(hwndDlg, &ps);
789 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
790 EndPaint(hwndDlg, &ps);
791 }
792 return TRUE;
793 }
794 case WM_DESTROY:
795 {
796 DeleteObject(pgContext->hBitmap);
797 return TRUE;
798 }
799 }
800
801 return FALSE;
802 }
803
804
805 static VOID
806 GUIDisplayLockedNotice(
807 IN OUT PGINA_CONTEXT pgContext)
808 {
809 TRACE("GUIdisplayLockedNotice()\n");
810
811 pgContext->pWlxFuncs->WlxDialogBoxParam(
812 pgContext->hWlx,
813 pgContext->hDllInstance,
814 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
815 GetDesktopWindow(),
816 LockedWindowProc,
817 (LPARAM)pgContext);
818 }
819
820 GINA_UI GinaGraphicalUI = {
821 GUIInitialize,
822 GUIDisplayStatusMessage,
823 GUIRemoveStatusMessage,
824 GUIDisplaySASNotice,
825 GUILoggedOnSAS,
826 GUILoggedOutSAS,
827 GUILockedSAS,
828 GUIDisplayLockedNotice,
829 };