Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 提升的应用程序需要获取非提升映射驱动器列表_C#_Uac_Elevated Privileges - Fatal编程技术网

C# 提升的应用程序需要获取非提升映射驱动器列表

C# 提升的应用程序需要获取非提升映射驱动器列表,c#,uac,elevated-privileges,C#,Uac,Elevated Privileges,我知道以提升方式运行的.NET应用程序无法看到用户的映射驱动器。我还知道有一个注册表黑客来修复这个问题(包括重新启动) 我想为这个问题创建一个不同的解决方案。我们的应用程序必须运行提升版,并且严重依赖于用户创建的映射驱动器。我想检测用户拥有的映射驱动器,并从提升的应用程序映射一组类似的驱动器 因此,问题是:如何从提升的应用程序中检测“普通”用户的映射驱动器?如果映射驱动器一直映射(选中“登录时重新连接”复选框),则可以在用户的注册表配置单元中找到它: HKEY_CURRENT_USER\Netw

我知道以提升方式运行的.NET应用程序无法看到用户的映射驱动器。我还知道有一个注册表黑客来修复这个问题(包括重新启动)

我想为这个问题创建一个不同的解决方案。我们的应用程序必须运行提升版,并且严重依赖于用户创建的映射驱动器。我想检测用户拥有的映射驱动器,并从提升的应用程序映射一组类似的驱动器


因此,问题是:如何从提升的应用程序中检测“普通”用户的映射驱动器?

如果映射驱动器一直映射(选中“登录时重新连接”复选框),则可以在用户的注册表配置单元中找到它:

HKEY_CURRENT_USER\Network\<drive letter>
HKEY\U当前用户\网络\

该键有一个值
RemotePath
,其中包含UNC路径。

我现在有一些解决此问题的方法。读取注册表是可以的,但找不到由域配置文件或其他临时映射驱动器创建的驱动器

我测试过的一个有效的解决方案是使用代码创建一个未提升的流程。我编写了一个简单的GetMappedDrives.exe应用程序,将映射的驱动器写入一个文件。提升的应用程序然后可以读取该文件以获取未提升的映射驱动器

另一种解决方案可能是在提升的应用程序周围使用未提升的包装器。未提升的包装将首先调用GetMappedDrives.exe,然后运行提升的应用程序。问题是,在重新启动应用程序之前,您不会知道映射驱动器的更改

如果您碰巧有一个未提升的进程作为应用程序套件的一部分运行,那么第三种解决方案可能适用。只需从未提升的应用程序中弹出一条网络消息,告诉它调用GetMappedDrive.exe

GetMappedDrive c#代码

TestGeMeAdvDead C++代码。在提升的命令提示符下运行此命令

#include "stdafx.h"
#include "windows.h"

//#ifndef SECURITY_MANDATORY_HIGH_RID
//  #define SECURITY_MANDATORY_UNTRUSTED_RID            (0x00000000L)
//  #define SECURITY_MANDATORY_LOW_RID                  (0x00001000L)
//  #define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
//  #define SECURITY_MANDATORY_HIGH_RID                 (0x00003000L)
//  #define SECURITY_MANDATORY_SYSTEM_RID               (0x00004000L)
//  #define SECURITY_MANDATORY_PROTECTED_PROCESS_RID    (0x00005000L)
//#endif

//#ifndef TokenIntegrityLevel
//  #define TokenIntegrityLevel ((TOKEN_INFORMATION_CLASS)25)
//#endif

//#ifndef TOKEN_MANDATORY_LABEL
//  typedef struct  
//  {
//      SID_AND_ATTRIBUTES Label;
//  } TOKEN_MANDATORY_LABEL;
//#endif

typedef BOOL (WINAPI *defCreateProcessWithTokenW)
(HANDLE,DWORD,LPCWSTR,LPWSTR,DWORD,LPVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION);


// Writes Integration Level of the process with the given ID into pu32_ProcessIL
// returns Win32 API error or 0 if succeeded
DWORD GetProcessIL(DWORD u32_PID, DWORD* pu32_ProcessIL)
{
*pu32_ProcessIL = 0;

HANDLE h_Process   = 0;
HANDLE h_Token     = 0;
DWORD  u32_Size    = 0;
BYTE*  pu8_Count   = 0;
DWORD* pu32_ProcIL = 0;
TOKEN_MANDATORY_LABEL* pk_Label = 0;

h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_PID);
if (!h_Process)
    goto _CleanUp;

