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.

388 lines
9.2 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. DWORD MyBreakOnDbgAndRenterLoop(void)
  16. {
  17. __try
  18. {
  19. DebugBreak();
  20. }
  21. _except (EXCEPTION_EXECUTE_HANDLER) {};
  22. return EXCEPTION_CONTINUE_EXECUTION;
  23. }
  24. void CreatePathString( TCHAR* pTo,
  25. int cTo,
  26. WCHAR* pId,
  27. TCHAR* pPrefix )
  28. {
  29. TCHAR chId[128];
  30. #ifdef UNICODE
  31. StringCchCopy( chId, 128, pId );
  32. #else
  33. wcstombs( chId, pId, 128 );
  34. #endif
  35. StringCchCopy( pTo, cTo, pPrefix );
  36. StringCchCat( pTo, cTo, chId );
  37. }
  38. struct CClassInfo
  39. {
  40. LIST_ENTRY m_Entry;
  41. const CLSID* m_pClsid;
  42. CUnkInternal* m_pFactory;
  43. LPTSTR m_szName;
  44. BOOL m_bFreeThreaded;
  45. BOOL m_bReallyFree;
  46. DWORD m_dwCookie;
  47. public:
  48. CClassInfo(): m_pClsid(0), m_pFactory(0), m_szName(0), m_bFreeThreaded(0), m_dwCookie(0){}
  49. CClassInfo(CLSID* pClsid, LPTSTR szName, BOOL bFreeThreaded, BOOL bReallyFree) :
  50. m_pClsid(pClsid), m_pFactory(NULL), m_szName(szName),
  51. m_bFreeThreaded(bFreeThreaded), m_bReallyFree( bReallyFree )
  52. {}
  53. virtual ~CClassInfo()
  54. {
  55. delete [] m_szName;
  56. m_pFactory->InternalRelease();
  57. }
  58. };
  59. LIST_ENTRY g_ClassInfoHead = { &g_ClassInfoHead, &g_ClassInfoHead };
  60. static HMODULE ghModule;
  61. void SetModuleHandle(HMODULE hModule)
  62. {
  63. ghModule = hModule;
  64. }
  65. HMODULE GetThisModuleHandle()
  66. {
  67. return ghModule;
  68. }
  69. HRESULT RegisterServer(CClassInfo* pInfo, BOOL bExe)
  70. {
  71. WCHAR wchId[128];
  72. TCHAR szPath[256];
  73. TCHAR szModule[MAX_PATH+1];
  74. HKEY hKey1, hKey2;
  75. StringFromGUID2( *pInfo->m_pClsid, wchId, 128 );
  76. // Create the path.
  77. CreatePathString( szPath,
  78. 256,
  79. wchId,
  80. TEXT("SOFTWARE\\Classes\\CLSID\\"));
  81. // Create entries under CLSID
  82. RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1);
  83. int cLen = lstrlen(pInfo->m_szName)+100;
  84. TCHAR* szName = new TCHAR[cLen];
  85. StringCchPrintf( szName, cLen, L"Microsoft WBEM %s", pInfo->m_szName );
  86. RegSetValueEx(hKey1, NULL, 0, REG_SZ,
  87. (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR));
  88. RegCreateKey(hKey1,
  89. bExe?TEXT("LocalServer32"): TEXT("InprocServer32"),
  90. &hKey2);
  91. szModule[MAX_PATH] = L'0';
  92. GetModuleFileName(ghModule, szModule, MAX_PATH);
  93. RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule,
  94. (lstrlen(szModule)+1) * sizeof(TCHAR));
  95. const TCHAR* szModel;
  96. if(pInfo->m_bFreeThreaded)
  97. {
  98. if ( !pInfo->m_bReallyFree )
  99. {
  100. szModel = TEXT("Both");
  101. }
  102. else
  103. {
  104. szModel = TEXT("Free");
  105. }
  106. }
  107. else
  108. {
  109. szModel = TEXT("Apartment");
  110. }
  111. RegSetValueEx(hKey2, TEXT("ThreadingModel"), 0, REG_SZ,
  112. (BYTE *)szModel, (lstrlen(szModel)+1) * sizeof(TCHAR));
  113. RegCloseKey(hKey1);
  114. RegCloseKey(hKey2);
  115. return NOERROR;
  116. }
  117. HRESULT UnregisterServer(CClassInfo* pInfo, BOOL bExe)
  118. {
  119. WCHAR wchId[128];
  120. TCHAR szPath[256];
  121. HKEY hKey;
  122. StringFromGUID2( *pInfo->m_pClsid, wchId, 128 );
  123. // Create the path using the CLSID
  124. CreatePathString( szPath,
  125. 256,
  126. wchId,
  127. TEXT("SOFTWARE\\Classes\\CLSID\\"));
  128. // First delete the InProcServer subkey.
  129. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey);
  130. if(dwRet == NO_ERROR)
  131. {
  132. RegDeleteKey(hKey, bExe? TEXT("LocalServer32"): TEXT("InProcServer32"));
  133. RegCloseKey(hKey);
  134. }
  135. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\CLSID"), &hKey);
  136. if(dwRet == NO_ERROR)
  137. {
  138. RegDeleteKeyW(hKey, wchId);
  139. RegCloseKey(hKey);
  140. }
  141. return NOERROR;
  142. }
  143. extern CLifeControl* g_pLifeControl;
  144. CComServer* g_pServer = NULL;
  145. CComServer::CComServer()
  146. {
  147. g_pServer = this;
  148. }
  149. CLifeControl* CComServer::GetLifeControl()
  150. {
  151. return g_pLifeControl;
  152. }
  153. HRESULT CComServer::InitializeCom()
  154. {
  155. return CoInitialize(NULL);
  156. }
  157. HRESULT CComServer::AddClassInfo( REFCLSID rclsid,
  158. CUnkInternal* pFactory,
  159. LPTSTR szName,
  160. BOOL bFreeThreaded,
  161. BOOL bReallyFree /* = FALSE */)
  162. {
  163. if(pFactory == NULL)
  164. return E_OUTOFMEMORY;
  165. CClassInfo* pNewInfo = new CClassInfo;
  166. if (!pNewInfo)
  167. return E_OUTOFMEMORY;
  168. //
  169. // this object does not hold external references to class factories.
  170. //
  171. pFactory->InternalAddRef();
  172. pNewInfo->m_pFactory = pFactory;
  173. pNewInfo->m_pClsid = &rclsid;
  174. pNewInfo->m_szName = new TCHAR[lstrlen(szName) + 1];
  175. if (!pNewInfo->m_szName)
  176. {
  177. delete pNewInfo;
  178. return E_OUTOFMEMORY;
  179. }
  180. StringCchCopy( pNewInfo->m_szName, lstrlen(szName)+1, szName);
  181. pNewInfo->m_bFreeThreaded = bFreeThreaded;
  182. pNewInfo->m_bReallyFree = bReallyFree;
  183. InsertTailList(&g_ClassInfoHead,&pNewInfo->m_Entry);
  184. return S_OK;
  185. }
  186. HRESULT CComServer::RegisterInterfaceMarshaler(REFIID riid, LPTSTR szName,
  187. int nNumMembers, REFIID riidParent)
  188. {
  189. WCHAR wchId[128];
  190. TCHAR szPath[256];
  191. HKEY hKey1, hKey2;
  192. StringFromGUID2( riid, wchId, 128 );
  193. // Create the path.
  194. CreatePathString(szPath,256,wchId,TEXT("SOFTWARE\\Classes\\Interface\\"));
  195. // Create entries under CLSID
  196. RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1);
  197. RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR));
  198. RegCreateKey(hKey1, TEXT("ProxyStubClsid32"), &hKey2);
  199. RegSetValueExW( hKey2, NULL, 0, REG_SZ,(BYTE*)wchId,(wcslen(wchId)+1)*2);
  200. RegCloseKey(hKey1);
  201. RegCloseKey(hKey2);
  202. return S_OK;
  203. }
  204. HRESULT CComServer::RegisterInterfaceMarshaler( REFIID riid,
  205. CLSID psclsid,
  206. LPTSTR szName,
  207. int nNumMembers,
  208. REFIID riidParent)
  209. {
  210. WCHAR wchId[128];
  211. WCHAR wchClsid[128];
  212. TCHAR szPath[256];
  213. TCHAR szNumMethods[32];
  214. HKEY hKey1, hKey2, hKey3;
  215. // Create the path.
  216. StringFromGUID2(riid, wchId, 128);
  217. // ProxyStub Class ID
  218. StringFromGUID2(psclsid, wchClsid, 128);
  219. CreatePathString( szPath,
  220. 256,
  221. wchId,
  222. TEXT("SOFTWARE\\Classes\\Interface\\"));
  223. // Number of Methods
  224. StringCchPrintf( szNumMethods, 32, 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. RegSetValueExW(hKey2,NULL,0,REG_SZ,(BYTE*)wchClsid,(wcslen(wchClsid)+1)*2);
  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. WCHAR wchId[128];
  240. TCHAR szPath[256];
  241. HKEY hKey;
  242. // Create the path using the CLSID
  243. StringFromGUID2(riid, wchId, 128);
  244. CreatePathString(szPath,256,wchId,TEXT("SOFTWARE\\Classes\\Interface\\"));
  245. // First delete the ProxyStubClsid32 subkey.
  246. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey);
  247. if(dwRet == NO_ERROR)
  248. {
  249. RegDeleteKey(hKey, TEXT("ProxyStubClsid32"));
  250. RegCloseKey(hKey);
  251. }
  252. dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\Interface"), &hKey);
  253. if(dwRet == NO_ERROR)
  254. {
  255. RegDeleteKeyW( hKey, wchId );
  256. RegCloseKey(hKey);
  257. }
  258. return S_OK;
  259. }
  260. //
  261. // the caller will hold g_CS
  262. //
  263. void EmptyList()
  264. {
  265. while(!IsListEmpty(&g_ClassInfoHead))
  266. {
  267. CClassInfo * pInfo = CONTAINING_RECORD(g_ClassInfoHead.Blink,CClassInfo,m_Entry);
  268. RemoveEntryList(&pInfo->m_Entry);
  269. delete pInfo;
  270. }
  271. }
  272. BOOL GlobalCanShutdown()
  273. {
  274. return g_pServer->CanShutdown();
  275. }
  276. HRESULT GlobalInitialize()
  277. {
  278. return g_pServer->Initialize();
  279. }
  280. void GlobalUninitialize()
  281. {
  282. g_pServer->Uninitialize();
  283. EmptyList();
  284. }
  285. void GlobalPostUninitialize()
  286. {
  287. g_pServer->PostUninitialize();
  288. }
  289. void GlobalRegister()
  290. {
  291. g_pServer->Register();
  292. }
  293. void GlobalUnregister()
  294. {
  295. g_pServer->Unregister();
  296. }
  297. HRESULT GlobalInitializeCom()
  298. {
  299. return g_pServer->InitializeCom();
  300. }