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
;
39 } DLG_DATA
, *PDLG_DATA
;
43 IN OUT PGINA_CONTEXT pgContext
)
45 TRACE("GUIInitialize(%p)\n", pgContext
);
52 SetWelcomeText(HWND hWnd
)
54 PWCHAR pBuffer
= NULL
, p
;
56 DWORD BufSize
, dwType
, dwWelcomeSize
, dwTitleLength
;
59 TRACE("SetWelcomeText(%p)\n", hWnd
);
61 /* Open the Winlogon key */
62 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
63 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
67 if (rc
!= ERROR_SUCCESS
)
69 WARN("RegOpenKeyExW() failed with error %lu\n", rc
);
73 /* Get the size of the Welcome value */
75 rc
= RegQueryValueExW(hKey
,
81 if (rc
== ERROR_FILE_NOT_FOUND
|| dwWelcomeSize
== 0 || dwType
!= REG_SZ
)
84 dwTitleLength
= GetWindowTextLengthW(hWnd
);
85 BufSize
= dwWelcomeSize
+ ((dwTitleLength
+ 1) * sizeof(WCHAR
));
87 pBuffer
= HeapAlloc(GetProcessHeap(), 0, BufSize
);
91 GetWindowTextW(hWnd
, pBuffer
, BufSize
/ sizeof(WCHAR
));
92 wcscat(pBuffer
, L
" ");
93 p
= &pBuffer
[dwTitleLength
+ 1];
95 RegQueryValueExW(hKey
,
102 SetWindowText(hWnd
, pBuffer
);
106 HeapFree(GetProcessHeap(), 0, pBuffer
);
112 static INT_PTR CALLBACK
120 UNREFERENCED_PARAMETER(wParam
);
122 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
128 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
132 msg
->Context
->hStatusWindow
= hwndDlg
;
135 SetWindowTextW(hwndDlg
, msg
->pTitle
);
136 SetDlgItemTextW(hwndDlg
, IDC_STATUS_MESSAGE
, msg
->pMessage
);
137 SetEvent(msg
->StartupEvent
);
139 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
140 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
142 if (pDlgData
== NULL
)
145 /* Load the bar bitmap */
146 pDlgData
->hBarBitmap
= LoadImageW(hDllInstance
, MAKEINTRESOURCEW(IDI_BAR
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
147 if (pDlgData
->hBarBitmap
)
151 GetObject(pDlgData
->hBarBitmap
, sizeof(BITMAP
), &bm
);
152 pDlgData
->BarWidth
= bm
.bmWidth
;
153 pDlgData
->BarHeight
= bm
.bmHeight
;
154 pDlgData
->TimerID
= SetTimer(hwndDlg
, -1, 20, NULL
);
164 * Default rotation bar image width is 413 (same as logo)
165 * We can divide 413 by 7 without remainder
167 pDlgData
->BarCounter
= (pDlgData
->BarCounter
+ 7) % pDlgData
->BarWidth
;
168 InvalidateRect(hwndDlg
, NULL
, FALSE
);
169 UpdateWindow(hwndDlg
);
176 LPDRAWITEMSTRUCT lpDis
= (LPDRAWITEMSTRUCT
)lParam
;
178 if (lpDis
->CtlID
!= IDC_BAR
)
183 if (pDlgData
&& pDlgData
->hBarBitmap
)
187 DWORD off
= pDlgData
->BarCounter
;
188 DWORD iw
= pDlgData
->BarWidth
;
189 DWORD ih
= pDlgData
->BarHeight
;
191 hdcMem
= CreateCompatibleDC(lpDis
->hDC
);
192 hOld
= SelectObject(hdcMem
, pDlgData
->hBarBitmap
);
193 BitBlt(lpDis
->hDC
, off
, 0, iw
- off
, ih
, hdcMem
, 0, 0, SRCCOPY
);
194 BitBlt(lpDis
->hDC
, 0, 0, off
, ih
, hdcMem
, iw
- off
, 0, SRCCOPY
);
195 SelectObject(hdcMem
, hOld
);
207 if (pDlgData
->hBarBitmap
)
209 KillTimer(hwndDlg
, pDlgData
->TimerID
);
210 DeleteObject(pDlgData
->hBarBitmap
);
212 HeapFree(GetProcessHeap(), 0, pDlgData
);
221 StartupWindowThread(LPVOID lpParam
)
224 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
226 /* When SetThreadDesktop is called the system closes the desktop handle when needed
227 so we have to create a new handle because this handle may still be in use by winlogon */
228 if (!DuplicateHandle ( GetCurrentProcess(),
234 DUPLICATE_SAME_ACCESS
))
236 ERR("Duplicating handle failed!\n");
237 HeapFree(GetProcessHeap(), 0, lpParam
);
241 if(!SetThreadDesktop(hDesk
))
243 ERR("Setting thread desktop failed!\n");
244 HeapFree(GetProcessHeap(), 0, lpParam
);
250 MAKEINTRESOURCEW(IDD_STATUS
),
255 HeapFree(GetProcessHeap(), 0, lpParam
);
260 GUIDisplayStatusMessage(
261 IN PGINA_CONTEXT pgContext
,
267 PDISPLAYSTATUSMSG msg
;
271 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage
);
273 if (!pgContext
->hStatusWindow
)
276 * If everything goes correctly, 'msg' is freed
277 * by the 'StartupWindowThread' thread.
279 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(),
285 msg
->Context
= pgContext
;
286 msg
->dwOptions
= dwOptions
;
287 msg
->pTitle
= pTitle
;
288 msg
->pMessage
= pMessage
;
289 msg
->hDesktop
= hDesktop
;
291 msg
->StartupEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
293 if (!msg
->StartupEvent
)
295 HeapFree(GetProcessHeap(), 0, msg
);
299 Thread
= CreateThread(NULL
,
307 /* 'msg' will be freed by 'StartupWindowThread' */
310 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
311 CloseHandle(msg
->StartupEvent
);
317 * The 'StartupWindowThread' thread couldn't be created,
318 * so we need to free the allocated 'msg'.
320 HeapFree(GetProcessHeap(), 0, msg
);
327 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
329 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUS_MESSAGE
, pMessage
);
335 GUIRemoveStatusMessage(
336 IN PGINA_CONTEXT pgContext
)
338 if (pgContext
->hStatusWindow
)
340 EndDialog(pgContext
->hStatusWindow
, 0);
341 pgContext
->hStatusWindow
= NULL
;
347 static INT_PTR CALLBACK
356 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
362 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
363 if (pDlgData
== NULL
)
366 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
368 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
370 /* Load the logo bitmap */
371 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
378 if (pDlgData
->hBitmap
)
380 BeginPaint(hwndDlg
, &ps
);
381 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
382 EndPaint(hwndDlg
, &ps
);
388 DeleteObject(pDlgData
->hBitmap
);
389 HeapFree(GetProcessHeap(), 0, pDlgData
);
398 IN OUT PGINA_CONTEXT pgContext
)
400 TRACE("GUIDisplaySASNotice()\n");
402 /* Display the notice window */
403 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
404 pgContext
->hDllInstance
,
405 MAKEINTRESOURCEW(IDD_WELCOME
),
411 /* Get the text contained in a textbox. Allocates memory in pText
412 * to contain the text. Returns TRUE in case of success */
422 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
423 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
426 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
428 HeapFree(GetProcessHeap(), 0, Text
);
439 IN PGINA_CONTEXT pgContext
,
445 WCHAR szCaption
[256];
448 LoadStringW(pgContext
->hDllInstance
, uCaption
, szCaption
, _countof(szCaption
));
449 LoadStringW(pgContext
->hDllInstance
, uText
, szText
, _countof(szText
));
451 return pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
462 IN PGINA_CONTEXT pgContext
,
467 WCHAR OldPassword
[256];
468 WCHAR NewPassword1
[256];
469 WCHAR NewPassword2
[256];
470 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
471 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
472 ULONG RequestBufferSize
;
473 ULONG ResponseBufferSize
= 0;
476 NTSTATUS ProtocolStatus
;
479 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, UserName
, _countof(UserName
));
480 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, Domain
, _countof(Domain
));
481 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_OLDPWD
, OldPassword
, _countof(OldPassword
));
482 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NewPassword1
, _countof(NewPassword1
));
483 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NewPassword2
, _countof(NewPassword2
));
485 /* Compare the two passwords and fail if they do not match */
486 if (wcscmp(NewPassword1
, NewPassword2
) != 0)
488 ResourceMessageBox(pgContext
,
490 MB_OK
| MB_ICONEXCLAMATION
,
492 IDS_NONMATCHINGPASSWORDS
);
496 /* Calculate the request buffer size */
497 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
498 ((wcslen(Domain
) + 1) * sizeof(WCHAR
)) +
499 ((wcslen(UserName
) + 1) * sizeof(WCHAR
)) +
500 ((wcslen(OldPassword
) + 1) * sizeof(WCHAR
)) +
501 ((wcslen(NewPassword1
) + 1) * sizeof(WCHAR
));
503 /* Allocate the request buffer */
504 RequestBuffer
= HeapAlloc(GetProcessHeap(),
507 if (RequestBuffer
== NULL
)
509 ERR("HeapAlloc failed\n");
513 /* Initialize the request buffer */
514 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
515 RequestBuffer
->Impersonating
= TRUE
;
517 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
519 /* Pack the domain name */
520 RequestBuffer
->DomainName
.Length
= wcslen(Domain
) * sizeof(WCHAR
);
521 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
522 RequestBuffer
->DomainName
.Buffer
= Ptr
;
524 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
526 RequestBuffer
->DomainName
.MaximumLength
);
528 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
530 /* Pack the user name */
531 RequestBuffer
->AccountName
.Length
= wcslen(UserName
) * sizeof(WCHAR
);
532 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
533 RequestBuffer
->AccountName
.Buffer
= Ptr
;
535 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
537 RequestBuffer
->AccountName
.MaximumLength
);
539 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
541 /* Pack the old password */
542 RequestBuffer
->OldPassword
.Length
= wcslen(OldPassword
) * sizeof(WCHAR
);
543 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
544 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
546 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
548 RequestBuffer
->OldPassword
.MaximumLength
);
550 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
552 /* Pack the new password */
553 RequestBuffer
->NewPassword
.Length
= wcslen(NewPassword1
) * sizeof(WCHAR
);
554 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
555 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
557 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
559 RequestBuffer
->NewPassword
.MaximumLength
);
561 /* Connect to the LSA server */
562 if (ConnectToLsa(pgContext
) != ERROR_SUCCESS
)
564 ERR("ConnectToLsa() failed\n");
568 /* Call the authentication package */
569 Status
= LsaCallAuthenticationPackage(pgContext
->LsaHandle
,
570 pgContext
->AuthenticationPackage
,
573 (PVOID
*)&ResponseBuffer
,
576 if (!NT_SUCCESS(Status
))
578 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status
);
582 if (!NT_SUCCESS(ProtocolStatus
))
584 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus
);
590 ResourceMessageBox(pgContext
,
592 MB_OK
| MB_ICONINFORMATION
,
594 IDS_PASSWORDCHANGED
);
596 if ((wcscmp(UserName
, pgContext
->UserName
) == 0) &&
597 (wcscmp(Domain
, pgContext
->DomainName
) == 0) &&
598 (wcscmp(OldPassword
, pgContext
->Password
) == 0))
600 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
601 wcscpy(pgContext
->Password
, NewPassword1
);
605 if (RequestBuffer
!= NULL
)
606 HeapFree(GetProcessHeap(), 0, RequestBuffer
);
608 if (ResponseBuffer
!= NULL
)
609 LsaFreeReturnBuffer(ResponseBuffer
);
615 static INT_PTR CALLBACK
616 ChangePasswordDialogProc(
622 PGINA_CONTEXT pgContext
;
624 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
630 pgContext
= (PGINA_CONTEXT
)lParam
;
631 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
633 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, pgContext
->UserName
);
634 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
635 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_SETCURSEL
, 0, 0);
636 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
641 switch (LOWORD(wParam
))
644 if (DoChangePassword(pgContext
, hwndDlg
))
646 EndDialog(hwndDlg
, TRUE
);
650 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NULL
);
651 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NULL
);
652 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
657 EndDialog(hwndDlg
, FALSE
);
663 EndDialog(hwndDlg
, FALSE
);
672 OnInitSecurityDlg(HWND hwnd
,
673 PGINA_CONTEXT pgContext
)
680 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, _countof(Buffer1
));
682 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
683 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
685 SetDlgItemTextW(hwnd
, IDC_SECURITY_MESSAGE
, Buffer4
);
687 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, _countof(Buffer1
));
689 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
690 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, _countof(Buffer2
));
692 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
693 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, _countof(Buffer3
));
695 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
697 SetDlgItemTextW(hwnd
, IDC_SECURITY_LOGONDATE
, Buffer4
);
699 if (pgContext
->bAutoAdminLogon
)
700 EnableWindow(GetDlgItem(hwnd
, IDC_SECURITY_LOGOFF
), FALSE
);
707 IN PGINA_CONTEXT pgContext
)
711 TRACE("OnChangePassword()\n");
713 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
715 pgContext
->hDllInstance
,
716 MAKEINTRESOURCEW(IDD_CHANGEPWD
),
718 ChangePasswordDialogProc
,
721 TRACE("Result: %x\n", res
);
727 static INT_PTR CALLBACK
740 switch (LOWORD(wParam
))
743 EndDialog(hwndDlg
, IDYES
);
747 EndDialog(hwndDlg
, IDNO
);
753 EndDialog(hwndDlg
, IDNO
);
765 IN PGINA_CONTEXT pgContext
)
767 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
769 pgContext
->hDllInstance
,
770 MAKEINTRESOURCEW(IDD_LOGOFF
),
781 IN PGINA_CONTEXT pgContext
)
784 DWORD ShutdownOptions
;
786 TRACE("OnShutDown(%p %p)\n", hwndDlg
, pgContext
);
788 pgContext
->nShutdownAction
= GetDefaultShutdownSelState();
789 ShutdownOptions
= GetDefaultShutdownOptions();
791 if (pgContext
->UserToken
!= NULL
)
793 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
795 pgContext
->nShutdownAction
= LoadShutdownSelState();
796 ShutdownOptions
= GetAllowedShutdownOptions();
801 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
805 ret
= ShutdownDialog(hwndDlg
, ShutdownOptions
, pgContext
);
809 if (pgContext
->UserToken
!= NULL
)
811 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
813 SaveShutdownSelState(pgContext
->nShutdownAction
);
818 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
827 static INT_PTR CALLBACK
834 PGINA_CONTEXT pgContext
;
836 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
842 pgContext
= (PGINA_CONTEXT
)lParam
;
843 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
845 SetWelcomeText(hwndDlg
);
847 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
848 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
854 switch (LOWORD(wParam
))
856 case IDC_SECURITY_LOCK
:
857 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
859 case IDC_SECURITY_LOGOFF
:
860 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
861 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
863 case IDC_SECURITY_SHUTDOWN
:
864 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
865 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
867 case IDC_SECURITY_CHANGEPWD
:
868 if (OnChangePassword(hwndDlg
, pgContext
))
869 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
871 case IDC_SECURITY_TASKMGR
:
872 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
875 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
882 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
892 IN OUT PGINA_CONTEXT pgContext
,
897 TRACE("GUILoggedOnSAS()\n");
899 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
901 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
902 * close itself thanks to the use of WlxDialogBoxParam */
903 return WLX_SAS_ACTION_NONE
;
906 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
909 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
911 pgContext
->hDllInstance
,
912 MAKEINTRESOURCEW(IDD_SECURITY
),
917 if (result
< WLX_SAS_ACTION_LOGON
||
918 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
920 result
= WLX_SAS_ACTION_NONE
;
923 if (result
== WLX_SAS_ACTION_NONE
)
925 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
937 IN OUT PGINA_CONTEXT pgContext
)
939 LPWSTR UserName
= NULL
;
940 LPWSTR Password
= NULL
;
941 LPWSTR Domain
= NULL
;
943 NTSTATUS Status
, SubStatus
= STATUS_SUCCESS
;
945 if (GetTextboxText(hwndDlg
, IDC_LOGON_USERNAME
, &UserName
) && *UserName
== '\0')
948 if (GetTextboxText(hwndDlg
, IDC_LOGON_DOMAIN
, &Domain
) && *Domain
== '\0')
951 if (!GetTextboxText(hwndDlg
, IDC_LOGON_PASSWORD
, &Password
))
954 Status
= DoLoginTasks(pgContext
, UserName
, Domain
, Password
, &SubStatus
);
955 if (Status
== STATUS_LOGON_FAILURE
)
957 ResourceMessageBox(pgContext
,
959 MB_OK
| MB_ICONEXCLAMATION
,
961 IDS_LOGONWRONGUSERORPWD
);
964 else if (Status
== STATUS_ACCOUNT_RESTRICTION
)
966 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status
, SubStatus
);
968 if (SubStatus
== STATUS_ACCOUNT_DISABLED
)
970 ResourceMessageBox(pgContext
,
972 MB_OK
| MB_ICONEXCLAMATION
,
974 IDS_LOGONUSERDISABLED
);
977 else if (SubStatus
== STATUS_ACCOUNT_LOCKED_OUT
)
979 TRACE("Account locked!\n");
980 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
984 MB_OK
| MB_ICONERROR
);
987 else if ((SubStatus
== STATUS_PASSWORD_MUST_CHANGE
) ||
988 (SubStatus
== STATUS_PASSWORD_EXPIRED
))
990 if (SubStatus
== STATUS_PASSWORD_MUST_CHANGE
)
991 ResourceMessageBox(pgContext
,
995 IDS_PASSWORDMUSTCHANGE
);
997 ResourceMessageBox(pgContext
,
1001 IDS_PASSWORDEXPIRED
);
1003 if (!OnChangePassword(hwndDlg
,
1007 Status
= DoLoginTasks(pgContext
,
1008 pgContext
->UserName
,
1009 pgContext
->DomainName
,
1010 pgContext
->Password
,
1012 if (!NT_SUCCESS(Status
))
1014 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status
);
1019 else if (SubStatus
== STATUS_ACCOUNT_EXPIRED
)
1021 ResourceMessageBox(pgContext
,
1023 MB_OK
| MB_ICONEXCLAMATION
,
1025 IDS_ACCOUNTEXPIRED
);
1029 TRACE("Other error!\n");
1030 pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
1034 MB_OK
| MB_ICONERROR
);
1038 else if (!NT_SUCCESS(Status
))
1040 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
1045 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
1047 ERR("Failed to create the profile!\n");
1051 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
1052 wcscpy(pgContext
->Password
, Password
);
1057 pgContext
->bAutoAdminLogon
= FALSE
;
1059 if (UserName
!= NULL
)
1060 HeapFree(GetProcessHeap(), 0, UserName
);
1062 if (Password
!= NULL
)
1063 HeapFree(GetProcessHeap(), 0, Password
);
1066 HeapFree(GetProcessHeap(), 0, Domain
);
1075 HWND hwndDomainComboBox
,
1076 PGINA_CONTEXT pgContext
)
1078 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1079 DWORD dwComputerNameLength
;
1083 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
1085 dwComputerNameLength
= _countof(szComputerName
);
1086 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
1088 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
1091 if (wcslen(pgContext
->DomainName
) != 0)
1093 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->DomainName
);
1094 if (lFindIndex
== CB_ERR
)
1096 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
1100 lIndex
= lFindIndex
;
1104 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
1108 static INT_PTR CALLBACK
1117 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1123 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1124 if (pDlgData
== NULL
)
1127 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1129 /* FIXME: take care of NoDomainUI */
1130 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1132 /* Draw the logo bitmap */
1133 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1135 SetWelcomeText(hwndDlg
);
1137 if (pDlgData
->pgContext
->bAutoAdminLogon
||
1138 !pDlgData
->pgContext
->bDontDisplayLastUserName
)
1139 SetDlgItemTextW(hwndDlg
, IDC_LOGON_USERNAME
, pDlgData
->pgContext
->UserName
);
1141 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1142 SetDlgItemTextW(hwndDlg
, IDC_LOGON_PASSWORD
, pDlgData
->pgContext
->Password
);
1144 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_DOMAIN
), pDlgData
->pgContext
);
1146 if (pDlgData
->pgContext
->bDisableCAD
)
1147 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1149 if (!pDlgData
->pgContext
->bShutdownWithoutLogon
)
1150 EnableWindow(GetDlgItem(hwndDlg
, IDC_LOGON_SHUTDOWN
), FALSE
);
1152 SetFocus(GetDlgItem(hwndDlg
, pDlgData
->pgContext
->bDontDisplayLastUserName
? IDC_LOGON_USERNAME
: IDC_LOGON_PASSWORD
));
1154 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1155 PostMessage(GetDlgItem(hwndDlg
, IDOK
), BM_CLICK
, 0, 0);
1163 if (pDlgData
->hBitmap
)
1165 BeginPaint(hwndDlg
, &ps
);
1166 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1167 EndPaint(hwndDlg
, &ps
);
1173 DeleteObject(pDlgData
->hBitmap
);
1174 HeapFree(GetProcessHeap(), 0, pDlgData
);
1178 switch (LOWORD(wParam
))
1181 if (DoLogon(hwndDlg
, pDlgData
->pgContext
))
1182 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1186 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1189 case IDC_LOGON_SHUTDOWN
:
1190 if (OnShutDown(hwndDlg
, pDlgData
->pgContext
) == IDOK
)
1191 EndDialog(hwndDlg
, pDlgData
->pgContext
->nShutdownAction
);
1204 LegalNoticeDialogProc(
1210 PLEGALNOTICEDATA pLegalNotice
;
1215 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1216 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1217 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1221 switch (LOWORD(wParam
))
1224 EndDialog(hwndDlg
, 0);
1228 EndDialog(hwndDlg
, 0);
1240 IN OUT PGINA_CONTEXT pgContext
)
1242 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1247 TRACE("GUILoggedOutSAS()\n");
1249 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1250 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1254 if (rc
== ERROR_SUCCESS
)
1256 ReadRegSzValue(hKey
,
1257 L
"LegalNoticeCaption",
1258 &LegalNotice
.pszCaption
);
1260 ReadRegSzValue(hKey
,
1262 &LegalNotice
.pszText
);
1267 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1268 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1270 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1271 pgContext
->hDllInstance
,
1272 MAKEINTRESOURCEW(IDD_LEGALNOTICE
),
1274 LegalNoticeDialogProc
,
1275 (LPARAM
)&LegalNotice
);
1278 if (LegalNotice
.pszCaption
!= NULL
)
1279 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1281 if (LegalNotice
.pszText
!= NULL
)
1282 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1284 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1286 pgContext
->hDllInstance
,
1287 MAKEINTRESOURCEW(IDD_LOGON
),
1291 if (result
>= WLX_SAS_ACTION_LOGON
&&
1292 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1294 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1298 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1299 return WLX_SAS_ACTION_NONE
;
1304 SetLockMessage(HWND hwnd
,
1306 PGINA_CONTEXT pgContext
)
1312 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1314 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
1315 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1317 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1325 IN PGINA_CONTEXT pgContext
,
1330 LPWSTR UserName
= NULL
;
1331 LPWSTR Password
= NULL
;
1334 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_USERNAME
, &UserName
) && *UserName
== '\0')
1336 HeapFree(GetProcessHeap(), 0, UserName
);
1340 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_PASSWORD
, &Password
))
1342 if (UserName
!= NULL
&& Password
!= NULL
&&
1343 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1344 wcscmp(Password
, pgContext
->Password
) == 0)
1346 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1349 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1350 wcscmp(Password
, pgContext
->Password
) != 0)
1352 /* Wrong Password */
1353 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1354 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1355 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1359 /* Wrong user name */
1360 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1362 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1367 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1368 wsprintfW(Buffer2
, Buffer1
, pgContext
->DomainName
, pgContext
->UserName
);
1369 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1370 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1375 if (UserName
!= NULL
)
1376 HeapFree(GetProcessHeap(), 0, UserName
);
1378 if (Password
!= NULL
)
1379 HeapFree(GetProcessHeap(), 0, Password
);
1395 INT result
= WLX_SAS_ACTION_NONE
;
1397 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1403 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1404 if (pDlgData
== NULL
)
1407 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1409 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1411 SetWelcomeText(hwndDlg
);
1413 SetLockMessage(hwndDlg
, IDC_UNLOCK_MESSAGE
, pDlgData
->pgContext
);
1415 SetDlgItemTextW(hwndDlg
, IDC_UNLOCK_USERNAME
, pDlgData
->pgContext
->UserName
);
1416 SetFocus(GetDlgItem(hwndDlg
, IDC_UNLOCK_PASSWORD
));
1418 if (pDlgData
->pgContext
->bDisableCAD
)
1419 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1421 /* Load the logo bitmap */
1422 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1429 if (pDlgData
->hBitmap
)
1431 BeginPaint(hwndDlg
, &ps
);
1432 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1433 EndPaint(hwndDlg
, &ps
);
1438 DeleteObject(pDlgData
->hBitmap
);
1439 HeapFree(GetProcessHeap(), 0, pDlgData
);
1443 switch (LOWORD(wParam
))
1446 if (DoUnlock(hwndDlg
, pDlgData
->pgContext
, &result
))
1447 EndDialog(hwndDlg
, result
);
1451 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1463 IN OUT PGINA_CONTEXT pgContext
)
1467 TRACE("GUILockedSAS()\n");
1469 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1471 pgContext
->hDllInstance
,
1472 MAKEINTRESOURCEW(IDD_UNLOCK
),
1476 if (result
>= WLX_SAS_ACTION_LOGON
&&
1477 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1479 WARN("GUILockedSAS() returns 0x%x\n", result
);
1483 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1484 return WLX_SAS_ACTION_NONE
;
1488 static INT_PTR CALLBACK
1497 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1503 pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DLG_DATA
));
1504 if (pDlgData
== NULL
)
1507 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
1509 pDlgData
->pgContext
= (PGINA_CONTEXT
)lParam
;
1511 /* Load the logo bitmap */
1512 pDlgData
->hBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
, MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
1514 SetWelcomeText(hwndDlg
);
1516 SetLockMessage(hwndDlg
, IDC_LOCKED_MESSAGE
, pDlgData
->pgContext
);
1522 if (pDlgData
->hBitmap
)
1524 BeginPaint(hwndDlg
, &ps
);
1525 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1526 EndPaint(hwndDlg
, &ps
);
1532 DeleteObject(pDlgData
->hBitmap
);
1533 HeapFree(GetProcessHeap(), 0, pDlgData
);
1543 GUIDisplayLockedNotice(
1544 IN OUT PGINA_CONTEXT pgContext
)
1546 TRACE("GUIdisplayLockedNotice()\n");
1548 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1550 pgContext
->hDllInstance
,
1551 MAKEINTRESOURCEW(IDD_LOCKED
),
1557 GINA_UI GinaGraphicalUI
= {
1559 GUIDisplayStatusMessage
,
1560 GUIRemoveStatusMessage
,
1561 GUIDisplaySASNotice
,
1565 GUIDisplayLockedNotice
,