32d08fbc767befd1e13b7dff961f7241ee82d0a7
[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 INT_PTR
608 CALLBACK
609 UnlockWindowProc(
610 IN HWND hwndDlg,
611 IN UINT uMsg,
612 IN WPARAM wParam,
613 IN LPARAM lParam)
614 {
615 PGINA_CONTEXT pgContext;
616
617 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
618
619 switch (uMsg)
620 {
621 case WM_INITDIALOG:
622 pgContext = (PGINA_CONTEXT)lParam;
623 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
624
625 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
626
627 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
628 SetFocus(GetDlgItem(hwndDlg, IDC_PASSWORD));
629
630 if (pgContext->bDisableCAD == TRUE)
631 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
632
633 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
634 return TRUE;
635
636 case WM_PAINT:
637 {
638 PAINTSTRUCT ps;
639 HDC hdc;
640 if (pgContext->hBitmap)
641 {
642 hdc = BeginPaint(hwndDlg, &ps);
643 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
644 EndPaint(hwndDlg, &ps);
645 }
646 return TRUE;
647 }
648 case WM_DESTROY:
649 DeleteObject(pgContext->hBitmap);
650 return TRUE;
651
652 case WM_COMMAND:
653 switch (LOWORD(wParam))
654 {
655 case IDOK:
656 {
657 LPWSTR UserName = NULL, Password = NULL;
658 INT result = WLX_SAS_ACTION_NONE;
659
660 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
661 break;
662 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password))
663 {
664 if (UserName != NULL && Password != NULL &&
665 wcscmp(UserName, pgContext->UserName) == 0 &&
666 wcscmp(Password, pgContext->Password) == 0)
667 {
668 result = WLX_SAS_ACTION_UNLOCK_WKSTA;
669 }
670 }
671 HeapFree(GetProcessHeap(), 0, UserName);
672 HeapFree(GetProcessHeap(), 0, Password);
673 EndDialog(hwndDlg, result);
674 return TRUE;
675 }
676
677 case IDCANCEL:
678 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
679 return TRUE;
680 }
681 break;
682 }
683
684 return FALSE;
685 }
686
687
688 static INT
689 GUILockedSAS(
690 IN OUT PGINA_CONTEXT pgContext)
691 {
692 int result;
693
694 TRACE("GUILockedSAS()\n");
695
696 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
697 pgContext->hWlx,
698 pgContext->hDllInstance,
699 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
700 GetDesktopWindow(),
701 UnlockWindowProc,
702 (LPARAM)pgContext);
703 if (result >= WLX_SAS_ACTION_LOGON &&
704 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
705 {
706 WARN("GUILockedSAS() returns 0x%x\n", result);
707 return result;
708 }
709
710 WARN("GUILockedSAS() failed (0x%x)\n", result);
711 return WLX_SAS_ACTION_NONE;
712 }
713
714
715 static INT_PTR CALLBACK
716 LockedWindowProc(
717 IN HWND hwndDlg,
718 IN UINT uMsg,
719 IN WPARAM wParam,
720 IN LPARAM lParam)
721 {
722 PGINA_CONTEXT pgContext;
723
724 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
725
726 switch (uMsg)
727 {
728 case WM_INITDIALOG:
729 {
730 pgContext = (PGINA_CONTEXT)lParam;
731 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
732
733 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
734 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
735 return TRUE;
736 }
737 case WM_PAINT:
738 {
739 PAINTSTRUCT ps;
740 HDC hdc;
741 if (pgContext->hBitmap)
742 {
743 hdc = BeginPaint(hwndDlg, &ps);
744 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
745 EndPaint(hwndDlg, &ps);
746 }
747 return TRUE;
748 }
749 case WM_DESTROY:
750 {
751 DeleteObject(pgContext->hBitmap);
752 return TRUE;
753 }
754 }
755
756 return FALSE;
757 }
758
759
760 static VOID
761 GUIDisplayLockedNotice(
762 IN OUT PGINA_CONTEXT pgContext)
763 {
764 TRACE("GUIdisplayLockedNotice()\n");
765
766 pgContext->pWlxFuncs->WlxDialogBoxParam(
767 pgContext->hWlx,
768 pgContext->hDllInstance,
769 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
770 GetDesktopWindow(),
771 LockedWindowProc,
772 (LPARAM)pgContext);
773 }
774
775 GINA_UI GinaGraphicalUI = {
776 GUIInitialize,
777 GUIDisplayStatusMessage,
778 GUIRemoveStatusMessage,
779 GUIDisplaySASNotice,
780 GUILoggedOnSAS,
781 GUILoggedOutSAS,
782 GUILockedSAS,
783 GUIDisplayLockedNotice,
784 };