Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

463 lines
11 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: regd.cpp
  7. //
  8. // Contents: registry functions for DCOM services
  9. //
  10. // History: July-97 xtan created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <pch.cpp>
  14. #pragma hdrstop
  15. #include <objbase.h>
  16. #include <assert.h>
  17. #include "regd.h"
  18. #define __dwFILE__ __dwFILE_OCMSETUP_REGD_CPP__
  19. // Size of a CLSID as a string
  20. const int CLSID_STRING_SIZE = 39;
  21. extern WCHAR g_wszServicePath[MAX_PATH];
  22. BYTE g_pNoOneLaunchPermission[] = {
  23. 0x01,0x00,0x04,0x80,0x34,0x00,0x00,0x00,
  24. 0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  25. 0x14,0x00,0x00,0x00,0x02,0x00,0x20,0x00,
  26. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  27. 0x3c,0x00,0xb9,0x00,0x07,0x00,0x03,0x00,
  28. 0x00,0x23,0x10,0x00,0x01,0x05,0x00,0x00,
  29. 0x00,0x00,0x00,0x05,0x01,0x05,0x00,0x00,
  30. 0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,
  31. 0xa0,0x5f,0x84,0x1f,0x5e,0x2e,0x6b,0x49,
  32. 0xce,0x12,0x03,0x03,0xf4,0x01,0x00,0x00,
  33. 0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,
  34. 0x15,0x00,0x00,0x00,0xa0,0x5f,0x84,0x1f,
  35. 0x5e,0x2e,0x6b,0x49,0xce,0x12,0x03,0x03,
  36. 0xf4,0x01,0x00,0x00};
  37. BYTE g_pEveryOneAccessPermission[] = {
  38. 0x01,0x00,0x04,0x80,0x34,0x00,0x00,0x00,
  39. 0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  40. 0x14,0x00,0x00,0x00,0x02,0x00,0x20,0x00,
  41. 0x01,0x00,0x00,0x00,0x00,0x00,0x18,0x00,
  42. 0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,
  43. 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
  44. 0x00,0x00,0x00,0x00,0x01,0x05,0x00,0x00,
  45. 0x00,0x00,0x00,0x05,0x15,0x00,0x00,0x00,
  46. 0xa0,0x65,0xcf,0x7e,0x78,0x4b,0x9b,0x5f,
  47. 0xe7,0x7c,0x87,0x70,0x36,0xbb,0x00,0x00,
  48. 0x01,0x05,0x00,0x00,0x00,0x00,0x00,0x05,
  49. 0x15,0x00,0x00,0x00,0xa0,0x65,0xcf,0x7e,
  50. 0x78,0x4b,0x9b,0x5f,0xe7,0x7c,0x87,0x70,
  51. 0x36,0xbb,0x00,0x00 };
  52. //
  53. // Create a key and set its value.
  54. // - This helper function was borrowed and modifed from
  55. // Kraig Brockschmidt's book Inside OLE.
  56. //
  57. HRESULT
  58. setKeyAndValue(
  59. const WCHAR *wszKey,
  60. const WCHAR *wszSubkey,
  61. const WCHAR *wszValueName,
  62. const WCHAR *wszValue)
  63. {
  64. HKEY hKey = NULL;
  65. HRESULT hr;
  66. WCHAR wszKeyBuf[1024] = L"";
  67. // Copy keyname into buffer.
  68. wcscpy(wszKeyBuf, wszKey);
  69. // Add subkey name to buffer.
  70. if (wszSubkey != NULL)
  71. {
  72. wcscat(wszKeyBuf, L"\\");
  73. wcscat(wszKeyBuf, wszSubkey);
  74. }
  75. // Create and open key and subkey.
  76. hr = RegCreateKeyEx(
  77. HKEY_CLASSES_ROOT,
  78. wszKeyBuf,
  79. 0,
  80. NULL,
  81. REG_OPTION_NON_VOLATILE,
  82. KEY_ALL_ACCESS,
  83. NULL,
  84. &hKey,
  85. NULL);
  86. _JumpIfError(hr, error, "RegCreateKeyEx");
  87. // Set the Value.
  88. if (NULL != wszValue)
  89. {
  90. RegSetValueEx(
  91. hKey,
  92. wszValueName,
  93. 0,
  94. REG_SZ,
  95. (BYTE *) wszValue,
  96. (wcslen(wszValue) + 1) * sizeof(WCHAR));
  97. _JumpIfError(hr, error, "RegSetValueEx");
  98. }
  99. error:
  100. if (NULL != hKey)
  101. {
  102. RegCloseKey(hKey);
  103. }
  104. return(hr);
  105. }
  106. HRESULT
  107. setCertSrvPermission(
  108. const WCHAR *wszKey)
  109. {
  110. HKEY hKey = NULL;
  111. HRESULT hr;
  112. // create and open key
  113. hr = RegCreateKeyEx(
  114. HKEY_CLASSES_ROOT,
  115. wszKey,
  116. 0,
  117. NULL,
  118. REG_OPTION_NON_VOLATILE,
  119. KEY_ALL_ACCESS,
  120. NULL,
  121. &hKey,
  122. NULL);
  123. _JumpIfError(hr, error, "RegCreateKeyEx");
  124. // set access permission
  125. hr = RegSetValueEx(
  126. hKey,
  127. L"AccessPermission",
  128. 0,
  129. REG_BINARY,
  130. g_pEveryOneAccessPermission,
  131. sizeof(g_pEveryOneAccessPermission));
  132. _JumpIfError(hr, error, "RegSetValueEx");
  133. // set access permission
  134. hr = RegSetValueEx(
  135. hKey,
  136. L"LaunchPermission",
  137. 0,
  138. REG_BINARY,
  139. g_pNoOneLaunchPermission,
  140. sizeof(g_pNoOneLaunchPermission));
  141. _JumpIfError(hr, error, "RegSetValueEx");
  142. error:
  143. if (NULL != hKey)
  144. {
  145. RegCloseKey(hKey);
  146. }
  147. return(hr);
  148. }
  149. // Convert a CLSID to a char string.
  150. VOID
  151. CLSIDtochar(
  152. const CLSID& clsid,
  153. WCHAR *wszCLSID,
  154. int length)
  155. {
  156. HRESULT hr;
  157. LPOLESTR wszTmpCLSID = NULL;
  158. assert(length >= CLSID_STRING_SIZE);
  159. // Get CLSID
  160. hr = StringFromCLSID(clsid, &wszTmpCLSID);
  161. assert(S_OK == hr);
  162. if (S_OK == hr)
  163. wcscpy(wszCLSID, wszTmpCLSID);
  164. else
  165. wszCLSID[0] = L'\0';
  166. // Free memory.
  167. CoTaskMemFree(wszTmpCLSID);
  168. }
  169. // Determine if a particular subkey exists.
  170. //
  171. BOOL
  172. SubkeyExists(
  173. const WCHAR *wszPath, // Path of key to check
  174. const WCHAR *wszSubkey) // Key to check
  175. {
  176. HRESULT hr;
  177. HKEY hKey;
  178. WCHAR wszKeyBuf[80] = L"";
  179. // Copy keyname into buffer.
  180. wcscpy(wszKeyBuf, wszPath);
  181. // Add subkey name to buffer.
  182. if (wszSubkey != NULL)
  183. {
  184. wcscat(wszKeyBuf, L"\\");
  185. wcscat(wszKeyBuf, wszSubkey);
  186. }
  187. // Determine if key exists by trying to open it.
  188. hr = RegOpenKeyEx(
  189. HKEY_CLASSES_ROOT,
  190. wszKeyBuf,
  191. 0,
  192. KEY_ALL_ACCESS,
  193. &hKey);
  194. if (S_OK == hr)
  195. {
  196. RegCloseKey(hKey);
  197. }
  198. return(S_OK == hr);
  199. }
  200. // Delete a key and all of its descendents.
  201. //
  202. HRESULT
  203. recursiveDeleteKey(
  204. HKEY hKeyParent, // Parent of key to delete
  205. const WCHAR *wszKeyChild) // Key to delete
  206. {
  207. HRESULT hr;
  208. FILETIME time;
  209. WCHAR wszBuffer[MAX_PATH];
  210. DWORD dwSize;
  211. HKEY hKeyChild = NULL;
  212. // Open the child.
  213. hr = RegOpenKeyEx(hKeyParent, wszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild);
  214. _JumpIfError2(hr, error, "RegOpenKeyEx", ERROR_FILE_NOT_FOUND);
  215. // Enumerate all of the decendents of this child.
  216. while (TRUE)
  217. {
  218. dwSize = sizeof(wszBuffer)/sizeof(wszBuffer[0]);
  219. hr = RegEnumKeyEx(
  220. hKeyChild,
  221. 0,
  222. wszBuffer,
  223. &dwSize,
  224. NULL,
  225. NULL,
  226. NULL,
  227. &time);
  228. if (S_OK != hr)
  229. {
  230. break;
  231. }
  232. // Delete the decendents of this child.
  233. hr = recursiveDeleteKey(hKeyChild, wszBuffer);
  234. _JumpIfError(hr, error, "recursiveDeleteKey");
  235. }
  236. // Delete this child.
  237. hr = RegDeleteKey(hKeyParent, wszKeyChild);
  238. _JumpIfError(hr, error, "RegDeleteKey");
  239. error:
  240. if (NULL != hKeyChild)
  241. {
  242. // Close the child.
  243. RegCloseKey(hKeyChild);
  244. }
  245. return(myHError(hr));
  246. }
  247. ///////////////////////////////////////////////////////
  248. //
  249. // Public function implementation
  250. //
  251. //
  252. // Register the component in the registry.
  253. //
  254. HRESULT
  255. RegisterDcomServer(
  256. const CLSID& clsid, // Class ID
  257. const WCHAR *wszFriendlyName, // Friendly Name
  258. const WCHAR *wszVerIndProgID, // Programmatic
  259. const WCHAR *wszProgID) // IDs
  260. {
  261. HRESULT hr;
  262. // Convert the CLSID into a char.
  263. WCHAR wszCLSID[CLSID_STRING_SIZE];
  264. CLSIDtochar(clsid, wszCLSID, sizeof(wszCLSID)/sizeof(WCHAR));
  265. // Build the key CLSID\\{...}
  266. WCHAR wszKey[64];
  267. wcscpy(wszKey, L"AppID\\");
  268. wcscat(wszKey, wszCLSID);
  269. // Add App IDs
  270. hr = setKeyAndValue(wszKey, NULL, NULL, wszFriendlyName);
  271. _JumpIfError(hr, error, "setKeyAndValue");
  272. // run as interactive
  273. hr = setKeyAndValue(wszKey, NULL, L"LocalService", wszSERVICE_NAME);
  274. _JumpIfError(hr, error, "setKeyAndValue");
  275. hr = setCertSrvPermission(wszKey);
  276. _JumpIfError(hr, error, "setCertSrvPermission");
  277. wcscpy(wszKey, L"CLSID\\");
  278. wcscat(wszKey, wszCLSID);
  279. // Add the CLSID to the registry.
  280. hr = setKeyAndValue(wszKey, NULL, NULL, wszFriendlyName);
  281. _JumpIfError(hr, error, "setKeyAndValue");
  282. // Add application ID
  283. hr = setKeyAndValue(wszKey, NULL, L"AppID", wszCLSID);
  284. _JumpIfError(hr, error, "setKeyAndValue");
  285. // Add the server filename subkey under the CLSID key.
  286. hr = setKeyAndValue(wszKey, L"LocalServer32", NULL, g_wszServicePath);
  287. _JumpIfError(hr, error, "setKeyAndValue");
  288. // Add the ProgID subkey under the CLSID key.
  289. hr = setKeyAndValue(wszKey, L"ProgID", NULL, wszProgID);
  290. _JumpIfError(hr, error, "setKeyAndValue");
  291. // Add the version-independent ProgID subkey under CLSID key.
  292. hr = setKeyAndValue(wszKey, L"VersionIndependentProgID", NULL, wszVerIndProgID);
  293. _JumpIfError(hr, error, "setKeyAndValue");
  294. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  295. hr = setKeyAndValue(wszVerIndProgID, NULL, NULL, wszFriendlyName);
  296. _JumpIfError(hr, error, "setKeyAndValue");
  297. hr = setKeyAndValue(wszVerIndProgID, L"CLSID", NULL, wszCLSID);
  298. _JumpIfError(hr, error, "setKeyAndValue");
  299. hr = setKeyAndValue(wszVerIndProgID, L"CurVer", NULL, wszProgID);
  300. _JumpIfError(hr, error, "setKeyAndValue");
  301. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  302. hr = setKeyAndValue(wszProgID, NULL, NULL, wszFriendlyName);
  303. _JumpIfError(hr, error, "setKeyAndValue");
  304. hr = setKeyAndValue(wszProgID, L"CLSID", NULL, wszCLSID);
  305. _JumpIfError(hr, error, "setKeyAndValue");
  306. error:
  307. return(hr);
  308. }
  309. //
  310. // Remove the component from the registry.
  311. //
  312. HRESULT
  313. UnregisterDcomServer(
  314. const CLSID& clsid, // Class ID
  315. const WCHAR *wszVerIndProgID, // Programmatic
  316. const WCHAR *wszProgID) // IDs
  317. {
  318. HRESULT hr;
  319. // Convert the CLSID into a char.
  320. WCHAR wszCLSID[CLSID_STRING_SIZE];
  321. CLSIDtochar(clsid, wszCLSID, sizeof(wszCLSID)/sizeof(WCHAR));
  322. // Build the key CLSID\\{...}
  323. WCHAR wszKey[80];
  324. wcscpy(wszKey, L"CLSID\\");
  325. wcscat(wszKey, wszCLSID);
  326. // Check for a another server for this component.
  327. if (SubkeyExists(wszKey, L"InprocServer32"))
  328. {
  329. // Delete only the path for this server.
  330. wcscat(wszKey, L"\\LocalServer32");
  331. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
  332. assert(hr == S_OK);
  333. }
  334. else
  335. {
  336. // Delete all related keys.
  337. // Delete the CLSID Key - CLSID\{...}
  338. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
  339. assert(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
  340. // Delete the version-independent ProgID Key.
  341. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszVerIndProgID);
  342. assert(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
  343. // Delete the ProgID key.
  344. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszProgID);
  345. assert(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
  346. }
  347. wcscpy(wszKey, L"AppID\\");
  348. wcscat(wszKey, wszCLSID);
  349. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
  350. assert(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
  351. return(hr);
  352. }
  353. HRESULT
  354. RegisterDcomApp(const CLSID& clsid)
  355. {
  356. HRESULT hr;
  357. // Convert the CLSID into a char.
  358. WCHAR wszCLSID[CLSID_STRING_SIZE];
  359. CLSIDtochar(clsid, wszCLSID, sizeof(wszCLSID)/sizeof(WCHAR));
  360. WCHAR wszKey[64];
  361. wcscpy(wszKey, L"AppID\\");
  362. wcscat(wszKey, wszCERTSRVEXENAME);
  363. // Add App IDs
  364. hr = setKeyAndValue(wszKey, NULL, NULL, NULL);
  365. _JumpIfError(hr, error, "setKeyAndValue");
  366. hr = setKeyAndValue(wszKey, NULL, L"AppId", wszCLSID);
  367. _JumpIfError(hr, error, "setKeyAndValue");
  368. error:
  369. return(hr);
  370. }
  371. void
  372. UnregisterDcomApp()
  373. {
  374. HRESULT hr;
  375. WCHAR wszKey[MAX_PATH];
  376. wcscpy(wszKey, L"AppID\\");
  377. wcscat(wszKey, wszCERTSRVEXENAME);
  378. hr = recursiveDeleteKey(HKEY_CLASSES_ROOT, wszKey);
  379. assert(S_OK == hr || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr);
  380. }