Changeset 96437 in vbox
- Timestamp:
- Aug 23, 2022 10:59:53 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Installer/VBoxDrvInst.cpp
r96422 r96437 355 355 356 356 357 static 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 357 375 static int ErrorBadArg(const char *pszName, wchar_t const *pwszArg, const char *pszValues = NULL) 358 376 { … … 420 438 PrintWStr(pwszMsg6); 421 439 PrintStr(pszMsg7); 440 } 441 442 443 static 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); 422 456 } 423 457 … … 958 992 959 993 994 995 /********************************************************************************************************************************* 996 * 'service' * 997 *********************************************************************************************************************************/ 998 999 /** 1000 * Worker for the 'service create' handler. 1001 */ 1002 static 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'. */ 1089 static 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 */ 1110 static 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' */ 1156 static 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 */ 1172 static 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 */ 1194 static 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 960 1210 /** 961 1211 * Checks if a string is a substring of another one. … … 1291 1541 latter is Vista and later, the former has a big fat warning on it. */ 1292 1542 wchar_t const wcEnd = pwszItem1[cwcItem1]; 1543 pwszItem1[cwcItem1] = '\0'; 1293 1544 int const iDiff = lstrcmpiW((wchar_t const *)pwszItem1, pwszItem2); 1294 1545 pwszItem1[cwcItem1] = wcEnd; … … 1314 1565 * @param fFlags VBOX_REG_STRINGLIST_ALLOW_DUPLICATES or 0. 1315 1566 */ 1316 static int RegistryAddStringToList( const wchar_t *pwszSubKey, const wchar_t *pwszValueName, const wchar_t *pwszItemToAdd,1317 uint32_t uPosition, uint32_t fFlags)1567 static int RegistryAddStringToList(HKEY hRootKey, const wchar_t *pwszSubKey, const wchar_t *pwszValueName, 1568 const wchar_t *pwszItemToAdd, uint32_t uPosition, uint32_t fFlags) 1318 1569 { 1319 1570 /* Overflow precaution - see comment below. */ … … 1327 1578 HKEY hKey = NULL; 1328 1579 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, 1330 1581 KEY_READ | KEY_WRITE, NULL /*pSecAttr*/, &hKey, &dwDisp); 1331 1582 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); 1333 1585 1334 1586 /* … … 1365 1617 wchar_t *pwszDst = wszNewValue; 1366 1618 wchar_t *pwszSrc = wszValue; 1367 unsigned uCurPos = 0; 1368 for (;;) 1619 for (unsigned uCurPos = 0;; uCurPos++) 1369 1620 { 1370 1621 /* Skip leading commas: */ … … 1380 1631 if (uCurPos == uPosition || (!wc && uCurPos < uPosition)) 1381 1632 { 1382 if (fLeadingComma )1633 if (fLeadingComma || (wc == '\0' && pwszDst != wszNewValue)) 1383 1634 *pwszDst++ = ','; 1384 1635 memcpy(pwszDst, pwszItemToAdd, cwcItemToAdd * sizeof(wchar_t)); … … 1403 1654 if ( !(fFlags & VBOX_REG_STRINGLIST_ALLOW_DUPLICATES) 1404 1655 && IsStringListItemMatch(pwszSrc, cwcItem, pwszItemToAdd, cwcItemToAdd)) 1656 { 1405 1657 pwszSrc = pwszSrcEnd; 1658 if (!fLeadingComma) 1659 while (*pwszSrc == ',') 1660 pwszSrc++; 1661 uCurPos--; 1662 } 1406 1663 else 1407 1664 { … … 1440 1697 } 1441 1698 else if (lrc != ERROR_SUCCESS) 1442 ErrorMsgLStatusSWSWS RS("RegistryAddStringToList: RegQueryValueEx HKLM/'",1443 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);1699 ErrorMsgLStatusSWSWSWSRS("RegistryAddStringToList: RegQueryValueEx ", RegistryRootToWStr(hRootKey), "/'", 1700 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL); 1444 1701 else 1445 ErrorMsgLStatusSWSWS RS("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)"); 1447 1704 1448 1705 RegCloseKey(hKey); … … 1463 1720 1464 1721 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", 1466 1724 L"ProviderOrder", 1467 1725 pwszProvider, uPosition, VBOX_REG_STRINGLIST_NONE); 1468 1726 if (rcExit == EXIT_OK) 1469 1727 PrintStr("Network provider successfully added!\r\n"); 1728 1729 return rcExit; 1730 } 1731 1732 1733 /** 1734 * Handles 'registry addlistitem'. 1735 */ 1736 static 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"); 1470 1774 1471 1775 return rcExit; … … 1480 1784 * 1481 1785 * @return Exit code (EXIT_OK, EXIT_FAIL) 1786 * @param hRootKey The root key. 1482 1787 * @param pwszSubKey Subkey containing the list value. 1483 1788 * @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 */ 1792 static int RegistryRemoveStringFromList(HKEY hRootKey, const wchar_t *pwszSubKey, const wchar_t *pwszValueName, 1793 const wchar_t *pwszItemToRemove) 1487 1794 { 1488 1795 /* … … 1492 1799 LSTATUS lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszSubKey, 0 /*dwOptions*/, KEY_READ | KEY_WRITE, &hKey); 1493 1800 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); 1495 1803 1496 1804 /* … … 1536 1844 ASMCompilerBarrier(); /* Paranoia ^ 2 */ 1537 1845 if (IsStringListItemMatch(pwszSrc, cwcItem, pwszItemToRemove, cwcItemToRemove)) 1846 { 1538 1847 pwszSrc = pwszSrcEnd; 1848 if (!fLeadingComma) 1849 while (*pwszSrc == ',') 1850 pwszSrc++; 1851 } 1539 1852 else 1540 1853 { … … 1566 1879 rcExit = EXIT_OK; 1567 1880 else 1568 ErrorMsgLStatusSWSWSWS RS("RegistryRemoveStringFromList: RegSetValueExW HKLM/'",1569 pwszSubKey, "'/'", pwszValueName, "' = '", wszValue, "' failed: ", lrc, NULL);1881 ErrorMsgLStatusSWSWSWSWSRS("RegistryRemoveStringFromList: RegSetValueExW ", RegistryRootToWStr(hRootKey), "/'", 1882 pwszSubKey, "'/'", pwszValueName, "' = '", wszValue, "' failed: ", lrc, NULL); 1570 1883 } 1571 1884 } … … 1578 1891 } 1579 1892 else if (lrc != ERROR_SUCCESS) 1580 ErrorMsgLStatusSWSWS RS("RegistryRemoveStringFromList: RegQueryValueEx HKLM/'",1581 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL);1893 ErrorMsgLStatusSWSWSWSRS("RegistryRemoveStringFromList: RegQueryValueEx ", RegistryRootToWStr(hRootKey), "/'", 1894 pwszSubKey, "'/'", pwszValueName, "' failed: ", lrc, NULL); 1582 1895 else 1583 ErrorMsgLStatusSWSWS RS("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)"); 1585 1898 RegCloseKey(hKey); 1586 1899 return rcExit; … … 1596 1909 PrintSWS("Removing network provider '", pwszProvider, "' ...\r\n"); 1597 1910 1598 int rcExit = RegistryRemoveStringFromList(L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order", 1911 int rcExit = RegistryRemoveStringFromList(HKEY_LOCAL_MACHINE, 1912 L"System\\CurrentControlSet\\Control\\NetworkProvider\\Order", 1599 1913 L"ProviderOrder", 1600 1914 pwszProvider); … … 1608 1922 1609 1923 /** 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 */ 1926 static 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 1694 1949 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 else1742 {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 else1750 rcExit = ErrorMsgLastErrSWS("Failed to delete service'", pwszService, "'!");1751 }1752 UnlockServiceDatabase(hSCLock);1753 }1754 else1755 ErrorMsgLastErr("LockServiceDatabase failed");1756 CloseServiceHandle(hService);1757 }1758 else1759 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 else1787 ErrorBadArg("root", pwszRoot, "hklm, hkcu, hkcr, hku or hkcc");1788 return hRootKey;1789 1950 } 1790 1951 … … 1807 1968 * Root key: 1808 1969 */ 1809 HKEY hRootKey = ArgToRegistryRoot(p apwszArgs[0]);1970 HKEY hRootKey = ArgToRegistryRoot(pwszRoot); 1810 1971 if (hRootKey == NULL) 1811 1972 return EXIT_USAGE; … … 1904 2065 KEY_WRITE, NULL /*pSecAttr*/, &hKey, NULL /*pdwDisposition*/); 1905 2066 if (lrc != ERROR_SUCCESS) 1906 return ErrorMsgLStatusSWSWSRS("RegCreateKeyExW ", pwszRoot, "/'", pwszSubKey, "' failed: ", lrc, NULL);2067 return ErrorMsgLStatusSWSWSRS("RegCreateKeyExW ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "' failed: ", lrc, NULL); 1907 2068 1908 2069 lrc = RegSetValueExW(hKey, pwszValueName, 0, dwType, pbValue, cbValue); 1909 2070 RegCloseKey(hKey); 1910 2071 if (lrc != ERROR_SUCCESS) 1911 return ErrorMsgLStatusSWSWSWSRS("RegSetValueExW ", pwszRoot, "/'", pwszSubKey, "'/'",2072 return ErrorMsgLStatusSWSWSWSRS("RegSetValueExW ", RegistryRootToWStr(hRootKey), "/'", pwszSubKey, "'/'", 1912 2073 pwszValueName, "' failed: ", lrc, NULL); 1913 2074 return EXIT_OK; … … 1992 2153 " VBoxDrvInst registry addmultisz <sub-key> <value-name> <to-add> <position>\r\n" 1993 2154 " 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" 1994 2158 "\r\n" 1995 2159 "Standard options:\r\n" … … 2018 2182 { "driver", "uninstall", 1, 2, handleDriverUninstall }, 2019 2183 { "driver", "executeinf", 1, 1, handleDriverExecuteInf }, 2184 { "service", "create", 5, 9, handleServiceCreate }, 2185 { "service", "delete", 1, 1, handleServiceDelete }, 2020 2186 { "netprovider", "add", 1, 2, handleNetProviderAdd }, 2021 2187 { "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 }, 2024 2190 { "registry", "addmultisz", 4, 4, handleRegistryAddMultiSz }, 2025 2191 { "registry", "delmultisz", 3, 3, handleRegistryDelMultiSz },
Note:
See TracChangeset
for help on using the changeset viewer.