编写了一个试图将映射驱动器转换为其等效网络UNC的DLL。但是,当安装程序作为高级进程运行DLL时,它会失败。作为一个潜在的修复程序,我修改了@RbMn提供的示例源,以回答以下问题:How to correctly detect Network drive when running with elevated privileges无法获取映射驱动器的关联网络UNC C/C++
对GetLogicalDrives的调用与它声明的一样工作。但是,当它使用映射的驱动器号对WNetGetConnection进行调用时,返回的错误是1222(ERROR_NO_NETWORK),因此不会提供关联的UNC。我相信问题源于我如何去冒充登录。由于我对UAC事务的知识非常有限,因此我不确定我为了正确获取所需信息而冒用登录方式必须改变什么。
任何帮助,非常感谢。
下面是实际的代码:使用Microsoft LAN Manager按登录会话
BOOL ConvertToMappedFolder(LPSTR pUncPath, LPSTR pMappedDrive)
{
BOOL bRet = 0;
if (1)
{
HANDLE hToken = NULL;
ULONG rcb = 0;
TOKEN_ELEVATION_TYPE tet = 0;
TOKEN_LINKED_TOKEN tlt = { 0 };
ULONG err = BOOL_TO_ERR(OpenProcessToken(GetCurrentProcess() /* NtCurrentProcess() */, TOKEN_QUERY, &hToken));
if (err == NOERROR)
{
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))))
{
bRet = ConvertToMappedFolderEx(pUncPath, pMappedDrive);
SetThreadToken(0, 0);
}
CloseHandle(tlt.LinkedToken);
}
}
}
}
}
BOOL ConvertToMappedFolderEx(LPSTR pUncPath, LPSTR pMappedDrive)
{
int nPos = 0;
UINT nType = 0;
char strDrive[MAX_PATH+1] = "?:\\";
DWORD dwDriveList = GetLogicalDrives();
BOOL bRet = FALSE;
(*pMappedDrive) = 0;
// Check each drive letter determining if it is a mapped drive...
while (dwDriveList)
{
if (dwDriveList & 1)
{
strDrive[0] = 0x41 + nPos;
nType = GetDriveType(strDrive);
// If drive unknown do not attempt to determine if its UNC matches up...
if (DRIVE_UNKNOWN != nType)
{
char szDeviceName[MAX_PATH+1] = "";
char szDriveLetter[4] = " :";
DWORD dwResult = 0;
DWORD cchBuff = MAX_PATH;
szDriveLetter[0] = strDrive[0];
dwResult = WNetGetConnection(szDriveLetter, (LPSTR) szDeviceName, &cchBuff);
if (NO_ERROR == dwResult)
{
LPSTR pPath = _stristr(pUncPath, szDeviceName);
if (NULL != pPath)
{
strcpy(pMappedDrive, szDriveLetter);
strcat(pMappedDrive, (pUncPath + strlen(szDeviceName)));
bRet = TRUE;
break;
}
}
}
}
dwDriveList >>= 1;
nPos++;
}
return (bRet);
}
@HarryJohnston - 不,'WNetGetConnection'或更好的'NetUseGetInfo'全力支持模拟。只是它不支持'SecurityIdentification'模拟级别。几乎没有人接受这个水平。 'GetLogicalDrives'这里很少例外。但对于'WNetGetConnection'则需要'SecurityImpersonation'级别。所以在进程查询中需要更多的代码实现 – RbMm
请记住,提升的令牌可能有自己的一组驱动器映射 - 例如,如果用户打开了提升的命令窗口并使用了net use,那么您需要确定哪些你想要的两个。 (安装程序首先关心驱动器映射是相当奇怪的。) –