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)
10 typedef struct _DISPLAYSTATUSMSG
12 PGINA_CONTEXT Context
;
18 } DISPLAYSTATUSMSG
, *PDISPLAYSTATUSMSG
;
22 IN OUT PGINA_CONTEXT pgContext
)
24 TRACE("GUIInitialize(%p)\n", pgContext
);
28 static INT_PTR CALLBACK
29 StatusMessageWindowProc(
35 UNREFERENCED_PARAMETER(wParam
);
41 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
45 msg
->Context
->hStatusWindow
= hwndDlg
;
48 SetWindowTextW(hwndDlg
, msg
->pTitle
);
49 SetDlgItemTextW(hwndDlg
, IDC_STATUSLABEL
, msg
->pMessage
);
50 SetEvent(msg
->StartupEvent
);
58 StartupWindowThread(LPVOID lpParam
)
61 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
63 /* When SetThreadDesktop is called the system closes the desktop handle when needed
64 so we have to create a new handle because this handle may still be in use by winlogon */
65 if (!DuplicateHandle ( GetCurrentProcess(),
71 DUPLICATE_SAME_ACCESS
))
73 HeapFree(GetProcessHeap(), 0, lpParam
);
77 if(!SetThreadDesktop(hDesk
))
79 HeapFree(GetProcessHeap(), 0, lpParam
);
85 MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG
),
87 StatusMessageWindowProc
,
90 HeapFree(GetProcessHeap(), 0, lpParam
);
95 GUIDisplayStatusMessage(
96 IN PGINA_CONTEXT pgContext
,
102 PDISPLAYSTATUSMSG msg
;
106 TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage
);
108 if (!pgContext
->hStatusWindow
)
110 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DISPLAYSTATUSMSG
));
114 msg
->Context
= pgContext
;
115 msg
->dwOptions
= dwOptions
;
116 msg
->pTitle
= pTitle
;
117 msg
->pMessage
= pMessage
;
118 msg
->hDesktop
= hDesktop
;
120 msg
->StartupEvent
= CreateEventW(
126 if (!msg
->StartupEvent
)
129 Thread
= CreateThread(
139 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
140 CloseHandle(msg
->StartupEvent
);
148 SetWindowTextW(pgContext
->hStatusWindow
, pTitle
);
150 SetDlgItemTextW(pgContext
->hStatusWindow
, IDC_STATUSLABEL
, pMessage
);
156 GUIRemoveStatusMessage(
157 IN PGINA_CONTEXT pgContext
)
159 if (pgContext
->hStatusWindow
)
161 EndDialog(pgContext
->hStatusWindow
, 0);
162 pgContext
->hStatusWindow
= NULL
;
168 static INT_PTR CALLBACK
175 UNREFERENCED_PARAMETER(hwndDlg
);
176 UNREFERENCED_PARAMETER(uMsg
);
177 UNREFERENCED_PARAMETER(wParam
);
178 UNREFERENCED_PARAMETER(lParam
);
185 IN OUT PGINA_CONTEXT pgContext
)
187 TRACE("GUIDisplaySASNotice()\n");
189 /* Display the notice window */
190 pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
191 pgContext
->hDllInstance
,
192 MAKEINTRESOURCEW(IDD_NOTICE_DLG
),
198 /* Get the text contained in a textbox. Allocates memory in pText
199 * to contain the text. Returns TRUE in case of success */
209 Count
= GetWindowTextLength(GetDlgItem(hwndDlg
, TextboxId
));
210 Text
= HeapAlloc(GetProcessHeap(), 0, (Count
+ 1) * sizeof(WCHAR
));
213 if (Count
!= GetWindowTextW(GetDlgItem(hwndDlg
, TextboxId
), Text
, Count
+ 1))
215 HeapFree(GetProcessHeap(), 0, Text
);
223 static INT_PTR CALLBACK
224 ChangePasswordDialogProc(
233 FIXME("ChangePasswordDialogProc: WM_INITDLG\n");
237 switch (LOWORD(wParam
))
240 EndDialog(hwndDlg
, TRUE
);
244 EndDialog(hwndDlg
, FALSE
);
250 EndDialog(hwndDlg
, FALSE
);
259 OnInitSecurityDlg(HWND hwnd
,
260 PGINA_CONTEXT pgContext
)
267 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONMSG
, Buffer1
, 256);
269 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
270 wsprintfW(Buffer4
, Buffer1
, Buffer2
);
272 SetDlgItemTextW(hwnd
, IDC_LOGONMSG
, Buffer4
);
274 LoadStringW(pgContext
->hDllInstance
, IDS_LOGONDATE
, Buffer1
, 256);
276 GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
,
277 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer2
, 256);
279 GetTimeFormatW(LOCALE_USER_DEFAULT
, 0,
280 (SYSTEMTIME
*)&pgContext
->LogonTime
, NULL
, Buffer3
, 256);
282 wsprintfW(Buffer4
, Buffer1
, Buffer2
, Buffer3
);
284 SetDlgItemTextW(hwnd
, IDC_LOGONDATE
, Buffer4
);
286 if (pgContext
->bAutoAdminLogon
== TRUE
)
287 EnableWindow(GetDlgItem(hwnd
, IDC_LOGOFF
), FALSE
);
294 IN PGINA_CONTEXT pgContext
)
298 FIXME("OnChangePassword()\n");
300 res
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
302 pgContext
->hDllInstance
,
303 MAKEINTRESOURCEW(IDD_CHANGE_PASSWORD
),
305 ChangePasswordDialogProc
,
308 FIXME("Result: %x\n", res
);
314 static INT_PTR CALLBACK
327 switch (LOWORD(wParam
))
330 EndDialog(hwndDlg
, IDYES
);
334 EndDialog(hwndDlg
, IDNO
);
340 EndDialog(hwndDlg
, IDNO
);
352 IN PGINA_CONTEXT pgContext
)
354 return pgContext
->pWlxFuncs
->WlxDialogBoxParam(
356 pgContext
->hDllInstance
,
357 MAKEINTRESOURCEW(IDD_LOGOFF_DLG
),
364 static INT_PTR CALLBACK
371 PGINA_CONTEXT pgContext
;
373 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
379 pgContext
= (PGINA_CONTEXT
)lParam
;
380 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
382 OnInitSecurityDlg(hwndDlg
, (PGINA_CONTEXT
)lParam
);
383 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
389 switch (LOWORD(wParam
))
392 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOCK_WKSTA
);
395 if (OnLogOff(hwndDlg
, pgContext
) == IDYES
)
396 EndDialog(hwndDlg
, WLX_SAS_ACTION_LOGOFF
);
399 EndDialog(hwndDlg
, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
);
402 if (OnChangePassword(hwndDlg
, pgContext
))
403 EndDialog(hwndDlg
, WLX_SAS_ACTION_PWD_CHANGED
);
406 EndDialog(hwndDlg
, WLX_SAS_ACTION_TASKLIST
);
409 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
416 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
426 IN OUT PGINA_CONTEXT pgContext
,
431 TRACE("GUILoggedOnSAS()\n");
433 if (dwSasType
!= WLX_SAS_TYPE_CTRL_ALT_DEL
)
435 /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will
436 * close itself thanks to the use of WlxDialogBoxParam */
437 return WLX_SAS_ACTION_NONE
;
440 pgContext
->pWlxFuncs
->WlxSwitchDesktopToWinlogon(
443 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
445 pgContext
->hDllInstance
,
446 MAKEINTRESOURCEW(IDD_LOGGEDON_DLG
),
451 if (result
< WLX_SAS_ACTION_LOGON
||
452 result
> WLX_SAS_ACTION_SWITCH_CONSOLE
)
454 result
= WLX_SAS_ACTION_NONE
;
457 if (result
== WLX_SAS_ACTION_NONE
)
459 pgContext
->pWlxFuncs
->WlxSwitchDesktopToUser(
466 static INT_PTR CALLBACK
473 PGINA_CONTEXT pgContext
;
475 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
481 /* FIXME: take care of NoDomainUI */
482 pgContext
= (PGINA_CONTEXT
)lParam
;
483 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
485 if (pgContext
->bDontDisplayLastUserName
== FALSE
)
486 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
488 if (pgContext
->bDisableCAD
== TRUE
)
489 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
491 if (pgContext
->bShutdownWithoutLogon
== FALSE
)
492 EnableWindow(GetDlgItem(hwndDlg
, IDC_SHUTDOWN
), FALSE
);
494 SetFocus(GetDlgItem(hwndDlg
, pgContext
->bDontDisplayLastUserName
? IDC_USERNAME
: IDC_PASSWORD
));
496 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
503 if (pgContext
->hBitmap
)
505 hdc
= BeginPaint(hwndDlg
, &ps
);
506 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
507 EndPaint(hwndDlg
, &ps
);
513 DeleteObject(pgContext
->hBitmap
);
518 switch (LOWORD(wParam
))
522 LPWSTR UserName
= NULL
, Password
= NULL
;
523 INT result
= WLX_SAS_ACTION_NONE
;
525 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
527 if (GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
) &&
528 DoLoginTasks(pgContext
, UserName
, NULL
, Password
))
530 pgContext
->Password
= HeapAlloc(GetProcessHeap(),
532 (wcslen(Password
) + 1) * sizeof(WCHAR
));
533 if (pgContext
->Password
!= NULL
)
534 wcscpy(pgContext
->Password
, Password
);
536 result
= WLX_SAS_ACTION_LOGON
;
538 HeapFree(GetProcessHeap(), 0, UserName
);
539 HeapFree(GetProcessHeap(), 0, Password
);
540 EndDialog(hwndDlg
, result
);
545 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
550 EndDialog(hwndDlg
, WLX_SAS_ACTION_SHUTDOWN
);
563 IN OUT PGINA_CONTEXT pgContext
)
567 TRACE("GUILoggedOutSAS()\n");
569 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
571 pgContext
->hDllInstance
,
572 MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG
),
576 if (result
>= WLX_SAS_ACTION_LOGON
&&
577 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
579 WARN("WlxLoggedOutSAS() returns 0x%x\n", result
);
583 WARN("WlxDialogBoxParam() failed (0x%x)\n", result
);
584 return WLX_SAS_ACTION_NONE
;
589 SetLockMessage(HWND hwnd
,
591 PGINA_CONTEXT pgContext
)
597 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKMSG
, Buffer1
, 256);
599 wsprintfW(Buffer2
, L
"%s\\%s", pgContext
->Domain
, pgContext
->UserName
);
600 wsprintfW(Buffer3
, Buffer1
, Buffer2
);
602 SetDlgItemTextW(hwnd
, nDlgItem
, Buffer3
);
610 IN PGINA_CONTEXT pgContext
,
615 LPWSTR UserName
= NULL
;
616 LPWSTR Password
= NULL
;
619 if (GetTextboxText(hwndDlg
, IDC_USERNAME
, &UserName
) && *UserName
== '\0')
622 if (GetTextboxText(hwndDlg
, IDC_PASSWORD
, &Password
))
624 if (UserName
!= NULL
&& Password
!= NULL
&&
625 wcscmp(UserName
, pgContext
->UserName
) == 0 &&
626 wcscmp(Password
, pgContext
->Password
) == 0)
628 *Action
= WLX_SAS_ACTION_UNLOCK_WKSTA
;
631 else if (wcscmp(UserName
, pgContext
->UserName
) == 0 &&
632 wcscmp(Password
, pgContext
->Password
) != 0)
635 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGPASSWORD
, Buffer2
, 256);
636 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, 256);
637 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
641 /* Wrong user name */
642 LoadStringW(pgContext
->hDllInstance
, IDS_LOCKEDWRONGUSER
, Buffer1
, 256);
643 wsprintfW(Buffer2
, Buffer1
, pgContext
->Domain
, pgContext
->UserName
);
644 LoadStringW(pgContext
->hDllInstance
, IDS_COMPUTERLOCKED
, Buffer1
, 256);
645 MessageBoxW(hwndDlg
, Buffer2
, Buffer1
, MB_OK
| MB_ICONERROR
);
649 if (UserName
!= NULL
)
650 HeapFree(GetProcessHeap(), 0, UserName
);
652 if (Password
!= NULL
)
653 HeapFree(GetProcessHeap(), 0, Password
);
668 PGINA_CONTEXT pgContext
;
669 INT result
= WLX_SAS_ACTION_NONE
;
671 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
676 pgContext
= (PGINA_CONTEXT
)lParam
;
677 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
679 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
681 SetDlgItemTextW(hwndDlg
, IDC_USERNAME
, pgContext
->UserName
);
682 SetFocus(GetDlgItem(hwndDlg
, IDC_PASSWORD
));
684 if (pgContext
->bDisableCAD
== TRUE
)
685 EnableWindow(GetDlgItem(hwndDlg
, IDCANCEL
), FALSE
);
687 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
694 if (pgContext
->hBitmap
)
696 hdc
= BeginPaint(hwndDlg
, &ps
);
697 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
698 EndPaint(hwndDlg
, &ps
);
703 DeleteObject(pgContext
->hBitmap
);
707 switch (LOWORD(wParam
))
710 if (DoUnlock(hwndDlg
, pgContext
, &result
))
711 EndDialog(hwndDlg
, result
);
715 EndDialog(hwndDlg
, WLX_SAS_ACTION_NONE
);
727 IN OUT PGINA_CONTEXT pgContext
)
731 TRACE("GUILockedSAS()\n");
733 result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(
735 pgContext
->hDllInstance
,
736 MAKEINTRESOURCEW(IDD_UNLOCK_DLG
),
740 if (result
>= WLX_SAS_ACTION_LOGON
&&
741 result
<= WLX_SAS_ACTION_SWITCH_CONSOLE
)
743 WARN("GUILockedSAS() returns 0x%x\n", result
);
747 WARN("GUILockedSAS() failed (0x%x)\n", result
);
748 return WLX_SAS_ACTION_NONE
;
752 static INT_PTR CALLBACK
759 PGINA_CONTEXT pgContext
;
761 pgContext
= (PGINA_CONTEXT
)GetWindowLongPtr(hwndDlg
, GWL_USERDATA
);
767 pgContext
= (PGINA_CONTEXT
)lParam
;
768 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)pgContext
);
770 pgContext
->hBitmap
= LoadImage(hDllInstance
, MAKEINTRESOURCE(IDI_ROSLOGO
), IMAGE_BITMAP
, 0, 0, LR_DEFAULTCOLOR
);
771 SetLockMessage(hwndDlg
, IDC_LOCKMSG
, pgContext
);
778 if (pgContext
->hBitmap
)
780 hdc
= BeginPaint(hwndDlg
, &ps
);
781 DrawStateW(hdc
, NULL
, NULL
, (LPARAM
)pgContext
->hBitmap
, (WPARAM
)0, 0, 0, 0, 0, DST_BITMAP
);
782 EndPaint(hwndDlg
, &ps
);
788 DeleteObject(pgContext
->hBitmap
);
798 GUIDisplayLockedNotice(
799 IN OUT PGINA_CONTEXT pgContext
)
801 TRACE("GUIdisplayLockedNotice()\n");
803 pgContext
->pWlxFuncs
->WlxDialogBoxParam(
805 pgContext
->hDllInstance
,
806 MAKEINTRESOURCEW(IDD_LOCKED_DLG
),
812 GINA_UI GinaGraphicalUI
= {
814 GUIDisplayStatusMessage
,
815 GUIRemoveStatusMessage
,
820 GUIDisplayLockedNotice
,