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.

512 lines
12 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. termmgr.cpp
  5. Abstract:
  6. Implementation of DLL Exports.
  7. Author:
  8. Created 05/01/97 Michael Clark.
  9. --*/
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "initguid.h"
  13. #include "termmgr.h"
  14. #include "dlldatax.h"
  15. #include "Manager.h"
  16. #include "allterm.h"
  17. #include "meterf.h"
  18. #include "medpump.h"
  19. #include <initguid.h>
  20. #include <uuids.h>
  21. #include <vfwmsgs.h>
  22. #include "FileRecordingTerminal.h"
  23. #include "FPTerm.h"
  24. #include "PTUtil.h"
  25. #include "PTReg.h"
  26. //
  27. // For the ntbuild environment we need to include this file to get the base
  28. // class implementations.
  29. //
  30. #ifdef _ATL_STATIC_REGISTRY
  31. #include <statreg.h>
  32. #include <statreg.cpp>
  33. #endif
  34. #include <atlimpl.cpp>
  35. #ifdef _MERGE_PROXYSTUB
  36. extern "C" HINSTANCE hProxyDll;
  37. #endif
  38. #ifdef DEBUG_HEAPS
  39. // ZoltanS: for heap debugging
  40. #include <crtdbg.h>
  41. #endif // DEBUG_HEAPS
  42. CComModule _Module;
  43. // Must have an entry here for each cocreatable object.
  44. BEGIN_OBJECT_MAP(ObjectMap)
  45. OBJECT_ENTRY(CLSID_TerminalManager, CTerminalManager)
  46. OBJECT_ENTRY(CLSID_VideoWindowTerminal_PRIVATE, CVideoRenderTerminal)
  47. OBJECT_ENTRY(CLSID_MediaStreamingTerminal_PRIVATE, CMediaTerminal)
  48. OBJECT_ENTRY(CLSID_FileRecordingTerminalCOMClass, CFileRecordingTerminal)
  49. OBJECT_ENTRY(CLSID_FilePlaybackTerminalCOMClass, CFPTerminal)
  50. OBJECT_ENTRY(CLSID_PluggableSuperclassRegistration,CPlugTerminalSuperclass)
  51. OBJECT_ENTRY(CLSID_PluggableTerminalRegistration, CPlugTerminal)
  52. END_OBJECT_MAP()
  53. //
  54. // PTInfo
  55. // Structure used to store information about
  56. // our pluggable temrinals implemented into Termmgr.dll
  57. typedef struct
  58. {
  59. UINT nSuperclassName; // Superclass Name
  60. BSTR bstrSueprclassCLSID; // Superclass CLSID
  61. const CLSID* pClsidTerminalClass; // Terminal Class (public CLSID)
  62. const CLSID* pClsidCOM; // COM clsid (private CLSID)
  63. UINT nTerminalName; // Terminal name
  64. UINT nCompanyName; // Company name
  65. UINT nVersion; // Terminal version
  66. DWORD dwDirections; // Terminal directions
  67. DWORD dwMediaTypes; // Media types supported
  68. } PTInfo;
  69. //
  70. // Global array with pluggable terminals implemented into Termmgr.dll
  71. //
  72. PTInfo g_PlugTerminals[] =
  73. {
  74. #define SUPERCLASS_CLSID_VIDEO_WINDOW L"{714C6F8C-6244-4685-87B3-B91F3F9EADA7}"
  75. {
  76. // VideoWindowTerminal
  77. IDS_VIDEO_SUPERCLASS, // superclass name
  78. SUPERCLASS_CLSID_VIDEO_WINDOW, //L"{714C6F8C-6244-4685-87B3-B91F3F9EADA7}",
  79. &CLSID_VideoWindowTerm,
  80. &CLSID_VideoWindowTerminal_PRIVATE, // com class id of the terminal object
  81. IDS_VIDEO_WINDOW_TERMINAL_NAME, // L"VideoWindow Terminal",
  82. IDS_TERMINAL_COMPANY_NAME_MICROSOFT, // L"Microsoft",
  83. IDS_VIDEO_TERMINAL_VERSION, // L"1.1",
  84. TMGR_TD_RENDER,
  85. TAPIMEDIATYPE_VIDEO
  86. },
  87. #define SUPERCLASS_CLSID_MST L"{214F4ACC-AE0B-4464-8405-07029003F8E2}"
  88. {
  89. // MediaStreaming Terminal
  90. IDS_STREAMING_SUPERCLASS,
  91. SUPERCLASS_CLSID_MST, //L"{214F4ACC-AE0B-4464-8405-07029003F8E2}",
  92. &CLSID_MediaStreamTerminal,
  93. &CLSID_MediaStreamingTerminal_PRIVATE,
  94. IDS_MEDIA_STREAMING_TERMINAL_NAME, //L"MediaStreaming Terminal",
  95. IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft",
  96. IDS_MEDIA_STREAMING_TERMINAL_VERSION, //L"1.1",
  97. TMGR_TD_BOTH,
  98. TAPIMEDIATYPE_AUDIO
  99. },
  100. #define SUPERCLASS_CLSID_FILE L"{B4790031-56DB-4D3E-88C8-6FFAAFA08A91}"
  101. {
  102. // FileRecording Terminal
  103. IDS_FILE_SUPERCLASS,
  104. SUPERCLASS_CLSID_FILE, //L"{B4790031-56DB-4d3e-88C8-6FFAAFA08A91}",
  105. &CLSID_FileRecordingTerminal,
  106. &CLSID_FileRecordingTerminalCOMClass,
  107. IDS_FILE_RECORD_TERMINAL_NAME, //L"FileRecording Terminal",
  108. IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft",
  109. IDS_FILE_RECORD_TERMINAL_VERSION, //L"1.1",
  110. TMGR_TD_RENDER,
  111. TAPIMEDIATYPE_AUDIO | TAPIMEDIATYPE_MULTITRACK
  112. },
  113. {
  114. // FilePlayback Terminal
  115. IDS_FILE_SUPERCLASS,
  116. SUPERCLASS_CLSID_FILE, //L"{B4790031-56DB-4d3e-88C8-6FFAAFA08A91}",
  117. &CLSID_FilePlaybackTerminal,
  118. &CLSID_FilePlaybackTerminalCOMClass,
  119. IDS_FILE_PLAYBACK_TERMINAL_NAME, //L"FilePlayback Terminal",
  120. IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft",
  121. IDS_FILE_PLAYBACK_TERMINAL_VERSION, //L"1.1",
  122. TMGR_TD_CAPTURE,
  123. TAPIMEDIATYPE_AUDIO | TAPIMEDIATYPE_MULTITRACK
  124. }
  125. };
  126. /*++
  127. PTRegisterTerminal
  128. Is called by PTRegister,
  129. read the information from the global Pluggable terminals array
  130. --*/
  131. HRESULT PTRegisterTerminal(
  132. IN int nTerminal
  133. )
  134. {
  135. CPTSuperclass Superclass;
  136. LOG((MSP_TRACE, "PTRegisterTerminal - enter"));
  137. //
  138. // Get the superclass name
  139. //
  140. Superclass.m_bstrName = SafeLoadString(g_PlugTerminals[nTerminal].nSuperclassName);
  141. if( Superclass.m_bstrName == NULL )
  142. {
  143. return E_OUTOFMEMORY;
  144. }
  145. LOG((MSP_TRACE, "PTRegisterTerminal - superclass [%S]", Superclass.m_bstrName));
  146. //
  147. // Get the superclass CLSID
  148. //
  149. HRESULT hr = CLSIDFromString(
  150. g_PlugTerminals[nTerminal].bstrSueprclassCLSID,
  151. &Superclass.m_clsidSuperclass);
  152. if( FAILED(hr) )
  153. {
  154. return hr;
  155. }
  156. Superclass.Add();
  157. CPTTerminal Terminal;
  158. PTInfo& TermInfo = g_PlugTerminals[nTerminal];
  159. //
  160. // Get the TerminalClass clsid
  161. //
  162. Terminal.m_clsidTerminalClass = *TermInfo.pClsidTerminalClass;
  163. //
  164. // Get terminal's com class id
  165. //
  166. Terminal.m_clsidCOM = *TermInfo.pClsidCOM;
  167. //
  168. // Set the other terminal fileds
  169. // CPTTerminal will deallocate the memory
  170. //
  171. Terminal.m_bstrName = SafeLoadString( TermInfo.nTerminalName );
  172. if( Terminal.m_bstrName == NULL)
  173. {
  174. return E_OUTOFMEMORY;
  175. }
  176. LOG((MSP_TRACE, "PTRegisterTerminal - terminal [%S]", Terminal.m_bstrName));
  177. Terminal.m_bstrCompany = SafeLoadString( TermInfo.nCompanyName );
  178. if( Terminal.m_bstrCompany == NULL )
  179. {
  180. return E_OUTOFMEMORY;
  181. }
  182. Terminal.m_bstrVersion = SafeLoadString( TermInfo.nVersion );
  183. if( Terminal.m_bstrVersion == NULL )
  184. {
  185. return E_OUTOFMEMORY;
  186. }
  187. Terminal.m_dwDirections = TermInfo.dwDirections;
  188. Terminal.m_dwMediaTypes = TermInfo.dwMediaTypes;
  189. //
  190. // Register terminal
  191. //
  192. hr = Terminal.Add( Superclass.m_clsidSuperclass );
  193. return hr;
  194. }
  195. /*++
  196. PTUnregisterTerminal
  197. Is called by PTUnregister,
  198. Read the information from global pluggable terminals array
  199. --*/
  200. HRESULT PTUnregisterTerminal(
  201. IN int nTerminal
  202. )
  203. {
  204. CPTSuperclass Superclass;
  205. {
  206. //
  207. // Get the superclass name
  208. //
  209. TCHAR szName[MAX_PATH+1];
  210. int nRetVal = LoadString( _Module.GetResourceInstance(),
  211. g_PlugTerminals[nTerminal].nSuperclassName,
  212. szName,
  213. MAX_PATH
  214. );
  215. if( 0 == nRetVal )
  216. {
  217. return E_OUTOFMEMORY;
  218. }
  219. Superclass.m_bstrName = SysAllocString( szName );
  220. }
  221. //
  222. // Get the superclass CLSID
  223. //
  224. HRESULT hr = CLSIDFromString(
  225. g_PlugTerminals[nTerminal].bstrSueprclassCLSID,
  226. &Superclass.m_clsidSuperclass);
  227. //
  228. // Unregister a terminal
  229. //
  230. CPTTerminal Terminal;
  231. Terminal.m_clsidTerminalClass = *g_PlugTerminals[nTerminal].pClsidTerminalClass;
  232. Terminal.Delete( Superclass.m_clsidSuperclass );
  233. return S_OK;
  234. }
  235. /////////////////////////////////////////////////////////////////////////////
  236. // PTRegister
  237. HRESULT PTRegister()
  238. {
  239. //
  240. // Register each pluggable terminal
  241. //
  242. for(int nItem = 0;
  243. nItem < (sizeof( g_PlugTerminals) / sizeof(PTInfo));
  244. nItem++)
  245. {
  246. PTRegisterTerminal(
  247. nItem
  248. );
  249. }
  250. return S_OK;
  251. }
  252. /////////////////////////////////////////////////////////////////////////////
  253. // PTUnregister
  254. HRESULT PTUnregister()
  255. {
  256. // Unregister each pluggable terminal
  257. for(int nItem = 0;
  258. nItem < (sizeof( g_PlugTerminals) / sizeof(PTInfo));
  259. nItem++)
  260. {
  261. PTUnregisterTerminal(
  262. nItem
  263. );
  264. }
  265. return S_OK;
  266. }
  267. /////////////////////////////////////////////////////////////////////////////
  268. // DLL Entry Point
  269. extern "C"
  270. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  271. {
  272. lpReserved;
  273. #ifdef _MERGE_PROXYSTUB
  274. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  275. {
  276. return FALSE;
  277. }
  278. #endif
  279. if (dwReason == DLL_PROCESS_ATTACH)
  280. {
  281. #ifdef DEBUG_HEAPS
  282. // ZoltanS: turn on leak detection on process exit
  283. _CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF );
  284. // ZoltanS: force a memory leak
  285. char * leak = new char [ 1977 ];
  286. sprintf(leak, "termmgr.dll NORMAL leak");
  287. leak = NULL;
  288. #endif // DEBUG_HEAPS
  289. _Module.Init(ObjectMap, hInstance);
  290. DisableThreadLibraryCalls(hInstance);
  291. // Register for trace output.
  292. MSPLOGREGISTER(_T("termmgr"));
  293. }
  294. else if (dwReason == DLL_PROCESS_DETACH)
  295. {
  296. //
  297. // do not deregister if the process is terminating -- working around
  298. // bugs in rtutils that could cause a "deadlock" if DeregisterTracing
  299. // is called from DllMain on process termination
  300. //
  301. if (NULL == lpReserved)
  302. {
  303. // Deregister for trace output.
  304. MSPLOGDEREGISTER();
  305. }
  306. _Module.Term();
  307. }
  308. return TRUE; // ok
  309. }
  310. /////////////////////////////////////////////////////////////////////////////
  311. // Used to determine whether the DLL can be unloaded by OLE
  312. STDAPI DllCanUnloadNow(void)
  313. {
  314. #ifdef _MERGE_PROXYSTUB
  315. if ( PrxDllCanUnloadNow() != S_OK )
  316. {
  317. return S_FALSE;
  318. }
  319. #endif
  320. if ( _Module.GetLockCount() == 0 )
  321. {
  322. //
  323. // All references to COM objects in this DLL have been released, so
  324. // the DLL can now be safely unloaded. After this returns, DllMain
  325. // will be called with dwReason == DLL_PROCESS_DETACH.
  326. //
  327. return S_OK;
  328. }
  329. else
  330. {
  331. return S_FALSE;
  332. }
  333. }
  334. /////////////////////////////////////////////////////////////////////////////
  335. // Returns a class factory to create an object of the requested type
  336. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  337. {
  338. #ifdef _MERGE_PROXYSTUB
  339. if ( PrxDllGetClassObject(rclsid, riid, ppv) == S_OK )
  340. {
  341. return S_OK;
  342. }
  343. #endif
  344. return _Module.GetClassObject(rclsid, riid, ppv);
  345. }
  346. /////////////////////////////////////////////////////////////////////////////
  347. // DllRegisterServer - Adds entries to the system registry
  348. STDAPI DllRegisterServer(void)
  349. {
  350. //
  351. // Register terminals
  352. HRESULT hReg = PTRegister();
  353. #ifdef _MERGE_PROXYSTUB
  354. HRESULT hRes = PrxDllRegisterServer();
  355. if ( FAILED(hRes) )
  356. {
  357. return hRes;
  358. }
  359. #endif
  360. // registers object, typelib and all interfaces in typelib
  361. HRESULT hr = _Module.RegisterServer(TRUE);
  362. if( FAILED(hr) )
  363. {
  364. //
  365. // This is real bad
  366. //
  367. return hr;
  368. }
  369. if( FAILED(hReg) )
  370. {
  371. //
  372. // Something was wrong with the
  373. // registration of pluggable terminals
  374. //
  375. return hReg;
  376. }
  377. //
  378. // Everything was OK
  379. //
  380. return S_OK;
  381. }
  382. /////////////////////////////////////////////////////////////////////////////
  383. // DllUnregisterServer - Removes entries from the system registry
  384. STDAPI DllUnregisterServer(void)
  385. {
  386. //
  387. // Unregister terminals
  388. //
  389. PTUnregister();
  390. #ifdef _MERGE_PROXYSTUB
  391. PrxDllUnregisterServer();
  392. #endif
  393. _Module.UnregisterServer();
  394. return S_OK;
  395. }