VirtualBox

Changeset 96437 in vbox


Ignore:
Timestamp:
Aug 23, 2022 10:59:53 AM (2 years ago)
Author:
vboxsync
Message:

Add/NT/Inst: Fixes to the netprovider list management in VBoxDrvInst.cpp. Added 'registry addlistitem' and 'registry dellistitem' for testing the 'netprovider' code w/o messing up the system. bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Installer/VBoxDrvInst.cpp

    r96422 r96437  
    355355
    356356
     357static int ErrorMsgLStatusSWSWSWSWSRS(const char *pszMsg1, const wchar_t *pwszMsg2, const char *pszMsg3, const wchar_t *pwszMsg4,
     358                                      const char *pszMsg5, const wchar_t *pwszMsg6, const char *pszMsg7, const wchar_t *pwszMsg8,
     359                                      const char *pszMsg9, LSTATUS lrc, const char *pszMsg10)
     360{
     361    ErrorMsgBegin(pszMsg1);
     362    ErrorMsgWStr(pwszMsg2);
     363    ErrorMsgStr(pszMsg3);
     364    ErrorMsgWStr(pwszMsg4);
     365    ErrorMsgStr(pszMsg5);
     366    ErrorMsgWStr(pwszMsg6);
     367    ErrorMsgStr(pszMsg7);
     368    ErrorMsgWStr(pwszMsg8);
     369    ErrorMsgStr(pszMsg9);
     370    ErrorMsgErrVal((DWORD)lrc, true);
     371    return ErrorMsgEnd(pszMsg10);
     372}
     373
     374
    357375static int ErrorBadArg(const char *pszName, wchar_t const *pwszArg, const char *pszValues = NULL)
    358376{
     
    420438    PrintWStr(pwszMsg6);
    421439    PrintStr(pszMsg7);
     440}
     441
     442
     443static void PrintSWSWSWSWS(const char *pszMsg1, const wchar_t *pwszMsg2, const char *pszMsg3, const wchar_t *pwszMsg4,
     444                           const char *pszMsg5, const wchar_t *pwszMsg6, const char *pszMsg7, const wchar_t *pwszMsg8,
     445                           const char *pszMsg9)
     446{
     447    PrintStr(pszMsg1);
     448    PrintWStr(pwszMsg2);
     449    PrintStr(pszMsg3);
     450    PrintWStr(pwszMsg4);
     451    PrintStr(pszMsg5);
     452    PrintWStr(pwszMsg6);
     453    PrintStr(pszMsg7);
     454    PrintWStr(pwszMsg8);
     455    PrintStr(pszMsg9);
    422456}
    423457
     
    958992
    959993
     994
     995/*********************************************************************************************************************************
     996*   'service'                                                                                                                    *
     997*********************************************************************************************************************************/
     998
     999/**
     1000 * Worker for the 'service create' handler.
     1001 */
     1002static int CreateService(const wchar_t *pwszService,
     1003                         const wchar_t *pwszDisplayName,
     1004                         uint32_t       uServiceType,
     1005                         uint32_t       uStartType,
     1006                         const wchar_t *pwszBinPath,
     1007                         const wchar_t *pwszLoadOrderGroup,
     1008                         const wchar_t *pwszDependencies,
     1009                         const wchar_t *pwszLogonUser,
     1010                         const wchar_t *pwszLogonPassword)
     1011{
     1012    PrintSWSWS("Installing service '", pwszService, "' ('", pwszDisplayName, ") ...\r\n");
     1013
     1014    /*
     1015     * Transform the dependency list to a REG_MULTI_SZ.
     1016     */
     1017    if (pwszDependencies != NULL)
     1018    {
     1019        /* Copy it into alloca() buffer so we can modify it. */
     1020        size_t cwc = RTUtf16Len(pwszDependencies);
     1021        wchar_t *pwszDup = (wchar_t *)alloca((cwc + 2) * sizeof(wchar_t));
     1022        memcpy(pwszDup, pwszDependencies, cwc * sizeof(wchar_t));
     1023        pwszDup[cwc]     = L'\0';
     1024        pwszDup[cwc + 1] = L'\0';   /* double termination */
     1025
     1026        /* Perform: s/,/\0/g */
     1027        while (cwc-- > 0 )
     1028            if (pwszDup[cwc] == L',')
     1029                pwszDup[cwc] = L'\0';
     1030
     1031        pwszDependencies = pwszDup;
     1032    }
     1033
     1034    SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     1035    if (hSCManager == NULL)
     1036        return ErrorMsgLastErr("OpenSCManagerW failed");
     1037
     1038    int rcExit = EXIT_FAIL;
     1039    DWORD dwTag = 0xDEADBEAF;
     1040    SC_HANDLE hService = CreateServiceW(hSCManager, pwszService, pwszDisplayName, SERVICE_ALL_ACCESS, uServiceType, uStartType,
     1041                                        SERVICE_ERROR_NORMAL, pwszBinPath, pwszLoadOrderGroup, pwszLoadOrderGroup ? &dwTag : NULL,
     1042                                        pwszDependencies, pwszLogonUser, pwszLogonPassword);
     1043    if (hService != NULL)
     1044    {
     1045        CloseServiceHandle(hService);
     1046        PrintStr("Installation of service successful!\r\n");
     1047        rcExit = EXIT_OK;
     1048    }
     1049    else
     1050    {
     1051        DWORD dwErr = GetLastError();
     1052        if (dwErr == ERROR_SERVICE_EXISTS)
     1053        {
     1054            PrintStr("Service already exists. Updating the service config ...\r\n");
     1055            hService = OpenServiceW(hSCManager, pwszService, SERVICE_ALL_ACCESS);
     1056            if (hService != NULL)
     1057            {
     1058                if (ChangeServiceConfigW(hService, uServiceType, uStartType, SERVICE_ERROR_NORMAL, pwszBinPath,
     1059                                         pwszLoadOrderGroup, pwszLoadOrderGroup ? &dwTag : NULL, pwszDependencies,
     1060                                         pwszLogonUser, pwszLogonPassword, pwszDisplayName))
     1061                {
     1062                    PrintStr("The service config has been successfully updated.\r\n");
     1063                    rcExit = EXIT_OK;
     1064                }
     1065                else
     1066                    rcExit = ErrorMsgLastErrSWS("ChangeServiceConfigW failed on '", pwszService, "'!");
     1067                CloseServiceHandle(hService);
     1068            }
     1069            else
     1070                rcExit = ErrorMsgLastErrSWS("OpenSCManagerW failed on '", pwszService, "'!");
     1071
     1072            /*
     1073             * This branch does not return an error to avoid installations failures,
     1074             * if updating service parameters. Better to have a running system with old
     1075             * parameters and the failure information in the installation log.
     1076             */
     1077            rcExit = EXIT_OK;
     1078        }
     1079        else
     1080            rcExit = ErrorMsgLastErrSWS("CreateServiceW for '", pwszService, "'!");
     1081    }
     1082
     1083    CloseServiceHandle(hSCManager);
     1084    return rcExit;
     1085}
     1086
     1087
     1088/** Handles 'service create'. */
     1089static int handleServiceCreate(unsigned cArgs, wchar_t **papwszArgs)
     1090{
     1091    uint32_t uServiceType;
     1092    if (!ArgToUInt32Full(papwszArgs[2], "service-type", &uServiceType))
     1093        return EXIT_USAGE;
     1094
     1095    uint32_t uStartType;
     1096    if (!ArgToUInt32Full(papwszArgs[3], "start-type", &uStartType))
     1097        return EXIT_USAGE;
     1098
     1099    return CreateService(papwszArgs[0], papwszArgs[1], uServiceType, uStartType, papwszArgs[4],
     1100                         cArgs > 5 ? papwszArgs[5] : NULL,
     1101                         cArgs > 6 ? papwszArgs[6] : NULL,
     1102                         cArgs > 7 ? papwszArgs[7] : NULL,
     1103                         cArgs > 8 ? papwszArgs[8] : NULL);
     1104}
     1105
     1106
     1107/**
     1108 * Worker for the 'service delete' handler.
     1109 */
     1110static int DelService(const wchar_t *pwszService)
     1111{
     1112    PrintSWS("Removing service '", pwszService, "' ...\r\n");
     1113
     1114    SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     1115    if (hSCManager == NULL)
     1116        return ErrorMsgLastErr("OpenSCManagerW failed");
     1117
     1118    int rcExit = EXIT_FAIL;
     1119    SC_HANDLE hService = NULL;
     1120    hService = OpenServiceW(hSCManager, pwszService, SERVICE_ALL_ACCESS);
     1121    if (hService)
     1122    {
     1123        SC_LOCK hSCLock = LockServiceDatabase(hSCManager);
     1124        if (hSCLock != NULL)
     1125        {
     1126            if (DeleteService(hService))
     1127            {
     1128                PrintSWS("Service '", pwszService, "' successfully deleted.\r\n");
     1129                rcExit = EXIT_OK;
     1130            }
     1131            else
     1132            {
     1133                DWORD dwErr = GetLastError();
     1134                if (dwErr == ERROR_SERVICE_MARKED_FOR_DELETE)
     1135                {
     1136                    PrintSWS("Service '", pwszService, "' already marked for deletion.\r\n");
     1137                    rcExit = EXIT_OK;
     1138                }
     1139                else
     1140                    rcExit = ErrorMsgLastErrSWS("Failed to delete service'", pwszService, "'!");
     1141            }
     1142            UnlockServiceDatabase(hSCLock);
     1143        }
     1144        else
     1145            ErrorMsgLastErr("LockServiceDatabase failed");
     1146        CloseServiceHandle(hService);
     1147    }
     1148    else
     1149        rcExit = ErrorMsgLastErrSWS("Failed to open service'", pwszService, "'!");
     1150    CloseServiceHandle(hSCManager);
     1151    return rcExit;
     1152}
     1153
     1154
     1155/** Handles 'service delete' */
     1156static int handleServiceDelete(unsigned cArgs, wchar_t **papwszArgs)
     1157{
     1158    RT_NOREF(cArgs);
     1159    return DelService(papwszArgs[0]);
     1160}
     1161
     1162
     1163
     1164
     1165/*********************************************************************************************************************************
     1166*   'registry'                                                                                                                   *
     1167*********************************************************************************************************************************/
     1168
     1169/**
     1170 * Translate a registry root specifier into a HKEY_XXX constant.
     1171 */
     1172static HKEY ArgToRegistryRoot(const wchar_t *pwszRoot)
     1173{
     1174    HKEY hRootKey = NULL;
     1175    if (RTUtf16ICmpAscii(pwszRoot, "hklm") == 0)
     1176        hRootKey = HKEY_LOCAL_MACHINE;
     1177    else if (RTUtf16ICmpAscii(pwszRoot, "hkcu") == 0)
     1178        hRootKey = HKEY_CURRENT_USER;
     1179    else if (RTUtf16ICmpAscii(pwszRoot, "hkcr") == 0)
     1180        hRootKey = HKEY_CLASSES_ROOT;
     1181    else if (RTUtf16ICmpAscii(pwszRoot, "hku") == 0)
     1182        hRootKey = HKEY_USERS;
     1183    else if (RTUtf16ICmpAscii(pwszRoot, "hkcc") == 0)
     1184        hRootKey = HKEY_CURRENT_CONFIG;
     1185    else
     1186        ErrorBadArg("root", pwszRoot, "hklm, hkcu, hkcr, hku or hkcc");
     1187    return hRootKey;
     1188}
     1189
     1190
     1191/**
     1192 * Reverse of ArgToRegistryRoot.
     1193 */
     1194static wchar_t const *RegistryRootToWStr(HKEY hRootKey)
     1195{
     1196    if (hRootKey == HKEY_LOCAL_MACHINE)
     1197        return L"HKLM";
     1198    if (hRootKey == HKEY_CURRENT_USER)
     1199        return L"HKCU";
     1200    if (hRootKey == HKEY_CLASSES_ROOT)
     1201        return L"HKCR";
     1202    if (hRootKey == HKEY_USERS)
     1203        return L"HKU";
     1204    if (hRootKey == HKEY_CURRENT_CONFIG)
     1205        return L"HKCC";
     1206    return L"<bad-hkey-root>";
     1207}
     1208
     1209
    9601210/**
    9611211 * Checks if a string is a substring of another one.
     
    12911541           latter is Vista and later, the former has a big fat warning on it.  */
    12921542        wchar_t const wcEnd = pwszItem1[cwcItem1];
     1543        pwszItem1[cwcItem1] = '\0';
    12931544        int const iDiff = lstrcmpiW((wchar_t const *)pwszItem1, pwszItem2);
    12941545        pwszItem1[cwcItem1] = wcEnd;
     
    13141565 * @param   fFlags              VBOX_REG_STRINGLIST_ALLOW_DUPLICATES or 0.
    13151566 */
    1316 static int RegistryAddStringToList(const wchar_t *pwszSubKey, const wchar_t *pwszValueName, const wchar_t *pwszItemToAdd,
    1317                                    uint32_t uPosition, uint32_t fFlags)
     1567static int RegistryAddStringToList(HKEY hRootKey, const wchar_t *pwszSubKey, const wchar_t *pwszValueName,
     1568                                   const wchar_t *pwszItemToAdd, uint32_t uPosition, uint32_t fFlags)
    13181569{
    13191570    /* Overflow precaution - see comment below. */
     
    13271578    HKEY    hKey   = NULL;
    13281579    DWORD   dwDisp = 0;
    1329     LSTATUS lrc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, pwszSubKey, 0 /*Reserved*/, NULL /*pClass*/, REG_OPTION_NON_VOLATILE,
     1580    LSTATUS lrc = RegCreateKeyEx(hRootKey, pwszSubKey, 0 /*Reserved*/, NULL /*pClass*/, REG_OPTION_NON_VOLATILE,
    13301581                                 KEY_READ | KEY_WRITE, NULL /*pSecAttr*/, &hKey, &dwDisp);
    13311582    if (lrc != ERROR_SUCCESS)
    1332         return ErrorMsgLStatusSWSRS("RegistryAddStringToList: RegCreateKeyEx HKLM/'", pwszSubKey, "' failed: ", lrc, NULL);
     1583        return ErrorMsgLStatusSWSWSRS("RegistryAddStringToList: RegCreateKeyEx ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey,
     1584                                      "' failed: ", lrc, NULL);
    13331585
    13341586    /*
     
    13651617        wchar_t *pwszDst = wszNewValue;
    13661618        wchar_t *pwszSrc = wszValue;
    1367         unsigned uCurPos = 0;
    1368         for (;;)
     1619        for (unsigned uCurPos = 0;; uCurPos++)
    13691620        {
    13701621            /* Skip leading commas: */
     
    13801631            if (uCurPos == uPosition || (!wc && uCurPos < uPosition))
    13811632            {
    1382                 if (fLeadingComma)
     1633                if (fLeadingComma || (wc == '\0' && pwszDst != wszNewValue))
    13831634                    *pwszDst++ = ',';
    13841635                memcpy(pwszDst, pwszItemToAdd, cwcItemToAdd * sizeof(wchar_t));
     
    14031654            if (   !(fFlags & VBOX_REG_STRINGLIST_ALLOW_DUPLICATES)
    14041655                && IsStringListItemMatch(pwszSrc, cwcItem, pwszItemToAdd, cwcItemToAdd))
     1656            {
    14051657                pwszSrc = pwszSrcEnd;
     1658                if (!fLeadingComma)
     1659                    while (*pwszSrc == ',')
     1660                        pwszSrc++;
     1661                uCurPos--;
     1662            }
    14061663            else
    14071664            {
     
    14401697    }
    14411698    else if (lrc != ERROR_SUCCESS)
    1442         ErrorMsgLStatusSWSWSRS("RegistryAddStringToList: RegQueryValueEx HKLM/'",
    1443                                pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);
     1699        ErrorMsgLStatusSWSWSWSRS("RegistryAddStringToList: RegQueryValueEx ", RegistryRootToWStr(hRootKey), "/'",
     1700                                 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);
    14441701    else
    1445         ErrorMsgLStatusSWSWSRS("RegistryAddStringToList: Unexpected value type for HKLM/'",
    1446                                pwszSubKey, "'/'", pwszValueName, "': ", (LSTATUS)dwType, ", expected REG_SZ (1)");
     1702        ErrorMsgLStatusSWSWSWSRS("RegistryAddStringToList: Unexpected value type for ", RegistryRootToWStr(hRootKey), "/'",
     1703                                 pwszSubKey, "'/'", pwszValueName, "': ", (LSTATUS)dwType, ", expected REG_SZ (1)");
    14471704
    14481705    RegCloseKey(hKey);
     
    14631720
    14641721    PrintSWSWS("Adding network provider '", pwszProvider, "' (Position = ", pwszPosition, ") ...\r\n");
    1465     int rcExit = RegistryAddStringToList(L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
     1722    int rcExit = RegistryAddStringToList(HKEY_LOCAL_MACHINE,
     1723                                         L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
    14661724                                         L"ProviderOrder",
    14671725                                         pwszProvider, uPosition, VBOX_REG_STRINGLIST_NONE);
    14681726    if (rcExit == EXIT_OK)
    14691727        PrintStr("Network provider successfully added!\r\n");
     1728
     1729    return rcExit;
     1730}
     1731
     1732
     1733/**
     1734 * Handles 'registry addlistitem'.
     1735 */
     1736static int handleRegistryAddListItem(unsigned cArgs, wchar_t **papwszArgs)
     1737{
     1738    /*
     1739     * Parameters.
     1740     */
     1741    wchar_t const * const pwszRoot      = papwszArgs[0];
     1742    wchar_t const * const pwszSubKey    = papwszArgs[1];
     1743    wchar_t const * const pwszValueName = papwszArgs[2];
     1744    wchar_t const * const pwszItem      = papwszArgs[3];
     1745    wchar_t const * const pwszPosition  = cArgs > 4 ? papwszArgs[4] : L"0";
     1746    wchar_t const * const pwszFlags     = cArgs > 5 ? papwszArgs[5] : NULL;
     1747
     1748    HKEY hRootKey = ArgToRegistryRoot(pwszRoot);
     1749    if (hRootKey == NULL)
     1750        return EXIT_USAGE;
     1751
     1752    uint32_t uPosition = 0;
     1753    if (!ArgToUInt32Full(pwszPosition, "position", &uPosition))
     1754        return EXIT_USAGE;
     1755
     1756    uint32_t fFlags = 0;
     1757    if (pwszFlags)
     1758    {
     1759        if (RTUtf16ICmpAscii(pwszFlags, "dup") == 0)
     1760            fFlags = VBOX_REG_STRINGLIST_ALLOW_DUPLICATES;
     1761        else if (RTUtf16ICmpAscii(pwszFlags, "no-dups") == 0)
     1762            fFlags = 0;
     1763        else
     1764            return ErrorBadArg("flags", pwszFlags, "'dup' or 'no-dups'");
     1765    }
     1766
     1767    /*
     1768     * Do the work.
     1769     */
     1770    int rcExit = RegistryAddStringToList(hRootKey, pwszSubKey, pwszValueName, pwszItem, uPosition, fFlags);
     1771    if (rcExit == EXIT_OK)
     1772        PrintSWSWSWSWS("Successfully added '", pwszItem, "' to ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "'/'",
     1773                       pwszValueName, "'\r\n");
    14701774
    14711775    return rcExit;
     
    14801784 *
    14811785 * @return  Exit code (EXIT_OK, EXIT_FAIL)
     1786 * @param   hRootKey            The root key.
    14821787 * @param   pwszSubKey          Subkey containing the list value.
    14831788 * @param   pwszValueName       The value name.
    1484  * @param   pwszItemToRemove    The item to remove from the list.
    1485  */
    1486 static int RegistryRemoveStringFromList(const wchar_t *pwszSubKey, const wchar_t *pwszValueName, const wchar_t *pwszItemToRemove)
     1789 * @param   pwszItemToRemove    The item to remove from the list.  Empty values
     1790 *                              are not supported.
     1791 */
     1792static int RegistryRemoveStringFromList(HKEY hRootKey, const wchar_t *pwszSubKey, const wchar_t *pwszValueName,
     1793                                        const wchar_t *pwszItemToRemove)
    14871794{
    14881795    /*
     
    14921799    LSTATUS lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszSubKey, 0 /*dwOptions*/, KEY_READ | KEY_WRITE, &hKey);
    14931800    if (lrc != ERROR_SUCCESS)
    1494         return ErrorMsgLStatusSWSRS("RegistryRemoveStringFromList: RegOpenKeyExW HKLM/'", pwszSubKey, "' failed: ", lrc, NULL);
     1801        return ErrorMsgLStatusSWSWSRS("RegistryRemoveStringFromList: RegOpenKeyExW ", RegistryRootToWStr(hRootKey),
     1802                                      "/'", pwszSubKey, "' failed: ", lrc, NULL);
    14951803
    14961804    /*
     
    15361844            ASMCompilerBarrier(); /* Paranoia ^ 2 */
    15371845            if (IsStringListItemMatch(pwszSrc, cwcItem, pwszItemToRemove, cwcItemToRemove))
     1846            {
    15381847                pwszSrc = pwszSrcEnd;
     1848                if (!fLeadingComma)
     1849                    while (*pwszSrc == ',')
     1850                        pwszSrc++;
     1851            }
    15391852            else
    15401853            {
     
    15661879                rcExit = EXIT_OK;
    15671880            else
    1568                 ErrorMsgLStatusSWSWSWSRS("RegistryRemoveStringFromList: RegSetValueExW HKLM/'",
    1569                                          pwszSubKey, "'/'", pwszValueName, "' = '", wszValue, "' failed: ", lrc, NULL);
     1881                ErrorMsgLStatusSWSWSWSWSRS("RegistryRemoveStringFromList: RegSetValueExW ", RegistryRootToWStr(hRootKey), "/'",
     1882                                           pwszSubKey, "'/'", pwszValueName, "' = '", wszValue, "' failed: ", lrc, NULL);
    15701883        }
    15711884    }
     
    15781891    }
    15791892    else if (lrc != ERROR_SUCCESS)
    1580         ErrorMsgLStatusSWSWSRS("RegistryRemoveStringFromList: RegQueryValueEx HKLM/'",
    1581                                pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);
     1893        ErrorMsgLStatusSWSWSWSRS("RegistryRemoveStringFromList: RegQueryValueEx ", RegistryRootToWStr(hRootKey), "/'",
     1894                                 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);
    15821895    else
    1583         ErrorMsgLStatusSWSWSRS("RegistryRemoveStringFromList: Unexpected value type for HKLM/'",
    1584                                pwszSubKey, "'/'", pwszValueName, "': ", (LSTATUS)dwType, ", expected REG_SZ (1)");
     1896        ErrorMsgLStatusSWSWSWSRS("RegistryRemoveStringFromList: Unexpected value type for ", RegistryRootToWStr(hRootKey), "/'",
     1897                                 pwszSubKey, "'/'", pwszValueName, "': ", (LSTATUS)dwType, ", expected REG_SZ (1)");
    15851898    RegCloseKey(hKey);
    15861899    return rcExit;
     
    15961909    PrintSWS("Removing network provider '", pwszProvider, "' ...\r\n");
    15971910
    1598     int rcExit = RegistryRemoveStringFromList(L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
     1911    int rcExit = RegistryRemoveStringFromList(HKEY_LOCAL_MACHINE,
     1912                                              L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order",
    15991913                                              L"ProviderOrder",
    16001914                                              pwszProvider);
     
    16081922
    16091923/**
    1610  * Worker for the 'service create' handler.
    1611  */
    1612 static int CreateService(const wchar_t *pwszService,
    1613                          const wchar_t *pwszDisplayName,
    1614                          uint32_t       uServiceType,
    1615                          uint32_t       uStartType,
    1616                          const wchar_t *pwszBinPath,
    1617                          const wchar_t *pwszLoadOrderGroup,
    1618                          const wchar_t *pwszDependencies,
    1619                          const wchar_t *pwszLogonUser,
    1620                          const wchar_t *pwszLogonPassword)
    1621 {
    1622     PrintSWSWS("Installing service '", pwszService, "' ('", pwszDisplayName, ") ...\r\n");
    1623 
    1624     /*
    1625      * Transform the dependency list to a REG_MULTI_SZ.
    1626      */
    1627     if (pwszDependencies != NULL)
    1628     {
    1629         /* Copy it into alloca() buffer so we can modify it. */
    1630         size_t cwc = RTUtf16Len(pwszDependencies);
    1631         wchar_t *pwszDup = (wchar_t *)alloca((cwc + 2) * sizeof(wchar_t));
    1632         memcpy(pwszDup, pwszDependencies, cwc * sizeof(wchar_t));
    1633         pwszDup[cwc]     = L'\0';
    1634         pwszDup[cwc + 1] = L'\0';   /* double termination */
    1635 
    1636         /* Perform: s/,/\0/g */
    1637         while (cwc-- > 0 )
    1638             if (pwszDup[cwc] == L',')
    1639                 pwszDup[cwc] = L'\0';
    1640 
    1641         pwszDependencies = pwszDup;
    1642     }
    1643 
    1644     SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    1645     if (hSCManager == NULL)
    1646         return ErrorMsgLastErr("OpenSCManagerW failed");
    1647 
    1648     int rcExit = EXIT_FAIL;
    1649     DWORD dwTag = 0xDEADBEAF;
    1650     SC_HANDLE hService = CreateServiceW(hSCManager, pwszService, pwszDisplayName, SERVICE_ALL_ACCESS, uServiceType, uStartType,
    1651                                         SERVICE_ERROR_NORMAL, pwszBinPath, pwszLoadOrderGroup, pwszLoadOrderGroup ? &dwTag : NULL,
    1652                                         pwszDependencies, pwszLogonUser, pwszLogonPassword);
    1653     if (hService != NULL)
    1654     {
    1655         CloseServiceHandle(hService);
    1656         PrintStr("Installation of service successful!\r\n");
    1657         rcExit = EXIT_OK;
    1658     }
    1659     else
    1660     {
    1661         DWORD dwErr = GetLastError();
    1662         if (dwErr == ERROR_SERVICE_EXISTS)
    1663         {
    1664             PrintStr("Service already exists. Updating the service config ...\r\n");
    1665             hService = OpenServiceW(hSCManager, pwszService, SERVICE_ALL_ACCESS);
    1666             if (hService != NULL)
    1667             {
    1668                 if (ChangeServiceConfigW(hService, uServiceType, uStartType, SERVICE_ERROR_NORMAL, pwszBinPath,
    1669                                          pwszLoadOrderGroup, pwszLoadOrderGroup ? &dwTag : NULL, pwszDependencies,
    1670                                          pwszLogonUser, pwszLogonPassword, pwszDisplayName))
    1671                 {
    1672                     PrintStr("The service config has been successfully updated.\r\n");
    1673                     rcExit = EXIT_OK;
    1674                 }
    1675                 else
    1676                     rcExit = ErrorMsgLastErrSWS("ChangeServiceConfigW failed on '", pwszService, "'!");
    1677                 CloseServiceHandle(hService);
    1678             }
    1679             else
    1680                 rcExit = ErrorMsgLastErrSWS("OpenSCManagerW failed on '", pwszService, "'!");
    1681 
    1682             /*
    1683              * This branch does not return an error to avoid installations failures,
    1684              * if updating service parameters. Better to have a running system with old
    1685              * parameters and the failure information in the installation log.
    1686              */
    1687             rcExit = EXIT_OK;
    1688         }
    1689         else
    1690             rcExit = ErrorMsgLastErrSWS("CreateServiceW for '", pwszService, "'!");
    1691     }
    1692 
    1693     CloseServiceHandle(hSCManager);
     1924 * Handles 'registry dellistitem'.
     1925 */
     1926static int handleRegistryDelListItem(unsigned cArgs, wchar_t **papwszArgs)
     1927{
     1928    /*
     1929     * Parameters.
     1930     */
     1931    RT_NOREF(cArgs);
     1932    wchar_t const * const pwszRoot      = papwszArgs[0];
     1933    wchar_t const * const pwszSubKey    = papwszArgs[1];
     1934    wchar_t const * const pwszValueName = papwszArgs[2];
     1935    wchar_t const * const pwszItem      = papwszArgs[3];
     1936
     1937    HKEY hRootKey = ArgToRegistryRoot(pwszRoot);
     1938    if (hRootKey == NULL)
     1939        return EXIT_USAGE;
     1940
     1941    /*
     1942     * Do the work.
     1943     */
     1944    int rcExit = RegistryRemoveStringFromList(hRootKey, pwszSubKey, pwszValueName, pwszItem);
     1945    if (rcExit == EXIT_OK)
     1946        PrintSWSWSWSWS("Successfully removed '", pwszItem, "' from ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "'/'",
     1947                       pwszValueName, "'\r\n");
     1948
    16941949    return rcExit;
    1695 }
    1696 
    1697 
    1698 /** Handles 'service create'. */
    1699 static int handleServiceCreate(unsigned cArgs, wchar_t **papwszArgs)
    1700 {
    1701     uint32_t uServiceType;
    1702     if (!ArgToUInt32Full(papwszArgs[2], "service-type", &uServiceType))
    1703         return EXIT_USAGE;
    1704 
    1705     uint32_t uStartType;
    1706     if (!ArgToUInt32Full(papwszArgs[3], "start-type", &uStartType))
    1707         return EXIT_USAGE;
    1708 
    1709     return CreateService(papwszArgs[0], papwszArgs[1], uServiceType, uStartType, papwszArgs[4],
    1710                          cArgs > 5 ? papwszArgs[5] : NULL,
    1711                          cArgs > 6 ? papwszArgs[6] : NULL,
    1712                          cArgs > 7 ? papwszArgs[7] : NULL,
    1713                          cArgs > 8 ? papwszArgs[8] : NULL);
    1714 }
    1715 
    1716 
    1717 /**
    1718  * Worker for the 'service delete' handler.
    1719  */
    1720 static int DelService(const wchar_t *pwszService)
    1721 {
    1722     PrintSWS("Removing service '", pwszService, "' ...\r\n");
    1723 
    1724     SC_HANDLE hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    1725     if (hSCManager == NULL)
    1726         return ErrorMsgLastErr("OpenSCManagerW failed");
    1727 
    1728     int rcExit = EXIT_FAIL;
    1729     SC_HANDLE hService = NULL;
    1730     hService = OpenServiceW(hSCManager, pwszService, SERVICE_ALL_ACCESS);
    1731     if (hService)
    1732     {
    1733         SC_LOCK hSCLock = LockServiceDatabase(hSCManager);
    1734         if (hSCLock != NULL)
    1735         {
    1736             if (DeleteService(hService))
    1737             {
    1738                 PrintSWS("Service '", pwszService, "' successfully deleted.\r\n");
    1739                 rcExit = EXIT_OK;
    1740             }
    1741             else
    1742             {
    1743                 DWORD dwErr = GetLastError();
    1744                 if (dwErr == ERROR_SERVICE_MARKED_FOR_DELETE)
    1745                 {
    1746                     PrintSWS("Service '", pwszService, "' already marked for deletion.\r\n");
    1747                     rcExit = EXIT_OK;
    1748                 }
    1749                 else
    1750                     rcExit = ErrorMsgLastErrSWS("Failed to delete service'", pwszService, "'!");
    1751             }
    1752             UnlockServiceDatabase(hSCLock);
    1753         }
    1754         else
    1755             ErrorMsgLastErr("LockServiceDatabase failed");
    1756         CloseServiceHandle(hService);
    1757     }
    1758     else
    1759         rcExit = ErrorMsgLastErrSWS("Failed to open service'", pwszService, "'!");
    1760     CloseServiceHandle(hSCManager);
    1761     return rcExit;
    1762 }
    1763 
    1764 
    1765 /** Handles 'service delete' */
    1766 static int handleServiceDelete(unsigned cArgs, wchar_t **papwszArgs)
    1767 {
    1768     RT_NOREF(cArgs);
    1769     return DelService(papwszArgs[0]);
    1770 }
    1771 
    1772 
    1773 static HKEY ArgToRegistryRoot(const wchar_t *pwszRoot)
    1774 {
    1775     HKEY hRootKey = NULL;
    1776     if (RTUtf16ICmpAscii(pwszRoot, "hklm") == 0)
    1777         hRootKey = HKEY_LOCAL_MACHINE;
    1778     else if (RTUtf16ICmpAscii(pwszRoot, "hkcu") == 0)
    1779         hRootKey = HKEY_CURRENT_USER;
    1780     else if (RTUtf16ICmpAscii(pwszRoot, "hkcr") == 0)
    1781         hRootKey = HKEY_CLASSES_ROOT;
    1782     else if (RTUtf16ICmpAscii(pwszRoot, "hku") == 0)
    1783         hRootKey = HKEY_USERS;
    1784     else if (RTUtf16ICmpAscii(pwszRoot, "hkcc") == 0)
    1785         hRootKey = HKEY_CURRENT_CONFIG;
    1786     else
    1787         ErrorBadArg("root", pwszRoot, "hklm, hkcu, hkcr, hku or hkcc");
    1788     return hRootKey;
    17891950}
    17901951
     
    18071968     * Root key:
    18081969     */
    1809     HKEY hRootKey = ArgToRegistryRoot(papwszArgs[0]);
     1970    HKEY hRootKey = ArgToRegistryRoot(pwszRoot);
    18101971    if (hRootKey == NULL)
    18111972        return EXIT_USAGE;
     
    19042065                                   KEY_WRITE, NULL /*pSecAttr*/, &hKey, NULL /*pdwDisposition*/);
    19052066    if (lrc != ERROR_SUCCESS)
    1906         return ErrorMsgLStatusSWSWSRS("RegCreateKeyExW ", pwszRoot, "/'", pwszSubKey, "' failed: ", lrc, NULL);
     2067        return ErrorMsgLStatusSWSWSRS("RegCreateKeyExW ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "' failed: ", lrc, NULL);
    19072068
    19082069    lrc = RegSetValueExW(hKey, pwszValueName, 0, dwType, pbValue, cbValue);
    19092070    RegCloseKey(hKey);
    19102071    if (lrc != ERROR_SUCCESS)
    1911         return ErrorMsgLStatusSWSWSWSRS("RegSetValueExW ", pwszRoot, "/'", pwszSubKey, "'/'",
     2072        return ErrorMsgLStatusSWSWSWSRS("RegSetValueExW ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "'/'",
    19122073                                        pwszValueName, "' failed: ",  lrc, NULL);
    19132074    return EXIT_OK;
     
    19922153             "    VBoxDrvInst registry addmultisz <sub-key> <value-name> <to-add> <position>\r\n"
    19932154             "    VBoxDrvInst registry delmultisz <sub-key> <value-name> <to-remove>\r\n"
     2155             "    VBoxDrvInst registry addlistitem <root> <sub-key> <value-name> <to-add>\r\n"
     2156             "        [position [dup|no-dup]]\r\n"
     2157             "    VBoxDrvInst registry dellistitem <root> <sub-key> <value-name> <to-remove>\r\n"
    19942158             "\r\n"
    19952159             "Standard options:\r\n"
     
    20182182        { "driver",         "uninstall",    1,  2, handleDriverUninstall },
    20192183        { "driver",         "executeinf",   1,  1, handleDriverExecuteInf },
     2184        { "service",        "create",       5,  9, handleServiceCreate },
     2185        { "service",        "delete",       1,  1, handleServiceDelete },
    20202186        { "netprovider",    "add",          1,  2, handleNetProviderAdd },
    20212187        { "netprovider",    "remove",       1,  2, handleNetProviderRemove },
    2022         { "service",        "create",       5,  9, handleServiceCreate },
    2023         { "service",        "delete",       1,  1, handleServiceDelete },
     2188        { "registry",       "addlistitem",  4,  6, handleRegistryAddListItem },
     2189        { "registry",       "dellistitem",  4,  4, handleRegistryDelListItem },
    20242190        { "registry",       "addmultisz",   4,  4, handleRegistryAddMultiSz },
    20252191        { "registry",       "delmultisz",   3,  3, handleRegistryDelMultiSz },
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