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.

284 lines
7.5 KiB

  1. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  2. //
  3. // Registry.cpp
  4. //
  5. #include "precomp.h"
  6. #include <objbase.h>
  7. #include <assert.h>
  8. #include "Registry.h"
  9. ////////////////////////////////////////////////////////
  10. //
  11. // Internal helper functions prototypes
  12. //
  13. // Set the given key and its value.
  14. BOOL setKeyAndValue(LPCWSTR pszPath,
  15. LPCWSTR szSubkey,
  16. LPCWSTR szValue) ;
  17. // Convert a CLSID into a char string.
  18. void CLSIDtoWCHAR(const CLSID& clsid,
  19. LPWSTR szCLSID,
  20. int length) ;
  21. // Delete szKeyChild and all of its descendents.
  22. LONG recursiveDeleteKey(HKEY hKeyParent, LPCWSTR szKeyChild) ;
  23. BOOL setEntryAndValue(LPCWSTR szKey,
  24. LPCWSTR szSubkey,
  25. LPCWSTR szValue);
  26. ////////////////////////////////////////////////////////
  27. //
  28. // Constants
  29. //
  30. // Size of a CLSID as a string
  31. const int CLSID_STRING_SIZE = 39 ;
  32. /////////////////////////////////////////////////////////
  33. //
  34. // Public function implementation
  35. //
  36. //
  37. // Register the component in the registry.
  38. //
  39. HRESULT RegisterServer(HMODULE hModule, // DLL module handle
  40. const CLSID& clsid, // Class ID
  41. LPCWSTR szFriendlyName, // Friendly Name
  42. LPCWSTR szVerIndProgID, // Programmatic
  43. LPCWSTR szProgID) // typelib id
  44. {
  45. // Get server location.
  46. WCHAR szModule[512] ;
  47. szModule[511] = 0;
  48. DWORD dwResult =
  49. ::GetModuleFileNameW(hModule,
  50. szModule,
  51. sizeof(szModule)/sizeof(WCHAR) - 1) ;
  52. assert(dwResult != 0) ;
  53. // Convert the CLSID into a char.
  54. WCHAR szCLSID[CLSID_STRING_SIZE] ;
  55. CLSIDtoWCHAR(clsid, szCLSID, sizeof(szCLSID)/sizeof(WCHAR)) ;
  56. // Build the key CLSID\\{...}
  57. WCHAR szKey[64] ;
  58. wcscpy(szKey, L"CLSID\\") ;
  59. wcscat(szKey, szCLSID) ;
  60. // Add the CLSID to the registry.
  61. setKeyAndValue(szKey, NULL, szFriendlyName) ;
  62. // Add the server filename subkey under the CLSID key.
  63. setKeyAndValue(szKey, L"InprocServer32", szModule) ;
  64. // Add the ProgID subkey under the CLSID key.
  65. setKeyAndValue(szKey, L"ProgID", szProgID) ;
  66. // Add the version-independent ProgID subkey under CLSID key.
  67. setKeyAndValue(szKey, L"VersionIndependentProgID",
  68. szVerIndProgID) ;
  69. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  70. setKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;
  71. setKeyAndValue(szVerIndProgID, L"CLSID", szCLSID) ;
  72. setKeyAndValue(szVerIndProgID, L"CurVer", szProgID) ;
  73. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  74. setKeyAndValue(szProgID, NULL, szFriendlyName) ;
  75. setKeyAndValue(szProgID, L"CLSID", szCLSID) ;
  76. // Specify the threading model as Free...
  77. wcscat(szKey, L"\\");
  78. wcscat(szKey, L"InprocServer32");
  79. setEntryAndValue(szKey, L"ThreadingModel", L"Free");
  80. return S_OK ;
  81. }
  82. //
  83. // Remove the component from the registry.
  84. //
  85. LONG UnregisterServer(const CLSID& clsid, // Class ID
  86. LPCWSTR szVerIndProgID, // Programmatic
  87. LPCWSTR szProgID) // IDs
  88. {
  89. // Convert the CLSID into a char.
  90. WCHAR szCLSID[CLSID_STRING_SIZE] ;
  91. CLSIDtoWCHAR(clsid, szCLSID, sizeof(szCLSID)/sizeof(WCHAR)) ;
  92. // Build the key CLSID\\{...}
  93. WCHAR szKey[64] ;
  94. wcscpy(szKey, L"CLSID\\") ;
  95. wcscat(szKey, szCLSID) ;
  96. // Delete the CLSID Key - CLSID\{...}
  97. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  98. assert((lResult == ERROR_SUCCESS) ||
  99. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  100. // Delete the version-independent ProgID Key.
  101. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
  102. assert((lResult == ERROR_SUCCESS) ||
  103. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  104. // Delete the ProgID key.
  105. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
  106. assert((lResult == ERROR_SUCCESS) ||
  107. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  108. return S_OK ;
  109. }
  110. ///////////////////////////////////////////////////////////
  111. //
  112. // Internal helper functions
  113. //
  114. // Convert a CLSID to a char string.
  115. void CLSIDtoWCHAR(const CLSID& clsid,
  116. LPWSTR szCLSID,
  117. int length)
  118. {
  119. assert(length >= CLSID_STRING_SIZE) ;
  120. // Get CLSID
  121. LPOLESTR wszCLSID = NULL ;
  122. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  123. assert(SUCCEEDED(hr)) ;
  124. if(SUCCEEDED(hr) && wszCLSID)
  125. {
  126. wcsncpy(szCLSID, wszCLSID, length) ;
  127. }
  128. // Free memory.
  129. CoTaskMemFree(wszCLSID) ;
  130. }
  131. //
  132. // Delete a key and all of its descendents.
  133. //
  134. LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  135. LPCWSTR lpszKeyChild) // Key to delete
  136. {
  137. // Open the child.
  138. HKEY hKeyChild ;
  139. LONG lRes = RegOpenKeyExW(hKeyParent, lpszKeyChild, 0,
  140. KEY_ALL_ACCESS, &hKeyChild) ;
  141. if (lRes != ERROR_SUCCESS)
  142. {
  143. return lRes ;
  144. }
  145. // Enumerate all of the decendents of this child.
  146. FILETIME time ;
  147. WCHAR szBuffer[256] ;
  148. DWORD dwSize = 256 ;
  149. while (RegEnumKeyExW(hKeyChild, 0, szBuffer, &dwSize, NULL,
  150. NULL, NULL, &time) == S_OK)
  151. {
  152. // Delete the decendents of this child.
  153. lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
  154. if (lRes != ERROR_SUCCESS)
  155. {
  156. // Cleanup before exiting.
  157. RegCloseKey(hKeyChild) ;
  158. return lRes;
  159. }
  160. dwSize = 256 ;
  161. }
  162. // Close the child.
  163. RegCloseKey(hKeyChild) ;
  164. // Delete this child.
  165. return RegDeleteKeyW(hKeyParent, lpszKeyChild) ;
  166. }
  167. //
  168. // Create a key and set its value.
  169. // - This helper function was borrowed and modifed from
  170. // Kraig Brockschmidt's book Inside OLE.
  171. //
  172. BOOL setKeyAndValue(LPCWSTR szKey,
  173. LPCWSTR szSubkey,
  174. LPCWSTR szValue)
  175. {
  176. HKEY hKey;
  177. WCHAR szKeyBuf[1024] ;
  178. // Copy keyname into buffer.
  179. wcscpy(szKeyBuf, szKey) ;
  180. // Add subkey name to buffer.
  181. if (szSubkey != NULL)
  182. {
  183. wcscat(szKeyBuf, L"\\") ;
  184. wcscat(szKeyBuf, szSubkey ) ;
  185. }
  186. // Create and open key and subkey.
  187. long lResult = RegCreateKeyExW(HKEY_CLASSES_ROOT ,
  188. szKeyBuf,
  189. 0, NULL, REG_OPTION_NON_VOLATILE,
  190. KEY_ALL_ACCESS, NULL,
  191. &hKey, NULL) ;
  192. if (lResult != ERROR_SUCCESS)
  193. {
  194. return FALSE ;
  195. }
  196. // Set the Value.
  197. if (szValue != NULL)
  198. {
  199. RegSetValueExW(hKey, NULL, 0, REG_SZ,
  200. (BYTE *)szValue,
  201. (wcslen(szValue)+1) * sizeof(WCHAR)) ;
  202. }
  203. RegCloseKey(hKey) ;
  204. return TRUE ;
  205. }
  206. //
  207. // Create a value within an existing key and set its data.
  208. //
  209. BOOL setEntryAndValue(LPCWSTR szKey,
  210. LPCWSTR szValue,
  211. LPCWSTR szData)
  212. {
  213. HKEY hKey;
  214. WCHAR szKeyBuf[1024] ;
  215. // Copy keyname into buffer.
  216. wcscpy(szKeyBuf, szKey) ;
  217. // Create and open key and subkey.
  218. long lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT ,
  219. szKeyBuf,
  220. 0,
  221. KEY_ALL_ACCESS,
  222. &hKey) ;
  223. if (lResult != ERROR_SUCCESS)
  224. {
  225. return FALSE ;
  226. }
  227. // Set the Value.
  228. if (szValue != NULL)
  229. {
  230. RegSetValueExW(hKey, szValue, 0, REG_SZ,
  231. (BYTE *)szData,
  232. (wcslen(szData)+1) * sizeof(WCHAR)) ;
  233. }
  234. RegCloseKey(hKey) ;
  235. return TRUE ;
  236. }