VirtualBox

Changeset 39760 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Jan 12, 2012 2:30:32 PM (13 years ago)
Author:
vboxsync
Message:

VBoxService/VMInfo: Dump process names when enumerating active sessions on high verbosity.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp

    r39592 r39760  
    3030
    3131#include <iprt/assert.h>
     32#include <iprt/ldr.h>
    3233#include <iprt/mem.h>
    3334#include <iprt/thread.h>
     
    7273*   Prototypes
    7374*******************************************************************************/
    74 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs);
     75uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs);
    7576bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession);
    7677int  VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount);
    7778void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
    7879
     80typedef BOOL WINAPI FNQUERYFULLPROCESSIMAGENAME(HANDLE,  DWORD, LPTSTR, PDWORD);
     81typedef FNQUERYFULLPROCESSIMAGENAME *PFNQUERYFULLPROCESSIMAGENAME;
    7982
    8083
    8184#ifndef TARGET_NT4
     85
     86/**
     87 * Retrieves the module name of a given process.
     88 *
     89 * @return  IPRT status code.
     90 * @param   pProc
     91 * @param   pszBuf
     92 * @param   cbBuf
     93 */
     94static int VBoxServiceVMInfoWinProcessesGetModuleName(PVBOXSERVICEVMINFOPROC const pProc,
     95                                                      TCHAR *pszName, size_t cbName)
     96{
     97    AssertPtrReturn(pProc, VERR_INVALID_POINTER);
     98    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     99    AssertReturn(cbName, VERR_INVALID_PARAMETER);
     100
     101    OSVERSIONINFOEX OSInfoEx;
     102    RT_ZERO(OSInfoEx);
     103    OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     104    if (   !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
     105        || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT)
     106    {
     107        /* Platform other than NT (e.g. Win9x) not supported. */
     108        return VERR_NOT_SUPPORTED;
     109    }
     110
     111    int rc = VINF_SUCCESS;
     112
     113    DWORD dwFlags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
     114    if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
     115        dwFlags = 0x1000; /* = PROCESS_QUERY_LIMITED_INFORMATION; less privileges needed. */
     116
     117    HANDLE h = OpenProcess(dwFlags, FALSE, pProc->id);
     118    if (h == NULL)
     119    {
     120        DWORD dwErr = GetLastError();
     121        if (g_cVerbosity)
     122            VBoxServiceError("VMInfo/Users: Unable to open process with PID=%ld, error=%ld",
     123                             pProc->id, dwErr);
     124        rc = RTErrConvertFromWin32(dwErr);
     125    }
     126    else
     127    {
     128        /* Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps cannot query 64-bit
     129           apps and vice verse) we have to use a different code path for Vista and up. */
     130
     131        /* Note: For 2000 + NT4 we might just use GetModuleFileName() instead. */
     132        if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
     133        {
     134            /* Loading the module and getting the symbol for each and every process is expensive
     135             * -- since this function (at the moment) only is used for debugging purposes it's okay. */
     136            RTLDRMOD hMod;
     137            rc = RTLdrLoad("kernel32.dll", &hMod);
     138            if (RT_SUCCESS(rc))
     139            {
     140                PFNQUERYFULLPROCESSIMAGENAME pfnQueryFullProcessImageName;
     141                rc = RTLdrGetSymbol(hMod, "QueryFullProcessImageNameA", (void **)&pfnQueryFullProcessImageName);
     142                if (RT_SUCCESS(rc))
     143                {
     144                    DWORD dwLen = sizeof(pszName);
     145                    if (!pfnQueryFullProcessImageName(h, 0 /*PROCESS_NAME_NATIVE*/, pszName, &dwLen))
     146                        rc = VERR_ACCESS_DENIED;
     147                }
     148
     149                RTLdrClose(hMod);
     150            }
     151        }
     152        else
     153        {
     154            if (!GetModuleFileNameEx(h, NULL /* Get main executable */, pszName, cbName / sizeof(TCHAR)))
     155                rc = VERR_ACCESS_DENIED;
     156        }
     157
     158        if (VERR_ACCESS_DENIED == rc)
     159        {
     160            DWORD dwErr = GetLastError();
     161            if (g_cVerbosity)
     162                VBoxServiceError("VMInfo/Users: Unable to retrieve module name for PID=%ld, error=%ld",
     163                                 pProc->id, dwErr);
     164            rc = RTErrConvertFromWin32(dwErr);
     165        }
     166
     167        CloseHandle(h);
     168    }
     169
     170    return rc;
     171}
     172
    82173
    83174/**
     
    91182                                                     TOKEN_INFORMATION_CLASS tkClass)
    92183{
    93     AssertPtr(pProc);
     184    AssertPtrReturn(pProc, VERR_INVALID_POINTER);
    94185    HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pProc->id);
    95186    if (h == NULL)
    96         return RTErrConvertFromWin32(GetLastError());
     187    {
     188        DWORD dwErr = GetLastError();
     189        if (g_cVerbosity)
     190            VBoxServiceError("VMInfo/Users: Unable to open process with PID=%ld, error=%ld",
     191                             pProc->id, dwErr);
     192        return RTErrConvertFromWin32(dwErr);
     193    }
    97194
    98195     int    rc = VERR_NO_MEMORY;
     
    145242    }
    146243    else
    147         rc = RTErrConvertFromWin32(GetLastError());
     244    {
     245        DWORD dwErr = GetLastError();
     246        if (g_cVerbosity)
     247            VBoxServiceError("VMInfo/Users: Unable to query process token for PID=%ld, error=%ld\n",
     248                             pProc->id, dwErr);
     249        rc = RTErrConvertFromWin32(dwErr);
     250    }
    148251    CloseHandle(h);
    149252    return rc;
     
    171274     */
    172275    DWORD   cProcesses  = 64;
    173     PDWORD  paPids      = NULL;
     276    PDWORD  paPID       = NULL;
    174277    int     rc          = VINF_SUCCESS;
    175278    do
     
    177280        /* Allocate / grow the buffer first. */
    178281        cProcesses *= 2;
    179         void *pvNew = RTMemRealloc(paPids, cProcesses * sizeof(DWORD));
     282        void *pvNew = RTMemRealloc(paPID, cProcesses * sizeof(DWORD));
    180283        if (!pvNew)
    181284        {
     
    183286            break;
    184287        }
    185         paPids = (PDWORD)pvNew;
     288        paPID = (PDWORD)pvNew;
    186289
    187290        /* Query the processes. Not the cbRet == buffer size means there could be more work to be done. */
    188291        DWORD cbRet;
    189         if (!EnumProcesses(paPids, cProcesses * sizeof(DWORD), &cbRet))
     292        if (!EnumProcesses(paPID, cProcesses * sizeof(DWORD), &cbRet))
    190293        {
    191294            rc = RTErrConvertFromWin32(GetLastError());
     
    197300            break;
    198301        }
    199     } while (cProcesses <= 32768); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */
     302    } while (cProcesses <= _32K); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */
    200303    if (RT_SUCCESS(rc))
    201304    {
     
    210313            for (DWORD i = 0; i < cProcesses; i++)
    211314            {
    212                 paProcs[i].id = paPids[i];
     315                paProcs[i].id = paPID[i];
    213316                rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics);
    214317                if (RT_FAILURE(rc))
     
    233336    }
    234337
    235     RTMemFree(paPids);
     338    RTMemFree(paPID);
    236339    return rc;
    237340}
     
    256359 * @param   cProcs          The number of processes in the snaphot.
    257360 */
    258 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs)
     361uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs)
    259362{
    260363    if (!pSession)
     
    287390        {
    288391            cNumProcs++;
    289             if (g_cVerbosity < 4) /* We want a bit more info on high verbosity. */
     392            if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */
    290393                break;
    291         }
    292     }
    293 
    294     if (g_cVerbosity >= 4)
     394
     395            TCHAR szModule[_1K];
     396            int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));
     397            if (RT_SUCCESS(rc2))
     398                VBoxServiceVerbose(4, "VMInfo/Users: PID=%ld: %s\n",
     399                                   paProcs[i].id, szModule);
     400        }
     401    }
     402
     403    if (g_cVerbosity)
    295404        VBoxServiceVerbose(3, "VMInfo/Users: Session %u has %u processes\n",
    296405                           pSessionData->Session, cNumProcs);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette