6357d40439efca3c1c9257a7d12d4e990025ac0e
[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 INT
225 ResourceMessageBox(
226 IN PGINA_CONTEXT pgContext,
227 IN HWND hwnd,
228 IN UINT uType,
229 IN UINT uCaption,
230 IN UINT uText)
231 {
232 WCHAR szCaption[256];
233 WCHAR szText[256];
234
235 LoadStringW(pgContext->hDllInstance, uCaption, szCaption, 256);
236 LoadStringW(pgContext->hDllInstance, uText, szText, 256);
237
238 return pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx,
239 hwnd,
240 szText,
241 szCaption,
242 uType);
243 }
244
245
246 static
247 BOOL
248 DoChangePassword(
249 IN PGINA_CONTEXT pgContext,
250 IN HWND hwndDlg)
251 {
252 WCHAR UserName[256];
253 WCHAR DomainName[256];
254 WCHAR OldPassword[256];
255 WCHAR NewPassword1[256];
256 WCHAR NewPassword2[256];
257 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL;
258 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL;
259 ULONG RequestBufferSize;
260 ULONG ResponseBufferSize = 0;
261 LPWSTR Ptr;
262 BOOL res = FALSE;
263 NTSTATUS ProtocolStatus;
264 NTSTATUS Status;
265
266 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, UserName, 256);
267 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_DOMAIN, DomainName, 256);
268 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_OLDPWD, OldPassword, 256);
269 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NewPassword1, 256);
270 GetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NewPassword2, 256);
271
272 /* Compare the two passwords and fail if they do not match */
273 if (wcscmp(NewPassword1, NewPassword2) != 0)
274 {
275 ResourceMessageBox(pgContext,
276 hwndDlg,
277 MB_OK | MB_ICONEXCLAMATION,
278 IDS_CHANGEPWDTITLE,
279 IDS_NONMATCHINGPASSWORDS);
280 return FALSE;
281 }
282
283 /* Calculate the request buffer size */
284 RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
285 ((wcslen(DomainName) + 1) * sizeof(WCHAR)) +
286 ((wcslen(UserName) + 1) * sizeof(WCHAR)) +
287 ((wcslen(OldPassword) + 1) * sizeof(WCHAR)) +
288 ((wcslen(NewPassword1) + 1) * sizeof(WCHAR));
289
290 /* Allocate the request buffer */
291 RequestBuffer = HeapAlloc(GetProcessHeap(),
292 HEAP_ZERO_MEMORY,
293 RequestBufferSize);
294 if (RequestBuffer == NULL)
295 {
296 ERR("HeapAlloc failed\n");
297 return FALSE;
298 }
299
300 /* Initialize the request buffer */
301 RequestBuffer->MessageType = MsV1_0ChangePassword;
302 RequestBuffer->Impersonating = TRUE;
303
304 Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
305
306 /* Pack the domain name */
307 RequestBuffer->DomainName.Length = wcslen(DomainName) * sizeof(WCHAR);
308 RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR);
309 RequestBuffer->DomainName.Buffer = Ptr;
310
311 RtlCopyMemory(RequestBuffer->DomainName.Buffer,
312 DomainName,
313 RequestBuffer->DomainName.MaximumLength);
314
315 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
316
317 /* Pack the user name */
318 RequestBuffer->AccountName.Length = wcslen(UserName) * sizeof(WCHAR);
319 RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR);
320 RequestBuffer->AccountName.Buffer = Ptr;
321
322 RtlCopyMemory(RequestBuffer->AccountName.Buffer,
323 UserName,
324 RequestBuffer->AccountName.MaximumLength);
325
326 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
327
328 /* Pack the old password */
329 RequestBuffer->OldPassword.Length = wcslen(OldPassword) * sizeof(WCHAR);
330 RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR);
331 RequestBuffer->OldPassword.Buffer = Ptr;
332
333 RtlCopyMemory(RequestBuffer->OldPassword.Buffer,
334 OldPassword,
335 RequestBuffer->OldPassword.MaximumLength);
336
337 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
338
339 /* Pack the new password */
340 RequestBuffer->NewPassword.Length = wcslen(NewPassword1) * sizeof(WCHAR);
341 RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR);
342 RequestBuffer->NewPassword.Buffer = Ptr;
343
344 RtlCopyMemory(RequestBuffer->NewPassword.Buffer,
345 NewPassword1,
346 RequestBuffer->NewPassword.MaximumLength);
347
348 /* Call the authentication package */
349 Status = LsaCallAuthenticationPackage(pgContext->LsaHandle,
350 pgContext->AuthenticationPackage,
351 RequestBuffer,
352 RequestBufferSize,
353 (PVOID*)&ResponseBuffer,
354 &ResponseBufferSize,
355 &ProtocolStatus);
356 if (!NT_SUCCESS(Status))
357 {
358 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status);
359 goto done;
360 }
361
362 if (!NT_SUCCESS(ProtocolStatus))
363 {
364 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus);
365 goto done;
366 }
367
368 res = TRUE;
369
370 ResourceMessageBox(pgContext,
371 hwndDlg,
372 MB_OK | MB_ICONINFORMATION,
373 IDS_CHANGEPWDTITLE,
374 IDS_PASSWORDCHANGED);
375
376 done:
377 if (RequestBuffer != NULL)
378 HeapFree(GetProcessHeap(), 0, RequestBuffer);
379
380 if (ResponseBuffer != NULL)
381 LsaFreeReturnBuffer(ResponseBuffer);
382
383 return res;
384 }
385
386
387 static INT_PTR CALLBACK
388 ChangePasswordDialogProc(
389 IN HWND hwndDlg,
390 IN UINT uMsg,
391 IN WPARAM wParam,
392 IN LPARAM lParam)
393 {
394 PGINA_CONTEXT pgContext;
395
396 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
397
398 switch (uMsg)
399 {
400 case WM_INITDIALOG:
401 pgContext = (PGINA_CONTEXT)lParam;
402 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
403
404 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_USERNAME, pgContext->UserName);
405 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_ADDSTRING, 0, (LPARAM)pgContext->Domain);
406 SendDlgItemMessageW(hwndDlg, IDC_CHANGEPWD_DOMAIN, CB_SETCURSEL, 0, 0);
407 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD));
408 return TRUE;
409
410 case WM_COMMAND:
411 switch (LOWORD(wParam))
412 {
413 case IDOK:
414 if (DoChangePassword(pgContext, hwndDlg))
415 {
416 EndDialog(hwndDlg, TRUE);
417 }
418 else
419 {
420 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD1, NULL);
421 SetDlgItemTextW(hwndDlg, IDC_CHANGEPWD_NEWPWD2, NULL);
422 SetFocus(GetDlgItem(hwndDlg, IDC_CHANGEPWD_OLDPWD));
423 }
424 return TRUE;
425
426 case IDCANCEL:
427 EndDialog(hwndDlg, FALSE);
428 return TRUE;
429 }
430 break;
431
432 case WM_CLOSE:
433 EndDialog(hwndDlg, FALSE);
434 return TRUE;
435 }
436
437 return FALSE;
438 }
439
440
441 static VOID
442 OnInitSecurityDlg(HWND hwnd,
443 PGINA_CONTEXT pgContext)
444 {
445 WCHAR Buffer1[256];
446 WCHAR Buffer2[256];
447 WCHAR Buffer3[256];
448 WCHAR Buffer4[512];
449
450 LoadStringW(pgContext->hDllInstance, IDS_LOGONMSG, Buffer1, 256);
451
452 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
453 wsprintfW(Buffer4, Buffer1, Buffer2);
454
455 SetDlgItemTextW(hwnd, IDC_LOGONMSG, Buffer4);
456
457 LoadStringW(pgContext->hDllInstance, IDS_LOGONDATE, Buffer1, 256);
458
459 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE,
460 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer2, 256);
461
462 GetTimeFormatW(LOCALE_USER_DEFAULT, 0,
463 (SYSTEMTIME*)&pgContext->LogonTime, NULL, Buffer3, 256);
464
465 wsprintfW(Buffer4, Buffer1, Buffer2, Buffer3);
466
467 SetDlgItemTextW(hwnd, IDC_LOGONDATE, Buffer4);
468
469 if (pgContext->bAutoAdminLogon == TRUE)
470 EnableWindow(GetDlgItem(hwnd, IDC_LOGOFF), FALSE);
471 }
472
473
474 static BOOL
475 OnChangePassword(
476 IN HWND hwnd,
477 IN PGINA_CONTEXT pgContext)
478 {
479 INT res;
480
481 TRACE("OnChangePassword()\n");
482
483 res = pgContext->pWlxFuncs->WlxDialogBoxParam(
484 pgContext->hWlx,
485 pgContext->hDllInstance,
486 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD),
487 hwnd,
488 ChangePasswordDialogProc,
489 (LPARAM)pgContext);
490
491 TRACE("Result: %x\n", res);
492
493 return FALSE;
494 }
495
496
497 static INT_PTR CALLBACK
498 LogOffDialogProc(
499 IN HWND hwndDlg,
500 IN UINT uMsg,
501 IN WPARAM wParam,
502 IN LPARAM lParam)
503 {
504 switch (uMsg)
505 {
506 case WM_INITDIALOG:
507 return TRUE;
508
509 case WM_COMMAND:
510 switch (LOWORD(wParam))
511 {
512 case IDYES:
513 EndDialog(hwndDlg, IDYES);
514 return TRUE;
515
516 case IDNO:
517 EndDialog(hwndDlg, IDNO);
518 return TRUE;
519 }
520 break;
521
522 case WM_CLOSE:
523 EndDialog(hwndDlg, IDNO);
524 return TRUE;
525 }
526
527 return FALSE;
528 }
529
530
531 static
532 INT
533 OnLogOff(
534 IN HWND hwndDlg,
535 IN PGINA_CONTEXT pgContext)
536 {
537 return pgContext->pWlxFuncs->WlxDialogBoxParam(
538 pgContext->hWlx,
539 pgContext->hDllInstance,
540 MAKEINTRESOURCEW(IDD_LOGOFF_DLG),
541 hwndDlg,
542 LogOffDialogProc,
543 (LPARAM)pgContext);
544 }
545
546
547 static INT_PTR CALLBACK
548 LoggedOnWindowProc(
549 IN HWND hwndDlg,
550 IN UINT uMsg,
551 IN WPARAM wParam,
552 IN LPARAM lParam)
553 {
554 PGINA_CONTEXT pgContext;
555
556 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
557
558 switch (uMsg)
559 {
560 case WM_INITDIALOG:
561 {
562 pgContext = (PGINA_CONTEXT)lParam;
563 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
564
565 OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam);
566 SetFocus(GetDlgItem(hwndDlg, IDNO));
567 return TRUE;
568 }
569
570 case WM_COMMAND:
571 {
572 switch (LOWORD(wParam))
573 {
574 case IDC_LOCK:
575 EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA);
576 return TRUE;
577 case IDC_LOGOFF:
578 if (OnLogOff(hwndDlg, pgContext) == IDYES)
579 EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF);
580 return TRUE;
581 case IDC_SHUTDOWN:
582 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
583 return TRUE;
584 case IDC_CHANGEPWD:
585 if (OnChangePassword(hwndDlg, pgContext))
586 EndDialog(hwndDlg, WLX_SAS_ACTION_PWD_CHANGED);
587 return TRUE;
588 case IDC_TASKMGR:
589 EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST);
590 return TRUE;
591 case IDCANCEL:
592 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
593 return TRUE;
594 }
595 break;
596 }
597 case WM_CLOSE:
598 {
599 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
600 return TRUE;
601 }
602 }
603
604 return FALSE;
605 }
606
607 static INT
608 GUILoggedOnSAS(
609 IN OUT PGINA_CONTEXT pgContext,
610 IN DWORD dwSasType)
611 {
612 INT result;
613
614 TRACE("GUILoggedOnSAS()\n");
615
616 if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL)
617 {
618 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
619 * close itself thanks to the use of WlxDialogBoxParam */
620 return WLX_SAS_ACTION_NONE;
621 }
622
623 pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon(
624 pgContext->hWlx);
625
626 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
627 pgContext->hWlx,
628 pgContext->hDllInstance,
629 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG),
630 GetDesktopWindow(),
631 LoggedOnWindowProc,
632 (LPARAM)pgContext);
633
634 if (result < WLX_SAS_ACTION_LOGON ||
635 result > WLX_SAS_ACTION_SWITCH_CONSOLE)
636 {
637 result = WLX_SAS_ACTION_NONE;
638 }
639
640 if (result == WLX_SAS_ACTION_NONE)
641 {
642 pgContext->pWlxFuncs->WlxSwitchDesktopToUser(
643 pgContext->hWlx);
644 }
645
646 return result;
647 }
648
649 static INT_PTR CALLBACK
650 LoggedOutWindowProc(
651 IN HWND hwndDlg,
652 IN UINT uMsg,
653 IN WPARAM wParam,
654 IN LPARAM lParam)
655 {
656 PGINA_CONTEXT pgContext;
657
658 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
659
660 switch (uMsg)
661 {
662 case WM_INITDIALOG:
663 {
664 /* FIXME: take care of NoDomainUI */
665 pgContext = (PGINA_CONTEXT)lParam;
666 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
667
668 if (pgContext->bDontDisplayLastUserName == FALSE)
669 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
670
671 if (pgContext->bDisableCAD == TRUE)
672 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
673
674 if (pgContext->bShutdownWithoutLogon == FALSE)
675 EnableWindow(GetDlgItem(hwndDlg, IDC_SHUTDOWN), FALSE);
676
677 SetFocus(GetDlgItem(hwndDlg, pgContext->bDontDisplayLastUserName ? IDC_USERNAME : IDC_PASSWORD));
678
679 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
680 return TRUE;
681 }
682 case WM_PAINT:
683 {
684 PAINTSTRUCT ps;
685 HDC hdc;
686 if (pgContext->hBitmap)
687 {
688 hdc = BeginPaint(hwndDlg, &ps);
689 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
690 EndPaint(hwndDlg, &ps);
691 }
692 return TRUE;
693 }
694 case WM_DESTROY:
695 {
696 DeleteObject(pgContext->hBitmap);
697 return TRUE;
698 }
699 case WM_COMMAND:
700 {
701 switch (LOWORD(wParam))
702 {
703 case IDOK:
704 {
705 LPWSTR UserName = NULL, Password = NULL;
706 INT result = WLX_SAS_ACTION_NONE;
707
708 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
709 break;
710 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
711 DoLoginTasks(pgContext, UserName, NULL, Password))
712 {
713 pgContext->Password = HeapAlloc(GetProcessHeap(),
714 HEAP_ZERO_MEMORY,
715 (wcslen(Password) + 1) * sizeof(WCHAR));
716 if (pgContext->Password != NULL)
717 wcscpy(pgContext->Password, Password);
718
719 result = WLX_SAS_ACTION_LOGON;
720 }
721 HeapFree(GetProcessHeap(), 0, UserName);
722 HeapFree(GetProcessHeap(), 0, Password);
723 EndDialog(hwndDlg, result);
724 return TRUE;
725 }
726 case IDCANCEL:
727 {
728 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
729 return TRUE;
730 }
731 case IDC_SHUTDOWN:
732 {
733 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
734 return TRUE;
735 }
736 }
737 break;
738 }
739 }
740
741 return FALSE;
742 }
743
744 static INT
745 GUILoggedOutSAS(
746 IN OUT PGINA_CONTEXT pgContext)
747 {
748 int result;
749
750 TRACE("GUILoggedOutSAS()\n");
751
752 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
753 pgContext->hWlx,
754 pgContext->hDllInstance,
755 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG),
756 GetDesktopWindow(),
757 LoggedOutWindowProc,
758 (LPARAM)pgContext);
759 if (result >= WLX_SAS_ACTION_LOGON &&
760 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
761 {
762 WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
763 return result;
764 }
765
766 WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
767 return WLX_SAS_ACTION_NONE;
768 }
769
770
771 static VOID
772 SetLockMessage(HWND hwnd,
773 INT nDlgItem,
774 PGINA_CONTEXT pgContext)
775 {
776 WCHAR Buffer1[256];
777 WCHAR Buffer2[256];
778 WCHAR Buffer3[512];
779
780 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, 256);
781
782 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
783 wsprintfW(Buffer3, Buffer1, Buffer2);
784
785 SetDlgItemTextW(hwnd, nDlgItem, Buffer3);
786 }
787
788
789 static
790 BOOL
791 DoUnlock(
792 IN HWND hwndDlg,
793 IN PGINA_CONTEXT pgContext,
794 OUT LPINT Action)
795 {
796 WCHAR Buffer1[256];
797 WCHAR Buffer2[256];
798 LPWSTR UserName = NULL;
799 LPWSTR Password = NULL;
800 BOOL res = FALSE;
801
802 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
803 return FALSE;
804
805 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password))
806 {
807 if (UserName != NULL && Password != NULL &&
808 wcscmp(UserName, pgContext->UserName) == 0 &&
809 wcscmp(Password, pgContext->Password) == 0)
810 {
811 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
812 res = TRUE;
813 }
814 else if (wcscmp(UserName, pgContext->UserName) == 0 &&
815 wcscmp(Password, pgContext->Password) != 0)
816 {
817 /* Wrong Password */
818 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, 256);
819 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
820 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
821 }
822 else
823 {
824 /* Wrong user name */
825 if (DoAdminUnlock(UserName, NULL, Password))
826 {
827 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
828 res = TRUE;
829 }
830 else
831 {
832 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, 256);
833 wsprintfW(Buffer2, Buffer1, pgContext->Domain, pgContext->UserName);
834 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
835 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
836 }
837 }
838 }
839
840 if (UserName != NULL)
841 HeapFree(GetProcessHeap(), 0, UserName);
842
843 if (Password != NULL)
844 HeapFree(GetProcessHeap(), 0, Password);
845
846 return res;
847 }
848
849
850 static
851 INT_PTR
852 CALLBACK
853 UnlockWindowProc(
854 IN HWND hwndDlg,
855 IN UINT uMsg,
856 IN WPARAM wParam,
857 IN LPARAM lParam)
858 {
859 PGINA_CONTEXT pgContext;
860 INT result = WLX_SAS_ACTION_NONE;
861
862 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
863
864 switch (uMsg)
865 {
866 case WM_INITDIALOG:
867 pgContext = (PGINA_CONTEXT)lParam;
868 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
869
870 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
871
872 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
873 SetFocus(GetDlgItem(hwndDlg, IDC_PASSWORD));
874
875 if (pgContext->bDisableCAD == TRUE)
876 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
877
878 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
879 return TRUE;
880
881 case WM_PAINT:
882 {
883 PAINTSTRUCT ps;
884 HDC hdc;
885 if (pgContext->hBitmap)
886 {
887 hdc = BeginPaint(hwndDlg, &ps);
888 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
889 EndPaint(hwndDlg, &ps);
890 }
891 return TRUE;
892 }
893 case WM_DESTROY:
894 DeleteObject(pgContext->hBitmap);
895 return TRUE;
896
897 case WM_COMMAND:
898 switch (LOWORD(wParam))
899 {
900 case IDOK:
901 if (DoUnlock(hwndDlg, pgContext, &result))
902 EndDialog(hwndDlg, result);
903 return TRUE;
904
905 case IDCANCEL:
906 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
907 return TRUE;
908 }
909 break;
910 }
911
912 return FALSE;
913 }
914
915
916 static INT
917 GUILockedSAS(
918 IN OUT PGINA_CONTEXT pgContext)
919 {
920 int result;
921
922 TRACE("GUILockedSAS()\n");
923
924 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
925 pgContext->hWlx,
926 pgContext->hDllInstance,
927 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
928 GetDesktopWindow(),
929 UnlockWindowProc,
930 (LPARAM)pgContext);
931 if (result >= WLX_SAS_ACTION_LOGON &&
932 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
933 {
934 WARN("GUILockedSAS() returns 0x%x\n", result);
935 return result;
936 }
937
938 WARN("GUILockedSAS() failed (0x%x)\n", result);
939 return WLX_SAS_ACTION_NONE;
940 }
941
942
943 static INT_PTR CALLBACK
944 LockedWindowProc(
945 IN HWND hwndDlg,
946 IN UINT uMsg,
947 IN WPARAM wParam,
948 IN LPARAM lParam)
949 {
950 PGINA_CONTEXT pgContext;
951
952 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
953
954 switch (uMsg)
955 {
956 case WM_INITDIALOG:
957 {
958 pgContext = (PGINA_CONTEXT)lParam;
959 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
960
961 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
962 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
963 return TRUE;
964 }
965 case WM_PAINT:
966 {
967 PAINTSTRUCT ps;
968 HDC hdc;
969 if (pgContext->hBitmap)
970 {
971 hdc = BeginPaint(hwndDlg, &ps);
972 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
973 EndPaint(hwndDlg, &ps);
974 }
975 return TRUE;
976 }
977 case WM_DESTROY:
978 {
979 DeleteObject(pgContext->hBitmap);
980 return TRUE;
981 }
982 }
983
984 return FALSE;
985 }
986
987
988 static VOID
989 GUIDisplayLockedNotice(
990 IN OUT PGINA_CONTEXT pgContext)
991 {
992 TRACE("GUIdisplayLockedNotice()\n");
993
994 pgContext->pWlxFuncs->WlxDialogBoxParam(
995 pgContext->hWlx,
996 pgContext->hDllInstance,
997 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
998 GetDesktopWindow(),
999 LockedWindowProc,
1000 (LPARAM)pgContext);
1001 }
1002
1003 GINA_UI GinaGraphicalUI = {
1004 GUIInitialize,
1005 GUIDisplayStatusMessage,
1006 GUIRemoveStatusMessage,
1007 GUIDisplaySASNotice,
1008 GUILoggedOnSAS,
1009 GUILoggedOutSAS,
1010 GUILockedSAS,
1011 GUIDisplayLockedNotice,
1012 };