83b1ebdd11e91fdc60d3abbdd2b3deb7403f3921
[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 DontDisplayLastUserName, NoDomainUI, ShutdownWithoutLogon */
482 pgContext = (PGINA_CONTEXT)lParam;
483 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
484
485 if (pgContext->bDisableCAD == TRUE)
486 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
487
488 SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME));
489
490 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
491 return TRUE;
492 }
493 case WM_PAINT:
494 {
495 PAINTSTRUCT ps;
496 HDC hdc;
497 if (pgContext->hBitmap)
498 {
499 hdc = BeginPaint(hwndDlg, &ps);
500 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
501 EndPaint(hwndDlg, &ps);
502 }
503 return TRUE;
504 }
505 case WM_DESTROY:
506 {
507 DeleteObject(pgContext->hBitmap);
508 return TRUE;
509 }
510 case WM_COMMAND:
511 {
512 switch (LOWORD(wParam))
513 {
514 case IDOK:
515 {
516 LPWSTR UserName = NULL, Password = NULL;
517 INT result = WLX_SAS_ACTION_NONE;
518
519 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
520 break;
521 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
522 DoLoginTasks(pgContext, UserName, NULL, Password))
523 {
524 result = WLX_SAS_ACTION_LOGON;
525 }
526 HeapFree(GetProcessHeap(), 0, UserName);
527 HeapFree(GetProcessHeap(), 0, Password);
528 EndDialog(hwndDlg, result);
529 return TRUE;
530 }
531 case IDCANCEL:
532 {
533 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
534 return TRUE;
535 }
536 case IDC_SHUTDOWN:
537 {
538 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
539 return TRUE;
540 }
541 }
542 break;
543 }
544 }
545
546 return FALSE;
547 }
548
549 static INT
550 GUILoggedOutSAS(
551 IN OUT PGINA_CONTEXT pgContext)
552 {
553 int result;
554
555 TRACE("GUILoggedOutSAS()\n");
556
557 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
558 pgContext->hWlx,
559 pgContext->hDllInstance,
560 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG),
561 GetDesktopWindow(),
562 LoggedOutWindowProc,
563 (LPARAM)pgContext);
564 if (result >= WLX_SAS_ACTION_LOGON &&
565 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
566 {
567 WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
568 return result;
569 }
570
571 WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
572 return WLX_SAS_ACTION_NONE;
573 }
574
575
576 static
577 INT_PTR
578 CALLBACK
579 UnlockWindowProc(
580 IN HWND hwndDlg,
581 IN UINT uMsg,
582 IN WPARAM wParam,
583 IN LPARAM lParam)
584 {
585 PGINA_CONTEXT pgContext;
586
587 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
588
589 switch (uMsg)
590 {
591 case WM_INITDIALOG:
592 pgContext = (PGINA_CONTEXT)lParam;
593 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
594
595 if (pgContext->bDisableCAD == TRUE)
596 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
597
598 SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME));
599
600 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
601 return TRUE;
602
603 case WM_PAINT:
604 {
605 PAINTSTRUCT ps;
606 HDC hdc;
607 if (pgContext->hBitmap)
608 {
609 hdc = BeginPaint(hwndDlg, &ps);
610 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
611 EndPaint(hwndDlg, &ps);
612 }
613 return TRUE;
614 }
615 case WM_DESTROY:
616 DeleteObject(pgContext->hBitmap);
617 return TRUE;
618
619 case WM_COMMAND:
620 switch (LOWORD(wParam))
621 {
622 case IDOK:
623 {
624 #if 0
625 LPWSTR UserName = NULL, Password = NULL;
626 INT result = WLX_SAS_ACTION_NONE;
627
628 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
629 break;
630 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
631 DoLoginTasks(pgContext, UserName, NULL, Password))
632 {
633 result = WLX_SAS_ACTION_LOGON;
634 }
635 HeapFree(GetProcessHeap(), 0, UserName);
636 HeapFree(GetProcessHeap(), 0, Password);
637 EndDialog(hwndDlg, result);
638 #endif
639 EndDialog(hwndDlg, WLX_SAS_ACTION_UNLOCK_WKSTA);
640 return TRUE;
641 }
642
643 case IDCANCEL:
644 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
645 return TRUE;
646 }
647 break;
648 }
649
650 return FALSE;
651 }
652
653
654 static INT
655 GUILockedSAS(
656 IN OUT PGINA_CONTEXT pgContext)
657 {
658 int result;
659
660 TRACE("GUILockedSAS()\n");
661
662 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
663 pgContext->hWlx,
664 pgContext->hDllInstance,
665 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
666 GetDesktopWindow(),
667 UnlockWindowProc,
668 (LPARAM)pgContext);
669 if (result >= WLX_SAS_ACTION_LOGON &&
670 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
671 {
672 WARN("GUILockedSAS() returns 0x%x\n", result);
673 return result;
674 }
675
676 WARN("GUILockedSAS() failed (0x%x)\n", result);
677 return WLX_SAS_ACTION_NONE;
678 }
679
680
681 static VOID
682 OnInitLockedDlg(HWND hwnd,
683 PGINA_CONTEXT pgContext)
684 {
685 WCHAR Buffer1[256];
686 WCHAR Buffer2[256];
687 WCHAR Buffer3[512];
688
689 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, 256);
690
691 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
692 wsprintfW(Buffer3, Buffer1, Buffer2);
693
694 SetDlgItemTextW(hwnd, IDC_LOCKMSG, Buffer3);
695 }
696
697
698 static INT_PTR CALLBACK
699 LockedWindowProc(
700 IN HWND hwndDlg,
701 IN UINT uMsg,
702 IN WPARAM wParam,
703 IN LPARAM lParam)
704 {
705 PGINA_CONTEXT pgContext;
706
707 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
708
709 switch (uMsg)
710 {
711 case WM_INITDIALOG:
712 {
713 pgContext = (PGINA_CONTEXT)lParam;
714 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
715
716 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
717 OnInitLockedDlg(hwndDlg, pgContext);
718 return TRUE;
719 }
720 case WM_PAINT:
721 {
722 PAINTSTRUCT ps;
723 HDC hdc;
724 if (pgContext->hBitmap)
725 {
726 hdc = BeginPaint(hwndDlg, &ps);
727 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
728 EndPaint(hwndDlg, &ps);
729 }
730 return TRUE;
731 }
732 case WM_DESTROY:
733 {
734 DeleteObject(pgContext->hBitmap);
735 return TRUE;
736 }
737 }
738
739 return FALSE;
740 }
741
742
743 static VOID
744 GUIDisplayLockedNotice(
745 IN OUT PGINA_CONTEXT pgContext)
746 {
747 TRACE("GUIdisplayLockedNotice()\n");
748
749 pgContext->pWlxFuncs->WlxDialogBoxParam(
750 pgContext->hWlx,
751 pgContext->hDllInstance,
752 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
753 GetDesktopWindow(),
754 LockedWindowProc,
755 (LPARAM)pgContext);
756 }
757
758 GINA_UI GinaGraphicalUI = {
759 GUIInitialize,
760 GUIDisplayStatusMessage,
761 GUIRemoveStatusMessage,
762 GUIDisplaySASNotice,
763 GUILoggedOnSAS,
764 GUILoggedOutSAS,
765 GUILockedSAS,
766 GUIDisplayLockedNotice,
767 };