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.

450 lines
12 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. #define STRINGS_ONLY
  22. #include "Extend.h"
  23. #include "globals.h"
  24. // list all of the nodes that we extend
  25. EXTENDER_NODE _NodeExtensions[] = {
  26. {ToolBarExtension,
  27. {0x29743811, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28}},
  28. {0x20e42dd2, 0x5ccf, 0x11d3, {0x91, 0x47, 0x0, 0xc0, 0x4f, 0x65, 0xb3, 0xf9}},
  29. _T("Extension to the Vehicle Node Toolbar")},
  30. {DummyExtension,
  31. NULL,
  32. NULL,
  33. NULL}
  34. };
  35. ////////////////////////////////////////////////////////
  36. //
  37. // Internal helper functions prototypes
  38. //
  39. // Set the given key and its value.
  40. BOOL setKeyAndValue(const _TCHAR* pszPath,
  41. const _TCHAR* szSubkey,
  42. const _TCHAR* szValue) ;
  43. // Set the given key and its value in the MMC Snapin location
  44. BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
  45. const _TCHAR* szSubkey,
  46. const _TCHAR* szName,
  47. const _TCHAR* szValue);
  48. // Set the given valuename under the key to value
  49. BOOL setValue(const _TCHAR* szKey,
  50. const _TCHAR* szValueName,
  51. const _TCHAR* szValue);
  52. // Delete szKeyChild and all of its descendents.
  53. LONG recursiveDeleteKey(HKEY hKeyParent, const _TCHAR* szKeyChild) ;
  54. ////////////////////////////////////////////////////////
  55. //
  56. // Constants
  57. //
  58. // Size of a CLSID as a string
  59. //const int CLSID_STRING_SIZE = 39 ;
  60. /////////////////////////////////////////////////////////
  61. //
  62. // Public function implementation
  63. //
  64. //
  65. // Register the component in the registry.
  66. //
  67. HRESULT RegisterServer(HMODULE hModule, // DLL module handle
  68. const CLSID& clsid, // Class ID
  69. const _TCHAR* szFriendlyName) // IDs
  70. {
  71. // Get server location.
  72. _TCHAR szModule[512] ;
  73. DWORD dwResult =
  74. ::GetModuleFileName(hModule,
  75. szModule,
  76. sizeof(szModule)/sizeof(_TCHAR)) ;
  77. assert(dwResult != 0) ;
  78. // Get CLSID
  79. LPOLESTR wszCLSID = NULL ;
  80. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  81. assert(SUCCEEDED(hr)) ;
  82. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  83. // Build the key CLSID\\{...}
  84. _TCHAR szKey[64] ;
  85. _tcscpy(szKey, _T("CLSID\\")) ;
  86. _tcscat(szKey, pszCLSID) ;
  87. // Add the CLSID to the registry.
  88. setKeyAndValue(szKey, NULL, szFriendlyName) ;
  89. // Add the server filename subkey under the CLSID key.
  90. setKeyAndValue(szKey, _T("InprocServer32"), szModule) ;
  91. // set the threading model
  92. _tcscat(szKey, _T("\\InprocServer32"));
  93. setValue(szKey, _T("ThreadingModel"), _T("Apartment"));
  94. // Free memory.
  95. CoTaskMemFree(wszCLSID) ;
  96. return S_OK ;
  97. }
  98. //
  99. // Remove the component from the registry.
  100. //
  101. LONG UnregisterServer(const CLSID& clsid) // IDs
  102. {
  103. // Get CLSID
  104. LPOLESTR wszCLSID = NULL ;
  105. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  106. // Build the key CLSID\\{...}
  107. _TCHAR szKey[64] ;
  108. _tcscpy(szKey, _T("CLSID\\")) ;
  109. MAKE_TSTRPTR_FROMWIDE(pszT, wszCLSID);
  110. _tcscat(szKey, pszT) ;
  111. // Delete the CLSID Key - CLSID\{...}
  112. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  113. assert((lResult == ERROR_SUCCESS) ||
  114. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  115. // Free memory.
  116. CoTaskMemFree(wszCLSID) ;
  117. return S_OK ;
  118. }
  119. //
  120. // Register the snap-in in the registry.
  121. //
  122. HRESULT RegisterSnapin(const CLSID& clsid, // Class ID
  123. const _TCHAR* szNameString, // NameString
  124. const CLSID& clsidAbout, // Class Id for About Class
  125. const BOOL fSupportExtensions)
  126. {
  127. // Get CLSID
  128. LPOLESTR wszCLSID = NULL ;
  129. LPOLESTR wszAboutCLSID = NULL;
  130. LPOLESTR wszExtendCLSID = NULL;
  131. LPOLESTR wszNodeCLSID = NULL;
  132. EXTENDER_NODE *pNodeExtension;
  133. _TCHAR szKeyBuf[1024] ;
  134. HKEY hKey;
  135. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  136. if (IID_NULL != clsidAbout)
  137. hr = StringFromCLSID(clsidAbout, &wszAboutCLSID);
  138. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  139. MAKE_TSTRPTR_FROMWIDE(pszAboutCLSID, wszAboutCLSID);
  140. // Add the CLSID to the registry.
  141. setSnapInKeyAndValue(pszCLSID, NULL, _T("NameString"), szNameString) ;
  142. if (IID_NULL != clsidAbout)
  143. setSnapInKeyAndValue(pszCLSID, NULL, _T("About"), pszAboutCLSID);
  144. if (fSupportExtensions) {
  145. // Build the key NodeType
  146. setSnapInKeyAndValue(pszCLSID, _T("NodeTypes"), NULL, NULL);
  147. _TCHAR szKey[64] ;
  148. _tcscpy(szKey, pszCLSID) ;
  149. _tcscat(szKey, _T("\\NodeTypes")) ;
  150. setSnapInKeyAndValue(szKey, pszCLSID, NULL, NULL);
  151. }
  152. // register each of the node extensions
  153. for (pNodeExtension = &(_NodeExtensions[0]);*pNodeExtension->szDescription;pNodeExtension++)
  154. {
  155. hr = StringFromCLSID(pNodeExtension->guidNode, &wszExtendCLSID);
  156. MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
  157. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
  158. _tcscat(szKeyBuf, pszExtendCLSID);
  159. switch (pNodeExtension->eType) {
  160. case ToolBarExtension:
  161. _tcscat(szKeyBuf, _T("\\Extensions\\ToolBar"));
  162. break;
  163. default:
  164. break;
  165. }
  166. // Create and open key and subkey.
  167. long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  168. szKeyBuf,
  169. 0, NULL, REG_OPTION_NON_VOLATILE,
  170. KEY_ALL_ACCESS, NULL,
  171. &hKey, NULL) ;
  172. if (lResult != ERROR_SUCCESS)
  173. {
  174. return FALSE ;
  175. }
  176. hr = StringFromCLSID(pNodeExtension->guidExtension, &wszNodeCLSID);
  177. assert(SUCCEEDED(hr));
  178. MAKE_TSTRPTR_FROMWIDE(pszNodeCLSID, wszNodeCLSID);
  179. // Set the Value.
  180. if (pNodeExtension->szDescription != NULL)
  181. {
  182. RegSetValueEx(hKey, pszNodeCLSID, 0, REG_SZ,
  183. (BYTE *)pNodeExtension->szDescription,
  184. (_tcslen(pNodeExtension->szDescription)+1)*sizeof(_TCHAR)) ;
  185. }
  186. RegCloseKey(hKey) ;
  187. CoTaskMemFree(wszExtendCLSID);
  188. CoTaskMemFree(wszNodeCLSID);
  189. }
  190. // Free memory.
  191. CoTaskMemFree(wszCLSID) ;
  192. if (IID_NULL != clsidAbout)
  193. CoTaskMemFree(wszAboutCLSID);
  194. return S_OK ;
  195. }
  196. //
  197. // Unregister the snap-in in the registry.
  198. //
  199. HRESULT UnregisterSnapin(const CLSID& clsid) // Class ID
  200. {
  201. _TCHAR szKeyBuf[1024];
  202. LPOLESTR wszCLSID = NULL;
  203. // Get CLSID
  204. HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  205. MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
  206. // Load the buffer with the Snap-In Location
  207. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
  208. // Copy keyname into buffer.
  209. _tcscat(szKeyBuf, _T("\\"));
  210. _tcscat(szKeyBuf, pszCLSID);
  211. // Delete the CLSID Key - CLSID\{...}
  212. LONG lResult = recursiveDeleteKey(HKEY_LOCAL_MACHINE, szKeyBuf);
  213. assert((lResult == ERROR_SUCCESS) ||
  214. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  215. // free the memory
  216. CoTaskMemFree(wszCLSID);
  217. return S_OK;
  218. }
  219. //
  220. // Delete a key and all of its descendents.
  221. //
  222. LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  223. const _TCHAR* lpszKeyChild) // Key to delete
  224. {
  225. // Open the child.
  226. HKEY hKeyChild ;
  227. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  228. KEY_ALL_ACCESS, &hKeyChild) ;
  229. if (lRes != ERROR_SUCCESS)
  230. {
  231. return lRes ;
  232. }
  233. // Enumerate all of the decendents of this child.
  234. FILETIME time ;
  235. _TCHAR szBuffer[256] ;
  236. DWORD dwSize = 256 ;
  237. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  238. NULL, NULL, &time) == S_OK)
  239. {
  240. // Delete the decendents of this child.
  241. lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
  242. if (lRes != ERROR_SUCCESS)
  243. {
  244. // Cleanup before exiting.
  245. RegCloseKey(hKeyChild) ;
  246. return lRes;
  247. }
  248. dwSize = 256 ;
  249. }
  250. // Close the child.
  251. RegCloseKey(hKeyChild) ;
  252. // Delete this child.
  253. return RegDeleteKey(hKeyParent, lpszKeyChild) ;
  254. }
  255. //
  256. // Create a key and set its value.
  257. // - This helper function was borrowed and modifed from
  258. // Kraig Brockschmidt's book Inside OLE.
  259. //
  260. BOOL setKeyAndValue(const _TCHAR* szKey,
  261. const _TCHAR* szSubkey,
  262. const _TCHAR* szValue)
  263. {
  264. HKEY hKey;
  265. _TCHAR szKeyBuf[1024] ;
  266. // Copy keyname into buffer.
  267. _tcscpy(szKeyBuf, szKey) ;
  268. // Add subkey name to buffer.
  269. if (szSubkey != NULL)
  270. {
  271. _tcscat(szKeyBuf, _T("\\")) ;
  272. _tcscat(szKeyBuf, szSubkey ) ;
  273. }
  274. // Create and open key and subkey.
  275. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  276. szKeyBuf,
  277. 0, NULL, REG_OPTION_NON_VOLATILE,
  278. KEY_ALL_ACCESS, NULL,
  279. &hKey, NULL) ;
  280. if (lResult != ERROR_SUCCESS)
  281. {
  282. return FALSE ;
  283. }
  284. // Set the Value.
  285. if (szValue != NULL)
  286. {
  287. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  288. (BYTE *)szValue,
  289. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  290. }
  291. RegCloseKey(hKey) ;
  292. return TRUE ;
  293. }
  294. //
  295. // Open a key value and set it
  296. //
  297. BOOL setValue(const _TCHAR* szKey,
  298. const _TCHAR* szValueName,
  299. const _TCHAR* szValue)
  300. {
  301. HKEY hKey;
  302. _TCHAR szKeyBuf[1024] ;
  303. // Copy keyname into buffer.
  304. _tcscpy(szKeyBuf, szKey) ;
  305. // Create and open key and subkey.
  306. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  307. szKeyBuf,
  308. 0, NULL, REG_OPTION_NON_VOLATILE,
  309. KEY_ALL_ACCESS, NULL,
  310. &hKey, NULL) ;
  311. if (lResult != ERROR_SUCCESS)
  312. {
  313. return FALSE ;
  314. }
  315. // Set the Value.
  316. if (szValue != NULL)
  317. {
  318. RegSetValueEx(hKey, szValueName, 0, REG_SZ,
  319. (BYTE *)szValue,
  320. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  321. }
  322. RegCloseKey(hKey) ;
  323. return TRUE ;
  324. }
  325. //
  326. // Create a key and set its value.
  327. // - This helper function was borrowed and modifed from
  328. // Kraig Brockschmidt's book Inside OLE.
  329. //
  330. BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
  331. const _TCHAR* szSubkey,
  332. const _TCHAR* szName,
  333. const _TCHAR* szValue)
  334. {
  335. HKEY hKey;
  336. _TCHAR szKeyBuf[1024] ;
  337. // Load the buffer with the Snap-In Location
  338. _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
  339. // Copy keyname into buffer.
  340. _tcscat(szKeyBuf, _T("\\")) ;
  341. _tcscat(szKeyBuf, szKey) ;
  342. // Add subkey name to buffer.
  343. if (szSubkey != NULL)
  344. {
  345. _tcscat(szKeyBuf, _T("\\")) ;
  346. _tcscat(szKeyBuf, szSubkey ) ;
  347. }
  348. // Create and open key and subkey.
  349. long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
  350. szKeyBuf,
  351. 0, NULL, REG_OPTION_NON_VOLATILE,
  352. KEY_ALL_ACCESS, NULL,
  353. &hKey, NULL) ;
  354. if (lResult != ERROR_SUCCESS)
  355. {
  356. return FALSE ;
  357. }
  358. // Set the Value.
  359. if (szValue != NULL)
  360. {
  361. RegSetValueEx(hKey, szName, 0, REG_SZ,
  362. (BYTE *)szValue,
  363. (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
  364. }
  365. RegCloseKey(hKey) ;
  366. return TRUE ;
  367. }