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.

329 lines
8.4 KiB

  1. /*****************************************************************************\
  2. * MODULE: registry.cpp
  3. *
  4. * PURPOSE: Implementation of COM interface for BidiSpooler
  5. *
  6. * Copyright (C) 2000 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 03/07/00 Weihai Chen (weihaic) Created
  11. *
  12. \*****************************************************************************/
  13. #include "precomp.h"
  14. #include "registry.h"
  15. ////////////////////////////////////////////////////////
  16. //
  17. // Internal helper functions prototypes
  18. //
  19. // Set the given key and its value.
  20. ////////////////////////////////////////////////////////
  21. //
  22. // Constants
  23. //
  24. // Size of a CLSID as a string
  25. CONST DWORD TComRegistry::m_cdwClsidStringSize = 39;
  26. CONST TCHAR TComRegistry::m_cszCLSID[] = _T ("CLSID\\");
  27. CONST TCHAR TComRegistry::m_cszCLSID2[] = _T ("CLSID");
  28. CONST TCHAR TComRegistry::m_cszInprocServer32[] = _T ("InprocServer32");
  29. CONST TCHAR TComRegistry::m_cszProgID[] = _T ("ProgID");
  30. CONST TCHAR TComRegistry::m_cszVersionIndependentProgID[] = _T ("VersionIndependentProgID");
  31. CONST TCHAR TComRegistry::m_cszCurVer[] = _T ("CurVer");
  32. CONST TCHAR TComRegistry::m_cszThreadingModel[] = _T ("ThreadingModel");
  33. CONST TCHAR TComRegistry::m_cszBoth[] = _T ("Both");
  34. /////////////////////////////////////////////////////////
  35. //
  36. // Public function implementation
  37. //
  38. //
  39. // Register the component in the registry.
  40. //
  41. BOOL
  42. TComRegistry::RegisterServer(
  43. IN HMODULE hModule, // DLL module handle
  44. IN REFCLSID clsid, // Class ID
  45. IN LPCTSTR pszFriendlyName, // Friendly Name
  46. IN LPCTSTR pszVerIndProgID, // Programmatic
  47. IN LPCTSTR pszProgID) // IDs
  48. {
  49. BOOL bRet = FALSE;
  50. // Get server location.
  51. TCHAR szModule [MAX_PATH];
  52. DWORD dwResult;
  53. TCHAR szCLSID[m_cdwClsidStringSize] ;
  54. DBGMSG(DBG_TRACE,("Enter RegisterServer"));
  55. if (GetModuleFileName(hModule, szModule,MAX_PATH) > 0) {
  56. // Convert the CLSID into a string.
  57. if (CLSIDtoString(clsid, szCLSID, sizeof(szCLSID))) {
  58. // Build the key CLSID\\{...}
  59. TCHAR szKey[64] ;
  60. lstrcpy(szKey, m_cszCLSID) ;
  61. lstrcat(szKey, szCLSID) ;
  62. // Add the CLSID to the registry.
  63. if (SetKeyAndValue(szKey, NULL, pszFriendlyName) &&
  64. // Add the server filename subkey under the CLSID key.
  65. SetKeyAndValue(szKey, m_cszInprocServer32, szModule) &&
  66. SetKeyAndNameValue(szKey, m_cszInprocServer32, m_cszThreadingModel, m_cszBoth) &&
  67. // Add the ProgID subkey under the CLSID key.
  68. SetKeyAndValue(szKey, m_cszProgID, pszProgID) &&
  69. // Add the version-independent ProgID subkey under CLSID key.
  70. SetKeyAndValue(szKey, m_cszVersionIndependentProgID, pszVerIndProgID) &&
  71. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  72. SetKeyAndValue(pszVerIndProgID, NULL, pszFriendlyName) &&
  73. SetKeyAndValue(pszVerIndProgID, m_cszCLSID2, szCLSID) &&
  74. SetKeyAndValue(pszVerIndProgID, m_cszCurVer, pszProgID) &&
  75. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  76. SetKeyAndValue(pszProgID, NULL, pszFriendlyName) &&
  77. SetKeyAndValue(pszProgID, m_cszCLSID2, szCLSID) ) {
  78. bRet = TRUE;
  79. }
  80. }
  81. }
  82. DBGMSG(DBG_TRACE,("Leave RegisterServer (Ret = %d)\n", bRet));
  83. return bRet;
  84. }
  85. //
  86. // Remove the component from the registry.
  87. //
  88. BOOL
  89. TComRegistry::UnregisterServer(
  90. IN REFCLSID clsid, // Class ID
  91. IN LPCTSTR pszVerIndProgID, // Programmatic
  92. IN LPCTSTR pszProgID) // IDs
  93. {
  94. BOOL bRet = FALSE;
  95. // Convert the CLSID into a char.
  96. TCHAR szCLSID[m_cdwClsidStringSize] ;
  97. DBGMSG(DBG_TRACE,("Enter UnregisterServer\n", bRet));
  98. if (CLSIDtoString(clsid, szCLSID, sizeof(szCLSID))) {
  99. TCHAR szKey[64] ;
  100. lstrcpy(szKey, m_cszCLSID) ;
  101. lstrcat(szKey, szCLSID) ;
  102. if (RecursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) &&
  103. RecursiveDeleteKey(HKEY_CLASSES_ROOT, pszVerIndProgID) &&
  104. RecursiveDeleteKey(HKEY_CLASSES_ROOT, pszProgID)) {
  105. bRet = TRUE;
  106. }
  107. }
  108. DBGMSG(DBG_TRACE,("Leave UnregisterServer (Ret = %d)\n", bRet));
  109. return bRet;
  110. }
  111. ///////////////////////////////////////////////////////////
  112. //
  113. // Internal helper functions
  114. //
  115. // Convert a CLSID to a string.
  116. BOOL
  117. TComRegistry::CLSIDtoString(
  118. IN REFCLSID clsid,
  119. IN OUT LPTSTR pszCLSID,
  120. IN DWORD dwLength)
  121. {
  122. BOOL bRet = FALSE;
  123. HRESULT hr = E_FAIL;
  124. LPWSTR pwszCLSID = NULL ;
  125. if (dwLength >= m_cdwClsidStringSize ) {
  126. // Get CLSID
  127. hr = StringFromCLSID(clsid, &pwszCLSID);
  128. if (SUCCEEDED (hr)) {
  129. lstrcpy (pszCLSID, pwszCLSID);
  130. // Free memory.
  131. CoTaskMemFree(pwszCLSID) ;
  132. bRet = TRUE;
  133. }
  134. else
  135. SetLastError (HRESULTTOWIN32 (hr));
  136. }
  137. return bRet;
  138. }
  139. //
  140. // Delete a key and all of its descendents.
  141. //
  142. BOOL
  143. TComRegistry::RecursiveDeleteKey(
  144. IN HKEY hKeyParent, // Parent of key to delete
  145. IN LPCTSTR lpszKeyChild) // Key to delete
  146. {
  147. BOOL bRet = FALSE;
  148. // Open the child.
  149. HKEY hKeyChild = NULL;
  150. LONG lResult = 0;
  151. FILETIME time ;
  152. TCHAR szBuffer[MAX_PATH] ;
  153. DWORD dwSize;
  154. lResult = RegOpenKeyEx (hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild) ;
  155. if (lResult == ERROR_SUCCESS)
  156. {
  157. // Enumerate all of the decendents of this child.
  158. for (;;) {
  159. dwSize = MAX_PATH ;
  160. lResult = RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time);
  161. if (lResult == ERROR_NO_MORE_ITEMS) {
  162. break;
  163. }
  164. else if (lResult == ERROR_SUCCESS) {
  165. // Delete the decendents of this child.
  166. if (!RecursiveDeleteKey (hKeyChild, szBuffer)) {
  167. goto Cleanup;
  168. }
  169. }
  170. else {
  171. goto Cleanup;
  172. }
  173. }
  174. // Close the child.
  175. RegCloseKey(hKeyChild) ;
  176. hKeyChild = NULL;
  177. // Delete this child.
  178. if (ERROR_SUCCESS == RegDeleteKey(hKeyParent, lpszKeyChild)) {
  179. bRet = TRUE;
  180. }
  181. }
  182. Cleanup:
  183. // Cleanup before exiting.
  184. if (hKeyChild)
  185. RegCloseKey(hKeyChild) ;
  186. if (!bRet && lResult)
  187. SetLastError (lResult);
  188. return bRet;
  189. }
  190. //
  191. // Create a key and set its value.
  192. // - This helper function was borrowed and modifed from
  193. // Kraig Brockschmidt's book Inside OLE.
  194. //
  195. BOOL
  196. TComRegistry::SetKeyAndValue(
  197. IN LPCTSTR pszKey,
  198. IN LPCTSTR pszSubkey,
  199. IN LPCTSTR pszValue)
  200. {
  201. return SetKeyAndNameValue (pszKey, pszSubkey, NULL, pszValue);
  202. }
  203. BOOL
  204. TComRegistry::SetKeyAndNameValue(
  205. IN LPCTSTR pszKey,
  206. IN LPCTSTR pszSubkey,
  207. IN LPCTSTR pszName,
  208. IN LPCTSTR pszValue)
  209. {
  210. BOOL bRet = FALSE;
  211. HKEY hKey = NULL;
  212. LPTSTR pszKeyBuf = NULL;
  213. long lResult;
  214. DWORD dwLen = lstrlen (pszKey) + 1;
  215. if (pszSubkey)
  216. {
  217. dwLen += lstrlen (pszSubkey) + 1;
  218. }
  219. pszKeyBuf = new TCHAR [dwLen];
  220. if (pszKeyBuf)
  221. {
  222. // Copy keyname into buffer.
  223. lstrcpy(pszKeyBuf, pszKey) ;
  224. // Add subkey name to buffer.
  225. if (pszSubkey != NULL)
  226. {
  227. lstrcat(pszKeyBuf, _T ("\\")) ;
  228. lstrcat(pszKeyBuf, pszSubkey ) ;
  229. }
  230. // Create and open key and subkey.
  231. lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  232. pszKeyBuf, 0, NULL,
  233. REG_OPTION_NON_VOLATILE,
  234. KEY_ALL_ACCESS, NULL, &hKey, NULL);
  235. if (ERROR_SUCCESS == lResult ) {
  236. // Set the Value.
  237. if (pszValue != NULL) {
  238. lResult = RegSetValueEx (hKey, pszName, 0, REG_SZ,
  239. (PBYTE) pszValue, sizeof (TCHAR) * lstrlen(pszValue));
  240. if (ERROR_SUCCESS == lResult ) {
  241. bRet = TRUE;
  242. }
  243. }
  244. else
  245. bRet = TRUE;
  246. }
  247. if (hKey) {
  248. RegCloseKey(hKey) ;
  249. }
  250. delete [] pszKeyBuf;
  251. }
  252. return bRet;
  253. }