VirtualBox

Changeset 106488 in vbox for trunk/src/VBox/GuestHost


Ignore:
Timestamp:
Oct 18, 2024 7:16:23 PM (3 months ago)
Author:
vboxsync
Message:

Windows driver installation: Try a bit harder running the [un]installation sections by probing various combinations. bugref:10762

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/installation/VBoxWinDrvInst.cpp

    r106485 r106488  
    116116typedef BOOL(WINAPI* PFNSETUPUNINSTALLOEMINFW) (PCWSTR InfFileName, DWORD Flags, PVOID Reserved);
    117117typedef BOOL(WINAPI *PFNSETUPSETNONINTERACTIVEMODE) (BOOL NonInteractiveFlag);
     118
     119/** Function pointer for a general try INF section callback. */
     120typedef int (*PFNVBOXWINDRVINST_TRYINFSECTION_CALLBACK)(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx);
    118121
    119122
     
    674677    PVBOXWINDRVINSTINTERNAL pThis;
    675678    /** Weak pointer to INF file being handled. */
    676     PRTUTF16                pwszInfFile;
     679    PCRTUTF16               pwszInfFile;
    677680    /** Weak pointer to INF section being handled. */
    678     PRTUTF16                pwszSection;
     681    PCRTUTF16               pwszSection;
    679682    /** User-supplied context pointer. */
    680683    void                   *pvSetupContext;
     
    741744}
    742745RT_C_DECLS_END
     746
     747/**
     748 * Generic function to for probing a list of well-known sections for [un]installation.
     749 *
     750 * Due to the nature of INF files this function tries different combinations of decorations (e.g. SectionName[.NTAMD64|.X86])
     751 * and invokes the given callback for the first found section.
     752 *
     753 * @returns VBox status code.
     754 * @param   pCtx                Windows driver installer context.
     755 * @param   pwszInfPathAbs      Absolute path of INF file to use for [un]installation.
     756 * @param   pwszSection         Section to invoke for [un]installation.
     757 * @param   pfnCallback         Callback to invoke for each found section.
     758 */
     759static int vboxWinDrvTryInfSection(PVBOXWINDRVINSTINTERNAL pCtx, PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection,
     760                                   PFNVBOXWINDRVINST_TRYINFSECTION_CALLBACK pfnCallback)
     761{
     762    vboxWinDrvInstLogVerbose(pCtx, 1, "Trying section \"%ls\"", pwszSection);
     763
     764    /* Sorted by most likely-ness. */
     765    PCRTUTF16 apwszTryInstallSections[] =
     766    {
     767        /* The more specific (using decorations), the better. Try these first. Might be NULL. */
     768        pwszSection,
     769        /* Applies to primitive (and legacy) drivers. */
     770        L"DefaultUninstall"
     771    };
     772
     773    PCRTUTF16 apwszTryInstallDecorations[] =
     774    {
     775        /* No decoration. Try that first. */
     776        L"",
     777        /* Native architecture. */
     778        L"" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR
     779    };
     780
     781    int rc = VINF_SUCCESS; /* Shut up MSVC. */
     782
     783    for (size_t i = 0; i < RT_ELEMENTS(apwszTryInstallSections); i++)
     784    {
     785        PCRTUTF16 const pwszTrySection = apwszTryInstallSections[i];
     786        if (!pwszTrySection)
     787            continue;
     788
     789        for (size_t d = 0; d < RT_ELEMENTS(apwszTryInstallDecorations); d++)
     790        {
     791            RTUTF16 wszTrySection[64];
     792            rc = RTUtf16Copy(wszTrySection, sizeof(wszTrySection), pwszTrySection);
     793            AssertRCBreak(rc);
     794            rc = RTUtf16Cat(wszTrySection, sizeof(wszTrySection), apwszTryInstallDecorations[d]);
     795            AssertRCBreak(rc);
     796
     797            rc = pfnCallback(pwszInfPathAbs, wszTrySection, pCtx /* pvCtx */);
     798            if (RT_SUCCESS(rc))
     799                break;
     800
     801            if (rc == VERR_FILE_NOT_FOUND) /* File gone already. */
     802            {
     803                rc = VINF_SUCCESS;
     804                break;
     805            }
     806
     807            if (rc != VERR_NOT_FOUND)
     808                vboxWinDrvInstLogError(pCtx, "Uninstalling INF section failed with %Rrc", rc);
     809        }
     810    }
     811
     812    if (rc == VERR_NOT_FOUND)
     813    {
     814        vboxWinDrvInstLogWarn(pCtx, "No matching uninstallation section found -- buggy driver?");
     815        rc = VINF_SUCCESS;
     816    }
     817
     818    return rc;
     819}
    743820
    744821/**
     
    832909 *                              Can have a platform decoration (e.g. "Foobar.NTx86").
    833910 */
    834 static int vboxWinDrvInstallInfSectionEx(PVBOXWINDRVINSTINTERNAL pCtx, PRTUTF16 pwszInfFile, PRTUTF16 pwszSection)
     911static int vboxWinDrvInstallInfSectionEx(PVBOXWINDRVINSTINTERNAL pCtx, PCRTUTF16 pwszInfFile, PCRTUTF16 pwszSection)
    835912{
    836913    AssertPtrReturn(pwszInfFile, VERR_INVALID_POINTER);
     
    9541031
    9551032/**
    956  * Tries probing a list of well-known sections for installation and will install the first one found.
    957  *
    958  * @returns VBox status code.
    959  * @param   pCtx                Windows driver installer context.
    960  * @param   pParms              Windows driver installation parameters to use.
    961  */
    962 static int vboxWinDrvInstallTryInfSections(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms)
    963 {
    964     /* Sorted by most likely-ness. */
    965     PRTUTF16 apwszTryInstallSections[] =
    966     {
    967         /* The more specific (using decorations), the better. Try these first. */
    968         pParms->u.UnInstall.pwszModel,
    969         /* Applies to primitive drivers. */
    970         L"DefaultInstall" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
    971         L"DefaultInstall"
    972     };
    973 
    974     int rc = VINF_SUCCESS; /* Shut up MSVC. */
    975 
    976     for (int i = 0; i < RT_ELEMENTS(apwszTryInstallSections); i++)
    977     {
    978         PRTUTF16 const pwszSection = apwszTryInstallSections[i];
    979 
    980         rc = vboxWinDrvInstallInfSectionEx(pCtx, pParms->pwszInfFile, pwszSection);
    981         if (RT_SUCCESS(rc))
    982             break;
    983 
    984         if (rc != VERR_NOT_FOUND)
    985             vboxWinDrvInstLogError(pCtx, "Installing INF section failed with %Rrc", rc);
    986     }
    987 
    988     if (rc == VERR_NOT_FOUND)
    989     {
    990         vboxWinDrvInstLogWarn(pCtx, "No matching installation section found -- buggy driver?");
    991         rc = VINF_SUCCESS;
    992     }
    993 
    994     return rc;
     1033 * Callback implementation for invoking a section for installation.
     1034 *
     1035 * @returns VBox status code.
     1036 * @param   pwszInfPathAbs      Absolute path of INF file to use.
     1037 * @param   pwszSection         Section to invoke.
     1038 * @param   pvCtx               User-supplied pointer. Usually PVBOXWINDRVINSTINTERNAL.
     1039 */
     1040DECLCALLBACK(int) vboxWinDrvInstallTryInfSectionCallback(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx)
     1041{
     1042    PVBOXWINDRVINSTINTERNAL pCtx = (PVBOXWINDRVINSTINTERNAL)pvCtx;
     1043
     1044    return vboxWinDrvInstallInfSectionEx(pCtx, pwszInfPathAbs, pwszSection);
    9951045}
    9961046
     
    10341084                    rc = vboxWinDrvParmsDetermine(pCtx, pParms, true /* fForce */);
    10351085                    if (RT_SUCCESS(rc))
    1036                         /* rc ignored, keep going */ vboxWinDrvInstallTryInfSections(pCtx, pParms);
     1086                        /* rc ignored, keep going */ vboxWinDrvTryInfSection(pCtx,
     1087                                                                             pParms->pwszInfFile, pParms->u.UnInstall.pwszModel,
     1088                                                                             vboxWinDrvInstallTryInfSectionCallback);
    10371089                }
    10381090                else
     
    12711323
    12721324/**
    1273  * Tries probing a list of well-known sections for uninstallation and will uninstall the first one found.
    1274  *
    1275  * @returns VBox status code.
    1276  * @param   pCtx                Windows driver installer context.
    1277  * @param   pParms              Windows driver uninstallation parameters to use.
    1278  * @param   pwszInfPathAbs      Absolute path of INF file to use for uninstallation.
    1279  */
    1280 static int vboxWinDrvUninstallTryInfSections(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms, PCRTUTF16 pwszInfPathAbs)
    1281 {
    1282     /* Sorted by most likely-ness. */
    1283     PRTUTF16 s_apwszTryInstallSections[] =
    1284     {
    1285         /* The more specific (using decorations), the better. Try these first. */
    1286         pParms->u.UnInstall.pwszModel,
    1287         /* Applies to primitive drivers. */
    1288         L"DefaultUninstall" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
    1289         L"DefaultUninstall"
    1290     };
    1291 
    1292     int rc = VINF_SUCCESS; /* Shut up MSVC. */
    1293 
    1294     for (int i = 0; i < RT_ELEMENTS(s_apwszTryInstallSections); i++)
    1295     {
    1296         PRTUTF16 const pwszSection = s_apwszTryInstallSections[i];
    1297 
    1298         rc = vboxWinDrvUninstallInfSectionEx(pCtx, pwszInfPathAbs, pwszSection);
    1299         if (RT_SUCCESS(rc))
    1300             break;
    1301 
    1302         if (rc == VERR_FILE_NOT_FOUND) /* File gone already. */
    1303         {
    1304             rc = VINF_SUCCESS;
    1305             break;
    1306         }
    1307 
    1308         if (rc != VERR_FILE_NOT_FOUND)
    1309             vboxWinDrvInstLogError(pCtx, "Uninstalling INF section failed with %Rrc", rc);
    1310     }
    1311 
    1312     if (rc == VERR_NOT_FOUND)
    1313     {
    1314         vboxWinDrvInstLogWarn(pCtx, "No matching uninstallation section found -- buggy driver?");
    1315         rc = VINF_SUCCESS;
    1316     }
    1317 
    1318     return rc;
     1325 * Callback implementation for invoking a section for uninstallation.
     1326 *
     1327 * @returns VBox status code.
     1328 * @param   pwszInfPathAbs      Absolute path of INF file to use.
     1329 * @param   pwszSection         Section to invoke.
     1330 * @param   pvCtx               User-supplied pointer. Usually PVBOXWINDRVINSTINTERNAL.
     1331 */
     1332DECLCALLBACK(int) vboxWinDrvUninstallTryInfSectionCallback(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx)
     1333{
     1334    PVBOXWINDRVINSTINTERNAL pCtx = (PVBOXWINDRVINSTINTERNAL)pvCtx;
     1335
     1336    return vboxWinDrvUninstallInfSectionEx(pCtx, pwszInfPathAbs, pwszSection);
    13191337}
    13201338
     
    13511369        vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" ...", wszInfPathAbs);
    13521370
     1371        /* rc ignored, keep going */ vboxWinDrvTryInfSection(pCtx, wszInfPathAbs, pCur->wszModel,
     1372                                                             vboxWinDrvUninstallTryInfSectionCallback);
     1373
    13531374        /*
    13541375         * Remove the driver from the driver store.
     
    13761397        }
    13771398
     1399        int rc2 = VINF_SUCCESS;
     1400
    13781401        if (fRc)
    13791402            vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" successful", wszInfPathAbs);
    13801403        else
    1381             rc = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs);
     1404            rc2 = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs);
    13821405
    13831406        /* If anything failed above, try removing stuff ourselves as good as we can. */
    1384         /* rc ignored, keep going */ vboxWinDrvUninstallTryInfSections(pCtx, pParms, wszInfPathAbs);
     1407        if (RT_FAILURE(rc2))
     1408            /* rc ignored, keep going */ vboxWinDrvTryInfSection(pCtx, wszInfPathAbs, pCur->wszModel,
     1409                                                                 vboxWinDrvUninstallTryInfSectionCallback);
     1410
     1411        if (RT_SUCCESS(rc)) /* Keep first error if already set. */
     1412            rc = rc2;
    13851413    }
    13861414
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