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
);
876 pgContext
->bAutoAdminLogon
= FALSE
;
881 if (UserName
!= NULL
)
882 HeapFree(GetProcessHeap(), 0, UserName
);
884 if (Password
!= NULL
)
885 HeapFree(GetProcessHeap(), 0, Password
);
888 HeapFree(GetProcessHeap(), 0, Domain
);
897 HWND hwndDomainComboBox
,
898 PGINA_CONTEXT pgContext
)
900 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
901 DWORD dwComputerNameLength
;
905 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
907 dwComputerNameLength
= _countof(szComputerName
);
908 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
910 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
913 if (wcslen(pgContext
->Domain
) != 0)
915 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->Domain
);
916 if (lFindIndex
== CB_ERR
)
918 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->Domain
);
926 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
930 static INT_PTR CALLBACK
937 PGINA_CONTEXT pgContext
;
939 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
945 /* FIXME: take care of NoDomainUI */
946 pgContext
= (PGINA_CONTEXT
)lParam
;
947 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
949 if (pgContext
->bAutoAdminLogon
||
950 !pgContext
->bDontDisplayLastUserName
)
951 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
953 if (pgContext
->bAutoAdminLogon
)
954 SetDlgItemTextW(hwndDlg
, IDC_PASSWORD
, pgContext
->Password
);
956 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_TO
), pgContext
);
958 if (pgContext
->bDisableCAD
)
959 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
961 if (!pgContext
->bShutdownWithoutLogon
)
962 EnableWindow(GetDlgItem(hwndDlg
, IDC_SHUTDOWN
), FALSE
);
964 SetFocus(GetDlgItem(hwndDlg
, pgContext
->bDontDisplayLastUserName
? IDC_USERNAME
: IDC_PASSWORD
));
966 /* Draw the logo bitmap */
967 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
969 if (pgContext
->bAutoAdminLogon
)
970 PostMessage(GetDlgItem(hwndDlg
, IDOK
), BM_CLICK
, 0, 0);
978 if (pgContext
->hBitmap
)
980 BeginPaint(hwndDlg
, &ps
);
981 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
982 EndPaint(hwndDlg
, &ps
);
988 DeleteObject(pgContext
->hBitmap
);
992 switch (LOWORD(wParam
))
995 if (DoLogon(hwndDlg
, pgContext
))
996 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1000 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1004 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
1005 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
1018 LegalNoticeDialogProc(
1024 PLEGALNOTICEDATA pLegalNotice
;
1029 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1030 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1031 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1035 switch (LOWORD(wParam
))
1038 EndDialog(hwndDlg
, 0);
1042 EndDialog(hwndDlg
, 0);
1054 IN OUT PGINA_CONTEXT pgContext
)
1056 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1061 TRACE("GUILoggedOutSAS()\n");
1063 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1064 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1068 if (rc
== ERROR_SUCCESS
)
1070 ReadRegSzValue(hKey
,
1071 L
"LegalNoticeCaption",
1072 &LegalNotice
.pszCaption
);
1074 ReadRegSzValue(hKey
,
1076 &LegalNotice
.pszText
);
1081 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1082 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1084 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1085 pgContext
->hDllInstance
,
1086 MAKEINTRESOURCEW(IDD_LEGALNOTICE_DLG
),
1088 LegalNoticeDialogProc
,
1089 (LPARAM
)&LegalNotice
);
1092 if (LegalNotice
.pszCaption
!= NULL
)
1093 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1095 if (LegalNotice
.pszText
!= NULL
)
1096 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1098 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1100 pgContext
->hDllInstance
,
1101 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG
),
1103 LoggedOutWindowProc
,
1105 if (result
>= WLX_SAS_ACTION_LOGON
&&
1106 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1108 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1112 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1113 return WLX_SAS_ACTION_NONE
;
1118 SetLockMessage(HWND hwnd
,
1120 PGINA_CONTEXT pgContext
)
1126 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1128 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
1129 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1131 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1139 IN PGINA_CONTEXT pgContext
,
1144 LPWSTR UserName
= NULL
;
1145 LPWSTR Password
= NULL
;
1148 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
1150 HeapFree(GetProcessHeap(), 0, UserName
);
1154 if (GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
1156 if (UserName
!= NULL
&& Password
!= NULL
&&
1157 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1158 wcscmp(Password
, pgContext
->Password
) == 0)
1160 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1163 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1164 wcscmp(Password
, pgContext
->Password
) != 0)
1166 /* Wrong Password */
1167 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1168 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1169 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1173 /* Wrong user name */
1174 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1176 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1181 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1182 wsprintfW(Buffer2
, Buffer1
, pgContext
->Domain
, pgContext
->UserName
);
1183 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1184 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1189 if (UserName
!= NULL
)
1190 HeapFree(GetProcessHeap(), 0, UserName
);
1192 if (Password
!= NULL
)
1193 HeapFree(GetProcessHeap(), 0, Password
);
1208 PGINA_CONTEXT pgContext
;
1209 INT result
= WLX_SAS_ACTION_NONE
;
1211 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1217 pgContext
= (PGINA_CONTEXT
)lParam
;
1218 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
1220 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1222 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
1223 SetFocus(GetDlgItem(hwndDlg
, IDC_PASSWORD
));
1225 if (pgContext
->bDisableCAD
)
1226 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1228 /* Draw the logo bitmap */
1229 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1236 if (pgContext
->hBitmap
)
1238 BeginPaint(hwndDlg
, &ps
);
1239 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1240 EndPaint(hwndDlg
, &ps
);
1245 DeleteObject(pgContext
->hBitmap
);
1249 switch (LOWORD(wParam
))
1252 if (DoUnlock(hwndDlg
, pgContext
, &result
))
1253 EndDialog(hwndDlg
, result
);
1257 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1269 IN OUT PGINA_CONTEXT pgContext
)
1273 TRACE("GUILockedSAS()\n");
1275 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1277 pgContext
->hDllInstance
,
1278 MAKEINTRESOURCEW(IDD_UNLOCK_DLG
),
1282 if (result
>= WLX_SAS_ACTION_LOGON
&&
1283 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1285 WARN("GUILockedSAS() returns 0x%x\n", result
);
1289 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1290 return WLX_SAS_ACTION_NONE
;
1294 static INT_PTR CALLBACK
1301 PGINA_CONTEXT pgContext
;
1303 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1309 pgContext
= (PGINA_CONTEXT
)lParam
;
1310 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
1312 /* Draw the logo bitmap */
1313 pgContext
->hBitmap
= LoadImageW(pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1314 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
1320 if (pgContext
->hBitmap
)
1322 BeginPaint(hwndDlg
, &ps
);
1323 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1324 EndPaint(hwndDlg
, &ps
);
1330 DeleteObject(pgContext
->hBitmap
);
1340 GUIDisplayLockedNotice(
1341 IN OUT PGINA_CONTEXT pgContext
)
1343 TRACE("GUIdisplayLockedNotice()\n");
1345 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1347 pgContext
->hDllInstance
,
1348 MAKEINTRESOURCEW(IDD_LOCKED_DLG
),
1354 GINA_UI GinaGraphicalUI
= {
1356 GUIDisplayStatusMessage
,
1357 GUIRemoveStatusMessage
,
1358 GUIDisplaySASNotice
,
1362 GUIDisplayLockedNotice
,