Search code examples
c++winapic++11wmiwin32-process

Get all processes for Current User


I need to get all processes for current user. Currently I have a function implemented using WMI that gets all active processes by All Users. I need to somehow get all processes by Current User.

If you go to Task Manager in Windows, Details tab, you will see all processes by All Users. But say you are in Visual Studio and you go to Debug/Attach To Process, this shows all processes by Current User. That's the list that I need.

Here is my solution of All Processes by All Users:

    CComPtr<IEnumWbemClassObject> pEnumerator;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_Process"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

Either a WMI or Win32 solution will be good enough. Thank you!!


Solution

  • OK, there is now short way. But here is the working solution if anyone is interested:

    std::wstring GetProcessUserName(DWORD dwProcessId)
    {
        HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
        if (processHandle != NULL)
        {
            HANDLE tokenHandle;
            if (OpenProcessToken(processHandle, TOKEN_READ, &tokenHandle))
            {
                TOKEN_USER tokenUser;
                ZeroMemory(&tokenUser, sizeof(TOKEN_USER));
                DWORD tokenUserLength = 0;
    
                PTOKEN_USER pTokenUser;
                GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS::TokenUser, NULL,      
                0, &tokenUserLength);
                pTokenUser = (PTOKEN_USER) new BYTE[tokenUserLength];
    
                if (GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS::TokenUser, pTokenUser, tokenUserLength, &tokenUserLength))
                {
                    TCHAR szUserName[_MAX_PATH];
                    DWORD dwUserNameLength = _MAX_PATH;
                    TCHAR szDomainName[_MAX_PATH];
                    DWORD dwDomainNameLength = _MAX_PATH;
                    SID_NAME_USE sidNameUse;
                    LookupAccountSid(NULL, pTokenUser->User.Sid, szUserName, &dwUserNameLength, szDomainName, &dwDomainNameLength, &sidNameUse);
                    delete pTokenUser;
                    return std::wstring(szUserName);
                }
            }
        }
    
        return std::wstring();
    }
    
    std::unordered_map<std::wstring, std::vector<DWORD>> GetAllRunningProcessesForCurrentUser()
    {
        std::unordered_map<std::wstring, std::vector<DWORD>> processHash;
    
        HRESULT hres;
    
        // Initialize COM. ------------------------------------------
    
        hres = CoInitializeEx(0, COINIT_MULTITHREADED);
        if (FAILED(hres))
        {
            return processHash;
        }
    
        do {
            // Obtain the initial locator to WMI -------------------------
    
            CComPtr<IWbemLocator> pLoc;
            hres = pLoc.CoCreateInstance(CLSID_WbemLocator);
            if (FAILED(hres))
            {
                break;
            }
    
            // Connect to WMI through the IWbemLocator::ConnectServer method
            // Connect to the root\cimv2 namespace with
            // the current user and obtain pointer pSvc
            // to make IWbemServices calls.
            CComPtr<IWbemServices> pSvc;
            hres = pLoc->ConnectServer(
            _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
            NULL,                    // User name. NULL = current user
            NULL,                    // User password. NULL = current
            0,                       // Locale. NULL indicates current
            NULL,                    // Security flags.
            0,                       // Authority (for example, Kerberos)
            0,                       // Context object 
            &pSvc                    // pointer to IWbemServices proxy
            );
    
            if (FAILED(hres))
            {
                break;
            }
    
            // Set security levels on the proxy -------------------------
            hres = CoSetProxyBlanket(
            pSvc,                        // Indicates the proxy to set
            RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
            RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
            NULL,                        // Server principal name 
            RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
            RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
            NULL,                        // client identity
            EOAC_NONE                    // proxy capabilities 
            );
    
            if (FAILED(hres))
            {
                break;
            }
    
            // Use the IWbemServices pointer to make requests of WMI ----
    
            CComPtr<IEnumWbemClassObject> pEnumerator;
            hres = pSvc->ExecQuery(
            bstr_t("WQL"),
            bstr_t("SELECT * FROM Win32_Process"),
            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
            NULL,
            &pEnumerator);
    
            if (FAILED(hres))
            {
                break;
            }
    
            // Get the data from the query in step 6 -------------------
    
            CComPtr<IWbemClassObject> pclsObj;
            while (pEnumerator)
            {
                ULONG uReturn = 0;
                HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
    
                if (0 == uReturn)
                {
                    break;
                }
    
                VARIANT vtProp;
                VARIANT vtProp2;
    
                hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
                hr = pclsObj->Get(L"ProcessId", 0, &vtProp2, NULL, NULL);
    
                auto userName = GetProcessUserName(vtProp2.intVal);
    
                TCHAR szActiveUserName[_MAX_PATH];
                DWORD dwActiveUserNameLength = _MAX_PATH;
                GetUserName(szActiveUserName, &dwActiveUserNameLength);
    
                if (_tcscmp(userName.c_str(), szActiveUserName) == 0)
                {
                    processHash[vtProp.bstrVal].push_back(vtProp2.intVal);
                }
    
    
                VariantClear(&vtProp2);
                VariantClear(&vtProp);
    
                pclsObj.Release();
            }
        } while (false);
    
        CoUninitialize();
    
        return processHash;
    }