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
);
937 TRACE("Other error!\n");
938 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
942 MB_OK
| MB_ICONERROR
);
946 else if (!NT_SUCCESS(Status
))
948 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
953 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
955 ERR("Failed to create the profile!\n");
959 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
960 wcscpy(pgContext
->Password
, Password
);
965 pgContext
->bAutoAdminLogon
= FALSE
;
967 if (UserName
!= NULL
)
968 HeapFree(GetProcessHeap(), 0, UserName
);
970 if (Password
!= NULL
)
971 HeapFree(GetProcessHeap(), 0, Password
);
974 HeapFree(GetProcessHeap(), 0, Domain
);
983 HWND hwndDomainComboBox
,
984 PGINA_CONTEXT pgContext
)
986 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
987 DWORD dwComputerNameLength
;
991 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
993 dwComputerNameLength
= _countof(szComputerName
);
994 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
996 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
999 if (wcslen(pgContext
->DomainName
) != 0)
1001 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->DomainName
);
1002 if (lFindIndex
== CB_ERR
)
1004 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
1008 lIndex
= lFindIndex
;
1012 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
1016 static INT_PTR CALLBACK
1025 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1031 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1032 if (pDlgData
== NULL
)
1035 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1037 /* FIXME: take care of NoDomainUI */
1038 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1040 /* Draw the logo bitmap */
1041 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1043 SetWelcomeText(hwndDlg
);
1045 if (pDlgData
->pgContext
->bAutoAdminLogon
||
1046 !pDlgData
->pgContext
->bDontDisplayLastUserName
)
1047 SetDlgItemTextW(hwndDlg
, IDC_LOGON_USERNAME
, pDlgData
->pgContext
->UserName
);
1049 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1050 SetDlgItemTextW(hwndDlg
, IDC_LOGON_PASSWORD
, pDlgData
->pgContext
->Password
);
1052 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_DOMAIN
), pDlgData
->pgContext
);
1054 if (pDlgData
->pgContext
->bDisableCAD
)
1055 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1057 if (!pDlgData
->pgContext
->bShutdownWithoutLogon
)
1058 EnableWindow(GetDlgItem(hwndDlg
, IDC_LOGON_SHUTDOWN
), FALSE
);
1060 SetFocus(GetDlgItem(hwndDlg
, pDlgData
->pgContext
->bDontDisplayLastUserName
? IDC_LOGON_USERNAME
: IDC_LOGON_PASSWORD
));
1062 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1063 PostMessage(GetDlgItem(hwndDlg
, IDOK
), BM_CLICK
, 0, 0);
1071 if (pDlgData
->hBitmap
)
1073 BeginPaint(hwndDlg
, &ps
);
1074 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1075 EndPaint(hwndDlg
, &ps
);
1081 DeleteObject(pDlgData
->hBitmap
);
1082 HeapFree(GetProcessHeap(), 0, pDlgData
);
1086 switch (LOWORD(wParam
))
1089 if (DoLogon(hwndDlg
, pDlgData
->pgContext
))
1090 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1094 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1097 case IDC_LOGON_SHUTDOWN
:
1098 if (OnShutDown(hwndDlg
, pDlgData
->pgContext
) == IDOK
)
1099 EndDialog(hwndDlg
, pDlgData
->pgContext
->nShutdownAction
);
1112 LegalNoticeDialogProc(
1118 PLEGALNOTICEDATA pLegalNotice
;
1123 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1124 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1125 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1129 switch (LOWORD(wParam
))
1132 EndDialog(hwndDlg
, 0);
1136 EndDialog(hwndDlg
, 0);
1148 IN OUT PGINA_CONTEXT pgContext
)
1150 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1155 TRACE("GUILoggedOutSAS()\n");
1157 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1158 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1162 if (rc
== ERROR_SUCCESS
)
1164 ReadRegSzValue(hKey
,
1165 L
"LegalNoticeCaption",
1166 &LegalNotice
.pszCaption
);
1168 ReadRegSzValue(hKey
,
1170 &LegalNotice
.pszText
);
1175 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1176 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1178 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1179 pgContext
->hDllInstance
,
1180 MAKEINTRESOURCEW(IDD_LEGALNOTICE
),
1182 LegalNoticeDialogProc
,
1183 (LPARAM
)&LegalNotice
);
1186 if (LegalNotice
.pszCaption
!= NULL
)
1187 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1189 if (LegalNotice
.pszText
!= NULL
)
1190 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1192 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1194 pgContext
->hDllInstance
,
1195 MAKEINTRESOURCEW(IDD_LOGON
),
1199 if (result
>= WLX_SAS_ACTION_LOGON
&&
1200 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1202 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1206 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1207 return WLX_SAS_ACTION_NONE
;
1212 SetLockMessage(HWND hwnd
,
1214 PGINA_CONTEXT pgContext
)
1220 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1222 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
1223 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1225 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1233 IN PGINA_CONTEXT pgContext
,
1238 LPWSTR UserName
= NULL
;
1239 LPWSTR Password
= NULL
;
1242 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_USERNAME
, &UserName
) && *UserName
== '\0')
1244 HeapFree(GetProcessHeap(), 0, UserName
);
1248 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_PASSWORD
, &Password
))
1250 if (UserName
!= NULL
&& Password
!= NULL
&&
1251 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1252 wcscmp(Password
, pgContext
->Password
) == 0)
1254 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1257 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1258 wcscmp(Password
, pgContext
->Password
) != 0)
1260 /* Wrong Password */
1261 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1262 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1263 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1267 /* Wrong user name */
1268 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1270 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1275 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1276 wsprintfW(Buffer2
, Buffer1
, pgContext
->DomainName
, pgContext
->UserName
);
1277 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1278 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1283 if (UserName
!= NULL
)
1284 HeapFree(GetProcessHeap(), 0, UserName
);
1286 if (Password
!= NULL
)
1287 HeapFree(GetProcessHeap(), 0, Password
);
1303 INT result
= WLX_SAS_ACTION_NONE
;
1305 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1311 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1312 if (pDlgData
== NULL
)
1315 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1317 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1319 SetWelcomeText(hwndDlg
);
1321 SetLockMessage(hwndDlg
, IDC_UNLOCK_MESSAGE
, pDlgData
->pgContext
);
1323 SetDlgItemTextW(hwndDlg
, IDC_UNLOCK_USERNAME
, pDlgData
->pgContext
->UserName
);
1324 SetFocus(GetDlgItem(hwndDlg
, IDC_UNLOCK_PASSWORD
));
1326 if (pDlgData
->pgContext
->bDisableCAD
)
1327 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1329 /* Load the logo bitmap */
1330 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1337 if (pDlgData
->hBitmap
)
1339 BeginPaint(hwndDlg
, &ps
);
1340 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1341 EndPaint(hwndDlg
, &ps
);
1346 DeleteObject(pDlgData
->hBitmap
);
1347 HeapFree(GetProcessHeap(), 0, pDlgData
);
1351 switch (LOWORD(wParam
))
1354 if (DoUnlock(hwndDlg
, pDlgData
->pgContext
, &result
))
1355 EndDialog(hwndDlg
, result
);
1359 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1371 IN OUT PGINA_CONTEXT pgContext
)
1375 TRACE("GUILockedSAS()\n");
1377 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1379 pgContext
->hDllInstance
,
1380 MAKEINTRESOURCEW(IDD_UNLOCK
),
1384 if (result
>= WLX_SAS_ACTION_LOGON
&&
1385 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1387 WARN("GUILockedSAS() returns 0x%x\n", result
);
1391 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1392 return WLX_SAS_ACTION_NONE
;
1396 static INT_PTR CALLBACK
1405 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1411 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1412 if (pDlgData
== NULL
)
1415 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1417 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1419 /* Load the logo bitmap */
1420 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1422 SetWelcomeText(hwndDlg
);
1424 SetLockMessage(hwndDlg
, IDC_LOCKED_MESSAGE
, pDlgData
->pgContext
);
1430 if (pDlgData
->hBitmap
)
1432 BeginPaint(hwndDlg
, &ps
);
1433 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1434 EndPaint(hwndDlg
, &ps
);
1440 DeleteObject(pDlgData
->hBitmap
);
1441 HeapFree(GetProcessHeap(), 0, pDlgData
);
1451 GUIDisplayLockedNotice(
1452 IN OUT PGINA_CONTEXT pgContext
)
1454 TRACE("GUIdisplayLockedNotice()\n");
1456 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1458 pgContext
->hDllInstance
,
1459 MAKEINTRESOURCEW(IDD_LOCKED
),
1465 GINA_UI GinaGraphicalUI
= {
1467 GUIDisplayStatusMessage
,
1468 GUIRemoveStatusMessage
,
1469 GUIDisplaySASNotice
,
1473 GUIDisplayLockedNotice
,