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.

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