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.

441 lines
13 KiB

  1. #include <objbase.h>
  2. #include <comcat.h>
  3. #include "common.h"
  4. #include "registry.h"
  5. // Safe String
  6. #define STRSAFE_NO_DEPRECATE
  7. #include "strsafe.h"
  8. ////////////////////////////////////////////////////////
  9. //
  10. // Internal helper functions prototypes
  11. //
  12. #ifndef UNDER_CE
  13. // Set the given key and its value.
  14. BOOL SetKeyAndValue(const char* pszPath,
  15. const char* szSubkey,
  16. const char* szValue,
  17. const char* szName=NULL) ;
  18. // Convert a CLSID into a char string.
  19. void CLSIDtochar(const CLSID& clsid,
  20. char* szCLSID,
  21. int length) ;
  22. // Delete szKeyChild and all of its descendents.
  23. LONG RecursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild) ;
  24. #else // UNDER_CE
  25. // Set the given key and its value.
  26. BOOL SetKeyAndValue(LPCTSTR pszPath,
  27. LPCTSTR szSubkey,
  28. LPCTSTR szValue,
  29. LPCTSTR szName=NULL) ;
  30. // Convert a CLSID into a char string.
  31. void CLSIDtochar(const CLSID& clsid,
  32. LPTSTR szCLSID,
  33. int length) ;
  34. // Delete szKeyChild and all of its descendents.
  35. LONG RecursiveDeleteKey(HKEY hKeyParent, LPCTSTR szKeyChild) ;
  36. #endif // UNDER_CE
  37. ////////////////////////////////////////////////////////
  38. //
  39. // Constants
  40. //
  41. // Size of a CLSID as a string
  42. const int CLSID_STRING_SIZE = 39 ;
  43. /////////////////////////////////////////////////////////
  44. //
  45. // Public function implementation
  46. //
  47. //
  48. // Register the component in the registry.
  49. //
  50. #ifndef UNDER_CE
  51. HRESULT Register(HMODULE hModule, // DLL module handle
  52. const CLSID& clsid, // Class ID
  53. const char* szFriendlyName, // Friendly Name
  54. const char* szVerIndProgID, // Programmatic
  55. const char* szProgID) // IDs
  56. #else // UNDER_CE
  57. HRESULT Register(HMODULE hModule, // DLL module handle
  58. const CLSID& clsid, // Class ID
  59. LPCTSTR szFriendlyName, // Friendly Name
  60. LPCTSTR szVerIndProgID, // Programmatic
  61. LPCTSTR szProgID) // IDs
  62. #endif // UNDER_CE
  63. {
  64. // Get server location.
  65. #ifndef UNDER_CE
  66. char szModule[512] ;
  67. //DWORD dwResult =
  68. ::GetModuleFileName(hModule,
  69. szModule,
  70. sizeof(szModule)/sizeof(char)) ;
  71. #else // UNDER_CE
  72. TCHAR szModule[512];
  73. //DWORD dwResult =
  74. ::GetModuleFileName(hModule,
  75. szModule,
  76. sizeof(szModule)/sizeof(TCHAR)) ;
  77. #endif // UNDER_CE
  78. // Convert the CLSID into a char.
  79. #ifndef UNDER_CE
  80. char szCLSID[CLSID_STRING_SIZE] ;
  81. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  82. #else // UNDER_CE
  83. TCHAR szCLSID[CLSID_STRING_SIZE];
  84. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  85. #endif // UNDER_CE
  86. // Build the key CLSID\\{...}
  87. #ifndef UNDER_CE
  88. char szKey[64] ;
  89. StringCchCopy(szKey, ARRAYSIZE(szKey), "CLSID\\") ;
  90. StringCchCat(szKey, ARRAYSIZE(szKey), szCLSID) ;
  91. #else // UNDER_CE
  92. TCHAR szKey[64] ;
  93. lstrcpy(szKey, TEXT("CLSID\\")) ;
  94. lstrcat(szKey, szCLSID) ;
  95. #endif // UNDER_CE
  96. // Add the CLSID to the registry.
  97. SetKeyAndValue(szKey, NULL, szFriendlyName) ;
  98. // Add the server filename subkey under the CLSID key.
  99. #ifndef UNDER_CE
  100. SetKeyAndValue(szKey, "InprocServer32", szModule) ;
  101. SetKeyAndValue(szKey,
  102. "InprocServer32",
  103. "Apartment",
  104. "ThreadingModel") ;
  105. #else // UNDER_CE
  106. SetKeyAndValue(szKey, TEXT("InprocServer32"), szModule) ;
  107. SetKeyAndValue(szKey,
  108. TEXT("InprocServer32"),
  109. TEXT("Apartment"),
  110. TEXT("ThreadingModel")) ;
  111. #endif // UNDER_CE
  112. // Add the ProgID subkey under the CLSID key.
  113. #ifndef UNDER_CE
  114. SetKeyAndValue(szKey, "ProgID", szProgID) ;
  115. #else // UNDER_CE
  116. SetKeyAndValue(szKey, TEXT("ProgID"), szProgID) ;
  117. #endif // UNDER_CE
  118. // Add the version-independent ProgID subkey under CLSID key.
  119. #ifndef UNDER_CE
  120. SetKeyAndValue(szKey, "VersionIndependentProgID",
  121. szVerIndProgID) ;
  122. #else // UNDER_CE
  123. SetKeyAndValue(szKey, TEXT("VersionIndependentProgID"),
  124. szVerIndProgID) ;
  125. #endif // UNDER_CE
  126. // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  127. #ifndef UNDER_CE
  128. SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;
  129. SetKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;
  130. SetKeyAndValue(szVerIndProgID, "CurVer", szProgID) ;
  131. #else // UNDER_CE
  132. SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ;
  133. SetKeyAndValue(szVerIndProgID, TEXT("CLSID"), szCLSID) ;
  134. SetKeyAndValue(szVerIndProgID, TEXT("CurVer"), szProgID) ;
  135. #endif // UNDER_CE
  136. // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  137. #ifndef UNDER_CE
  138. SetKeyAndValue(szProgID, NULL, szFriendlyName) ;
  139. SetKeyAndValue(szProgID, "CLSID", szCLSID) ;
  140. #else // UNDER_CE
  141. SetKeyAndValue(szProgID, NULL, szFriendlyName) ;
  142. SetKeyAndValue(szProgID, TEXT("CLSID"), szCLSID) ;
  143. #endif // UNDER_CE
  144. return S_OK ;
  145. }
  146. //
  147. // Remove the component from the registry.
  148. //
  149. #ifndef UNDER_CE
  150. LONG Unregister(const CLSID& clsid, // Class ID
  151. const char* szVerIndProgID, // Programmatic
  152. const char* szProgID) // IDs
  153. #else // UNDER_CE
  154. LONG Unregister(const CLSID& clsid, // Class ID
  155. LPCTSTR szVerIndProgID, // Programmatic
  156. LPCTSTR szProgID) // IDs
  157. #endif // UNDER_CE
  158. {
  159. // Convert the CLSID into a char.
  160. #ifndef UNDER_CE
  161. char szCLSID[CLSID_STRING_SIZE] ;
  162. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  163. #else // UNDER_CE
  164. TCHAR szCLSID[CLSID_STRING_SIZE] ;
  165. CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  166. #endif // UNDER_CE
  167. // Build the key CLSID\\{...}
  168. #ifndef UNDER_CE
  169. char szKey[64] ;
  170. StringCchCopy(szKey, ARRAYSIZE(szKey), "CLSID\\") ;
  171. StringCchCat(szKey, ARRAYSIZE(szKey), szCLSID) ;
  172. #else // UNDER_CE
  173. TCHAR szKey[64] ;
  174. lstrcpy(szKey, TEXT("CLSID\\")) ;
  175. lstrcat(szKey, szCLSID) ;
  176. #endif // UNDER_CE
  177. // Delete the CLSID Key - CLSID\{...}
  178. LONG lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  179. // Delete the version-independent ProgID Key.
  180. lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
  181. // Delete the ProgID key.
  182. lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
  183. return S_OK ;
  184. }
  185. void SelfRegisterCategory(BOOL bRegister,
  186. const CATID &catId,
  187. REFCLSID clsId)
  188. {
  189. #ifndef UNDER_CE
  190. CHAR szCLSID[256];
  191. CHAR szKey[1024];
  192. CHAR szSub[1024];
  193. CLSIDtochar(clsId, szCLSID, sizeof(szCLSID));
  194. StringCchPrintf(szKey, ARRAYSIZE(szKey), "CLSID\\%s\\Implemented Categories", szCLSID);
  195. CLSIDtochar(catId, szSub, sizeof(szSub));
  196. #else // UNDER_CE
  197. TCHAR szCLSID[256];
  198. TCHAR szKey[1024];
  199. TCHAR szSub[1024];
  200. CLSIDtochar(clsId, szCLSID, sizeof(szCLSID)/sizeof(TCHAR));
  201. wsprintf(szKey, TEXT("CLSID\\%s\\Implemented Categories"), szCLSID);
  202. CLSIDtochar(catId, szSub, sizeof(szSub)/sizeof(TCHAR));
  203. #endif // UNDER_CE
  204. SetKeyAndValue(szKey,
  205. szSub,
  206. NULL,
  207. NULL);
  208. return;
  209. UNREFERENCED_PARAMETER(bRegister);
  210. }
  211. void RegisterCategory(BOOL bRegister,
  212. const CATID &catId,
  213. REFCLSID clsId)
  214. {
  215. // Create the standard COM Category Manager
  216. ICatRegister* pICatRegister = NULL ;
  217. HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr,
  218. NULL, CLSCTX_ALL, IID_ICatRegister,
  219. (void**)&pICatRegister) ;
  220. if (FAILED(hr)){
  221. //ErrorMessage("Could not create the ComCat component.", hr);
  222. SelfRegisterCategory(bRegister, catId, clsId);
  223. return ;
  224. }
  225. // Array of Categories
  226. int cIDs = 1 ;
  227. CATID IDs[1] ;
  228. IDs[0] = catId;
  229. // Register or Unregister
  230. if(bRegister) {
  231. hr = pICatRegister->RegisterClassImplCategories(clsId,
  232. cIDs, IDs);
  233. //ASSERT_HRESULT(hr) ;
  234. }
  235. else {
  236. // Unregister the component from its categories.
  237. hr = pICatRegister->UnRegisterClassImplCategories(clsId,
  238. cIDs, IDs);
  239. }
  240. if(pICatRegister) {
  241. pICatRegister->Release() ;
  242. }
  243. }
  244. ///////////////////////////////////////////////////////////
  245. //
  246. // Internal helper functions
  247. //
  248. // Convert a CLSID to a char string.
  249. #ifndef UNDER_CE
  250. void CLSIDtochar(const CLSID& clsid,
  251. char* szCLSID,
  252. int length)
  253. #else // UNDER_CE
  254. void CLSIDtochar(const CLSID& clsid,
  255. LPTSTR szCLSID,
  256. int length)
  257. #endif // UNDER_CE
  258. {
  259. // Get CLSID
  260. LPOLESTR wszCLSID = NULL ;
  261. //HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  262. StringFromCLSID(clsid, &wszCLSID);
  263. if (wszCLSID != NULL)
  264. {
  265. // Covert from wide characters to non-wide.
  266. #ifndef UNDER_CE // #ifndef UNICODE
  267. wcstombs(szCLSID, wszCLSID, length);
  268. #else // UNDER_CE
  269. wcsncpy(szCLSID, wszCLSID, length);
  270. szCLSID[length-1] = TEXT('\0');
  271. #endif // UNDER_CE
  272. // Free memory.
  273. CoTaskMemFree(wszCLSID) ;
  274. }
  275. }
  276. //
  277. // Delete a key and all of its descendents.
  278. //
  279. #ifndef UNDER_CE
  280. LONG RecursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  281. const char* lpszKeyChild) // Key to delete
  282. #else // UNDER_CE
  283. LONG RecursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
  284. LPCTSTR lpszKeyChild) // Key to delete
  285. #endif // UNDER_CE
  286. {
  287. // Open the child.
  288. HKEY hKeyChild ;
  289. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
  290. KEY_ALL_ACCESS, &hKeyChild) ;
  291. if (lRes != ERROR_SUCCESS)
  292. {
  293. return lRes ;
  294. }
  295. // Enumerate all of the decendents of this child.
  296. FILETIME time ;
  297. #ifndef UNDER_CE
  298. char szBuffer[256] ;
  299. #else // UNDER_CE
  300. TCHAR szBuffer[256];
  301. #endif // UNDER_CE
  302. DWORD dwSize = 256 ;
  303. while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  304. NULL, NULL, &time) == S_OK)
  305. {
  306. // Delete the decendents of this child.
  307. lRes = RecursiveDeleteKey(hKeyChild, szBuffer) ;
  308. if (lRes != ERROR_SUCCESS)
  309. {
  310. // Cleanup before exiting.
  311. RegCloseKey(hKeyChild) ;
  312. return lRes;
  313. }
  314. dwSize = 256 ;
  315. }
  316. // Close the child.
  317. RegCloseKey(hKeyChild) ;
  318. // Delete this child.
  319. return RegDeleteKey(hKeyParent, lpszKeyChild) ;
  320. }
  321. //
  322. // Create a key and set its value.
  323. // - This helper function was borrowed and modifed from
  324. // Kraig Brockschmidt's book Inside OLE.
  325. //
  326. #ifndef UNDER_CE
  327. BOOL SetKeyAndValue(const char* szKey,
  328. const char* szSubkey,
  329. const char* szValue,
  330. const char* szName)
  331. #else // UNDER_CE
  332. BOOL SetKeyAndValue(LPCTSTR szKey,
  333. LPCTSTR szSubkey,
  334. LPCTSTR szValue,
  335. LPCTSTR szName)
  336. #endif // UNDER_CE
  337. {
  338. HKEY hKey;
  339. #ifndef UNDER_CE
  340. char szKeyBuf[1024] ;
  341. #else // UNDER_CE
  342. TCHAR szKeyBuf[1024];
  343. #endif // UNDER_CE
  344. // Copy keyname into buffer.
  345. #ifndef UNDER_CE
  346. StringCchCopyA(szKeyBuf, ARRAYSIZE(szKeyBuf), szKey);
  347. #else // UNDER_CE
  348. lstrcpy(szKeyBuf, szKey);
  349. #endif // UNDER_CE
  350. // Add subkey name to buffer.
  351. if (szSubkey != NULL)
  352. {
  353. #ifndef UNDER_CE
  354. StringCchCat(szKeyBuf, ARRAYSIZE(szKeyBuf), "\\") ;
  355. StringCchCat(szKeyBuf, ARRAYSIZE(szKeyBuf), szSubkey ) ;
  356. #else // UNDER_CE
  357. lstrcat(szKeyBuf, TEXT("\\")) ;
  358. lstrcat(szKeyBuf, szSubkey ) ;
  359. #endif // UNDER_CE
  360. }
  361. // Create and open key and subkey.
  362. #ifndef UNDER_CE
  363. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
  364. szKeyBuf,
  365. 0, NULL, REG_OPTION_NON_VOLATILE,
  366. KEY_ALL_ACCESS, NULL,
  367. &hKey, NULL) ;
  368. #else // UNDER_CE
  369. DWORD dwDisposition; // Under WinCE, Must set lpdwDisposition.
  370. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  371. szKeyBuf,
  372. 0, NULL, REG_OPTION_NON_VOLATILE,
  373. KEY_ALL_ACCESS, NULL,
  374. &hKey, &dwDisposition);
  375. #endif // UNDER_CE
  376. if (lResult != ERROR_SUCCESS)
  377. {
  378. return FALSE ;
  379. }
  380. // Set the Value.
  381. if (szValue != NULL)
  382. {
  383. #ifndef UNDER_CE
  384. RegSetValueEx(hKey, szName, 0, REG_SZ,
  385. (BYTE *)szValue,
  386. lstrlen(szValue)+1) ;
  387. #else // UNDER_CE
  388. RegSetValueEx(hKey, szName, 0, REG_SZ,
  389. (BYTE *)szValue,
  390. (lstrlen(szValue)+1) * sizeof(TCHAR));
  391. #endif // UNDER_CE
  392. }
  393. RegCloseKey(hKey) ;
  394. return TRUE ;
  395. }