|
|
|
|
@@ -66,6 +66,10 @@ ReadRegSzKey(
|
|
|
|
|
DWORD cbData = 0;
|
|
|
|
|
LPWSTR Value;
|
|
|
|
|
|
|
|
|
|
if (!pValue)
|
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
*pValue = NULL;
|
|
|
|
|
rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
|
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
|
return rc;
|
|
|
|
|
@@ -145,39 +149,44 @@ WlxInitialize(
|
|
|
|
|
PVOID pWinlogonFunctions,
|
|
|
|
|
PVOID *pWlxContext)
|
|
|
|
|
{
|
|
|
|
|
PGINA_CONTEXT pgContext;
|
|
|
|
|
|
|
|
|
|
pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT));
|
|
|
|
|
if(!pgContext)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* return the context to winlogon */
|
|
|
|
|
*pWlxContext = (PVOID)pgContext;
|
|
|
|
|
|
|
|
|
|
pgContext->hDllInstance = hDllInstance;
|
|
|
|
|
|
|
|
|
|
/* save pointer to dispatch table */
|
|
|
|
|
pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions;
|
|
|
|
|
|
|
|
|
|
/* save the winlogon handle used to call the dispatch functions */
|
|
|
|
|
pgContext->hWlx = hWlx;
|
|
|
|
|
|
|
|
|
|
/* save window station */
|
|
|
|
|
pgContext->station = lpWinsta;
|
|
|
|
|
|
|
|
|
|
/* clear status window handle */
|
|
|
|
|
pgContext->hStatusWindow = 0;
|
|
|
|
|
|
|
|
|
|
/* notify winlogon that we will use the default SAS */
|
|
|
|
|
pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);
|
|
|
|
|
|
|
|
|
|
/* Locates the authentification package */
|
|
|
|
|
//LsaRegisterLogonProcess(...);
|
|
|
|
|
PGINA_CONTEXT pgContext;
|
|
|
|
|
|
|
|
|
|
pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY;
|
|
|
|
|
UNREFERENCED_PARAMETER(pvReserved);
|
|
|
|
|
|
|
|
|
|
ChooseGinaUI();
|
|
|
|
|
return pGinaUI->Initialize(pgContext);
|
|
|
|
|
pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT));
|
|
|
|
|
if(!pgContext)
|
|
|
|
|
{
|
|
|
|
|
WARN("LocalAlloc() failed\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the context to winlogon */
|
|
|
|
|
*pWlxContext = (PVOID)pgContext;
|
|
|
|
|
pgContext->hDllInstance = hDllInstance;
|
|
|
|
|
|
|
|
|
|
/* Save pointer to dispatch table */
|
|
|
|
|
pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions;
|
|
|
|
|
|
|
|
|
|
/* Save the winlogon handle used to call the dispatch functions */
|
|
|
|
|
pgContext->hWlx = hWlx;
|
|
|
|
|
|
|
|
|
|
/* Save window station */
|
|
|
|
|
pgContext->station = lpWinsta;
|
|
|
|
|
|
|
|
|
|
/* Clear status window handle */
|
|
|
|
|
pgContext->hStatusWindow = 0;
|
|
|
|
|
|
|
|
|
|
/* Notify winlogon that we will use the default SAS */
|
|
|
|
|
pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);
|
|
|
|
|
|
|
|
|
|
/* Locates the authentification package */
|
|
|
|
|
//LsaRegisterLogonProcess(...);
|
|
|
|
|
|
|
|
|
|
/* Check autologon settings the first time */
|
|
|
|
|
pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY;
|
|
|
|
|
|
|
|
|
|
ChooseGinaUI();
|
|
|
|
|
return pGinaUI->Initialize(pgContext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@@ -190,39 +199,43 @@ WlxStartApplication(
|
|
|
|
|
PVOID pEnvironment,
|
|
|
|
|
PWSTR pszCmdLine)
|
|
|
|
|
{
|
|
|
|
|
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
|
|
|
|
|
STARTUPINFOW StartupInfo;
|
|
|
|
|
PROCESS_INFORMATION ProcessInformation;
|
|
|
|
|
WCHAR CurrentDirectory[MAX_PATH];
|
|
|
|
|
BOOL Ret;
|
|
|
|
|
|
|
|
|
|
StartupInfo.cb = sizeof(STARTUPINFOW);
|
|
|
|
|
StartupInfo.lpReserved = NULL;
|
|
|
|
|
StartupInfo.lpTitle = pszCmdLine;
|
|
|
|
|
StartupInfo.dwX = StartupInfo.dwY = StartupInfo.dwXSize = StartupInfo.dwYSize = 0L;
|
|
|
|
|
StartupInfo.dwFlags = 0;
|
|
|
|
|
StartupInfo.wShowWindow = SW_SHOW;
|
|
|
|
|
StartupInfo.lpReserved2 = NULL;
|
|
|
|
|
StartupInfo.cbReserved2 = 0;
|
|
|
|
|
StartupInfo.lpDesktop = pszDesktopName;
|
|
|
|
|
|
|
|
|
|
GetWindowsDirectoryW (CurrentDirectory, MAX_PATH);
|
|
|
|
|
Ret = CreateProcessAsUserW(pgContext->UserToken,
|
|
|
|
|
pszCmdLine,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
FALSE,
|
|
|
|
|
CREATE_UNICODE_ENVIRONMENT,
|
|
|
|
|
pEnvironment,
|
|
|
|
|
CurrentDirectory,
|
|
|
|
|
&StartupInfo,
|
|
|
|
|
&ProcessInformation);
|
|
|
|
|
|
|
|
|
|
//VirtualFree(pEnvironment, 0, MEM_RELEASE);
|
|
|
|
|
return Ret;
|
|
|
|
|
}
|
|
|
|
|
PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
|
|
|
|
|
STARTUPINFOW StartupInfo;
|
|
|
|
|
PROCESS_INFORMATION ProcessInformation;
|
|
|
|
|
WCHAR CurrentDirectory[MAX_PATH];
|
|
|
|
|
UINT len;
|
|
|
|
|
BOOL ret;
|
|
|
|
|
|
|
|
|
|
ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
|
|
|
|
|
StartupInfo.cb = sizeof(STARTUPINFOW);
|
|
|
|
|
StartupInfo.lpTitle = pszCmdLine;
|
|
|
|
|
StartupInfo.dwX = StartupInfo.dwY = StartupInfo.dwXSize = StartupInfo.dwYSize = 0L;
|
|
|
|
|
StartupInfo.dwFlags = 0;
|
|
|
|
|
StartupInfo.wShowWindow = SW_SHOW;
|
|
|
|
|
StartupInfo.lpDesktop = pszDesktopName;
|
|
|
|
|
|
|
|
|
|
len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH);
|
|
|
|
|
if (len > MAX_PATH)
|
|
|
|
|
{
|
|
|
|
|
WARN("GetWindowsDirectoryW() failed\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ret = CreateProcessAsUserW(
|
|
|
|
|
pgContext->UserToken,
|
|
|
|
|
pszCmdLine,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
FALSE,
|
|
|
|
|
CREATE_UNICODE_ENVIRONMENT,
|
|
|
|
|
pEnvironment,
|
|
|
|
|
CurrentDirectory,
|
|
|
|
|
&StartupInfo,
|
|
|
|
|
&ProcessInformation);
|
|
|
|
|
if (!ret)
|
|
|
|
|
WARN("CreateProcessAsUserW() failed with error %lu\n", GetLastError());
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
@@ -234,37 +247,57 @@ WlxActivateUserShell(
|
|
|
|
|
PWSTR pszMprLogonScript,
|
|
|
|
|
PVOID pEnvironment)
|
|
|
|
|
{
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
DWORD BufSize, ValueType;
|
|
|
|
|
WCHAR pszUserInitApp[MAX_PATH];
|
|
|
|
|
WCHAR pszExpUserInitApp[MAX_PATH];
|
|
|
|
|
TRACE("WlxActivateUserShell()\n");
|
|
|
|
|
/* get the path of userinit */
|
|
|
|
|
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
|
|
|
0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
|
|
|
|
|
{ERR("GINA: Failed: 1\n");
|
|
|
|
|
VirtualFree(pEnvironment, 0, MEM_RELEASE);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
BufSize = MAX_PATH * sizeof(WCHAR);
|
|
|
|
|
if((RegQueryValueExW(hKey, L"Userinit", NULL, &ValueType, (LPBYTE)pszUserInitApp,
|
|
|
|
|
&BufSize) != ERROR_SUCCESS) ||
|
|
|
|
|
!((ValueType == REG_SZ) || (ValueType == REG_EXPAND_SZ)))
|
|
|
|
|
{ERR("GINA: Failed: 2\n");
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
VirtualFree(pEnvironment, 0, MEM_RELEASE);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
|
|
|
|
|
|
|
|
|
|
/* Start userinit */
|
|
|
|
|
/* FIXME - allow to start more applications that are comma-separated */
|
|
|
|
|
/* FIXME: Call VirtualFree(pEnvironment, 0, MEM_RELEASE); ? */
|
|
|
|
|
return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp);
|
|
|
|
|
}
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
DWORD BufSize, ValueType;
|
|
|
|
|
WCHAR pszUserInitApp[MAX_PATH + 1];
|
|
|
|
|
WCHAR pszExpUserInitApp[MAX_PATH];
|
|
|
|
|
DWORD len;
|
|
|
|
|
LONG rc;
|
|
|
|
|
|
|
|
|
|
TRACE("WlxActivateUserShell()\n");
|
|
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(pszMprLogonScript);
|
|
|
|
|
|
|
|
|
|
/* Get the path of userinit */
|
|
|
|
|
rc = RegOpenKeyExW(
|
|
|
|
|
HKEY_LOCAL_MACHINE,
|
|
|
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
|
|
|
0,
|
|
|
|
|
KEY_QUERY_VALUE,
|
|
|
|
|
&hKey);
|
|
|
|
|
if (rc != ERROR_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
WARN("RegOpenKeyExW() failed with error %lu\n", rc);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Query userinit application */
|
|
|
|
|
BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL);
|
|
|
|
|
rc = RegQueryValueExW(
|
|
|
|
|
hKey,
|
|
|
|
|
L"Userinit",
|
|
|
|
|
NULL,
|
|
|
|
|
&ValueType,
|
|
|
|
|
(LPBYTE)pszUserInitApp,
|
|
|
|
|
&BufSize);
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ))
|
|
|
|
|
{
|
|
|
|
|
WARN("RegQueryValueExW() failed with error %lu\n", rc);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
pszUserInitApp[MAX_PATH] = UNICODE_NULL;
|
|
|
|
|
|
|
|
|
|
len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
|
|
|
|
|
if (len > MAX_PATH)
|
|
|
|
|
{
|
|
|
|
|
WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Start userinit app */
|
|
|
|
|
return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
@@ -280,6 +313,8 @@ WlxLoggedOnSAS(
|
|
|
|
|
|
|
|
|
|
TRACE("WlxLoggedOnSAS(0x%lx)\n", dwSasType);
|
|
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(pReserved);
|
|
|
|
|
|
|
|
|
|
switch (dwSasType)
|
|
|
|
|
{
|
|
|
|
|
case WLX_SAS_TYPE_CTRL_ALT_DEL:
|
|
|
|
|
@@ -361,8 +396,11 @@ DoLoginTasks(
|
|
|
|
|
IN PWSTR Domain,
|
|
|
|
|
IN PWSTR Password)
|
|
|
|
|
{
|
|
|
|
|
LPWSTR ProfilePath = NULL;
|
|
|
|
|
TOKEN_STATISTICS Stats;
|
|
|
|
|
DWORD cbStats;
|
|
|
|
|
PWLX_PROFILE_V1_0 pProfile = NULL;
|
|
|
|
|
DWORD cbStats, cbSize;
|
|
|
|
|
BOOL bResult;
|
|
|
|
|
|
|
|
|
|
if (!LogonUserW(UserName, Domain, Password,
|
|
|
|
|
LOGON32_LOGON_INTERACTIVE, /* FIXME - use LOGON32_LOGON_UNLOCK instead! */
|
|
|
|
|
@@ -370,17 +408,37 @@ DoLoginTasks(
|
|
|
|
|
&pgContext->UserToken))
|
|
|
|
|
{
|
|
|
|
|
WARN("LogonUserW() failed\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pgContext->UserToken)
|
|
|
|
|
/* Get profile path */
|
|
|
|
|
cbSize = 0;
|
|
|
|
|
bResult = GetProfilesDirectoryW(NULL, &cbSize);
|
|
|
|
|
if (!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
|
{
|
|
|
|
|
WARN("UserToken == NULL!\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
ProfilePath = HeapAlloc(GetProcessHeap(), 0, cbSize * sizeof(WCHAR));
|
|
|
|
|
if (!ProfilePath)
|
|
|
|
|
{
|
|
|
|
|
WARN("HeapAlloc() failed\n");
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
bResult = GetProfilesDirectoryW(ProfilePath, &cbSize);
|
|
|
|
|
}
|
|
|
|
|
if (!bResult)
|
|
|
|
|
{
|
|
|
|
|
WARN("GetUserProfileDirectoryW() failed\n");
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*pgContext->pdwOptions = 0;
|
|
|
|
|
*pgContext->pProfile = NULL;
|
|
|
|
|
/* Allocate memory for profile */
|
|
|
|
|
pProfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLX_PROFILE_V1_0));
|
|
|
|
|
if (!pProfile)
|
|
|
|
|
{
|
|
|
|
|
WARN("HeapAlloc() failed\n");
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
pProfile->dwType = WLX_PROFILE_TYPE_V1_0;
|
|
|
|
|
pProfile->pszProfile = ProfilePath;
|
|
|
|
|
|
|
|
|
|
if (!GetTokenInformation(pgContext->UserToken,
|
|
|
|
|
TokenStatistics,
|
|
|
|
|
@@ -389,14 +447,21 @@ DoLoginTasks(
|
|
|
|
|
&cbStats))
|
|
|
|
|
{
|
|
|
|
|
WARN("Couldn't get Authentication id from user token!\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
*pgContext->pAuthenticationId = Stats.AuthenticationId;
|
|
|
|
|
pgContext->pNprNotifyInfo->pszUserName = DuplicationString(UserName);
|
|
|
|
|
pgContext->pNprNotifyInfo->pszDomain = DuplicationString(Domain);
|
|
|
|
|
pgContext->pNprNotifyInfo->pszPassword = DuplicationString(Password);
|
|
|
|
|
pgContext->pNprNotifyInfo->pszOldPassword = NULL;
|
|
|
|
|
*pgContext->pdwOptions = 0;
|
|
|
|
|
*pgContext->pProfile = pProfile;
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, pProfile);
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, ProfilePath);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static BOOL
|
|
|
|
|
@@ -543,12 +608,15 @@ WlxLoggedOutSAS(
|
|
|
|
|
|
|
|
|
|
TRACE("WlxLoggedOutSAS()\n");
|
|
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(dwSasType);
|
|
|
|
|
UNREFERENCED_PARAMETER(pLogonSid);
|
|
|
|
|
|
|
|
|
|
pgContext->pAuthenticationId = pAuthenticationId;
|
|
|
|
|
pgContext->pdwOptions = pdwOptions;
|
|
|
|
|
pgContext->pNprNotifyInfo = pNprNotifyInfo;
|
|
|
|
|
pgContext->pProfile = pProfile;
|
|
|
|
|
|
|
|
|
|
if (!GetSystemMetrics(SM_REMOTESESSION) &&
|
|
|
|
|
if (0 == GetSystemMetrics(SM_REMOTESESSION) &&
|
|
|
|
|
DoAutoLogon(pgContext))
|
|
|
|
|
{
|
|
|
|
|
/* User is local and registry contains information
|
|
|
|
|
@@ -574,6 +642,8 @@ WlxWkstaLockedSAS(
|
|
|
|
|
|
|
|
|
|
TRACE("WlxWkstaLockedSAS()\n");
|
|
|
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(dwSasType);
|
|
|
|
|
|
|
|
|
|
return pGinaUI->LockedSAS(pgContext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -583,6 +653,8 @@ DllMain(
|
|
|
|
|
IN DWORD dwReason,
|
|
|
|
|
IN LPVOID lpvReserved)
|
|
|
|
|
{
|
|
|
|
|
UNREFERENCED_PARAMETER(lpvReserved);
|
|
|
|
|
|
|
|
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
|
|
|
hDllInstance = hinstDLL;
|
|
|
|
|
|
|
|
|
|
|