Source code of Windows XP (NT5)
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.

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