Changeset 106488 in vbox for trunk/src/VBox/GuestHost
- Timestamp:
- Oct 18, 2024 7:16:23 PM (3 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/installation/VBoxWinDrvInst.cpp
r106485 r106488 116 116 typedef BOOL(WINAPI* PFNSETUPUNINSTALLOEMINFW) (PCWSTR InfFileName, DWORD Flags, PVOID Reserved); 117 117 typedef BOOL(WINAPI *PFNSETUPSETNONINTERACTIVEMODE) (BOOL NonInteractiveFlag); 118 119 /** Function pointer for a general try INF section callback. */ 120 typedef int (*PFNVBOXWINDRVINST_TRYINFSECTION_CALLBACK)(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx); 118 121 119 122 … … 674 677 PVBOXWINDRVINSTINTERNAL pThis; 675 678 /** Weak pointer to INF file being handled. */ 676 P RTUTF16pwszInfFile;679 PCRTUTF16 pwszInfFile; 677 680 /** Weak pointer to INF section being handled. */ 678 P RTUTF16pwszSection;681 PCRTUTF16 pwszSection; 679 682 /** User-supplied context pointer. */ 680 683 void *pvSetupContext; … … 741 744 } 742 745 RT_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 */ 759 static 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 } 743 820 744 821 /** … … 832 909 * Can have a platform decoration (e.g. "Foobar.NTx86"). 833 910 */ 834 static int vboxWinDrvInstallInfSectionEx(PVBOXWINDRVINSTINTERNAL pCtx, P RTUTF16 pwszInfFile, PRTUTF16 pwszSection)911 static int vboxWinDrvInstallInfSectionEx(PVBOXWINDRVINSTINTERNAL pCtx, PCRTUTF16 pwszInfFile, PCRTUTF16 pwszSection) 835 912 { 836 913 AssertPtrReturn(pwszInfFile, VERR_INVALID_POINTER); … … 954 1031 955 1032 /** 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 */ 1040 DECLCALLBACK(int) vboxWinDrvInstallTryInfSectionCallback(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx) 1041 { 1042 PVBOXWINDRVINSTINTERNAL pCtx = (PVBOXWINDRVINSTINTERNAL)pvCtx; 1043 1044 return vboxWinDrvInstallInfSectionEx(pCtx, pwszInfPathAbs, pwszSection); 995 1045 } 996 1046 … … 1034 1084 rc = vboxWinDrvParmsDetermine(pCtx, pParms, true /* fForce */); 1035 1085 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); 1037 1089 } 1038 1090 else … … 1271 1323 1272 1324 /** 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 */ 1332 DECLCALLBACK(int) vboxWinDrvUninstallTryInfSectionCallback(PCRTUTF16 pwszInfPathAbs, PCRTUTF16 pwszSection, void *pvCtx) 1333 { 1334 PVBOXWINDRVINSTINTERNAL pCtx = (PVBOXWINDRVINSTINTERNAL)pvCtx; 1335 1336 return vboxWinDrvUninstallInfSectionEx(pCtx, pwszInfPathAbs, pwszSection); 1319 1337 } 1320 1338 … … 1351 1369 vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" ...", wszInfPathAbs); 1352 1370 1371 /* rc ignored, keep going */ vboxWinDrvTryInfSection(pCtx, wszInfPathAbs, pCur->wszModel, 1372 vboxWinDrvUninstallTryInfSectionCallback); 1373 1353 1374 /* 1354 1375 * Remove the driver from the driver store. … … 1376 1397 } 1377 1398 1399 int rc2 = VINF_SUCCESS; 1400 1378 1401 if (fRc) 1379 1402 vboxWinDrvInstLogInfo(pCtx, "Uninstalling OEM INF \"%ls\" successful", wszInfPathAbs); 1380 1403 else 1381 rc = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs);1404 rc2 = vboxWinDrvInstLogLastError(pCtx, "Uninstalling OEM INF \"%ls\" failed", wszInfPathAbs); 1382 1405 1383 1406 /* 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; 1385 1413 } 1386 1414
Note:
See TracChangeset
for help on using the changeset viewer.