📄 profile.c
字号:
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey (hKey);
SetLastError((DWORD)Error);
return FALSE;
}
RegCloseKey (hKey);
wcscat (szProfilePath, L"\\");
wcscat (szProfilePath, szBuffer);
dwLength = wcslen (szProfilePath) + 1;
if (lpProfileDir != NULL)
{
if (*lpcchSize < dwLength)
{
*lpcchSize = dwLength;
SetLastError (ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
wcscpy (lpProfileDir, szProfilePath);
}
*lpcchSize = dwLength;
return TRUE;
}
BOOL WINAPI
GetProfilesDirectoryA (LPSTR lpProfileDir,
LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
lpBuffer = GlobalAlloc (GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
return FALSE;
bResult = GetProfilesDirectoryW (lpBuffer,
lpcchSize);
if (bResult)
{
WideCharToMultiByte (CP_ACP,
0,
lpBuffer,
-1,
lpProfileDir,
*lpcchSize,
NULL,
NULL);
}
GlobalFree (lpBuffer);
return bResult;
}
BOOL WINAPI
GetProfilesDirectoryW (LPWSTR lpProfilesDir,
LPDWORD lpcchSize)
{
WCHAR szProfilesPath[MAX_PATH];
WCHAR szBuffer[MAX_PATH];
DWORD dwLength;
HKEY hKey;
LONG Error;
Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
0,
KEY_QUERY_VALUE,
&hKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
/* Get profiles path */
dwLength = sizeof(szBuffer);
Error = RegQueryValueExW (hKey,
L"ProfilesDirectory",
NULL,
NULL,
(LPBYTE)szBuffer,
&dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1("Error: %lu\n", Error);
RegCloseKey (hKey);
SetLastError((DWORD)Error);
return FALSE;
}
RegCloseKey (hKey);
/* Expand it */
if (!ExpandEnvironmentStringsW (szBuffer,
szProfilesPath,
MAX_PATH))
{
DPRINT1("Error: %lu\n", GetLastError());
return FALSE;
}
dwLength = wcslen (szProfilesPath) + 1;
if (lpProfilesDir != NULL)
{
if (*lpcchSize < dwLength)
{
*lpcchSize = dwLength;
SetLastError (ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
wcscpy (lpProfilesDir, szProfilesPath);
}
*lpcchSize = dwLength;
return TRUE;
}
BOOL WINAPI
GetUserProfileDirectoryA (HANDLE hToken,
LPSTR lpProfileDir,
LPDWORD lpcchSize)
{
LPWSTR lpBuffer;
BOOL bResult;
lpBuffer = GlobalAlloc (GMEM_FIXED,
*lpcchSize * sizeof(WCHAR));
if (lpBuffer == NULL)
return FALSE;
bResult = GetUserProfileDirectoryW (hToken,
lpBuffer,
lpcchSize);
if (bResult)
{
WideCharToMultiByte (CP_ACP,
0,
lpBuffer,
-1,
lpProfileDir,
*lpcchSize,
NULL,
NULL);
}
GlobalFree (lpBuffer);
return bResult;
}
BOOL WINAPI
GetUserProfileDirectoryW (HANDLE hToken,
LPWSTR lpProfileDir,
LPDWORD lpcchSize)
{
UNICODE_STRING SidString;
WCHAR szKeyName[MAX_PATH];
WCHAR szRawImagePath[MAX_PATH];
WCHAR szImagePath[MAX_PATH];
DWORD dwLength;
HKEY hKey;
LONG Error;
if (!GetUserSidFromToken (hToken,
&SidString))
{
DPRINT1 ("GetUserSidFromToken() failed\n");
return FALSE;
}
DPRINT ("SidString: '%wZ'\n", &SidString);
wcscpy (szKeyName,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
wcscat (szKeyName,
SidString.Buffer);
RtlFreeUnicodeString (&SidString);
DPRINT ("KeyName: '%S'\n", szKeyName);
Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
szKeyName,
0,
KEY_QUERY_VALUE,
&hKey);
if (Error != ERROR_SUCCESS)
{
DPRINT1 ("Error: %lu\n", Error);
SetLastError((DWORD)Error);
return FALSE;
}
dwLength = sizeof(szRawImagePath);
Error = RegQueryValueExW (hKey,
L"ProfileImagePath",
NULL,
NULL,
(LPBYTE)szRawImagePath,
&dwLength);
if (Error != ERROR_SUCCESS)
{
DPRINT1 ("Error: %lu\n", Error);
RegCloseKey (hKey);
SetLastError((DWORD)Error);
return FALSE;
}
RegCloseKey (hKey);
DPRINT ("RawImagePath: '%S'\n", szRawImagePath);
/* Expand it */
if (!ExpandEnvironmentStringsW (szRawImagePath,
szImagePath,
MAX_PATH))
{
DPRINT1 ("Error: %lu\n", GetLastError());
return FALSE;
}
DPRINT ("ImagePath: '%S'\n", szImagePath);
dwLength = wcslen (szImagePath) + 1;
if (*lpcchSize < dwLength)
{
*lpcchSize = dwLength;
SetLastError (ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
*lpcchSize = dwLength;
wcscpy (lpProfileDir,
szImagePath);
return TRUE;
}
static BOOL
CheckForLoadedProfile (HANDLE hToken)
{
UNICODE_STRING SidString;
HKEY hKey;
DPRINT ("CheckForLoadedProfile() called \n");
if (!GetUserSidFromToken (hToken,
&SidString))
{
DPRINT1 ("GetUserSidFromToken() failed\n");
return FALSE;
}
if (RegOpenKeyExW (HKEY_USERS,
SidString.Buffer,
0,
MAXIMUM_ALLOWED,
&hKey))
{
DPRINT ("Profile not loaded\n");
RtlFreeUnicodeString (&SidString);
return FALSE;
}
RegCloseKey (hKey);
RtlFreeUnicodeString (&SidString);
DPRINT ("Profile already loaded\n");
return TRUE;
}
BOOL WINAPI
LoadUserProfileA (HANDLE hToken,
LPPROFILEINFOA lpProfileInfo)
{
DPRINT ("LoadUserProfileA() not implemented\n");
return FALSE;
}
BOOL WINAPI
LoadUserProfileW(
IN HANDLE hToken,
IN OUT LPPROFILEINFOW lpProfileInfo)
{
WCHAR szUserHivePath[MAX_PATH];
LPWSTR UserName = NULL, Domain = NULL;
DWORD UserNameLength = 0, DomainLength = 0;
PTOKEN_USER UserSid = NULL;
SID_NAME_USE AccountType;
UNICODE_STRING SidString = { 0, };
LONG Error;
BOOL ret = FALSE;
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
DPRINT("LoadUserProfileW() called\n");
/* Check profile info */
if (!lpProfileInfo
|| lpProfileInfo->dwSize != sizeof(PROFILEINFOW)
|| lpProfileInfo->lpUserName == NULL
|| lpProfileInfo->lpUserName[0] == 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return TRUE;
}
/* Don't load a profile twice */
if (CheckForLoadedProfile(hToken))
{
DPRINT ("Profile already loaded\n");
lpProfileInfo->hProfile = NULL;
return TRUE;
}
if (lpProfileInfo->lpProfilePath)
{
wcscpy(szUserHivePath, lpProfileInfo->lpProfilePath);
}
else
{
/* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
{
DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
return FALSE;
}
}
wcscat(szUserHivePath, L"\\");
wcscat(szUserHivePath, lpProfileInfo->lpUserName);
dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
if (!AppendSystemPostfix(szUserHivePath, dwLength))
{
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
return FALSE;
}
/* Create user hive name */
wcscat(szUserHivePath, L"\\ntuser.dat");
DPRINT("szUserHivePath: %S\n", szUserHivePath);
/* Create user profile directory if needed */
if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
{
/* Get user sid */
if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength)
|| GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
DPRINT1 ("GetTokenInformation() failed\n");
return FALSE;
}
UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
if (!UserSid)
{
DPRINT1 ("HeapAlloc() failed\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
{
DPRINT1 ("GetTokenInformation() failed\n");
goto cleanup;
}
/* Get user name */
do
{
if (UserNameLength > 0)
{
HeapFree(GetProcessHeap(), 0, UserName);
UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
if (!UserName)
{
DPRINT1("HeapAlloc() failed\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
}
if (DomainLength > 0)
{
HeapFree(GetProcessHeap(), 0, Domain);
Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
if (!Domain)
{
DPRINT1("HeapAlloc() failed\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
}
ret = LookupAccountSidW(
NULL, UserSid->User.Sid,
UserName, &UserNameLength,
Domain, &DomainLength,
&AccountType);
} while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
if (!ret)
{
DPRINT1("LookupAccountSidW() failed\n");
goto cleanup;
}
/* Create profile */
/* FIXME: ignore Domain? */
DPRINT("UserName %S, Domain %S\n", UserName, Domain);
ret = CreateUserProfileW(UserSid->User.Sid, UserName);
if (!ret)
{
DPRINT1("CreateUserProfileW() failed\n");
goto cleanup;
}
}
/* Get user SID string */
ret = GetUserSidFromToken(hToken, &SidString);
if (!ret)
{
DPRINT1("GetUserSidFromToken() failed\n");
goto cleanup;
}
ret = FALSE;
/* Load user registry hive */
Error = RegLoadKeyW(HKEY_USERS,
SidString.Buffer,
szUserHivePath);
if (Error != ERROR_SUCCESS)
{
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
SetLastError((DWORD)Error);
goto cleanup;
}
/* Open future HKEY_CURRENT_USER */
Error = RegOpenKeyExW(HKEY_USERS,
SidString.Buffer,
0,
MAXIMUM_ALLOWED,
(PHKEY)&lpProfileInfo->hProfile);
if (Error != ERROR_SUCCESS)
{
DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
SetLastError((DWORD)Error);
goto cleanup;
}
ret = TRUE;
cleanup:
HeapFree(GetProcessHeap(), 0, UserSid);
HeapFree(GetProcessHeap(), 0, UserName);
HeapFree(GetProcessHeap(), 0, Domain);
RtlFreeUnicodeString(&SidString);
DPRINT("LoadUserProfileW() done\n");
return ret;
}
BOOL WINAPI
UnloadUserProfile (HANDLE hToken,
HANDLE hProfile)
{
UNICODE_STRING SidString;
LONG Error;
DPRINT ("UnloadUserProfile() called\n");
if (hProfile == NULL)
{
DPRINT1 ("Invalide profile handle\n");
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
RegCloseKey (hProfile);
if (!GetUserSidFromToken (hToken,
&SidString))
{
DPRINT1 ("GetUserSidFromToken() failed\n");
return FALSE;
}
DPRINT ("SidString: '%wZ'\n", &SidString);
Error = RegUnLoadKeyW (HKEY_USERS,
SidString.Buffer);
if (Error != ERROR_SUCCESS)
{
DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", Error);
RtlFreeUnicodeString (&SidString);
SetLastError((DWORD)Error);
return FALSE;
}
RtlFreeUnicodeString (&SidString);
DPRINT ("UnloadUserProfile() done\n");
return TRUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -