我正在开发一个需要正确检测Windows上所有已用驱动器号的应用程序。我使用GetLogicalDrives()
函数。当用户使用提升的权限启动我的应用程序时,此功能可正常工作(即,使用帐户登录的用户属于'管理员'组并通过选择&#34启动我的应用程序;以管理员身份运行&#34 ; 选项)。在这种情况下,GetLogicalDrives()
无法检测到计算机上的映射网络驱动器。
问题的根本原因似乎是在这种情况下,Windows并行运行2个用户会话。我的应用程序运行在"提升的权限"会话,而驱动器映射在"非提升"会话:
此问题是否有任何编程解决方法?我试图重新启动我的应用程序" non-elevated"会议,但不知道如何(或甚至可能)。我尝试过的是使用限制令牌重新启动我的应用程序(使用带有CreateRestrictedToken
选项的DISABLE_MAX_PRIVILEGE
),希望Windows能够以某种方式弄清楚它现在可以重新启动我的应用程序。升高"会话,但它没有用。
答案 0 :(得分:4)
为此您可以临时模拟链接令牌 - 因此获取自己的链接令牌(如果存在),将其设置为线程,调用GetLogicalDrives()
并返回进程令牌(链接令牌具有{{3} } == SecurityIdentification
因此可以非常限制地使用)
#define BOOL_TO_ERR(b) ((b) ? NOERROR : GetLastError())
ULONG GetLogicalDrivesEx(PULONG pDrives)
{
HANDLE hToken;
ULONG err = BOOL_TO_ERR(OpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken));
if (err != NOERROR)
{
return err;
}
union {
TOKEN_ELEVATION_TYPE tet;
TOKEN_LINKED_TOKEN tlt;
};
ULONG rcb;
err = BOOL_TO_ERR(GetTokenInformation(hToken, TokenElevationType, &tet, sizeof(tet), &rcb));
if (err == NOERROR)
{
if (tet == TokenElevationTypeFull)
{
err = BOOL_TO_ERR(GetTokenInformation(hToken, TokenLinkedToken, &tlt, sizeof(tlt), &rcb));
if (err == NOERROR)
{
if (NOERROR == (err = BOOL_TO_ERR(SetThreadToken(0, tlt.LinkedToken))))
{
err = (rcb = GetLogicalDrives()) ? NOERROR : GetLastError();
SetThreadToken(0, 0);
}
CloseHandle(tlt.LinkedToken);
}
}
else
{
err = (rcb = GetLogicalDrives()) ? NOERROR : GetLastError();
}
}
*pDrives = rcb;
return err;
}
void test()
{
ULONG Drives, Drives0 = GetLogicalDrives();
GetLogicalDrivesEx(&Drives);
WCHAR sz[32];
swprintf(sz, L"%08x %08x", Drives0, Drives);
MessageBoxW(0, sz, L"", MB_OK);
}
如果没有错误(GetLogicalDrivesEx
返回NOERROR
),则Drives
是未提升会话的逻辑驱动器,而当驱动器0 - 用于提升(当然,如果您以提升方式运行)