2014-01-07 5 views
0

У меня есть служба, и мне нужно запустить приложение gui с текущими пользовательскими привилегиями от этой службы. Это мой код, и он всегда возвращает GetLastError с помощью функции 3015 CreateProcessAsUser fucntion. Как я могу это исправить или, может быть, мой код не прав, и вы можете посоветовать мне что-то полезное. Спасибо.CreateProcessAsUser - Ошибка 1305

void ConnectionManager::LaunchDialer() 
{ 
    HANDLE currentToken; 
    HANDLE primaryToken; 

    int dwSessionId = 0; 
    PHANDLE hUserToken = 0; 
    PHANDLE hTokenDup = 0; 

    PWTS_SESSION_INFO pSessionInfo = 0; 
    DWORD dwCount = 0; 

    // Get the list of all terminal sessions 
    WTSEnumerateSessions (WTS_CURRENT_SERVER_HANDLE, 0, 1, 
      &pSessionInfo, &dwCount); 

    int dataSize = sizeof (WTS_SESSION_INFO); 

    // look over obtained list in search of the active session 
    for (DWORD i = 0; i < dwCount; ++i) 
    { 
     WTS_SESSION_INFO si = pSessionInfo [i]; 
     if (WTSActive == si.State) 
     { 
      // If the current session is active – store its ID 
      dwSessionId = si.SessionId; 
      break; 
     } 
    } 

    WTSFreeMemory (pSessionInfo); 

    // Get token of the logged in user by the active session ID 
    BOOL bRet = WTSQueryUserToken (dwSessionId, &currentToken); 
    if (!bRet) 
    { 
     ModemDetectorService::instance()->logMessage (QString ("WTSQueryUserToken: %1") 
       .arg (GetLastError())); 
     return; 
    } 

    bRet = DuplicateTokenEx (currentToken, 
      TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 
      0, 
      SecurityImpersonation, 
      TokenPrimary, 
      &primaryToken); 
    if (!bRet) 
    { 
     ModemDetectorService::instance()->logMessage (QString ("DuplicateTokenEx: %1") 
        .arg (GetLastError())); 
     return; 
    } 

    if (!primaryToken) 
    { 
     ModemDetectorService::instance()->logMessage ("Invalid user token"); 
     return; 
    } 

    STARTUPINFO StartupInfo; 
    PROCESS_INFORMATION processInfo; 
    ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); 
    StartupInfo.cb= sizeof(STARTUPINFO); 
    StartupInfo.lpDesktop = TEXT("winsta0\\default"); 

    SECURITY_ATTRIBUTES Security1; 
    SECURITY_ATTRIBUTES Security2; 

    QSettings settings ("HKEY_LOCAL_MACHINE\\Software\\Olive\\OliveDialer", 
       QSettings::NativeFormat); 
    const QString path = QDir::toNativeSeparators (settings.value ("InstallationDirectory").toString()); 
    QByteArray command = ("\"" + path + "\\" + 
      ApplicationInfo::Olive::ShortApplicationName + ".exe" + "\"").toUtf8(); 

    void* lpEnvironment = NULL; 
    // Get all necessary environment variables of logged in user 
    // to pass them to the process 
    BOOL resultEnv = CreateEnvironmentBlock (&lpEnvironment, 
      primaryToken, 
      FALSE); 
    if (!resultEnv) 
    { 
     long nError = GetLastError(); 
     ModemDetectorService::instance()->logMessage (QString ("CreateEnvironmentBlock failed with: %1") 
       .arg (nError)); 
    } 

    // Start the process on behalf of the current user 
    BOOL result = CreateProcessAsUser (primaryToken, 0, 
      (LPSTR)(command.data()), 
      &Security1, 
      &Security2, 
      FALSE, 
      NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, 
      lpEnvironment, 
      NULL, 
      &StartupInfo, 
      &processInfo); 
    if (!result) 
    { 
     DWORD errorCode = GetLastError(); 
     ModemDetectorService::instance()->logMessage (QString ("Application start failed: %1 %2") 
       .arg (errorCode) 
       .arg (command.data())); 
    } 
    else 
     ModemDetectorService::instance()->logMessage ("Application started successfully"); 
    DestroyEnvironmentBlock (lpEnvironment); 
    CloseHandle (primaryToken); 
} 
+1

Вы должны сразу же вызвать GetLastError сразу после обнаружения сбоя. Другие функции (например, DestroyEnvironmentBlock) могут и будут изменять его на другое значение статуса. –

+0

Отлаживать код и находить точно, какая функция возвращает ошибку 1305 –

+0

Я перемещаю GetLastError до функции CreateProcessAsUser, и он все равно возвращает 1305. – Magog

ответ

2

Ошибка 1305 является ERROR_UNKNOWN_REVISION ("Уровень ревизии неизвестен"), который обычно относится к объектов безопасности. Действительно, вы проходите две структуры SECURITY_ATTRIBUTES (Security1 и Security2), которые никогда не были инициализированы.

Вам необходимо либо пройти NULL вместо &Security1 и &Security2, либо правильно инициализировать структуры.

+0

все хорошо. Спасибо. – Magog

0

Попробуйте установить lpCurrentDirectory что-то вроде C: \ Windows

Или загрузки профиля пользователя с LoadUserProfile

Смежные вопросы