2 * PROJECT: ReactOS msgina.dll
3 * FILE: dll/win32/msgina/gui.c
4 * PURPOSE: ReactOS Logon GINA DLL
5 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
6 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
15 typedef struct _DISPLAYSTATUSMSG
17 PGINA_CONTEXT Context
;
23 } DISPLAYSTATUSMSG
, *PDISPLAYSTATUSMSG
;
25 typedef struct _LEGALNOTICEDATA
29 } LEGALNOTICEDATA
, *PLEGALNOTICEDATA
;
31 // Timer ID for the animated dialog bar.
34 typedef struct _DLG_DATA
36 PGINA_CONTEXT pgContext
;
45 } DLG_DATA
, *PDLG_DATA
;
48 DlgData_Create(HWND hwndDlg
, PGINA_CONTEXT pgContext
)
50 PDLG_DATA pDlgData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*pDlgData
));
53 pDlgData
->pgContext
= pgContext
;
54 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pDlgData
);
60 DlgData_LoadBitmaps(_Inout_ PDLG_DATA pDlgData
)
69 pDlgData
->hLogoBitmap
= LoadImageW(pDlgData
->pgContext
->hDllInstance
,
70 MAKEINTRESOURCEW(IDI_ROSLOGO
), IMAGE_BITMAP
,
71 0, 0, LR_DEFAULTCOLOR
);
72 if (pDlgData
->hLogoBitmap
)
74 GetObject(pDlgData
->hLogoBitmap
, sizeof(bm
), &bm
);
75 pDlgData
->LogoWidth
= bm
.bmWidth
;
76 pDlgData
->LogoHeight
= bm
.bmHeight
;
79 pDlgData
->hBarBitmap
= LoadImageW(hDllInstance
, MAKEINTRESOURCEW(IDI_BAR
),
80 IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
81 if (pDlgData
->hBarBitmap
)
83 GetObject(pDlgData
->hBarBitmap
, sizeof(bm
), &bm
);
84 pDlgData
->BarWidth
= bm
.bmWidth
;
85 pDlgData
->BarHeight
= bm
.bmHeight
;
90 DlgData_Destroy(_Inout_ HWND hwndDlg
)
94 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
100 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)NULL
);
102 if (pDlgData
->hBarBitmap
)
104 DeleteObject(pDlgData
->hBarBitmap
);
107 if (pDlgData
->hLogoBitmap
)
109 DeleteObject(pDlgData
->hLogoBitmap
);
112 HeapFree(GetProcessHeap(), 0, pDlgData
);
117 IN OUT PGINA_CONTEXT pgContext
)
119 TRACE("GUIInitialize(%p)\n", pgContext
);
125 SetWelcomeText(HWND hWnd
)
127 PWCHAR pBuffer
= NULL
, p
;
129 DWORD BufSize
, dwType
, dwWelcomeSize
, dwTitleLength
;
132 TRACE("SetWelcomeText(%p)\n", hWnd
);
134 /* Open the Winlogon key */
135 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
136 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
140 if (rc
!= ERROR_SUCCESS
)
142 WARN("RegOpenKeyExW() failed with error %lu\n", rc
);
146 /* Get the size of the Welcome value */
148 rc
= RegQueryValueExW(hKey
,
154 if (rc
== ERROR_FILE_NOT_FOUND
|| dwWelcomeSize
== 0 || dwType
!= REG_SZ
)
157 dwTitleLength
= GetWindowTextLengthW(hWnd
);
158 BufSize
= dwWelcomeSize
+ ((dwTitleLength
+ 1) * sizeof(WCHAR
));
160 pBuffer
= HeapAlloc(GetProcessHeap(), 0, BufSize
);
164 GetWindowTextW(hWnd
, pBuffer
, BufSize
/ sizeof(WCHAR
));
165 wcscat(pBuffer
, L
" ");
166 p
= &pBuffer
[dwTitleLength
+ 1];
168 RegQueryValueExW(hKey
,
175 SetWindowText(hWnd
, pBuffer
);
179 HeapFree(GetProcessHeap(), 0, pBuffer
);
185 static INT_PTR CALLBACK
193 UNREFERENCED_PARAMETER(wParam
);
195 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
201 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
205 msg
->Context
->hStatusWindow
= hwndDlg
;
208 SetWindowTextW(hwndDlg
, msg
->pTitle
);
209 SetDlgItemTextW(hwndDlg
, IDC_STATUS_MESSAGE
, msg
->pMessage
);
210 SetEvent(msg
->StartupEvent
);
212 pDlgData
= DlgData_Create(hwndDlg
, msg
->Context
);
213 if (pDlgData
== NULL
)
216 DlgData_LoadBitmaps(pDlgData
);
217 if (pDlgData
->hBarBitmap
)
219 if (SetTimer(hwndDlg
, IDT_BAR
, 20, NULL
) == 0)
221 ERR("SetTimer(IDT_BAR) failed: %d\n", GetLastError());
225 /* Get the animation bar control */
226 pDlgData
->hWndBarCtrl
= GetDlgItem(hwndDlg
, IDC_BAR
);
234 if (pDlgData
&& pDlgData
->hBarBitmap
)
237 * Default rotation bar image width is 413 (same as logo)
238 * We can divide 413 by 7 without remainder
240 pDlgData
->BarCounter
= (pDlgData
->BarCounter
+ 7) % pDlgData
->BarWidth
;
241 InvalidateRect(pDlgData
->hWndBarCtrl
, NULL
, FALSE
);
242 UpdateWindow(pDlgData
->hWndBarCtrl
);
249 LPDRAWITEMSTRUCT lpDis
= (LPDRAWITEMSTRUCT
)lParam
;
251 if (lpDis
->CtlID
!= IDC_BAR
)
256 if (pDlgData
&& pDlgData
->hBarBitmap
)
260 DWORD off
= pDlgData
->BarCounter
;
261 DWORD iw
= pDlgData
->BarWidth
;
262 DWORD ih
= pDlgData
->BarHeight
;
264 hdcMem
= CreateCompatibleDC(lpDis
->hDC
);
265 hOld
= SelectObject(hdcMem
, pDlgData
->hBarBitmap
);
266 BitBlt(lpDis
->hDC
, off
, 0, iw
- off
, ih
, hdcMem
, 0, 0, SRCCOPY
);
267 BitBlt(lpDis
->hDC
, 0, 0, off
, ih
, hdcMem
, iw
- off
, 0, SRCCOPY
);
268 SelectObject(hdcMem
, hOld
);
278 if (pDlgData
&& pDlgData
->hBarBitmap
)
280 KillTimer(hwndDlg
, IDT_BAR
);
282 DlgData_Destroy(hwndDlg
);
290 StartupWindowThread(LPVOID lpParam
)
293 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
295 /* When SetThreadDesktop is called the system closes the desktop handle when needed
296 so we have to create a new handle because this handle may still be in use by winlogon */
297 if (!DuplicateHandle ( GetCurrentProcess(),
303 DUPLICATE_SAME_ACCESS
))
305 ERR("Duplicating handle failed!\n");
306 HeapFree(GetProcessHeap(), 0, lpParam
);
310 if(!SetThreadDesktop(hDesk
))
312 ERR("Setting thread desktop failed!\n");
313 HeapFree(GetProcessHeap(), 0, lpParam
);
319 MAKEINTRESOURCEW(IDD_STATUS
),
324 HeapFree(GetProcessHeap(), 0, lpParam
);
329 GUIDisplayStatusMessage(
330 IN PGINA_CONTEXT pgContext
,
336 PDISPLAYSTATUSMSG msg
;
340 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage
);
342 if (!pgContext
->hStatusWindow
)
345 * If everything goes correctly, 'msg' is freed
346 * by the 'StartupWindowThread' thread.
348 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(),
354 msg
->Context
= pgContext
;
355 msg
->dwOptions
= dwOptions
;
356 msg
->pTitle
= pTitle
;
357 msg
->pMessage
= pMessage
;
358 msg
->hDesktop
= hDesktop
;
360 msg
->StartupEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
362 if (!msg
->StartupEvent
)
364 HeapFree(GetProcessHeap(), 0, msg
);
368 Thread
= CreateThread(NULL
,
376 /* 'msg' will be freed by 'StartupWindowThread' */
379 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
380 CloseHandle(msg
->StartupEvent
);
386 * The 'StartupWindowThread' thread couldn't be created,
387 * so we need to free the allocated 'msg'.
389 HeapFree(GetProcessHeap(), 0, msg
);
396 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
398 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUS_MESSAGE
, pMessage
);
404 GUIRemoveStatusMessage(
405 IN PGINA_CONTEXT pgContext
)
407 if (pgContext
->hStatusWindow
)
409 EndDialog(pgContext
->hStatusWindow
, 0);
410 pgContext
->hStatusWindow
= NULL
;
416 static INT_PTR CALLBACK
425 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
431 pDlgData
= DlgData_Create(hwndDlg
, (PGINA_CONTEXT
)lParam
);
432 if (pDlgData
== NULL
)
435 DlgData_LoadBitmaps(pDlgData
);
442 if (pDlgData
&& pDlgData
->hLogoBitmap
)
444 BeginPaint(hwndDlg
, &ps
);
445 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hLogoBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
446 EndPaint(hwndDlg
, &ps
);
452 DlgData_Destroy(hwndDlg
);
461 IN OUT PGINA_CONTEXT pgContext
)
463 TRACE("GUIDisplaySASNotice()\n");
465 /* Display the notice window */
466 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
467 pgContext
->hDllInstance
,
468 MAKEINTRESOURCEW(IDD_WELCOME
),
474 /* Get the text contained in a textbox. Allocates memory in pText
475 * to contain the text. Returns TRUE in case of success */
485 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
486 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
489 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
491 HeapFree(GetProcessHeap(), 0, Text
);
502 IN PGINA_CONTEXT pgContext
,
508 WCHAR szCaption
[256];
511 LoadStringW(pgContext
->hDllInstance
, uCaption
, szCaption
, _countof(szCaption
));
512 LoadStringW(pgContext
->hDllInstance
, uText
, szText
, _countof(szText
));
514 return pgContext
->pWlxFuncs
->WlxMessageBox(pgContext
->hWlx
,
525 IN PGINA_CONTEXT pgContext
,
530 WCHAR OldPassword
[256];
531 WCHAR NewPassword1
[256];
532 WCHAR NewPassword2
[256];
533 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
534 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
535 ULONG RequestBufferSize
;
536 ULONG ResponseBufferSize
= 0;
539 NTSTATUS ProtocolStatus
;
542 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, UserName
, _countof(UserName
));
543 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, Domain
, _countof(Domain
));
544 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_OLDPWD
, OldPassword
, _countof(OldPassword
));
545 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NewPassword1
, _countof(NewPassword1
));
546 GetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NewPassword2
, _countof(NewPassword2
));
548 /* Compare the two passwords and fail if they do not match */
549 if (wcscmp(NewPassword1
, NewPassword2
) != 0)
551 ResourceMessageBox(pgContext
,
553 MB_OK
| MB_ICONEXCLAMATION
,
555 IDS_NONMATCHINGPASSWORDS
);
559 /* Calculate the request buffer size */
560 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
561 ((wcslen(Domain
) + 1) * sizeof(WCHAR
)) +
562 ((wcslen(UserName
) + 1) * sizeof(WCHAR
)) +
563 ((wcslen(OldPassword
) + 1) * sizeof(WCHAR
)) +
564 ((wcslen(NewPassword1
) + 1) * sizeof(WCHAR
));
566 /* Allocate the request buffer */
567 RequestBuffer
= HeapAlloc(GetProcessHeap(),
570 if (RequestBuffer
== NULL
)
572 ERR("HeapAlloc failed\n");
576 /* Initialize the request buffer */
577 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
578 RequestBuffer
->Impersonating
= TRUE
;
580 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
582 /* Pack the domain name */
583 RequestBuffer
->DomainName
.Length
= (USHORT
)wcslen(Domain
) * sizeof(WCHAR
);
584 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
585 RequestBuffer
->DomainName
.Buffer
= Ptr
;
587 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
589 RequestBuffer
->DomainName
.MaximumLength
);
591 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
593 /* Pack the user name */
594 RequestBuffer
->AccountName
.Length
= (USHORT
)wcslen(UserName
) * sizeof(WCHAR
);
595 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
596 RequestBuffer
->AccountName
.Buffer
= Ptr
;
598 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
600 RequestBuffer
->AccountName
.MaximumLength
);
602 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
604 /* Pack the old password */
605 RequestBuffer
->OldPassword
.Length
= (USHORT
)wcslen(OldPassword
) * sizeof(WCHAR
);
606 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
607 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
609 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
611 RequestBuffer
->OldPassword
.MaximumLength
);
613 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
615 /* Pack the new password */
616 RequestBuffer
->NewPassword
.Length
= (USHORT
)wcslen(NewPassword1
) * sizeof(WCHAR
);
617 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
618 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
620 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
622 RequestBuffer
->NewPassword
.MaximumLength
);
624 /* Connect to the LSA server */
625 if (ConnectToLsa(pgContext
) != ERROR_SUCCESS
)
627 ERR("ConnectToLsa() failed\n");
631 /* Call the authentication package */
632 Status
= LsaCallAuthenticationPackage(pgContext
->LsaHandle
,
633 pgContext
->AuthenticationPackage
,
636 (PVOID
*)&ResponseBuffer
,
639 if (!NT_SUCCESS(Status
))
641 ERR("LsaCallAuthenticationPackage failed (Status 0x%08lx)\n", Status
);
645 if (!NT_SUCCESS(ProtocolStatus
))
647 TRACE("LsaCallAuthenticationPackage failed (ProtocolStatus 0x%08lx)\n", ProtocolStatus
);
653 ResourceMessageBox(pgContext
,
655 MB_OK
| MB_ICONINFORMATION
,
657 IDS_PASSWORDCHANGED
);
659 if ((wcscmp(UserName
, pgContext
->UserName
) == 0) &&
660 (wcscmp(Domain
, pgContext
->DomainName
) == 0) &&
661 (wcscmp(OldPassword
, pgContext
->Password
) == 0))
663 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
664 wcscpy(pgContext
->Password
, NewPassword1
);
668 if (RequestBuffer
!= NULL
)
669 HeapFree(GetProcessHeap(), 0, RequestBuffer
);
671 if (ResponseBuffer
!= NULL
)
672 LsaFreeReturnBuffer(ResponseBuffer
);
678 static INT_PTR CALLBACK
679 ChangePasswordDialogProc(
685 PGINA_CONTEXT pgContext
;
687 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
693 pgContext
= (PGINA_CONTEXT
)lParam
;
694 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
696 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_USERNAME
, pgContext
->UserName
);
697 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
698 SendDlgItemMessageW(hwndDlg
, IDC_CHANGEPWD_DOMAIN
, CB_SETCURSEL
, 0, 0);
699 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
704 switch (LOWORD(wParam
))
707 if (DoChangePassword(pgContext
, hwndDlg
))
709 EndDialog(hwndDlg
, TRUE
);
713 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD1
, NULL
);
714 SetDlgItemTextW(hwndDlg
, IDC_CHANGEPWD_NEWPWD2
, NULL
);
715 SetFocus(GetDlgItem(hwndDlg
, IDC_CHANGEPWD_OLDPWD
));
720 EndDialog(hwndDlg
, FALSE
);
726 EndDialog(hwndDlg
, FALSE
);
735 OnInitSecurityDlg(HWND hwnd
,
736 PGINA_CONTEXT pgContext
)
743 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, _countof(Buffer1
));
745 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
746 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
748 SetDlgItemTextW(hwnd
, IDC_SECURITY_MESSAGE
, Buffer4
);
750 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, _countof(Buffer1
));
752 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
753 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, _countof(Buffer2
));
755 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
756 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, _countof(Buffer3
));
758 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
760 SetDlgItemTextW(hwnd
, IDC_SECURITY_LOGONDATE
, Buffer4
);
762 if (pgContext
->bAutoAdminLogon
)
763 EnableWindow(GetDlgItem(hwnd
, IDC_SECURITY_LOGOFF
), FALSE
);
770 IN PGINA_CONTEXT pgContext
)
774 TRACE("OnChangePassword()\n");
776 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
778 pgContext
->hDllInstance
,
779 MAKEINTRESOURCEW(IDD_CHANGEPWD
),
781 ChangePasswordDialogProc
,
784 TRACE("Result: %x\n", res
);
790 static INT_PTR CALLBACK
803 switch (LOWORD(wParam
))
806 EndDialog(hwndDlg
, IDYES
);
810 EndDialog(hwndDlg
, IDNO
);
816 EndDialog(hwndDlg
, IDNO
);
828 IN PGINA_CONTEXT pgContext
)
830 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
832 pgContext
->hDllInstance
,
833 MAKEINTRESOURCEW(IDD_LOGOFF
),
844 IN PGINA_CONTEXT pgContext
)
847 DWORD ShutdownOptions
;
849 TRACE("OnShutDown(%p %p)\n", hwndDlg
, pgContext
);
851 pgContext
->nShutdownAction
= GetDefaultShutdownSelState();
852 ShutdownOptions
= GetDefaultShutdownOptions();
854 if (pgContext
->UserToken
!= NULL
)
856 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
858 pgContext
->nShutdownAction
= LoadShutdownSelState();
859 ShutdownOptions
= GetAllowedShutdownOptions();
864 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
868 ret
= ShutdownDialog(hwndDlg
, ShutdownOptions
, pgContext
);
872 if (pgContext
->UserToken
!= NULL
)
874 if (ImpersonateLoggedOnUser(pgContext
->UserToken
))
876 SaveShutdownSelState(pgContext
->nShutdownAction
);
881 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
890 static INT_PTR CALLBACK
897 PGINA_CONTEXT pgContext
;
899 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
905 pgContext
= (PGINA_CONTEXT
)lParam
;
906 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (LONG_PTR
)pgContext
);
908 SetWelcomeText(hwndDlg
);
910 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
911 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
917 switch (LOWORD(wParam
))
919 case IDC_SECURITY_LOCK
:
920 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
922 case IDC_SECURITY_LOGOFF
:
923 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
924 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
926 case IDC_SECURITY_SHUTDOWN
:
927 if (OnShutDown(hwndDlg
, pgContext
) == IDOK
)
928 EndDialog(hwndDlg
, pgContext
->nShutdownAction
);
930 case IDC_SECURITY_CHANGEPWD
:
931 if (OnChangePassword(hwndDlg
, pgContext
))
932 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
934 case IDC_SECURITY_TASKMGR
:
935 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
938 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
945 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
955 IN OUT PGINA_CONTEXT pgContext
,
960 TRACE("GUILoggedOnSAS()\n");
962 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
964 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
965 * close itself thanks to the use of WlxDialogBoxParam */
966 return WLX_SAS_ACTION_NONE
;
969 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
972 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
974 pgContext
->hDllInstance
,
975 MAKEINTRESOURCEW(IDD_SECURITY
),
980 if (result
< WLX_SAS_ACTION_LOGON
||
981 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
983 result
= WLX_SAS_ACTION_NONE
;
986 if (result
== WLX_SAS_ACTION_NONE
)
988 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
1000 IN OUT PGINA_CONTEXT pgContext
)
1002 LPWSTR UserName
= NULL
;
1003 LPWSTR Password
= NULL
;
1004 LPWSTR Domain
= NULL
;
1005 BOOL result
= FALSE
;
1006 NTSTATUS Status
, SubStatus
= STATUS_SUCCESS
;
1008 if (GetTextboxText(hwndDlg
, IDC_LOGON_USERNAME
, &UserName
) && *UserName
== '\0')
1011 if (GetTextboxText(hwndDlg
, IDC_LOGON_DOMAIN
, &Domain
) && *Domain
== '\0')
1014 if (!GetTextboxText(hwndDlg
, IDC_LOGON_PASSWORD
, &Password
))
1017 Status
= DoLoginTasks(pgContext
, UserName
, Domain
, Password
, &SubStatus
);
1018 if (Status
== STATUS_LOGON_FAILURE
)
1020 ResourceMessageBox(pgContext
,
1022 MB_OK
| MB_ICONEXCLAMATION
,
1024 IDS_LOGONWRONGUSERORPWD
);
1027 else if (Status
== STATUS_ACCOUNT_RESTRICTION
)
1029 TRACE("DoLoginTasks failed! Status 0x%08lx SubStatus 0x%08lx\n", Status
, SubStatus
);
1031 if (SubStatus
== STATUS_ACCOUNT_DISABLED
)
1033 ResourceMessageBox(pgContext
,
1035 MB_OK
| MB_ICONEXCLAMATION
,
1037 IDS_LOGONUSERDISABLED
);
1040 else if (SubStatus
== STATUS_ACCOUNT_LOCKED_OUT
)
1042 TRACE("Account locked!\n");
1043 ResourceMessageBox(pgContext
,
1045 MB_OK
| MB_ICONERROR
,
1050 else if ((SubStatus
== STATUS_PASSWORD_MUST_CHANGE
) ||
1051 (SubStatus
== STATUS_PASSWORD_EXPIRED
))
1053 if (SubStatus
== STATUS_PASSWORD_MUST_CHANGE
)
1054 ResourceMessageBox(pgContext
,
1056 MB_OK
| MB_ICONSTOP
,
1058 IDS_PASSWORDMUSTCHANGE
);
1060 ResourceMessageBox(pgContext
,
1062 MB_OK
| MB_ICONSTOP
,
1064 IDS_PASSWORDEXPIRED
);
1066 if (!OnChangePassword(hwndDlg
,
1070 Status
= DoLoginTasks(pgContext
,
1071 pgContext
->UserName
,
1072 pgContext
->DomainName
,
1073 pgContext
->Password
,
1075 if (!NT_SUCCESS(Status
))
1077 TRACE("Login after password change failed! (Status 0x%08lx)\n", Status
);
1082 else if (SubStatus
== STATUS_ACCOUNT_EXPIRED
)
1084 ResourceMessageBox(pgContext
,
1086 MB_OK
| MB_ICONEXCLAMATION
,
1088 IDS_ACCOUNTEXPIRED
);
1090 else if (SubStatus
== STATUS_INVALID_LOGON_HOURS
)
1092 ResourceMessageBox(pgContext
,
1094 MB_OK
| MB_ICONERROR
,
1096 IDS_INVALIDLOGONHOURS
);
1099 else if (SubStatus
== STATUS_INVALID_WORKSTATION
)
1101 ResourceMessageBox(pgContext
,
1103 MB_OK
| MB_ICONERROR
,
1105 IDS_INVALIDWORKSTATION
);
1110 TRACE("Other error!\n");
1111 ResourceMessageBox(pgContext
,
1113 MB_OK
| MB_ICONERROR
,
1115 IDS_ACCOUNTRESTRICTION
);
1119 else if (!NT_SUCCESS(Status
))
1121 TRACE("DoLoginTasks failed! Status 0x%08lx\n", Status
);
1125 if (!CreateProfile(pgContext
, UserName
, Domain
, Password
))
1127 ERR("Failed to create the profile!\n");
1131 ZeroMemory(pgContext
->Password
, sizeof(pgContext
->Password
));
1132 wcscpy(pgContext
->Password
, Password
);
1137 pgContext
->bAutoAdminLogon
= FALSE
;
1139 if (UserName
!= NULL
)
1140 HeapFree(GetProcessHeap(), 0, UserName
);
1142 if (Password
!= NULL
)
1143 HeapFree(GetProcessHeap(), 0, Password
);
1146 HeapFree(GetProcessHeap(), 0, Domain
);
1155 HWND hwndDomainComboBox
,
1156 PGINA_CONTEXT pgContext
)
1158 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1159 DWORD dwComputerNameLength
;
1163 SendMessageW(hwndDomainComboBox
, CB_RESETCONTENT
, 0, 0);
1165 dwComputerNameLength
= _countof(szComputerName
);
1166 if (GetComputerNameW(szComputerName
, &dwComputerNameLength
))
1168 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)szComputerName
);
1171 if (wcslen(pgContext
->DomainName
) != 0)
1173 lFindIndex
= SendMessageW(hwndDomainComboBox
, CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)pgContext
->DomainName
);
1174 if (lFindIndex
== CB_ERR
)
1176 lIndex
= SendMessageW(hwndDomainComboBox
, CB_ADDSTRING
, 0, (LPARAM
)pgContext
->DomainName
);
1180 lIndex
= lFindIndex
;
1184 SendMessageW(hwndDomainComboBox
, CB_SETCURSEL
, lIndex
, 0);
1188 static INT_PTR CALLBACK
1197 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1203 /* FIXME: take care of NoDomainUI */
1204 pDlgData
= DlgData_Create(hwndDlg
, (PGINA_CONTEXT
)lParam
);
1205 if (pDlgData
== NULL
)
1208 DlgData_LoadBitmaps(pDlgData
);
1210 SetWelcomeText(hwndDlg
);
1212 if (pDlgData
->pgContext
->bAutoAdminLogon
||
1213 !pDlgData
->pgContext
->bDontDisplayLastUserName
)
1214 SetDlgItemTextW(hwndDlg
, IDC_LOGON_USERNAME
, pDlgData
->pgContext
->UserName
);
1216 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1217 SetDlgItemTextW(hwndDlg
, IDC_LOGON_PASSWORD
, pDlgData
->pgContext
->Password
);
1219 SetDomainComboBox(GetDlgItem(hwndDlg
, IDC_LOGON_DOMAIN
), pDlgData
->pgContext
);
1221 if (pDlgData
->pgContext
->bDisableCAD
)
1222 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1224 if (!pDlgData
->pgContext
->bShutdownWithoutLogon
)
1225 EnableWindow(GetDlgItem(hwndDlg
, IDC_LOGON_SHUTDOWN
), FALSE
);
1227 SetFocus(GetDlgItem(hwndDlg
, pDlgData
->pgContext
->bDontDisplayLastUserName
? IDC_LOGON_USERNAME
: IDC_LOGON_PASSWORD
));
1229 if (pDlgData
->pgContext
->bAutoAdminLogon
)
1230 PostMessage(GetDlgItem(hwndDlg
, IDOK
), BM_CLICK
, 0, 0);
1238 if (pDlgData
&& pDlgData
->hLogoBitmap
)
1240 BeginPaint(hwndDlg
, &ps
);
1241 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hLogoBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1242 EndPaint(hwndDlg
, &ps
);
1248 DlgData_Destroy(hwndDlg
);
1252 switch (LOWORD(wParam
))
1255 if (DoLogon(hwndDlg
, pDlgData
->pgContext
))
1256 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGON
);
1260 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1263 case IDC_LOGON_SHUTDOWN
:
1264 if (OnShutDown(hwndDlg
, pDlgData
->pgContext
) == IDOK
)
1265 EndDialog(hwndDlg
, pDlgData
->pgContext
->nShutdownAction
);
1278 LegalNoticeDialogProc(
1284 PLEGALNOTICEDATA pLegalNotice
;
1289 pLegalNotice
= (PLEGALNOTICEDATA
)lParam
;
1290 SetWindowTextW(hwndDlg
, pLegalNotice
->pszCaption
);
1291 SetDlgItemTextW(hwndDlg
, IDC_LEGALNOTICE_TEXT
, pLegalNotice
->pszText
);
1295 switch (LOWORD(wParam
))
1298 EndDialog(hwndDlg
, 0);
1302 EndDialog(hwndDlg
, 0);
1314 IN OUT PGINA_CONTEXT pgContext
)
1316 LEGALNOTICEDATA LegalNotice
= {NULL
, NULL
};
1321 TRACE("GUILoggedOutSAS()\n");
1323 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1324 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1328 if (rc
== ERROR_SUCCESS
)
1330 ReadRegSzValue(hKey
,
1331 L
"LegalNoticeCaption",
1332 &LegalNotice
.pszCaption
);
1334 ReadRegSzValue(hKey
,
1336 &LegalNotice
.pszText
);
1341 if (LegalNotice
.pszCaption
!= NULL
&& wcslen(LegalNotice
.pszCaption
) != 0 &&
1342 LegalNotice
.pszText
!= NULL
&& wcslen(LegalNotice
.pszText
) != 0)
1344 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
1345 pgContext
->hDllInstance
,
1346 MAKEINTRESOURCEW(IDD_LEGALNOTICE
),
1348 LegalNoticeDialogProc
,
1349 (LPARAM
)&LegalNotice
);
1352 if (LegalNotice
.pszCaption
!= NULL
)
1353 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszCaption
);
1355 if (LegalNotice
.pszText
!= NULL
)
1356 HeapFree(GetProcessHeap(), 0, LegalNotice
.pszText
);
1358 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1360 pgContext
->hDllInstance
,
1361 MAKEINTRESOURCEW(IDD_LOGON
),
1365 if (result
>= WLX_SAS_ACTION_LOGON
&&
1366 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1368 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
1372 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
1373 return WLX_SAS_ACTION_NONE
;
1378 SetLockMessage(HWND hwnd
,
1380 PGINA_CONTEXT pgContext
)
1386 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, _countof(Buffer1
));
1388 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->DomainName
, pgContext
->UserName
);
1389 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
1391 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
1399 IN PGINA_CONTEXT pgContext
,
1404 LPWSTR UserName
= NULL
;
1405 LPWSTR Password
= NULL
;
1408 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_USERNAME
, &UserName
) && *UserName
== '\0')
1410 HeapFree(GetProcessHeap(), 0, UserName
);
1414 if (GetTextboxText(hwndDlg
, IDC_UNLOCK_PASSWORD
, &Password
))
1416 if (UserName
!= NULL
&& Password
!= NULL
&&
1417 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1418 wcscmp(Password
, pgContext
->Password
) == 0)
1420 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1423 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
1424 wcscmp(Password
, pgContext
->Password
) != 0)
1426 /* Wrong Password */
1427 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, _countof(Buffer2
));
1428 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1429 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1433 /* Wrong user name */
1434 if (DoAdminUnlock(pgContext
, UserName
, NULL
, Password
))
1436 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
1441 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, _countof(Buffer1
));
1442 wsprintfW(Buffer2
, Buffer1
, pgContext
->DomainName
, pgContext
->UserName
);
1443 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, _countof(Buffer1
));
1444 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
1449 if (UserName
!= NULL
)
1450 HeapFree(GetProcessHeap(), 0, UserName
);
1452 if (Password
!= NULL
)
1453 HeapFree(GetProcessHeap(), 0, Password
);
1469 INT result
= WLX_SAS_ACTION_NONE
;
1471 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1477 pDlgData
= DlgData_Create(hwndDlg
, (PGINA_CONTEXT
)lParam
);
1478 if (pDlgData
== NULL
)
1481 SetWelcomeText(hwndDlg
);
1483 SetLockMessage(hwndDlg
, IDC_UNLOCK_MESSAGE
, pDlgData
->pgContext
);
1485 SetDlgItemTextW(hwndDlg
, IDC_UNLOCK_USERNAME
, pDlgData
->pgContext
->UserName
);
1486 SetFocus(GetDlgItem(hwndDlg
, IDC_UNLOCK_PASSWORD
));
1488 if (pDlgData
->pgContext
->bDisableCAD
)
1489 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
1491 DlgData_LoadBitmaps(pDlgData
);
1498 if (pDlgData
&& pDlgData
->hLogoBitmap
)
1500 BeginPaint(hwndDlg
, &ps
);
1501 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hLogoBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1502 EndPaint(hwndDlg
, &ps
);
1507 DlgData_Destroy(hwndDlg
);
1511 switch (LOWORD(wParam
))
1514 if (DoUnlock(hwndDlg
, pDlgData
->pgContext
, &result
))
1515 EndDialog(hwndDlg
, result
);
1519 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
1531 IN OUT PGINA_CONTEXT pgContext
)
1535 TRACE("GUILockedSAS()\n");
1537 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1539 pgContext
->hDllInstance
,
1540 MAKEINTRESOURCEW(IDD_UNLOCK
),
1544 if (result
>= WLX_SAS_ACTION_LOGON
&&
1545 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
1547 WARN("GUILockedSAS() returns 0x%x\n", result
);
1551 WARN("GUILockedSAS() failed (0x%x)\n", result
);
1552 return WLX_SAS_ACTION_NONE
;
1556 static INT_PTR CALLBACK
1565 pDlgData
= (PDLG_DATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
1571 pDlgData
= DlgData_Create(hwndDlg
, (PGINA_CONTEXT
)lParam
);
1572 if (pDlgData
== NULL
)
1575 DlgData_LoadBitmaps(pDlgData
);
1577 SetWelcomeText(hwndDlg
);
1579 SetLockMessage(hwndDlg
, IDC_LOCKED_MESSAGE
, pDlgData
->pgContext
);
1585 if (pDlgData
&& pDlgData
->hLogoBitmap
)
1587 BeginPaint(hwndDlg
, &ps
);
1588 DrawStateW(ps
.hdc
, NULL
, NULL
, (LPARAM
)pDlgData
->hLogoBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
1589 EndPaint(hwndDlg
, &ps
);
1595 DlgData_Destroy(hwndDlg
);
1605 GUIDisplayLockedNotice(
1606 IN OUT PGINA_CONTEXT pgContext
)
1608 TRACE("GUIdisplayLockedNotice()\n");
1610 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
1612 pgContext
->hDllInstance
,
1613 MAKEINTRESOURCEW(IDD_LOCKED
),
1619 GINA_UI GinaGraphicalUI
= {
1621 GUIDisplayStatusMessage
,
1622 GUIRemoveStatusMessage
,
1623 GUIDisplaySASNotice
,
1627 GUIDisplayLockedNotice
,