SHGetFolderPath返回运行该程序的用户的%APPDATA%,即使已使用SYSTEM用户令牌对其进行了调用。
答案 0 :(得分:0)
如果运行提升,此代码对我有用:
// Compile with –DPSAPI_VERSION=1
#pragma comment(lib, "userenv.lib")
#pragma comment(lib, "Psapi.lib")
#include <windows.h>
#include <sddl.h>
#include <UserEnv.h>
#include <psapi.h>
#include <shlobj.h>
#include <vector>
bool EnablePrivilege(WCHAR *szPrivName, bool enable)
{
TOKEN_PRIVILEGES tp;
LUID id;
HANDLE token;
if (!LookupPrivilegeValue(0, szPrivName, &id))
return false;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
return false;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
tp.Privileges[0].Luid.LowPart = id.LowPart;
tp.Privileges[0].Luid.HighPart = id.HighPart;
AdjustTokenPrivileges(token, FALSE, &tp, sizeof(tp), 0, 0);
CloseHandle(token);
return (GetLastError() == ERROR_SUCCESS);
}
bool IsTokenSystem(HANDLE tokenHandle)
{
bool result = false;
DWORD retLen = 0;
DWORD tokenLen = 1024;
std::vector<WCHAR> buf(tokenLen);
TOKEN_USER *token = (TOKEN_USER*)&buf.front();
if (GetTokenInformation(tokenHandle, TokenUser, token, tokenLen, &retLen)) {
WCHAR *stringSid = 0;
if (ConvertSidToStringSid(token->User.Sid, &stringSid))
if (wcscmp(stringSid, L"S-1-5-18") == 0) // SYSTEM user SID
result = true;
LocalFree(stringSid);
}
return result;
}
HANDLE GetSystemProcessToken()
{
if (!EnablePrivilege(SE_DEBUG_NAME, true))
printf("Enable SeDebugPrivilege error: %d\n", GetLastError());
DWORD pids[10000] = { 0 };
DWORD needed = 0;
if (!EnumProcesses(pids, sizeof(pids), &needed)) {
return 0;
}
for (DWORD i = 0; i < needed / sizeof(DWORD); ++i) {
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pids[i]);
if (!processHandle)
continue;
HANDLE tokenHandle = 0;
DWORD access = TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_EXECUTE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_READ;
if (OpenProcessToken(processHandle, access, &tokenHandle)) {
if (IsTokenSystem(tokenHandle)) {
CloseHandle(processHandle);
return tokenHandle;
}
}
CloseHandle(tokenHandle);
CloseHandle(processHandle);
}
return 0;
}
int wmain(int argc, WCHAR * argv[])
{
HANDLE systemToken = GetSystemProcessToken();
if (systemToken == 0)
printf("Can't get systemToken\n");
WCHAR path[MAX_PATH];
if (SHGetFolderPath(0, CSIDL_APPDATA, systemToken, SHGFP_TYPE_CURRENT, &path[0]) == S_OK) {
printf("AppData folder: %ls\n", &path[0]);
} else {
printf("SHGetFolderPath error: %d\n", GetLastError());
}
return 0;
}