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.

567 lines
16 KiB

  1. //==============================================================;
  2. //
  3. // This source code is only intended as a supplement to existing Microsoft documentation.
  4. //
  5. //
  6. //
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  9. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  10. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  11. // PURPOSE.
  12. //
  13. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  14. //
  15. //
  16. //
  17. //==============================================================;
  18. #include <objbase.h>
  19. #include <assert.h>
  20. #include "Registry.h"
  21. #include "Extend.h"
  22. #include "GUIDs.h"
  23. #include "globals.h"
  24. // if not standalone comment out next line
  25. //#define STANDALONE
  26. // list all nodes that are extendable here
  27. // List the GUID and then the description
  28. // terminate with a NULL, NULL set.
  29. EXTENSION_NODE _ExtendableNodes[] = {
  30. {NULL, NULL}
  31. };
  32. // list all of the nodes that we extend
  33. EXTENDER_NODE _NodeExtensions[] = {
  34. {PropertySheetExtension,
  35. {0x29743811, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28}},
  36. {0xcfcdc9f3, 0xc50e, 0x11d2, {0x95, 0x2b, 0x0, 0xc0, 0x4f, 0xb9, 0x2e, 0xc2}},
  37. _T("Extension to the Rocket Node")},
  38. {DummyExtension,
  39. NULL,
  40. NULL,
  41. NULL}
  42. };
  43. ////////////////////////////////////////////////////////
  44. //
  45. // Internal helper functions prototypes
  46. //
  47. // Set the given key and its value.
  48. BOOL setKeyAndValue(const _TCHAR* pszPath,
  49. const _TCHAR* szSubkey,
  50. const _TCHAR* szValue) ;
  51. // Set the given key and its value in the MMC Snapin location
  52. BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
  53. const _TCHAR* szSubkey,
  54. const _TCHAR* szName,
  55. const _TCHAR* szValue);
  56. // Set the given valuename under the key to value
  57. BOOL setValue(const _TCHAR* szKey,
  58. const _TCHAR* szValueName,
  59. const _TCHAR* szValue);
  60. BOOL setSnapInExtensionNode(const _TCHAR* szSnapID,
  61. const _TCHAR* szNodeID,
  62. const _TCHAR* szDescription);
  63. // Delete szKeyChild and all of its descendents.
  64. LONG recursiveDeleteKey(HKEY hKeyParent, const _TCHAR* szKeyChild) ;
  65. ////////////////////////////////////////////////////////
  66. //
  67. // Constants
  68. //
  69. // Size of a CLSID as a string
  70. //const int CLSID_STRING_SIZE = 39 ;
  71. /////////////////////////////////////////////////////////
  72. //
  73. // Public function implementation
  74. //
  75. //
  76. // Register the component in the registry.
  77. //
  78. HRESULT RegisterServer(HMODULE hModule, // DLL module handle
  79. const CLSID& clsid, // Class ID
  80. const _TCHAR* szFriendlyName) // IDs
  81. {
  82. // Get server location.
  83. _TCHAR szModule[512] ;
  84. DWORD dwResult =
  85. ::GetModuleFileName(hModule,
  86. szModule,
  87. sizeof(szModule)/sizeof(_TCHAR)) ;
  88. assert(dwResult != 0) ;
  89. // Get CLSID
  90. LPOLESTR wszCLSID = NULL ;
  91. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  92. assert(SUCCEEDED(hr)) ;
  93. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  94. // Build the key CLSID\\{...}
  95. _TCHAR szKey[64] ;
  96. _tcscpy(szKey, _T("CLSID\\")) ;
  97. _tcscat(szKey, pszCLSID) ;
  98. // Add the CLSID to the registry.
  99. setKeyAndValue(szKey, NULL, szFriendlyName) ;
  100. // Add the server filename subkey under the CLSID key.
  101. setKeyAndValue(szKey, _T("InprocServer32"), szModule) ;
  102. // set the threading model
  103. _tcscat(szKey, _T("\\InprocServer32"));
  104. setValue(szKey, _T("ThreadingModel"), _T("Apartment"));
  105. // Free memory.
  106. CoTaskMemFree(wszCLSID) ;
  107. return S_OK ;
  108. }
  109. //
  110. // Remove the component from the registry.
  111. //
  112. LONG UnregisterServer(const CLSID& clsid) // IDs
  113. {
  114. // Get CLSID
  115. LPOLESTR wszCLSID = NULL ;
  116. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  117. // Build the key CLSID\\{...}
  118. _TCHAR szKey[64] ;
  119. _tcscpy(szKey, _T("CLSID\\")) ;
  120. MAKE_TSTRPTR_FROMWIDE(pszT, wszCLSID);
  121. _tcscat(szKey, pszT) ;
  122. // Delete the CLSID Key - CLSID\{...}
  123. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  124. assert((lResult == ERROR_SUCCESS) ||
  125. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  126. // Free memory.
  127. CoTaskMemFree(wszCLSID) ;
  128. return S_OK ;
  129. }
  130. //
  131. // Register the snap-in in the registry.
  132. //
  133. HRESULT RegisterSnapin(const CLSID& clsid, // Class ID
  134. const _TCHAR* szNameString, // NameString
  135. const CLSID& clsidAbout) // Class Id for About Class
  136. {
  137. // Get CLSID
  138. LPOLESTR wszCLSID = NULL ;
  139. LPOLESTR wszAboutCLSID = NULL;
  140. LPOLESTR wszExtendCLSID = NULL;
  141. LPOLESTR wszNodeCLSID = NULL;
  142. EXTENSION_NODE *pExtensionNode;
  143. EXTENDER_NODE *pNodeExtension;
  144. _TCHAR szKeyBuf[1024] ;
  145. HKEY hKey;
  146. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  147. if (IID_NULL != clsidAbout)
  148. hr = StringFromCLSID(clsidAbout, &wszAboutCLSID);
  149. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  150. MAKE_TSTRPTR_FROMWIDE(pszAboutCLSID, wszAboutCLSID);
  151. // Add the CLSID to the registry.
  152. setSnapInKeyAndValue(pszCLSID, NULL, _T("NameString"), szNameString) ;
  153. #ifdef STANDALONE
  154. setSnapInKeyAndValue(pszCLSID, _T("StandAlone"), NULL, NULL);
  155. #endif
  156. if (IID_NULL != clsidAbout)
  157. setSnapInKeyAndValue(pszCLSID, NULL, _T("About"), pszAboutCLSID);
  158. // register each of the node types in _ExtendableNodes as an extendable node
  159. for (pExtensionNode = &(_ExtendableNodes[0]);*pExtensionNode->szDescription;pExtensionNode++)
  160. {
  161. hr = StringFromCLSID(pExtensionNode->GUID, &wszExtendCLSID);
  162. MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
  163. setSnapInExtensionNode(pszCLSID, pszExtendCLSID, pExtensionNode->szDescription);
  164. CoTaskMemFree(wszExtendCLSID);
  165. }
  166. // register each of the node extensions
  167. for (pNodeExtension = &(_NodeExtensions[0]);*pNodeExtension->szDescription;pNodeExtension++)
  168. {
  169. hr = StringFromCLSID(pNodeExtension->guidNode, &wszExtendCLSID);
  170. MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
  171. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
  172. _tcscat(szKeyBuf, pszExtendCLSID);
  173. switch (pNodeExtension->eType) {
  174. case NameSpaceExtension:
  175. _tcscat(szKeyBuf, _T("\\Extensions\\NameSpace"));
  176. break;
  177. case ContextMenuExtension:
  178. _tcscat(szKeyBuf, _T("\\Extensions\\ContextMenu"));
  179. break;
  180. case ToolBarExtension:
  181. _tcscat(szKeyBuf, _T("\\Extensions\\ToolBar"));
  182. break;
  183. case PropertySheetExtension:
  184. _tcscat(szKeyBuf, _T("\\Extensions\\PropertySheet"));
  185. break;
  186. case TaskExtension:
  187. _tcscat(szKeyBuf, _T("\\Extensions\\Task"));
  188. break;
  189. case DynamicExtension:
  190. _tcscat(szKeyBuf, _T("\\Dynamic Extensions"));
  191. default:
  192. break;
  193. }
  194. // Create and open key and subkey.
  195. long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  196. szKeyBuf,
  197. 0, NULL, REG_OPTION_NON_VOLATILE,
  198. KEY_ALL_ACCESS, NULL,
  199. &hKey, NULL) ;
  200. if (lResult != ERROR_SUCCESS)
  201. {
  202. return FALSE ;
  203. }
  204. hr = StringFromCLSID(pNodeExtension->guidExtension, &wszNodeCLSID);
  205. assert(SUCCEEDED(hr));
  206. MAKE_TSTRPTR_FROMWIDE(pszNodeCLSID, wszNodeCLSID);
  207. // Set the Value.
  208. if (pNodeExtension->szDescription != NULL)
  209. {
  210. RegSetValueEx(hKey, pszNodeCLSID, 0, REG_SZ,
  211. (BYTE *)pNodeExtension->szDescription,
  212. (_tcslen(pNodeExtension->szDescription)+1)*sizeof(_TCHAR)) ;
  213. }
  214. RegCloseKey(hKey) ;
  215. CoTaskMemFree(wszExtendCLSID);
  216. CoTaskMemFree(wszNodeCLSID);
  217. }
  218. // Free memory.
  219. CoTaskMemFree(wszCLSID) ;
  220. if (IID_NULL != clsidAbout)
  221. CoTaskMemFree(wszAboutCLSID);
  222. return S_OK ;
  223. }
  224. //
  225. // Unregister the snap-in in the registry.
  226. //
  227. HRESULT UnregisterSnapin(const CLSID& clsid) // Class ID
  228. {
  229. _TCHAR szKeyBuf[1024];
  230. LPOLESTR wszCLSID = NULL;
  231. // Get CLSID
  232. HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  233. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  234. // Load the buffer with the Snap-In Location
  235. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
  236. // Copy keyname into buffer.
  237. _tcscat(szKeyBuf, _T("\\"));
  238. _tcscat(szKeyBuf, pszCLSID);
  239. // Delete the CLSID Key - CLSID\{...}
  240. LONG lResult = recursiveDeleteKey(HKEY_LOCAL_MACHINE, szKeyBuf);
  241. assert((lResult == ERROR_SUCCESS) ||
  242. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  243. //Uncomment following for loop to unregister all extendable node types
  244. //Note that if a snap-in's extendable node types are unregistered,
  245. //any extension snap-ins for these node types will have to be re-registered
  246. //in order to rebuild their entries under the SOFTWARE\Microsoft\MMC\NodeTypes key
  247. /*
  248. // Unregister each of the node types in _ExtendableNodes as an extendable node
  249. // Note that this snap-in does not register any extendable node types
  250. EXTENSION_NODE *pNode;
  251. LPOLESTR wszExtendCLSID = NULL;
  252. for (pNode = &(_ExtendableNodes[0]);*pNode->szDescription;pNode++)
  253. {
  254. hr = StringFromCLSID(pNode->GUID, &wszExtendCLSID);
  255. MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
  256. // Load the buffer with the Snap-In Location
  257. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
  258. // Copy keyname into buffer.
  259. _tcscat(szKeyBuf, pszExtendCLSID);
  260. recursiveDeleteKey(HKEY_LOCAL_MACHINE, szKeyBuf);
  261. CoTaskMemFree(wszExtendCLSID);
  262. }
  263. */
  264. // free the memory
  265. CoTaskMemFree(wszCLSID);
  266. return S_OK;
  267. }
  268. //
  269. // Delete a key and all of its descendents.
  270. //
  271. LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  272. const _TCHAR* lpszKeyChild) // Key to delete
  273. {
  274. // Open the child.
  275. HKEY hKeyChild ;
  276. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  277. KEY_ALL_ACCESS, &hKeyChild) ;
  278. if (lRes != ERROR_SUCCESS)
  279. {
  280. return lRes ;
  281. }
  282. // Enumerate all of the decendents of this child.
  283. FILETIME time ;
  284. _TCHAR szBuffer[256] ;
  285. DWORD dwSize = 256 ;
  286. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  287. NULL, NULL, &time) == S_OK)
  288. {
  289. // Delete the decendents of this child.
  290. lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
  291. if (lRes != ERROR_SUCCESS)
  292. {
  293. // Cleanup before exiting.
  294. RegCloseKey(hKeyChild) ;
  295. return lRes;
  296. }
  297. dwSize = 256 ;
  298. }
  299. // Close the child.
  300. RegCloseKey(hKeyChild) ;
  301. // Delete this child.
  302. return RegDeleteKey(hKeyParent, lpszKeyChild) ;
  303. }
  304. //
  305. // Create a key and set its value.
  306. // - This helper function was borrowed and modifed from
  307. // Kraig Brockschmidt's book Inside OLE.
  308. //
  309. BOOL setKeyAndValue(const _TCHAR* szKey,
  310. const _TCHAR* szSubkey,
  311. const _TCHAR* szValue)
  312. {
  313. HKEY hKey;
  314. _TCHAR szKeyBuf[1024] ;
  315. // Copy keyname into buffer.
  316. _tcscpy(szKeyBuf, szKey) ;
  317. // Add subkey name to buffer.
  318. if (szSubkey != NULL)
  319. {
  320. _tcscat(szKeyBuf, _T("\\")) ;
  321. _tcscat(szKeyBuf, szSubkey ) ;
  322. }
  323. // Create and open key and subkey.
  324. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  325. szKeyBuf,
  326. 0, NULL, REG_OPTION_NON_VOLATILE,
  327. KEY_ALL_ACCESS, NULL,
  328. &hKey, NULL) ;
  329. if (lResult != ERROR_SUCCESS)
  330. {
  331. return FALSE ;
  332. }
  333. // Set the Value.
  334. if (szValue != NULL)
  335. {
  336. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  337. (BYTE *)szValue,
  338. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  339. }
  340. RegCloseKey(hKey) ;
  341. return TRUE ;
  342. }
  343. //
  344. // Open a key value and set it
  345. //
  346. BOOL setValue(const _TCHAR* szKey,
  347. const _TCHAR* szValueName,
  348. const _TCHAR* szValue)
  349. {
  350. HKEY hKey;
  351. _TCHAR szKeyBuf[1024] ;
  352. // Copy keyname into buffer.
  353. _tcscpy(szKeyBuf, szKey) ;
  354. // Create and open key and subkey.
  355. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  356. szKeyBuf,
  357. 0, NULL, REG_OPTION_NON_VOLATILE,
  358. KEY_ALL_ACCESS, NULL,
  359. &hKey, NULL) ;
  360. if (lResult != ERROR_SUCCESS)
  361. {
  362. return FALSE ;
  363. }
  364. // Set the Value.
  365. if (szValue != NULL)
  366. {
  367. RegSetValueEx(hKey, szValueName, 0, REG_SZ,
  368. (BYTE *)szValue,
  369. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  370. }
  371. RegCloseKey(hKey) ;
  372. return TRUE ;
  373. }
  374. //
  375. // Create a key and set its value.
  376. // - This helper function was borrowed and modifed from
  377. // Kraig Brockschmidt's book Inside OLE.
  378. //
  379. BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
  380. const _TCHAR* szSubkey,
  381. const _TCHAR* szName,
  382. const _TCHAR* szValue)
  383. {
  384. HKEY hKey;
  385. _TCHAR szKeyBuf[1024] ;
  386. // Load the buffer with the Snap-In Location
  387. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
  388. // Copy keyname into buffer.
  389. _tcscat(szKeyBuf, _T("\\")) ;
  390. _tcscat(szKeyBuf, szKey) ;
  391. // Add subkey name to buffer.
  392. if (szSubkey != NULL)
  393. {
  394. _tcscat(szKeyBuf, _T("\\")) ;
  395. _tcscat(szKeyBuf, szSubkey ) ;
  396. }
  397. // Create and open key and subkey.
  398. long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  399. szKeyBuf,
  400. 0, NULL, REG_OPTION_NON_VOLATILE,
  401. KEY_ALL_ACCESS, NULL,
  402. &hKey, NULL) ;
  403. if (lResult != ERROR_SUCCESS)
  404. {
  405. return FALSE ;
  406. }
  407. // Set the Value.
  408. if (szValue != NULL)
  409. {
  410. RegSetValueEx(hKey, szName, 0, REG_SZ,
  411. (BYTE *)szValue,
  412. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  413. }
  414. RegCloseKey(hKey) ;
  415. return TRUE ;
  416. }
  417. BOOL setSnapInExtensionNode(const _TCHAR* szSnapID,
  418. const _TCHAR* szNodeID,
  419. const _TCHAR* szDescription)
  420. {
  421. HKEY hKey;
  422. _TCHAR szSnapNodeKeyBuf[1024] ;
  423. _TCHAR szMMCNodeKeyBuf[1024];
  424. // Load the buffer with the Snap-In Location
  425. _tcscpy(szSnapNodeKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns\\"));
  426. // add in the clisid into buffer.
  427. _tcscat(szSnapNodeKeyBuf, szSnapID) ;
  428. _tcscat(szSnapNodeKeyBuf, _T("\\NodeTypes\\"));
  429. _tcscat(szSnapNodeKeyBuf, szNodeID) ;
  430. // Load the buffer with the NodeTypes Location
  431. _tcscpy(szMMCNodeKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
  432. _tcscat(szMMCNodeKeyBuf, szNodeID) ;
  433. // Create and open the Snapin Key.
  434. long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  435. szSnapNodeKeyBuf,
  436. 0, NULL, REG_OPTION_NON_VOLATILE,
  437. KEY_ALL_ACCESS, NULL,
  438. &hKey, NULL) ;
  439. if (lResult != ERROR_SUCCESS)
  440. {
  441. return FALSE ;
  442. }
  443. // Set the Value.
  444. if (szDescription != NULL)
  445. {
  446. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  447. (BYTE *)szDescription,
  448. (_tcslen(szDescription)+1)*sizeof(_TCHAR)) ;
  449. }
  450. RegCloseKey(hKey) ;
  451. // Create and open the NodeTypes Key.
  452. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  453. szMMCNodeKeyBuf,
  454. 0, NULL, REG_OPTION_NON_VOLATILE,
  455. KEY_ALL_ACCESS, NULL,
  456. &hKey, NULL) ;
  457. if (lResult != ERROR_SUCCESS)
  458. {
  459. return FALSE ;
  460. }
  461. // Set the Value.
  462. if (szDescription != NULL)
  463. {
  464. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  465. (BYTE *)szDescription,
  466. (_tcslen(szDescription)+1)*sizeof(_TCHAR)) ;
  467. }
  468. RegCloseKey(hKey) ;
  469. return TRUE ;
  470. }