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.

232 lines
6.0 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. // Delete szKeyChild and all of its descendents.
  20. LONG recursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild) ;
  21. ////////////////////////////////////////////////////////
  22. //
  23. // Constants
  24. //
  25. // Size of a CLSID as a string
  26. const int CLSID_STRING_SIZE = 39 ;
  27. /////////////////////////////////////////////////////////
  28. //
  29. // Public function implementation
  30. //
  31. //
  32. // Register the component in the registry.
  33. //
  34. HRESULT RegisterServer(HMODULE hModule, // DLL module handle
  35. const CLSID& clsid, // Class ID
  36. const char* szFriendlyName, // Friendly Name
  37. const char* szVerIndProgID, // Programmatic
  38. const char* szProgID) // IDs
  39. {
  40. // Get server location.
  41. char szModule[512] ;
  42. DWORD dwResult =
  43. ::GetModuleFileName(hModule,
  44. szModule,
  45. sizeof(szModule)/sizeof(char)) ;
  46. assert(dwResult != 0) ;
  47. // Convert the CLSID into a char.
  48. char szCLSID[CLSID_STRING_SIZE] ;
  49. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  50. // Build the key CLSID\\{...}
  51. char szKey[64] ;
  52. strcpy(szKey, "CLSID\\") ;
  53. strcat(szKey, szCLSID) ;
  54. // Add the CLSID to the registry.
  55. setKeyAndValue(szKey, NULL, szFriendlyName) ;
  56. // Add the server filename subkey under the CLSID key.
  57. setKeyAndValue(szKey, "InprocServer32", szModule) ;
  58. // Add the ProgID subkey under the CLSID key.
  59. setKeyAndValue(szKey, "ProgID", szProgID) ;
  60. // Add the version-independent ProgID subkey under CLSID key.
  61. setKeyAndValue(szKey, "VersionIndependentProgID",
  62. szVerIndProgID) ;
  63. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  64. setKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;
  65. setKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;
  66. setKeyAndValue(szVerIndProgID, "CurVer", szProgID) ;
  67. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  68. setKeyAndValue(szProgID, NULL, szFriendlyName) ;
  69. setKeyAndValue(szProgID, "CLSID", szCLSID) ;
  70. return S_OK ;
  71. }
  72. //
  73. // Remove the component from the registry.
  74. //
  75. LONG UnregisterServer(const CLSID& clsid, // Class ID
  76. const char* szVerIndProgID, // Programmatic
  77. const char* szProgID) // IDs
  78. {
  79. // Convert the CLSID into a char.
  80. char szCLSID[CLSID_STRING_SIZE] ;
  81. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  82. // Build the key CLSID\\{...}
  83. char szKey[64] ;
  84. strcpy(szKey, "CLSID\\") ;
  85. strcat(szKey, szCLSID) ;
  86. // Delete the CLSID Key - CLSID\{...}
  87. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  88. assert((lResult == ERROR_SUCCESS) ||
  89. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  90. // Delete the version-independent ProgID Key.
  91. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
  92. assert((lResult == ERROR_SUCCESS) ||
  93. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  94. // Delete the ProgID key.
  95. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
  96. assert((lResult == ERROR_SUCCESS) ||
  97. (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  98. return S_OK ;
  99. }
  100. ///////////////////////////////////////////////////////////
  101. //
  102. // Internal helper functions
  103. //
  104. // Convert a CLSID to a char string.
  105. void CLSIDtochar(const CLSID& clsid,
  106. char* szCLSID,
  107. int length)
  108. {
  109. assert(length >= CLSID_STRING_SIZE) ;
  110. // Get CLSID
  111. LPOLESTR wszCLSID = NULL ;
  112. HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  113. assert(SUCCEEDED(hr)) ;
  114. // Covert from wide characters to non-wide.
  115. wcstombs(szCLSID, wszCLSID, length) ;
  116. // Free memory.
  117. CoTaskMemFree(wszCLSID) ;
  118. }
  119. //
  120. // Delete a key and all of its descendents.
  121. //
  122. LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  123. const char* lpszKeyChild) // Key to delete
  124. {
  125. // Open the child.
  126. HKEY hKeyChild ;
  127. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  128. KEY_ALL_ACCESS, &hKeyChild) ;
  129. if (lRes != ERROR_SUCCESS)
  130. {
  131. return lRes ;
  132. }
  133. // Enumerate all of the decendents of this child.
  134. FILETIME time ;
  135. char szBuffer[256] ;
  136. DWORD dwSize = 256 ;
  137. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  138. NULL, NULL, &time) == S_OK)
  139. {
  140. // Delete the decendents of this child.
  141. lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
  142. if (lRes != ERROR_SUCCESS)
  143. {
  144. // Cleanup before exiting.
  145. RegCloseKey(hKeyChild) ;
  146. return lRes;
  147. }
  148. dwSize = 256 ;
  149. }
  150. // Close the child.
  151. RegCloseKey(hKeyChild) ;
  152. // Delete this child.
  153. return RegDeleteKey(hKeyParent, lpszKeyChild) ;
  154. }
  155. //
  156. // Create a key and set its value.
  157. // - This helper function was borrowed and modifed from
  158. // Kraig Brockschmidt's book Inside OLE.
  159. //
  160. BOOL setKeyAndValue(const char* szKey,
  161. const char* szSubkey,
  162. const char* szValue)
  163. {
  164. HKEY hKey;
  165. char szKeyBuf[1024] ;
  166. // Copy keyname into buffer.
  167. strcpy(szKeyBuf, szKey) ;
  168. // Add subkey name to buffer.
  169. if (szSubkey != NULL)
  170. {
  171. strcat(szKeyBuf, "\\") ;
  172. strcat(szKeyBuf, szSubkey ) ;
  173. }
  174. // Create and open key and subkey.
  175. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  176. szKeyBuf,
  177. 0, NULL, REG_OPTION_NON_VOLATILE,
  178. KEY_ALL_ACCESS, NULL,
  179. &hKey, NULL) ;
  180. if (lResult != ERROR_SUCCESS)
  181. {
  182. return FALSE ;
  183. }
  184. // Set the Value.
  185. if (szValue != NULL)
  186. {
  187. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  188. (BYTE *)szValue,
  189. strlen(szValue)+1) ;
  190. }
  191. RegCloseKey(hKey) ;
  192. return TRUE ;
  193. }