Changeset 59370 in vbox
- Timestamp:
- Jan 17, 2016 8:31:19 PM (9 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c
r59367 r59370 8 8 9 9 /* 10 * Copyright (C) 2006-201 3Oracle Corporation10 * Copyright (C) 2006-2016 Oracle Corporation 11 11 * 12 12 * This file is part of VirtualBox Open Source Edition (OSE), as … … 32 32 #include <iprt/alloca.h> 33 33 #include <iprt/assert.h> 34 #include <iprt/ctype.h> 35 #include <iprt/initterm.h> 34 36 #include <iprt/path.h> 35 37 #include <iprt/string.h> … … 40 42 * Defined Constants And Macros * 41 43 *********************************************************************************************************************************/ 42 /** @def WITH_MANUAL_CLEANUP43 * Manually clean up the registry. */44 #if 1 /*defined(DEBUG) && !defined(VBOX_IN_32_ON_64_MAIN_API) - needed on testboxes (and obviously dev boxes)! */45 # define WITH_MANUAL_CLEANUP46 #endif47 48 44 #ifdef DEBUG_bird 49 45 # define VBSP_LOG_ENABLED … … 66 62 #else 67 63 # define VBSP_LOG_NEW_KEY(a) do { } while (0) 64 #endif 65 66 #ifdef VBSP_LOG_ENABLED 67 # define VBSP_LOG_DEL_KEY(a) RTAssertMsg2 a 68 #else 69 # define VBSP_LOG_DEL_KEY(a) do { } while (0) 68 70 #endif 69 71 … … 94 96 95 97 96 #ifdef WITH_MANUAL_CLEANUP 97 /** Type library GUIDs to clean up manually.*/98 static const char * const g_apszTypelibGuids[] =99 { 100 "{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}",101 "{d7569351-1750-46f0-936e-bd127d5bc264}",98 /** Type library GUIDs to clean up manually. 99 * Must be upper case! */ 100 static PCRTUTF16 const g_apwszTypeLibIds[] = 101 { 102 L"{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}", 103 L"{D7569351-1750-46F0-936E-BD127D5BC264}", 102 104 }; 103 105 104 /** Same as above but with a "Typelib\\" prefix. */105 static const char * const g_apszTypelibGuidKeys[] =106 { 107 "TypeLib\\{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}",108 "TypeLib\\{d7569351-1750-46f0-936e-bd127d5bc264}",106 /** Type library version to clean up manually. */ 107 static PCRTUTF16 const g_apwszTypelibVersions[] = 108 { 109 L"1.0", 110 L"1.3", 109 111 }; 110 112 111 /** Type library version to clean up manually. */ 112 static const char * const g_apszTypelibVersions[] = 113 { 114 "1.0", 115 "1.3", 113 /** Proxy stub class IDs we wish to clean up manually. 114 * Must be upper case! */ 115 static PCRTUTF16 const g_apwszProxyStubClsIds[] = 116 { 117 L"{0BB3B78C-1807-4249-5BA5-EA42D66AF0BF}", 118 L"{327E3C00-EE61-462F-AED3-0DFF6CBF9904}", 116 119 }; 117 #endif118 119 120 /*********************************************************************************************************************************121 * Internal Functions *122 *********************************************************************************************************************************/123 #ifdef WITH_MANUAL_CLEANUP124 static void removeOldMess(void);125 #endif126 127 128 120 129 121 … … 148 140 DisableThreadLibraryCalls(hInstance); 149 141 150 /* We don't use IPRT, so no need to init it! */ 142 /* Init IPRT. */ 143 RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); 151 144 break; 152 145 … … 509 502 if (pState->hkeyInterfaceRootDst == NULL) 510 503 { 511 rc = RegOpenKeyExA(pState->hkeyClassesRootDst, "Interface", 0 /*fOptions*/, pState->fSamBoth, &pState->hkeyInterfaceRootDst); 504 rc = RegOpenKeyExW(pState->hkeyClassesRootDst, L"Interface", 0 /*fOptions*/, pState->fSamBoth, 505 &pState->hkeyInterfaceRootDst); 512 506 AssertMsgReturnStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->hkeyInterfaceRootDst = NULL, pState->rc = rc); 513 507 } … … 520 514 if (pState->aAltDeletes[i].hkeyInterface == NULL) 521 515 { 522 rc = RegOpenKeyEx A(pState->aAltDeletes[i].hkeyClasses,"Interface", 0 /*fOptions*/, pState->fSamDelete,516 rc = RegOpenKeyExW(pState->aAltDeletes[i].hkeyClasses, L"Interface", 0 /*fOptions*/, pState->fSamDelete, 523 517 &pState->aAltDeletes[i].hkeyInterface); 524 518 if (rc != ERROR_SUCCESS) … … 894 888 AssertReturn(*pszKey != '\0', pState->rc = ERROR_INVALID_PARAMETER); 895 889 890 #ifdef VBSP_LOG_ENABLED 891 { 892 HKEY hkeyLog; 893 rc = RegOpenKeyExA(hkeyParent, pszKey, 0 /*fOptions*/, pState->fSamDelete, &hkeyLog); 894 if (rc != ERROR_FILE_NOT_FOUND) 895 VBSP_LOG_DEL_KEY(("vbpsDeleteKeyRecursiveA: %ls/%s (at %d)\n", vbpsDebugKeyToWSZ(hkeyParent), pszKey, uLine)); 896 if (rc == ERROR_SUCCESS) 897 RegCloseKey(hkeyLog); 898 } 899 #endif 900 896 901 rc = SHDeleteKeyA(hkeyParent, pszKey); 897 902 if (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND) … … 899 904 900 905 AssertMsgFailed(("%d: delete key '%s' -> %u\n", uLine, pszKey, rc)); 906 pState->rc = rc; 907 return rc; 908 } 909 910 911 /** 912 * Recursively deletes a registry key, wide char version. 913 * 914 * @returns See SHDeleteKeyW (errors are remembered in the state). 915 * @param pState The registry modifier state. 916 * @param hkeyParent The parent key. 917 * @param pwszKey The key under @a hkeyParent that should be 918 * deleted. 919 * @param uLine The line we're called from. 920 */ 921 static LSTATUS vbpsDeleteKeyRecursiveW(VBPSREGSTATE *pState, HKEY hkeyParent, PCRTUTF16 pwszKey, unsigned uLine) 922 { 923 LSTATUS rc; 924 925 Assert(pState->fDelete); 926 Assert(pwszKey); 927 AssertReturn(*pwszKey != '\0', pState->rc = ERROR_INVALID_PARAMETER); 928 929 #ifdef VBSP_LOG_ENABLED 930 { 931 HKEY hkeyLog; 932 rc = RegOpenKeyExW(hkeyParent, pwszKey, 0 /*fOptions*/, pState->fSamDelete, &hkeyLog); 933 if (rc != ERROR_FILE_NOT_FOUND) 934 VBSP_LOG_DEL_KEY(("vbpsDeleteKeyRecursiveW: %ls/%ls (at %d)\n", vbpsDebugKeyToWSZ(hkeyParent), pwszKey, uLine)); 935 if (rc == ERROR_SUCCESS) 936 RegCloseKey(hkeyLog); 937 } 938 #endif 939 940 rc = SHDeleteKeyW(hkeyParent, pwszKey); 941 if (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND) 942 return ERROR_SUCCESS; 943 944 AssertMsgFailed(("%d: delete key '%ls' -> %u\n", uLine, pwszKey, rc)); 901 945 pState->rc = rc; 902 946 return rc; … … 1448 1492 } 1449 1493 1450 #ifdef WITH_MANUAL_CLEANUP 1451 1452 /** 1453 * Checks if the typelib GUID is one of the ones we wish to clean up. 1494 1495 /** 1496 * Checks if the string matches any of our type library versions. 1497 * 1498 * @returns true on match, false on mismatch. 1499 * @param pwszTypeLibVersion The type library version string. 1500 */ 1501 static DECLINLINE(bool) vbpsIsTypeLibVersionToRemove(PCRTUTF16 pwszTypeLibVersion) 1502 { 1503 AssertCompile(RT_ELEMENTS(g_apwszTypelibVersions) == 2); 1504 1505 /* ASSUMES: 1.x version strings and that the input buffer is at least 3 wchars long. */ 1506 if ( g_apwszTypelibVersions[0][3] == pwszTypeLibVersion[3] 1507 && RTUtf16Cmp(g_apwszTypelibVersions[0], pwszTypeLibVersion) == 0) 1508 return true; 1509 if ( g_apwszTypelibVersions[1][3] == pwszTypeLibVersion[3] 1510 && RTUtf16Cmp(g_apwszTypelibVersions[1], pwszTypeLibVersion) == 0) 1511 return true; 1512 1513 return false; 1514 } 1515 1516 1517 /** 1518 * Quick check whether the given string looks like a UUID in braces. 1519 * 1520 * This does not check the whole string, just do a quick sweep. 1521 * 1522 * @returns true if possible UUID, false if definitely not. 1523 * @param pwszUuid Alleged UUID in braces. 1524 */ 1525 DECLINLINE(bool) vbpsIsUuidInBracesQuickW(PCRTUTF16 pwszUuid) 1526 { 1527 return pwszUuid[ 0] == '{' 1528 && pwszUuid[ 9] == '-' 1529 && pwszUuid[14] == '-' 1530 && pwszUuid[19] == '-' 1531 && pwszUuid[24] == '-' 1532 && pwszUuid[37] == '}' 1533 && pwszUuid[38] == '\0' 1534 && RT_C_IS_XDIGIT(pwszUuid[1]); 1535 } 1536 1537 1538 /** 1539 * Compares two UUIDs (in braces). 1540 * 1541 * @returns true on match, false if no match. 1542 * @param pwszUuid1 The first UUID. 1543 * @param pwszUuid2 The second UUID. 1544 */ 1545 static bool vbpsCompareUuidW(PCRTUTF16 pwszUuid1, PCRTUTF16 pwszUuid2) 1546 { 1547 #define COMPARE_EXACT_RET(a_wch1, a_wch2) \ 1548 if ((a_wch1) == (a_wch2)) { } else return false 1549 1550 #define COMPARE_XDIGITS_RET(a_wch1, a_wch2) \ 1551 if ((a_wch1) == (a_wch2)) { } \ 1552 else if (RT_C_TO_UPPER(a_wch1) != RT_C_TO_UPPER(a_wch2) || (a_wch1) >= 127U || (a_wch2) >= 127U) \ 1553 return false 1554 COMPARE_EXACT_RET( pwszUuid1[ 0], pwszUuid2[ 0]); /* { */ 1555 COMPARE_XDIGITS_RET(pwszUuid1[ 1], pwszUuid2[ 1]); /* 5 */ 1556 COMPARE_XDIGITS_RET(pwszUuid1[ 2], pwszUuid2[ 2]); /* e */ 1557 COMPARE_XDIGITS_RET(pwszUuid1[ 3], pwszUuid2[ 3]); /* 5 */ 1558 COMPARE_XDIGITS_RET(pwszUuid1[ 4], pwszUuid2[ 4]); /* e */ 1559 COMPARE_XDIGITS_RET(pwszUuid1[ 5], pwszUuid2[ 5]); /* 3 */ 1560 COMPARE_XDIGITS_RET(pwszUuid1[ 6], pwszUuid2[ 6]); /* 6 */ 1561 COMPARE_XDIGITS_RET(pwszUuid1[ 7], pwszUuid2[ 7]); /* 4 */ 1562 COMPARE_XDIGITS_RET(pwszUuid1[ 8], pwszUuid2[ 8]); /* 0 */ 1563 COMPARE_EXACT_RET( pwszUuid1[ 9], pwszUuid2[ 9]); /* - */ 1564 COMPARE_XDIGITS_RET(pwszUuid1[10], pwszUuid2[10]); /* 7 */ 1565 COMPARE_XDIGITS_RET(pwszUuid1[11], pwszUuid2[11]); /* 4 */ 1566 COMPARE_XDIGITS_RET(pwszUuid1[12], pwszUuid2[12]); /* f */ 1567 COMPARE_XDIGITS_RET(pwszUuid1[13], pwszUuid2[13]); /* 3 */ 1568 COMPARE_EXACT_RET( pwszUuid1[14], pwszUuid2[14]); /* - */ 1569 COMPARE_XDIGITS_RET(pwszUuid1[15], pwszUuid2[15]); /* 4 */ 1570 COMPARE_XDIGITS_RET(pwszUuid1[16], pwszUuid2[16]); /* 6 */ 1571 COMPARE_XDIGITS_RET(pwszUuid1[17], pwszUuid2[17]); /* 8 */ 1572 COMPARE_XDIGITS_RET(pwszUuid1[18], pwszUuid2[18]); /* 9 */ 1573 COMPARE_EXACT_RET( pwszUuid1[19], pwszUuid2[19]); /* - */ 1574 COMPARE_XDIGITS_RET(pwszUuid1[20], pwszUuid2[20]); /* 9 */ 1575 COMPARE_XDIGITS_RET(pwszUuid1[21], pwszUuid2[21]); /* 7 */ 1576 COMPARE_XDIGITS_RET(pwszUuid1[22], pwszUuid2[22]); /* 9 */ 1577 COMPARE_XDIGITS_RET(pwszUuid1[23], pwszUuid2[23]); /* f */ 1578 COMPARE_EXACT_RET( pwszUuid1[24], pwszUuid2[24]); /* - */ 1579 COMPARE_XDIGITS_RET(pwszUuid1[25], pwszUuid2[25]); /* 6 */ 1580 COMPARE_XDIGITS_RET(pwszUuid1[26], pwszUuid2[26]); /* b */ 1581 COMPARE_XDIGITS_RET(pwszUuid1[27], pwszUuid2[27]); /* 1 */ 1582 COMPARE_XDIGITS_RET(pwszUuid1[28], pwszUuid2[28]); /* b */ 1583 COMPARE_XDIGITS_RET(pwszUuid1[29], pwszUuid2[29]); /* 8 */ 1584 COMPARE_XDIGITS_RET(pwszUuid1[30], pwszUuid2[30]); /* d */ 1585 COMPARE_XDIGITS_RET(pwszUuid1[31], pwszUuid2[31]); /* 7 */ 1586 COMPARE_XDIGITS_RET(pwszUuid1[32], pwszUuid2[32]); /* 6 */ 1587 COMPARE_XDIGITS_RET(pwszUuid1[33], pwszUuid2[33]); /* 0 */ 1588 COMPARE_XDIGITS_RET(pwszUuid1[34], pwszUuid2[34]); /* 9 */ 1589 COMPARE_XDIGITS_RET(pwszUuid1[35], pwszUuid2[35]); /* a */ 1590 COMPARE_XDIGITS_RET(pwszUuid1[36], pwszUuid2[36]); /* 5 */ 1591 COMPARE_EXACT_RET( pwszUuid1[37], pwszUuid2[37]); /* } */ 1592 COMPARE_EXACT_RET( pwszUuid1[38], pwszUuid2[38]); /* \0 */ 1593 #undef COMPARE_EXACT_RET 1594 #undef COMPARE_XDIGITS_RET 1595 return true; 1596 } 1597 1598 1599 /** 1600 * Checks if the type library ID is one of the ones we wish to clean up. 1454 1601 * 1455 1602 * @returns true if it should be cleaned up, false if not. 1456 * @param pszTypelibGuid The typelib GUID as bracketed string. 1457 */ 1458 static bool isTypelibGuidToRemove(const char *pszTypelibGuid) 1459 { 1460 unsigned i = RT_ELEMENTS(g_apszTypelibGuids); 1461 while (i-- > 0) 1462 if (!stricmp(g_apszTypelibGuids[i], pszTypelibGuid)) 1603 * @param pwszTypeLibId The type library ID as a bracketed string. 1604 */ 1605 static DECLINLINE(bool) vbpsIsTypeLibIdToRemove(PRTUTF16 pwszTypeLibId) 1606 { 1607 #ifdef VBOX_STRICT 1608 static bool s_fDoneStrict = false; 1609 if (s_fDoneStrict) { } 1610 else 1611 { 1612 Assert(RT_ELEMENTS(g_apwszTypeLibIds) == 2); 1613 Assert(g_apwszTypeLibIds[0] == '{'); 1614 Assert(g_apwszTypeLibIds[1] == '{'); 1615 Assert(RT_C_IS_XDIGIT(g_apwszTypeLibIds[0][1])); 1616 Assert(RT_C_IS_XDIGIT(g_apwszTypeLibIds[1][1])); 1617 Assert(RT_C_IS_UPPER(g_apwszTypeLibIds[0][1]) || RT_C_IS_DIGIT(g_apwszTypeLibIds[0][1])); 1618 Assert(RT_C_IS_UPPER(g_apwszTypeLibIds[1][1]) || RT_C_IS_DIGIT(g_apwszTypeLibIds[1][1])); 1619 s_fDoneStrict = true; 1620 } 1621 #endif 1622 AssertCompile(RT_ELEMENTS(g_apwszTypeLibIds) == 2); 1623 1624 /* 1625 * Rolled out matching with inlined check of the opening braces 1626 * and first two digits. 1627 * 1628 * ASSUMES input buffer is at least 3 wchars big and uppercased UUID in 1629 * our matching array. 1630 */ 1631 if (pwszTypeLibId[0] == '{') 1632 { 1633 RTUTF16 const wcFirstDigit = RT_C_TO_UPPER(pwszTypeLibId[1]); 1634 RTUTF16 const wcSecondDigit = RT_C_TO_UPPER(pwszTypeLibId[2]); 1635 PCRTUTF16 pwsz2 = g_apwszTypeLibIds[0]; 1636 if ( wcFirstDigit == pwsz2[1] 1637 && wcSecondDigit == pwsz2[2] 1638 && vbpsCompareUuidW(pwszTypeLibId, pwsz2)) 1463 1639 return true; 1640 pwsz2 = g_apwszTypeLibIds[1]; 1641 if ( wcFirstDigit == pwsz2[1] 1642 && wcSecondDigit == pwsz2[2] 1643 && vbpsCompareUuidW(pwszTypeLibId, pwsz2)) 1644 return true; 1645 } 1464 1646 return false; 1465 1647 } … … 1467 1649 1468 1650 /** 1469 * Checks if the typelib versionis one of the ones we wish to clean up.1651 * Checks if the proxy stub class ID is one of the ones we wish to clean up. 1470 1652 * 1471 1653 * @returns true if it should be cleaned up, false if not. 1472 * @param pszTypelibVer The typelib version as string. 1473 */ 1474 static bool isTypelibVersionToRemove(const char *pszTypelibVer) 1475 { 1476 unsigned i = RT_ELEMENTS(g_apszTypelibVersions); 1477 while (i-- > 0) 1478 if (!strcmp(g_apszTypelibVersions[i], pszTypelibVer)) 1654 * @param pwszProxyStubId The proxy stub class ID. 1655 */ 1656 static DECLINLINE(bool) vbpsIsProxyStubClsIdToRemove(PRTUTF16 pwszProxyStubId) 1657 { 1658 #ifdef VBOX_STRICT 1659 static bool s_fDoneStrict = false; 1660 if (s_fDoneStrict) { } 1661 else 1662 { 1663 Assert(RT_ELEMENTS(g_apwszProxyStubClsIds) == 2); 1664 Assert(g_apwszProxyStubClsIds[0] == '{'); 1665 Assert(g_apwszProxyStubClsIds[1] == '{'); 1666 Assert(RT_C_IS_XDIGIT(g_apwszProxyStubClsIds[0][1])); 1667 Assert(RT_C_IS_XDIGIT(g_apwszProxyStubClsIds[1][1])); 1668 Assert(RT_C_IS_UPPER(g_apwszProxyStubClsIds[0][1]) || RT_C_IS_DIGIT(g_apwszProxyStubClsIds[0][1])); 1669 Assert(RT_C_IS_UPPER(g_apwszProxyStubClsIds[1][1]) || RT_C_IS_DIGIT(g_apwszProxyStubClsIds[1][1])); 1670 s_fDoneStrict = true; 1671 } 1672 #endif 1673 AssertCompile(RT_ELEMENTS(g_apwszProxyStubClsIds) == 2); 1674 1675 /* 1676 * Rolled out matching with inlined check of the opening braces 1677 * and first two digits. 1678 * 1679 * ASSUMES input buffer is at least 3 wchars big and uppercased UUID in 1680 * our matching array. 1681 */ 1682 if (pwszProxyStubId[0] == '{') 1683 { 1684 RTUTF16 const wcFirstDigit = RT_C_TO_UPPER(pwszProxyStubId[1]); 1685 RTUTF16 const wcSecondDigit = RT_C_TO_UPPER(pwszProxyStubId[2]); 1686 PCRTUTF16 pwsz2 = g_apwszProxyStubClsIds[0]; 1687 if ( wcFirstDigit == pwsz2[1] 1688 && wcSecondDigit == pwsz2[2] 1689 && vbpsCompareUuidW(pwszProxyStubId, pwsz2)) 1479 1690 return true; 1691 pwsz2 = g_apwszProxyStubClsIds[1]; 1692 if ( wcFirstDigit == pwsz2[1] 1693 && wcSecondDigit == pwsz2[2] 1694 && vbpsCompareUuidW(pwszProxyStubId, pwsz2)) 1695 return true; 1696 } 1480 1697 return false; 1698 } 1699 1700 1701 /** 1702 * Hack to clean out the interfaces belonging to obsolete typelibs on 1703 * development boxes and such likes. 1704 */ 1705 static void vbpsRemoveOldInterfaces(VBPSREGSTATE *pState) 1706 { 1707 unsigned iAlt = pState->cAltDeletes; 1708 while (iAlt-- > 0) 1709 { 1710 /* 1711 * Open the interface root key. Not using the vbpsRegOpenInterfaceKeys feature 1712 * here in case it messes things up by keeping the special HKEY_CLASSES_ROOT key 1713 * open with possibly pending deletes in parent views or other weird stuff. 1714 */ 1715 HKEY hkeyInterfaces; 1716 LRESULT rc = RegOpenKeyExW(pState->aAltDeletes[iAlt].hkeyClasses, L"Interface", 1717 0 /*fOptions*/, pState->fSamDelete, &hkeyInterfaces); 1718 if (rc == ERROR_SUCCESS) 1719 { 1720 /* 1721 * This is kind of expensive, but we have to check all registered interfaces. 1722 * Only use wide APIs to avoid wasting time on string conversion. 1723 */ 1724 DWORD idxKey; 1725 for (idxKey = 0;; idxKey++) 1726 { 1727 RTUTF16 wszCurNm[128 + 48]; 1728 DWORD cwcCurNm = 128; 1729 rc = RegEnumKeyExW(hkeyInterfaces, idxKey, wszCurNm, &cwcCurNm, 1730 NULL /*pdwReserved*/, NULL /*pwszClass*/, NULL /*pcwcClass*/, NULL /*pLastWriteTime*/); 1731 if (rc == ERROR_SUCCESS) 1732 { 1733 /* 1734 * We match the interface by type library ID or proxy stub class ID. 1735 * 1736 * We have to check the proxy ID last, as it is almost always there 1737 * and we can safely skip it if there is a mismatching type lib 1738 * associated with the interface. 1739 */ 1740 static RTUTF16 const s_wszTypeLib[] = L"\\TypeLib"; 1741 bool fDeleteMe = false; 1742 HKEY hkeySub; 1743 RTUTF16 wszValue[128]; 1744 DWORD cbValue; 1745 DWORD dwType; 1746 1747 /* Skip this entry if it doesn't look like a braced UUID. */ 1748 wszCurNm[cwcCurNm] = '\0'; /* paranoia */ 1749 if (vbpsIsUuidInBracesQuickW(wszCurNm)) { } 1750 else continue; 1751 1752 /* Try the TypeLib sub-key. */ 1753 memcpy(&wszCurNm[cwcCurNm], s_wszTypeLib, sizeof(s_wszTypeLib)); 1754 rc = RegOpenKeyExW(hkeyInterfaces, wszCurNm, 0 /*fOptions*/, KEY_QUERY_VALUE, &hkeySub); 1755 if (rc == ERROR_SUCCESS) 1756 { 1757 cbValue = sizeof(wszValue) - sizeof(RTUTF16); 1758 rc = RegQueryValueExW(hkeySub, NULL /*pszValueNm*/, NULL /*pdwReserved*/, 1759 &dwType, (PBYTE)&wszValue[0], &cbValue); 1760 if (rc != ERROR_SUCCESS || dwType != REG_SZ) 1761 cbValue = 0; 1762 wszValue[cbValue / sizeof(RTUTF16)] = '\0'; 1763 1764 if ( rc == ERROR_SUCCESS 1765 && vbpsIsTypeLibIdToRemove(wszValue)) 1766 { 1767 /* Check the TypeLib/Version value to make sure. */ 1768 cbValue = sizeof(wszValue) - sizeof(RTUTF16); 1769 rc = RegQueryValueExW(hkeySub, L"Version", 0 /*pdwReserved*/, &dwType, (PBYTE)&wszValue[0], &cbValue); 1770 if (rc != ERROR_SUCCESS) 1771 cbValue = 0; 1772 wszValue[cbValue] = '\0'; 1773 1774 if ( rc == ERROR_SUCCESS 1775 && vbpsIsTypeLibVersionToRemove(wszValue)) 1776 fDeleteMe = true; 1777 } 1778 vbpsCloseKey(pState, hkeySub, __LINE__); 1779 } 1780 else if (rc == ERROR_FILE_NOT_FOUND) 1781 { 1782 /* No TypeLib, try the ProxyStubClsid32 sub-key next. */ 1783 static RTUTF16 const s_wszProxyStubClsid32[] = L"\\ProxyStubClsid32"; 1784 memcpy(&wszCurNm[cwcCurNm], s_wszProxyStubClsid32, sizeof(s_wszProxyStubClsid32)); 1785 rc = RegOpenKeyExW(hkeyInterfaces, wszCurNm, 0 /*fOptions*/, KEY_QUERY_VALUE, &hkeySub); 1786 if (rc == ERROR_SUCCESS) 1787 { 1788 cbValue = sizeof(wszValue) - sizeof(RTUTF16); 1789 rc = RegQueryValueExW(hkeySub, NULL /*pszValueNm*/, NULL /*pdwReserved*/, 1790 &dwType, (PBYTE)&wszValue[0], &cbValue); 1791 if (rc != ERROR_SUCCESS || dwType != REG_SZ) 1792 cbValue = 0; 1793 wszValue[cbValue / sizeof(RTUTF16)] = '\0'; 1794 1795 if ( rc == ERROR_SUCCESS 1796 && vbpsIsProxyStubClsIdToRemove(wszValue)) 1797 fDeleteMe = true; 1798 1799 vbpsCloseKey(pState, hkeySub, __LINE__); 1800 } 1801 } 1802 1803 if (fDeleteMe) 1804 { 1805 /* 1806 * Ok, it's an orphaned VirtualBox interface. Delete it. 1807 */ 1808 wszCurNm[cwcCurNm] = '\0'; 1809 vbpsDeleteKeyRecursiveW(pState, hkeyInterfaces, wszCurNm, __LINE__); 1810 } 1811 } 1812 else 1813 { 1814 Assert(rc == ERROR_NO_MORE_ITEMS); 1815 break; 1816 } 1817 } 1818 1819 vbpsCloseKey(pState, hkeyInterfaces, __LINE__); 1820 } 1821 } 1481 1822 } 1482 1823 … … 1486 1827 * boxes and such likes. 1487 1828 */ 1488 static void removeOldClassIDs(HKEY hkeyClassesRoot) 1489 { 1490 HKEY hkeyClsId; 1491 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "CLSID", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 1492 &hkeyClsId); 1493 if (rc == ERROR_SUCCESS) 1494 { 1495 DWORD idxKey; 1496 for (idxKey = 0;; idxKey++) 1829 static void vbpsRemoveOldClassIDs(VBPSREGSTATE *pState) 1830 { 1831 unsigned iAlt = pState->cAltDeletes; 1832 while (iAlt-- > 0) 1833 { 1834 /* 1835 * Open the CLSID key if it exists. 1836 * We don't use the hKeyClsid member for the same paranoid reasons as 1837 * already stated in vbpsRemoveOldInterfaces. 1838 */ 1839 HKEY hkeyClsIds; 1840 LRESULT rc; 1841 rc = RegOpenKeyExW(pState->aAltDeletes[iAlt].hkeyClasses, L"CLSID", 0 /*fOptions*/, pState->fSamDelete, &hkeyClsIds); 1842 if (rc == ERROR_SUCCESS) 1497 1843 { 1498 char szCurNm[128 + 128]; 1499 DWORD cbCurNm = 128; 1500 rc = RegEnumKeyExA(hkeyClsId, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL); 1501 if (rc == ERROR_SUCCESS) 1844 /* 1845 * This is kind of expensive, but we have to check all registered interfaces. 1846 * Only use wide APIs to avoid wasting time on string conversion. 1847 */ 1848 DWORD idxKey; 1849 for (idxKey = 0;; idxKey++) 1502 1850 { 1503 /* 1504 * Get the typelib GUID and program ID with the class ID. 1505 */ 1506 HKEY hkeyIfTypelib; 1507 strcpy(&szCurNm[cbCurNm], "\\TypeLib"); 1508 rc = RegOpenKeyExA(hkeyClsId, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfTypelib); 1851 RTUTF16 wszCurNm[128 + 48]; 1852 DWORD cwcCurNm = 128; 1853 rc = RegEnumKeyExW(hkeyClsIds, idxKey, wszCurNm, &cwcCurNm, 1854 NULL /*pdwReserved*/, NULL /*pwszClass*/, NULL /*pcwcClass*/, NULL /*pLastWriteTime*/); 1509 1855 if (rc == ERROR_SUCCESS) 1510 1856 { 1511 char szTypelibGuid[128]; 1512 DWORD cbValue = sizeof(szTypelibGuid) - 1; 1513 rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue); 1514 if (rc != ERROR_SUCCESS) 1515 cbValue = 0; 1516 szTypelibGuid[cbValue] = '\0'; 1517 RegCloseKey(hkeyIfTypelib); 1518 if (isTypelibGuidToRemove(szTypelibGuid)) 1857 /* 1858 * Match both the type library ID and the program ID. 1859 */ 1860 static RTUTF16 const s_wszTypeLib[] = L"\\TypeLib"; 1861 HKEY hkeySub; 1862 RTUTF16 wszValue[128]; 1863 DWORD cbValue; 1864 DWORD dwType; 1865 1866 1867 /* Skip this entry if it doesn't look like a braced UUID. (Microsoft 1868 has one two malformed ones plus a hack.) */ 1869 wszCurNm[cwcCurNm] = '\0'; /* paranoia */ 1870 if (vbpsIsUuidInBracesQuickW(wszCurNm)) { } 1871 else continue; 1872 1873 /* The TypeLib sub-key. */ 1874 memcpy(&wszCurNm[cwcCurNm], s_wszTypeLib, sizeof(s_wszTypeLib)); 1875 rc = RegOpenKeyExW(hkeyClsIds, wszCurNm, 0 /*fOptions*/, KEY_QUERY_VALUE, &hkeySub); 1876 if (rc == ERROR_SUCCESS) 1519 1877 { 1520 /* ProgId */ 1521 HKEY hkeyIfProgId; 1522 strcpy(&szCurNm[cbCurNm], "\\ProgId"); 1523 rc = RegOpenKeyExA(hkeyClsId, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfProgId); 1524 if (rc == ERROR_SUCCESS) 1878 bool fDeleteMe = false; 1879 1880 cbValue = sizeof(wszValue) - sizeof(RTUTF16); 1881 rc = RegQueryValueExW(hkeySub, NULL /*pszValueNm*/, NULL /*pdwReserved*/, 1882 &dwType, (PBYTE)&wszValue[0], &cbValue); 1883 if (rc != ERROR_SUCCESS || dwType != REG_SZ) 1884 cbValue = 0; 1885 wszValue[cbValue / sizeof(RTUTF16)] = '\0'; 1886 1887 if ( rc == ERROR_SUCCESS 1888 && vbpsIsTypeLibIdToRemove(wszValue)) 1889 fDeleteMe = true; 1890 1891 vbpsCloseKey(pState, hkeySub, __LINE__); 1892 1893 if (fDeleteMe) 1525 1894 { 1526 char szProgId[64]; 1527 cbValue = sizeof(szProgId) - 1; 1528 rc = RegQueryValueExA(hkeyIfProgId, NULL, NULL, NULL, (PBYTE)&szProgId[0], &cbValue); 1529 if (rc != ERROR_SUCCESS) 1530 cbValue = 0; 1531 szProgId[cbValue] = '\0'; 1532 RegCloseKey(hkeyIfProgId); 1533 if ( rc == ERROR_SUCCESS 1534 && strnicmp(szProgId, RT_STR_TUPLE("VirtualBox.")) == 0) 1895 /* The ProgId sub-key. */ 1896 static RTUTF16 const s_wszProgId[] = L"\\ProgId"; 1897 memcpy(&wszCurNm[cwcCurNm], s_wszProgId, sizeof(s_wszProgId)); 1898 rc = RegOpenKeyExW(hkeyClsIds, wszCurNm, 0 /*fOptions*/, KEY_QUERY_VALUE, &hkeySub); 1899 if (rc == ERROR_SUCCESS) 1900 { 1901 static RTUTF16 const s_wszProgIdPrefix[] = L"VirtualBox."; 1902 1903 cbValue = sizeof(wszValue) - sizeof(RTUTF16); 1904 rc = RegQueryValueExW(hkeySub, NULL /*pszValueNm*/, NULL /*pdwReserved*/, 1905 &dwType, (PBYTE)&wszValue[0], &cbValue); 1906 if (rc != ERROR_SUCCESS || dwType != REG_SZ) 1907 cbValue = 0; 1908 wszValue[cbValue / sizeof(RTUTF16)] = '\0'; 1909 1910 if ( cbValue < sizeof(s_wszProgIdPrefix) 1911 || memcmp(wszValue, s_wszProgIdPrefix, sizeof(s_wszProgIdPrefix) - sizeof(RTUTF16)) != 0) 1912 fDeleteMe = false; 1913 1914 vbpsCloseKey(pState, hkeySub, __LINE__); 1915 } 1916 else 1917 AssertStmt(rc == ERROR_FILE_NOT_FOUND, fDeleteMe = false); 1918 1919 if (fDeleteMe) 1535 1920 { 1536 1921 /* 1537 1922 * Ok, it's an orphaned VirtualBox interface. Delete it. 1538 1923 */ 1539 szCurNm[cbCurNm] = '\0'; 1540 #ifdef DEBUG_bird 1541 RTAssertMsg2("Should delete HCR/CLSID/%s\n", szCurNm); 1542 #endif 1543 rc = SHDeleteKeyA(hkeyClsId, szCurNm); 1544 Assert(rc == ERROR_SUCCESS); 1924 wszCurNm[cwcCurNm] = '\0'; 1925 vbpsDeleteKeyRecursiveW(pState, hkeyClsIds, wszCurNm, __LINE__); 1545 1926 } 1546 1927 } 1547 1928 } 1929 else 1930 Assert(rc == ERROR_FILE_NOT_FOUND); 1548 1931 } 1549 1932 else 1933 { 1934 Assert(rc == ERROR_NO_MORE_ITEMS); 1935 break; 1936 } 1550 1937 } 1551 else 1938 1939 vbpsCloseKey(pState, hkeyClsIds, __LINE__); 1940 } 1941 else 1942 Assert(rc == ERROR_FILE_NOT_FOUND); 1943 } 1944 } 1945 1946 1947 /** 1948 * Hack to clean obsolete typelibs on development boxes and such. 1949 */ 1950 static void vbpsRemoveOldTypeLibs(VBPSREGSTATE *pState) 1951 { 1952 unsigned iAlt = pState->cAltDeletes; 1953 while (iAlt-- > 0) 1954 { 1955 /* 1956 * Open the TypeLib key, if it exists. 1957 */ 1958 HKEY hkeyTypeLibs; 1959 LRESULT rc; 1960 rc = RegOpenKeyExW(pState->aAltDeletes[iAlt].hkeyClasses, L"TypeLib", 0 /*fOptions*/, pState->fSamDelete, &hkeyTypeLibs); 1961 if (rc == ERROR_SUCCESS) 1962 { 1963 /* 1964 * Look for our type library IDs. 1965 */ 1966 unsigned iTlb = RT_ELEMENTS(g_apwszTypeLibIds); 1967 while (iTlb-- > 0) 1552 1968 { 1553 Assert(rc == ERROR_NO_MORE_ITEMS); 1554 break; 1969 HKEY hkeyTypeLibId; 1970 LONG rc = RegOpenKeyExW(hkeyTypeLibs, g_apwszTypeLibIds[iTlb], 0 /*fOptions*/, pState->fSamDelete, &hkeyTypeLibId); 1971 if (rc == ERROR_SUCCESS) 1972 { 1973 unsigned iVer = RT_ELEMENTS(g_apwszTypelibVersions); 1974 while (iVer-- > 0) 1975 { 1976 HKEY hkeyVer; 1977 rc = RegOpenKeyExW(hkeyTypeLibId, g_apwszTypelibVersions[iVer], 0, KEY_READ, &hkeyVer); 1978 if (rc == ERROR_SUCCESS) 1979 { 1980 char szValue[128]; 1981 DWORD cbValue = sizeof(szValue) - 1; 1982 rc = RegQueryValueExA(hkeyVer, NULL, NULL, NULL, (PBYTE)&szValue[0], &cbValue); 1983 vbpsCloseKey(pState, hkeyVer, __LINE__); 1984 if (rc == ERROR_SUCCESS) 1985 { 1986 szValue[cbValue] = '\0'; 1987 if (!strcmp(szValue, "VirtualBox Type Library")) 1988 { 1989 /* 1990 * Delete the type library version. 1991 * We do not delete the whole type library ID, just this version of it. 1992 */ 1993 vbpsDeleteKeyRecursiveW(pState, hkeyTypeLibId, g_apwszTypelibVersions[iVer], __LINE__); 1994 } 1995 } 1996 } 1997 } 1998 vbpsCloseKey(pState, hkeyTypeLibId, __LINE__); 1999 2000 /* 2001 * The type library ID key should be empty now, so we can try remove it (non-recursively). 2002 */ 2003 rc = RegDeleteKeyW(hkeyTypeLibs, g_apwszTypeLibIds[iTlb]); 2004 Assert(rc == ERROR_SUCCESS); 2005 } 1555 2006 } 1556 2007 } 1557 1558 RegCloseKey(hkeyClsId); 1559 } 1560 } 1561 1562 1563 /** 1564 * Hack to clean out the interfaces belonging to obsolete typelibs on 1565 * development boxes and such likes. 1566 */ 1567 static void removeOldInterfaces(HKEY hkeyClassesRoot) 1568 { 1569 HKEY hkeyInterface; 1570 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "Interface", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 1571 &hkeyInterface); 2008 else 2009 Assert(rc == ERROR_FILE_NOT_FOUND); 2010 } 2011 } 2012 2013 2014 /** 2015 * Hack to clean out obsolete typelibs on development boxes and such. 2016 */ 2017 static void vbpsRemoveOldMessSub(REGSAM fSamWow) 2018 { 2019 /* 2020 * Note! The worker procedures does not use the default destination, 2021 * because it's much much simpler to enumerate alternative locations. 2022 */ 2023 VBPSREGSTATE State; 2024 LRESULT rc = vbpsRegInit(&State, HKEY_CLASSES_ROOT, NULL, true /*fDelete*/, false /*fUpdate*/, fSamWow); 1572 2025 if (rc == ERROR_SUCCESS) 1573 2026 { 1574 DWORD idxKey; 1575 for (idxKey = 0;; idxKey++) 1576 { 1577 char szCurNm[128 + 128]; 1578 DWORD cbCurNm = 128; 1579 rc = RegEnumKeyExA(hkeyInterface, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL); 1580 if (rc == ERROR_SUCCESS) 1581 { 1582 /* 1583 * Get the typelib GUID and version associated with the interface. 1584 */ 1585 HKEY hkeyIfTypelib; 1586 strcpy(&szCurNm[cbCurNm], "\\TypeLib"); 1587 rc = RegOpenKeyExA(hkeyInterface, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfTypelib); 1588 if (rc == ERROR_SUCCESS) 1589 { 1590 char szTypelibGuid[128]; 1591 DWORD cbValue = sizeof(szTypelibGuid) - 1; 1592 rc = RegQueryValueExA(hkeyIfTypelib, 0, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue); 1593 if (rc != ERROR_SUCCESS) 1594 cbValue = 0; 1595 szTypelibGuid[cbValue] = '\0'; 1596 if ( rc == ERROR_SUCCESS 1597 && isTypelibGuidToRemove(szTypelibGuid)) 1598 { 1599 char szTypelibVer[64]; 1600 cbValue = sizeof(szTypelibVer) - 1; 1601 rc = RegQueryValueExA(hkeyIfTypelib, "Version", 0, NULL, (PBYTE)&szTypelibVer[0], &cbValue); 1602 if (rc != ERROR_SUCCESS) 1603 cbValue = 0; 1604 szTypelibVer[cbValue] = '\0'; 1605 1606 if ( rc == ERROR_SUCCESS 1607 && isTypelibVersionToRemove(szTypelibVer)) 1608 { 1609 /* 1610 * Ok, it's an orphaned VirtualBox interface. Delete it. 1611 */ 1612 szCurNm[cbCurNm] = '\0'; 1613 RTAssertMsg2("Should delete HCR/Interface/%s\n", szCurNm); 1614 rc = SHDeleteKeyA(hkeyInterface, szCurNm); 1615 Assert(rc == ERROR_SUCCESS); 1616 } 1617 } 1618 RegCloseKey(hkeyIfTypelib); 1619 } 1620 } 1621 else 1622 { 1623 Assert(rc == ERROR_NO_MORE_ITEMS); 1624 break; 1625 } 1626 } 1627 1628 RegCloseKey(hkeyInterface); 1629 } 1630 } 1631 1632 1633 /** 1634 * Hack to clean obsolete typelibs on development boxes and such. 1635 */ 1636 static void removeOldTypelib(HKEY hkeyClassesRoot) 1637 { 1638 /* 1639 * Open it and verify the identity. 1640 */ 1641 unsigned i = RT_ELEMENTS(g_apszTypelibGuidKeys); 1642 while (i-- > 0) 1643 { 1644 HKEY hkeyTyplib; 1645 LONG rc = RegOpenKeyExA(hkeyClassesRoot, g_apszTypelibGuidKeys[i], 0, 1646 DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyTyplib); 1647 if (rc == ERROR_SUCCESS) 1648 { 1649 unsigned iVer = RT_ELEMENTS(g_apszTypelibVersions); 1650 while (iVer-- > 0) 1651 { 1652 HKEY hkeyVer; 1653 rc = RegOpenKeyExA(hkeyTyplib, g_apszTypelibVersions[iVer], 0, KEY_READ, &hkeyVer); 1654 if (rc == ERROR_SUCCESS) 1655 { 1656 char szValue[128]; 1657 DWORD cbValue = sizeof(szValue) - 1; 1658 rc = RegQueryValueExA(hkeyVer, NULL, NULL, NULL, (PBYTE)&szValue[0], &cbValue); 1659 if (rc == ERROR_SUCCESS) 1660 { 1661 szValue[cbValue] = '\0'; 1662 if (!strcmp(szValue, "VirtualBox Type Library")) 1663 { 1664 RegCloseKey(hkeyVer); 1665 hkeyVer = NULL; 1666 1667 /* 1668 * Delete the type library. 1669 */ 1670 RTAssertMsg2("Should delete HCR\\%s\\%s\n", g_apszTypelibGuidKeys[i], g_apszTypelibVersions[iVer]); 1671 rc = SHDeleteKeyA(hkeyTyplib, g_apszTypelibVersions[iVer]); 1672 Assert(rc == ERROR_SUCCESS); 1673 } 1674 } 1675 1676 if (hkeyVer != NULL) 1677 RegCloseKey(hkeyVer); 1678 } 1679 } 1680 RegCloseKey(hkeyTyplib); 1681 1682 /* 1683 * The typelib key should be empty now, so we can try remove it (non-recursively). 1684 */ 1685 rc = RegDeleteKeyA(hkeyClassesRoot, g_apszTypelibGuidKeys[i]); 1686 Assert(rc == ERROR_SUCCESS); 1687 } 1688 } 2027 vbpsRegAddAltDelete(&State, HKEY_CURRENT_USER, "Software\\Classes"); 2028 vbpsRegAddAltDelete(&State, HKEY_LOCAL_MACHINE, "Software\\Classes"); 2029 vbpsRegAddAltDelete(&State, HKEY_CLASSES_ROOT, NULL); 2030 2031 vbpsRemoveOldInterfaces(&State); 2032 vbpsRemoveOldClassIDs(&State); 2033 vbpsRemoveOldTypeLibs(&State); 2034 } 2035 vbpsRegTerm(&State); 1689 2036 } 1690 2037 … … 1695 2042 static void removeOldMess(void) 1696 2043 { 1697 HKEY hkeyWow64; 1698 LONG rc; 1699 1700 /* 1701 * The standard location. 1702 */ 1703 removeOldTypelib(HKEY_CLASSES_ROOT); 1704 removeOldInterfaces(HKEY_CLASSES_ROOT); 1705 removeOldClassIDs(HKEY_CLASSES_ROOT); 1706 1707 /* 1708 * Wow64 if present. 1709 */ 1710 rc = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Wow6432Node", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyWow64); 1711 if (rc == ERROR_SUCCESS) 1712 { 1713 removeOldTypelib(hkeyWow64); 1714 removeOldInterfaces(hkeyWow64); 1715 removeOldClassIDs(hkeyWow64); 1716 1717 RegCloseKey(hkeyWow64); 1718 } 1719 } 1720 1721 #endif /* WITH_MANUAL_CLEANUP */ 2044 vbpsRemoveOldMessSub(0 /*fSamWow*/); 2045 #if ARCH_BITS == 64 || defined(VBOX_IN_32_ON_64_MAIN_API) 2046 vbpsRemoveOldMessSub(KEY_WOW64_32KEY); 2047 #endif 2048 } 2049 1722 2050 1723 2051 … … 1810 2138 AssertMsgStmt(SUCCEEDED(hrc2), ("%Rhrc\n", hrc2), if (SUCCEEDED(hrc)) hrc = hrc2); 1811 2139 1812 #ifdef WITH_MANUAL_CLEANUP1813 2140 /* 1814 2141 * Purge old mess. 1815 2142 */ 1816 2143 removeOldMess(); 1817 #endif1818 2144 1819 2145 return hrc; … … 1863 2189 1864 2190 1865 / /#if defined(VBOX_IN_32_ON_64_MAIN_API) || (ARCH_BITS == 64 && defined(VBOX_WITH_32_ON_64_MAIN_API))2191 /*#if defined(VBOX_IN_32_ON_64_MAIN_API) || (ARCH_BITS == 64 && defined(VBOX_WITH_32_ON_64_MAIN_API)) ?? */ 1866 2192 #ifndef VBOX_IN_32_ON_64_MAIN_API 1867 2193 /* … … 1870 2196 if (rc == ERROR_SUCCESS) 1871 2197 { 1872 //rc = vbpsRegInit(&State, HKEY_CLASSES_ROOT, "Wow6432Node", fDelete, fUpdate, KEY_WOW64_32KEY);1873 2198 rc = vbpsRegInit(&State, HKEY_CLASSES_ROOT, NULL, false /*fDelete*/, true /*fUpdate*/, 1874 2199 !fIs32On64 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
Note:
See TracChangeset
for help on using the changeset viewer.

