gpt4 book ai didi

windows - 为什么在模拟 session 中定义的 DOS 设备没有出现在资源管理器中

转载 作者:可可西里 更新时间:2023-11-01 13:34:34 25 4
gpt4 key购买 nike

我有一个在本地系统帐户下运行的 Windows 服务,它使用 DefineDosDevice 函数创建 DOS 设备。该服务在 W2K8 远程桌面服务器上运行。如果设备是使用服务的凭据创建的,则它们是在 GLOBAL 设备 namespace 中创建的,因此对所有用户可见。我需要仅对特定交互 session 可见的设备。

我通过模拟我希望驱动器出现在其 session 中的用户来完成此操作。这非常简单,前提是 session ID 可用。这是我编写的一个简单的测试应用程序来说明问题:

int _tmain(int argc, _TCHAR* argv[])
{
BOOL result = TRUE;

if(argc > 3 && !wcscmp(argv[2], L"/i"))
{
HANDLE hToken = 0;
DWORD dwSessionId = _wtoi(argv[3]);
result = WTSQueryUserToken(dwSessionId, &hToken);
if(result) result = ImpersonateLoggedOnUser(hToken);
}
if(result)
{
LPTSTR drive = argv[1];
DefineDosDevice(DDD_REMOVE_DEFINITION, drive, NULL);
result = DefineDosDevice(0, drive, L"C:\\test");
}

if(!result)
{
printf("Error: %d\n", GetLastError());
}
return 0;
}

为了测试这段代码,我创建了一个在本地系统帐户下启动命令 shell 的服务:

sc create test_svc binpath= "cmd /K start" type= own type= interact

此服务无法启动,但在失败之前,它会生成一个在 LocalSystem 帐户下运行的命令 shell。

我从 LocalSystem cmd.exe 运行:

MySubst.exe x: /i 2

调用 ImpersonateLoggedOnUser(),然后调用 DefineDosDevice()

在用户 session 中运行的 cmd.exe 中,我运行:

MySubst.exe y:

调用 DefineDosDevice 而不调用 ImpersonateLoggedOnUser()。

这行得通。从 cmd.exe 我可以访问两个驱动器 X: 和 Y:。我可以从开始菜单启动 notepad.exe,然后看到 X: 和 Y: 驱动器。此外,如果我与其他用户创建新的终端服务 session ,我看不到 X: 或 Y:。

但是,资源管理器仅在“所有计算机”下显示 Y: 驱动器。 Y:是通过在目标 session 中运行的 cmd.exe 运行我的测试应用程序而创建的驱动器,即未完成模拟。如果我从任务管理器重新启动 explorer.exe,X: 和 Y: 驱动器都会显示。

我还使用了 SysInternals 的 WinObj.exe 来检查定义的 Win NT 设备。我看到的是:

- Sessions
- 0
- DosDevices
00000000-000057607

(57607 是与我正在模拟的 session 关联的登录 session 的 ID)

“00000000-000057607”的内容是:

Global    SymbolicLink    \Global??
X: SymbolicLink \\??\C:\test
Y: SymbolicLink \\??\C:\test

根据 WinObj,这两个 dos 设备是相同的。它们属于同一个 session 和登录 session 。它们是指向同一 NT 对象的符号链接(symbolic link)。

怎么可能其中一个出现在资源管理器中而另一个没有。

最佳答案

@arx 和@HarryJohnston 赚了钱。如果我从与资源管理器相同的 session 中的线程广播 WM_DEVICECHANGE 消息,新驱动器将出现在我的电脑中。这是代码:

DWORD recipients = BSM_ALLDESKTOPS | BSM_APPLICATIONS;

DEV_BROADCAST_VOLUME msg;
ZeroMemory(&msg, sizeof(msg));
msg.dbcv_size = sizeof(msg);
msg.dbcv_devicetype = DBT_DEVTYP_VOLUME;
msg.dbcv_unitmask = 1 << ('X' - 'A');

long success = BroadcastSystemMessage(0, &recipients, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)&msg);

关于windows - 为什么在模拟 session 中定义的 DOS 设备没有出现在资源管理器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14866008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com