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.

333 lines
9.0 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. StringCchCopy(szKey, COUNTOF(szKey), m_cszCLSID) ;
  61. StringCchCat(szKey, COUNTOF(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. StringCchCopy(szKey, COUNTOF(szKey), m_cszCLSID) ;
  101. StringCchCat(szKey, COUNTOF(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. {
  130. hr = StringCbCopy( pszCLSID, dwLength, pwszCLSID);
  131. if (SUCCEEDED(hr))
  132. bRet = TRUE;
  133. else
  134. SetLastError (HRESULTTOWIN32 (hr));
  135. // Free memory.
  136. CoTaskMemFree(pwszCLSID) ;
  137. }
  138. else
  139. SetLastError (HRESULTTOWIN32 (hr));
  140. }
  141. return bRet;
  142. }
  143. //
  144. // Delete a key and all of its descendents.
  145. //
  146. BOOL
  147. TComRegistry::RecursiveDeleteKey(
  148. IN HKEY hKeyParent, // Parent of key to delete
  149. IN LPCTSTR lpszKeyChild) // Key to delete
  150. {
  151. BOOL bRet = FALSE;
  152. // Open the child.
  153. HKEY hKeyChild = NULL;
  154. LONG lResult = 0;
  155. FILETIME time ;
  156. TCHAR szBuffer[MAX_PATH] ;
  157. DWORD dwSize;
  158. lResult = RegOpenKeyEx (hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild) ;
  159. if (lResult == ERROR_SUCCESS)
  160. {
  161. // Enumerate all of the decendents of this child.
  162. for (;;) {
  163. dwSize = MAX_PATH ;
  164. lResult = RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time);
  165. if (lResult == ERROR_NO_MORE_ITEMS) {
  166. break;
  167. }
  168. else if (lResult == ERROR_SUCCESS) {
  169. // Delete the decendents of this child.
  170. if (!RecursiveDeleteKey (hKeyChild, szBuffer)) {
  171. goto Cleanup;
  172. }
  173. }
  174. else {
  175. goto Cleanup;
  176. }
  177. }
  178. // Close the child.
  179. RegCloseKey(hKeyChild) ;
  180. hKeyChild = NULL;
  181. // Delete this child.
  182. if (ERROR_SUCCESS == RegDeleteKey(hKeyParent, lpszKeyChild)) {
  183. bRet = TRUE;
  184. }
  185. }
  186. Cleanup:
  187. // Cleanup before exiting.
  188. if (hKeyChild)
  189. RegCloseKey(hKeyChild) ;
  190. if (!bRet && lResult)
  191. SetLastError (lResult);
  192. return bRet;
  193. }
  194. //
  195. // Create a key and set its value.
  196. // - This helper function was borrowed and modifed from
  197. // Kraig Brockschmidt's book Inside OLE.
  198. //
  199. BOOL
  200. TComRegistry::SetKeyAndValue(
  201. IN LPCTSTR pszKey,
  202. IN LPCTSTR pszSubkey,
  203. IN LPCTSTR pszValue)
  204. {
  205. return SetKeyAndNameValue (pszKey, pszSubkey, NULL, pszValue);
  206. }
  207. BOOL
  208. TComRegistry::SetKeyAndNameValue(
  209. IN LPCTSTR pszKey,
  210. IN LPCTSTR pszSubkey,
  211. IN LPCTSTR pszName,
  212. IN LPCTSTR pszValue)
  213. {
  214. BOOL bRet = FALSE;
  215. HKEY hKey = NULL;
  216. LPTSTR pszKeyBuf = NULL;
  217. long lResult;
  218. DWORD dwLen = lstrlen (pszKey) + 1;
  219. if (pszSubkey)
  220. {
  221. dwLen += lstrlen (pszSubkey) + 1;
  222. }
  223. pszKeyBuf = new TCHAR [dwLen];
  224. if (pszKeyBuf)
  225. {
  226. // Copy keyname into buffer.
  227. StringCchCopy(pszKeyBuf, dwLen, pszKey) ;
  228. // Add subkey name to buffer.
  229. if (pszSubkey != NULL)
  230. {
  231. StringCchCat(pszKeyBuf, dwLen, _T ("\\")) ;
  232. StringCchCat(pszKeyBuf, dwLen, pszSubkey ) ;
  233. }
  234. // Create and open key and subkey.
  235. lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  236. pszKeyBuf, 0, NULL,
  237. REG_OPTION_NON_VOLATILE,
  238. KEY_ALL_ACCESS, NULL, &hKey, NULL);
  239. if (ERROR_SUCCESS == lResult ) {
  240. // Set the Value.
  241. if (pszValue != NULL) {
  242. lResult = RegSetValueEx (hKey, pszName, 0, REG_SZ,
  243. (PBYTE) pszValue, sizeof (TCHAR) * lstrlen(pszValue));
  244. if (ERROR_SUCCESS == lResult ) {
  245. bRet = TRUE;
  246. }
  247. }
  248. else
  249. bRet = TRUE;
  250. }
  251. if (hKey) {
  252. RegCloseKey(hKey) ;
  253. }
  254. delete [] pszKeyBuf;
  255. }
  256. return bRet;
  257. }