2012-04-07 4 views
2

RDP에는 원격 사용자의 워크 스테이션에서 RDP 서버로 내보내기 디스크를 보낼 수있는 환상적인 기능이 있습니다. 내가 말할 수있는 한, 그것은 단지 윈도우 탐색기 트릭이 아니지만 모든 종류의 프로그램은 바로 가기 "X :", "Y :", "Z :"등을 사용할 수 있습니다. 이 stack overflow entry은 RDP 디스크 복사 RDP 사용자의 컴퓨터를 가리키는 '\ tsclient'별칭을 언급합니다. 이제는 2 명 이상의 사용자가있는 경우 각자 고유의 충돌하지 않는 목적지를가집니다.서비스에서 RDP를 통해 매핑 된 디스크에 액세스하는 방법은 무엇입니까?

그래서 내 질문은 다음과 같습니다. 서비스에서 모든 원격 사용자 공유 리소스 (디스크)의 목록을 가져와 액세스하려면 어떻게해야합니까? 2 사용자가 연결하고 자신의 C 공유 한 말한다면 이상적 : 드라이브를, 나는 같은 목록을 얻을 것 :

  • UserJohnDoe \ VolumeXyzC \ - 존의 C 드라이브 UserJaneRoe \ VolumeXyzC \
  • - 제인의 C 드라이브

감사합니다. UPDATE :

여기에 코드 (gist snippet)의 작업 조각

// rdpjoker by Konrads 

#include "stdafx.h" 
#define SERVER "XXX.compute-1.amazonaws.com" 
#define CMD "cmd.exe /C dir \\tsclient\\c >output.txt" 

int main(int argc, char **argv){ 
    HANDLE server; 
    PWTS_SESSION_INFOA ppSessionInfo=NULL; 
    WTS_SESSION_INFOA pSessionInfo; 
    DWORD pCount; 
    DWORD pLevel=1; 
    DWORD i=0; 
    LPSTR ppBuffer; 
    DWORD bytesReturned;  
    HANDLE userToken=NULL; 
    HANDLE pUserToken=NULL; 
    ULONG sessionid; 
    DWORD dwCreationFlags=0; 
    LPVOID environment=NULL; 
    STARTUPINFOA si; 
    PROCESS_INFORMATION pi; 
    char *cmdline; 
    char *username; 
    char *homedir;//[MAX_PATH]; 
    char desktop[8192]; 

    server=WTSOpenServerA(WTS_CURRENT_SERVER_NAME); 
    if(argc>2){ 
     sessionid=atol(argv[1]); 
     printf("[*] Impersonating session: %i\n",sessionid); 
     if(WTSQueryUserToken(sessionid,&userToken)){ 
      //if(DuplicateTokenEx(userToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&pUserToken)){ 
       if(CreateEnvironmentBlock(&environment,pUserToken,FALSE)){ 
        ZeroMemory(&si, sizeof(STARTUPINFO)); 
        //WTSQuerySessionInformationA(server,sessionid,WTSWinStationName,&ppBuffer,&bytesReturned); 
        //sprintf_s(desktop,8192,"%s\\default",ppBuffer); 
        si.lpDesktop = "winsta0\\default";; 
        si.cb=sizeof(STARTUPINFO); 
        //WTSFreeMemory(ppBuffer); 
        ZeroMemory(&pi,sizeof(pi)); 
        cmdline=(char *)malloc(MAX_PATH +1); 
        //GetUserProfileDirectoryA(userToken,homedir,&bytesReturned); 
        //WTSUserConfigTerminalServerProfilePath 
        //WTSQuerySessionInformationA(server,sessionid,WTSUserName,&ppBuffer,&bytesReturned); 
        WTSQuerySessionInformationA(server,sessionid,WTSUserName,&ppBuffer,&bytesReturned); 

        username=_strdup(ppBuffer); 
        WTSFreeMemory(ppBuffer); 
        //WTSQueryUserConfigA(WTS_CURRENT_SERVER_NAME,username,WTSUserConfigTerminalServerProfilePath,&ppBuffer,&bytesReturned); 
        homedir=(char *)malloc(MAX_PATH); 
        sprintf_s(homedir,MAX_PATH,"C:\\Users\\%s\\",username); 
        //homedir=_strdup(ppBuffer); 
        //WTSFreeMemory(ppBuffer); 
        printf("[D] homedir: %s\n",homedir); 
        sprintf_s(cmdline,MAX_PATH,"cmd.exe /C dir %s >output.txt",argv[2]); 
        dwCreationFlags|= CREATE_UNICODE_ENVIRONMENT | NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; 

        //WTSQuerySessionInformationA(server,sessionid,WTSWinStationName,&ppBuffer,&bytesReturned); 
        //printf("station: %s",ppBuffer); 


        if(CreateProcessAsUserA(userToken, 
         NULL, 
         cmdline, 
         NULL, 
         NULL, 
         FALSE, 
         dwCreationFlags, 
         environment, 
         homedir, 
         &si, 
         &pi)){ 
          printf("[*]CreateProcessAsUserA succeeded! pid:%i, tid:%i\n",pi.dwProcessId,pi.dwProcessId); 
        }else{ 
         printf("[E] CreateProcessAsUserA failed: %i\n", GetLastError()); 
        } 


       //}else{ 
        //printf("[E] CreateEnvironmentBlock failed: %i\n", GetLastError()); 
     //  } 
     }else{ 
        printf("[E] DuplicateTokenEx failed: %i\n", GetLastError()); 
       } 


     } 
     else{ 
      printf("[E] WTSQueryUserToken failed: %i\n", GetLastError()); 
      exit(-1); 
     } 
    } 

    else{ // no arguments specified 
     if(WTSEnumerateSessionsA(server,0,1,&ppSessionInfo,&pCount)){ 

      // printf("pCount: %i,",pCount); 
      for (i=0;i<pCount;++i){ 
       // printf("i = %i\n",i); 
       pSessionInfo=ppSessionInfo[i]; 
       printf("Session ID: %i; name: %s, ",pSessionInfo.SessionId,pSessionInfo.pWinStationName); 
       if(WTSQuerySessionInformationA(server,pSessionInfo.SessionId,WTSUserName,&ppBuffer,&bytesReturned)){ 
        printf("user: %s, ",ppBuffer); 
        WTSFreeMemory(ppBuffer); 
       }else{ 
        printf("WTSQuerySessionInformation[WTSUserName] failed: %i\n", GetLastError()); 
       } 
       if(WTSQuerySessionInformationA(server,pSessionInfo.SessionId,WTSWinStationName,&ppBuffer,&bytesReturned)){ 
        printf("station: %s",ppBuffer); 
        WTSFreeMemory(ppBuffer); 
       }else{ 
        printf("WTSQuerySessionInformation[WTSWinStationName] failed: %i\n", GetLastError()); 
       } 
       printf("\n"); 
      } 
      WTSFreeMemory(ppSessionInfo); 
     }else //0014fb3c 
     { 
      printf("EnumerateSessions failed: %i\n", GetLastError()); 
     } 
    } 
} 

답변

2

난 당신이 사용 CreateProcessAsUser 달성 할 수 있다고 생각하지만, 당신은 당신이 WTSQueryUserToken를 통해 할 사용자의 세션에 대한 토큰을 검색해야합니다.

+0

나는 그것을 줄 것이다. 하지만 확실히 윈도우 어딘가에 절대적으로 상대방을 통하지 않는 UNC 경로가 있어야합니다. \\ tsclient – Konrads

+0

@Konrads 터미널 서비스가이 경우 네트워크 서비스 제공자라는 문제가 있다고 생각하지만, 'tsclient' 머신 이름. – Neil

+0

하지만 어떻게 알지? :) 사용자 이름에 따라 UNC 해상도를 변경하는 시스템에 몇 가지 문제가 있습니까? – Konrads