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