if (!OpenProcessToken(h_Process, TOKEN_QUERY, &h_Token))
    goto _CleanUp;

if (!GetTokenInformation(h_Token, TokenIntegrityLevel, NULL, 0, &u32_Size) &&
     GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    goto _CleanUp;

pk_Label = (TOKEN_MANDATORY_LABEL*) HeapAlloc(GetProcessHeap(), 0, u32_Size);
if (!pk_Label)
    goto _CleanUp;

if (!GetTokenInformation(h_Token, TokenIntegrityLevel, pk_Label, u32_Size, &u32_Size))
    goto _CleanUp;

pu8_Count = GetSidSubAuthorityCount(pk_Label->Label.Sid);
if (!pu8_Count)
    goto _CleanUp;

pu32_ProcIL = GetSidSubAuthority(pk_Label->Label.Sid, *pu8_Count-1);
if (!pu32_ProcIL)
    goto _CleanUp;

*pu32_ProcessIL = *pu32_ProcIL;
SetLastError(ERROR_SUCCESS);

_CleanUp:
DWORD u32_Error = GetLastError();
if (pk_Label)  HeapFree(GetProcessHeap(), 0, pk_Label);
if (h_Token)   CloseHandle(h_Token);
if (h_Process) CloseHandle(h_Process);
return u32_Error;
}

// Creates a new process u16_Path with the integration level of the Explorer process (MEDIUM IL)
// If you need this function in a service you must replace FindWindow() with another API to find Explorer process
// The parent process of the new process will be svchost.exe if this EXE was run "As Administrator"
// returns Win32 API error or 0 if succeeded
DWORD CreateProcessMediumIL(WCHAR* u16_Path, WCHAR* u16_CmdLine)
{
HANDLE h_Process = 0;
HANDLE h_Token   = 0;
HANDLE h_Token2  = 0;
PROCESS_INFORMATION k_ProcInfo    = {0};
STARTUPINFOW        k_StartupInfo = {0};

BOOL b_UseToken = FALSE;

// Detect Windows Vista, 2008, Windows 7 and higher
if (GetProcAddress(GetModuleHandleA("Kernel32"), "GetProductInfo"))
{
    DWORD u32_CurIL;
    DWORD u32_Err = GetProcessIL(GetCurrentProcessId(), &u32_CurIL);
    if (u32_Err)
        return u32_Err;

    if (u32_CurIL > SECURITY_MANDATORY_MEDIUM_RID)
        b_UseToken = TRUE;
}

// Create the process normally (before Windows Vista or if current process runs with a medium IL)
if (!b_UseToken)
{
    if (!CreateProcessW(u16_Path, u16_CmdLine, 0, 0, FALSE, 0, 0, 0, &k_StartupInfo, &k_ProcInfo))
        return GetLastError();

    CloseHandle(k_ProcInfo.hThread);
    CloseHandle(k_ProcInfo.hProcess); 
    return ERROR_SUCCESS;
}

defCreateProcessWithTokenW f_CreateProcessWithTokenW = 
    (defCreateProcessWithTokenW) GetProcAddress(GetModuleHandleA("Advapi32"), "CreateProcessWithTokenW");

if (!f_CreateProcessWithTokenW) // This will never happen on Vista!
    return ERROR_INVALID_FUNCTION; 

HWND h_Progman = ::GetShellWindow();

DWORD u32_ExplorerPID = 0;      
GetWindowThreadProcessId(h_Progman, &u32_ExplorerPID);

// ATTENTION:
// If UAC is turned OFF all processes run with SECURITY_MANDATORY_HIGH_RID, also Explorer!
// But this does not matter because to start the new process without UAC no elevation is required.
h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_ExplorerPID);
if (!h_Process)
    goto _CleanUp;

if (!OpenProcessToken(h_Process, TOKEN_DUPLICATE, &h_Token))
    goto _CleanUp;

