tru*_*ong 3 c++ windows winapi
我正在开发一个需要正确检测 Windows 上所有使用的驱动器号的应用程序。我用这个GetLogicalDrives()函数来实现这个目的。除非用户使用提升的权限启动我的应用程序(即,使用属于“管理员”组的帐户登录并通过选择“以管理员身份运行”选项启动我的应用程序),否则此功能工作正常。在这种情况下,GetLogicalDrives()无法检测计算机上的映射网络驱动器。
问题的根本原因似乎是在这种情况下 Windows 并行运行 2 个用户会话。我的应用程序在“提升权限”会话中运行,而驱动器在“非提升”会话中映射:
这个问题有任何程序化的解决方法吗?我尝试在“非提升”会话中重新启动我的应用程序,但不知道如何(或者是否可能)。我已经尝试过使用受限令牌(使用CreateRestrictedTokenwithDISABLE_MAX_PRIVILEGE选项)重新启动我的应用程序,希望 Windows 能够以某种方式发现它现在可以在“非提升”会话中重新启动我的应用程序,但它不起作用。
为此,您可以临时模拟链接令牌 - 因此获取自己的链接令牌,如果存在,将其设置为线程,调用GetLogicalDrives()并返回进程令牌(链接令牌具有SECURITY_IMPERSONATION_LEVEL==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);
}
Run Code Online (Sandbox Code Playgroud)
如果没有错误(GetLogicalDrivesEx返回NOERROR),Drives则为未提升会话的逻辑驱动器,而 Drives0 - 为提升的会话(当然,如果您以提升的方式运行)
| 归档时间: |
|
| 查看次数: |
1592 次 |
| 最近记录: |