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
;
30 typedef struct _DLG_DATA
32 PGINA_CONTEXT pgContext
;
34 } DLG_DATA
, *PDLG_DATA
;
38 IN OUT PGINA_CONTEXT pgContext
)
40 TRACE("GUIInitialize(%p)\n", pgContext
);
47 SetWelcomeText(HWND hWnd
)
49 PWCHAR pBuffer
= NULL
, p
;
51 DWORD BufSize
, dwType
, dwWelcomeSize
, dwTitleLength
;
54 TRACE("SetWelcomeText(%p)\n", hWnd
);
56 /* Open the Winlogon key */
57 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
58 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
62 if (rc
!= ERROR_SUCCESS
)
64 WARN("RegOpenKeyExW() failed with error %lu\n", rc
);
68 /* Get the size of the Welcome value */
70 rc
= RegQueryValueExW(hKey
,
76 if (rc
== ERROR_FILE_NOT_FOUND
|| dwWelcomeSize
== 0 || dwType
!= REG_SZ
)
79 dwTitleLength
= GetWindowTextLengthW(hWnd
);
80 BufSize
= dwWelcomeSize
+ ((dwTitleLength
+ 1) * sizeof(WCHAR
));
82 pBuffer
= HeapAlloc(GetProcessHeap(), 0, BufSize
);
86 GetWindowTextW(hWnd
, pBuffer
, BufSize
/ sizeof(WCHAR
));
87 wcscat(pBuffer
, L
" ");
88 p
= &pBuffer
[dwTitleLength
+ 1];
90 RegQueryValueExW(hKey
,
97 SetWindowText(hWnd
, pBuffer
);
101 HeapFree(GetProcessHeap(), 0, pBuffer
);
107 static INT_PTR CALLBACK
114 UNREFERENCED_PARAMETER(wParam
);
120 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
124 msg
->Context
->hStatusWindow
= hwndDlg
;
127 SetWindowTextW(hwndDlg
, msg
->pTitle
);
128 SetDlgItemTextW(hwndDlg
, IDC_STATUS_MESSAGE
, msg
->pMessage
);
129 SetEvent(msg
->StartupEvent
);
137 StartupWindowThread(LPVOID lpParam
)
140 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
142 /* When SetThreadDesktop is called the system closes the desktop handle when needed
143 so we have to create a new handle because this handle may still be in use by winlogon */
144 if (!DuplicateHandle ( GetCurrentProcess(),
150 DUPLICATE_SAME_ACCESS
))
152 ERR("Duplicating handle failed!\n");
153 HeapFree(GetProcessHeap(), 0, lpParam
);
157 if(!SetThreadDesktop(hDesk
))
159 ERR("Setting thread desktop failed!\n");
160 HeapFree(GetProcessHeap(), 0, lpParam
);
166 MAKEINTRESOURCEW(IDD_STATUS
),
171 HeapFree(GetProcessHeap(), 0, lpParam
);
176 GUIDisplayStatusMessage(
177 IN PGINA_CONTEXT pgContext
,
183 PDISPLAYSTATUSMSG msg
;
187 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage
);
189 if (!pgContext
->hStatusWindow
)
192 * If everything goes correctly, 'msg' is freed
193 * by the 'StartupWindowThread' thread.
195 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(),
201 msg
->Context
= pgContext
;
202 msg
->dwOptions
= dwOptions
;
203 msg
->pTitle
= pTitle
;
204 msg
->pMessage
= pMessage
;
205 msg
->hDesktop
= hDesktop
;
207 msg
->StartupEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
209 if (!msg
->StartupEvent
)
211 HeapFree(GetProcessHeap(), 0, msg
);
215 Thread
= CreateThread(NULL
,
223 /* 'msg' will be freed by 'StartupWindowThread' */
226 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
227 CloseHandle(msg
->StartupEvent
);
233 * The 'StartupWindowThread' thread couldn't be created,
234 * so we need to free the allocated 'msg'.
236 HeapFree(GetProcessHeap(), 0, msg
);
243 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
245 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUS_MESSAGE
, pMessage
);
251 GUIRemoveStatusMessage(
252 IN PGINA_CONTEXT pgContext
)
254 if (pgContext
->hStatusWindow
)
256 EndDialog(pgContext
->hStatusWindow
, 0);
257 pgContext
->hStatusWindow
= NULL
;
263 static INT_PTR CALLBACK
272 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
278 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
279 if (pDlgData
== NULL
)
282 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
284 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
286 /* Load the logo bitmap */
287 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
294 if (pDlgData
->hBitmap
)
296 BeginPaint(hwndDlg
, &ps
);
297 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
298 EndPaint(hwndDlg
, &ps
);
304 DeleteObject(pDlgData
->hBitmap
);
305 HeapFree(GetProcessHeap(), 0, pDlgData
);
314 IN OUT PGINA_CONTEXT pgContext
)
316 TRACE("GUIDisplaySASNotice()\n");
318 /* Display the notice window */
319 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
320 pgContext
->hDllInstance
,
321 MAKEINTRESOURCEW(IDD_WELCOME
),
327 /* Get the text contained in a textbox. Allocates memory in pText
328 * to contain the text. Returns TRUE in case of success */
338 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
339 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
342 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
344 HeapFree(GetProcessHeap(), 0, Text
);
355 IN PGINA_CONTEXT pgContext
,
361 WCHAR szCaption
[256];
364 LoadStringW(pgContext
->hDllInstance
, uCaption
, szCaption
, _countof(szCaption
));
365 LoadStringW(pgContext
->hDllInstance
, uText
, szText
, _countof(szText
));
367 return pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
378 IN PGINA_CONTEXT pgContext
,
383 WCHAR OldPassword
[256];
384 WCHAR NewPassword1
[256];
385 WCHAR NewPassword2
[256];
386 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
387 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
388 ULONG RequestBufferSize
;
389 ULONG ResponseBufferSize
= 0;
392 NTSTATUS ProtocolStatus
;
395 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, UserName
, _countof(UserName
));
396 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, Domain
, _countof(Domain
));
397 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_OLDPWD
, OldPassword
, _countof(OldPassword
));
398 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NewPassword1
, _countof(NewPassword1
));
399 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NewPassword2
, _countof(NewPassword2
));
401 /* Compare the two passwords and fail if they do not match */
402 if (wcscmp(NewPassword1
, NewPassword2
) != 0)
404 ResourceMessageBox(pgContext
,
406 MB_OK
| MB_ICONEXCLAMATION
,
408 IDS_NONMATCHINGPASSWORDS
);
412 /* Calculate the request buffer size */
413 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
414 ((wcslen(Domain
) + 1) * sizeof(WCHAR
)) +
415 ((wcslen(UserName
) + 1) * sizeof(WCHAR
)) +
416 ((wcslen(OldPassword
) + 1) * sizeof(WCHAR
)) +
417 ((wcslen(NewPassword1
) + 1) * sizeof(WCHAR
));
419 /* Allocate the request buffer */
420 RequestBuffer
= HeapAlloc(GetProcessHeap(),
423 if (RequestBuffer
== NULL
)
425 ERR("HeapAlloc failed\n");
429 /* Initialize the request buffer */
430 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
431 RequestBuffer
->Impersonating
= TRUE
;
433 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
435 /* Pack the domain name */
436 RequestBuffer
->DomainName
.Length
= wcslen(Domain
) * sizeof(WCHAR
);
437 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
438 RequestBuffer
->DomainName
.Buffer
= Ptr
;
440 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
442 RequestBuffer
->DomainName
.MaximumLength
);
444 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
446 /* Pack the user name */
447 RequestBuffer
->AccountName
.Length
= wcslen(UserName
) * sizeof(WCHAR
);
448 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
449 RequestBuffer
->AccountName
.Buffer
= Ptr
;
451 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
453 RequestBuffer
->AccountName
.MaximumLength
);
455 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
457 /* Pack the old password */
458 RequestBuffer
->OldPassword
.Length
= wcslen(OldPassword
) * sizeof(WCHAR
);
459 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
460 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
462 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
464 RequestBuffer
->OldPassword
.MaximumLength
);
466 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
468 /* Pack the new password */
469 RequestBuffer
->NewPassword
.Length
= wcslen(NewPassword1
) * sizeof(WCHAR
);
470 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
471 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
473 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
475 RequestBuffer
->NewPassword
.MaximumLength
);
477 /* Connect to the LSA server */
478 if (ConnectToLsa(pgContext
) != ERROR_SUCCESS
)
480 ERR("ConnectToLsa() failed\n");
484 /* Call the authentication package */
485 Status
= LsaCallAuthenticationPackage(pgContext
->LsaHandle
,
486 pgContext
->AuthenticationPackage
,
489 (PVOID
*)&ResponseBuffer
,
492 if (!NT_SUCCESS(Status
))
494 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status
);
498 if (!NT_SUCCESS(ProtocolStatus
))
500 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus
);
506 ResourceMessageBox(pgContext
,
508 MB_OK
| MB_ICONINFORMATION
,
510 IDS_PASSWORDCHANGED
);
512 if ((wcscmp(UserName
, pgContext
->UserName
) == 0) &&
513 (wcscmp(Domain
, pgContext
->DomainName
) == 0) &&
514 (wcscmp(OldPassword
, pgContext
->Password
) == 0))
516 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
517 wcscpy(pgContext
->Password
, NewPassword1
);
521 if (RequestBuffer
!= NULL
)
522 HeapFree(GetProcessHeap(), 0, RequestBuffer
);
524 if (ResponseBuffer
!= NULL
)
525 LsaFreeReturnBuffer(ResponseBuffer
);
531 static INT_PTR CALLBACK
532 ChangePasswordDialogProc(
538 PGINA_CONTEXT pgContext
;
540 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
546 pgContext
= (PGINA_CONTEXT
)lParam
;
547 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
549 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, pgContext
->UserName
);
550 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
551 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_SETCURSEL
, 0, 0);
552 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
557 switch (LOWORD(wParam
))
560 if (DoChangePassword(pgContext
, hwndDlg
))
562 EndDialog(hwndDlg
, TRUE
);
566 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NULL
);
567 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NULL
);
568 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
573 EndDialog(hwndDlg
, FALSE
);
579 EndDialog(hwndDlg
, FALSE
);
588 OnInitSecurityDlg(HWND hwnd
,
589 PGINA_CONTEXT pgContext
)
596 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, _countof(Buffer1
));
598 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
599 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
601 SetDlgItemTextW(hwnd
, IDC_SECURITY_MESSAGE
, Buffer4
);
603 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, _countof(Buffer1
));
605 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
606 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, _countof(Buffer2
));
608 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
609 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, _countof(Buffer3
));
611 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
613 SetDlgItemTextW(hwnd
, IDC_SECURITY_LOGONDATE
, Buffer4
);
615 if (pgContext
->bAutoAdminLogon
)
616 EnableWindow(GetDlgItem(hwnd
, IDC_SECURITY_LOGOFF
), FALSE
);
623 IN PGINA_CONTEXT pgContext
)
627 TRACE("OnChangePassword()\n");
629 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
631 pgContext
->hDllInstance
,
632 MAKEINTRESOURCEW(IDD_CHANGEPWD
),
634 ChangePasswordDialogProc
,
637 TRACE("Result: %x\n", res
);
643 static INT_PTR CALLBACK
656 switch (LOWORD(wParam
))
659 EndDialog(hwndDlg
, IDYES
);
663 EndDialog(hwndDlg
, IDNO
);
669 EndDialog(hwndDlg
, IDNO
);
681 IN PGINA_CONTEXT pgContext
)
683 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
685 pgContext
->hDllInstance
,
686 MAKEINTRESOURCEW(IDD_LOGOFF
),
697 IN PGINA_CONTEXT pgContext
)
700 DWORD ShutdownOptions
;
702 TRACE("OnShutDown(%p %p)\n", hwndDlg
, pgContext
);
704 pgContext
->nShutdownAction
= GetDefaultShutdownSelState();
705 ShutdownOptions
= GetDefaultShutdownOptions();
707 if (pgContext
->UserToken
!= NULL
)
709 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
711 pgContext
->nShutdownAction
= LoadShutdownSelState();
712 ShutdownOptions
= GetAllowedShutdownOptions();
717 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
721 ret
= ShutdownDialog(hwndDlg
, ShutdownOptions
, pgContext
);
725 if (pgContext
->UserToken
!= NULL
)
727 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
729 SaveShutdownSelState(pgContext
->nShutdownAction
);
734 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
743 static INT_PTR CALLBACK
750 PGINA_CONTEXT pgContext
;
752 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
758 pgContext
= (PGINA_CONTEXT
)lParam
;
759 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
761 SetWelcomeText(hwndDlg
);
763 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
764 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
770 switch (LOWORD(wParam
))
772 case IDC_SECURITY_LOCK
:
773 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
775 case IDC_SECURITY_LOGOFF
:
776 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
777 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
779 case IDC_SECURITY_SHUTDOWN
:
780 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
781 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
783 case IDC_SECURITY_CHANGEPWD
:
784 if (OnChangePassword(hwndDlg
, pgContext
))
785 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
787 case IDC_SECURITY_TASKMGR
:
788 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
791 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
798 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
808 IN OUT PGINA_CONTEXT pgContext
,
813 TRACE("GUILoggedOnSAS()\n");
815 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
817 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
818 * close itself thanks to the use of WlxDialogBoxParam */
819 return WLX_SAS_ACTION_NONE
;
822 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
825 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
827 pgContext
->hDllInstance
,
828 MAKEINTRESOURCEW(IDD_SECURITY
),
833 if (result
< WLX_SAS_ACTION_LOGON
||
834 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
836 result
= WLX_SAS_ACTION_NONE
;
839 if (result
== WLX_SAS_ACTION_NONE
)
841 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
853 IN OUT PGINA_CONTEXT pgContext
)
855 LPWSTR UserName
= NULL
;
856 LPWSTR Password
= NULL
;
857 LPWSTR Domain
= NULL
;
859 NTSTATUS Status
, SubStatus
= STATUS_SUCCESS
;
861 if (GetTextboxText(hwndDlg
, IDC_LOGON_USERNAME
, &UserName
) && *UserName
== '\0')
864 if (GetTextboxText(hwndDlg
, IDC_LOGON_DOMAIN
, &Domain
) && *Domain
== '\0')
867 if (!GetTextboxText(hwndDlg
, IDC_LOGON_PASSWORD
, &Password
))
870 Status
= DoLoginTasks(pgContext
, UserName
, Domain
, Password
, &SubStatus
);
871 if (Status
== STATUS_LOGON_FAILURE
)
873 ResourceMessageBox(pgContext
,
875 MB_OK
| MB_ICONEXCLAMATION
,
877 IDS_LOGONWRONGUSERORPWD
);
880 else if (Status
== STATUS_ACCOUNT_RESTRICTION
)
882 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status
, SubStatus
);
884 if (SubStatus
== STATUS_ACCOUNT_DISABLED
)
886 ResourceMessageBox(pgContext
,
888 MB_OK
| MB_ICONEXCLAMATION
,
890 IDS_LOGONUSERDISABLED
);
893 else if (SubStatus
== STATUS_ACCOUNT_LOCKED_OUT
)
895 TRACE("Account locked!\n");
896 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
900 MB_OK
| MB_ICONERROR
);
903 else if ((SubStatus
== STATUS_PASSWORD_MUST_CHANGE
) ||
904 (SubStatus
== STATUS_PASSWORD_EXPIRED
))
906 if (SubStatus
== STATUS_PASSWORD_MUST_CHANGE
)
907 ResourceMessageBox(pgContext
,
911 IDS_PASSWORDMUSTCHANGE
);
913 ResourceMessageBox(pgContext
,
917 IDS_PASSWORDEXPIRED
);
919 if (!OnChangePassword(hwndDlg
,
923 Status
= DoLoginTasks(pgContext
,
925 pgContext
->DomainName
,
928 if (!NT_SUCCESS(Status
))
930 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status
);
935 else if (SubStatus
== STATUS_ACCOUNT_EXPIRED
)
937 ResourceMessageBox(pgContext
,
939 MB_OK
| MB_ICONEXCLAMATION
,
945 TRACE("Other error!\n");
946 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
950 MB_OK
| MB_ICONERROR
);
954 else if (!NT_SUCCESS(Status
))
956 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
961 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
963 ERR("Failed to create the profile!\n");
967 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
968 wcscpy(pgContext
->Password
, Password
);
973 pgContext
->bAutoAdminLogon
= FALSE
;
975 if (UserName
!= NULL
)
976 HeapFree(GetProcessHeap(), 0, UserName
);
978 if (Password
!= NULL
)
979 HeapFree(GetProcessHeap(), 0, Password
);
982 HeapFree(GetProcessHeap(), 0, Domain
);
991 HWND hwndDomainComboBox
,
992 PGINA_CONTEXT pgContext
)
994 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
995 DWORD dwComputerNameLength
;
999 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
1001 dwComputerNameLength
= _countof(szComputerName
);
1002 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
1004 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
1007 if (wcslen(pgContext
->DomainName
) != 0)
1009 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->DomainName
);
1010 if (lFindIndex
== CB_ERR
)
1012 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
1016 lIndex
= lFindIndex
;
1020 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
1024 static INT_PTR CALLBACK
1033 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1039 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1040 if (pDlgData
== NULL
)
1043 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1045 /* FIXME: take care of NoDomainUI */
1046 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1048 /* Draw the logo bitmap */
1049 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1051 SetWelcomeText(hwndDlg
);
1053 if (pDlgData
->pgContext
->bAutoAdminLogon
||
1054 !pDlgData
->pgContext
->bDontDisplayLastUserName
)
1055 SetDlgItemTextW(hwndDlg
, IDC_LOGON_USERNAME
, pDlgData
->pgContext
->UserName
);
1057 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1058 SetDlgItemTextW(hwndDlg
, IDC_LOGON_PASSWORD
, pDlgData
->pgContext
->Password
);
1060 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_DOMAIN
), pDlgData
->pgContext
);
1062 if (pDlgData
->pgContext
->bDisableCAD
)
1063 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1065 if (!pDlgData
->pgContext
->bShutdownWithoutLogon
)
1066 EnableWindow(GetDlgItem(hwndDlg
, IDC_LOGON_SHUTDOWN
), FALSE
);
1068 SetFocus(GetDlgItem(hwndDlg
, pDlgData
->pgContext
->bDontDisplayLastUserName
? IDC_LOGON_USERNAME
: IDC_LOGON_PASSWORD
));
1070 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1071 PostMessage(GetDlgItem(hwndDlg
, IDOK
), BM_CLICK
, 0, 0);
1079 if (pDlgData
->hBitmap
)
1081 BeginPaint(hwndDlg
, &ps
);
1082 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1083 EndPaint(hwndDlg
, &ps
);
1089 DeleteObject(pDlgData
->hBitmap
);
1090 HeapFree(GetProcessHeap(), 0, pDlgData
);
1094 switch (LOWORD(wParam
))
1097 if (DoLogon(hwndDlg
, pDlgData
->pgContext
))
1098 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1102 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1105 case IDC_LOGON_SHUTDOWN
:
1106 if (OnShutDown(hwndDlg
, pDlgData
->pgContext
) == IDOK
)
1107 EndDialog(hwndDlg
, pDlgData
->pgContext
->nShutdownAction
);
1120 LegalNoticeDialogProc(
1126 PLEGALNOTICEDATA pLegalNotice
;
1131 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1132 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1133 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1137 switch (LOWORD(wParam
))
1140 EndDialog(hwndDlg
, 0);
1144 EndDialog(hwndDlg
, 0);
1156 IN OUT PGINA_CONTEXT pgContext
)
1158 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1163 TRACE("GUILoggedOutSAS()\n");
1165 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1166 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1170 if (rc
== ERROR_SUCCESS
)
1172 ReadRegSzValue(hKey
,
1173 L
"LegalNoticeCaption",
1174 &LegalNotice
.pszCaption
);
1176 ReadRegSzValue(hKey
,
1178 &LegalNotice
.pszText
);
1183 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1184 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1186 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1187 pgContext
->hDllInstance
,
1188 MAKEINTRESOURCEW(IDD_LEGALNOTICE
),
1190 LegalNoticeDialogProc
,
1191 (LPARAM
)&LegalNotice
);
1194 if (LegalNotice
.pszCaption
!= NULL
)
1195 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1197 if (LegalNotice
.pszText
!= NULL
)
1198 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1200 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1202 pgContext
->hDllInstance
,
1203 MAKEINTRESOURCEW(IDD_LOGON
),
1207 if (result
>= WLX_SAS_ACTION_LOGON
&&
1208 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1210 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1214 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1215 return WLX_SAS_ACTION_NONE
;
1220 SetLockMessage(HWND hwnd
,
1222 PGINA_CONTEXT pgContext
)
1228 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1230 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
1231 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1233 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1241 IN PGINA_CONTEXT pgContext
,
1246 LPWSTR UserName
= NULL
;
1247 LPWSTR Password
= NULL
;
1250 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_USERNAME
, &UserName
) && *UserName
== '\0')
1252 HeapFree(GetProcessHeap(), 0, UserName
);
1256 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_PASSWORD
, &Password
))
1258 if (UserName
!= NULL
&& Password
!= NULL
&&
1259 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1260 wcscmp(Password
, pgContext
->Password
) == 0)
1262 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1265 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1266 wcscmp(Password
, pgContext
->Password
) != 0)
1268 /* Wrong Password */
1269 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1270 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1271 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1275 /* Wrong user name */
1276 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1278 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1283 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1284 wsprintfW(Buffer2
, Buffer1
, pgContext
->DomainName
, pgContext
->UserName
);
1285 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1286 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1291 if (UserName
!= NULL
)
1292 HeapFree(GetProcessHeap(), 0, UserName
);
1294 if (Password
!= NULL
)
1295 HeapFree(GetProcessHeap(), 0, Password
);
1311 INT result
= WLX_SAS_ACTION_NONE
;
1313 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1319 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1320 if (pDlgData
== NULL
)
1323 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1325 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1327 SetWelcomeText(hwndDlg
);
1329 SetLockMessage(hwndDlg
, IDC_UNLOCK_MESSAGE
, pDlgData
->pgContext
);
1331 SetDlgItemTextW(hwndDlg
, IDC_UNLOCK_USERNAME
, pDlgData
->pgContext
->UserName
);
1332 SetFocus(GetDlgItem(hwndDlg
, IDC_UNLOCK_PASSWORD
));
1334 if (pDlgData
->pgContext
->bDisableCAD
)
1335 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1337 /* Load the logo bitmap */
1338 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1345 if (pDlgData
->hBitmap
)
1347 BeginPaint(hwndDlg
, &ps
);
1348 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1349 EndPaint(hwndDlg
, &ps
);
1354 DeleteObject(pDlgData
->hBitmap
);
1355 HeapFree(GetProcessHeap(), 0, pDlgData
);
1359 switch (LOWORD(wParam
))
1362 if (DoUnlock(hwndDlg
, pDlgData
->pgContext
, &result
))
1363 EndDialog(hwndDlg
, result
);
1367 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1379 IN OUT PGINA_CONTEXT pgContext
)
1383 TRACE("GUILockedSAS()\n");
1385 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1387 pgContext
->hDllInstance
,
1388 MAKEINTRESOURCEW(IDD_UNLOCK
),
1392 if (result
>= WLX_SAS_ACTION_LOGON
&&
1393 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1395 WARN("GUILockedSAS() returns 0x%x\n", result
);
1399 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1400 return WLX_SAS_ACTION_NONE
;
1404 static INT_PTR CALLBACK
1413 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1419 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1420 if (pDlgData
== NULL
)
1423 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1425 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1427 /* Load the logo bitmap */
1428 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1430 SetWelcomeText(hwndDlg
);
1432 SetLockMessage(hwndDlg
, IDC_LOCKED_MESSAGE
, pDlgData
->pgContext
);
1438 if (pDlgData
->hBitmap
)
1440 BeginPaint(hwndDlg
, &ps
);
1441 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1442 EndPaint(hwndDlg
, &ps
);
1448 DeleteObject(pDlgData
->hBitmap
);
1449 HeapFree(GetProcessHeap(), 0, pDlgData
);
1459 GUIDisplayLockedNotice(
1460 IN OUT PGINA_CONTEXT pgContext
)
1462 TRACE("GUIdisplayLockedNotice()\n");
1464 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1466 pgContext
->hDllInstance
,
1467 MAKEINTRESOURCEW(IDD_LOCKED
),
1473 GINA_UI GinaGraphicalUI
= {
1475 GUIDisplayStatusMessage
,
1476 GUIRemoveStatusMessage
,
1477 GUIDisplaySASNotice
,
1481 GUIDisplayLockedNotice
,