VirtualBox

Changeset 59370 in vbox


Ignore:
Timestamp:
Jan 17, 2016 8:31:19 PM (9 years ago)
Author:
vboxsync
Message:

VBoxProxyStub.c: Redid the cleanup-registry-mess code that deals with orphaned interfaces every VirtualBox.xidl UUID change generate. Also, capitulated and started using IPRT.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c

    r59367 r59370  
    88
    99/*
    10  * Copyright (C) 2006-2013 Oracle Corporation
     10 * Copyright (C) 2006-2016 Oracle Corporation
    1111 *
    1212 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3232#include <iprt/alloca.h>
    3333#include <iprt/assert.h>
     34#include <iprt/ctype.h>
     35#include <iprt/initterm.h>
    3436#include <iprt/path.h>
    3537#include <iprt/string.h>
     
    4042*   Defined Constants And Macros                                                                                                 *
    4143*********************************************************************************************************************************/
    42 /** @def WITH_MANUAL_CLEANUP
    43  * 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_CLEANUP
    46 #endif
    47 
    4844#ifdef DEBUG_bird
    4945# define VBSP_LOG_ENABLED
     
    6662#else
    6763# 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)
    6870#endif
    6971
     
    9496
    9597
    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! */
     100static PCRTUTF16 const      g_apwszTypeLibIds[] =
     101{
     102    L"{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}",
     103    L"{D7569351-1750-46F0-936E-BD127D5BC264}",
    102104};
    103105
    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. */
     107static PCRTUTF16 const      g_apwszTypelibVersions[] =
     108{
     109    L"1.0",
     110    L"1.3",
    109111};
    110112
    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!  */
     115static PCRTUTF16 const      g_apwszProxyStubClsIds[] =
     116{
     117    L"{0BB3B78C-1807-4249-5BA5-EA42D66AF0BF}",
     118    L"{327E3C00-EE61-462F-AED3-0DFF6CBF9904}",
    116119};
    117 #endif
    118 
    119 
    120 /*********************************************************************************************************************************
    121 *   Internal Functions                                                                                                           *
    122 *********************************************************************************************************************************/
    123 #ifdef WITH_MANUAL_CLEANUP
    124 static void removeOldMess(void);
    125 #endif
    126 
    127 
    128120
    129121
     
    148140            DisableThreadLibraryCalls(hInstance);
    149141
    150             /* We don't use IPRT, so no need to init it! */
     142            /* Init IPRT. */
     143            RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
    151144            break;
    152145
     
    509502    if (pState->hkeyInterfaceRootDst == NULL)
    510503    {
    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);
    512506        AssertMsgReturnStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->hkeyInterfaceRootDst = NULL,  pState->rc = rc);
    513507    }
     
    520514        if (pState->aAltDeletes[i].hkeyInterface == NULL)
    521515        {
    522             rc = RegOpenKeyExA(pState->aAltDeletes[i].hkeyClasses, "Interface", 0 /*fOptions*/, pState->fSamDelete,
     516            rc = RegOpenKeyExW(pState->aAltDeletes[i].hkeyClasses, L"Interface", 0 /*fOptions*/, pState->fSamDelete,
    523517                               &pState->aAltDeletes[i].hkeyInterface);
    524518            if (rc != ERROR_SUCCESS)
     
    894888    AssertReturn(*pszKey != '\0', pState->rc = ERROR_INVALID_PARAMETER);
    895889
     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
    896901    rc = SHDeleteKeyA(hkeyParent, pszKey);
    897902    if (rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND)
     
    899904
    900905    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 */
     921static 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));
    901945    pState->rc = rc;
    902946    return rc;
     
    14481492}
    14491493
    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 */
     1501static 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 */
     1525DECLINLINE(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 */
     1545static 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.
    14541601 *
    14551602 * @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 */
     1605static 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))
    14631639            return true;
     1640        pwsz2 = g_apwszTypeLibIds[1];
     1641        if (   wcFirstDigit  == pwsz2[1]
     1642            && wcSecondDigit == pwsz2[2]
     1643            && vbpsCompareUuidW(pwszTypeLibId, pwsz2))
     1644            return true;
     1645    }
    14641646    return false;
    14651647}
     
    14671649
    14681650/**
    1469  * Checks if the typelib version is 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.
    14701652 *
    14711653 * @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 */
     1656static 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))
    14791690            return true;
     1691        pwsz2 = g_apwszProxyStubClsIds[1];
     1692        if (   wcFirstDigit  == pwsz2[1]
     1693            && wcSecondDigit == pwsz2[2]
     1694            && vbpsCompareUuidW(pwszProxyStubId, pwsz2))
     1695            return true;
     1696    }
    14801697    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 */
     1705static 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    }
    14811822}
    14821823
     
    14861827 * boxes and such likes.
    14871828 */
    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++)
     1829static 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)
    14971843        {
    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++)
    15021850            {
    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*/);
    15091855                if (rc == ERROR_SUCCESS)
    15101856                {
    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)
    15191877                    {
    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)
    15251894                        {
    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)
    15351920                            {
    15361921                                /*
    15371922                                 * Ok, it's an orphaned VirtualBox interface. Delete it.
    15381923                                 */
    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__);
    15451926                            }
    15461927                        }
    15471928                    }
     1929                    else
     1930                        Assert(rc == ERROR_FILE_NOT_FOUND);
    15481931                }
    1549 
     1932                else
     1933                {
     1934                    Assert(rc == ERROR_NO_MORE_ITEMS);
     1935                    break;
     1936                }
    15501937            }
    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 */
     1950static 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)
    15521968            {
    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                }
    15552006            }
    15562007        }
    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 */
     2017static 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);
    15722025    if (rc == ERROR_SUCCESS)
    15732026    {
    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);
    16892036}
    16902037
     
    16952042static void removeOldMess(void)
    16962043{
    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
    17222050
    17232051
     
    18102138    AssertMsgStmt(SUCCEEDED(hrc2), ("%Rhrc\n", hrc2), if (SUCCEEDED(hrc)) hrc = hrc2);
    18112139
    1812 #ifdef WITH_MANUAL_CLEANUP
    18132140    /*
    18142141     * Purge old mess.
    18152142     */
    18162143    removeOldMess();
    1817 #endif
    18182144
    18192145    return hrc;
     
    18632189
    18642190
    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)) ?? */
    18662192#ifndef VBOX_IN_32_ON_64_MAIN_API
    18672193    /*
     
    18702196    if (rc == ERROR_SUCCESS)
    18712197    {
    1872         //rc = vbpsRegInit(&State, HKEY_CLASSES_ROOT, "Wow6432Node", fDelete, fUpdate, KEY_WOW64_32KEY);
    18732198        rc = vbpsRegInit(&State, HKEY_CLASSES_ROOT, NULL, false /*fDelete*/, true /*fUpdate*/,
    18742199                         !fIs32On64 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
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