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.

292 lines
8.7 KiB

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