VirtualBox

Ignore:
Timestamp:
Sep 1, 2022 8:36:22 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
153448
Message:

HostDrives,Installer/win: Reworked the windows installer related code for no-CRT mode, where applicable, and changed the XxxxInstall.exe/XxxxUninstall.exe utilities to link against VBoxRT.dll instead of being statically linked. Lot's of cleanup. The change is uncomfortably large, but difficult to detangle these things. bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp

    r96407 r96572  
    11/* $Id$ */
    22/** @file
    3  * VBoxDrvCfg.cpp - Windows Driver Manipulation API implementation
     3 * VBoxDrvCfg.cpp - Windows Driver Manipulation API implementation.
     4 *
     5 * @note This is EXTREMELY BADLY documented code. Please help improve by
     6 *       adding comments whenever you've got a chance!
    47 */
    58
     
    4346#include <iprt/win/setupapi.h>
    4447#include <iprt/win/shlobj.h>
    45 
    46 #include <string.h>
    47 
    48 #include <stdlib.h>
    49 #include <malloc.h>
    50 #include <stdio.h>
    51 
    5248#include <Newdev.h>
     49
     50#include <iprt/alloca.h>
     51#include <iprt/mem.h>
     52#include <iprt/path.h>
     53#include <iprt/string.h>
     54#include <iprt/utf16.h>
    5355
    5456
     
    5658*   Global Variables                                                                                                             *
    5759*********************************************************************************************************************************/
    58 static PFNVBOXDRVCFG_LOG g_pfnVBoxDrvCfgLog;
     60static PFNVBOXDRVCFGLOG g_pfnVBoxDrvCfgLog;
    5961static void *g_pvVBoxDrvCfgLog;
    6062
    61 static PFNVBOXDRVCFG_PANIC g_pfnVBoxDrvCfgPanic;
     63static PFNVBOXDRVCFGPANIC g_pfnVBoxDrvCfgPanic;
    6264static void *g_pvVBoxDrvCfgPanic;
    6365
    6466
    65 VBOXDRVCFG_DECL(void) VBoxDrvCfgLoggerSet(PFNVBOXDRVCFG_LOG pfnLog, void *pvLog)
     67VBOXDRVCFG_DECL(void) VBoxDrvCfgLoggerSet(PFNVBOXDRVCFGLOG pfnLog, void *pvLog)
    6668{
    6769    g_pfnVBoxDrvCfgLog = pfnLog;
     
    6971}
    7072
    71 VBOXDRVCFG_DECL(void) VBoxDrvCfgPanicSet(PFNVBOXDRVCFG_PANIC pfnPanic, void *pvPanic)
     73VBOXDRVCFG_DECL(void) VBoxDrvCfgPanicSet(PFNVBOXDRVCFGPANIC pfnPanic, void *pvPanic)
    7274{
    7375    g_pfnVBoxDrvCfgPanic = pfnPanic;
     
    7577}
    7678
    77 static void vboxDrvCfgLogRel(LPCSTR szString, ...)
    78 {
    79     PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
    80     void * pvLog = g_pvVBoxDrvCfgLog;
     79static void vboxDrvCfgLogRel(const char *pszFormat, ...)
     80{
     81    PFNVBOXDRVCFGLOG pfnLog = g_pfnVBoxDrvCfgLog;
     82    void *pvLog = g_pvVBoxDrvCfgLog;
    8183    if (pfnLog)
    8284    {
    83         char szBuffer[4096] = {0};
    84         va_list pArgList;
    85         va_start(pArgList, szString);
    86         _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
    87         va_end(pArgList);
     85        char szBuffer[4096];
     86        va_list va;
     87        va_start(va, pszFormat);
     88        RTStrPrintfV(szBuffer, RT_ELEMENTS(szBuffer), pszFormat, va);
     89        va_end(va);
    8890        pfnLog(VBOXDRVCFG_LOG_SEVERITY_REL, szBuffer, pvLog);
    8991    }
    9092}
    9193
    92 static void vboxDrvCfgLogRegular(LPCSTR szString, ...)
    93 {
    94     PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
    95     void * pvLog = g_pvVBoxDrvCfgLog;
     94static void vboxDrvCfgLogRegular(const char *pszFormat, ...)
     95{
     96    PFNVBOXDRVCFGLOG pfnLog = g_pfnVBoxDrvCfgLog;
     97    void *pvLog = g_pvVBoxDrvCfgLog;
    9698    if (pfnLog)
    9799    {
    98         char szBuffer[4096] = {0};
    99         va_list pArgList;
    100         va_start(pArgList, szString);
    101         _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
    102         va_end(pArgList);
     100        char szBuffer[4096];
     101        va_list va;
     102        va_start(va, pszFormat);
     103        RTStrPrintfV(szBuffer, RT_ELEMENTS(szBuffer), pszFormat, va);
     104        va_end(va);
    103105        pfnLog(VBOXDRVCFG_LOG_SEVERITY_REGULAR, szBuffer, pvLog);
    104106    }
    105107}
    106108
    107 static void vboxDrvCfgLogFlow(LPCSTR szString, ...)
    108 {
    109     PFNVBOXDRVCFG_LOG pfnLog = g_pfnVBoxDrvCfgLog;
    110     void * pvLog = g_pvVBoxDrvCfgLog;
     109static void vboxDrvCfgLogFlow(const char *pszFormat, ...)
     110{
     111    PFNVBOXDRVCFGLOG pfnLog = g_pfnVBoxDrvCfgLog;
     112    void *pvLog = g_pvVBoxDrvCfgLog;
    111113    if (pfnLog)
    112114    {
    113         char szBuffer[4096] = {0};
    114         va_list pArgList;
    115         va_start(pArgList, szString);
    116         _vsnprintf(szBuffer, RT_ELEMENTS(szBuffer), szString, pArgList);
    117         va_end(pArgList);
     115        char szBuffer[4096];
     116        va_list va;
     117        va_start(va, pszFormat);
     118        RTStrPrintfV(szBuffer, RT_ELEMENTS(szBuffer), pszFormat, va);
     119        va_end(va);
    118120        pfnLog(VBOXDRVCFG_LOG_SEVERITY_FLOW, szBuffer, pvLog);
    119121    }
    120122}
    121123
    122 static void vboxDrvCfgPanic()
    123 {
    124     PFNVBOXDRVCFG_PANIC pfnPanic = g_pfnVBoxDrvCfgPanic;
    125     void * pvPanic = g_pvVBoxDrvCfgPanic;
     124static void vboxDrvCfgPanic(void)
     125{
     126    PFNVBOXDRVCFGPANIC pfnPanic = g_pfnVBoxDrvCfgPanic;
     127    void *pvPanic = g_pvVBoxDrvCfgPanic;
    126128    if (pfnPanic)
    127     {
    128129        pfnPanic(pvPanic);
    129     }
    130130}
    131131
     
    141141
    142142
     143/**
     144 * This is a simple string vector class.
     145 *
     146 * @note Is is _NOT_ a list as the name could lead you to believe, but a vector.
     147 */
    143148class VBoxDrvCfgStringList
    144149{
    145150public:
    146     VBoxDrvCfgStringList(int aSize);
    147 
     151    VBoxDrvCfgStringList(size_t a_cElements);
    148152    ~VBoxDrvCfgStringList();
    149153
    150154    HRESULT add(LPWSTR pStr);
    151155
    152     int size() {return mSize;}
    153 
    154     LPWSTR get(int i) {return maList[i];}
     156    size_t size() { return m_cUsed; }
     157
     158    LPWSTR get(size_t i) { return i < m_cUsed ? m_paStrings[i] : NULL; }
    155159private:
    156     HRESULT resize(int newSize);
    157 
    158     LPWSTR *maList;
    159     int mBufSize;
    160     int mSize;
     160    HRESULT grow(size_t a_cNew);
     161
     162    /** Array of strings. */
     163    LPWSTR *m_paStrings;
     164    size_t  m_cAllocated;
     165    size_t  m_cUsed;
    161166};
    162167
    163 VBoxDrvCfgStringList::VBoxDrvCfgStringList(int aSize)
    164 {
    165     maList = (LPWSTR*)malloc( sizeof(maList[0]) * aSize);
    166     mBufSize = aSize;
    167     mSize = 0;
     168VBoxDrvCfgStringList::VBoxDrvCfgStringList(size_t a_cElements)
     169{
     170    m_paStrings  = (LPWSTR *)RTMemAllocZ(sizeof(m_paStrings[0]) * a_cElements);
     171    m_cAllocated = a_cElements;
     172    m_cUsed      = 0;
    168173}
    169174
    170175VBoxDrvCfgStringList::~VBoxDrvCfgStringList()
    171176{
    172     if (!mBufSize)
     177    if (!m_cAllocated)
    173178        return;
    174179
    175     for (int i = 0; i < mSize; ++i)
    176     {
    177         free(maList[i]);
    178     }
    179 
    180     free(maList);
     180    for (size_t i = 0; i < m_cUsed; ++i)
     181        RTMemFree(m_paStrings[i]);
     182    RTMemFree(m_paStrings);
     183    m_paStrings  = NULL;
     184    m_cAllocated = 0;
     185    m_cUsed      = 0;
    181186}
    182187
    183188HRESULT VBoxDrvCfgStringList::add(LPWSTR pStr)
    184189{
    185     if (mSize == mBufSize)
    186     {
    187         int hr = resize(mBufSize+10);
    188         if (SUCCEEDED(hr))
    189             return hr;
    190     }
    191     size_t cStr = wcslen(pStr) + 1;
    192     LPWSTR str = (LPWSTR)malloc( sizeof(maList[0][0]) * cStr);
    193     memcpy(str, pStr, sizeof(maList[0][0]) * cStr);
    194     maList[mSize] = str;
    195     ++mSize;
     190    if (m_cUsed == m_cAllocated)
     191    {
     192        int hrc = grow(m_cAllocated + 16);
     193        if (SUCCEEDED(hrc))
     194            return hrc;
     195    }
     196    LPWSTR str = (LPWSTR)RTMemDup(pStr, (RTUtf16Len(pStr) + 1) * sizeof(m_paStrings[0][0]));
     197    if (!str)
     198        return E_OUTOFMEMORY;
     199    m_paStrings[m_cUsed] = str;
     200    ++m_cUsed;
    196201    return S_OK;
    197202}
    198203
    199 HRESULT VBoxDrvCfgStringList::resize(int newSize)
    200 {
    201     NonStandardAssert(newSize >= mSize);
    202     if (newSize < mSize)
     204HRESULT VBoxDrvCfgStringList::grow(size_t a_cNew)
     205{
     206    NonStandardAssert(a_cNew >= m_cUsed);
     207    if (a_cNew < m_cUsed)
    203208        return E_FAIL;
    204     LPWSTR* pOld = maList;
    205     maList = (LPWSTR*)malloc( sizeof(maList[0]) * newSize);
    206     mBufSize = newSize;
    207     memcpy(maList, pOld, mSize*sizeof(maList[0]));
    208     free(pOld);
     209    void *pvNew = RTMemReallocZ(m_paStrings, m_cUsed * sizeof(m_paStrings[0]), a_cNew * sizeof(m_paStrings[0]));
     210    if (!pvNew)
     211        return E_OUTOFMEMORY;
     212    m_paStrings  = (LPWSTR *)pvNew;
     213    m_cAllocated = a_cNew;
    209214    return S_OK;
    210215}
     
    213218 * inf file manipulation API
    214219 */
    215 typedef bool (*PFNVBOXNETCFG_ENUMERATION_CALLBACK) (LPCWSTR lpszFileName, PVOID pContext);
    216 
    217 typedef struct _INF_INFO
    218 {
    219     LPCWSTR lpszClassName;
    220     LPCWSTR lpszPnPId;
    221 } INF_INFO, *PINF_INFO;
    222 
    223 typedef struct _INFENUM_CONTEXT
    224 {
    225     INF_INFO InfInfo;
    226     DWORD Flags;
    227     HRESULT hr;
    228 } INFENUM_CONTEXT, *PINFENUM_CONTEXT;
    229 
    230 static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, PINFCONTEXT pCtx)
    231 {
    232     if (!SetupFindFirstLineW(hInf, lpszSection, lpszKey, pCtx))
     220typedef bool (*PFNVBOXNETCFG_ENUMERATION_CALLBACK_T)(LPCWSTR lpszFileName, PVOID pContext);
     221
     222typedef struct INF_INFO_T
     223{
     224    LPCWSTR pwszClassName;
     225    LPCWSTR pwszPnPId;
     226} INF_INFO_T, *PINF_INFO_T;
     227
     228typedef struct INFENUM_CONTEXT_T
     229{
     230    INF_INFO_T InfInfo;
     231    DWORD fFlags;
     232    HRESULT hrc;
     233} INFENUM_CONTEXT_T, *PINFENUM_CONTEXT_T;
     234
     235static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx)
     236{
     237    if (!SetupFindFirstLineW(hInf, pwszSection, pwszKey, pCtx))
    233238    {
    234239        DWORD dwErr = GetLastError();
    235         NonStandardLogRelCrap((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%d) for Section(%S), Key(%S)\n", dwErr, lpszSection, lpszKey));
     240        NonStandardLogRelCrap((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%Rwc) for Section(%ls), Key(%ls)\n",
     241                               dwErr, pwszSection, pwszKey));
    236242        return HRESULT_FROM_WIN32(dwErr);
    237243    }
     
    239245}
    240246
    241 static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *lppszValue, PDWORD pcValue)
    242 {
    243     DWORD dwErr;
    244     DWORD cValue;
    245 
    246     if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cValue))
    247     {
    248         dwErr = GetLastError();
     247static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *ppwszValue, PDWORD pcwcValue)
     248{
     249    *ppwszValue = NULL;
     250    if (pcwcValue)
     251        *pcwcValue = 0;
     252
     253    DWORD cwcValue;
     254    if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cwcValue))
     255    {
     256        DWORD dwErr = GetLastError();
    249257//        NonStandardAssert(dwErr == ERROR_INSUFFICIENT_BUFFER);
    250258        if (dwErr != ERROR_INSUFFICIENT_BUFFER)
    251259        {
    252             NonStandardLogFlowCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
     260            NonStandardLogFlowCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%Rwc) for iValue(%d)\n", dwErr, iValue));
    253261            return HRESULT_FROM_WIN32(dwErr);
    254262        }
    255263    }
    256264
    257     LPWSTR lpszValue = (LPWSTR)malloc(cValue * sizeof (lpszValue[0]));
    258     NonStandardAssert(lpszValue);
    259     if (!lpszValue)
    260     {
    261         NonStandardLogRelCrap((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n", cValue * sizeof (lpszValue[0]), iValue));
     265    LPWSTR pwszValue = (LPWSTR)RTMemAlloc(cwcValue * sizeof(pwszValue[0]));
     266    NonStandardAssert(pwszValue);
     267    if (!pwszValue)
     268    {
     269        NonStandardLogRelCrap((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n",
     270                               cwcValue * sizeof(pwszValue[0]), iValue));
    262271        return E_FAIL;
    263272    }
    264273
    265     if (!SetupGetStringFieldW(pCtx, iValue, lpszValue, cValue, &cValue))
    266     {
    267         dwErr = GetLastError();
    268         NonStandardLogRelCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%d) for iValue(%d)\n", dwErr, iValue));
    269         NonStandardAssert(0);
    270         free(lpszValue);
     274    if (!SetupGetStringFieldW(pCtx, iValue, pwszValue, cwcValue, &cwcValue))
     275    {
     276        DWORD dwErr = GetLastError();
     277        NonStandardLogRelCrap((__FUNCTION__ ": SetupGetStringField failed WinEr (%Rwc) for iValue(%d)\n", dwErr, iValue));
     278        NonStandardAssertFailed();
     279        RTMemFree(pwszValue);
    271280        return HRESULT_FROM_WIN32(dwErr);
    272281    }
    273282
    274     *lppszValue = lpszValue;
    275     if (pcValue)
    276         *pcValue = cValue;
     283    *ppwszValue = pwszValue;
     284    if (pcwcValue)
     285        *pcwcValue = cwcValue;
    277286    return S_OK;
    278287}
     288
    279289#if defined(RT_ARCH_AMD64)
    280 # define VBOXDRVCFG_ARCHSTR L"amd64"
     290# define VBOXDRVCFG_ARCHSTR "amd64"
    281291#else
    282 # define VBOXDRVCFG_ARCHSTR L"x86"
     292# define VBOXDRVCFG_ARCHSTR "x86"
    283293#endif
    284294
    285 static HRESULT vboxDrvCfgInfQueryModelsSectionName(HINF hInf, LPWSTR *lppszValue, PDWORD pcValue)
    286 {
     295static HRESULT vboxDrvCfgInfQueryModelsSectionName(HINF hInf, LPWSTR *ppwszValue, PDWORD pcwcValue)
     296{
     297    *ppwszValue = NULL;
     298    if (pcwcValue)
     299        *pcwcValue = 0;
     300
    287301    INFCONTEXT InfCtx;
    288     LPWSTR lpszModels, lpszPlatform = NULL, lpszPlatformCur;
    289     LPWSTR lpszResult = NULL;
    290     DWORD cModels, cPlatform = 0, cPlatformCur, cResult = 0;
    291     bool bNt = false, bArch = false /*, bOs = false */;
    292 
    293     HRESULT hr = vboxDrvCfgInfQueryContext(hInf, L"Manufacturer", NULL, &InfCtx);
    294     if (hr != S_OK)
    295     {
    296         NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for Manufacturer failed, hr=0x%x\n", hr));
    297         return hr;
    298     }
    299 
    300     hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 1, &lpszModels, &cModels);
    301     if (hr != S_OK)
    302     {
    303         NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue 1 for Manufacturer failed, hr=0x%x\n", hr));
    304         return hr;
    305     }
    306 
    307     for (DWORD i = 2; (hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, i, &lpszPlatformCur, &cPlatformCur)) == S_OK; ++i)
    308     {
    309         if (wcsicmp(lpszPlatformCur, L"NT" VBOXDRVCFG_ARCHSTR))
    310         {
    311             if (bNt)
     302    HRESULT hrc = vboxDrvCfgInfQueryContext(hInf, L"Manufacturer", NULL, &InfCtx);
     303    if (hrc != S_OK)
     304    {
     305        NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for Manufacturer failed, hrc=0x%x\n", hrc));
     306        return hrc;
     307    }
     308
     309    LPWSTR pwszModels;
     310    DWORD  cwcModels;
     311    hrc = vboxDrvCfgInfQueryKeyValue(&InfCtx, 1, &pwszModels, &cwcModels);
     312    if (hrc != S_OK)
     313    {
     314        NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue 1 for Manufacturer failed, hrc=0x%x\n", hrc));
     315        return hrc;
     316    }
     317
     318    LPWSTR pwszPlatform = NULL;
     319    DWORD  cwcPlatform  = 0;
     320    bool   fArch        = false;
     321    bool   fNt          = false;
     322
     323    LPWSTR pwszPlatformCur;
     324    DWORD  cwcPlatformCur;
     325    for (DWORD i = 2; (hrc = vboxDrvCfgInfQueryKeyValue(&InfCtx, i, &pwszPlatformCur, &cwcPlatformCur)) == S_OK; ++i)
     326    {
     327        if (RTUtf16ICmpAscii(pwszPlatformCur, "NT" VBOXDRVCFG_ARCHSTR) == 0)
     328            fArch = true;
     329        else
     330        {
     331            if (fNt || RTUtf16ICmpAscii(pwszPlatformCur, "NT") != 0)
    312332            {
    313                 free(lpszPlatformCur);
    314                 lpszPlatformCur = NULL;
     333                RTMemFree(pwszPlatformCur);
     334                pwszPlatformCur = NULL;
    315335                continue;
    316336            }
    317 
    318             if (wcsicmp(lpszPlatformCur, L"NT"))
     337            fNt = true;
     338        }
     339
     340        cwcPlatform = cwcPlatformCur;
     341        if (pwszPlatform)
     342            RTMemFree(pwszPlatform);
     343        pwszPlatform = pwszPlatformCur;
     344        pwszPlatformCur = NULL;
     345    }
     346
     347    hrc = S_OK;
     348
     349    LPWSTR pwszResult = NULL;
     350    DWORD  cwcResult = 0;
     351    if (pwszPlatform)
     352    {
     353        pwszResult = (LPWSTR)RTMemAlloc((cwcModels + cwcPlatform) * sizeof(pwszResult[0]));
     354        if (pwszResult)
     355        {
     356            memcpy(pwszResult, pwszModels, (cwcModels - 1) * sizeof(pwszResult[0]));
     357            pwszResult[cwcModels - 1] = L'.';
     358            memcpy(&pwszResult[cwcModels], pwszPlatform, cwcPlatform * sizeof(pwszResult[0]));
     359            cwcResult = cwcModels + cwcPlatform;
     360        }
     361        else
     362            hrc = E_OUTOFMEMORY;
     363    }
     364    else
     365    {
     366        pwszResult = pwszModels;
     367        cwcResult  = cwcModels;
     368        pwszModels = NULL;
     369    }
     370
     371    if (pwszModels)
     372        RTMemFree(pwszModels);
     373    if (pwszPlatform)
     374        RTMemFree(pwszPlatform);
     375
     376    if (hrc == S_OK)
     377    {
     378        *ppwszValue = pwszResult;
     379        if (pcwcValue)
     380            *pcwcValue = cwcResult;
     381    }
     382
     383    return hrc;
     384}
     385
     386static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *ppwszPnPId)
     387{
     388    *ppwszPnPId = NULL;
     389
     390    LPWSTR pwszModels;
     391    HRESULT hrc = vboxDrvCfgInfQueryModelsSectionName(hInf, &pwszModels, NULL);
     392    NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryModelsSectionName returned pwszModels = (%ls)", pwszModels));
     393    if (hrc != S_OK)
     394    {
     395        NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for Manufacturer failed, hrc=0x%x\n", hrc));
     396        return hrc;
     397    }
     398
     399    LPWSTR     pwszPnPId = NULL;
     400    INFCONTEXT InfCtx;
     401    hrc = vboxDrvCfgInfQueryContext(hInf, pwszModels, NULL, &InfCtx);
     402    if (hrc == S_OK)
     403    {
     404        hrc = vboxDrvCfgInfQueryKeyValue(&InfCtx, 2, &pwszPnPId, NULL);
     405        if (hrc == S_OK)
     406        {
     407            NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%ls) returned pwszPnPId (%ls)\n", pwszModels, pwszPnPId));
     408            *ppwszPnPId = pwszPnPId;
     409        }
     410        else
     411            NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%ls) failed, hrc=0x%x\n", pwszModels, hrc));
     412    }
     413    else
     414        NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for models (%ls) failed, hrc=0x%x\n", pwszModels, hrc));
     415
     416    RTMemFree(pwszModels);
     417    return hrc;
     418}
     419
     420static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR pwszFileName, PVOID pCtxt)
     421{
     422    PINFENUM_CONTEXT_T pContext = (PINFENUM_CONTEXT_T)pCtxt;
     423    NonStandardLogRelCrap((__FUNCTION__": pwszFileName (%ls)\n", pwszFileName));
     424    NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.pwszClassName = (%ls)\n", pContext->InfInfo.pwszClassName));
     425    HINF hInf = SetupOpenInfFileW(pwszFileName, pContext->InfInfo.pwszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
     426    if (hInf == INVALID_HANDLE_VALUE)
     427    {
     428        DWORD const dwErr = GetLastError();
     429//        NonStandardAssert(dwErr == ERROR_CLASS_MISMATCH);
     430        if (dwErr != ERROR_CLASS_MISMATCH)
     431            NonStandardLogCrap((__FUNCTION__ ": SetupOpenInfFileW err dwErr=%u\n", dwErr));
     432        else
     433            NonStandardLogCrap((__FUNCTION__ ": dwErr == ERROR_CLASS_MISMATCH\n"));
     434        return true;
     435    }
     436
     437    LPWSTR pwszPnPId;
     438    HRESULT hrc = vboxDrvCfgInfQueryFirstPnPId(hInf, &pwszPnPId);
     439    NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId returned pwszPnPId = (%ls)\n", pwszPnPId));
     440    NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.pwszPnPId = (%ls)\n", pContext->InfInfo.pwszPnPId));
     441    if (hrc == S_OK)
     442    {
     443        if (!RTUtf16ICmp(pContext->InfInfo.pwszPnPId, pwszPnPId))
     444        {
     445            /** @todo bird/2020-09-01: See the following during uninstallation with
     446             * windbg attached (see DllMain trick):
     447             *
     448             *   ModLoad: 00007ffa`73c20000 00007ffa`73c4f000   C:\WINDOWS\SYSTEM32\drvsetup.dll
     449             *   (1b238.1b254): Access violation - code c0000005 (first chance)
     450             *   First chance exceptions are reported before any exception handling.
     451             *   This exception may be expected and handled.
     452             *   KERNELBASE!WaitForMultipleObjectsEx+0x9e:
     453             *   00007ffa`8247cb6e 458b74fd00      mov     r14d,dword ptr [r13+rdi*8] ds:00000000`00000010=????????
     454             *   0:006> k
     455             *    # Child-SP          RetAddr           Call Site
     456             *   00 00000099`6e4fe7a0 00007ffa`73c2df46 KERNELBASE!WaitForMultipleObjectsEx+0x9e
     457             *   01 00000099`6e4fea90 00007ffa`73c32ec2 drvsetup!pSetupStringTableEnum+0x3e
     458             *   02 00000099`6e4feae0 00007ffa`73c2ae9d drvsetup!DrvUtilsUpdateInfoEnumDriverInfs+0x8e
     459             *   03 00000099`6e4feb20 00007ffa`73c2b1cc drvsetup!DrvSetupUninstallDriverInternal+0x211
     460             *   04 00000099`6e4febe0 00007ffa`83eb09d7 drvsetup!pDrvSetupUninstallDriver+0xfc
     461             *   05 00000099`6e4fec30 00007ffa`83eb06a0 SETUPAPI!pSetupUninstallOEMInf+0x26b
     462             *   06 00000099`6e4fef00 00007ffa`57a39fb7 SETUPAPI!SetupUninstallOEMInfW+0x170
     463             *   07 00000099`6e4ff190 00007ffa`57a3ae0c MSID039!vboxDrvCfgInfEnumerationCallback+0xf7 [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 445]
     464             *   08 00000099`6e4ff1c0 00007ffa`57a321e6 MSID039!VBoxDrvCfgInfUninstallAllSetupDi+0xfc [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 653]
     465             *   09 (Inline Function) --------`-------- MSID039!_removeHostOnlyInterfaces+0x6c [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1523]
     466             *   0a 00000099`6e4ff240 00007ffa`610f59d3 MSID039!RemoveHostOnlyInterfaces+0x76 [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1545]
     467             *   0b 00000099`6e4ff270 00007ffa`610d80ac msi!CallCustomDllEntrypoint+0x2b
     468             *   0c 00000099`6e4ff2e0 00007ffa`84567034 msi!CMsiCustomAction::CustomActionThread+0x34c
     469             *   0d 00000099`6e4ff8d0 00007ffa`849a2651 KERNEL32!BaseThreadInitThunk+0x14
     470             *   0e 00000099`6e4ff900 00000000`00000000 ntdll!RtlUserThreadStart+0x21
     471             *   0:006> r
     472             *   rax=000000996e114000 rbx=0000000000000002 rcx=0000000000000002
     473             *   rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
     474             *   rip=00007ffa8247cb6e rsp=000000996e4fe7a0 rbp=0000000000000004
     475             *    r8=0000000000000000  r9=00000000ffffffff r10=0000000000000000
     476             *   r11=0000000000000246 r12=00000000ffffffff r13=0000000000000010
     477             *   r14=00007ffa73c32e00 r15=0000000000000001
     478             *   iopl=0         nv up ei ng nz ac pe cy
     479             *   cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010293
     480             *   KERNELBASE!WaitForMultipleObjectsEx+0x9e:
     481             *   00007ffa`8247cb6e 458b74fd00      mov     r14d,dword ptr [r13+rdi*8] ds:00000000`00000010=????????
     482             *
     483             * Happens with the filter driver too:
     484             *
     485             *   (1b238.1b7e0): Access violation - code c0000005 (first chance)
     486             *   First chance exceptions are reported before any exception handling.
     487             *   This exception may be expected and handled.
     488             *   KERNELBASE!WaitForMultipleObjectsEx+0x9e:
     489             *   00007ffa`8247cb6e 458b74fd00      mov     r14d,dword ptr [r13+rdi*8] ds:00000000`00000010=????????
     490             *   0:006> k
     491             *    # Child-SP          RetAddr           Call Site
     492             *   00 00000099`6e4fe8c0 00007ffa`6558df46 KERNELBASE!WaitForMultipleObjectsEx+0x9e
     493             *   01 00000099`6e4febb0 00007ffa`65592ec2 drvsetup!pSetupStringTableEnum+0x3e
     494             *   02 00000099`6e4fec00 00007ffa`6558ae9d drvsetup!DrvUtilsUpdateInfoEnumDriverInfs+0x8e
     495             *   03 00000099`6e4fec40 00007ffa`6558b1cc drvsetup!DrvSetupUninstallDriverInternal+0x211
     496             *   04 00000099`6e4fed00 00007ffa`83eb09d7 drvsetup!pDrvSetupUninstallDriver+0xfc
     497             *   05 00000099`6e4fed50 00007ffa`83eb06a0 SETUPAPI!pSetupUninstallOEMInf+0x26b
     498             *   06 00000099`6e4ff020 00007ffa`57a39fb7 SETUPAPI!SetupUninstallOEMInfW+0x170
     499             *   07 00000099`6e4ff2b0 00007ffa`57a3abaf MSI398C!vboxDrvCfgInfEnumerationCallback+0xf7 [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 445]
     500             *   08 (Inline Function) --------`-------- MSI398C!vboxDrvCfgEnumFiles+0x4f [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 670]
     501             *   09 00000099`6e4ff2e0 00007ffa`57a3792e MSI398C!VBoxDrvCfgInfUninstallAllF+0xdf [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 723]
     502             *   0a 00000099`6e4ff7b0 00007ffa`57a33411 MSI398C!vboxNetCfgWinNetLwfUninstall+0x9e [E:\vbox\svn\trunk\src\VBox\HostDrivers\VBoxNetFlt\win\cfg\VBoxNetCfg.cpp @ 2249]
     503             *   0b 00000099`6e4ff7e0 00007ffa`57a3263d MSI398C!_uninstallNetLwf+0x71 [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1206]
     504             *   0c 00000099`6e4ff810 00007ffa`610f59d3 MSI398C!UninstallNetFlt+0xd [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1124]
     505             *   0d 00000099`6e4ff840 00007ffa`610d80ac msi!CallCustomDllEntrypoint+0x2b
     506             *   0e 00000099`6e4ff8b0 00007ffa`84567034 msi!CMsiCustomAction::CustomActionThread+0x34c
     507             *   0f 00000099`6e4ffea0 00007ffa`849a2651 KERNEL32!BaseThreadInitThunk+0x14
     508             *   10 00000099`6e4ffed0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
     509             *   0:006> r
     510             *   rax=000000996e114000 rbx=0000000000000002 rcx=0000000000000002
     511             *   rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
     512             *   rip=00007ffa8247cb6e rsp=000000996e4fe8c0 rbp=0000000000000004
     513             *    r8=0000000000000000  r9=00000000ffffffff r10=0000000000000000
     514             *   r11=0000000000000246 r12=00000000ffffffff r13=0000000000000010
     515             *   r14=00007ffa65592e00 r15=0000000000000000
     516             *   iopl=0         nv up ei ng nz ac pe cy
     517             *   cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010293
     518             *   KERNELBASE!WaitForMultipleObjectsEx+0x9e:
     519             *   00007ffa`8247cb6e 458b74fd00      mov     r14d,dword ptr [r13+rdi*8] ds:00000000`00000010=????????
     520             *
     521             * BUGBUG
     522             */
     523#if 0
     524            if (!SetupUninstallOEMInfW(pwszFileName, pContext->fFlags, /* could be SUOI_FORCEDELETE */ NULL /* Reserved */))
     525#else /* Just in case the API doesn't catch it itself (seems it does on w10/19044).  */
     526            BOOL  fRc = TRUE;
     527            __try
    319528            {
    320                 free(lpszPlatformCur);
    321                 lpszPlatformCur = NULL;
    322                 continue;
     529                fRc = SetupUninstallOEMInfW(pwszFileName, pContext->fFlags, /* could be SUOI_FORCEDELETE */ NULL /* Reserved */);
    323530            }
    324 
    325             bNt = true;
    326         }
    327         else
    328         {
    329             bArch = true;
    330         }
    331 
    332         cPlatform = cPlatformCur;
    333         if(lpszPlatform)
    334             free(lpszPlatform);
    335         lpszPlatform = lpszPlatformCur;
    336         lpszPlatformCur = NULL;
    337     }
    338 
    339     hr = S_OK;
    340 
    341     if (lpszPlatform)
    342     {
    343         lpszResult = (LPWSTR)malloc((cModels + cPlatform) * sizeof (lpszResult[0]));
    344         if (lpszResult)
    345         {
    346             memcpy(lpszResult, lpszModels, (cModels - 1) * sizeof (lpszResult[0]));
    347             *(lpszResult + cModels - 1) = L'.';
    348             memcpy(lpszResult + cModels, lpszPlatform, cPlatform * sizeof (lpszResult[0]));
    349             cResult = cModels + cPlatform;
    350         }
    351         else
    352         {
    353             hr = E_FAIL;
    354         }
     531            __except(hrc = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER)
     532            {
     533                NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf raised an exception: %#x\n", hrc));
     534                hrc = E_ABORT;
     535            }
     536            if (!fRc)
     537#endif
     538            {
     539                DWORD const dwErr = GetLastError();
     540                NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%ls), dwErr=%u\n", pwszFileName, dwErr));
     541                NonStandardAssertFailed();
     542                hrc = HRESULT_FROM_WIN32( dwErr );
     543            }
     544        }
     545
     546        RTMemFree(pwszPnPId);
    355547    }
    356548    else
    357     {
    358         lpszResult = lpszModels;
    359         cResult = cModels;
    360         lpszModels = NULL;
    361     }
    362 
    363     if (lpszModels)
    364         free(lpszModels);
    365     if (lpszPlatform)
    366         free(lpszPlatform);
    367 
    368     if (hr == S_OK)
    369     {
    370         *lppszValue = lpszResult;
    371         if (pcValue)
    372             *pcValue = cResult;
    373     }
    374 
    375     return hr;
    376 }
    377 
    378 static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *lppszPnPId)
    379 {
    380     *lppszPnPId = NULL;
    381 
    382     LPWSTR lpszModels;
    383     HRESULT hr = vboxDrvCfgInfQueryModelsSectionName(hInf, &lpszModels, NULL);
    384     NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryModelsSectionName returned lpszModels = (%S)", lpszModels));
    385     if (hr != S_OK)
    386     {
    387         NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for Manufacturer failed, hr=0x%x\n", hr));
    388         return hr;
    389     }
    390 
    391     LPWSTR lpszPnPId = NULL;
    392     INFCONTEXT InfCtx;
    393     hr = vboxDrvCfgInfQueryContext(hInf, lpszModels, NULL, &InfCtx);
    394     if (hr != S_OK)
    395     {
    396         NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryContext for models (%S) failed, hr=0x%x\n", lpszModels, hr));
    397     }
    398     else
    399     {
    400         hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 2, &lpszPnPId, NULL);
    401         NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) returned lpszPnPId (%S) \n", lpszModels, lpszPnPId));
    402 
    403         if (hr != S_OK)
    404             NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) failed, hr=0x%x\n", lpszModels, hr));
    405     }
    406     /* free models string right away */
    407     free(lpszModels);
    408     if (hr != S_OK)
    409         return hr;
    410 
    411     *lppszPnPId = lpszPnPId;
     549        NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId failed, hrc=0x%x\n", hrc));
     550
     551    SetupCloseInfFile(hInf);
     552    return true;
     553}
     554
     555
     556#define VBOXDRVCFG_S_INFEXISTS (HRESULT_FROM_WIN32(ERROR_FILE_EXISTS))
     557
     558static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR pwszInfPath, IN DWORD fCopyStyle, OUT LPWSTR pwszDstName, IN DWORD cwcDstName,
     559                                   OUT PDWORD pcwcDstNameRet, OUT LPWSTR *pwszDstNameComponent)
     560{
     561    /* Extract the director from pwszInfPath */
     562    size_t cchPath = RTUtf16Len(pwszInfPath);
     563    while (cchPath > 0 && !RTPATH_IS_SEP(pwszInfPath[cchPath - 1]))
     564        cchPath--;
     565
     566    WCHAR *pwszMediaLocation = (WCHAR *)alloca(((cchPath) + 1) * sizeof(pwszMediaLocation[0]));
     567    memcpy(pwszMediaLocation, pwszInfPath, cchPath * sizeof(pwszMediaLocation[0]));
     568    pwszMediaLocation[cchPath] = '\0';
     569
     570
     571    if (!SetupCopyOEMInfW(pwszInfPath, pwszMediaLocation, SPOST_PATH, fCopyStyle,
     572                          pwszDstName, cwcDstName, pcwcDstNameRet, pwszDstNameComponent))
     573    {
     574        DWORD const dwErr = GetLastError();
     575        HRESULT hrc = HRESULT_FROM_WIN32(dwErr);
     576        if (fCopyStyle != SP_COPY_REPLACEONLY || hrc != VBOXDRVCFG_S_INFEXISTS)
     577            NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%u\n", dwErr));
     578        return hrc;
     579    }
     580
    412581    return S_OK;
    413582}
    414583
    415 static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt);
    416 
    417 #define VBOXDRVCFG_S_INFEXISTS (HRESULT_FROM_WIN32(ERROR_FILE_EXISTS))
    418 
    419 static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle, OUT LPWSTR lpszDstName, IN DWORD cbDstName, OUT PDWORD pcbDstNameSize, OUT LPWSTR* lpszDstNameComponent)
    420 {
    421     WCHAR aMediaLocation[_MAX_DIR];
    422     WCHAR aDir[_MAX_DIR];
    423 
    424     _wsplitpath(lpszInfPath, aMediaLocation, aDir, NULL, NULL);
    425     wcscat(aMediaLocation, aDir);
    426 
    427     if (!SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,
    428             lpszDstName, cbDstName, pcbDstNameSize,
    429             lpszDstNameComponent))
    430     {
    431         DWORD dwErr = GetLastError();
    432         HRESULT hr = HRESULT_FROM_WIN32(dwErr);
    433         if (fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS)
    434         {
    435             NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%ld\n", dwErr));
    436         }
    437         return hr;
    438     }
    439 
     584VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfInstall(IN LPCWSTR pwszInfPath)
     585{
     586    return vboxDrvCfgInfCopyEx(pwszInfPath, 0 /*fCopyStyle*/, NULL /*pwszDstName*/, 0 /*cwcDstName*/,
     587                               NULL /*pcwcDstNameRet*/, NULL /*pwszDstNameComponent*/);
     588}
     589
     590VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstall(IN LPCWSTR pwszInfPath, DWORD fFlags)
     591{
     592    WCHAR   wszDstInfName[MAX_PATH];
     593    DWORD   cwcDword = RT_ELEMENTS(wszDstInfName);
     594    HRESULT hrc = vboxDrvCfgInfCopyEx(pwszInfPath, SP_COPY_REPLACEONLY, wszDstInfName, cwcDword, &cwcDword, NULL);
     595    if (hrc == VBOXDRVCFG_S_INFEXISTS)
     596    {
     597        if (!SetupUninstallOEMInfW(wszDstInfName, fFlags, NULL /*Reserved*/))
     598        {
     599            DWORD dwErr = GetLastError();
     600            NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%ls), oem(%ls), dwErr=%u\n",
     601                                   pwszInfPath, wszDstInfName, dwErr));
     602            NonStandardAssertFailed();
     603            return HRESULT_FROM_WIN32(dwErr);
     604        }
     605    }
    440606    return S_OK;
    441607}
    442608
    443 static HRESULT vboxDrvCfgInfCopy(IN LPCWSTR lpszInfPath)
    444 {
    445     return vboxDrvCfgInfCopyEx(lpszInfPath, 0, NULL, 0, NULL, NULL);
    446 }
    447 
    448 VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfInstall(IN LPCWSTR lpszInfPath)
    449 {
    450     return vboxDrvCfgInfCopy(lpszInfPath);
    451 }
    452 
    453 VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstall(IN LPCWSTR lpszInfPath, DWORD fFlags)
    454 {
    455     WCHAR DstInfName[MAX_PATH];
    456     DWORD cbDword = sizeof (DstInfName);
    457     HRESULT hr = vboxDrvCfgInfCopyEx(lpszInfPath, SP_COPY_REPLACEONLY, DstInfName, cbDword, &cbDword, NULL);
    458     if (hr == VBOXDRVCFG_S_INFEXISTS)
    459     {
    460         if (!SetupUninstallOEMInfW(DstInfName, fFlags, NULL /*__in PVOID Reserved == NULL */))
    461         {
    462             DWORD dwErr = GetLastError();
    463             NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), oem(%S), dwErr=%ld\n", lpszInfPath, DstInfName, dwErr));
    464             NonStandardAssert(0);
    465             return HRESULT_FROM_WIN32(dwErr);
    466         }
    467     }
    468     return S_OK;
    469 }
    470 
    471 
    472 static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId, VBoxDrvCfgStringList & list)
    473 {
    474     DWORD dwErr = ERROR_SUCCESS;
    475     HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(
    476                             pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
    477                             NULL /*IN HWND hwndParent OPTIONAL */
    478                             );
     609
     610static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID *pGuid, LPCWSTR pwszPnPId, VBoxDrvCfgStringList &a_rList)
     611{
     612    DWORD dwErrRet = ERROR_SUCCESS;
     613    HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(pGuid, /*ClassGuid*/ NULL /*hwndParent*/);
    479614    if (hDevInfo != INVALID_HANDLE_VALUE)
    480615    {
    481         if (SetupDiBuildDriverInfoList(hDevInfo,
    482                     NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
    483                     SPDIT_CLASSDRIVER  /*IN DWORD DriverType*/
    484                     ))
     616        /** @todo bird/2020-09-01: seeing this during uninstall when windbg is
     617         * attached to msiexec.exe (see trick in DllMain):
     618         *
     619         *    (1b238.1b254): Access violation - code c0000005 (first chance)
     620         *    First chance exceptions are reported before any exception handling.
     621         *    This exception may be expected and handled.
     622         *    SETUPAPI!SpSignVerifyInfFile+0x246:
     623         *    00007ffa`83e3ee3e 663907          cmp     word ptr [rdi],ax ds:00000000`00000000=????
     624         *    0:006> k
     625         *     # Child-SP          RetAddr           Call Site
     626         *    00 00000099`6e4f8340 00007ffa`83e1e765 SETUPAPI!SpSignVerifyInfFile+0x246
     627         *    01 00000099`6e4f8420 00007ffa`83e9ebfd SETUPAPI!DrvSearchCallback+0x1155
     628         *    02 00000099`6e4f9380 00007ffa`83e9eed3 SETUPAPI!InfCacheSearchDirectory+0x469
     629         *    03 00000099`6e4f98b0 00007ffa`83e9f454 SETUPAPI!InfCacheSearchDirectoryRecursive+0xcf
     630         *    04 00000099`6e4f9fe0 00007ffa`83e9da10 SETUPAPI!InfCacheSearchPath+0x1a0
     631         *    05 00000099`6e4fa2b0 00007ffa`83e262a2 SETUPAPI!EnumDrvInfsInDirPathList+0x560
     632         *    06 00000099`6e4fa3f0 00007ffa`57a39a21 SETUPAPI!SetupDiBuildDriverInfoList+0x1242
     633         *    07 00000099`6e4fab10 00007ffa`57a3ad6e MSID039!vboxDrvCfgCollectInfsSetupDi+0x71 [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 526]
     634         *    08 00000099`6e4ff1c0 00007ffa`57a321e6 MSID039!VBoxDrvCfgInfUninstallAllSetupDi+0x5e [E:\vbox\svn\trunk\src\VBox\HostDrivers\win\cfg\VBoxDrvCfg.cpp @ 633]
     635         *    09 (Inline Function) --------`-------- MSID039!_removeHostOnlyInterfaces+0x6c [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1523]
     636         *    0a 00000099`6e4ff240 00007ffa`610f59d3 MSID039!RemoveHostOnlyInterfaces+0x76 [E:\vbox\svn\trunk\src\VBox\Installer\win\InstallHelper\VBoxInstallHelper.cpp @ 1545]
     637         *    0b 00000099`6e4ff270 00007ffa`610d80ac msi!CallCustomDllEntrypoint+0x2b
     638         *    0c 00000099`6e4ff2e0 00007ffa`84567034 msi!CMsiCustomAction::CustomActionThread+0x34c
     639         *    0d 00000099`6e4ff8d0 00007ffa`849a2651 KERNEL32!BaseThreadInitThunk+0x14
     640         *    0e 00000099`6e4ff900 00000000`00000000 ntdll!RtlUserThreadStart+0x21
     641         *    0:006> r
     642         *    rax=0000000000000000 rbx=0000000000000490 rcx=aa222a2675da0000
     643         *    rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
     644         *    rip=00007ffa83e3ee3e rsp=000000996e4f8340 rbp=000000996e4f9480
     645         *     r8=0000000000050004  r9=00007ffa83ef5418 r10=0000000000008000
     646         *    r11=000000996e4f76f0 r12=000000996e4f84c8 r13=0000000000000000
     647         *    r14=000000996e4f88d0 r15=0000000000000000
     648         *    iopl=0         nv up ei pl nz ac pe cy
     649         *    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010213
     650         *    SETUPAPI!SpSignVerifyInfFile+0x246:
     651         *    00007ffa`83e3ee3e 663907          cmp     word ptr [rdi],ax ds:00000000`00000000=????
     652          */
     653#if 0
     654        if (SetupDiBuildDriverInfoList(hDevInfo, NULL /*DeviceInfoData*/, SPDIT_CLASSDRIVER))
     655#else   /* Just in case the API doesn't catch it itself (seems it does on w10/19044).  */
     656        BOOL fRc = FALSE;
     657        DWORD uXcpt = 0;
     658        __try
     659        {
     660            fRc = SetupDiBuildDriverInfoList(hDevInfo, NULL /*DeviceInfoData*/, SPDIT_CLASSDRIVER);
     661        }
     662        __except(uXcpt = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER)
     663        {
     664            NonStandardLogRelCrap((__FUNCTION__ ": SetupDiBuildDriverInfoList raised an exception: %#x\n", uXcpt));
     665        }
     666        if (fRc)
     667#endif
    485668        {
    486669            SP_DRVINFO_DATA DrvInfo;
    487670            DrvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
    488             char DetailBuf[16384];
    489             PSP_DRVINFO_DETAIL_DATA pDrvDetail = (PSP_DRVINFO_DETAIL_DATA)DetailBuf;
    490 
    491             for (DWORD i = 0; ; i++)
     671
     672            union
    492673            {
    493                 if (SetupDiEnumDriverInfo(hDevInfo,
    494                         NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
    495                         SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
    496                         i, /*IN DWORD MemberIndex,*/
    497                         &DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
    498                         ))
     674                SP_DRVINFO_DETAIL_DATA_W s;
     675                uint8_t ab[16384];
     676            } DrvDetail;
     677
     678            /* Ensure zero terminated buffer: */
     679            DrvDetail.ab[sizeof(DrvDetail) - 1] = '\0';
     680            DrvDetail.ab[sizeof(DrvDetail) - 2] = '\0';
     681
     682            for (DWORD i = 0; dwErrRet == ERROR_SUCCESS; i++)
     683            {
     684                if (SetupDiEnumDriverInfo(hDevInfo, NULL /*DeviceInfoData*/, SPDIT_CLASSDRIVER /*DriverType*/,
     685                                          i /*MemberIndex*/, &DrvInfo /*DriverInfoData*/))
    499686                {
    500                     DWORD dwReq;
    501                     pDrvDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
    502                     if (SetupDiGetDriverInfoDetail(
    503                             hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
    504                             NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
    505                             &DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
    506                             pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
    507                             sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
    508                             &dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
    509                             ))
     687                    DWORD dwReq = 0;
     688                    DrvDetail.s.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
     689                    if (SetupDiGetDriverInfoDetail(hDevInfo, NULL /*DeviceInfoData*/, &DrvInfo,
     690                                                   &DrvDetail.s, sizeof(DrvDetail) - 2 /*our terminator*/, &dwReq))
    510691                    {
    511                         for (WCHAR *pwszHwId = pDrvDetail->HardwareID;
    512                              pwszHwId && *pwszHwId && (uintptr_t)pwszHwId < (uintptr_t)DetailBuf + sizeof(DetailBuf);
    513                              pwszHwId += wcslen(pwszHwId) + 1)
     692                        for (WCHAR *pwszHwId = DrvDetail.s.HardwareID;
     693                             *pwszHwId != '\0' && (uintptr_t)pwszHwId < (uintptr_t)&DrvDetail.ab[sizeof(DrvDetail)];
     694                             pwszHwId += RTUtf16Len(pwszHwId) + 1)
    514695                        {
    515                             if (!wcsicmp(pwszHwId, pPnPId))
     696                            if (RTUtf16ICmp(pwszHwId, pwszPnPId) == 0)
    516697                            {
    517                                 NonStandardAssert(pDrvDetail->InfFileName[0]);
    518                                 if (pDrvDetail->InfFileName)
     698                                NonStandardAssert(DrvDetail.s.InfFileName[0]);
     699                                if (DrvDetail.s.InfFileName[0])
    519700                                {
    520                                     list.add(pDrvDetail->InfFileName);
    521                                     NonStandardLogRelCrap((__FUNCTION__": %S added to list", pDrvDetail->InfFileName));
     701                                    HRESULT hrc = a_rList.add(DrvDetail.s.InfFileName);
     702                                    NonStandardLogRelCrap((__FUNCTION__": %ls added to list (%#x)", DrvDetail.s.InfFileName, hrc));
     703                                    if (hrc != S_OK)
     704                                    {
     705                                        dwErrRet = ERROR_OUTOFMEMORY;
     706                                        break;
     707                                    }
    522708                                }
    523709                            }
     
    527713                    {
    528714                        DWORD dwErr2 = GetLastError();
    529                         NonStandardLogRelCrap((__FUNCTION__": SetupDiGetDriverInfoDetail fail dwErr=%ld, size(%d)", dwErr2, dwReq));
    530 //                        NonStandardAssert(0);
     715                        NonStandardLogRelCrap((__FUNCTION__": SetupDiGetDriverInfoDetail fail dwErr=%u, size(%d)", dwErr2, dwReq));
     716//                        NonStandardAssertFailed();
    531717                    }
    532 
    533718                }
    534719                else
     
    540725                        break;
    541726                    }
    542 
    543                     NonStandardAssert(0);
     727                    NonStandardAssertFailed();
    544728                }
    545729            }
    546730
    547             SetupDiDestroyDriverInfoList(hDevInfo,
    548                       NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
    549                       SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
    550                       );
     731            SetupDiDestroyDriverInfoList(hDevInfo, NULL /*DeviceInfoData*/, SPDIT_CLASSDRIVER);
    551732        }
    552733        else
    553734        {
    554             dwErr = GetLastError();
    555             NonStandardAssert(0);
     735            dwErrRet = GetLastError();
     736            NonStandardAssertFailed();
    556737        }
    557738
     
    560741    else
    561742    {
    562         dwErr = GetLastError();
    563         NonStandardAssert(0);
    564     }
    565 
    566     return HRESULT_FROM_WIN32(dwErr);
     743        dwErrRet = GetLastError();
     744        NonStandardAssertFailed();
     745    }
     746
     747    return HRESULT_FROM_WIN32(dwErrRet);
    567748}
    568749
     
    586767#endif
    587768
    588 VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidClass, IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD Flags)
     769VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID *pGuidClass, IN LPCWSTR pwszClassName,
     770                                                          IN LPCWSTR pwszPnPId, IN DWORD fFlags)
    589771{
    590772    VBoxDrvCfgStringList list(128);
    591     HRESULT hr = vboxDrvCfgCollectInfsSetupDi(pGuidClass, lpszPnPId, list);
    592     NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgCollectInfsSetupDi returned %d devices with PnPId %S and class name %S", list.size(), lpszPnPId, lpszClassName));
    593     if (hr == S_OK)
    594     {
    595         INFENUM_CONTEXT Context;
    596         Context.InfInfo.lpszClassName = lpszClassName;
    597         Context.InfInfo.lpszPnPId = lpszPnPId;
    598         Context.Flags = Flags;
    599         Context.hr = S_OK;
    600         int size = list.size();
    601         for (int i = 0; i < size; ++i)
    602         {
    603             LPCWSTR pInf = list.get(i);
    604             const WCHAR* pRel = wcsrchr(pInf, '\\');
    605             if (pRel)
    606                 ++pRel;
    607             else
    608                 pRel = pInf;
    609 
    610             vboxDrvCfgInfEnumerationCallback(pRel, &Context);
    611             NonStandardLogRelCrap((__FUNCTION__": inf = %S\n", list.get(i)));
    612         }
    613     }
    614     return hr;
    615 }
    616 
    617 static HRESULT vboxDrvCfgEnumFiles(LPCWSTR pPattern, PFNVBOXNETCFG_ENUMERATION_CALLBACK pfnCallback, PVOID pContext)
    618 {
    619     WIN32_FIND_DATA Data;
    620     memset(&Data, 0, sizeof(Data));
    621     HRESULT hr = S_OK;
    622 
    623     HANDLE hEnum = FindFirstFile(pPattern,&Data);
     773    HRESULT hrc = vboxDrvCfgCollectInfsSetupDi(pGuidClass, pwszPnPId, list);
     774    NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgCollectInfsSetupDi returned %d devices with PnPId %ls and class name %ls",
     775                           list.size(), pwszPnPId, pwszClassName));
     776    if (hrc == S_OK)
     777    {
     778        INFENUM_CONTEXT_T Context;
     779        Context.InfInfo.pwszClassName = pwszClassName;
     780        Context.InfInfo.pwszPnPId = pwszPnPId;
     781        Context.fFlags = fFlags;
     782        Context.hrc = S_OK;
     783        size_t const cItems = list.size();
     784        for (size_t i = 0; i < cItems; ++i)
     785        {
     786            LPCWSTR pwszInf = list.get(i);
     787
     788            /* Find the start of the filename: */
     789            size_t offFilename = RTUtf16Len(pwszInf);
     790            while (offFilename > 0 && !RTPATH_IS_SEP(pwszInf[offFilename - 1]))
     791                offFilename--;
     792
     793            vboxDrvCfgInfEnumerationCallback(&pwszInf[offFilename], &Context);
     794            NonStandardLogRelCrap((__FUNCTION__": inf = %ls\n", pwszInf));
     795        }
     796    }
     797    return hrc;
     798}
     799
     800static HRESULT vboxDrvCfgEnumFiles(LPCWSTR pwszDirAndPattern, PFNVBOXNETCFG_ENUMERATION_CALLBACK_T pfnCallback, PVOID pContext)
     801{
     802    HRESULT hrc = S_OK;
     803
     804    WIN32_FIND_DATAW Data;
     805    RT_ZERO(Data);
     806    HANDLE hEnum = FindFirstFileW(pwszDirAndPattern, &Data);
    624807    if (hEnum != INVALID_HANDLE_VALUE)
    625808    {
    626 
    627         do
     809        for (;;)
    628810        {
    629811            if (!pfnCallback(Data.cFileName, pContext))
    630             {
    631812                break;
    632             }
    633813
    634814            /* next iteration */
    635             memset(&Data, 0, sizeof(Data));
    636             BOOL bNext = FindNextFile(hEnum,&Data);
    637             if (!bNext)
     815            RT_ZERO(Data);
     816            BOOL fNext = FindNextFile(hEnum, &Data);
     817            if (!fNext)
    638818            {
    639819                DWORD dwErr = GetLastError();
    640820                if (dwErr != ERROR_NO_MORE_FILES)
    641821                {
    642                     NonStandardLogRelCrap((__FUNCTION__": FindNextFile fail dwErr=%ld\n", dwErr));
    643                     NonStandardAssert(0);
    644                     hr = HRESULT_FROM_WIN32(dwErr);
     822                    NonStandardLogRelCrap((__FUNCTION__": FindNextFile fail dwErr=%u\n", dwErr));
     823                    NonStandardAssertFailed();
     824                    hrc = HRESULT_FROM_WIN32(dwErr);
    645825                }
    646826                break;
    647827            }
    648         }while (true);
     828        }
     829
    649830        FindClose(hEnum);
    650831    }
     
    654835        if (dwErr != ERROR_NO_MORE_FILES)
    655836        {
    656             NonStandardLogRelCrap((__FUNCTION__": FindFirstFile fail dwErr=%ld\n", dwErr));
    657             NonStandardAssert(0);
    658             hr = HRESULT_FROM_WIN32(dwErr);
    659         }
    660     }
    661 
    662     return hr;
    663 }
    664 
    665 static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt)
    666 {
    667     PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt;
    668     DWORD dwErr;
    669     NonStandardLogRelCrap((__FUNCTION__": lpszFileName (%S)\n", lpszFileName));
    670     NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszClassName = (%S)\n", pContext->InfInfo.lpszClassName));
    671     HINF hInf = SetupOpenInfFileW(lpszFileName, pContext->InfInfo.lpszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
    672     if (hInf == INVALID_HANDLE_VALUE)
    673     {
    674         dwErr = GetLastError();
    675 //        NonStandardAssert(dwErr == ERROR_CLASS_MISMATCH);
    676         if (dwErr != ERROR_CLASS_MISMATCH)
    677         {
    678             NonStandardLogCrap((__FUNCTION__ ": SetupOpenInfFileW err dwErr=%ld\n", dwErr));
    679         }
     837            NonStandardLogRelCrap((__FUNCTION__": FindFirstFile fail dwErr=%u\n", dwErr));
     838            NonStandardAssertFailed();
     839            hrc = HRESULT_FROM_WIN32(dwErr);
     840        }
     841    }
     842
     843    return hrc;
     844}
     845
     846VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR pwszClassName, LPCWSTR pwszPnPId, DWORD fFlags)
     847{
     848    static WCHAR const s_wszFilter[] = L"\\inf\\oem*.inf";
     849
     850    HRESULT hrc;
     851    WCHAR   wszInfDirPath[MAX_PATH];
     852    UINT    cwcInput = RT_ELEMENTS(wszInfDirPath) - RT_ELEMENTS(s_wszFilter);
     853    UINT    cwcWindows = GetSystemWindowsDirectoryW(wszInfDirPath, cwcInput);
     854    if (cwcWindows > 0 && cwcWindows < cwcInput)
     855    {
     856        RTUtf16Copy(&wszInfDirPath[cwcWindows], RT_ELEMENTS(wszInfDirPath) - cwcWindows, s_wszFilter);
     857
     858        INFENUM_CONTEXT_T Context;
     859        Context.InfInfo.pwszClassName = pwszClassName;
     860        Context.InfInfo.pwszPnPId = pwszPnPId;
     861        Context.fFlags = fFlags;
     862        Context.hrc = S_OK;
     863        NonStandardLogRelCrap((__FUNCTION__": Calling vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context)"));
     864        hrc = vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context);
     865        NonStandardAssert(hrc == S_OK);
     866        if (hrc == S_OK)
     867            hrc = Context.hrc;
    680868        else
    681         {
    682             NonStandardLogCrap((__FUNCTION__ ": dwErr == ERROR_CLASS_MISMATCH\n"));
    683         }
    684         return true;
    685     }
    686 
    687     LPWSTR lpszPnPId;
    688     HRESULT hr = vboxDrvCfgInfQueryFirstPnPId(hInf, &lpszPnPId);
    689     NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId returned lpszPnPId = (%S)\n", lpszPnPId));
    690     NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszPnPId = (%S)\n", pContext->InfInfo.lpszPnPId));
    691     if (hr == S_OK)
    692     {
    693         if (!wcsicmp(pContext->InfInfo.lpszPnPId, lpszPnPId))
    694         {
    695             if (!SetupUninstallOEMInfW(lpszFileName,
    696                         pContext->Flags, /*DWORD Flags could be SUOI_FORCEDELETE */
    697                         NULL /*__in PVOID Reserved == NULL */
    698                         ))
    699             {
    700                 dwErr = GetLastError();
    701                 NonStandardLogRelCrap((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), dwErr=%ld\n", lpszFileName, dwErr));
    702                 NonStandardAssert(0);
    703                 hr = HRESULT_FROM_WIN32( dwErr );
    704             }
    705         }
    706 
    707         free(lpszPnPId);
    708     }
    709     else
    710     {
    711         NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId failed, hr=0x%x\n", hr));
    712     }
    713 
    714     SetupCloseInfFile(hInf);
    715 
    716     return true;
    717 }
    718 
    719 VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR lpszClassName, LPCWSTR lpszPnPId, DWORD Flags)
    720 {
    721     static WCHAR const s_wszFilter[] = L"\\inf\\oem*.inf";
    722     HRESULT hr;
    723     WCHAR wszInfDirPath[MAX_PATH];
    724     UINT cwcInput = RT_ELEMENTS(wszInfDirPath) - RT_ELEMENTS(s_wszFilter);
    725     UINT cwcWindows = GetSystemWindowsDirectory(wszInfDirPath, cwcInput);
    726     if (cwcWindows > 0 && cwcWindows < cwcInput)
    727     {
    728         wcscpy(&wszInfDirPath[cwcWindows], s_wszFilter);
    729 
    730         INFENUM_CONTEXT Context;
    731         Context.InfInfo.lpszClassName = lpszClassName;
    732         Context.InfInfo.lpszPnPId = lpszPnPId;
    733         Context.Flags = Flags;
    734         Context.hr = S_OK;
    735         NonStandardLogRelCrap((__FUNCTION__": Calling vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context)"));
    736         hr = vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context);
    737         NonStandardAssert(hr == S_OK);
    738         if (hr == S_OK)
    739         {
    740             hr = Context.hr;
    741         }
    742         else
    743         {
    744             NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgEnumFiles failed, hr=0x%x\n", hr));
    745         }
     869            NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgEnumFiles failed, hrc=0x%x\n", hrc));
    746870    }
    747871    else
     
    749873        NonStandardLogRelCrap((__FUNCTION__": GetSystemWindowsDirectory failed, cwcWindows=%u lasterr=%u\n", cwcWindows, GetLastError()));
    750874        NonStandardAssertFailed();
    751         hr = E_FAIL;
    752     }
    753 
    754     return hr;
     875        hrc = E_FAIL;
     876    }
     877
     878    return hrc;
    755879
    756880}
     
    764888#define VBOXDRVCFG_SVC_WAITSTART_RETRIES (VBOXDRVCFG_SVC_WAITSTART_TIME/VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD)
    765889
    766 VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR lpszSvcName)
    767 {
    768     SC_HANDLE hMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
     890VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR pwszSvcName)
     891{
     892    SC_HANDLE hMgr = OpenSCManagerW(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
    769893    if (hMgr == NULL)
    770894    {
    771895        DWORD dwErr = GetLastError();
    772         NonStandardLogRelCrap((__FUNCTION__": OpenSCManager failed, dwErr=%ld\n", dwErr));
     896        NonStandardLogRelCrap((__FUNCTION__": OpenSCManager failed, dwErr=%u\n", dwErr));
    773897        return HRESULT_FROM_WIN32(dwErr);
    774898    }
    775899
    776     HRESULT hr = S_OK;
    777     SC_HANDLE hSvc = OpenServiceW(hMgr, lpszSvcName, SERVICE_QUERY_STATUS | SERVICE_START);
     900    HRESULT hrc = S_OK;
     901    SC_HANDLE hSvc = OpenServiceW(hMgr, pwszSvcName, SERVICE_QUERY_STATUS | SERVICE_START);
    778902    if (hSvc)
    779903    {
    780         do
    781         {
    782             SERVICE_STATUS Status;
    783             BOOL fRc = QueryServiceStatus(hSvc, &Status);
    784             if (!fRc)
    785             {
    786                 DWORD dwErr = GetLastError();
    787                 NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
    788                 hr = HRESULT_FROM_WIN32(dwErr);
    789                 break;
    790             }
    791 
     904        SERVICE_STATUS Status;
     905        BOOL fRc = QueryServiceStatus(hSvc, &Status);
     906        if (fRc)
     907        {
    792908            if (Status.dwCurrentState != SERVICE_RUNNING && Status.dwCurrentState != SERVICE_START_PENDING)
    793909            {
    794                 NonStandardLogRelCrap(("Starting service (%S)\n", lpszSvcName));
     910                NonStandardLogRelCrap(("Starting service (%ls)\n", pwszSvcName));
    795911
    796912                fRc = StartService(hSvc, 0, NULL);
     
    798914                {
    799915                    DWORD dwErr = GetLastError();
    800                     NonStandardLogRelCrap((__FUNCTION__": StartService failed dwErr=%ld\n", dwErr));
    801                     hr = HRESULT_FROM_WIN32(dwErr);
    802                     break;
     916                    NonStandardLogRelCrap((__FUNCTION__": StartService failed dwErr=%u\n", dwErr));
     917                    hrc = HRESULT_FROM_WIN32(dwErr);
    803918                }
    804919            }
    805920
    806             fRc = QueryServiceStatus(hSvc, &Status);
    807             if (!fRc)
     921            if (fRc)
    808922            {
    809                 DWORD dwErr = GetLastError();
    810                 NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
    811                 hr = HRESULT_FROM_WIN32(dwErr);
    812                 break;
    813             }
    814 
    815             if (Status.dwCurrentState == SERVICE_START_PENDING)
    816             {
    817                 for (int i = 0; i < VBOXDRVCFG_SVC_WAITSTART_RETRIES; ++i)
     923                fRc = QueryServiceStatus(hSvc, &Status);
     924                if (fRc)
    818925                {
    819                     Sleep(VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD);
    820                     fRc = QueryServiceStatus(hSvc, &Status);
    821                     if (!fRc)
     926                    if (Status.dwCurrentState == SERVICE_START_PENDING)
     927                        for (size_t i = 0; i < VBOXDRVCFG_SVC_WAITSTART_RETRIES; ++i)
     928                        {
     929                            Sleep(VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD);
     930                            fRc = QueryServiceStatus(hSvc, &Status);
     931                            if (!fRc)
     932                            {
     933                                DWORD dwErr = GetLastError();
     934                                NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%u\n", dwErr));
     935                                hrc = HRESULT_FROM_WIN32(dwErr);
     936                                break;
     937                            }
     938                            if (Status.dwCurrentState != SERVICE_START_PENDING)
     939                                break;
     940                        }
     941
     942                    if (hrc != S_OK || Status.dwCurrentState != SERVICE_RUNNING)
    822943                    {
    823                         DWORD dwErr = GetLastError();
    824                         NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr));
    825                         hr = HRESULT_FROM_WIN32(dwErr);
    826                         break;
     944                        NonStandardLogRelCrap((__FUNCTION__": Failed to start the service\n"));
     945                        hrc = E_FAIL;
    827946                    }
    828                     else if (Status.dwCurrentState != SERVICE_START_PENDING)
    829                         break;
     947                }
     948                else
     949                {
     950                    DWORD dwErr = GetLastError();
     951                    NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%u\n", dwErr));
     952                    hrc = HRESULT_FROM_WIN32(dwErr);
    830953                }
    831954            }
    832 
    833             if (hr != S_OK || Status.dwCurrentState != SERVICE_RUNNING)
    834             {
    835                 NonStandardLogRelCrap((__FUNCTION__": Failed to start the service\n"));
    836                 hr = E_FAIL;
    837                 break;
    838             }
    839 
    840         } while (0);
     955        }
     956        else
     957        {
     958            DWORD dwErr = GetLastError();
     959            NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%u\n", dwErr));
     960            hrc = HRESULT_FROM_WIN32(dwErr);
     961        }
    841962
    842963        CloseServiceHandle(hSvc);
     
    845966    {
    846967        DWORD dwErr = GetLastError();
    847         NonStandardLogRelCrap((__FUNCTION__": OpenServiceW failed, dwErr=%ld\n", dwErr));
    848         hr = HRESULT_FROM_WIN32(dwErr);
     968        NonStandardLogRelCrap((__FUNCTION__": OpenServiceW failed, dwErr=%u\n", dwErr));
     969        hrc = HRESULT_FROM_WIN32(dwErr);
    849970    }
    850971
    851972    CloseServiceHandle(hMgr);
    852 
    853     return hr;
    854 }
    855 
    856 
    857 HRESULT VBoxDrvCfgDrvUpdate(LPCWSTR pcszwHwId, LPCWSTR pcsxwInf, BOOL *pbRebootRequired)
    858 {
    859     if (pbRebootRequired)
    860         *pbRebootRequired = FALSE;
    861     BOOL bRebootRequired = FALSE;
    862     WCHAR InfFullPath[MAX_PATH];
    863     DWORD dwChars = GetFullPathNameW(pcsxwInf,
    864             sizeof (InfFullPath) / sizeof (InfFullPath[0]),
    865             InfFullPath,
    866             NULL /* LPTSTR *lpFilePart */
    867             );
     973    return hrc;
     974}
     975
     976
     977HRESULT VBoxDrvCfgDrvUpdate(LPCWSTR pszwHwId, LPCWSTR psxwInf, BOOL *pfRebootRequired)
     978{
     979    if (pfRebootRequired)
     980        *pfRebootRequired = FALSE;
     981
     982    WCHAR wszInfFullPath[MAX_PATH];
     983    DWORD dwChars = GetFullPathNameW(psxwInf, MAX_PATH, wszInfFullPath, NULL /*lpFilePart*/);
    868984    if (!dwChars || dwChars >= MAX_PATH)
    869985    {
    870         NonStandardLogCrap(("GetFullPathNameW failed, dwErr=%ld, dwChars=%ld\n",
    871                             GetLastError(), dwChars));
     986        NonStandardLogCrap(("GetFullPathNameW failed, dwErr=%u, dwChars=%ld\n", GetLastError(), dwChars));
    872987        return E_INVALIDARG;
    873988    }
    874989
    875 
    876     if (!UpdateDriverForPlugAndPlayDevicesW(NULL, /* HWND hwndParent */
    877             pcszwHwId,
    878             InfFullPath,
    879             INSTALLFLAG_FORCE,
    880             &bRebootRequired))
     990    BOOL fRebootRequired = FALSE;
     991    if (!UpdateDriverForPlugAndPlayDevicesW(NULL /*hwndParent*/, pszwHwId, wszInfFullPath, INSTALLFLAG_FORCE, &fRebootRequired))
    881992    {
    882993        DWORD dwErr = GetLastError();
    883         NonStandardLogCrap(("UpdateDriverForPlugAndPlayDevicesW failed, dwErr=%ld\n",
    884                             dwErr));
     994        NonStandardLogCrap(("UpdateDriverForPlugAndPlayDevicesW failed, dwErr=%u\n", dwErr));
    885995        return HRESULT_FROM_WIN32(dwErr);
    886996    }
    887997
    888 
    889     if (bRebootRequired)
    890         NonStandardLogCrap(("!!Driver Update: REBOOT REQUIRED!!\n", GetLastError(), dwChars));
    891 
    892     if (pbRebootRequired)
    893         *pbRebootRequired = bRebootRequired;
     998    if (fRebootRequired)
     999        NonStandardLogCrap(("!!Driver Update: REBOOT REQUIRED!!\n"));
     1000
     1001    if (pfRebootRequired)
     1002        *pfRebootRequired = fRebootRequired;
    8941003
    8951004    return S_OK;
    8961005}
     1006
Note: See TracChangeset for help on using the changeset viewer.

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