if (!DuplicateTokenEx(h_Token, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &h_Token2))
    goto _CleanUp;

if (!f_CreateProcessWithTokenW(h_Token2, 0, u16_Path, u16_CmdLine, 0, 0, 0, &k_StartupInfo, &k_ProcInfo))
    goto _CleanUp;

SetLastError(ERROR_SUCCESS);

_CleanUp:
DWORD u32_Error = GetLastError();
if (h_Token)   CloseHandle(h_Token);
if (h_Token2)  CloseHandle(h_Token2);
if (h_Process) CloseHandle(h_Process);
CloseHandle(k_ProcInfo.hThread);
CloseHandle(k_ProcInfo.hProcess); 
return u32_Error;
}


int _tmain(int argc, _TCHAR* argv[])
{
DWORD u32_Err = CreateProcessMediumIL(L"C:\\src\\bin\\release\\GetMappedDrives.exe", NULL);

printf("CreateProcessMediumIL() exited with error %d\r\n", u32_Err);
Sleep(2000);
return 0;
}

没什么-我不知道从哪里开始。我知道如何获取映射驱动器的列表,但不适用于未提升的用户。我想我可以从提升的应用程序生成一个未提升的进程,以获取驱动器列表并将结果存储在某处。然后,提升的应用程序可以读取列表。不过有点黑。如果有人有更好的建议,我会的。嗨,海格。这部分注册表中的条目似乎不是我可用的完整映射驱动器集。例如,我可以看到我的O和Y驱动器,但看不到我的P驱动器。P驱动器是我的主驱动器,已由我的域配置文件映射。我猜P驱动器不是持久性的,因为它可能是在我每次登录时创建的。
#include "stdafx.h"
#include "windows.h"

//#ifndef SECURITY_MANDATORY_HIGH_RID
//  #define SECURITY_MANDATORY_UNTRUSTED_RID            (0x00000000L)
//  #define SECURITY_MANDATORY_LOW_RID                  (0x00001000L)
//  #define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
//  #define SECURITY_MANDATORY_HIGH_RID                 (0x00003000L)
//  #define SECURITY_MANDATORY_SYSTEM_RID               (0x00004000L)
//  #define SECURITY_MANDATORY_PROTECTED_PROCESS_RID    (0x00005000L)
//#endif

//#ifndef TokenIntegrityLevel
//  #define TokenIntegrityLevel ((TOKEN_INFORMATION_CLASS)25)
//#endif

//#ifndef TOKEN_MANDATORY_LABEL
//  typedef struct  
//  {
//      SID_AND_ATTRIBUTES Label;
//  } TOKEN_MANDATORY_LABEL;
//#endif

typedef BOOL (WINAPI *defCreateProcessWithTokenW)
(HANDLE,DWORD,LPCWSTR,LPWSTR,DWORD,LPVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION);


// Writes Integration Level of the process with the given ID into pu32_ProcessIL
// returns Win32 API error or 0 if succeeded
DWORD GetProcessIL(DWORD u32_PID, DWORD* pu32_ProcessIL)
{
*pu32_ProcessIL = 0;

HANDLE h_Process   = 0;
HANDLE h_Token     = 0;
DWORD  u32_Size    = 0;
BYTE*  pu8_Count   = 0;
DWORD* pu32_ProcIL = 0;
TOKEN_MANDATORY_LABEL* pk_Label = 0;

h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_PID);
if (!h_Process)
    goto _CleanUp;

if (!OpenProcessToken(h_Process, TOKEN_QUERY, &h_Token))
    goto _CleanUp;

if (!GetTokenInformation(h_Token, TokenIntegrityLevel, NULL, 0, &u32_Size) &&
     GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    goto _CleanUp;

pk_Label = (TOKEN_MANDATORY_LABEL*) HeapAlloc(GetProcessHeap(), 0, u32_Size);
if (!pk_Label)
    goto _CleanUp;

if (!GetTokenInformation(h_Token, TokenIntegrityLevel, pk_Label, u32_Size, &u32_Size))
    goto _CleanUp;

pu8_Count = GetSidSubAuthorityCount(pk_Label->Label.Sid);
if (!pu8_Count)
    goto _CleanUp;

pu32_ProcIL = GetSidSubAuthority(pk_Label->Label.Sid, *pu8_Count-1);
if (!pu32_ProcIL)
    goto _CleanUp;

*pu32_ProcessIL = *pu32_ProcIL;
SetLastError(ERROR_SUCCESS);

_CleanUp:
DWORD u32_Error = GetLastError();
if (pk_Label)  HeapFree(GetProcessHeap(), 0, pk_Label);
if (h_Token)   CloseHandle(h_Token);
if (h_Process) CloseHandle(h_Process);
return u32_Error;
}

