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.

332 lines
8.9 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: registry.cpp
  3. //
  4. // Desc: Contains COM register and unregister functions for the UI.
  5. //
  6. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "common.hpp"
  9. ////////////////////////////////////////////////////////
  10. //
  11. // Internal helper functions prototypes
  12. //
  13. // Set the given key and its value.
  14. BOOL setKeyAndValue(LPCTSTR pszPath,
  15. LPCTSTR szSubkey,
  16. LPCTSTR szValue);
  17. // Set named value.
  18. BOOL setNamedValue(LPCTSTR pszPath,
  19. LPCTSTR szSubkey,
  20. LPCTSTR szKeyName,
  21. LPCTSTR szValue);
  22. // Convert a CLSID into a char string.
  23. void CLSIDtochar(const CLSID& clsid,
  24. LPTSTR szCLSID,
  25. int length);
  26. // Delete szKeyChild and all of its descendents.
  27. LONG recursiveDeleteKey(HKEY hKeyParent, LPCTSTR szKeyChild);
  28. ////////////////////////////////////////////////////////
  29. //
  30. // Constants
  31. //
  32. // Size of a CLSID as a string
  33. const int CLSID_STRING_SIZE = 39 ;
  34. /////////////////////////////////////////////////////////
  35. //
  36. // Public function implementation
  37. //
  38. //
  39. // Register the component in the registry.
  40. //
  41. HRESULT RegisterServer(HMODULE hModule, // DLL module handle
  42. const CLSID& clsid, // Class ID
  43. LPCTSTR szFriendlyName, // Friendly Name
  44. LPCTSTR szVerIndProgID, // Programmatic
  45. LPCTSTR szProgID) // IDs
  46. {
  47. // Get server location.
  48. TCHAR szModule[512];
  49. DWORD dwResult =
  50. ::GetModuleFileName(hModule,
  51. szModule,
  52. sizeof(szModule)/sizeof(TCHAR));
  53. if (!dwResult) return E_FAIL;
  54. // Convert the CLSID into a char.
  55. TCHAR szCLSID[CLSID_STRING_SIZE];
  56. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  57. // Build the key CLSID\\{...}
  58. TCHAR szKey[64];
  59. _tcscpy(szKey, _T("CLSID\\"));
  60. _tcscat(szKey, szCLSID);
  61. TCHAR szThreadKey[64];
  62. _tcscpy(szThreadKey, szKey);
  63. _tcscat(szThreadKey, _T("\\InProcServer32"));
  64. // Add the CLSID to the registry.
  65. setKeyAndValue(szKey, NULL, szFriendlyName);
  66. // Add the server filename subkey under the CLSID key.
  67. setKeyAndValue(szKey, _T("InProcServer32"), szModule);
  68. // Add the threading model subkey under the CLSID key
  69. setNamedValue(szKey, _T("InProcServer32"), _T("ThreadingModel"), _T("Both"));
  70. // Add the ProgID subkey under the CLSID key.
  71. setKeyAndValue(szKey, _T("ProgID"), szProgID);
  72. // Add the version-independent ProgID subkey under CLSID key.
  73. setKeyAndValue(szKey, _T("VersionIndependentProgID"),
  74. szVerIndProgID);
  75. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  76. setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);
  77. setKeyAndValue(szVerIndProgID, _T("CLSID"), szCLSID);
  78. setKeyAndValue(szVerIndProgID, _T("CurVer"), szProgID);
  79. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  80. setKeyAndValue(szProgID, NULL, szFriendlyName);
  81. setKeyAndValue(szProgID, _T("CLSID"), szCLSID);
  82. return S_OK;
  83. }
  84. //
  85. // Remove the component from the registry.
  86. //
  87. LONG UnregisterServer(const CLSID& clsid, // Class ID
  88. LPCTSTR szVerIndProgID, // Programmatic
  89. LPCTSTR szProgID) // IDs
  90. {
  91. // Convert the CLSID into a char.
  92. TCHAR szCLSID[CLSID_STRING_SIZE];
  93. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  94. // Build the key CLSID\\{...}
  95. TCHAR szKey[64];
  96. _tcscpy(szKey, _T("CLSID\\"));
  97. _tcscat(szKey, szCLSID);
  98. // Delete the CLSID Key - CLSID\{...}
  99. LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey);
  100. assert((lResult == ERROR_SUCCESS) ||
  101. (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  102. // Delete the version-independent ProgID Key.
  103. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
  104. assert((lResult == ERROR_SUCCESS) ||
  105. (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  106. // Delete the ProgID key.
  107. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
  108. assert((lResult == ERROR_SUCCESS) ||
  109. (lResult == ERROR_FILE_NOT_FOUND)); // Subkey may not exist.
  110. return S_OK;
  111. }
  112. ///////////////////////////////////////////////////////////
  113. //
  114. // Internal helper functions
  115. //
  116. // Convert a CLSID to a char string.
  117. void CLSIDtochar(const CLSID& clsid,
  118. LPTSTR szCLSID,
  119. int length)
  120. {
  121. if (length < CLSID_STRING_SIZE)
  122. return;
  123. // Get CLSID
  124. LPOLESTR wszCLSID = NULL;
  125. HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  126. assert(SUCCEEDED(hr));
  127. if (!wszCLSID) return;
  128. #ifdef _UNICODE
  129. _tcsncpy(szCLSID, wszCLSID, length);
  130. #else
  131. // Covert from wide characters to non-wide.
  132. wcstombs(szCLSID, wszCLSID, length);
  133. #endif
  134. // Free memory.
  135. CoTaskMemFree(wszCLSID);
  136. }
  137. //
  138. // Delete a key and all of its descendents.
  139. //
  140. LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  141. LPCTSTR lpszKeyChild) // Key to delete
  142. {
  143. // Open the child.
  144. HKEY hKeyChild;
  145. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  146. KEY_ALL_ACCESS, &hKeyChild);
  147. if (lRes != ERROR_SUCCESS)
  148. {
  149. return lRes;
  150. }
  151. // Enumerate all of the decendents of this child.
  152. FILETIME time;
  153. TCHAR szBuffer[256];
  154. DWORD dwSize = 256;
  155. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  156. NULL, NULL, &time) == S_OK)
  157. {
  158. // Delete the decendents of this child.
  159. lRes = recursiveDeleteKey(hKeyChild, szBuffer);
  160. if (lRes != ERROR_SUCCESS)
  161. {
  162. // Cleanup before exiting.
  163. RegCloseKey(hKeyChild);
  164. return lRes;
  165. }
  166. dwSize = 256;
  167. }
  168. // Close the child.
  169. RegCloseKey(hKeyChild);
  170. // Delete this child.
  171. return RegDeleteKey(hKeyParent, lpszKeyChild);
  172. }
  173. //
  174. // Create a key and set its value.
  175. //@@BEGIN_INTERNAL
  176. // - This helper function was borrowed and modifed from
  177. // Kraig Brockschmidt's book Inside OLE.
  178. //@@END_INTERNAL
  179. //
  180. BOOL setKeyAndValue(LPCTSTR szKey,
  181. LPCTSTR szSubkey,
  182. LPCTSTR szValue)
  183. {
  184. HKEY hKey;
  185. LPTSTR szKeyBuf;
  186. if (szKey == NULL) return FALSE;
  187. // Allocate space
  188. szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
  189. if (!szKeyBuf) return FALSE;
  190. // Copy keyname into buffer.
  191. _tcscpy(szKeyBuf, szKey);
  192. // Add subkey name to buffer.
  193. if (szSubkey != NULL)
  194. {
  195. //@@BEGIN_MSINTERNAL
  196. /*
  197. /* PREFIX seems to think that there is a bug here (Whistler 171821)
  198. /* and that szKeyBuf is uninitilaized -- but we assert that szKey is not NULL
  199. /* and then initialize szKeyBuf by _tcscpy() above.
  200. */
  201. //@@END_MSINTERNAL
  202. _tcscat(szKeyBuf, _T("\\"));
  203. _tcscat(szKeyBuf, szSubkey );
  204. }
  205. // Create and open key and subkey.
  206. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  207. szKeyBuf,
  208. 0, NULL, REG_OPTION_NON_VOLATILE,
  209. KEY_ALL_ACCESS, NULL,
  210. &hKey, NULL);
  211. if (lResult != ERROR_SUCCESS)
  212. {
  213. delete[] szKeyBuf;
  214. return FALSE;
  215. }
  216. // Set the Value.
  217. if (szValue != NULL)
  218. {
  219. RegSetValueEx(hKey, NULL, 0, REG_SZ,
  220. (BYTE *)szValue,
  221. sizeof(TCHAR) * ( _tcslen(szValue)+1) );
  222. }
  223. RegCloseKey(hKey);
  224. delete[] szKeyBuf;
  225. return TRUE;
  226. }
  227. //
  228. // Create a key and set its value.
  229. BOOL setNamedValue(LPCTSTR szKey,
  230. LPCTSTR szSubkey,
  231. LPCTSTR szKeyName,
  232. LPCTSTR szValue)
  233. {
  234. HKEY hKey;
  235. LPTSTR szKeyBuf;
  236. if (szKey == NULL) return FALSE;
  237. // Allocate space
  238. szKeyBuf = new TCHAR[lstrlen(szKey) + lstrlen(szSubkey) + 2];
  239. if (!szKeyBuf) return FALSE;
  240. // Copy keyname into buffer.
  241. _tcscpy(szKeyBuf, szKey);
  242. // Add subkey name to buffer.
  243. if (szSubkey != NULL)
  244. {
  245. //@@BEGIN_MSINTERNAL
  246. /*
  247. /* PREFIX seems to think that there is a bug here (Whistler 171820)
  248. /* and that szKeyBuf is uninitilaized -- but we assert that szKey is not NULL
  249. /* and then initialize szKeyBuf by _tcscpy() above.
  250. */
  251. //@@END_MSINTERNAL
  252. _tcscat(szKeyBuf, _T("\\"));
  253. _tcscat(szKeyBuf, szSubkey );
  254. }
  255. // Create and open key and subkey.
  256. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  257. szKeyBuf,
  258. 0, NULL, REG_OPTION_NON_VOLATILE,
  259. KEY_ALL_ACCESS, NULL,
  260. &hKey, NULL);
  261. if (lResult != ERROR_SUCCESS)
  262. {
  263. delete[] szKeyBuf;
  264. return FALSE ;
  265. }
  266. // Set the Value.
  267. if (szValue != NULL)
  268. {
  269. RegSetValueEx(hKey, szKeyName, 0, REG_SZ,
  270. (BYTE *)szValue,
  271. sizeof(TCHAR) * ( _tcslen(szValue)+1) );
  272. }
  273. RegCloseKey(hKey);
  274. delete[] szKeyBuf;
  275. return TRUE;
  276. }