简体   繁体   English

在C#中以管理员身份添加网络驱动器:注销后消失

[英]Adding network drives in C# as admin: disappear after logoff

Ok, first of all: my task is, to map a network drive programmatically from a C# program that runs as administrator . 好的,首先:我的任务是,以管理员身份运行的C#程序以编程方式映射网络驱动器。

I managed to map a drive as my normal admin user without elevated privileges and it was still visible after logoff/reboot (even though it didn't reconnect, but that's a different story). 我设法以普通的管理员用户身份将驱动器映射为没有提升的特权,并且注销/重新引导后仍然可见(即使它没有重新连接,但这是另一回事)。 I did this with the WNetAddConnection2 WinApi function and also with the net use command in cmd, just to check. 我使用WNetAddConnection2 WinApi函数以及cmd中的net use命令执行此操作,只是为了进行检查。

Sadly, both didn't work with elevated privileges. 可悲的是,两者都没有使用提升的特权。 In this case the drive is added as it schould, but after a reboot it is completely gone. 在这种情况下,将按原样添加驱动器,但是在重新启动后,驱动器将完全消失。

Is it even possible to achieve this with elevated privileges or is there some Windows account magical stuff I don't know about that prevents that? 甚至可以通过提升的特权来实现这一目标或者有一些我不知道的Windows帐户不可思议的功能可以防止这种情况发生?

Here is the Code I used, setting all flags that should usually make the drive be remembered and also reconnected: 这是我使用的代码,设置通常应该使驱动器被记住并重新连接的所有标志:

uint flags = (uint)(Flags.CONNECT_CMD_SAVECRED | 
                    Flags.CONNECT_INTERACTIVE | 
                    Flags.CONNECT_COMMANDLINE | 
                    Flags.CONNECT_UPDATE_PROFILE);

NETRESOURCE NetworkResource = new NETRESOURCE();
oNetworkResource.dwType = ResourceType.RESOURCETYPE_DISK;
oNetworkResource.lpLocalName = Console.ReadLine() + ":";
oNetworkResource.lpRemoteName = @"\\[Server]\foo";
oNetworkResource.lpProvider = null;

Console.WriteLine(WNetAddConnection2(NetworkResource, "[Password]", @"[Domain]\[Username]", flags));

it was still visible after logoff/reboot 注销/重启后仍然可见

this is because, when CONNECT_UPDATE_PROFILE flag used - called exported, but undocumented function I_MprSaveConn (from mpr.dll ) which save in registry, under HKEY_CURRENT_USER\\Network\\<lpLocalName> information which you pass to WNetAddConnection2 . 这是因为,当使用CONNECT_UPDATE_PROFILE标志时-称为导出的但未记录的函数I_MprSaveConn (来自mpr.dll ),该函数保存在注册表中,并在HKEY_CURRENT_USER\\Network\\<lpLocalName>信息下传递给WNetAddConnection2 but I_MprSaveConn at very begin call function bool IsElevatedCaller(PLUID ) and if function return true - it just exit, without saving in registry. I_MprSaveConn在非常开始通话功能bool IsElevatedCaller(PLUID )如果函数返回true -它只是退出,而不在注册表中保存。 so you absolute correct - when you call WNetAddConnection2 from elevated process ( without impersonation ) - this connection not persist (info not saved in registry) 所以您绝对正确-当您从提升的进程中调用WNetAddConnection2时( 没有模拟 )-该连接不会持久(信息未保存在注册表中)

solution: you need got not elevated token (say from explorer ) - open/duplicate (for TokenImpersonation type) and call SetThreadToken . 解决方案:您不需要提升令牌(例如来自explorer )-打开/复制(对于TokenImpersonation类型)并调用SetThreadToken in this case IsElevatedCaller ( can ) return false (it first try open thread token (only if it not exist - process token) ) and query opened token for TokenElevationType (and return true if TokenElevationTypeFull ) 在这种情况下, IsElevatedCallercan )返回false(它首先尝试打开线程令牌(仅在不存在时-处理令牌))并查询TokenElevationType打开令牌(如果TokenElevationTypeFull返回true)

so this of course not documented, but current (i test) if you impersonate self thread with not elevated token (how you got it separate question) flag CONNECT_UPDATE_PROFILE will be worked well 因此,这当然没有记录在案,但是如果您假冒不带提升令牌的自我线程(如何获得独立问题),那么当前(测试)标记CONNECT_UPDATE_PROFILE将可以很好地工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM