C ++ Получить имя пользователя из процесса - PullRequest
8 голосов
/ 21 апреля 2010

У меня есть дескриптор процесса с

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, THE_PROCESS_ID);

Как я могу получить имя пользователя, который запускает процесс?

Я использую неуправляемый код (без .NET).

Ответы [ 4 ]

20 голосов
/ 21 апреля 2010

Используйте OpenProcessToken для получения токена (очевидно), затем GetTokenInformation с флагом TokenOwner для получения SID владельца. Затем вы можете использовать LookupAccountSid , чтобы получить имя пользователя.

5 голосов
/ 24 января 2012

, если WMI не вариант, тогда используйте GetUserFromProcess ниже, который принимает идентификатор процесса в качестве входного параметра и возвращает имя пользователя и домен:

#include <comdef.h>
#define MAX_NAME 256
BOOL GetLogonFromToken (HANDLE hToken, _bstr_t& strUser, _bstr_t& strdomain) 
{
   DWORD dwSize = MAX_NAME;
   BOOL bSuccess = FALSE;
   DWORD dwLength = 0;
   strUser = "";
   strdomain = "";
   PTOKEN_USER ptu = NULL;
 //Verify the parameter passed in is not NULL.
    if (NULL == hToken)
        goto Cleanup;

       if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenUser,    // get information about the token's groups 
         (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
         0,              // size of buffer
         &dwLength       // receives required buffer size
      )) 
   {
      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
         goto Cleanup;

      ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, dwLength);

      if (ptu == NULL)
         goto Cleanup;
   }

    if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenUser,    // get information about the token's groups 
         (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
         dwLength,       // size of buffer
         &dwLength       // receives required buffer size
         )) 
   {
      goto Cleanup;
   }
    SID_NAME_USE SidType;
    char lpName[MAX_NAME];
    char lpDomain[MAX_NAME];

    if( !LookupAccountSid( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) )                                    
    {
        DWORD dwResult = GetLastError();
        if( dwResult == ERROR_NONE_MAPPED )
           strcpy (lpName, "NONE_MAPPED" );
        else 
        {
            printf("LookupAccountSid Error %u\n", GetLastError());
        }
    }
    else
    {
        printf( "Current user is  %s\\%s\n", 
                lpDomain, lpName );
        strUser = lpName;
        strdomain = lpDomain;
        bSuccess = TRUE;
    }

Cleanup: 

   if (ptu != NULL)
      HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
   return bSuccess;
}

HRESULT GetUserFromProcess(const DWORD procId,  _bstr_t& strUser, _bstr_t& strdomain)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,procId); 
    if(hProcess == NULL)
        return E_FAIL;
    HANDLE hToken = NULL;

    if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) )
    {
        CloseHandle( hProcess );
        return E_FAIL;
    }
    BOOL bres = GetLogonFromToken (hToken, strUser,  strdomain);

    CloseHandle( hToken );
    CloseHandle( hProcess );
    return bres?S_OK:E_FAIL;
}
1 голос
/ 21 апреля 2010

WMI - это, вероятно, путь наименьшего сопротивления. Вы также должны иметь возможность получить токен, используя OpenProcessToken, затем GetTokenInformation, чтобы получить SID владельца. Затем вы можете превратить SID в имя пользователя.

0 голосов
/ 21 апреля 2010

WMI сможет сообщить вам эту информацию. В противном случае вам нужно полагаться на недокументированное веселье в ntdll.dll. Похоже, что другие нашли решения, которые не используют ntdll.dll - используйте их вместо недокументированных вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...