3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS msgina.dll
22 * FILE: lib/msgina/msgina.c
23 * PURPOSE: ReactOS Logon GINA DLL
24 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
33 #include <wine/debug.h>
35 extern HINSTANCE hDllInstance
;
37 typedef struct _DISPLAYSTATUSMSG
39 PGINA_CONTEXT Context
;
45 } DISPLAYSTATUSMSG
, *PDISPLAYSTATUSMSG
;
59 switch(LOWORD(wParam
))
64 EndDialog(hwndDlg
, LOWORD(wParam
));
72 SetFocus(GetDlgItem(hwndDlg
, IDNO
));
77 EndDialog(hwndDlg
, IDNO
);
90 DWORD dwWinlogonVersion
,
93 if(!pdwDllVersion
|| (dwWinlogonVersion
< GINA_VERSION
))
96 *pdwDllVersion
= GINA_VERSION
;
110 PVOID pWinlogonFunctions
,
113 PGINA_CONTEXT pgContext
;
115 pgContext
= (PGINA_CONTEXT
)LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, sizeof(GINA_CONTEXT
));
119 /* return the context to winlogon */
120 *pWlxContext
= (PVOID
)pgContext
;
122 pgContext
->hDllInstance
= hDllInstance
;
124 /* save pointer to dispatch table */
125 pgContext
->pWlxFuncs
= (PWLX_DISPATCH_VERSION
)pWinlogonFunctions
;
127 /* save the winlogon handle used to call the dispatch functions */
128 pgContext
->hWlx
= hWlx
;
130 /* save window station */
131 pgContext
->station
= lpWinsta
;
133 /* clear status window handle */
134 pgContext
->hStatusWindow
= 0;
136 /* notify winlogon that we will use the default SAS */
137 pgContext
->pWlxFuncs
->WlxUseCtrlAltDel(hWlx
);
149 PWSTR pszDesktopName
,
153 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
155 PROCESS_INFORMATION pi
;
158 si
.cb
= sizeof(STARTUPINFO
);
159 si
.lpReserved
= NULL
;
160 si
.lpTitle
= pszCmdLine
;
161 si
.dwX
= si
.dwY
= si
.dwXSize
= si
.dwYSize
= 0L;
163 si
.wShowWindow
= SW_SHOW
;
164 si
.lpReserved2
= NULL
;
166 si
.lpDesktop
= pszDesktopName
;
168 Ret
= CreateProcessAsUser(pgContext
->UserToken
,
174 CREATE_UNICODE_ENVIRONMENT
,
180 VirtualFree(pEnvironment
, 0, MEM_RELEASE
);
189 WlxActivateUserShell(
191 PWSTR pszDesktopName
,
192 PWSTR pszMprLogonScript
,
195 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
197 PROCESS_INFORMATION pi
;
199 DWORD BufSize
, ValueType
;
200 WCHAR pszUserInitApp
[MAX_PATH
];
201 WCHAR pszExpUserInitApp
[MAX_PATH
];
204 /* get the path of userinit */
205 if(RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
206 L
"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon",
207 0, KEY_QUERY_VALUE
, &hKey
) != ERROR_SUCCESS
)
208 {ERR("GINA: Failed: 1\n");
209 VirtualFree(pEnvironment
, 0, MEM_RELEASE
);
212 BufSize
= MAX_PATH
* sizeof(WCHAR
);
213 if((RegQueryValueEx(hKey
, L
"Userinit", NULL
, &ValueType
, (LPBYTE
)pszUserInitApp
,
214 &BufSize
) != ERROR_SUCCESS
) ||
215 !((ValueType
== REG_SZ
) || (ValueType
== REG_EXPAND_SZ
)))
216 {ERR("GINA: Failed: 2\n");
218 VirtualFree(pEnvironment
, 0, MEM_RELEASE
);
224 /* FIXME - allow to start more applications that are comma-separated */
225 si
.cb
= sizeof(STARTUPINFO
);
226 si
.lpReserved
= NULL
;
227 si
.lpTitle
= L
"userinit";
228 si
.dwX
= si
.dwY
= si
.dwXSize
= si
.dwYSize
= 0;
230 si
.wShowWindow
= SW_SHOW
;
231 si
.lpReserved2
= NULL
;
233 si
.lpDesktop
= pszDesktopName
;
235 ExpandEnvironmentStrings(pszUserInitApp
, pszExpUserInitApp
, MAX_PATH
);
237 Ret
= CreateProcessAsUser(pgContext
->UserToken
,
243 CREATE_UNICODE_ENVIRONMENT
,
248 if(!Ret
) ERR("GINA: Failed: 3\n");
249 VirtualFree(pEnvironment
, 0, MEM_RELEASE
);
263 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
264 int SasAction
= WLX_SAS_ACTION_NONE
;
268 case WLX_SAS_TYPE_CTRL_ALT_DEL
:
271 /* display "Are you sure you want to log off?" dialog */
272 Result
= pgContext
->pWlxFuncs
->WlxDialogBoxParam(pgContext
->hWlx
,
273 pgContext
->hDllInstance
,
274 (LPTSTR
)IDD_LOGOFF_DLG
,
280 SasAction
= WLX_SAS_ACTION_LOCK_WKSTA
;
284 case WLX_SAS_TYPE_SC_INSERT
:
286 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
289 case WLX_SAS_TYPE_SC_REMOVE
:
291 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
294 case WLX_SAS_TYPE_TIMEOUT
:
296 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
301 WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType
);
312 StatusMessageWindowProc(
323 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lParam
;
327 msg
->Context
->hStatusWindow
= hwndDlg
;
330 SetWindowText(hwndDlg
, msg
->pTitle
);
331 SetDlgItemText(hwndDlg
, IDC_STATUSLABEL
, msg
->pMessage
);
332 if(!msg
->Context
->SignaledStatusWindowCreated
)
334 msg
->Context
->SignaledStatusWindowCreated
= TRUE
;
335 SetEvent(msg
->StartupEvent
);
345 StartupWindowThread(LPVOID lpParam
)
348 PDISPLAYSTATUSMSG msg
= (PDISPLAYSTATUSMSG
)lpParam
;
350 OldDesk
= GetThreadDesktop(GetCurrentThreadId());
352 if(!SetThreadDesktop(msg
->hDesktop
))
354 HeapFree(GetProcessHeap(), 0, lpParam
);
357 DialogBoxParam(hDllInstance
,
358 MAKEINTRESOURCE(IDD_STATUSWINDOW
),
360 StatusMessageWindowProc
,
362 SetThreadDesktop(OldDesk
);
364 msg
->Context
->hStatusWindow
= 0;
365 msg
->Context
->SignaledStatusWindowCreated
= FALSE
;
367 HeapFree(GetProcessHeap(), 0, lpParam
);
376 WlxDisplayStatusMessage(
383 PDISPLAYSTATUSMSG msg
;
386 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
388 if(!pgContext
->hStatusWindow
)
390 msg
= (PDISPLAYSTATUSMSG
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DISPLAYSTATUSMSG
));
394 msg
->Context
= pgContext
;
395 msg
->dwOptions
= dwOptions
;
396 msg
->pTitle
= pTitle
;
397 msg
->pMessage
= pMessage
;
398 msg
->hDesktop
= hDesktop
;
400 msg
->StartupEvent
= CreateEvent(NULL
,
405 if(!msg
->StartupEvent
)
408 Thread
= CreateThread(NULL
,
417 WaitForSingleObject(msg
->StartupEvent
, INFINITE
);
418 CloseHandle(msg
->StartupEvent
);
426 SetWindowText(pgContext
->hStatusWindow
, pTitle
);
428 SetDlgItemText(pgContext
->hStatusWindow
, IDC_STATUSLABEL
, pMessage
);
438 WlxRemoveStatusMessage(
441 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
442 if(pgContext
->hStatusWindow
)
444 EndDialog(pgContext
->hStatusWindow
, 0);
445 pgContext
->hStatusWindow
= 0;
459 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
460 pgContext
->pWlxFuncs
->WlxSasNotify(pgContext
->hWlx
, WLX_SAS_TYPE_CTRL_ALT_DEL
);
465 DuplicationString(PWSTR Str
)
470 cb
= (wcslen(Str
) + 1) * sizeof(WCHAR
);
471 if((NewStr
= LocalAlloc(LMEM_FIXED
, cb
)))
473 memcpy(NewStr
, Str
, cb
);
486 PLUID pAuthenticationId
,
490 PWLX_MPR_NOTIFY_INFO pNprNotifyInfo
,
493 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
494 TOKEN_STATISTICS Stats
;
499 WARN("msgina: phToken == NULL!\n");
500 return WLX_SAS_ACTION_NONE
;
503 if(!LogonUser(L
"Administrator", NULL
, L
"Secrect",
504 LOGON32_LOGON_INTERACTIVE
, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
505 LOGON32_PROVIDER_DEFAULT
,
508 WARN("msgina: Logonuser() failed\n");
509 return WLX_SAS_ACTION_NONE
;
514 WARN("msgina: *phToken == NULL!\n");
515 return WLX_SAS_ACTION_NONE
;
518 pgContext
->UserToken
=*phToken
;
523 if(!GetTokenInformation(*phToken
,
526 sizeof(TOKEN_STATISTICS
),
529 WARN("msgina: Couldn't get Autentication id from user token!\n");
530 return WLX_SAS_ACTION_NONE
;
532 *pAuthenticationId
= Stats
.AuthenticationId
;
533 pNprNotifyInfo
->pszUserName
= DuplicationString(L
"Administrator");
534 pNprNotifyInfo
->pszDomain
= NULL
;
535 pNprNotifyInfo
->pszPassword
= DuplicationString(L
"Secret");
536 pNprNotifyInfo
->pszOldPassword
= NULL
;
538 return WLX_SAS_ACTION_LOGON
;
550 case DLL_PROCESS_ATTACH
:
552 case DLL_THREAD_ATTACH
:
553 hDllInstance
= hinstDLL
;
555 case DLL_THREAD_DETACH
:
557 case DLL_PROCESS_DETACH
: