VirtualBox

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


Ignore:
Timestamp:
Nov 8, 2024 3:15:20 PM (2 months ago)
Author:
vboxsync
Message:

Windows driver installation: More cleanup, a few detection fixes. bugref:10762

Location:
trunk/src/VBox/GuestHost/installation
Files:
4 edited

Legend:

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

    r106869 r106890  
    6262
    6363/*********************************************************************************************************************************
    64 *   Structures and Typedefs                                                                                                      *
     64*   Prototypes                                                                                                                   *
    6565*********************************************************************************************************************************/
    66 
    67 
    68 /*********************************************************************************************************************************
    69 *   Global Variables                                                                                                             *
    70 *********************************************************************************************************************************/
    71 
    72 
    73 /*********************************************************************************************************************************
    74 *   Implementation                                                                                                               *
    75 *********************************************************************************************************************************/
    76 
     66static int vboxWinDrvInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx);
     67
     68
     69/**
     70 * Returns the type of an INF file.
     71 *
     72 * @returns Type of the INF file.
     73 * @param   hInf                INF handle to use.
     74 * @param   ppwszSection        Where to return main section of the driver.
     75 *                              Optional and can be NULL.
     76 */
     77VBOXWINDRVINFTYPE VBoxWinDrvInfGetTypeEx(HINF hInf, PRTUTF16 *ppwszSection)
     78{
     79    /*
     80     * Regular driver?
     81     */
     82
     83    /* Sorted by most likely-ness. */
     84    static PRTUTF16 s_apwszSections[] =
     85    {
     86        /* Most likely (and doesn't have a decoration). */
     87        L"Manufacturer",
     88        L"Manufacturer" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
     89    };
     90
     91    int rc;
     92
     93    INFCONTEXT InfCtx;
     94    size_t     i;
     95    for (i = 0; i < RT_ELEMENTS(s_apwszSections); i++)
     96    {
     97        PRTUTF16 const pwszSection = s_apwszSections[i];
     98        rc = vboxWinDrvInfQueryContext(hInf, pwszSection, NULL, &InfCtx);
     99        if (RT_SUCCESS(rc))
     100            break;
     101    }
     102
     103    if (RT_SUCCESS(rc))
     104    {
     105        if (ppwszSection)
     106            *ppwszSection = RTUtf16Dup(s_apwszSections[i]);
     107
     108        return VBOXWINDRVINFTYPE_NORMAL;
     109    }
     110
     111    /*
     112     * Primitive driver?
     113     */
     114
     115    /* Sorted by most likely-ness. */
     116    static PRTUTF16 s_apwszPrimitiveSections[] =
     117    {
     118        /* Most likely (and doesn't have a decoration). */
     119        L"DefaultInstall",
     120        L"DefaultInstall" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
     121        /** @todo Handle more specific decorations like "NTAMD64.6.3..10622". */
     122    };
     123
     124    for (i = 0; i < RT_ELEMENTS(s_apwszPrimitiveSections); i++)
     125    {
     126        PRTUTF16 const pwszSection = s_apwszPrimitiveSections[i];
     127        rc = vboxWinDrvInfQueryContext(hInf, pwszSection, NULL, &InfCtx);
     128        if (RT_SUCCESS(rc))
     129            break;
     130    }
     131
     132    if (RT_SUCCESS(rc))
     133    {
     134        if (ppwszSection)
     135            *ppwszSection = RTUtf16Dup(s_apwszPrimitiveSections[i]);
     136
     137        return VBOXWINDRVINFTYPE_PRIMITIVE;
     138    }
     139
     140    return VBOXWINDRVINFTYPE_INVALID;
     141}
     142
     143/**
     144 * Returns the type of an INF file.
     145 *
     146 * @returns Type of the INF file.
     147 * @param   hInf                INF handle to use.
     148 */
     149VBOXWINDRVINFTYPE VBoxWinDrvInfGetType(HINF hInf)
     150{
     151    return VBoxWinDrvInfGetTypeEx(hInf, NULL);
     152}
    77153
    78154/**
     
    85161 * @param   pCtx                Where to return the INF context on success.
    86162 */
    87 int VBoxWinDrvInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx)
     163static int vboxWinDrvInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx)
    88164{
    89165    if (!SetupFindFirstLineW(hInf, pwszSection, pwszKey, pCtx))
     
    113189        DWORD const dwErr = GetLastError();
    114190        if (dwErr != ERROR_INSUFFICIENT_BUFFER)
    115             return RTErrConvertFromWin32(dwErr);
     191            return VBoxWinDrvInstErrorFromWin32(dwErr);
    116192    }
    117193
     
    122198    {
    123199        RTMemFree(pwszValue);
    124         return RTErrConvertFromWin32(GetLastError());
     200        return VBoxWinDrvInstErrorFromWin32(GetLastError());
    125201    }
    126202
     
    133209
    134210/**
    135  * Queries a model name from an INF file.
     211 * Queries a model name from an INF section.
    136212 *
    137213 * @returns VBox status code.
    138214 * @retval  VERR_NOT_FOUND if no model has been found.
    139215 * @param   hInf                INF handle to use.
     216 * @param   pwszSection         Section to query model for.
    140217 * @param   uIndex              Index of model to query.
    141218 *                              Currently only the first model (index 0) is supported.
    142219 * @param   ppwszValue          Where to return the model name on success.
    143220 * @param   pcwcValue           Where to return the number of characters for \a ppwszValue. Optional an can be NULL.
    144  *
    145  * @note    Only for non-"primitive" drivers.
    146  */
    147 int VBoxWinDrvInfQueryModel(HINF hInf, unsigned uIndex, PRTUTF16 *ppwszValue, PDWORD pcwcValue)
    148 {
     221 */
     222int VBoxWinDrvInfQueryModelEx(HINF hInf, PCRTUTF16 pwszSection, unsigned uIndex, PRTUTF16 *ppwszValue, PDWORD pcwcValue)
     223{
     224    AssertPtrReturn(pwszSection, VERR_INVALID_POINTER);
    149225    AssertReturn(uIndex == 0, VERR_INVALID_PARAMETER);
    150226
     
    153229        *pcwcValue = 0;
    154230
    155     /* Sorted by most likely-ness. */
    156     static PRTUTF16 s_apwszSections[] =
    157     {
    158         /* Most likely (and doesn't have a decoration). */
    159         L"Manufacturer",
    160         L"Manufacturer" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
    161         /* Note: Don't search for "DefaultInstall" or "DefaultUninstall" sections here, as
    162          *       those only are used for "primitive" drivers. */
    163     };
    164 
    165231    int rc = VINF_SUCCESS;
    166232
    167233    INFCONTEXT InfCtx;
    168     for (int i = 0; i < RT_ELEMENTS(s_apwszSections); i++)
    169     {
    170         PRTUTF16 const pwszSection = s_apwszSections[i];
    171         rc = VBoxWinDrvInfQueryContext(hInf, pwszSection, NULL, &InfCtx);
    172         if (RT_SUCCESS(rc))
    173             break;
    174     }
    175 
     234    rc = vboxWinDrvInfQueryContext(hInf, pwszSection, NULL, &InfCtx);
    176235    if (RT_FAILURE(rc))
    177236        return rc;
     
    191250    if (RT_SUCCESS(rc)) /* Platform is optional. */
    192251    {
     252        /* Convert to uppercase first so that RTUtf16FindAscii() below works. */
     253        RTUtf16ToUpper(pwszPlatform);
     254
    193255        /* Note! The platform can be more specific, e.g. "NTAMD64.6.0". */
    194256        if (RTUtf16FindAscii(pwszPlatform, VBOXWINDRVINF_NT_NATIVE_ARCH_STR) == 0)
     
    243305{
    244306    INFCONTEXT InfCtx;
    245     int rc = VBoxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
     307    int rc = vboxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
    246308    if (RT_FAILURE(rc))
    247309        return rc;
     
    317379            }
    318380            else
    319                 rc = RTErrConvertFromWin32(GetLastError());
     381                rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
    320382        }
    321383        else /* Legacy INF files are not supported. */
     
    323385    }
    324386    else
    325         rc = RTErrConvertFromWin32(GetLastError());
     387        rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
    326388
    327389    RTMemFree(pInfo);
     
    353415    HINF hInf = SetupOpenInfFileW(pwszInfFile, pwszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
    354416    if (hInf == INVALID_HANDLE_VALUE)
    355         return RTErrConvertFromWin32(GetLastError());
     417        return VBoxWinDrvInstErrorFromWin32(GetLastError());
    356418
    357419    *phInf = hInf;
     
    380442    }
    381443    else
    382         rc = RTErrConvertFromWin32(GetLastError());
     444        rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
    383445
    384446    return rc;
     
    425487 * @retval  VERR_NOT_FOUND if no model has been found.
    426488 * @param   hInf                INF handle to use.
     489 * @param   pwszSection         Section to query model for.
    427490 * @param   ppwszModel          Where to return the model on success.
    428491 *                              Needs to be free'd by RTUtf16Free().
    429  *
    430  * @note    Only for non-"primitive" drivers.
    431  */
    432 int VBoxWinDrvInfQueryFirstModel(HINF hInf, PRTUTF16 *ppwszModel)
     492 */
     493int VBoxWinDrvInfQueryFirstModel(HINF hInf, PCRTUTF16 pwszSection, PRTUTF16 *ppwszModel)
    433494{
    434495    *ppwszModel = NULL;
    435496
    436     return VBoxWinDrvInfQueryModel(hInf, 0 /* Index */, ppwszModel, NULL);
     497    return VBoxWinDrvInfQueryModelEx(hInf, pwszSection, 0 /* Index */, ppwszModel, NULL);
    437498}
    438499
     
    446507 * @param   ppwszPnPId          Where to return the PnP ID on success.
    447508 *                              Needs to be free'd by RTUtf16Free().
    448  *
    449  * @note    Only for non-"primitive" drivers.
    450509 */
    451510int VBoxWinDrvInfQueryFirstPnPId(HINF hInf, PRTUTF16 pwszModel, PRTUTF16 *ppwszPnPId)
     
    458517    PRTUTF16   pwszPnPId = NULL;
    459518    INFCONTEXT InfCtx;
    460     int rc = VBoxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
     519    int rc = vboxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
    461520    if (RT_SUCCESS(rc))
    462521    {
     
    469528}
    470529
     530
     531/**
     532 * Returns a Setup API error as a string.
     533 *
     534 * Needded to get at least a minimally meaningful error string back from Setup API.
     535 *
     536 * @returns Setup API error as a string, or NULL if not found.
     537 * @param   dwErr               Error code to return as a string.
     538 */
     539const char *VBoxWinDrvSetupApiErrToStr(const DWORD dwErr)
     540{
     541    switch (dwErr)
     542    {
     543        RT_CASE_RET_STR(ERROR_EXPECTED_SECTION_NAME             );
     544        RT_CASE_RET_STR(ERROR_BAD_SECTION_NAME_LINE             );
     545        RT_CASE_RET_STR(ERROR_SECTION_NAME_TOO_LONG             );
     546        RT_CASE_RET_STR(ERROR_GENERAL_SYNTAX                    );
     547        RT_CASE_RET_STR(ERROR_WRONG_INF_STYLE                   );
     548        RT_CASE_RET_STR(ERROR_SECTION_NOT_FOUND                 );
     549        RT_CASE_RET_STR(ERROR_LINE_NOT_FOUND                    );
     550        RT_CASE_RET_STR(ERROR_NO_BACKUP                         );
     551        RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_CLASS               );
     552        RT_CASE_RET_STR(ERROR_CLASS_MISMATCH                    );
     553        RT_CASE_RET_STR(ERROR_DUPLICATE_FOUND                   );
     554        RT_CASE_RET_STR(ERROR_NO_DRIVER_SELECTED                );
     555        RT_CASE_RET_STR(ERROR_KEY_DOES_NOT_EXIST                );
     556        RT_CASE_RET_STR(ERROR_INVALID_DEVINST_NAME              );
     557        RT_CASE_RET_STR(ERROR_INVALID_CLASS                     );
     558        RT_CASE_RET_STR(ERROR_DEVINST_ALREADY_EXISTS            );
     559        RT_CASE_RET_STR(ERROR_DEVINFO_NOT_REGISTERED            );
     560        RT_CASE_RET_STR(ERROR_INVALID_REG_PROPERTY              );
     561        RT_CASE_RET_STR(ERROR_NO_INF                            );
     562        RT_CASE_RET_STR(ERROR_NO_SUCH_DEVINST                   );
     563        RT_CASE_RET_STR(ERROR_CANT_LOAD_CLASS_ICON              );
     564        RT_CASE_RET_STR(ERROR_INVALID_CLASS_INSTALLER           );
     565        RT_CASE_RET_STR(ERROR_DI_DO_DEFAULT                     );
     566        RT_CASE_RET_STR(ERROR_DI_NOFILECOPY                     );
     567        RT_CASE_RET_STR(ERROR_INVALID_HWPROFILE                 );
     568        RT_CASE_RET_STR(ERROR_NO_DEVICE_SELECTED                );
     569        RT_CASE_RET_STR(ERROR_DEVINFO_LIST_LOCKED               );
     570        RT_CASE_RET_STR(ERROR_DEVINFO_DATA_LOCKED               );
     571        RT_CASE_RET_STR(ERROR_DI_BAD_PATH                       );
     572        RT_CASE_RET_STR(ERROR_NO_CLASSINSTALL_PARAMS            );
     573        RT_CASE_RET_STR(ERROR_FILEQUEUE_LOCKED                  );
     574        RT_CASE_RET_STR(ERROR_BAD_SERVICE_INSTALLSECT           );
     575        RT_CASE_RET_STR(ERROR_NO_CLASS_DRIVER_LIST              );
     576        RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_SERVICE             );
     577        RT_CASE_RET_STR(ERROR_NO_DEFAULT_DEVICE_INTERFACE       );
     578        RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_ACTIVE           );
     579        RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_REMOVED          );
     580        RT_CASE_RET_STR(ERROR_BAD_INTERFACE_INSTALLSECT         );
     581        RT_CASE_RET_STR(ERROR_NO_SUCH_INTERFACE_CLASS           );
     582        RT_CASE_RET_STR(ERROR_INVALID_REFERENCE_STRING          );
     583        RT_CASE_RET_STR(ERROR_INVALID_MACHINENAME               );
     584        RT_CASE_RET_STR(ERROR_REMOTE_COMM_FAILURE               );
     585        RT_CASE_RET_STR(ERROR_MACHINE_UNAVAILABLE               );
     586        RT_CASE_RET_STR(ERROR_NO_CONFIGMGR_SERVICES             );
     587        RT_CASE_RET_STR(ERROR_INVALID_PROPPAGE_PROVIDER         );
     588        RT_CASE_RET_STR(ERROR_NO_SUCH_DEVICE_INTERFACE          );
     589        RT_CASE_RET_STR(ERROR_DI_POSTPROCESSING_REQUIRED        );
     590        RT_CASE_RET_STR(ERROR_INVALID_COINSTALLER               );
     591        RT_CASE_RET_STR(ERROR_NO_COMPAT_DRIVERS                 );
     592        RT_CASE_RET_STR(ERROR_NO_DEVICE_ICON                    );
     593        RT_CASE_RET_STR(ERROR_INVALID_INF_LOGCONFIG             );
     594        RT_CASE_RET_STR(ERROR_DI_DONT_INSTALL                   );
     595        RT_CASE_RET_STR(ERROR_INVALID_FILTER_DRIVER             );
     596        RT_CASE_RET_STR(ERROR_NON_WINDOWS_NT_DRIVER             );
     597        RT_CASE_RET_STR(ERROR_NON_WINDOWS_DRIVER                );
     598        RT_CASE_RET_STR(ERROR_NO_CATALOG_FOR_OEM_INF            );
     599        RT_CASE_RET_STR(ERROR_DEVINSTALL_QUEUE_NONNATIVE        );
     600        RT_CASE_RET_STR(ERROR_NOT_DISABLEABLE                   );
     601        RT_CASE_RET_STR(ERROR_CANT_REMOVE_DEVINST               );
     602        RT_CASE_RET_STR(ERROR_INVALID_TARGET                    );
     603        RT_CASE_RET_STR(ERROR_DRIVER_NONNATIVE                  );
     604        RT_CASE_RET_STR(ERROR_IN_WOW64                          );
     605        RT_CASE_RET_STR(ERROR_SET_SYSTEM_RESTORE_POINT          );
     606        RT_CASE_RET_STR(ERROR_SCE_DISABLED                      );
     607        RT_CASE_RET_STR(ERROR_UNKNOWN_EXCEPTION                 );
     608        RT_CASE_RET_STR(ERROR_PNP_REGISTRY_ERROR                );
     609        RT_CASE_RET_STR(ERROR_REMOTE_REQUEST_UNSUPPORTED        );
     610        RT_CASE_RET_STR(ERROR_NOT_AN_INSTALLED_OEM_INF          );
     611        RT_CASE_RET_STR(ERROR_INF_IN_USE_BY_DEVICES             );
     612        RT_CASE_RET_STR(ERROR_DI_FUNCTION_OBSOLETE              );
     613        RT_CASE_RET_STR(ERROR_NO_AUTHENTICODE_CATALOG           );
     614        RT_CASE_RET_STR(ERROR_AUTHENTICODE_DISALLOWED           );
     615        RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUSTED_PUBLISHER    );
     616        RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED);
     617        RT_CASE_RET_STR(ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED);
     618        RT_CASE_RET_STR(ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH    );
     619        RT_CASE_RET_STR(ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE    );
     620        RT_CASE_RET_STR(ERROR_DEVICE_INSTALLER_NOT_READY        );
     621        RT_CASE_RET_STR(ERROR_DRIVER_STORE_ADD_FAILED           );
     622        RT_CASE_RET_STR(ERROR_DEVICE_INSTALL_BLOCKED            );
     623        RT_CASE_RET_STR(ERROR_DRIVER_INSTALL_BLOCKED            );
     624        RT_CASE_RET_STR(ERROR_WRONG_INF_TYPE                    );
     625        RT_CASE_RET_STR(ERROR_FILE_HASH_NOT_IN_CATALOG          );
     626        RT_CASE_RET_STR(ERROR_DRIVER_STORE_DELETE_FAILED        );
     627        RT_CASE_RET_STR(ERROR_NOT_INSTALLED                     );
     628        default:
     629            break;
     630    }
     631
     632    return NULL;
     633}
     634
     635/**
     636 * Returns a winerr.h error as a string.
     637 *
     638 * Needded to get at least a minimally meaningful error string back.
     639 *
     640 * @returns Error as a string, or NULL if not found.
     641 * @param   dwErr               Error code to return as a string.
     642 */
     643const char *VBoxWinDrvWinErrToStr(const DWORD dwErr)
     644{
     645    switch (dwErr)
     646    {
     647        RT_CASE_RET_STR(ERROR_BADKEY                            );
     648        RT_CASE_RET_STR(ERROR_SERVICE_MARKED_FOR_DELETE         );
     649        default:
     650            break;
     651    }
     652
     653    return NULL;
     654}
     655
     656/**
     657 * Translates a native Windows error code to a VBox one.
     658 *
     659 * @returns VBox status code.
     660 * @retval  VERR_UNRESOLVED_ERROR if no translation was possible.
     661 * @param   uNativeCode         Native Windows error code to translate.
     662 */
     663int VBoxWinDrvInstErrorFromWin32(unsigned uNativeCode)
     664{
     665#ifdef DEBUG_andy
     666    bool const fAssertMayPanic = RTAssertMayPanic();
     667    RTAssertSetMayPanic(false);
     668#endif
     669
     670    const char *pszErr = VBoxWinDrvSetupApiErrToStr(uNativeCode);
     671    if (!pszErr)
     672        VBoxWinDrvWinErrToStr(uNativeCode);
     673
     674    int const rc = RTErrConvertFromWin32(uNativeCode);
     675    if (rc == VERR_UNRESOLVED_ERROR)
     676        AssertMsgFailed(("Unhandled error %u (%#x): %s\n", uNativeCode, uNativeCode, pszErr ? pszErr : "<Unknown>"));
     677
     678#ifdef DEBUG_andy
     679    RTAssertSetMayPanic(fAssertMayPanic);
     680#endif
     681    return rc;
     682}
     683
  • trunk/src/VBox/GuestHost/installation/VBoxWinDrvCommon.h

    r106869 r106890  
    3939#include <VBox/GuestHost/VBoxWinDrvDefs.h>
    4040
     41/**
     42 * Enumeration specifying the INF (driver) type.
     43 */
     44typedef enum VBOXWINDRVINFTYPE
     45{
     46    /** Invalid type. */
     47    VBOXWINDRVINFTYPE_INVALID = 0,
     48    /** Primitive driver.
     49     *  This uses a "DefaultInstall" (plus optionally "DefaultUninstall") sections
     50     *  and does not have a PnP ID. */
     51    VBOXWINDRVINFTYPE_PRIMITIVE,
     52    /** Normal driver.
     53     *  Uses a "Manufacturer" section and can have a PnP ID. */
     54    VBOXWINDRVINFTYPE_NORMAL
     55} VBOXWINDRVINFTYPE;
     56
    4157int VBoxWinDrvInfOpenEx(PCRTUTF16 pwszInfFile, PRTUTF16 pwszClassName, HINF *phInf);
    4258int VBoxWinDrvInfOpen(PCRTUTF16 pwszInfFile, HINF *phInf);
    4359int VBoxWinDrvInfOpenUtf8(const char *pszInfFile, HINF *phInf);
    4460int VBoxWinDrvInfClose(HINF hInf);
    45 int VBoxWinDrvInfQueryFirstModel(HINF hInf, PRTUTF16 *ppwszModel);
     61VBOXWINDRVINFTYPE VBoxWinDrvInfGetTypeEx(HINF hInf, PRTUTF16 *ppwszSection);
     62VBOXWINDRVINFTYPE VBoxWinDrvInfGetType(HINF hInf);
     63int VBoxWinDrvInfQueryFirstModel(HINF hInf, PCRTUTF16 pwszSection, PRTUTF16 *ppwszModel);
    4664int VBoxWinDrvInfQueryFirstPnPId(HINF hInf, PRTUTF16 pwszModel, PRTUTF16 *ppwszPnPId);
    4765int VBoxWinDrvInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, PRTUTF16 *ppwszValue, PDWORD pcwcValue);
    48 int VBoxWinDrvInfQueryModel(HINF hInf, PRTUTF16 *ppwszValue, PDWORD pcwcValue);
     66int VBoxWinDrvInfQueryModelEx(HINF hInf, PCRTUTF16 pwszSection, unsigned uIndex, PRTUTF16 *ppwszValue, PDWORD pcwcValue);
     67int VBoxWinDrvInfQueryModel(HINF hInf, PCRTUTF16 pwszSection, unsigned uIndex, PRTUTF16 *ppwszValue, PDWORD pcwcValue);
    4968int VBoxWinDrvInfQueryInstallSectionEx(HINF hInf, PCRTUTF16 pwszModel, PRTUTF16 *ppwszValue, PDWORD pcwcValue);
    5069int VBoxWinDrvInfQueryInstallSection(HINF hInf, PCRTUTF16 pwszModel, PRTUTF16 *ppwszValue);
     
    5271int VBoxWinDrvInfQuerySectionVer(HINF hInf, PVBOXWINDRVINFSEC_VERSION pVer);
    5372
     73const char *VBoxWinDrvSetupApiErrToStr(const DWORD dwErr);
     74const char *VBoxWinDrvWinErrToStr(const DWORD dwErr);
     75int VBoxWinDrvInstErrorFromWin32(unsigned uNativeCode);
     76
    5477#endif /* !VBOX_INCLUDED_SRC_installation_VBoxWinDrvCommon_h */
    5578
  • trunk/src/VBox/GuestHost/installation/VBoxWinDrvInst.cpp

    r106868 r106890  
    169169    /** INF file to use for (un)installation. */
    170170    PRTUTF16           pwszInfFile;
    171     /** Indicator whether (un)installation parameters were determined from the INF file or not. */
    172     bool               fDeterminedFromInfFile;
    173171    /** Union keeping specific parameters, depending on \a enmMode. */
    174172    union
     
    180178            /** Hardware (Pnp) ID; optional and might be NULL. */
    181179            PRTUTF16   pwszPnpId;
     180            /** Name of section to install. */
     181            PRTUTF16   pwszSection;
    182182        } UnInstall;
    183183        struct
     
    393393
    394394/**
    395  * Returns a Setup API error as a string.
    396  *
    397  * Needded to get at least a minimally meaningful error string back from Setup API.
    398  *
    399  * @returns Setup API error as a string, or NULL if not found.
    400  * @param   dwErr               Error code to return as a string.
    401  */
    402 DECLINLINE(const char *) vboxWinDrvSetupApiErrToStr(const DWORD dwErr)
    403 {
    404     switch (dwErr)
    405     {
    406         RT_CASE_RET_STR(ERROR_EXPECTED_SECTION_NAME             );
    407         RT_CASE_RET_STR(ERROR_BAD_SECTION_NAME_LINE             );
    408         RT_CASE_RET_STR(ERROR_SECTION_NAME_TOO_LONG             );
    409         RT_CASE_RET_STR(ERROR_GENERAL_SYNTAX                    );
    410         RT_CASE_RET_STR(ERROR_WRONG_INF_STYLE                   );
    411         RT_CASE_RET_STR(ERROR_SECTION_NOT_FOUND                 );
    412         RT_CASE_RET_STR(ERROR_LINE_NOT_FOUND                    );
    413         RT_CASE_RET_STR(ERROR_NO_BACKUP                         );
    414         RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_CLASS               );
    415         RT_CASE_RET_STR(ERROR_CLASS_MISMATCH                    );
    416         RT_CASE_RET_STR(ERROR_DUPLICATE_FOUND                   );
    417         RT_CASE_RET_STR(ERROR_NO_DRIVER_SELECTED                );
    418         RT_CASE_RET_STR(ERROR_KEY_DOES_NOT_EXIST                );
    419         RT_CASE_RET_STR(ERROR_INVALID_DEVINST_NAME              );
    420         RT_CASE_RET_STR(ERROR_INVALID_CLASS                     );
    421         RT_CASE_RET_STR(ERROR_DEVINST_ALREADY_EXISTS            );
    422         RT_CASE_RET_STR(ERROR_DEVINFO_NOT_REGISTERED            );
    423         RT_CASE_RET_STR(ERROR_INVALID_REG_PROPERTY              );
    424         RT_CASE_RET_STR(ERROR_NO_INF                            );
    425         RT_CASE_RET_STR(ERROR_NO_SUCH_DEVINST                   );
    426         RT_CASE_RET_STR(ERROR_CANT_LOAD_CLASS_ICON              );
    427         RT_CASE_RET_STR(ERROR_INVALID_CLASS_INSTALLER           );
    428         RT_CASE_RET_STR(ERROR_DI_DO_DEFAULT                     );
    429         RT_CASE_RET_STR(ERROR_DI_NOFILECOPY                     );
    430         RT_CASE_RET_STR(ERROR_INVALID_HWPROFILE                 );
    431         RT_CASE_RET_STR(ERROR_NO_DEVICE_SELECTED                );
    432         RT_CASE_RET_STR(ERROR_DEVINFO_LIST_LOCKED               );
    433         RT_CASE_RET_STR(ERROR_DEVINFO_DATA_LOCKED               );
    434         RT_CASE_RET_STR(ERROR_DI_BAD_PATH                       );
    435         RT_CASE_RET_STR(ERROR_NO_CLASSINSTALL_PARAMS            );
    436         RT_CASE_RET_STR(ERROR_FILEQUEUE_LOCKED                  );
    437         RT_CASE_RET_STR(ERROR_BAD_SERVICE_INSTALLSECT           );
    438         RT_CASE_RET_STR(ERROR_NO_CLASS_DRIVER_LIST              );
    439         RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_SERVICE             );
    440         RT_CASE_RET_STR(ERROR_NO_DEFAULT_DEVICE_INTERFACE       );
    441         RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_ACTIVE           );
    442         RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_REMOVED          );
    443         RT_CASE_RET_STR(ERROR_BAD_INTERFACE_INSTALLSECT         );
    444         RT_CASE_RET_STR(ERROR_NO_SUCH_INTERFACE_CLASS           );
    445         RT_CASE_RET_STR(ERROR_INVALID_REFERENCE_STRING          );
    446         RT_CASE_RET_STR(ERROR_INVALID_MACHINENAME               );
    447         RT_CASE_RET_STR(ERROR_REMOTE_COMM_FAILURE               );
    448         RT_CASE_RET_STR(ERROR_MACHINE_UNAVAILABLE               );
    449         RT_CASE_RET_STR(ERROR_NO_CONFIGMGR_SERVICES             );
    450         RT_CASE_RET_STR(ERROR_INVALID_PROPPAGE_PROVIDER         );
    451         RT_CASE_RET_STR(ERROR_NO_SUCH_DEVICE_INTERFACE          );
    452         RT_CASE_RET_STR(ERROR_DI_POSTPROCESSING_REQUIRED        );
    453         RT_CASE_RET_STR(ERROR_INVALID_COINSTALLER               );
    454         RT_CASE_RET_STR(ERROR_NO_COMPAT_DRIVERS                 );
    455         RT_CASE_RET_STR(ERROR_NO_DEVICE_ICON                    );
    456         RT_CASE_RET_STR(ERROR_INVALID_INF_LOGCONFIG             );
    457         RT_CASE_RET_STR(ERROR_DI_DONT_INSTALL                   );
    458         RT_CASE_RET_STR(ERROR_INVALID_FILTER_DRIVER             );
    459         RT_CASE_RET_STR(ERROR_NON_WINDOWS_NT_DRIVER             );
    460         RT_CASE_RET_STR(ERROR_NON_WINDOWS_DRIVER                );
    461         RT_CASE_RET_STR(ERROR_NO_CATALOG_FOR_OEM_INF            );
    462         RT_CASE_RET_STR(ERROR_DEVINSTALL_QUEUE_NONNATIVE        );
    463         RT_CASE_RET_STR(ERROR_NOT_DISABLEABLE                   );
    464         RT_CASE_RET_STR(ERROR_CANT_REMOVE_DEVINST               );
    465         RT_CASE_RET_STR(ERROR_INVALID_TARGET                    );
    466         RT_CASE_RET_STR(ERROR_DRIVER_NONNATIVE                  );
    467         RT_CASE_RET_STR(ERROR_IN_WOW64                          );
    468         RT_CASE_RET_STR(ERROR_SET_SYSTEM_RESTORE_POINT          );
    469         RT_CASE_RET_STR(ERROR_SCE_DISABLED                      );
    470         RT_CASE_RET_STR(ERROR_UNKNOWN_EXCEPTION                 );
    471         RT_CASE_RET_STR(ERROR_PNP_REGISTRY_ERROR                );
    472         RT_CASE_RET_STR(ERROR_REMOTE_REQUEST_UNSUPPORTED        );
    473         RT_CASE_RET_STR(ERROR_NOT_AN_INSTALLED_OEM_INF          );
    474         RT_CASE_RET_STR(ERROR_INF_IN_USE_BY_DEVICES             );
    475         RT_CASE_RET_STR(ERROR_DI_FUNCTION_OBSOLETE              );
    476         RT_CASE_RET_STR(ERROR_NO_AUTHENTICODE_CATALOG           );
    477         RT_CASE_RET_STR(ERROR_AUTHENTICODE_DISALLOWED           );
    478         RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUSTED_PUBLISHER    );
    479         RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED);
    480         RT_CASE_RET_STR(ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED);
    481         RT_CASE_RET_STR(ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH    );
    482         RT_CASE_RET_STR(ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE    );
    483         RT_CASE_RET_STR(ERROR_DEVICE_INSTALLER_NOT_READY        );
    484         RT_CASE_RET_STR(ERROR_DRIVER_STORE_ADD_FAILED           );
    485         RT_CASE_RET_STR(ERROR_DEVICE_INSTALL_BLOCKED            );
    486         RT_CASE_RET_STR(ERROR_DRIVER_INSTALL_BLOCKED            );
    487         RT_CASE_RET_STR(ERROR_WRONG_INF_TYPE                    );
    488         RT_CASE_RET_STR(ERROR_FILE_HASH_NOT_IN_CATALOG          );
    489         RT_CASE_RET_STR(ERROR_DRIVER_STORE_DELETE_FAILED        );
    490         RT_CASE_RET_STR(ERROR_NOT_INSTALLED                     );
    491         default:
    492             break;
    493     }
    494 
    495     return NULL;
    496 }
    497 
    498 /**
    499  * Returns a winerr.h error as a string.
    500  *
    501  * Needded to get at least a minimally meaningful error string back.
    502  *
    503  * @returns Error as a string, or NULL if not found.
    504  * @param   dwErr               Error code to return as a string.
    505  */
    506 DECLINLINE(const char *) vboxWinDrvWinErrToStr(const DWORD dwErr)
    507 {
    508     switch (dwErr)
    509     {
    510 
    511         RT_CASE_RET_STR(ERROR_BADKEY                            );
    512         default:
    513             break;
    514     }
    515 
    516     return NULL;
    517 }
    518 
    519 /**
    520395 * Logs the last Windows error given via GetLastError().
    521396 *
     
    544419
    545420    /* Try resolving Setup API errors first (we don't handle those in IPRT). */
    546     const char *pszErr = vboxWinDrvSetupApiErrToStr(dwErr);
     421    const char *pszErr = VBoxWinDrvSetupApiErrToStr(dwErr);
    547422    if (!pszErr) /* Also ask for special winerr.h codes we don't handle in IPRT. */
    548         pszErr = vboxWinDrvWinErrToStr(dwErr);
     423        pszErr = VBoxWinDrvWinErrToStr(dwErr);
    549424    if (!pszErr)
    550425        rc = RTErrConvertFromWin32(dwErr);
     
    579454{
    580455    int rc = RTLdrGetSymbol(hMod, pszSymbol, pfnFunc);
    581     if (RT_SUCCESS(rc))
    582     {
    583         vboxWinDrvInstLogVerbose(pCtx, 4, "Resolving symbol \"%s\"  ...", pszSymbol, rc);
    584     }
    585     else
     456    if (RT_FAILURE(rc))
    586457    {
    587458        vboxWinDrvInstLogVerbose(pCtx, 1, "Warning: Symbol \"%s\" not found (%Rrc)", pszSymbol, rc);
     
    674545            RTUtf16Free(pParms->u.UnInstall.pwszPnpId);
    675546            pParms->u.UnInstall.pwszPnpId = NULL;
     547            RTUtf16Free(pParms->u.UnInstall.pwszSection);
     548            pParms->u.UnInstall.pwszSection = NULL;
    676549            break;
    677550        }
     
    989862    }
    990863    else
    991         rc = vboxWinDrvInstLogLastError(pCtx, "Installing INF section \"%ls\" failed", pwszSection);
     864    {
     865        DWORD const dwErr = GetLastError();
     866        /* Seems like newer Windows OSes (seen on Win10) don't like undecorated sections with SetupInstallFromInfSectionW().
     867         * So ignore this and continue. */
     868        if (dwErr == ERROR_BADKEY)
     869        {
     870            vboxWinDrvInstLogVerbose(pCtx, 1, "Installing INF section \"%ls\" failed with %#x (%d), ignoring",
     871                                     pwszSection, dwErr, dwErr);
     872        }
     873        else
     874           rc = vboxWinDrvInstLogLastError(pCtx, "Installing INF section \"%ls\" failed", pwszSection);
     875    }
    992876
    993877    /*
    994      * Install services (if any).
     878     * Try install services.
    995879     */
    996880    RTUTF16 wszSection[64];
    997881    ssize_t const cwchSection = RTUtf16Printf(wszSection, RT_ELEMENTS(wszSection),
    998                                               "%ls%s", pwszSection, ".Services");
     882                                              "%ls%ls%s", pwszSection, VBOXWINDRVINF_DECORATION_SEP_UTF16_STR, "Services");
    999883    if (cwchSection > 0)
    1000884    {
     
    1022906                     *       'sc query <service name> won't show this, however.
    1023907                     *       Use 'sc delete <service name>' to delete the leftover. */
    1024                     vboxWinDrvInstLogError(pCtx,
    1025                                            "Hint: An old service (SCM) entry might be dangling around.\n"
    1026                                            "Try removing it via 'sc delete <service name>' and try again.");
     908                    vboxWinDrvInstLogError(pCtx, "An old service (SCM) entry might be dangling around.");
     909                    vboxWinDrvInstLogInfo (pCtx, "Try removing it via 'sc delete <service name>' and try again.");
    1027910                }
    1028911            }
     
    1114997            BOOL fRc = FALSE;
    1115998            BOOL fReboot = FALSE;
    1116 
    1117             if (pParms->u.UnInstall.pwszPnpId)
    1118                 vboxWinDrvInstLogInfo(pCtx, "Using PnP ID \"%ls\"", pParms->u.UnInstall.pwszPnpId);
    1119999
    11201000            uint64_t const uNtVer = RTSystemGetNtVersion();
     
    11531033
    11541034                if (fRc)
    1155                 {
    11561035                    rc = vboxWinDrvTryInfSection(pCtx,
    1157                                                  pParms->pwszInfFile, pParms->u.UnInstall.pwszModel,
     1036                                                 pParms->pwszInfFile, pParms->u.UnInstall.pwszSection,
    11581037                                                 vboxWinDrvInstallTryInfSectionCallback);
    1159                 }
    11601038            }
    11611039            else /* For Windows 2000 and below. */
    11621040            {
    1163                 bool fPreInstall     = false; /* Whether to pre-install the driver. */
    1164                 bool fInstallSection = false; /* Whether to install the section of the specified driver model. */
    1165 
    11661041                if (pParms->u.UnInstall.pwszPnpId)
    11671042                {
     
    11931068                                vboxWinDrvInstLogInfo(pCtx, "Device (\"%ls\") not found (yet), pre-installing driver ...",
    11941069                                                      pParms->u.UnInstall.pwszPnpId);
    1195                                 fPreInstall     = true;
    1196                                 fInstallSection = true;
    11971070                                break;
    11981071                            }
     
    12011074                            {
    12021075                                vboxWinDrvInstLogWarn(pCtx, "Not able to select a driver from the given INF, using given model");
    1203                                 fPreInstall     = true;
    1204                                 fInstallSection = true;
    12051076                                break;
    12061077                            }
     
    12121083                    }
    12131084                }
     1085
     1086                if (RT_FAILURE(rc))
     1087                    break;
     1088
     1089                /*
     1090                 * Pre-install driver.
     1091                 */
     1092                RTUTF16 wszInfFileAbs[RTPATH_MAX] = { 0 };
     1093                LPWSTR  pwszInfFile = NULL;
     1094                if (   GetFullPathNameW(pParms->pwszInfFile, RT_ELEMENTS(wszInfFileAbs), wszInfFileAbs, &pwszInfFile)
     1095                    && pwszInfFile)
     1096                {
     1097                    RTUTF16 wszSrcPathAbs[RTPATH_MAX] = { 0 };
     1098                    rc = RTUtf16CopyEx(wszSrcPathAbs, RT_ELEMENTS(wszSrcPathAbs), wszInfFileAbs,
     1099                                       RTUtf16Len(wszInfFileAbs) - RTUtf16Len(pwszInfFile));
     1100                    if (RT_SUCCESS(rc))
     1101                    {
     1102                        RTUTF16 wszDstPathAbs[RTPATH_MAX] = { 0 };
     1103                        fRc = g_pfnSetupCopyOEMInfW(wszInfFileAbs, wszSrcPathAbs, SPOST_PATH, 0,
     1104                                                    wszDstPathAbs, RT_ELEMENTS(wszDstPathAbs), NULL, NULL);
     1105
     1106                        vboxWinDrvInstLogVerbose(pCtx, 1, "   INF file: %ls", wszInfFileAbs);
     1107                        vboxWinDrvInstLogVerbose(pCtx, 1, "Source path: %ls", wszSrcPathAbs);
     1108                        vboxWinDrvInstLogVerbose(pCtx, 1, "  Dest path: %ls", wszDstPathAbs);
     1109
     1110                        if (fRc)
     1111                            vboxWinDrvInstLogInfo(pCtx, "Copying OEM INF successful");
     1112                        else
     1113                            rc = vboxWinDrvInstLogLastError(pCtx, "Installation(SetupCopyOEMInfW) failed");
     1114                    }
     1115                }
    12141116                else
     1117                    rc = vboxWinDrvInstLogLastError(pCtx, "GetFullPathNameW() failed");
     1118
     1119                rc = vboxWinDrvTryInfSection(pCtx,
     1120                                             pParms->pwszInfFile, pParms->u.UnInstall.pwszSection,
     1121                                             vboxWinDrvInstallTryInfSectionCallback);
     1122            }
     1123
     1124            if (RT_FAILURE(rc))
     1125                break;
     1126
     1127            pCtx->fReboot = RT_BOOL(fReboot);
     1128            break;
     1129        }
     1130
     1131        case VBOXWINDRVINSTMODE_INSTALL_INFSECTION:
     1132        {
     1133            rc = vboxWinDrvInstallInfSection(pCtx, pParms);
     1134            break;
     1135        }
     1136
     1137        default:
     1138            break;
     1139    }
     1140
     1141    return rc;
     1142}
     1143
     1144/**
     1145 * Returns whether the given (in)installation parameters are valid or not.
     1146 *
     1147 * @returns \c true if valid, \c false if not.
     1148 * @param   pCtx                Windows driver installer context.
     1149 * @param   pParms              Windows driver (un)installation parameters to validate.
     1150 */
     1151static bool vboxWinDrvParmsAreValid(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms)
     1152{
     1153    if (pParms->u.UnInstall.pwszPnpId)
     1154    {
     1155        size_t const cchPnpId = RTUtf16Len(pParms->u.UnInstall.pwszPnpId);
     1156        if (   !cchPnpId
     1157            || cchPnpId > MAX_DEVICE_ID_LEN)
     1158        {
     1159            vboxWinDrvInstLogVerbose(pCtx, 1, "PnP ID not specified explicitly or invalid");
     1160            return false;
     1161        }
     1162    }
     1163
     1164    return true;
     1165}
     1166
     1167/**
     1168 * Determines (un)installation parameters from a given set of parameters, logged.
     1169 *
     1170 * @returns VBox status code.
     1171 * @retval  VERR_INVALID_PARAMETER if no valid parameters could be determined.
     1172 * @param   pCtx                Windows driver installer context.
     1173 * @param   pParms              Windows driver installation parameters to determine for.
     1174 * @param   fForce              Whether to overwrite already set parameters or not.
     1175 *
     1176 * @note    Only can deal with the first model / PnP ID found for now.
     1177 */
     1178static int vboxWinDrvParmsDetermine(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms, bool fForce)
     1179{
     1180    int rc;
     1181
     1182    /* INF file given? */
     1183    if (pParms->pwszInfFile)
     1184    {
     1185        HINF hInf;
     1186        rc = VBoxWinDrvInfOpen(pParms->pwszInfFile, &hInf);
     1187        if (RT_SUCCESS(rc))
     1188        {
     1189            /* Get the INF type first. */
     1190            PRTUTF16 pwszMainSection;
     1191            VBOXWINDRVINFTYPE enmType = VBoxWinDrvInfGetTypeEx(hInf, &pwszMainSection);
     1192            if (enmType != VBOXWINDRVINFTYPE_INVALID)
     1193            {
     1194                vboxWinDrvInstLogVerbose(pCtx, 1, "INF type is: %s",
     1195                                           enmType == VBOXWINDRVINFTYPE_NORMAL
     1196                                         ? "Normal" : "Primitive");
     1197                /*
     1198                 * Determine model.
     1199                 */
     1200                if (   !pParms->u.UnInstall.pwszModel
     1201                    || fForce)
    12151202                {
    1216                     fPreInstall     = true;
    1217                     fInstallSection = true;
    1218                 }
    1219 
    1220                 if (fPreInstall)
    1221                 {
    1222                     RTUTF16 wszInfFileAbs[RTPATH_MAX] = { 0 };
    1223                     LPWSTR  pwszInfFile = NULL;
    1224                     if (   GetFullPathNameW(pParms->pwszInfFile, RT_ELEMENTS(wszInfFileAbs), wszInfFileAbs, &pwszInfFile)
    1225                         && pwszInfFile)
     1203                    vboxWinDrvInstLogVerbose(pCtx, 1, "Determining model ...");
     1204                    if (fForce)
    12261205                    {
    1227                         RTUTF16 wszSrcPathAbs[RTPATH_MAX] = { 0 };
    1228                         rc = RTUtf16CopyEx(wszSrcPathAbs, RT_ELEMENTS(wszSrcPathAbs), wszInfFileAbs,
    1229                                            RTUtf16Len(wszInfFileAbs) - RTUtf16Len(pwszInfFile));
    1230                         if (RT_SUCCESS(rc))
     1206                        RTUtf16Free(pParms->u.UnInstall.pwszModel);
     1207                        pParms->u.UnInstall.pwszModel = NULL;
     1208                    }
     1209                    rc = VBoxWinDrvInfQueryFirstModel(hInf, pwszMainSection, &pParms->u.UnInstall.pwszModel);
     1210                    if (RT_SUCCESS(rc))
     1211                    {
     1212                        RTUtf16Free(pParms->u.UnInstall.pwszSection);
     1213                        pParms->u.UnInstall.pwszSection = NULL;
     1214
     1215                        /* Now that we have determined the model, try if there is a section in the INF file for this model. */
     1216                        rc = VBoxWinDrvInfQueryInstallSection(hInf, pParms->u.UnInstall.pwszModel,
     1217                                                              &pParms->u.UnInstall.pwszSection);
     1218                        if (RT_FAILURE(rc))
    12311219                        {
    1232                             RTUTF16 wszDstPathAbs[RTPATH_MAX] = { 0 };
    1233                             fRc = g_pfnSetupCopyOEMInfW(wszInfFileAbs, wszSrcPathAbs, SPOST_PATH, 0,
    1234                                                         wszDstPathAbs, RT_ELEMENTS(wszDstPathAbs), NULL, NULL);
    1235 
    1236                             vboxWinDrvInstLogVerbose(pCtx, 1, "   INF file: %ls", wszInfFileAbs);
    1237                             vboxWinDrvInstLogVerbose(pCtx, 1, "Source path: %ls", wszSrcPathAbs);
    1238                             vboxWinDrvInstLogVerbose(pCtx, 1, "  Dest path: %ls", wszDstPathAbs);
    1239 
    1240                             if (fRc)
    1241                                 vboxWinDrvInstLogInfo(pCtx, "Copying OEM INF successful");
    1242                             else
    1243                                 rc = vboxWinDrvInstLogLastError(pCtx, "Installation(SetupCopyOEMInfW) failed");
     1220                            switch (enmType)
     1221                            {
     1222                                case VBOXWINDRVINFTYPE_NORMAL:
     1223                                {
     1224                                    vboxWinDrvInstLogError(pCtx, "No section to install found, can't continue");
     1225                                    break;
     1226                                }
     1227
     1228                                case VBOXWINDRVINFTYPE_PRIMITIVE:
     1229                                {
     1230                                    /* If for the given model there is no install section, set the section to main section
     1231                                     * we got when we determined the INF type.
     1232                                     *
     1233                                     * This will be mostly the case for primitive drivers. */
     1234                                    if (rc == VERR_NOT_FOUND)
     1235                                    {
     1236                                        pParms->u.UnInstall.pwszSection = RTUtf16Dup(pwszMainSection);
     1237                                        if (pParms->u.UnInstall.pwszSection)
     1238                                        {
     1239                                            rc = VINF_SUCCESS;
     1240                                        }
     1241                                        else
     1242                                            rc = VERR_NO_MEMORY;
     1243                                    }
     1244                                    break;
     1245                                }
     1246
     1247                                default:
     1248                                    AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     1249                                    break;
     1250                            }
    12441251                        }
    12451252                    }
    12461253                    else
    1247                         rc = vboxWinDrvInstLogLastError(pCtx, "GetFullPathNameW() failed");
     1254                    {
     1255                        switch (rc)
     1256                        {
     1257                            case VERR_PLATFORM_ARCH_NOT_SUPPORTED:
     1258                            {
     1259                                vboxWinDrvInstLogError(pCtx, "Model found, but platform is not supported");
     1260                                break;
     1261                            }
     1262
     1263                            case VERR_NOT_FOUND:
     1264                            {
     1265                                vboxWinDrvInstLogError(pCtx, "No model found to install found -- buggy driver?");
     1266                                break;
     1267                            }
     1268
     1269                            default:
     1270                                break;
     1271                        }
     1272                    }
    12481273                }
    12491274
    1250                 if (fInstallSection)
    1251                     rc = vboxWinDrvTryInfSection(pCtx,
    1252                                                  pParms->pwszInfFile, pParms->u.UnInstall.pwszModel,
    1253                                                  vboxWinDrvInstallTryInfSectionCallback);
     1275                /*
     1276                 * Determine PnP ID.
     1277                 *
     1278                 * Only available in non-primitive drivers.
     1279                 */
     1280                if (   enmType == VBOXWINDRVINFTYPE_NORMAL
     1281                    && (   !pParms->u.UnInstall.pwszPnpId
     1282                        || fForce))
     1283                {
     1284                    if (pParms->u.UnInstall.pwszModel)
     1285                    {
     1286                        vboxWinDrvInstLogVerbose(pCtx, 1, "Determining PnP ID ...");
     1287                        if (fForce)
     1288                        {
     1289                            RTUtf16Free(pParms->u.UnInstall.pwszPnpId);
     1290                            pParms->u.UnInstall.pwszPnpId = NULL;
     1291                        }
     1292                        /* ignore rc */ VBoxWinDrvInfQueryFirstPnPId(hInf,
     1293                                                                     pParms->u.UnInstall.pwszModel, &pParms->u.UnInstall.pwszPnpId);
     1294                    }
     1295                    else
     1296                        vboxWinDrvInstLogVerbose(pCtx, 1, "No first model found/set, skipping determining PnP ID");
     1297                }
     1298
     1299                RTUtf16Free(pwszMainSection);
    12541300            }
    1255 
    1256             if (RT_FAILURE(rc))
    1257                 break;
    1258 
    1259             pCtx->fReboot = RT_BOOL(fReboot);
    1260             break;
    1261         }
    1262 
    1263         case VBOXWINDRVINSTMODE_INSTALL_INFSECTION:
    1264         {
    1265             rc = vboxWinDrvInstallInfSection(pCtx, pParms);
    1266             break;
    1267         }
    1268 
    1269         default:
    1270             break;
    1271     }
    1272 
    1273     return rc;
    1274 }
    1275 
    1276 /**
    1277  * Returns whether the given (in)installation parameters are valid or not.
    1278  *
    1279  * @returns \c true if valid, \c false if not.
    1280  * @param   pCtx                Windows driver installer context.
    1281  * @param   pParms              Windows driver (un)installation parameters to validate.
    1282  */
    1283 static bool vboxWinDrvParmsAreValid(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms)
    1284 {
    1285     if (pParms->u.UnInstall.pwszPnpId)
    1286     {
    1287         size_t const cchPnpId = RTUtf16Len(pParms->u.UnInstall.pwszPnpId);
    1288         if (   !cchPnpId
    1289             || cchPnpId > MAX_DEVICE_ID_LEN)
    1290         {
    1291             vboxWinDrvInstLogVerbose(pCtx, 1, "PnP ID not specified explicitly or invalid");
    1292             return false;
    1293         }
    1294     }
    1295 
    1296     return true;
    1297 }
    1298 
    1299 /**
    1300  * Determines (un)installation parameters from a given set of parameters, logged.
    1301  *
    1302  * @returns VBox status code.
    1303  * @retval  VERR_INVALID_PARAMETER if no valid parameters could be determined.
    1304  * @param   pCtx                Windows driver installer context.
    1305  * @param   pParms              Windows driver installation parameters to determine for.
    1306  * @param   fForce              Whether to overwrite already set parameters or not.
    1307  *
    1308  * @note    Only can deal with the first model / PnP ID found for now.
    1309  */
    1310 static int vboxWinDrvParmsDetermine(PVBOXWINDRVINSTINTERNAL pCtx, PVBOXWINDRVINSTPARMS pParms, bool fForce)
    1311 {
    1312     int rc;
    1313     /* INF file given? */
    1314     if (    pParms->pwszInfFile
    1315         && !pParms->fDeterminedFromInfFile)
    1316     {
    1317         HINF hInf;
    1318         rc = VBoxWinDrvInfOpen(pParms->pwszInfFile, &hInf);
    1319         if (RT_SUCCESS(rc))
    1320         {
    1321             /* Note: Model must come first for getting the PnP ID. */
    1322             if (!pParms->u.UnInstall.pwszModel || fForce)
     1301            else
    13231302            {
    1324                 vboxWinDrvInstLogVerbose(pCtx, 1, "Determining model ...");
    1325                 if (fForce)
    1326                 {
    1327                     RTUtf16Free(pParms->u.UnInstall.pwszModel);
    1328                     pParms->u.UnInstall.pwszModel = NULL;
    1329                 }
    1330                 rc = VBoxWinDrvInfQueryFirstModel(hInf, &pParms->u.UnInstall.pwszModel);
    1331                 if (rc == VERR_NOT_FOUND)
    1332                 {
    1333                     vboxWinDrvInstLogVerbose(pCtx, 1, "No model found, probably a primitive driver");
    1334                     rc = VINF_SUCCESS; /* Reset rc, non-fatal. */
    1335                 }
     1303                vboxWinDrvInstLogError(pCtx, "INF file is invalid");
     1304                rc = VERR_INVALID_PARAMETER;
    13361305            }
    1337             if (!pParms->u.UnInstall.pwszPnpId  || fForce)
    1338             {
    1339                 if (pParms->u.UnInstall.pwszModel)
    1340                 {
    1341                     vboxWinDrvInstLogVerbose(pCtx, 1, "Determining PnP ID ...");
    1342                     if (fForce)
    1343                     {
    1344                         RTUtf16Free(pParms->u.UnInstall.pwszPnpId);
    1345                         pParms->u.UnInstall.pwszPnpId = NULL;
    1346                     }
    1347                     /* ignore rc */ VBoxWinDrvInfQueryFirstPnPId(hInf,
    1348                                                                  pParms->u.UnInstall.pwszModel, &pParms->u.UnInstall.pwszPnpId);
    1349                 }
    1350                 else
    1351                     vboxWinDrvInstLogVerbose(pCtx, 1, "No first model found/set, skipping determining PnP ID");
    1352             }
     1306
    13531307            VBoxWinDrvInfClose(hInf);
    13541308        }
    1355 
    1356         pParms->fDeterminedFromInfFile = true;
    13571309    }
    13581310    /* No INF file given but either the model or the PnP ID? */
     
    13641316    }
    13651317    else
     1318    {
     1319        vboxWinDrvInstLogError(pCtx, "Neither INF file nor model/PnP ID given; can't continue");
    13661320        rc = VERR_INVALID_PARAMETER;
     1321    }
    13671322
    13681323    if (RT_SUCCESS(rc))
     
    13751330        vboxWinDrvInstLogVerbose(pCtx, 1, "\t  PnP ID: %ls",
    13761331                                 pParms->u.UnInstall.pwszPnpId ? pParms->u.UnInstall.pwszPnpId : L"<None>");
     1332        vboxWinDrvInstLogVerbose(pCtx, 1, "\t Section: %ls",
     1333                                 pParms->u.UnInstall.pwszSection ? pParms->u.UnInstall.pwszSection : L"<None>");
    13771334    }
    13781335
     
    14741431        AssertBreakStmt(cwchInfPathAbs > 0, rc = VERR_BUFFER_OVERFLOW);
    14751432
    1476         vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" ...", wszInfPathAbs);
     1433        vboxWinDrvInstLogInfo(pCtx, "Uninstalling %ls (%ls)", pCur->wszModel, wszInfPathAbs);
    14771434
    14781435        /* Only calltry calling the "DefaultUninstall" section here, as there aren't any other section(s)
     
    14911448            if (fRc)
    14921449                pCtx->fReboot = RT_BOOL(fReboot);
     1450            else
     1451            {
     1452                /* Not fatal, try next block. */
     1453                DWORD const dwErr = GetLastError();
     1454                vboxWinDrvInstLogVerbose(pCtx, 1, "DiUninstallDriverW() failed with %#x (%d)", dwErr, dwErr);
     1455            }
    14931456        }
    14941457
     
    15111474            vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" successful", wszInfPathAbs);
    15121475        else
    1513             rc2 = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs);
     1476        {
     1477            DWORD const dwErr = GetLastError();
     1478            if (dwErr == ERROR_INF_IN_USE_BY_DEVICES)
     1479                vboxWinDrvInstLogError(pCtx, "Unable to uninstall OEM INF \"%ls\": Driver still in use by device", wszInfPathAbs);
     1480            else
     1481                rc2 = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs);
     1482        }
    15141483
    15151484        /* If anything failed above, try removing stuff ourselves as good as we can. */
     
    15201489        if (RT_SUCCESS(rc)) /* Keep first error if already set. */
    15211490            rc = rc2;
     1491
     1492        /* Keep going. */
    15221493    }
    15231494
  • trunk/src/VBox/GuestHost/installation/VBoxWinDrvStore.cpp

    r106397 r106890  
    414414        if (RT_SUCCESS(rc))
    415415        {
    416             PRTUTF16 pwszModel;
    417             rc = VBoxWinDrvInfQueryFirstModel(hInf, &pwszModel);
    418             if (RT_SUCCESS(rc))
     416            PRTUTF16 pwszMainSection;
     417            VBOXWINDRVINFTYPE enmType = VBoxWinDrvInfGetTypeEx(hInf, &pwszMainSection);
     418            if (enmType != VBOXWINDRVINFTYPE_INVALID)
    419419            {
    420                 rc = RTUtf16Copy(pEntry->wszModel, RT_ELEMENTS(pEntry->wszModel), pwszModel);
     420                PRTUTF16 pwszModel;
     421                rc = VBoxWinDrvInfQueryFirstModel(hInf, pwszMainSection, &pwszModel);
    421422                if (RT_SUCCESS(rc))
    422423                {
    423                     /* PnP ID is optional. */
    424                     PRTUTF16 pwszPnpId;
    425                     int rc2 = VBoxWinDrvInfQueryFirstPnPId(hInf, pEntry->wszModel, &pwszPnpId);
    426                     if (RT_SUCCESS(rc2))
     424                    rc = RTUtf16Copy(pEntry->wszModel, RT_ELEMENTS(pEntry->wszModel), pwszModel);
     425                    if (RT_SUCCESS(rc))
    427426                    {
    428                         rc = RTUtf16Copy(pEntry->wszPnpId, RT_ELEMENTS(pEntry->wszPnpId), pwszPnpId);
    429                         RTUtf16Free(pwszPnpId);
     427                        /* PnP ID is optional. */
     428                        PRTUTF16 pwszPnpId;
     429                        int rc2 = VBoxWinDrvInfQueryFirstPnPId(hInf, pEntry->wszModel, &pwszPnpId);
     430                        if (RT_SUCCESS(rc2))
     431                        {
     432                            rc = RTUtf16Copy(pEntry->wszPnpId, RT_ELEMENTS(pEntry->wszPnpId), pwszPnpId);
     433                            RTUtf16Free(pwszPnpId);
     434                        }
    430435                    }
    431                 }
    432 
    433                 RTUtf16Free(pwszModel);
     436
     437                    RTUtf16Free(pwszModel);
     438                }
     439
     440                RTUtf16Free(pwszMainSection);
    434441            }
     442            else
     443                rc = VERR_INVALID_PARAMETER;
    435444        }
    436445
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