PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CppExeCOMServer/Reg.cpp

#
C++ | 352 lines | 164 code | 41 blank | 147 comment | 39 complexity | bb14c498b4ae461f56e5c0febd2a740a MD5 | raw file
  1. /****************************** Module Header ******************************\
  2. Module Name: Reg.cpp
  3. Project: CppExeCOMServer
  4. Copyright (c) Microsoft Corporation.
  5. This source is subject to the Microsoft Public License.
  6. See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  7. All other rights reserved.
  8. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  9. EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  10. WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  11. \***************************************************************************/
  12. #include "Reg.h"
  13. #include <strsafe.h>
  14. //
  15. // FUNCTION: SetHKCRRegistryKeyAndValue
  16. //
  17. // PURPOSE: The function creates a HKCR registry key and sets the specified
  18. // registry value.
  19. //
  20. // PARAMETERS:
  21. // * pszSubKey - specifies the registry key under HKCR. If the key does not
  22. // exist, the function will create the registry key.
  23. // * pszValueName - specifies the registry value to be set. If pszValueName
  24. // is NULL, the function will set the default value.
  25. // * pszData - specifies the string data of the registry value.
  26. //
  27. HRESULT SetHKCRRegistryKeyAndValue(PCWSTR pszSubKey,
  28. PCWSTR pszValueName,
  29. PCWSTR pszData)
  30. {
  31. HRESULT hr;
  32. HKEY hKey = NULL;
  33. // Creates the specified registry key. If the key already exists, the
  34. // function opens it.
  35. hr = HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT, pszSubKey, 0,
  36. NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL));
  37. // Set the value of the key.
  38. if (SUCCEEDED(hr))
  39. {
  40. DWORD cbData = (pszData == NULL) ? 0 : (lstrlen(pszData) * sizeof(*pszData));
  41. hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, pszValueName, 0, REG_SZ,
  42. (LPBYTE)pszData, cbData));
  43. RegCloseKey(hKey);
  44. }
  45. return hr;
  46. }
  47. //
  48. // FUNCTION: RegisterLocalServer
  49. //
  50. // PURPOSE: This helper function registers the out-of-process component in
  51. // the registry.
  52. //
  53. // PARAMETERS:
  54. // * pszModule - Path of the module that contains the component
  55. // * clsid - Class ID of the component
  56. // * pszFriendlyName - Friendly name
  57. // * pszThreadModel - Threading model
  58. // * libid - Type library ID
  59. // * pszProgID - ProgID of the component
  60. // * pszVerIndProgID - Version independent ProgID
  61. //
  62. // NOTE: The function creates the HKCR\CLSID\{<CLSID>} key and the
  63. // HKCR\<ProgID> key in the registry.
  64. //
  65. // HKCR
  66. // {
  67. // <ProgID> = s '<Friendly Name>'
  68. // {
  69. // CLSID = s '{<CLSID>}'
  70. // }
  71. // <VersionIndependentProgID> = s '<Friendly Name>'
  72. // {
  73. // CLSID = s '{<CLSID>}'
  74. // CurVer = s '<ProgID>'
  75. // }
  76. // NoRemove CLSID
  77. // {
  78. // ForceRemove {<CLSID>} = s '<Friendly Name>'
  79. // {
  80. // ProgID = s '<ProgID>'
  81. // VersionIndependentProgID = s '<VersionIndependentProgID>'
  82. // LocalServer32 = s '%MODULE%'
  83. // TypeLib = s '{<LIBID>}'
  84. // }
  85. // }
  86. // }
  87. //
  88. HRESULT RegisterLocalServer(PCWSTR pszModule,
  89. const CLSID& clsid,
  90. PCWSTR pszFriendlyName,
  91. const IID& libid,
  92. PCWSTR pszProgID,
  93. PCWSTR pszVerIndProgID)
  94. {
  95. HRESULT hr;
  96. wchar_t szCLSID[MAX_PATH];
  97. StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
  98. wchar_t szLIBID[MAX_PATH];
  99. StringFromGUID2(libid, szLIBID, ARRAYSIZE(szLIBID));
  100. wchar_t szSubkey[MAX_PATH];
  101. // Create the HKCR\CLSID\{<CLSID>} key.
  102. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
  103. if (SUCCEEDED(hr))
  104. {
  105. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszFriendlyName);
  106. // Create the HKCR\CLSID\{<CLSID>}\ProgID key with the default value
  107. // '<ProgID>'
  108. if (SUCCEEDED(hr) && pszProgID != NULL)
  109. {
  110. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
  111. L"CLSID\\%s\\ProgID", szCLSID);
  112. if (SUCCEEDED(hr))
  113. {
  114. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszProgID);
  115. }
  116. }
  117. // Create the HKCR\CLSID\{<CLSID>}\VersionIndependentProgID key with
  118. // the default value '<VersionIndependentProgID>'.
  119. if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
  120. {
  121. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
  122. L"CLSID\\%s\\VersionIndependentProgID", szCLSID);
  123. if (SUCCEEDED(hr))
  124. {
  125. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszVerIndProgID);
  126. }
  127. }
  128. // Create the HKCR\CLSID\{<CLSID>}\TypeLib key with the default value
  129. // '{<LIBID>}'
  130. if (SUCCEEDED(hr))
  131. {
  132. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
  133. L"CLSID\\%s\\TypeLib", szCLSID);
  134. if (SUCCEEDED(hr))
  135. {
  136. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szLIBID);
  137. }
  138. }
  139. // Create the HKCR\CLSID\{<CLSID>}\LocalServer32 key.
  140. if (SUCCEEDED(hr))
  141. {
  142. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
  143. L"CLSID\\%s\\LocalServer32", szCLSID);
  144. if (SUCCEEDED(hr))
  145. {
  146. // Set the default value of the LocalServer32 key to the path
  147. // of the COM module.
  148. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszModule);
  149. }
  150. }
  151. }
  152. // Create the HKCR\<ProgId> key.
  153. if (SUCCEEDED(hr) && pszProgID != NULL)
  154. {
  155. hr = SetHKCRRegistryKeyAndValue(pszProgID, NULL, pszFriendlyName);
  156. // Create the HKCR\<ProgId>\CLSID key with the default value
  157. // '{<CLSID>}'.
  158. if (SUCCEEDED(hr))
  159. {
  160. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CLSID",
  161. pszProgID);
  162. if (SUCCEEDED(hr))
  163. {
  164. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szCLSID);
  165. }
  166. }
  167. }
  168. // Create the HKCR\<VersionIndependentProgID> key.
  169. if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
  170. {
  171. hr = SetHKCRRegistryKeyAndValue(pszVerIndProgID, NULL, pszFriendlyName);
  172. // Create the HKCR\<VersionIndependentProgID>\CLSID key with the
  173. // default value '{<CLSID>}'.
  174. if (SUCCEEDED(hr))
  175. {
  176. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CLSID",
  177. pszVerIndProgID);
  178. if (SUCCEEDED(hr))
  179. {
  180. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szCLSID);
  181. }
  182. }
  183. // Create the HKCR\<VersionIndependentProgID>\CurVer key with the
  184. // default value '<ProgID>'.
  185. if (SUCCEEDED(hr) && pszProgID != NULL)
  186. {
  187. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CurVer",
  188. pszVerIndProgID);
  189. if (SUCCEEDED(hr))
  190. {
  191. hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszProgID);
  192. }
  193. }
  194. }
  195. return hr;
  196. }
  197. //
  198. // FUNCTION: RegisterTypeLib
  199. //
  200. // PURPOSE: This helper function registers the type library.
  201. //
  202. // PARAMETERS:
  203. // * pszTypeLib - The type library file.
  204. //
  205. // NOTE: The function creates the HKCR\TypeLib\{<LIBID>} key and the
  206. // HKCR\Interface\{<IID>} key in the registry.
  207. //
  208. // HKCR
  209. // {
  210. // NoRemove TypeLib
  211. // {
  212. ...
  213. // }
  214. // NoRemove Interface
  215. // {
  216. // ForceRemove {<IID>} = s '<Interface Name>'
  217. // {
  218. // ProxyStubClsid = s '<ProgID>'
  219. // ProxyStubClsid32 = s '<VersionIndependentProgID>'
  220. // TypeLib = s '{<LIBID>}'
  221. // {
  222. // val Version = s '<TypeLib Version>'
  223. // }
  224. // }
  225. // }
  226. // }
  227. //
  228. HRESULT RegisterTypeLib(PCWSTR pszTypeLib)
  229. {
  230. HRESULT hr;
  231. ITypeLib *pTLB = NULL;
  232. hr = LoadTypeLibEx(pszTypeLib, REGKIND_REGISTER, &pTLB);
  233. if (SUCCEEDED(hr))
  234. {
  235. pTLB->Release();
  236. }
  237. return hr;
  238. }
  239. //
  240. // FUNCTION: UnregisterLocalServer(void)
  241. //
  242. // PURPOSE: Unegister the out-of-process component in the registry.
  243. //
  244. // PARAMETERS:
  245. // * clsid - Class ID of the component
  246. // * pszProgID - ProgID of the component
  247. // * pszVerIndProgID - Version independent ProgID
  248. //
  249. // NOTE: The function deletes the HKCR\CLSID\{<CLSID>} key and the
  250. // HKCR\<ProgID> key in the registry.
  251. //
  252. HRESULT UnregisterLocalServer(const CLSID& clsid,
  253. PCWSTR pszProgID,
  254. PCWSTR pszVerIndProgID)
  255. {
  256. HRESULT hr = S_OK;
  257. wchar_t szCLSID[MAX_PATH];
  258. StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
  259. wchar_t szSubkey[MAX_PATH];
  260. // Delete the HKCR\CLSID\{<CLSID>} key.
  261. hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
  262. if (SUCCEEDED(hr))
  263. {
  264. hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, szSubkey));
  265. }
  266. // Delete the HKCR\<ProgID> key.
  267. if (SUCCEEDED(hr) && pszProgID != NULL)
  268. {
  269. hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszProgID));
  270. }
  271. // Delete the HKCR\<VersionIndependentProgID> key.
  272. if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
  273. {
  274. hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszVerIndProgID));
  275. }
  276. return hr;
  277. }
  278. //
  279. // FUNCTION: UnregisterTypeLib
  280. //
  281. // PURPOSE: This helper function unregisters the type library.
  282. //
  283. // PARAMETERS:
  284. // * pszTypeLib - The type library file.
  285. //
  286. // NOTE: The function deletes the HKCR\TypeLib\{<LIBID>} key and the
  287. // HKCR\Interface\{<IID>} key in the registry.
  288. //
  289. HRESULT UnregisterTypeLib(PCWSTR pszTypeLib)
  290. {
  291. HRESULT hr;
  292. ITypeLib *pTLB = NULL;
  293. hr = LoadTypeLibEx(pszTypeLib, REGKIND_NONE, &pTLB);
  294. if (SUCCEEDED(hr))
  295. {
  296. TLIBATTR *pAttr = NULL;
  297. hr = pTLB->GetLibAttr(&pAttr);
  298. if (SUCCEEDED(hr))
  299. {
  300. hr = UnRegisterTypeLib(pAttr->guid, pAttr->wMajorVerNum,
  301. pAttr->wMinorVerNum, pAttr->lcid, pAttr->syskind);
  302. pTLB->ReleaseTLibAttr(pAttr);
  303. }
  304. pTLB->Release();
  305. }
  306. return hr;
  307. }