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