// Creates a new process u16_Path with the integration level of the Explorer process (MEDIUM IL)
// If you need this function in a service you must replace FindWindow() with another API to find Explorer process
// The parent process of the new process will be svchost.exe if this EXE was run "As Administrator"
// returns Win32 API error or 0 if succeeded
DWORD CreateProcessMediumIL(WCHAR* u16_Path, WCHAR* u16_CmdLine)
{
HANDLE h_Process = 0;
HANDLE h_Token   = 0;
HANDLE h_Token2  = 0;
PROCESS_INFORMATION k_ProcInfo    = {0};
STARTUPINFOW        k_StartupInfo = {0};

BOOL b_UseToken = FALSE;

// Detect Windows Vista, 2008, Windows 7 and higher
if (GetProcAddress(GetModuleHandleA("Kernel32"), "GetProductInfo"))
{
    DWORD u32_CurIL;
    DWORD u32_Err = GetProcessIL(GetCurrentProcessId(), &u32_CurIL);
    if (u32_Err)
        return u32_Err;

    if (u32_CurIL > SECURITY_MANDATORY_MEDIUM_RID)
        b_UseToken = TRUE;
}

// Create the process normally (before Windows Vista or if current process runs with a medium IL)
if (!b_UseToken)
{
    if (!CreateProcessW(u16_Path, u16_CmdLine, 0, 0, FALSE, 0, 0, 0, &k_StartupInfo, &k_ProcInfo))
        return GetLastError();

    CloseHandle(k_ProcInfo.hThread);
    CloseHandle(k_ProcInfo.hProcess); 
    return ERROR_SUCCESS;
}

defCreateProcessWithTokenW f_CreateProcessWithTokenW = 
    (defCreateProcessWithTokenW) GetProcAddress(GetModuleHandleA("Advapi32"), "CreateProcessWithTokenW");

if (!f_CreateProcessWithTokenW) // This will never happen on Vista!
    return ERROR_INVALID_FUNCTION; 

HWND h_Progman = ::GetShellWindow();

DWORD u32_ExplorerPID = 0;      
GetWindowThreadProcessId(h_Progman, &u32_ExplorerPID);

// ATTENTION:
// If UAC is turned OFF all processes run with SECURITY_MANDATORY_HIGH_RID, also Explorer!
// But this does not matter because to start the new process without UAC no elevation is required.
h_Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, u32_ExplorerPID);
if (!h_Process)
    goto _CleanUp;

if (!OpenProcessToken(h_Process, TOKEN_DUPLICATE, &h_Token))
    goto _CleanUp;

if (!DuplicateTokenEx(h_Token, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &h_Token2))
    goto _CleanUp;

if (!f_CreateProcessWithTokenW(h_Token2, 0, u16_Path, u16_CmdLine, 0, 0, 0, &k_StartupInfo, &k_ProcInfo))
    goto _CleanUp;

SetLastError(ERROR_SUCCESS);

_CleanUp:
DWORD u32_Error = GetLastError();
if (h_Token)   CloseHandle(h_Token);
if (h_Token2)  CloseHandle(h_Token2);
if (h_Process) CloseHandle(h_Process);
CloseHandle(k_ProcInfo.hThread);
CloseHandle(k_ProcInfo.hProcess); 
return u32_Error;
}


int _tmain(int argc, _TCHAR* argv[])
{
DWORD u32_Err = CreateProcessMediumIL(L"C:\\src\\bin\\release\\GetMappedDrives.exe", NULL);

printf("CreateProcessMediumIL() exited with error %d\r\n", u32_Err);
Sleep(2000);
return 0;
}