[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 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 SendDlgItemMessageW(hwndDlg, IDC_LOGON_TO, CB_ADDSTRING, 0, (LPARAM)pgContext->Domain);
711 SendDlgItemMessageW(hwndDlg, IDC_LOGON_TO, CB_SETCURSEL, 0, 0);
712
713 SetFocus(GetDlgItem(hwndDlg, pgContext->bDontDisplayLastUserName ? IDC_USERNAME : IDC_PASSWORD));
714
715 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
716 return TRUE;
717 }
718 case WM_PAINT:
719 {
720 PAINTSTRUCT ps;
721 HDC hdc;
722 if (pgContext->hBitmap)
723 {
724 hdc = BeginPaint(hwndDlg, &ps);
725 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
726 EndPaint(hwndDlg, &ps);
727 }
728 return TRUE;
729 }
730 case WM_DESTROY:
731 {
732 DeleteObject(pgContext->hBitmap);
733 return TRUE;
734 }
735 case WM_COMMAND:
736 {
737 switch (LOWORD(wParam))
738 {
739 case IDOK:
740 {
741 LPWSTR UserName = NULL, Password = NULL, Domain = NULL;
742 INT result = WLX_SAS_ACTION_NONE;
743
744 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
745 break;
746 if (GetTextboxText(hwndDlg, IDC_LOGON_TO, &Domain) && *Domain == '\0')
747 break;
748 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) &&
749 DoLoginTasks(pgContext, UserName, Domain, Password))
750 {
751 pgContext->Password = HeapAlloc(GetProcessHeap(),
752 HEAP_ZERO_MEMORY,
753 (wcslen(Password) + 1) * sizeof(WCHAR));
754 if (pgContext->Password != NULL)
755 wcscpy(pgContext->Password, Password);
756
757 result = WLX_SAS_ACTION_LOGON;
758 }
759 HeapFree(GetProcessHeap(), 0, UserName);
760 HeapFree(GetProcessHeap(), 0, Password);
761 HeapFree(GetProcessHeap(), 0, Domain);
762 EndDialog(hwndDlg, result);
763 return TRUE;
764 }
765 case IDCANCEL:
766 {
767 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
768 return TRUE;
769 }
770 case IDC_SHUTDOWN:
771 {
772 EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN);
773 return TRUE;
774 }
775 }
776 break;
777 }
778 }
779
780 return FALSE;
781 }
782
783 static INT
784 GUILoggedOutSAS(
785 IN OUT PGINA_CONTEXT pgContext)
786 {
787 int result;
788
789 TRACE("GUILoggedOutSAS()\n");
790
791 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
792 pgContext->hWlx,
793 pgContext->hDllInstance,
794 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG),
795 GetDesktopWindow(),
796 LoggedOutWindowProc,
797 (LPARAM)pgContext);
798 if (result >= WLX_SAS_ACTION_LOGON &&
799 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
800 {
801 WARN("WlxLoggedOutSAS() returns 0x%x\n", result);
802 return result;
803 }
804
805 WARN("WlxDialogBoxParam() failed (0x%x)\n", result);
806 return WLX_SAS_ACTION_NONE;
807 }
808
809
810 static VOID
811 SetLockMessage(HWND hwnd,
812 INT nDlgItem,
813 PGINA_CONTEXT pgContext)
814 {
815 WCHAR Buffer1[256];
816 WCHAR Buffer2[256];
817 WCHAR Buffer3[512];
818
819 LoadStringW(pgContext->hDllInstance, IDS_LOCKMSG, Buffer1, 256);
820
821 wsprintfW(Buffer2, L"%s\\%s", pgContext->Domain, pgContext->UserName);
822 wsprintfW(Buffer3, Buffer1, Buffer2);
823
824 SetDlgItemTextW(hwnd, nDlgItem, Buffer3);
825 }
826
827
828 static
829 BOOL
830 DoUnlock(
831 IN HWND hwndDlg,
832 IN PGINA_CONTEXT pgContext,
833 OUT LPINT Action)
834 {
835 WCHAR Buffer1[256];
836 WCHAR Buffer2[256];
837 LPWSTR UserName = NULL;
838 LPWSTR Password = NULL;
839 BOOL res = FALSE;
840
841 if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0')
842 return FALSE;
843
844 if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password))
845 {
846 if (UserName != NULL && Password != NULL &&
847 wcscmp(UserName, pgContext->UserName) == 0 &&
848 wcscmp(Password, pgContext->Password) == 0)
849 {
850 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
851 res = TRUE;
852 }
853 else if (wcscmp(UserName, pgContext->UserName) == 0 &&
854 wcscmp(Password, pgContext->Password) != 0)
855 {
856 /* Wrong Password */
857 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGPASSWORD, Buffer2, 256);
858 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
859 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
860 }
861 else
862 {
863 /* Wrong user name */
864 if (DoAdminUnlock(pgContext, UserName, NULL, Password))
865 {
866 *Action = WLX_SAS_ACTION_UNLOCK_WKSTA;
867 res = TRUE;
868 }
869 else
870 {
871 LoadStringW(pgContext->hDllInstance, IDS_LOCKEDWRONGUSER, Buffer1, 256);
872 wsprintfW(Buffer2, Buffer1, pgContext->Domain, pgContext->UserName);
873 LoadStringW(pgContext->hDllInstance, IDS_COMPUTERLOCKED, Buffer1, 256);
874 MessageBoxW(hwndDlg, Buffer2, Buffer1, MB_OK | MB_ICONERROR);
875 }
876 }
877 }
878
879 if (UserName != NULL)
880 HeapFree(GetProcessHeap(), 0, UserName);
881
882 if (Password != NULL)
883 HeapFree(GetProcessHeap(), 0, Password);
884
885 return res;
886 }
887
888
889 static
890 INT_PTR
891 CALLBACK
892 UnlockWindowProc(
893 IN HWND hwndDlg,
894 IN UINT uMsg,
895 IN WPARAM wParam,
896 IN LPARAM lParam)
897 {
898 PGINA_CONTEXT pgContext;
899 INT result = WLX_SAS_ACTION_NONE;
900
901 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
902
903 switch (uMsg)
904 {
905 case WM_INITDIALOG:
906 pgContext = (PGINA_CONTEXT)lParam;
907 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
908
909 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
910
911 SetDlgItemTextW(hwndDlg, IDC_USERNAME, pgContext->UserName);
912 SetFocus(GetDlgItem(hwndDlg, IDC_PASSWORD));
913
914 if (pgContext->bDisableCAD == TRUE)
915 EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
916
917 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
918 return TRUE;
919
920 case WM_PAINT:
921 {
922 PAINTSTRUCT ps;
923 HDC hdc;
924 if (pgContext->hBitmap)
925 {
926 hdc = BeginPaint(hwndDlg, &ps);
927 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
928 EndPaint(hwndDlg, &ps);
929 }
930 return TRUE;
931 }
932 case WM_DESTROY:
933 DeleteObject(pgContext->hBitmap);
934 return TRUE;
935
936 case WM_COMMAND:
937 switch (LOWORD(wParam))
938 {
939 case IDOK:
940 if (DoUnlock(hwndDlg, pgContext, &result))
941 EndDialog(hwndDlg, result);
942 return TRUE;
943
944 case IDCANCEL:
945 EndDialog(hwndDlg, WLX_SAS_ACTION_NONE);
946 return TRUE;
947 }
948 break;
949 }
950
951 return FALSE;
952 }
953
954
955 static INT
956 GUILockedSAS(
957 IN OUT PGINA_CONTEXT pgContext)
958 {
959 int result;
960
961 TRACE("GUILockedSAS()\n");
962
963 result = pgContext->pWlxFuncs->WlxDialogBoxParam(
964 pgContext->hWlx,
965 pgContext->hDllInstance,
966 MAKEINTRESOURCEW(IDD_UNLOCK_DLG),
967 GetDesktopWindow(),
968 UnlockWindowProc,
969 (LPARAM)pgContext);
970 if (result >= WLX_SAS_ACTION_LOGON &&
971 result <= WLX_SAS_ACTION_SWITCH_CONSOLE)
972 {
973 WARN("GUILockedSAS() returns 0x%x\n", result);
974 return result;
975 }
976
977 WARN("GUILockedSAS() failed (0x%x)\n", result);
978 return WLX_SAS_ACTION_NONE;
979 }
980
981
982 static INT_PTR CALLBACK
983 LockedWindowProc(
984 IN HWND hwndDlg,
985 IN UINT uMsg,
986 IN WPARAM wParam,
987 IN LPARAM lParam)
988 {
989 PGINA_CONTEXT pgContext;
990
991 pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
992
993 switch (uMsg)
994 {
995 case WM_INITDIALOG:
996 {
997 pgContext = (PGINA_CONTEXT)lParam;
998 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext);
999
1000 pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
1001 SetLockMessage(hwndDlg, IDC_LOCKMSG, pgContext);
1002 return TRUE;
1003 }
1004 case WM_PAINT:
1005 {
1006 PAINTSTRUCT ps;
1007 HDC hdc;
1008 if (pgContext->hBitmap)
1009 {
1010 hdc = BeginPaint(hwndDlg, &ps);
1011 DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP);
1012 EndPaint(hwndDlg, &ps);
1013 }
1014 return TRUE;
1015 }
1016 case WM_DESTROY:
1017 {
1018 DeleteObject(pgContext->hBitmap);
1019 return TRUE;
1020 }
1021 }
1022
1023 return FALSE;
1024 }
1025
1026
1027 static VOID
1028 GUIDisplayLockedNotice(
1029 IN OUT PGINA_CONTEXT pgContext)
1030 {
1031 TRACE("GUIdisplayLockedNotice()\n");
1032
1033 pgContext->pWlxFuncs->WlxDialogBoxParam(
1034 pgContext->hWlx,
1035 pgContext->hDllInstance,
1036 MAKEINTRESOURCEW(IDD_LOCKED_DLG),
1037 GetDesktopWindow(),
1038 LockedWindowProc,
1039 (LPARAM)pgContext);
1040 }
1041
1042 GINA_UI GinaGraphicalUI = {
1043 GUIInitialize,
1044 GUIDisplayStatusMessage,
1045 GUIRemoveStatusMessage,
1046 GUIDisplaySASNotice,
1047 GUILoggedOnSAS,
1048 GUILoggedOutSAS,
1049 GUILockedSAS,
1050 GUIDisplayLockedNotice,
1051 };