YAHOOOOO
YAHOOOOO

Reputation: 957

Get Process Username c++

i am making a taskmanager like app. for windows,i can get all the system processes,now i want to get process's username.I got the code from net.

void enableDebugPrivileges()
{
    HANDLE hcurrent=GetCurrentProcess();
    HANDLE hToken;
    BOOL bret=OpenProcessToken(hcurrent,40,&hToken);
    LUID luid;
    bret=LookupPrivilegeValue(NULL,SE_LOAD_DRIVER_NAME, &luid);
    TOKEN_PRIVILEGES NewState,PreviousState;
    DWORD ReturnLength;
    NewState.PrivilegeCount =1;
    NewState.Privileges[0].Luid =luid;
    NewState.Privileges[0].Attributes=2;
    AdjustTokenPrivileges(hToken,FALSE,&NewState,28,&PreviousState,&ReturnLength);
}

char *GetProcessUsername(HANDLE *phProcess, BOOL bIncDomain) 
{
    static char sname[300];
    HANDLE tok = 0;
    HANDLE hProcess;
    TOKEN_USER *ptu;
    DWORD nlen, dlen;
    char name[300], dom[300], tubuf[300], *pret = 0;
    int iUse;

    //if phProcess is NULL we get process handle of this
    //process.
    hProcess = phProcess?*phProcess:GetCurrentProcess();

    //open the processes token
    if (!OpenProcessToken(hProcess,TOKEN_QUERY,&tok)) goto ert;

    //get the SID of the token
    ptu = (TOKEN_USER*)tubuf;
    if (!GetTokenInformation(tok,(TOKEN_INFORMATION_CLASS)1,ptu,300,&nlen)) goto ert;

    //get the account/domain name of the SID
    dlen = 300;
    nlen = 300;
    if (!LookupAccountSidA(0, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto ert;


    //copy info to our static buffer
    if (dlen && bIncDomain) {
    strcpy(sname,dom);
    strcat(sname,"");
    strcat(sname,name);
    } else {
    strcpy(sname,name);
    }
    //set our return variable
    pret = sname;

    ert:
    if (tok) CloseHandle(tok);
    return pret;
}
int main(){
    enableDebugPrivileges();
    DWORD dwPID=3436;        
    HANDLE  hProcess_i = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPID);
    printf("%s",GetProcessUsername(&hProcess_i,0));
}

Its working well for system and curr. user processes but not for NETWORK SERVICE and LOCAL SERVICES and i got null string.please tell how can i get usernames of these processes too. thanks.

Upvotes: 1

Views: 5397

Answers (2)

Santhosh Kumar
Santhosh Kumar

Reputation: 411

I also used the code I got from the Net and used your GetUserName() part(Thanks for sharing) and it works perfectly. I used VS2019. I am printing Process, PID and User Name all in one line.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>

void enableDebugPrivileges()
{
    HANDLE hcurrent = GetCurrentProcess();
    HANDLE hToken;
    BOOL bret = OpenProcessToken(hcurrent, 40, &hToken);
    LUID luid;
    bret = LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &luid);
    TOKEN_PRIVILEGES NewState, PreviousState;
    DWORD ReturnLength;
    NewState.PrivilegeCount = 1;
    NewState.Privileges[0].Luid = luid;
    NewState.Privileges[0].Attributes = 2;
    AdjustTokenPrivileges(hToken, FALSE, &NewState, 28, &PreviousState, &ReturnLength);
}

char* GetProcessUsername(HANDLE* phProcess, BOOL bIncDomain)
{
    static char sname[300];
    HANDLE tok = 0;
    HANDLE hProcess;
    TOKEN_USER* ptu;
    DWORD nlen, dlen;
    char name[300], dom[300], tubuf[300], * pret = 0;
    int iUse;

    //if phProcess is NULL we get process handle of this
    //process.
    hProcess = phProcess ? *phProcess : GetCurrentProcess();

    //open the processes token
    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &tok)) goto ert;

    //get the SID of the token
    ptu = (TOKEN_USER*)tubuf;
    if (!GetTokenInformation(tok, (TOKEN_INFORMATION_CLASS)1, ptu, 300, &nlen)) goto ert;

    //get the account/domain name of the SID
    dlen = 300;
    nlen = 300;
    if (!LookupAccountSidA(0, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto ert;


    //copy info to our static buffer
    if (dlen && bIncDomain) {
        strcpy_s(sname, dom);
        strcat_s(sname, "");
        strcat_s(sname, name);
    }
    else {
        strcpy_s(sname, name);
    }
    //set our return variable
    pret = sname;

ert:
    if (tok) CloseHandle(tok);
    return pret;
}

// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1

void PrintProcessNameAndID( DWORD processID )
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    HMODULE hMod;
    DWORD cbNeeded;

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName, 
                               sizeof(szProcessName)/sizeof(TCHAR) );
        }
    }

    if (!_tcscmp(szProcessName, _T("svchost.exe"))) {
         _tprintf(TEXT("%s  PID: %u "), szProcessName, processID);
         printf("User Name: %s\n", GetProcessUsername(&hProcess, 0));
    }

    // Release the handle to the process.

    if (NULL != hProcess) 
    {
        CloseHandle(hProcess);
    }
}

int main()
{
    enableDebugPrivileges();
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    UINT32 i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
    {
        return 1;
    }


    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
    {
        if( aProcesses[i] != 0 )
        {
            PrintProcessNameAndID( aProcesses[i] );
        }
    }

    return 0;
}

Upvotes: 0

Foo Bah
Foo Bah

Reputation: 26281

IIRC there's a separate pseudo account called LocalService, but its not in the normal security system (hence you get a null string). There's also a NetworkService account.

Upvotes: 2

Related Questions