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)
14 typedef struct _DISPLAYSTATUSMSG
16 PGINA_CONTEXT Context
;
22 } DISPLAYSTATUSMSG
, *PDISPLAYSTATUSMSG
;
24 typedef struct _LEGALNOTICEDATA
28 } LEGALNOTICEDATA
, *PLEGALNOTICEDATA
;
33 IN OUT PGINA_CONTEXT pgContext
)
35 TRACE("GUIInitialize(%p)\n", pgContext
);
39 static INT_PTR CALLBACK
40 StatusMessageWindowProc(
46 UNREFERENCED_PARAMETER(wParam
);
52 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
56 msg
->Context
->hStatusWindow
= hwndDlg
;
59 SetWindowTextW(hwndDlg
, msg
->pTitle
);
60 SetDlgItemTextW(hwndDlg
, IDC_STATUSLABEL
, msg
->pMessage
);
61 SetEvent(msg
->StartupEvent
);
69 StartupWindowThread(LPVOID lpParam
)
72 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
74 /* When SetThreadDesktop is called the system closes the desktop handle when needed
75 so we have to create a new handle because this handle may still be in use by winlogon */
76 if (!DuplicateHandle ( GetCurrentProcess(),
82 DUPLICATE_SAME_ACCESS
))
84 ERR("Duplicating handle failed!\n");
85 HeapFree(GetProcessHeap(), 0, lpParam
);
89 if(!SetThreadDesktop(hDesk
))
91 ERR("Setting thread desktop failed!\n");
92 HeapFree(GetProcessHeap(), 0, lpParam
);
98 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG
),
100 StatusMessageWindowProc
,
103 HeapFree(GetProcessHeap(), 0, lpParam
);
108 GUIDisplayStatusMessage(
109 IN PGINA_CONTEXT pgContext
,
115 PDISPLAYSTATUSMSG msg
;
119 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage
);
121 if (!pgContext
->hStatusWindow
)
124 * If everything goes correctly, 'msg' is freed
125 * by the 'StartupWindowThread' thread.
127 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(),
129 sizeof(DISPLAYSTATUSMSG
));
133 msg
->Context
= pgContext
;
134 msg
->dwOptions
= dwOptions
;
135 msg
->pTitle
= pTitle
;
136 msg
->pMessage
= pMessage
;
137 msg
->hDesktop
= hDesktop
;
139 msg
->StartupEvent
= CreateEventW(NULL
,
144 if (!msg
->StartupEvent
)
146 HeapFree(GetProcessHeap(), 0, msg
);
150 Thread
= CreateThread(NULL
,
158 /* 'msg' will be freed by 'StartupWindowThread' */
161 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
162 CloseHandle(msg
->StartupEvent
);
168 * The 'StartupWindowThread' thread couldn't be created,
169 * so we need to free the allocated 'msg'.
171 HeapFree(GetProcessHeap(), 0, msg
);
178 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
180 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUSLABEL
, pMessage
);
186 GUIRemoveStatusMessage(
187 IN PGINA_CONTEXT pgContext
)
189 if (pgContext
->hStatusWindow
)
191 EndDialog(pgContext
->hStatusWindow
, 0);
192 pgContext
->hStatusWindow
= NULL
;
198 static INT_PTR CALLBACK
205 PGINA_CONTEXT pgContext
;
207 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
213 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
219 if (pgContext
->hBitmap
)
221 hdc
= BeginPaint(hwndDlg
, &ps
);
222 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
223 EndPaint(hwndDlg
, &ps
);
229 DeleteObject(pgContext
->hBitmap
);
238 IN OUT PGINA_CONTEXT pgContext
)
240 TRACE("GUIDisplaySASNotice()\n");
242 /* Display the notice window */
243 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
244 pgContext
->hDllInstance
,
245 MAKEINTRESOURCEW(IDD_NOTICE_DLG
),
251 /* Get the text contained in a textbox. Allocates memory in pText
252 * to contain the text. Returns TRUE in case of success */
262 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
263 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
266 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
268 HeapFree(GetProcessHeap(), 0, Text
);
279 IN PGINA_CONTEXT pgContext
,
285 WCHAR szCaption
[256];
288 LoadStringW(pgContext
->hDllInstance
, uCaption
, szCaption
, 256);
289 LoadStringW(pgContext
->hDllInstance
, uText
, szText
, 256);
291 return pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
302 IN PGINA_CONTEXT pgContext
,
307 WCHAR OldPassword
[256];
308 WCHAR NewPassword1
[256];
309 WCHAR NewPassword2
[256];
310 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
311 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
312 ULONG RequestBufferSize
;
313 ULONG ResponseBufferSize
= 0;
316 NTSTATUS ProtocolStatus
;
319 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, UserName
, 256);
320 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, Domain
, 256);
321 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_OLDPWD
, OldPassword
, 256);
322 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NewPassword1
, 256);
323 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NewPassword2
, 256);
325 /* Compare the two passwords and fail if they do not match */
326 if (wcscmp(NewPassword1
, NewPassword2
) != 0)
328 ResourceMessageBox(pgContext
,
330 MB_OK
| MB_ICONEXCLAMATION
,
332 IDS_NONMATCHINGPASSWORDS
);
336 /* Calculate the request buffer size */
337 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
338 ((wcslen(Domain
) + 1) * sizeof(WCHAR
)) +
339 ((wcslen(UserName
) + 1) * sizeof(WCHAR
)) +
340 ((wcslen(OldPassword
) + 1) * sizeof(WCHAR
)) +
341 ((wcslen(NewPassword1
) + 1) * sizeof(WCHAR
));
343 /* Allocate the request buffer */
344 RequestBuffer
= HeapAlloc(GetProcessHeap(),
347 if (RequestBuffer
== NULL
)
349 ERR("HeapAlloc failed\n");
353 /* Initialize the request buffer */
354 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
355 RequestBuffer
->Impersonating
= TRUE
;
357 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
359 /* Pack the domain name */
360 RequestBuffer
->DomainName
.Length
= wcslen(Domain
) * sizeof(WCHAR
);
361 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
362 RequestBuffer
->DomainName
.Buffer
= Ptr
;
364 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
366 RequestBuffer
->DomainName
.MaximumLength
);
368 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
370 /* Pack the user name */
371 RequestBuffer
->AccountName
.Length
= wcslen(UserName
) * sizeof(WCHAR
);
372 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
373 RequestBuffer
->AccountName
.Buffer
= Ptr
;
375 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
377 RequestBuffer
->AccountName
.MaximumLength
);
379 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
381 /* Pack the old password */
382 RequestBuffer
->OldPassword
.Length
= wcslen(OldPassword
) * sizeof(WCHAR
);
383 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
384 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
386 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
388 RequestBuffer
->OldPassword
.MaximumLength
);
390 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
392 /* Pack the new password */
393 RequestBuffer
->NewPassword
.Length
= wcslen(NewPassword1
) * sizeof(WCHAR
);
394 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
395 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
397 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
399 RequestBuffer
->NewPassword
.MaximumLength
);
401 /* Connect to the LSA server */
402 if (!ConnectToLsa(pgContext
))
404 ERR("ConnectToLsa() failed\n");
408 /* Call the authentication package */
409 Status
= LsaCallAuthenticationPackage(pgContext
->LsaHandle
,
410 pgContext
->AuthenticationPackage
,
413 (PVOID
*)&ResponseBuffer
,
416 if (!NT_SUCCESS(Status
))
418 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status
);
422 if (!NT_SUCCESS(ProtocolStatus
))
424 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus
);
430 ResourceMessageBox(pgContext
,
432 MB_OK
| MB_ICONINFORMATION
,
434 IDS_PASSWORDCHANGED
);
436 if ((wcscmp(UserName
, pgContext
->UserName
) == 0) &&
437 (wcscmp(Domain
, pgContext
->Domain
) == 0) &&
438 (wcscmp(OldPassword
, pgContext
->Password
) == 0))
440 ZeroMemory(pgContext
->Password
, 256 * sizeof(WCHAR
));
441 wcscpy(pgContext
->Password
, NewPassword1
);
445 if (RequestBuffer
!= NULL
)
446 HeapFree(GetProcessHeap(), 0, RequestBuffer
);
448 if (ResponseBuffer
!= NULL
)
449 LsaFreeReturnBuffer(ResponseBuffer
);
455 static INT_PTR CALLBACK
456 ChangePasswordDialogProc(
462 PGINA_CONTEXT pgContext
;
464 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
469 pgContext
= (PGINA_CONTEXT
)lParam
;
470 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
472 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, pgContext
->UserName
);
473 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->Domain
);
474 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_SETCURSEL
, 0, 0);
475 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
479 switch (LOWORD(wParam
))
482 if (DoChangePassword(pgContext
, hwndDlg
))
484 EndDialog(hwndDlg
, TRUE
);
488 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NULL
);
489 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NULL
);
490 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
495 EndDialog(hwndDlg
, FALSE
);
501 EndDialog(hwndDlg
, FALSE
);
510 OnInitSecurityDlg(HWND hwnd
,
511 PGINA_CONTEXT pgContext
)
518 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, 256);
520 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
521 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
523 SetDlgItemTextW(hwnd
, IDC_LOGONMSG
, Buffer4
);
525 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, 256);
527 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
528 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, 256);
530 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
531 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, 256);
533 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
535 SetDlgItemTextW(hwnd
, IDC_LOGONDATE
, Buffer4
);
537 if (pgContext
->bAutoAdminLogon
== TRUE
)
538 EnableWindow(GetDlgItem(hwnd
, IDC_LOGOFF
), FALSE
);
545 IN PGINA_CONTEXT pgContext
)
549 TRACE("OnChangePassword()\n");
551 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
553 pgContext
->hDllInstance
,
554 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD
),
556 ChangePasswordDialogProc
,
559 TRACE("Result: %x\n", res
);
565 static INT_PTR CALLBACK
578 switch (LOWORD(wParam
))
581 EndDialog(hwndDlg
, IDYES
);
585 EndDialog(hwndDlg
, IDNO
);
591 EndDialog(hwndDlg
, IDNO
);
603 IN PGINA_CONTEXT pgContext
)
605 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
607 pgContext
->hDllInstance
,
608 MAKEINTRESOURCEW(IDD_LOGOFF_DLG
),
621 UINT shutdownDescId
= 0;
622 int shutdownCode
= 0;
624 shutdownCode
= SendDlgItemMessageW(hwnd
, IDC_SHUTDOWN_LIST
, CB_GETCURSEL
, 0, 0);
626 switch (shutdownCode
)
628 case 0: /* Log off */
629 shutdownDescId
= IDS_SHUTDOWN_LOGOFF_DESC
;
632 case 1: /* Shut down */
633 shutdownDescId
= IDS_SHUTDOWN_SHUTDOWN_DESC
;
636 case 2: /* Restart */
637 shutdownDescId
= IDS_SHUTDOWN_RESTART_DESC
;
641 shutdownDescId
= IDS_SHUTDOWN_SLEEP_DESC
;
644 case 4: /* Hibernate */
645 shutdownDescId
= IDS_SHUTDOWN_HIBERNATE_DESC
;
652 LoadStringW(hDllInstance
, shutdownDescId
, szBuffer
, sizeof(szBuffer
));
653 SetDlgItemTextW(hwnd
, IDC_SHUTDOWN_DESCRIPTION
, szBuffer
);
661 IN PGINA_CONTEXT pgContext
)
664 WCHAR szBuffer2
[256];
668 hwndList
= GetDlgItem(hwndDlg
, IDC_SHUTDOWN_LIST
);
670 /* Clears the content before it's used */
671 SendMessageW(hwndList
, CB_RESETCONTENT
, 0, 0);
674 LoadStringW(hDllInstance
, IDS_SHUTDOWN_LOGOFF
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
675 wsprintfW(szBuffer2
, szBuffer
, pgContext
->UserName
);
676 idx
= SendMessageW(hwndList
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer2
);
678 SendMessageW(hwndList
, CB_SETITEMDATA
, idx
, WLX_SAS_ACTION_LOGOFF
);
681 LoadStringW(hDllInstance
, IDS_SHUTDOWN_SHUTDOWN
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
682 idx
= SendMessageW(hwndList
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
684 SendMessageW(hwndList
, CB_SETITEMDATA
, idx
, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
);
687 LoadStringW(hDllInstance
, IDS_SHUTDOWN_RESTART
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
688 idx
= SendMessageW(hwndList
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
690 SendMessageW(hwndList
, CB_SETITEMDATA
, idx
, WLX_SAS_ACTION_SHUTDOWN_REBOOT
);
694 LoadStringW(hDllInstance
, IDS_SHUTDOWN_SLEEP
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
695 idx
= SendMessageW(hwndList
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
697 SendMessageW(hwndList
, CB_SETITEMDATA
, idx
, WLX_SAS_ACTION_SHUTDOWN_SLEEP
);
702 LoadStringW(hDllInstance
, IDS_SHUTDOWN_HIBERNATE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
703 idx
= SendMessageW(hwndList
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
705 SendMessageW(hwndList
, CB_SETITEMDATA
, idx
, WLX_SAS_ACTION_SHUTDOWN_HIBERNATE
);
708 /* Sets the default shut down selection */
709 count
= SendMessageW(hwndList
, CB_GETCOUNT
, 0, 0);
710 for (i
= 0; i
< count
; i
++)
712 if (pgContext
->nShutdownAction
== SendMessageW(hwndList
, CB_GETITEMDATA
, i
, 0))
714 SendMessageW(hwndList
, CB_SETCURSEL
, i
, 0);
719 /* Updates the choice description based on the current selection */
720 UpdateShutdownDesc(hwndDlg
);
728 IN PGINA_CONTEXT pgContext
)
732 idx
= SendDlgItemMessageW(hwndDlg
,
739 pgContext
->nShutdownAction
= SendDlgItemMessageW(hwndDlg
,
756 PGINA_CONTEXT pgContext
;
758 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwnd
, GWL_USERDATA
);
763 pgContext
= (PGINA_CONTEXT
)lParam
;
764 SetWindowLongPtr(hwnd
, GWL_USERDATA
, (INT_PTR
)pgContext
);
766 ShutDownOnInit(hwnd
, pgContext
);
768 /* Draw the logo graphic */
769 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
776 if (pgContext
->hBitmap
)
778 hdc
= BeginPaint(hwnd
, &ps
);
779 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
786 DeleteObject(pgContext
->hBitmap
);
790 switch(LOWORD(wParam
))
793 ShutDownOnOk(hwnd
, pgContext
);
794 EndDialog(hwnd
, IDOK
);
798 EndDialog(hwnd
, IDCANCEL
);
801 case IDC_SHUTDOWN_LIST
:
802 UpdateShutdownDesc(hwnd
);
818 IN PGINA_CONTEXT pgContext
)
820 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
822 pgContext
->hDllInstance
,
823 MAKEINTRESOURCEW(IDD_SHUTDOWN_DLG
),
830 static INT_PTR CALLBACK
837 PGINA_CONTEXT pgContext
;
839 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
845 pgContext
= (PGINA_CONTEXT
)lParam
;
846 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
848 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
849 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
855 switch (LOWORD(wParam
))
858 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
861 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
862 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
865 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
866 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
869 if (OnChangePassword(hwndDlg
, pgContext
))
870 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
873 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
876 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
883 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
893 IN OUT PGINA_CONTEXT pgContext
,
898 TRACE("GUILoggedOnSAS()\n");
900 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
902 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
903 * close itself thanks to the use of WlxDialogBoxParam */
904 return WLX_SAS_ACTION_NONE
;
907 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
910 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
912 pgContext
->hDllInstance
,
913 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG
),
918 if (result
< WLX_SAS_ACTION_LOGON
||
919 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
921 result
= WLX_SAS_ACTION_NONE
;
924 if (result
== WLX_SAS_ACTION_NONE
)
926 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
938 IN OUT PGINA_CONTEXT pgContext
)
940 LPWSTR UserName
= NULL
;
941 LPWSTR Password
= NULL
;
942 LPWSTR Domain
= NULL
;
944 NTSTATUS Status
, SubStatus
= STATUS_SUCCESS
;
946 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
949 if (GetTextboxText(hwndDlg
, IDC_LOGON_TO
, &Domain
) && *Domain
== '\0')
952 if (!GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
955 Status
= DoLoginTasks(pgContext
, UserName
, Domain
, Password
, &SubStatus
);
956 if (Status
== STATUS_LOGON_FAILURE
)
958 ResourceMessageBox(pgContext
,
960 MB_OK
| MB_ICONEXCLAMATION
,
962 IDS_LOGONWRONGUSERORPWD
);
965 else if (Status
== STATUS_ACCOUNT_RESTRICTION
)
967 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status
, SubStatus
);
969 if (SubStatus
== STATUS_ACCOUNT_DISABLED
)
971 ResourceMessageBox(pgContext
,
973 MB_OK
| MB_ICONEXCLAMATION
,
975 IDS_LOGONUSERDISABLED
);
978 else if (SubStatus
== STATUS_ACCOUNT_LOCKED_OUT
)
980 TRACE("Account locked!\n");
981 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
985 MB_OK
| MB_ICONERROR
);
988 else if ((SubStatus
== STATUS_PASSWORD_MUST_CHANGE
) ||
989 (SubStatus
== STATUS_PASSWORD_EXPIRED
))
991 if (SubStatus
== STATUS_PASSWORD_MUST_CHANGE
)
992 ResourceMessageBox(pgContext
,
996 IDS_PASSWORDMUSTCHANGE
);
998 ResourceMessageBox(pgContext
,
1000 MB_OK
| MB_ICONSTOP
,
1002 IDS_PASSWORDEXPIRED
);
1004 if (!OnChangePassword(hwndDlg
,
1008 Status
= DoLoginTasks(pgContext
,
1009 pgContext
->UserName
,
1011 pgContext
->Password
,
1013 if (!NT_SUCCESS(Status
))
1015 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status
);
1022 TRACE("Other error!\n");
1023 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
1027 MB_OK
| MB_ICONERROR
);
1031 else if (!NT_SUCCESS(Status
))
1033 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
1039 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
1041 ERR("Failed to create the profile!\n");
1045 ZeroMemory(pgContext
->Password
, 256 * sizeof(WCHAR
));
1046 wcscpy(pgContext
->Password
, Password
);
1051 if (UserName
!= NULL
)
1052 HeapFree(GetProcessHeap(), 0, UserName
);
1054 if (Password
!= NULL
)
1055 HeapFree(GetProcessHeap(), 0, Password
);
1058 HeapFree(GetProcessHeap(), 0, Domain
);
1067 HWND hwndDomainComboBox
,
1068 PGINA_CONTEXT pgContext
)
1070 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1071 DWORD dwComputerNameLength
;
1075 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
1077 dwComputerNameLength
= sizeof(szComputerName
) / sizeof(WCHAR
);
1078 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
1080 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
1083 if (wcslen(pgContext
->Domain
) != 0)
1085 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->Domain
);
1086 if (lFindIndex
== CB_ERR
)
1088 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->Domain
);
1092 lIndex
= lFindIndex
;
1096 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
1100 static INT_PTR CALLBACK
1101 LoggedOutWindowProc(
1107 PGINA_CONTEXT pgContext
;
1109 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1114 /* FIXME: take care of NoDomainUI */
1115 pgContext
= (PGINA_CONTEXT
)lParam
;
1116 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
1118 if (pgContext
->bDontDisplayLastUserName
== FALSE
)
1119 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
1121 if (pgContext
->bDisableCAD
== TRUE
)
1122 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1124 if (pgContext
->bShutdownWithoutLogon
== FALSE
)
1125 EnableWindow(GetDlgItem(hwndDlg
, IDC_SHUTDOWN
), FALSE
);
1127 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_TO
), pgContext
);
1129 SetFocus(GetDlgItem(hwndDlg
, pgContext
->bDontDisplayLastUserName
? IDC_USERNAME
: IDC_PASSWORD
));
1131 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1138 if (pgContext
->hBitmap
)
1140 hdc
= BeginPaint(hwndDlg
, &ps
);
1141 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1142 EndPaint(hwndDlg
, &ps
);
1148 DeleteObject(pgContext
->hBitmap
);
1152 switch (LOWORD(wParam
))
1155 if (DoLogon(hwndDlg
, pgContext
))
1156 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1160 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1164 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
1165 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
1178 LegalNoticeDialogProc(
1184 PLEGALNOTICEDATA pLegalNotice
;
1189 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1190 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1191 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1195 switch (LOWORD(wParam
))
1198 EndDialog(hwndDlg
, 0);
1202 EndDialog(hwndDlg
, 0);
1214 IN OUT PGINA_CONTEXT pgContext
)
1216 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1221 TRACE("GUILoggedOutSAS()\n");
1223 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1224 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1228 if (rc
== ERROR_SUCCESS
)
1230 ReadRegSzValue(hKey
,
1231 L
"LegalNoticeCaption",
1232 &LegalNotice
.pszCaption
);
1234 ReadRegSzValue(hKey
,
1236 &LegalNotice
.pszText
);
1241 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1242 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1244 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1245 pgContext
->hDllInstance
,
1246 MAKEINTRESOURCEW(IDD_LEGALNOTICE_DLG
),
1248 LegalNoticeDialogProc
,
1249 (LPARAM
)&LegalNotice
);
1252 if (LegalNotice
.pszCaption
!= NULL
)
1253 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1255 if (LegalNotice
.pszText
!= NULL
)
1256 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1258 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1260 pgContext
->hDllInstance
,
1261 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG
),
1263 LoggedOutWindowProc
,
1265 if (result
>= WLX_SAS_ACTION_LOGON
&&
1266 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1268 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1272 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1273 return WLX_SAS_ACTION_NONE
;
1278 SetLockMessage(HWND hwnd
,
1280 PGINA_CONTEXT pgContext
)
1286 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, 256);
1288 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
1289 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1291 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1299 IN PGINA_CONTEXT pgContext
,
1304 LPWSTR UserName
= NULL
;
1305 LPWSTR Password
= NULL
;
1308 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
1310 HeapFree(GetProcessHeap(), 0, UserName
);
1314 if (GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
1316 if (UserName
!= NULL
&& Password
!= NULL
&&
1317 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1318 wcscmp(Password
, pgContext
->Password
) == 0)
1320 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1323 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1324 wcscmp(Password
, pgContext
->Password
) != 0)
1326 /* Wrong Password */
1327 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, 256);
1328 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, 256);
1329 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1333 /* Wrong user name */
1334 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1336 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1341 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, 256);
1342 wsprintfW(Buffer2
, Buffer1
, pgContext
->Domain
, pgContext
->UserName
);
1343 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, 256);
1344 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1349 if (UserName
!= NULL
)
1350 HeapFree(GetProcessHeap(), 0, UserName
);
1352 if (Password
!= NULL
)
1353 HeapFree(GetProcessHeap(), 0, Password
);
1368 PGINA_CONTEXT pgContext
;
1369 INT result
= WLX_SAS_ACTION_NONE
;
1371 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1376 pgContext
= (PGINA_CONTEXT
)lParam
;
1377 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
1379 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1381 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
1382 SetFocus(GetDlgItem(hwndDlg
, IDC_PASSWORD
));
1384 if (pgContext
->bDisableCAD
== TRUE
)
1385 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1387 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1394 if (pgContext
->hBitmap
)
1396 hdc
= BeginPaint(hwndDlg
, &ps
);
1397 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1398 EndPaint(hwndDlg
, &ps
);
1403 DeleteObject(pgContext
->hBitmap
);
1407 switch (LOWORD(wParam
))
1410 if (DoUnlock(hwndDlg
, pgContext
, &result
))
1411 EndDialog(hwndDlg
, result
);
1415 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1427 IN OUT PGINA_CONTEXT pgContext
)
1431 TRACE("GUILockedSAS()\n");
1433 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1435 pgContext
->hDllInstance
,
1436 MAKEINTRESOURCEW(IDD_UNLOCK_DLG
),
1440 if (result
>= WLX_SAS_ACTION_LOGON
&&
1441 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1443 WARN("GUILockedSAS() returns 0x%x\n", result
);
1447 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1448 return WLX_SAS_ACTION_NONE
;
1452 static INT_PTR CALLBACK
1459 PGINA_CONTEXT pgContext
;
1461 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
1467 pgContext
= (PGINA_CONTEXT
)lParam
;
1468 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
1470 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1471 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1478 if (pgContext
->hBitmap
)
1480 hdc
= BeginPaint(hwndDlg
, &ps
);
1481 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1482 EndPaint(hwndDlg
, &ps
);
1488 DeleteObject(pgContext
->hBitmap
);
1498 GUIDisplayLockedNotice(
1499 IN OUT PGINA_CONTEXT pgContext
)
1501 TRACE("GUIdisplayLockedNotice()\n");
1503 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1505 pgContext
->hDllInstance
,
1506 MAKEINTRESOURCEW(IDD_LOCKED_DLG
),
1512 GINA_UI GinaGraphicalUI
= {
1514 GUIDisplayStatusMessage
,
1515 GUIRemoveStatusMessage
,
1516 GUIDisplaySASNotice
,
1520 GUIDisplayLockedNotice
,