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.

301 lines
7.8 KiB

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