Leaked source code of windows server 2003
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.

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