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