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.

389 lines
8.6 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. COMMAIN.CPP
  5. Abstract:
  6. COM Helpers
  7. History:
  8. --*/
  9. #include <windows.h>
  10. #include <objbase.h>
  11. #include <stdio.h>
  12. #include <vector>
  13. #include <clsfac.h>
  14. #include "commain.h"
  15. void CopyOrConvert(TCHAR * pTo, WCHAR * pFrom, int iLen)
  16. {
  17. #ifdef UNICODE
  18. lstrcpy(pTo, pFrom);
  19. #else
  20. wcstombs(pTo, pFrom, iLen);
  21. #endif
  22. return;
  23. }
  24. struct CClassInfo
  25. {
  26. const CLSID* m_pClsid;
  27. CUnkInternal* m_pFactory;
  28. LPTSTR m_szName;
  29. BOOL m_bFreeThreaded;
  30. BOOL m_bReallyFree;
  31. DWORD m_dwCookie;
  32. public:
  33. CClassInfo(): m_pClsid(0), m_pFactory(0), m_szName(0), m_bFreeThreaded(0), m_dwCookie(0){}
  34. CClassInfo(CLSID* pClsid, LPTSTR szName, BOOL bFreeThreaded, BOOL bReallyFree) :
  35. m_pClsid(pClsid), m_pFactory(NULL), m_szName(szName),
  36. m_bFreeThreaded(bFreeThreaded), m_bReallyFree( bReallyFree )
  37. {}
  38. ~CClassInfo()
  39. { delete [] m_szName; m_pFactory->InternalRelease();}
  40. };
  41. static std::vector<CClassInfo*>* g_pClassInfos;
  42. static HMODULE ghModule;
  43. /*
  44. class __CleanUp
  45. {
  46. public:
  47. __CleanUp() {}
  48. ~__CleanUp()
  49. {
  50. g_pClassInfos->erase();
  51. }
  52. };
  53. */
  54. void SetModuleHandle(HMODULE hModule)
  55. {
  56. ghModule = hModule;
  57. }
  58. HMODULE GetThisModuleHandle()
  59. {
  60. return ghModule;
  61. }
  62. HRESULT RegisterServer(CClassInfo* pInfo, BOOL bExe)
  63. {
  64. TCHAR szID[128];
  65. WCHAR wcID[128];
  66. TCHAR szCLSID[128];
  67. TCHAR szModule[MAX_PATH];
  68. HKEY hKey1, hKey2;
  69. // Create the path.
  70. StringFromGUID2(*pInfo->m_pClsid, wcID, 128);
  71. CopyOrConvert(szID, wcID, 128);
  72. lstrcpy(szCLSID, TEXT("SOFTWARE\\Classes\\CLSID\\"));
  73. lstrcat(szCLSID, szID);
  74. // Create entries under CLSID
  75. RegCreateKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey1);
  76. TCHAR* szName = new TCHAR[lstrlen(pInfo->m_szName)+100];
  77. #ifdef UNICODE
  78. wsprintf(szName, L"Microsoft WBEM %s", pInfo->m_szName);
  79. #else
  80. sprintf(szName, "Microsoft WBEM %s", pInfo->m_szName);
  81. #endif
  82. RegSetValueEx(hKey1, NULL, 0, REG_SZ,
  83. (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR));
  84. RegCreateKey(hKey1,
  85. bExe?TEXT("LocalServer32"): TEXT("InprocServer32"),
  86. &hKey2);
  87. GetModuleFileName(ghModule, szModule, MAX_PATH);
  88. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule,
  89. (lstrlen(szModule)+1) * sizeof(TCHAR));
  90. const TCHAR* szModel;
  91. if(pInfo->m_bFreeThreaded)
  92. {
  93. if ( !pInfo->m_bReallyFree )
  94. {
  95. szModel = TEXT("Both");
  96. }
  97. else
  98. {
  99. szModel = TEXT("Free");
  100. }
  101. }
  102. else
  103. {
  104. szModel = TEXT("Apartment");
  105. }
  106. RegSetValueEx(hKey2, TEXT("ThreadingModel"), 0, REG_SZ,
  107. (BYTE *)szModel, (lstrlen(szModel)+1) * sizeof(TCHAR));
  108. RegCloseKey(hKey1);
  109. RegCloseKey(hKey2);
  110. return NOERROR;
  111. }
  112. HRESULT UnregisterServer(CClassInfo* pInfo, BOOL bExe)
  113. {
  114. TCHAR szID[128];
  115. WCHAR wcID[128];
  116. TCHAR szCLSID[256];
  117. HKEY hKey;
  118. // Create the path using the CLSID
  119. StringFromGUID2(*pInfo->m_pClsid, wcID, 128);
  120. CopyOrConvert(szID, wcID, 128);
  121. lstrcpy(szCLSID, TEXT("SOFTWARE\\Classes\\CLSID\\"));
  122. lstrcat(szCLSID, szID);
  123. // First delete the InProcServer subkey.
  124. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szCLSID, &hKey);
  125. if(dwRet == NO_ERROR)
  126. {
  127. RegDeleteKey(hKey, bExe? TEXT("LocalServer32"): TEXT("InProcServer32"));
  128. RegCloseKey(hKey);
  129. }
  130. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\CLSID"), &hKey);
  131. if(dwRet == NO_ERROR)
  132. {
  133. RegDeleteKey(hKey,szID);
  134. RegCloseKey(hKey);
  135. }
  136. return NOERROR;
  137. }
  138. extern CLifeControl* g_pLifeControl;
  139. CComServer* g_pServer = NULL;
  140. CComServer::CComServer()
  141. {
  142. g_pServer = this;
  143. }
  144. CLifeControl* CComServer::GetLifeControl()
  145. {
  146. return g_pLifeControl;
  147. }
  148. HRESULT CComServer::InitializeCom()
  149. {
  150. return CoInitialize(NULL);
  151. }
  152. HRESULT CComServer::AddClassInfo( REFCLSID rclsid,
  153. CUnkInternal* pFactory,
  154. LPTSTR szName,
  155. BOOL bFreeThreaded,
  156. BOOL bReallyFree /* = FALSE */)
  157. {
  158. if ( NULL == g_pClassInfos )
  159. {
  160. return E_FAIL;
  161. }
  162. if(pFactory == NULL)
  163. return E_OUTOFMEMORY;
  164. CClassInfo* pNewInfo = new CClassInfo;
  165. if (!pNewInfo)
  166. return E_OUTOFMEMORY;
  167. //
  168. // this object does not hold external references to class factories.
  169. //
  170. pFactory->InternalAddRef();
  171. pNewInfo->m_pFactory = pFactory;
  172. pNewInfo->m_pClsid = &rclsid;
  173. pNewInfo->m_szName = new TCHAR[lstrlen(szName) + 1];
  174. if (!pNewInfo->m_szName)
  175. {
  176. delete pNewInfo;
  177. return E_OUTOFMEMORY;
  178. }
  179. lstrcpy(pNewInfo->m_szName, szName);
  180. pNewInfo->m_bFreeThreaded = bFreeThreaded;
  181. pNewInfo->m_bReallyFree = bReallyFree;
  182. g_pClassInfos->insert( g_pClassInfos->end(), pNewInfo );
  183. return S_OK;
  184. }
  185. HRESULT CComServer::RegisterInterfaceMarshaler(REFIID riid, LPTSTR szName,
  186. int nNumMembers, REFIID riidParent)
  187. {
  188. TCHAR szID[128];
  189. WCHAR wcID[128];
  190. TCHAR szPath[256];
  191. HKEY hKey1, hKey2;
  192. // Create the path.
  193. StringFromGUID2(riid, wcID, 128);
  194. CopyOrConvert(szID, wcID, 128);
  195. lstrcpy(szPath, TEXT("SOFTWARE\\Classes\\Interface\\"));
  196. lstrcat(szPath, szID);
  197. // Create entries under CLSID
  198. RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1);
  199. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR));
  200. RegCreateKey(hKey1, TEXT("ProxyStubClsid32"), &hKey2);
  201. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szID, (lstrlen(szID)+1) * sizeof(TCHAR));
  202. RegCloseKey(hKey1);
  203. RegCloseKey(hKey2);
  204. return S_OK;
  205. }
  206. HRESULT CComServer::RegisterInterfaceMarshaler(REFIID riid, CLSID psclsid, LPTSTR szName,
  207. int nNumMembers, REFIID riidParent)
  208. {
  209. TCHAR szID[128];
  210. TCHAR szClsID[128];
  211. WCHAR wcID[128];
  212. TCHAR szPath[128];
  213. TCHAR szNumMethods[32];
  214. HKEY hKey1, hKey2, hKey3;
  215. // Create the path.
  216. StringFromGUID2(riid, wcID, 128);
  217. CopyOrConvert(szID, wcID, 128);
  218. // ProxyStub Class ID
  219. StringFromGUID2(psclsid, wcID, 128);
  220. CopyOrConvert(szClsID, wcID, 128);
  221. lstrcpy(szPath, TEXT("SOFTWARE\\Classes\\Interface\\"));
  222. lstrcat(szPath, szID);
  223. // Number of Methods
  224. wsprintf( szNumMethods, TEXT("%d"), nNumMembers );
  225. // Create entries under CLSID
  226. RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1);
  227. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR));
  228. RegCreateKey(hKey1, TEXT("ProxyStubClsid32"), &hKey2);
  229. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szClsID, (lstrlen(szID)+1) * sizeof(TCHAR));
  230. RegCreateKey(hKey1, TEXT("NumMethods"), &hKey3);
  231. RegSetValueEx(hKey3, NULL, 0, REG_SZ, (BYTE *)szNumMethods, (lstrlen(szNumMethods)+1) * sizeof(TCHAR));
  232. RegCloseKey(hKey1);
  233. RegCloseKey(hKey2);
  234. RegCloseKey(hKey3);
  235. return S_OK;
  236. }
  237. HRESULT CComServer::UnregisterInterfaceMarshaler(REFIID riid)
  238. {
  239. TCHAR szID[128];
  240. WCHAR wcID[128];
  241. TCHAR szPath[128];
  242. HKEY hKey;
  243. // Create the path using the CLSID
  244. StringFromGUID2(riid, wcID, 128);
  245. CopyOrConvert(szID, wcID, 128);
  246. lstrcpy(szPath, TEXT("SOFTWARE\\Classes\\Interface\\"));
  247. lstrcat(szPath, szID);
  248. // First delete the ProxyStubClsid32 subkey.
  249. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey);
  250. if(dwRet == NO_ERROR)
  251. {
  252. RegDeleteKey(hKey, TEXT("ProxyStubClsid32"));
  253. RegCloseKey(hKey);
  254. }
  255. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\Interface"), &hKey);
  256. if(dwRet == NO_ERROR)
  257. {
  258. RegDeleteKey(hKey, szID);
  259. RegCloseKey(hKey);
  260. }
  261. return S_OK;
  262. }
  263. BOOL GlobalCanShutdown()
  264. {
  265. return g_pServer->CanShutdown();
  266. }
  267. HRESULT GlobalInitialize()
  268. {
  269. g_pClassInfos = new std::vector<CClassInfo*>;
  270. if ( g_pClassInfos == NULL )
  271. {
  272. return E_OUTOFMEMORY;
  273. }
  274. return g_pServer->Initialize();
  275. }
  276. void GlobalUninitialize()
  277. {
  278. g_pServer->Uninitialize();
  279. if ( NULL != g_pClassInfos )
  280. {
  281. for( int i=0; i < g_pClassInfos->size(); i++ )
  282. {
  283. delete (*g_pClassInfos)[i];
  284. }
  285. delete g_pClassInfos;
  286. g_pClassInfos = NULL;
  287. }
  288. }
  289. void GlobalPostUninitialize()
  290. {
  291. g_pServer->PostUninitialize();
  292. }
  293. void GlobalRegister()
  294. {
  295. g_pServer->Register();
  296. }
  297. void GlobalUnregister()
  298. {
  299. g_pServer->Unregister();
  300. }
  301. HRESULT GlobalInitializeCom()
  302. {
  303. return g_pServer->InitializeCom();
  304. }