3 * Copyright (C) 2003-2004, 2006 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * PROJECT: ReactOS msgina.dll
21 * FILE: dll/win32/msgina/msgina.c
22 * PURPOSE: ReactOS Logon GINA DLL
23 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * Hervé Poussineau (hpoussin@reactos.org)
29 HINSTANCE hDllInstance
;
31 extern GINA_UI GinaGraphicalUI
;
32 extern GINA_UI GinaTextUI
;
33 static PGINA_UI pGinaUI
;
40 IN DWORD dwWinlogonVersion
,
41 OUT PDWORD pdwDllVersion
)
43 TRACE("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion
, pdwDllVersion
);
45 if(!pdwDllVersion
|| (dwWinlogonVersion
< WLX_VERSION_1_3
))
48 *pdwDllVersion
= WLX_VERSION_1_3
;
65 return ERROR_INVALID_PARAMETER
;
68 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
69 if (rc
!= ERROR_SUCCESS
)
72 return ERROR_FILE_NOT_FOUND
;
73 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
75 return ERROR_NOT_ENOUGH_MEMORY
;
76 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
77 if (rc
!= ERROR_SUCCESS
)
79 HeapFree(GetProcessHeap(), 0, Value
);
82 /* NULL-terminate the string */
83 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
101 return ERROR_INVALID_PARAMETER
;
103 cbData
= sizeof(DWORD
);
104 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, (LPBYTE
)&dwValue
, &cbData
);
105 if (rc
== ERROR_SUCCESS
&& dwType
== REG_DWORD
)
108 return ERROR_SUCCESS
;
114 HKEY ControlKey
= NULL
;
115 LPWSTR SystemStartOptions
= NULL
;
116 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
117 BOOL ConsoleBoot
= FALSE
;
122 L
"SYSTEM\\CurrentControlSet\\Control",
127 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
128 if (rc
!= ERROR_SUCCESS
)
131 /* Check for CONSOLE switch in SystemStartOptions */
132 CurrentOption
= SystemStartOptions
;
133 while (CurrentOption
)
135 NextOption
= wcschr(CurrentOption
, L
' ');
138 if (wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
140 TRACE("Found %S. Switching to console boot\n", CurrentOption
);
144 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
149 pGinaUI
= &GinaTextUI
;
151 pGinaUI
= &GinaGraphicalUI
;
153 if (ControlKey
!= NULL
)
154 RegCloseKey(ControlKey
);
155 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
161 GetRegistrySettings(PGINA_CONTEXT pgContext
)
164 LPWSTR lpAutoAdminLogon
= NULL
;
165 DWORD dwDisableCAD
= 0;
168 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
169 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
173 if (rc
!= ERROR_SUCCESS
)
175 WARN("RegOpenKeyExW() failed with error %lu\n", rc
);
179 rc
= ReadRegSzKey(hKey
,
182 if (rc
== ERROR_SUCCESS
)
184 if (wcscmp(lpAutoAdminLogon
, L
"1") == 0)
185 pgContext
->bAutoAdminLogon
= TRUE
;
188 TRACE("bAutoAdminLogon: %s\n", pgContext
->bAutoAdminLogon
? "TRUE" : "FALSE");
190 rc
= ReadRegDwordKey(hKey
,
193 if (rc
== ERROR_SUCCESS
)
195 if (dwDisableCAD
!= 0)
196 pgContext
->bDisableCAD
= TRUE
;
199 TRACE("bDisableCAD: %s\n", pgContext
->bDisableCAD
? "TRUE" : "FALSE");
201 if (lpAutoAdminLogon
!= NULL
)
202 HeapFree(GetProcessHeap(), 0, lpAutoAdminLogon
);
219 PVOID pWinlogonFunctions
,
222 PGINA_CONTEXT pgContext
;
224 UNREFERENCED_PARAMETER(pvReserved
);
226 pgContext
= (PGINA_CONTEXT
)LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, sizeof(GINA_CONTEXT
));
229 WARN("LocalAlloc() failed\n");
233 if (!GetRegistrySettings(pgContext
))
235 WARN("GetRegistrySettings() failed\n");
236 LocalFree(pgContext
);
240 /* Return the context to winlogon */
241 *pWlxContext
= (PVOID
)pgContext
;
242 pgContext
->hDllInstance
= hDllInstance
;
244 /* Save pointer to dispatch table */
245 pgContext
->pWlxFuncs
= (PWLX_DISPATCH_VERSION_1_3
)pWinlogonFunctions
;
247 /* Save the winlogon handle used to call the dispatch functions */
248 pgContext
->hWlx
= hWlx
;
250 /* Save window station */
251 pgContext
->station
= lpWinsta
;
253 /* Clear status window handle */
254 pgContext
->hStatusWindow
= 0;
256 /* Notify winlogon that we will use the default SAS */
257 pgContext
->pWlxFuncs
->WlxUseCtrlAltDel(hWlx
);
259 /* Locates the authentification package */
260 //LsaRegisterLogonProcess(...);
262 /* Check autologon settings the first time */
263 pgContext
->AutoLogonState
= AUTOLOGON_CHECK_REGISTRY
;
266 return pGinaUI
->Initialize(pgContext
);
274 WlxScreenSaverNotify(
281 DWORD bufferSize
= sizeof(szBuffer
);
282 DWORD varType
= REG_SZ
;
285 TRACE("(%p %p)\n", pWlxContext
, pSecure
);
291 * HKLM\Software\Policies\Microsoft\Windows\Control Panel\Desktop : ScreenSaverIsSecure
293 * HKCU\Control Panel\Desktop : ScreenSaverIsSecure
296 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
,
297 L
"Control Panel\\Desktop",
301 TRACE("RegOpenKeyExW: %ld\n", rc
);
302 if (rc
== ERROR_SUCCESS
)
304 rc
= RegQueryValueExW(hKey
,
305 L
"ScreenSaverIsSecure",
311 TRACE("RegQueryValueExW: %ld\n", rc
);
313 if (rc
== ERROR_SUCCESS
)
315 TRACE("szBuffer: \"%S\"\n", szBuffer
);
316 *pSecure
= _wtoi(szBuffer
);
322 TRACE("*pSecure: %ld\n", *pSecure
);
336 PWSTR pszDesktopName
,
340 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
341 STARTUPINFOW StartupInfo
;
342 PROCESS_INFORMATION ProcessInformation
;
343 WCHAR CurrentDirectory
[MAX_PATH
];
348 len
= GetWindowsDirectoryW(CurrentDirectory
, MAX_PATH
);
349 if (len
== 0 || len
> MAX_PATH
)
351 ERR("GetWindowsDirectoryW() failed\n");
355 ret
= DuplicateTokenEx(pgContext
->UserToken
, MAXIMUM_ALLOWED
, NULL
, SecurityImpersonation
, TokenPrimary
, &hAppToken
);
358 ERR("DuplicateTokenEx() failed with error %lu\n", GetLastError());
362 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
363 ZeroMemory(&ProcessInformation
, sizeof(ProcessInformation
));
364 StartupInfo
.cb
= sizeof(StartupInfo
);
365 StartupInfo
.lpTitle
= pszCmdLine
;
366 StartupInfo
.dwFlags
= STARTF_USESHOWWINDOW
;
367 StartupInfo
.wShowWindow
= SW_SHOW
;
368 StartupInfo
.lpDesktop
= pszDesktopName
;
370 len
= GetWindowsDirectoryW(CurrentDirectory
, MAX_PATH
);
371 if (len
== 0 || len
> MAX_PATH
)
373 ERR("GetWindowsDirectoryW() failed\n");
376 ret
= CreateProcessAsUserW(
383 CREATE_UNICODE_ENVIRONMENT
,
387 &ProcessInformation
);
388 CloseHandle(ProcessInformation
.hProcess
);
389 CloseHandle(ProcessInformation
.hThread
);
390 CloseHandle(hAppToken
);
392 ERR("CreateProcessAsUserW() failed with error %lu\n", GetLastError());
400 WlxActivateUserShell(
402 PWSTR pszDesktopName
,
403 PWSTR pszMprLogonScript
,
407 DWORD BufSize
, ValueType
;
408 WCHAR pszUserInitApp
[MAX_PATH
+ 1];
409 WCHAR pszExpUserInitApp
[MAX_PATH
];
413 TRACE("WlxActivateUserShell()\n");
415 UNREFERENCED_PARAMETER(pszMprLogonScript
);
417 /* Get the path of userinit */
420 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
424 if (rc
!= ERROR_SUCCESS
)
426 WARN("RegOpenKeyExW() failed with error %lu\n", rc
);
430 /* Query userinit application */
431 BufSize
= sizeof(pszUserInitApp
) - sizeof(UNICODE_NULL
);
432 rc
= RegQueryValueExW(
437 (LPBYTE
)pszUserInitApp
,
440 if (rc
!= ERROR_SUCCESS
|| (ValueType
!= REG_SZ
&& ValueType
!= REG_EXPAND_SZ
))
442 WARN("RegQueryValueExW() failed with error %lu\n", rc
);
445 pszUserInitApp
[MAX_PATH
] = UNICODE_NULL
;
447 len
= ExpandEnvironmentStringsW(pszUserInitApp
, pszExpUserInitApp
, MAX_PATH
);
450 WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len
);
454 /* Start userinit app */
455 return WlxStartApplication(pWlxContext
, pszDesktopName
, pEnvironment
, pszExpUserInitApp
);
467 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
468 INT SasAction
= WLX_SAS_ACTION_NONE
;
470 TRACE("WlxLoggedOnSAS(0x%lx)\n", dwSasType
);
472 UNREFERENCED_PARAMETER(pReserved
);
476 case WLX_SAS_TYPE_CTRL_ALT_DEL
:
477 case WLX_SAS_TYPE_TIMEOUT
:
479 SasAction
= pGinaUI
->LoggedOnSAS(pgContext
, dwSasType
);
482 case WLX_SAS_TYPE_SC_INSERT
:
484 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
487 case WLX_SAS_TYPE_SC_REMOVE
:
489 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
494 WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType
);
506 WlxDisplayStatusMessage(
507 IN PVOID pWlxContext
,
513 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
515 TRACE("WlxDisplayStatusMessage(\"%S\")\n", pMessage
);
517 return pGinaUI
->DisplayStatusMessage(pgContext
, hDesktop
, dwOptions
, pTitle
, pMessage
);
524 WlxRemoveStatusMessage(
525 IN PVOID pWlxContext
)
527 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
529 TRACE("WlxRemoveStatusMessage()\n");
531 return pGinaUI
->RemoveStatusMessage(pgContext
);
535 DuplicationString(PWSTR Str
)
540 if (Str
== NULL
) return NULL
;
542 cb
= (wcslen(Str
) + 1) * sizeof(WCHAR
);
543 if ((NewStr
= LocalAlloc(LMEM_FIXED
, cb
)))
544 memcpy(NewStr
, Str
, cb
);
550 IN OUT PGINA_CONTEXT pgContext
,
555 LPWSTR ProfilePath
= NULL
;
556 LPWSTR lpEnvironment
= NULL
;
557 TOKEN_STATISTICS Stats
;
558 PWLX_PROFILE_V2_0 pProfile
= NULL
;
559 DWORD cbStats
, cbSize
;
563 if (!LogonUserW(UserName
, Domain
, Password
,
564 LOGON32_LOGON_INTERACTIVE
,
565 LOGON32_PROVIDER_DEFAULT
,
566 &pgContext
->UserToken
))
568 WARN("LogonUserW() failed\n");
572 /* Store the logon time in the context */
573 GetLocalTime(&pgContext
->LogonTime
);
575 /* Store user and domain in the context */
576 wcscpy(pgContext
->UserName
, UserName
);
577 if (Domain
== NULL
|| wcslen(Domain
) == 0)
580 GetComputerNameW(pgContext
->Domain
, &dwLength
);
584 wcscpy(pgContext
->Domain
, Domain
);
587 /* Get profile path */
589 bResult
= GetProfilesDirectoryW(NULL
, &cbSize
);
590 if (!bResult
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
592 ProfilePath
= HeapAlloc(GetProcessHeap(), 0, cbSize
* sizeof(WCHAR
));
595 WARN("HeapAlloc() failed\n");
598 bResult
= GetProfilesDirectoryW(ProfilePath
, &cbSize
);
602 WARN("GetUserProfileDirectoryW() failed\n");
606 /* Allocate memory for profile */
607 pProfile
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WLX_PROFILE_V2_0
));
610 WARN("HeapAlloc() failed\n");
613 pProfile
->dwType
= WLX_PROFILE_TYPE_V2_0
;
614 pProfile
->pszProfile
= ProfilePath
;
616 lpEnvironment
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
617 (wcslen(pgContext
->Domain
)+ 14 + 1) * sizeof(WCHAR
));
620 WARN("HeapAlloc() failed\n");
624 wsprintfW(lpEnvironment
, L
"LOGONSERVER=\\\\%s", pgContext
->Domain
);
626 pProfile
->pszEnvironment
= lpEnvironment
;
628 if (!GetTokenInformation(pgContext
->UserToken
,
631 sizeof(TOKEN_STATISTICS
),
634 WARN("Couldn't get Authentication id from user token!\n");
638 *pgContext
->pAuthenticationId
= Stats
.AuthenticationId
;
639 pgContext
->pMprNotifyInfo
->pszUserName
= DuplicationString(UserName
);
640 pgContext
->pMprNotifyInfo
->pszDomain
= DuplicationString(Domain
);
641 pgContext
->pMprNotifyInfo
->pszPassword
= DuplicationString(Password
);
642 pgContext
->pMprNotifyInfo
->pszOldPassword
= NULL
;
643 *pgContext
->pdwOptions
= 0;
644 *pgContext
->pProfile
= pProfile
;
650 HeapFree(GetProcessHeap(), 0, pProfile
->pszEnvironment
);
652 HeapFree(GetProcessHeap(), 0, pProfile
);
653 HeapFree(GetProcessHeap(), 0, ProfilePath
);
661 IN PGINA_CONTEXT pgContext
)
663 HKEY WinLogonKey
= NULL
;
664 LPWSTR AutoLogon
= NULL
;
668 if (pgContext
->AutoLogonState
== AUTOLOGON_DISABLED
)
671 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
672 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
676 if (rc
!= ERROR_SUCCESS
)
679 rc
= ReadRegSzKey(WinLogonKey
,
683 if (rc
!= ERROR_SUCCESS
)
686 if (wcscmp(AutoLogon
, L
"1") == 0)
690 if (WinLogonKey
!= NULL
)
691 RegCloseKey(WinLogonKey
);
692 HeapFree(GetProcessHeap(), 0, AutoLogon
);
700 IN PGINA_CONTEXT pgContext
)
702 HKEY WinLogonKey
= NULL
;
703 LPWSTR AutoLogon
= NULL
;
704 LPWSTR AutoCount
= NULL
;
705 LPWSTR IgnoreShiftOverride
= NULL
;
706 LPWSTR UserName
= NULL
;
707 LPWSTR DomainName
= NULL
;
708 LPWSTR Password
= NULL
;
712 TRACE("DoAutoLogon(): AutoLogonState = %lu\n",
713 pgContext
->AutoLogonState
);
715 if (pgContext
->AutoLogonState
== AUTOLOGON_DISABLED
)
720 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
724 if (rc
!= ERROR_SUCCESS
)
727 if (pgContext
->AutoLogonState
== AUTOLOGON_CHECK_REGISTRY
)
729 /* Set it by default to disabled, we might reenable it again later */
730 pgContext
->AutoLogonState
= AUTOLOGON_DISABLED
;
732 rc
= ReadRegSzKey(WinLogonKey
, L
"AutoAdminLogon", &AutoLogon
);
733 if (rc
!= ERROR_SUCCESS
)
735 if (wcscmp(AutoLogon
, L
"1") != 0)
738 rc
= ReadRegSzKey(WinLogonKey
, L
"AutoLogonCount", &AutoCount
);
739 if (rc
== ERROR_SUCCESS
&& wcscmp(AutoCount
, L
"0") == 0)
741 else if (rc
!= ERROR_FILE_NOT_FOUND
)
744 rc
= ReadRegSzKey(WinLogonKey
, L
"IgnoreShiftOverride", &UserName
);
745 if (rc
== ERROR_SUCCESS
)
747 if (wcscmp(AutoLogon
, L
"1") != 0 && GetKeyState(VK_SHIFT
) < 0)
750 else if (GetKeyState(VK_SHIFT
) < 0)
752 /* User pressed SHIFT */
756 pgContext
->AutoLogonState
= AUTOLOGON_ONCE
;
759 else /* pgContext->AutoLogonState == AUTOLOGON_ONCE */
761 pgContext
->AutoLogonState
= AUTOLOGON_DISABLED
;
763 rc
= ReadRegSzKey(WinLogonKey
, L
"DefaultUserName", &UserName
);
764 if (rc
!= ERROR_SUCCESS
)
766 rc
= ReadRegSzKey(WinLogonKey
, L
"DefaultDomainName", &DomainName
);
767 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_FILE_NOT_FOUND
)
769 rc
= ReadRegSzKey(WinLogonKey
, L
"DefaultPassword", &Password
);
770 if (rc
!= ERROR_SUCCESS
)
773 result
= DoLoginTasks(pgContext
, UserName
, DomainName
, Password
);
776 NotifyBootConfigStatus(TRUE
);
780 if (WinLogonKey
!= NULL
)
781 RegCloseKey(WinLogonKey
);
782 HeapFree(GetProcessHeap(), 0, AutoLogon
);
783 HeapFree(GetProcessHeap(), 0, AutoCount
);
784 HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride
);
785 HeapFree(GetProcessHeap(), 0, UserName
);
786 HeapFree(GetProcessHeap(), 0, DomainName
);
787 HeapFree(GetProcessHeap(), 0, Password
);
788 TRACE("DoAutoLogon(): AutoLogonState = %lu, returning %d\n",
789 pgContext
->AutoLogonState
, result
);
798 IN PVOID pWlxContext
)
800 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
802 TRACE("WlxDisplaySASNotice(%p)\n", pWlxContext
);
804 if (GetSystemMetrics(SM_REMOTESESSION
))
806 /* User is remotely logged on. Don't display a notice */
807 pgContext
->pWlxFuncs
->WlxSasNotify(pgContext
->hWlx
, WLX_SAS_TYPE_CTRL_ALT_DEL
);
811 // if (CheckAutoAdminLogon(pgContext))
812 if (pgContext
->bAutoAdminLogon
== TRUE
)
814 /* Don't display the window, we want to do an automatic logon */
815 pgContext
->AutoLogonState
= AUTOLOGON_ONCE
;
816 pgContext
->pWlxFuncs
->WlxSasNotify(pgContext
->hWlx
, WLX_SAS_TYPE_CTRL_ALT_DEL
);
820 pgContext
->AutoLogonState
= AUTOLOGON_DISABLED
;
822 if (pgContext
->bDisableCAD
== TRUE
)
824 pgContext
->pWlxFuncs
->WlxSasNotify(pgContext
->hWlx
, WLX_SAS_TYPE_CTRL_ALT_DEL
);
828 pGinaUI
->DisplaySASNotice(pgContext
);
830 TRACE("WlxDisplaySASNotice() done\n");
838 IN PVOID pWlxContext
,
840 OUT PLUID pAuthenticationId
,
841 IN OUT PSID pLogonSid
,
842 OUT PDWORD pdwOptions
,
844 OUT PWLX_MPR_NOTIFY_INFO pMprNotifyInfo
,
847 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
850 TRACE("WlxLoggedOutSAS()\n");
852 UNREFERENCED_PARAMETER(dwSasType
);
853 UNREFERENCED_PARAMETER(pLogonSid
);
855 pgContext
->pAuthenticationId
= pAuthenticationId
;
856 pgContext
->pdwOptions
= pdwOptions
;
857 pgContext
->pMprNotifyInfo
= pMprNotifyInfo
;
858 pgContext
->pProfile
= pProfile
;
860 if (0 == GetSystemMetrics(SM_REMOTESESSION
) &&
861 DoAutoLogon(pgContext
))
863 /* User is local and registry contains information
864 * to log on him automatically */
865 *phToken
= pgContext
->UserToken
;
866 return WLX_SAS_ACTION_LOGON
;
869 res
= pGinaUI
->LoggedOutSAS(pgContext
);
870 *phToken
= pgContext
->UserToken
;
882 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
884 TRACE("WlxWkstaLockedSAS()\n");
886 UNREFERENCED_PARAMETER(dwSasType
);
888 return pGinaUI
->LockedSAS(pgContext
);
897 WlxDisplayLockedNotice(PVOID pWlxContext
)
899 PGINA_CONTEXT pgContext
= (PGINA_CONTEXT
)pWlxContext
;
901 TRACE("WlxDisplayLockedNotice()\n");
903 if (pgContext
->bDisableCAD
== TRUE
)
905 pgContext
->pWlxFuncs
->WlxSasNotify(pgContext
->hWlx
, WLX_SAS_TYPE_CTRL_ALT_DEL
);
909 pGinaUI
->DisplayLockedNotice(pgContext
);
920 TRACE("WlxIsLogoffOk()\n");
921 UNREFERENCED_PARAMETER(pWlxContext
);
927 IN HINSTANCE hinstDLL
,
929 IN LPVOID lpvReserved
)
931 UNREFERENCED_PARAMETER(lpvReserved
);
933 if (dwReason
== DLL_PROCESS_ATTACH
)
934 hDllInstance
= hinstDLL
;