VirtualBox

Changeset 96502 in vbox


Ignore:
Timestamp:
Aug 25, 2022 10:36:36 PM (2 years ago)
Author:
vboxsync
Message:

Add/VBoxService: Replaced GetVersionEx calls with RTSystemGetNtVersion, so we don't need the IPRT fallback code for ancient NT versions that doesn't have that API. Checked out the KB970910 description against what we're doing with the API, and found that it shouldn't affect us, so RDP detection can run on all systems that have a WTSQuerySessionInformation API. Corrected QueryFullProcessImageNameW/GetModuleFileNameExW calls. bugref:10162

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
3 edited

Legend:

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

    r96407 r96502  
    12011201    OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    12021202
     1203
    12031204    SetLastError(NO_ERROR);
    12041205    HANDLE hMutexAppRunning;
    1205     if (    GetVersionEx((LPOSVERSIONINFO)&OSInfoEx)
    1206         &&  OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
    1207         &&  OSInfoEx.dwMajorVersion >= 5 /* NT 5.0 a.k.a W2K */)
    1208         hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\" VBOXSERVICE_NAME);
     1206    if (RTSystemGetNtVersion() >= RTSYSTEM_MAKE_NT_VERSION(5,0,0)) /* Windows 2000 */
     1207        hMutexAppRunning = CreateMutexW(NULL, FALSE, L"Global\\" VBOXSERVICE_NAME);
    12091208    else
    1210         hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME);
     1209        hMutexAppRunning = CreateMutexW(NULL, FALSE, RT_CONCAT(L,VBOXSERVICE_NAME));
    12111210    if (hMutexAppRunning == NULL)
    12121211    {
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp

    r96407 r96502  
    4444#include <iprt/string.h>
    4545#include <iprt/string.h>
     46#include <iprt/system.h>
    4647#include <iprt/thread.h>
    4748
     
    12971298         * so detect the OS and use a different path.
    12981299         */
    1299         OSVERSIONINFOEX OSInfoEx;
    1300         RT_ZERO(OSInfoEx);
    1301         OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    1302         BOOL fRet = GetVersionEx((LPOSVERSIONINFO) &OSInfoEx);
    1303         if (    fRet
    1304             &&  OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
    1305             &&  OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
     1300        if (RTSystemGetNtVersion() >= RTSYSTEM_MAKE_NT_VERSION(6,0,0) /* Vista and later */)
    13061301        {
    13071302            rc = RTEnvGetEx(RTENV_DEFAULT, "windir", szSysprepCmd, sizeof(szSysprepCmd), NULL);
     
    13261321                VGSvcError("Failed to detect sysrep location, rc=%Rrc\n", rc);
    13271322        }
    1328         else if (!fRet)
    1329             VGSvcError("Failed to retrieve OS information, last error=%ld\n", GetLastError());
    13301323
    13311324        VGSvcVerbose(3, "Sysprep executable is: %s\n", szSysprepCmd);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp

    r96451 r96502  
    144144/** @} */
    145145
    146 /** Windows version.  */
    147 static OSVERSIONINFOEXA                         g_WinVersion;
    148 
    149146
    150147/**
     
    157154    /* SECUR32 */
    158155    RTLDRMOD hLdrMod;
    159     int rc = RTLdrLoadSystem("secur32.dll", true, &hLdrMod);
     156    int rc = RTLdrLoadSystem("secur32.dll", true /*fNoUnload*/, &hLdrMod);
    160157    if (RT_SUCCESS(rc))
    161158    {
     
    174171        g_pfnLsaEnumerateLogonSessions = NULL;
    175172        g_pfnLsaFreeReturnBuffer = NULL;
    176         Assert(g_WinVersion.dwMajorVersion < 5);
     173        Assert(RTSystemGetNtVersion() < RTSYSTEM_MAKE_NT_VERSION(5, 0, 0));
    177174    }
    178175
    179176    /* WTSAPI32 */
    180     rc = RTLdrLoadSystem("wtsapi32.dll", true, &hLdrMod);
     177    rc = RTLdrLoadSystem("wtsapi32.dll", true /*fNoUnload*/, &hLdrMod);
    181178    if (RT_SUCCESS(rc))
    182179    {
     
    192189        g_pfnWTSFreeMemory = NULL;
    193190        g_pfnWTSQuerySessionInformationA = NULL;
    194         Assert(g_WinVersion.dwMajorVersion < 5);
     191        Assert(RTSystemGetNtVersion() < RTSYSTEM_MAKE_NT_VERSION(5, 0, 0));
    195192    }
    196193
    197194    /* PSAPI */
    198     rc = RTLdrLoadSystem("psapi.dll", true, &hLdrMod);
     195    rc = RTLdrLoadSystem("psapi.dll", true /*fNoUnload*/, &hLdrMod);
    199196    if (RT_SUCCESS(rc))
    200197    {
     
    210207        g_pfnEnumProcesses = NULL;
    211208        g_pfnGetModuleFileNameExW = NULL;
    212         Assert(g_WinVersion.dwMajorVersion < 5);
     209        Assert(RTSystemGetNtVersion() < RTSYSTEM_MAKE_NT_VERSION(5, 0, 0));
    213210    }
    214211
    215212    /* Kernel32: */
    216     rc = RTLdrLoadSystem("kernel32.dll", true, &hLdrMod);
     213    rc = RTLdrLoadSystem("kernel32.dll", true /*fNoUnload*/, &hLdrMod);
    217214    AssertRCReturn(rc, rc);
    218215    rc = RTLdrGetSymbol(hLdrMod, "QueryFullProcessImageNameW", (void **)&g_pfnQueryFullProcessImageNameW);
    219216    if (RT_FAILURE(rc))
    220217    {
    221         Assert(g_WinVersion.dwMajorVersion < 6);
     218        Assert(RTSystemGetNtVersion() < RTSYSTEM_MAKE_NT_VERSION(6, 0, 0));
    222219        g_pfnQueryFullProcessImageNameW = NULL;
    223220    }
    224221    RTLdrClose(hLdrMod);
    225 
    226     /*
    227      * Get the extended windows version once and for all.
    228      */
    229     g_WinVersion.dwOSVersionInfoSize = sizeof(g_WinVersion);
    230     if (!GetVersionExA((OSVERSIONINFO *)&g_WinVersion))
    231     {
    232         RT_ZERO(g_WinVersion);
    233         g_WinVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    234         if (!GetVersionExA((OSVERSIONINFO *)&g_WinVersion))
    235         {
    236             AssertFailed();
    237             RT_ZERO(g_WinVersion);
    238         }
    239     }
    240222
    241223    return VINF_SUCCESS;
     
    245227static bool vgsvcVMInfoSession0Separation(void)
    246228{
    247     return g_WinVersion.dwPlatformId == VER_PLATFORM_WIN32_NT
    248         && g_WinVersion.dwMajorVersion >= 6; /* Vista = 6.0 */
     229    return RTSystemGetNtVersion() >= RTSYSTEM_MAKE_NT_VERSION(6, 0, 0); /* Vista */
    249230}
    250231
     
    255236 * @return  IPRT status code.
    256237 */
    257 static int vgsvcVMInfoWinProcessesGetModuleNameA(PVBOXSERVICEVMINFOPROC const pProc, PRTUTF16 *ppszName)
    258 {
     238static int vgsvcVMInfoWinProcessesGetModuleNameW(PVBOXSERVICEVMINFOPROC const pProc, PRTUTF16 *ppszName)
     239{
     240    *ppszName = NULL;
     241    AssertPtrReturn(ppszName, VERR_INVALID_POINTER);
    259242    AssertPtrReturn(pProc, VERR_INVALID_POINTER);
    260     AssertPtrReturn(ppszName, VERR_INVALID_POINTER);
    261 
    262     /** @todo Only do this once. Later. */
    263     /* Platform other than NT (e.g. Win9x) not supported. */
    264     if (g_WinVersion.dwPlatformId != VER_PLATFORM_WIN32_NT)
    265         return VERR_NOT_SUPPORTED;
    266 
    267     int rc = VINF_SUCCESS;
    268 
     243    AssertReturn(g_pfnGetModuleFileNameExW || g_pfnQueryFullProcessImageNameW, VERR_NOT_SUPPORTED);
     244
     245    /*
     246     * Open the process.
     247     */
    269248    DWORD dwFlags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
    270     if (g_WinVersion.dwMajorVersion >= 6 /* Vista or later */)
     249    if (RTSystemGetNtVersion() >= RTSYSTEM_MAKE_NT_VERSION(6, 0, 0)) /* Vista and later */
    271250        dwFlags = PROCESS_QUERY_LIMITED_INFORMATION; /* possible to do on more processes */
    272251
    273     HANDLE h = OpenProcess(dwFlags, FALSE, pProc->id);
    274     if (h == NULL)
     252    HANDLE hProcess = OpenProcess(dwFlags, FALSE, pProc->id);
     253    if (hProcess == NULL)
    275254    {
    276255        DWORD dwErr = GetLastError();
    277256        if (g_cVerbosity)
    278257            VGSvcError("Unable to open process with PID=%u, error=%u\n", pProc->id, dwErr);
     258        return RTErrConvertFromWin32(dwErr);
     259    }
     260
     261    /*
     262     * Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps
     263     * cannot query 64-bit apps and vice verse) we have to use a different code
     264     * path for Vista and up.
     265     *
     266     * So use QueryFullProcessImageNameW when available (Vista+), fall back on
     267     * GetModuleFileNameExW on older windows version (
     268     */
     269    WCHAR wszName[_1K];
     270    DWORD dwLen = _1K;
     271    BOOL  fRc;
     272    if (g_pfnQueryFullProcessImageNameW)
     273        fRc = g_pfnQueryFullProcessImageNameW(hProcess, 0 /*PROCESS_NAME_NATIVE*/, wszName, &dwLen);
     274    else
     275        fRc = g_pfnGetModuleFileNameExW(hProcess, NULL /* Get main executable */, wszName, dwLen);
     276
     277    int rc;
     278    if (fRc)
     279        rc = RTUtf16DupEx(ppszName, wszName, 0);
     280    else
     281    {
     282        DWORD dwErr = GetLastError();
     283        if (g_cVerbosity > 3)
     284            VGSvcError("Unable to retrieve process name for PID=%u, LastError=%Rwc\n", pProc->id, dwErr);
    279285        rc = RTErrConvertFromWin32(dwErr);
    280286    }
    281     else
    282     {
    283         /* Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps cannot query 64-bit
    284            apps and vice verse) we have to use a different code path for Vista and up. */
    285         WCHAR wszName[_1K];
    286         DWORD dwLen = sizeof(wszName); /** @todo r=bird: wrong? */
    287 
    288         /* Use QueryFullProcessImageNameW if available (Vista+). */
    289         if (g_pfnQueryFullProcessImageNameW)
    290         {
    291             if (!g_pfnQueryFullProcessImageNameW(h, 0 /*PROCESS_NAME_NATIVE*/, wszName, &dwLen))
    292                 rc = VERR_ACCESS_DENIED;
    293         }
    294         else if (!g_pfnGetModuleFileNameExW(h, NULL /* Get main executable */, wszName, dwLen))
    295             rc = VERR_ACCESS_DENIED;
    296 
    297         if (   RT_FAILURE(rc)
    298             && g_cVerbosity > 3)
    299            VGSvcError("Unable to retrieve process name for PID=%u, error=%u\n", pProc->id, GetLastError());
    300         else
    301         {
    302             PRTUTF16 pszName = RTUtf16Dup(wszName);
    303             if (pszName)
    304                 *ppszName = pszName;
    305             else
    306                 rc = VERR_NO_MEMORY;
    307         }
    308 
    309         CloseHandle(h);
    310     }
    311 
     287
     288    CloseHandle(hProcess);
    312289    return rc;
    313290}
     
    697674                {
    698675                    PRTUTF16 pszName;
    699                     int rc2 = vgsvcVMInfoWinProcessesGetModuleNameA(&paProcs[i], &pszName);
     676                    int rc2 = vgsvcVMInfoWinProcessesGetModuleNameW(&paProcs[i], &pszName);
    700677                    VGSvcVerbose(4, "Session %RU32: PID=%u (fInt=%RTbool): %ls\n",
    701678                                 pSessionData->Session, paProcs[i].id, paProcs[i].fInteractive,
     
    867844                             pSessionData->LogonId.LowPart, pUserInfo->wszAuthenticationPackage, pUserInfo->wszLogonDomain);
    868845
    869                 /**
    870                  * Note: On certain Windows OSes WTSQuerySessionInformation leaks memory when used
    871                  * under a heavy stress situation. There are hotfixes available from Microsoft.
     846                /* KB970910 (check http://support.microsoft.com/kb/970910 on archive.org)
     847                 * indicates that WTSQuerySessionInformation may leak memory and return the
     848                 * wrong status code for WTSApplicationName and WTSInitialProgram queries.
    872849                 *
    873                  * See: http://support.microsoft.com/kb/970910
     850                 * The system must be low on resources, and presumably some internal operation
     851                 * must fail because of this, triggering an error handling path that forgets
     852                 * to free memory and set last error.
     853                 *
     854                 * bird 2022-08-26: However, we do not query either of those info items.  We
     855                 * query WTSConnectState, which is a rather simple affair.  So, I've
     856                 * re-enabled the code for all systems that includes the API.
    874857                 */
    875858                if (!s_fSkipRDPDetection)
    876859                {
    877                     /* Skip RDP detection on non-NT systems. */
    878                     if (g_WinVersion.dwPlatformId != VER_PLATFORM_WIN32_NT)
    879                         s_fSkipRDPDetection = true;
    880 
    881                     /* Skip RDP detection on Windows 2000.
    882                      * For Windows 2000 however we don't have any hotfixes, so just skip the
    883                      * RDP detection in any case. */
    884                     if (   g_WinVersion.dwMajorVersion == 5
    885                         && g_WinVersion.dwMinorVersion == 0)
    886                         s_fSkipRDPDetection = true;
    887 
    888860                    /* Skip if we don't have the WTS API. */
    889861                    if (!g_pfnWTSQuerySessionInformationA)
    890862                        s_fSkipRDPDetection = true;
    891 
     863#if 0 /* bird: see above */
     864                    /* Skip RDP detection on Windows 2000 and older.
     865                       For Windows 2000 however we don't have any hotfixes, so just skip the
     866                       RDP detection in any case. */
     867                    else if (RTSystemGetNtVersion() < RTSYSTEM_MAKE_NT_VERSION(5, 1, 0)) /* older than XP */
     868                        s_fSkipRDPDetection = true;
     869#endif
    892870                    if (s_fSkipRDPDetection)
    893871                        VGSvcVerbose(0, "Detection of logged-in users via RDP is disabled\n");
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