2017-02-15 2 views
0

서비스로 실행되며 외부와의 통신을위한 시스템 프록시 설정을 선택하는 응용 프로그램을 작성했습니다. WinHttpGetIEProxyConfigForCurrentUser을 시도했지만 프록시를 검색하지 못했습니다. 로컬 시스템의 도메인에서 서비스가 실행되고 있기 때문에 현재 사용자에 대한 설정입니다. 동일한 것을 실현하려면 사용자에게 응용 프로그램 사용자가 원하지 않는 서비스에 로그온하도록해야합니다. 나는 약 SERVICE_USER_OWN_PROCESS CreateService()에 전달할 수있는 매개 변수를 읽었지만 WinNT.h에서 그 선언을 찾지도 않았고 작동하는지 확실하지도 않았습니다. 이 문제로 인해 응용 프로그램 개발이 중단되었습니다. 누구든지 도와주세요.Windows 7 C에서 시스템 서비스 프록시 설정을 검색하는 방법

답변

1

현재 사용자의 컨텍스트에서 프로그램을 실행하는 것과 비슷한 상황이있었습니다. 어딘가 전역 범위에서 - - 모든

먼저 다음과 같은 변수를 정의

HANDLE hUsrToken; 
HANDLE hDupToken; 
int sessionId; 

을 당신은 현재 사용자의 세션 ID를 얻을 필요가 :

int getInteractiveSessinoId() 
{ 
    PWTS_SESSION_INFO pSessInfo; 
    ulong count;     // Number of current user sessions 
    int result = -1; 

    if (!WTSEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, &pSessInfo, &count)) 
    { 
     printf("Getting session information failed with error %d\n", << GetLastError()); 
     WTSFreeMemory(pSessInfo); 
     return -2; 
    } 

    for (ulong loop = 0; loop < count; loop++) 
    { 
     if (pSessInfo[loop].State == WTSActive) 
     { 
      printf("Session %d is currently active\n", pSessInfo[loop].SessionId); 
      result = pSessInfo[loop].SessionId; 
      break; 
     } 
    } 

    WTSFreeMemory(pSessInfo); 
    return result; 
} 

다음을 당신이를 가장 필요 현재 사용자 ("세션에 연결"이라고 함) :

bool attachToSession(int sessionId) 
{ 
    // We need to duplicate the token of the session's user 
    if (!WTSQueryUserToken(sessionId, &hUsrToken)) 
    { 
     pritnf("Query the user token failed with error %d\n", GetLastError()); 
     return false; 
    } 

    if (!DuplicateTokenEx(hUsrToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation , &hDupToken)) 
    { 
     printf("Duplicating a token failed with error %d\n", GetLastError()); 
     return false; 
    } 

    if (!ImpersonateLoggedOnUser(hDupToken)) 
    { 
     printf("Impersonating the user failed with error %d\n", GetLastError(); 
     return false; 
    } 

    return true; 
} 

이제 뭐든지 할 수 있습니다. NT 현재 사용자의 컨텍스트 내에서 수행 할 작업을, 완료되면, 사용자의 컨텍스트에서 ("분리"또는) 복귀 :

bool detachFromSession() 
{ 
    if (!RevertToSelf()) 
    { 
     printf("Reverting the token failed with error %d\n", GetLastError()); 
     return false; 
    } 

    (void)CloseHandle(hDupToken); 
    (void)CloseHandle(hUsrToken); 

    return true; 
} 

잘 모르겠어요가에 토큰을 적용하는 좋은 아이디어 인 경우 현재 (서비스) 스레드. 사용자 컨텍스트에서 수행하려는 작업을 실행하고 가장 된 토큰을 적용하는 새 스레드를 만드는 것이 더 좋은 아이디어라고 생각합니다. 나는이 문제를 해결할 수 있다고 garantee 수 없습니다

HANDLE hUsrToken; 
HANDLE hDupToken; 
HANDLE hThread; 
int sessionId; 
DWORD threadId; 

DWORD WINAPI MyThreadFunction(LPVOID lpParam) 
{ 
    // WinHttpGetIEProxyConfigForCurrentUser(... 
} 

sessionId = getInterActiveSessionId(); 

if (attachToSession(int sessionId) == false) 
{ 
    // Error handling 
    return; 
} 

hThread = CreateThread(NULL,     // default security attributes 
         0,      // use default stack size      
         MyThreadFunction,  // thread function name 
         NULL,     // argument to thread function 
         CREATE_SUSPENDED,  // Delay execution 
         &threadId); 

if (SetThreadToken(hThread, hDupToken) == false) 
{ 
    // Error handling 
    return; 
} 

ResumeThread(hThread); 

,하지만 난 그것을하지 희망 : 그래서 코드의 일부는 다음과 같이 보일 수 있습니다. 행운을 빕니다!

+0

사용자가 시스템에 로그온하지 않은 상태에서 가장 API를 호출하면 서비스 동작이 어떻게됩니까? – cbinder

+0

위의 코드에서 getInteractiveSessinoId()는 올바로 처리해야하는 잘못된 ID (-2 반환)와 함께 반환됩니다. 그렇지 않으면 WTSQueryUserToken()에서 attachToSession()이 실패하고 함수에서 처리되는 오류가 반환됩니다. 요약하면 대화 형 세션이 있는지 확인해야합니다. 세션 0 (서비스가 실행중인 경우)에 연결하는 것은 해당 세션에서 이미 실행 중이므로 의미가 없습니다. –

관련 문제