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 MAKEINTRESOURCEW(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(),
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
, TRUE
, FALSE
, NULL
);
141 if (!msg
->StartupEvent
)
143 HeapFree(GetProcessHeap(), 0, msg
);
147 Thread
= CreateThread(NULL
,
155 /* 'msg' will be freed by 'StartupWindowThread' */
158 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
159 CloseHandle(msg
->StartupEvent
);
165 * The 'StartupWindowThread' thread couldn't be created,
166 * so we need to free the allocated 'msg'.
168 HeapFree(GetProcessHeap(), 0, msg
);
175 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
177 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUSLABEL
, pMessage
);
183 GUIRemoveStatusMessage(
184 IN PGINA_CONTEXT pgContext
)
186 if (pgContext
->hStatusWindow
)
188 EndDialog(pgContext
->hStatusWindow
, 0);
189 pgContext
->hStatusWindow
= NULL
;
195 static INT_PTR CALLBACK
202 PGINA_CONTEXT pgContext
;
204 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
210 pgContext
= (PGINA_CONTEXT
)lParam
;
211 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
213 /* Draw the logo bitmap */
214 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
220 if (pgContext
->hBitmap
)
222 BeginPaint(hwndDlg
, &ps
);
223 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
224 EndPaint(hwndDlg
, &ps
);
230 DeleteObject(pgContext
->hBitmap
);
239 IN OUT PGINA_CONTEXT pgContext
)
241 TRACE("GUIDisplaySASNotice()\n");
243 /* Display the notice window */
244 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
245 pgContext
->hDllInstance
,
246 MAKEINTRESOURCEW(IDD_NOTICE_DLG
),
252 /* Get the text contained in a textbox. Allocates memory in pText
253 * to contain the text. Returns TRUE in case of success */
263 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
264 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
267 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
269 HeapFree(GetProcessHeap(), 0, Text
);
280 IN PGINA_CONTEXT pgContext
,
286 WCHAR szCaption
[256];
289 LoadStringW(pgContext
->hDllInstance
, uCaption
, szCaption
, _countof(szCaption
));
290 LoadStringW(pgContext
->hDllInstance
, uText
, szText
, _countof(szText
));
292 return pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
303 IN PGINA_CONTEXT pgContext
,
308 WCHAR OldPassword
[256];
309 WCHAR NewPassword1
[256];
310 WCHAR NewPassword2
[256];
311 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
312 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
313 ULONG RequestBufferSize
;
314 ULONG ResponseBufferSize
= 0;
317 NTSTATUS ProtocolStatus
;
320 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, UserName
, _countof(UserName
));
321 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, Domain
, _countof(Domain
));
322 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_OLDPWD
, OldPassword
, _countof(OldPassword
));
323 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NewPassword1
, _countof(NewPassword1
));
324 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NewPassword2
, _countof(NewPassword2
));
326 /* Compare the two passwords and fail if they do not match */
327 if (wcscmp(NewPassword1
, NewPassword2
) != 0)
329 ResourceMessageBox(pgContext
,
331 MB_OK
| MB_ICONEXCLAMATION
,
333 IDS_NONMATCHINGPASSWORDS
);
337 /* Calculate the request buffer size */
338 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
339 ((wcslen(Domain
) + 1) * sizeof(WCHAR
)) +
340 ((wcslen(UserName
) + 1) * sizeof(WCHAR
)) +
341 ((wcslen(OldPassword
) + 1) * sizeof(WCHAR
)) +
342 ((wcslen(NewPassword1
) + 1) * sizeof(WCHAR
));
344 /* Allocate the request buffer */
345 RequestBuffer
= HeapAlloc(GetProcessHeap(),
348 if (RequestBuffer
== NULL
)
350 ERR("HeapAlloc failed\n");
354 /* Initialize the request buffer */
355 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
356 RequestBuffer
->Impersonating
= TRUE
;
358 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
360 /* Pack the domain name */
361 RequestBuffer
->DomainName
.Length
= wcslen(Domain
) * sizeof(WCHAR
);
362 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
363 RequestBuffer
->DomainName
.Buffer
= Ptr
;
365 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
367 RequestBuffer
->DomainName
.MaximumLength
);
369 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
371 /* Pack the user name */
372 RequestBuffer
->AccountName
.Length
= wcslen(UserName
) * sizeof(WCHAR
);
373 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
374 RequestBuffer
->AccountName
.Buffer
= Ptr
;
376 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
378 RequestBuffer
->AccountName
.MaximumLength
);
380 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
382 /* Pack the old password */
383 RequestBuffer
->OldPassword
.Length
= wcslen(OldPassword
) * sizeof(WCHAR
);
384 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
385 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
387 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
389 RequestBuffer
->OldPassword
.MaximumLength
);
391 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
393 /* Pack the new password */
394 RequestBuffer
->NewPassword
.Length
= wcslen(NewPassword1
) * sizeof(WCHAR
);
395 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
396 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
398 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
400 RequestBuffer
->NewPassword
.MaximumLength
);
402 /* Connect to the LSA server */
403 if (!ConnectToLsa(pgContext
))
405 ERR("ConnectToLsa() failed\n");
409 /* Call the authentication package */
410 Status
= LsaCallAuthenticationPackage(pgContext
->LsaHandle
,
411 pgContext
->AuthenticationPackage
,
414 (PVOID
*)&ResponseBuffer
,
417 if (!NT_SUCCESS(Status
))
419 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status
);
423 if (!NT_SUCCESS(ProtocolStatus
))
425 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus
);
431 ResourceMessageBox(pgContext
,
433 MB_OK
| MB_ICONINFORMATION
,
435 IDS_PASSWORDCHANGED
);
437 if ((wcscmp(UserName
, pgContext
->UserName
) == 0) &&
438 (wcscmp(Domain
, pgContext
->Domain
) == 0) &&
439 (wcscmp(OldPassword
, pgContext
->Password
) == 0))
441 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
442 wcscpy(pgContext
->Password
, NewPassword1
);
446 if (RequestBuffer
!= NULL
)
447 HeapFree(GetProcessHeap(), 0, RequestBuffer
);
449 if (ResponseBuffer
!= NULL
)
450 LsaFreeReturnBuffer(ResponseBuffer
);
456 static INT_PTR CALLBACK
457 ChangePasswordDialogProc(
463 PGINA_CONTEXT pgContext
;
465 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
471 pgContext
= (PGINA_CONTEXT
)lParam
;
472 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
474 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, pgContext
->UserName
);
475 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->Domain
);
476 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_SETCURSEL
, 0, 0);
477 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
482 switch (LOWORD(wParam
))
485 if (DoChangePassword(pgContext
, hwndDlg
))
487 EndDialog(hwndDlg
, TRUE
);
491 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NULL
);
492 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NULL
);
493 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
498 EndDialog(hwndDlg
, FALSE
);
504 EndDialog(hwndDlg
, FALSE
);
513 OnInitSecurityDlg(HWND hwnd
,
514 PGINA_CONTEXT pgContext
)
521 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, _countof(Buffer1
));
523 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
524 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
526 SetDlgItemTextW(hwnd
, IDC_LOGONMSG
, Buffer4
);
528 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, _countof(Buffer1
));
530 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
531 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, _countof(Buffer2
));
533 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
534 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, _countof(Buffer3
));
536 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
538 SetDlgItemTextW(hwnd
, IDC_LOGONDATE
, Buffer4
);
540 if (pgContext
->bAutoAdminLogon
)
541 EnableWindow(GetDlgItem(hwnd
, IDC_LOGOFF
), FALSE
);
548 IN PGINA_CONTEXT pgContext
)
552 TRACE("OnChangePassword()\n");
554 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
556 pgContext
->hDllInstance
,
557 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD
),
559 ChangePasswordDialogProc
,
562 TRACE("Result: %x\n", res
);
568 static INT_PTR CALLBACK
581 switch (LOWORD(wParam
))
584 EndDialog(hwndDlg
, IDYES
);
588 EndDialog(hwndDlg
, IDNO
);
594 EndDialog(hwndDlg
, IDNO
);
606 IN PGINA_CONTEXT pgContext
)
608 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
610 pgContext
->hDllInstance
,
611 MAKEINTRESOURCEW(IDD_LOGOFF_DLG
),
622 IN PGINA_CONTEXT pgContext
)
625 DWORD ShutdownOptions
;
627 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
629 pgContext
->nShutdownAction
= LoadShutdownSelState();
630 ShutdownOptions
= GetAllowedShutdownOptions();
635 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
636 pgContext
->nShutdownAction
= 0;
640 ret
= ShutdownDialog(hwndDlg
, ShutdownOptions
, pgContext
);
644 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
646 SaveShutdownSelState(pgContext
->nShutdownAction
);
651 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
659 static INT_PTR CALLBACK
666 PGINA_CONTEXT pgContext
;
668 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
674 pgContext
= (PGINA_CONTEXT
)lParam
;
675 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
677 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
678 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
684 switch (LOWORD(wParam
))
687 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
690 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
691 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
694 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
695 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
698 if (OnChangePassword(hwndDlg
, pgContext
))
699 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
702 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
705 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
712 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
722 IN OUT PGINA_CONTEXT pgContext
,
727 TRACE("GUILoggedOnSAS()\n");
729 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
731 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
732 * close itself thanks to the use of WlxDialogBoxParam */
733 return WLX_SAS_ACTION_NONE
;
736 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
739 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
741 pgContext
->hDllInstance
,
742 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG
),
747 if (result
< WLX_SAS_ACTION_LOGON
||
748 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
750 result
= WLX_SAS_ACTION_NONE
;
753 if (result
== WLX_SAS_ACTION_NONE
)
755 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
767 IN OUT PGINA_CONTEXT pgContext
)
769 LPWSTR UserName
= NULL
;
770 LPWSTR Password
= NULL
;
771 LPWSTR Domain
= NULL
;
773 NTSTATUS Status
, SubStatus
= STATUS_SUCCESS
;
775 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
778 if (GetTextboxText(hwndDlg
, IDC_LOGON_TO
, &Domain
) && *Domain
== '\0')
781 if (!GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
784 Status
= DoLoginTasks(pgContext
, UserName
, Domain
, Password
, &SubStatus
);
785 if (Status
== STATUS_LOGON_FAILURE
)
787 ResourceMessageBox(pgContext
,
789 MB_OK
| MB_ICONEXCLAMATION
,
791 IDS_LOGONWRONGUSERORPWD
);
794 else if (Status
== STATUS_ACCOUNT_RESTRICTION
)
796 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status
, SubStatus
);
798 if (SubStatus
== STATUS_ACCOUNT_DISABLED
)
800 ResourceMessageBox(pgContext
,
802 MB_OK
| MB_ICONEXCLAMATION
,
804 IDS_LOGONUSERDISABLED
);
807 else if (SubStatus
== STATUS_ACCOUNT_LOCKED_OUT
)
809 TRACE("Account locked!\n");
810 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
814 MB_OK
| MB_ICONERROR
);
817 else if ((SubStatus
== STATUS_PASSWORD_MUST_CHANGE
) ||
818 (SubStatus
== STATUS_PASSWORD_EXPIRED
))
820 if (SubStatus
== STATUS_PASSWORD_MUST_CHANGE
)
821 ResourceMessageBox(pgContext
,
825 IDS_PASSWORDMUSTCHANGE
);
827 ResourceMessageBox(pgContext
,
831 IDS_PASSWORDEXPIRED
);
833 if (!OnChangePassword(hwndDlg
,
837 Status
= DoLoginTasks(pgContext
,
842 if (!NT_SUCCESS(Status
))
844 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status
);
851 TRACE("Other error!\n");
852 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
856 MB_OK
| MB_ICONERROR
);
860 else if (!NT_SUCCESS(Status
))
862 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
867 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
869 ERR("Failed to create the profile!\n");
873 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
874 wcscpy(pgContext
->Password
, Password
);
879 if (UserName
!= NULL
)
880 HeapFree(GetProcessHeap(), 0, UserName
);
882 if (Password
!= NULL
)
883 HeapFree(GetProcessHeap(), 0, Password
);
886 HeapFree(GetProcessHeap(), 0, Domain
);
895 HWND hwndDomainComboBox
,
896 PGINA_CONTEXT pgContext
)
898 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
899 DWORD dwComputerNameLength
;
903 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
905 dwComputerNameLength
= _countof(szComputerName
);
906 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
908 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
911 if (wcslen(pgContext
->Domain
) != 0)
913 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->Domain
);
914 if (lFindIndex
== CB_ERR
)
916 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->Domain
);
924 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
928 static INT_PTR CALLBACK
935 PGINA_CONTEXT pgContext
;
937 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
943 /* FIXME: take care of NoDomainUI */
944 pgContext
= (PGINA_CONTEXT
)lParam
;
945 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
947 if (!pgContext
->bDontDisplayLastUserName
)
948 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
950 if (pgContext
->bDisableCAD
)
951 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
953 if (!pgContext
->bShutdownWithoutLogon
)
954 EnableWindow(GetDlgItem(hwndDlg
, IDC_SHUTDOWN
), FALSE
);
956 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_TO
), pgContext
);
958 SetFocus(GetDlgItem(hwndDlg
, pgContext
->bDontDisplayLastUserName
? IDC_USERNAME
: IDC_PASSWORD
));
960 /* Draw the logo bitmap */
961 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
968 if (pgContext
->hBitmap
)
970 BeginPaint(hwndDlg
, &ps
);
971 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
972 EndPaint(hwndDlg
, &ps
);
978 DeleteObject(pgContext
->hBitmap
);
982 switch (LOWORD(wParam
))
985 if (DoLogon(hwndDlg
, pgContext
))
986 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
990 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
994 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
995 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
1008 LegalNoticeDialogProc(
1014 PLEGALNOTICEDATA pLegalNotice
;
1019 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1020 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1021 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1025 switch (LOWORD(wParam
))
1028 EndDialog(hwndDlg
, 0);
1032 EndDialog(hwndDlg
, 0);
1044 IN OUT PGINA_CONTEXT pgContext
)
1046 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1051 TRACE("GUILoggedOutSAS()\n");
1053 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1054 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1058 if (rc
== ERROR_SUCCESS
)
1060 ReadRegSzValue(hKey
,
1061 L
"LegalNoticeCaption",
1062 &LegalNotice
.pszCaption
);
1064 ReadRegSzValue(hKey
,
1066 &LegalNotice
.pszText
);
1071 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1072 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1074 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1075 pgContext
->hDllInstance
,
1076 MAKEINTRESOURCEW(IDD_LEGALNOTICE_DLG
),
1078 LegalNoticeDialogProc
,
1079 (LPARAM
)&LegalNotice
);
1082 if (LegalNotice
.pszCaption
!= NULL
)
1083 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1085 if (LegalNotice
.pszText
!= NULL
)
1086 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1088 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1090 pgContext
->hDllInstance
,
1091 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG
),
1093 LoggedOutWindowProc
,
1095 if (result
>= WLX_SAS_ACTION_LOGON
&&
1096 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1098 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1102 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1103 return WLX_SAS_ACTION_NONE
;
1108 SetLockMessage(HWND hwnd
,
1110 PGINA_CONTEXT pgContext
)
1116 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1118 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
1119 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1121 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1129 IN PGINA_CONTEXT pgContext
,
1134 LPWSTR UserName
= NULL
;
1135 LPWSTR Password
= NULL
;
1138 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
1140 HeapFree(GetProcessHeap(), 0, UserName
);
1144 if (GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
1146 if (UserName
!= NULL
&& Password
!= NULL
&&
1147 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1148 wcscmp(Password
, pgContext
->Password
) == 0)
1150 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1153 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1154 wcscmp(Password
, pgContext
->Password
) != 0)
1156 /* Wrong Password */
1157 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1158 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1159 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1163 /* Wrong user name */
1164 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1166 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1171 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1172 wsprintfW(Buffer2
, Buffer1
, pgContext
->Domain
, pgContext
->UserName
);
1173 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1174 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1179 if (UserName
!= NULL
)
1180 HeapFree(GetProcessHeap(), 0, UserName
);
1182 if (Password
!= NULL
)
1183 HeapFree(GetProcessHeap(), 0, Password
);
1198 PGINA_CONTEXT pgContext
;
1199 INT result
= WLX_SAS_ACTION_NONE
;
1201 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1207 pgContext
= (PGINA_CONTEXT
)lParam
;
1208 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
1210 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1212 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
1213 SetFocus(GetDlgItem(hwndDlg
, IDC_PASSWORD
));
1215 if (pgContext
->bDisableCAD
)
1216 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1218 /* Draw the logo bitmap */
1219 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1226 if (pgContext
->hBitmap
)
1228 BeginPaint(hwndDlg
, &ps
);
1229 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1230 EndPaint(hwndDlg
, &ps
);
1235 DeleteObject(pgContext
->hBitmap
);
1239 switch (LOWORD(wParam
))
1242 if (DoUnlock(hwndDlg
, pgContext
, &result
))
1243 EndDialog(hwndDlg
, result
);
1247 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1259 IN OUT PGINA_CONTEXT pgContext
)
1263 TRACE("GUILockedSAS()\n");
1265 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1267 pgContext
->hDllInstance
,
1268 MAKEINTRESOURCEW(IDD_UNLOCK_DLG
),
1272 if (result
>= WLX_SAS_ACTION_LOGON
&&
1273 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1275 WARN("GUILockedSAS() returns 0x%x\n", result
);
1279 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1280 return WLX_SAS_ACTION_NONE
;
1284 static INT_PTR CALLBACK
1291 PGINA_CONTEXT pgContext
;
1293 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1299 pgContext
= (PGINA_CONTEXT
)lParam
;
1300 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
1302 /* Draw the logo bitmap */
1303 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1304 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1310 if (pgContext
->hBitmap
)
1312 BeginPaint(hwndDlg
, &ps
);
1313 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1314 EndPaint(hwndDlg
, &ps
);
1320 DeleteObject(pgContext
->hBitmap
);
1330 GUIDisplayLockedNotice(
1331 IN OUT PGINA_CONTEXT pgContext
)
1333 TRACE("GUIdisplayLockedNotice()\n");
1335 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1337 pgContext
->hDllInstance
,
1338 MAKEINTRESOURCEW(IDD_LOCKED_DLG
),
1344 GINA_UI GinaGraphicalUI
= {
1346 GUIDisplayStatusMessage
,
1347 GUIRemoveStatusMessage
,
1348 GUIDisplaySASNotice
,
1352 GUIDisplayLockedNotice
,