/*++ Copyright (c) 1997-1999 Microsoft Corporation Module Name: termmgr.cpp Abstract: Implementation of DLL Exports. Author: Created 05/01/97 Michael Clark. --*/ #include "stdafx.h" #include "resource.h" #include "initguid.h" #include "termmgr.h" #include "dlldatax.h" #include "Manager.h" #include "allterm.h" #include "meterf.h" #include "medpump.h" #include #include #include #include "FileRecordingTerminal.h" #include "FPTerm.h" #include "PTUtil.h" #include "PTReg.h" // // For the ntbuild environment we need to include this file to get the base // class implementations. // #ifdef _ATL_STATIC_REGISTRY #include #include #endif #include #ifdef _MERGE_PROXYSTUB extern "C" HINSTANCE hProxyDll; #endif #ifdef DEBUG_HEAPS // ZoltanS: for heap debugging #include #endif // DEBUG_HEAPS CComModule _Module; // Must have an entry here for each cocreatable object. BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_TerminalManager, CTerminalManager) OBJECT_ENTRY(CLSID_VideoWindowTerminal_PRIVATE, CVideoRenderTerminal) OBJECT_ENTRY(CLSID_MediaStreamingTerminal_PRIVATE, CMediaTerminal) OBJECT_ENTRY(CLSID_FileRecordingTerminalCOMClass, CFileRecordingTerminal) OBJECT_ENTRY(CLSID_FilePlaybackTerminalCOMClass, CFPTerminal) OBJECT_ENTRY(CLSID_PluggableSuperclassRegistration,CPlugTerminalSuperclass) OBJECT_ENTRY(CLSID_PluggableTerminalRegistration, CPlugTerminal) END_OBJECT_MAP() // // PTInfo // Structure used to store information about // our pluggable temrinals implemented into Termmgr.dll typedef struct { UINT nSuperclassName; // Superclass Name BSTR bstrSueprclassCLSID; // Superclass CLSID const CLSID* pClsidTerminalClass; // Terminal Class (public CLSID) const CLSID* pClsidCOM; // COM clsid (private CLSID) UINT nTerminalName; // Terminal name UINT nCompanyName; // Company name UINT nVersion; // Terminal version DWORD dwDirections; // Terminal directions DWORD dwMediaTypes; // Media types supported } PTInfo; // // Global array with pluggable terminals implemented into Termmgr.dll // PTInfo g_PlugTerminals[] = { #define SUPERCLASS_CLSID_VIDEO_WINDOW L"{714C6F8C-6244-4685-87B3-B91F3F9EADA7}" { // VideoWindowTerminal IDS_VIDEO_SUPERCLASS, // superclass name SUPERCLASS_CLSID_VIDEO_WINDOW, //L"{714C6F8C-6244-4685-87B3-B91F3F9EADA7}", &CLSID_VideoWindowTerm, &CLSID_VideoWindowTerminal_PRIVATE, // com class id of the terminal object IDS_VIDEO_WINDOW_TERMINAL_NAME, // L"VideoWindow Terminal", IDS_TERMINAL_COMPANY_NAME_MICROSOFT, // L"Microsoft", IDS_VIDEO_TERMINAL_VERSION, // L"1.1", TMGR_TD_RENDER, TAPIMEDIATYPE_VIDEO }, #define SUPERCLASS_CLSID_MST L"{214F4ACC-AE0B-4464-8405-07029003F8E2}" { // MediaStreaming Terminal IDS_STREAMING_SUPERCLASS, SUPERCLASS_CLSID_MST, //L"{214F4ACC-AE0B-4464-8405-07029003F8E2}", &CLSID_MediaStreamTerminal, &CLSID_MediaStreamingTerminal_PRIVATE, IDS_MEDIA_STREAMING_TERMINAL_NAME, //L"MediaStreaming Terminal", IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft", IDS_MEDIA_STREAMING_TERMINAL_VERSION, //L"1.1", TMGR_TD_BOTH, TAPIMEDIATYPE_AUDIO }, #define SUPERCLASS_CLSID_FILE L"{B4790031-56DB-4D3E-88C8-6FFAAFA08A91}" { // FileRecording Terminal IDS_FILE_SUPERCLASS, SUPERCLASS_CLSID_FILE, //L"{B4790031-56DB-4d3e-88C8-6FFAAFA08A91}", &CLSID_FileRecordingTerminal, &CLSID_FileRecordingTerminalCOMClass, IDS_FILE_RECORD_TERMINAL_NAME, //L"FileRecording Terminal", IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft", IDS_FILE_RECORD_TERMINAL_VERSION, //L"1.1", TMGR_TD_RENDER, TAPIMEDIATYPE_AUDIO | TAPIMEDIATYPE_MULTITRACK }, { // FilePlayback Terminal IDS_FILE_SUPERCLASS, SUPERCLASS_CLSID_FILE, //L"{B4790031-56DB-4d3e-88C8-6FFAAFA08A91}", &CLSID_FilePlaybackTerminal, &CLSID_FilePlaybackTerminalCOMClass, IDS_FILE_PLAYBACK_TERMINAL_NAME, //L"FilePlayback Terminal", IDS_TERMINAL_COMPANY_NAME_MICROSOFT, //L"Microsoft", IDS_FILE_PLAYBACK_TERMINAL_VERSION, //L"1.1", TMGR_TD_CAPTURE, TAPIMEDIATYPE_AUDIO | TAPIMEDIATYPE_MULTITRACK } }; /*++ PTRegisterTerminal Is called by PTRegister, read the information from the global Pluggable terminals array --*/ HRESULT PTRegisterTerminal( IN int nTerminal ) { CPTSuperclass Superclass; LOG((MSP_TRACE, "PTRegisterTerminal - enter")); // // Get the superclass name // Superclass.m_bstrName = SafeLoadString(g_PlugTerminals[nTerminal].nSuperclassName); if( Superclass.m_bstrName == NULL ) { return E_OUTOFMEMORY; } LOG((MSP_TRACE, "PTRegisterTerminal - superclass [%S]", Superclass.m_bstrName)); // // Get the superclass CLSID // HRESULT hr = CLSIDFromString( g_PlugTerminals[nTerminal].bstrSueprclassCLSID, &Superclass.m_clsidSuperclass); if( FAILED(hr) ) { return hr; } Superclass.Add(); CPTTerminal Terminal; PTInfo& TermInfo = g_PlugTerminals[nTerminal]; // // Get the TerminalClass clsid // Terminal.m_clsidTerminalClass = *TermInfo.pClsidTerminalClass; // // Get terminal's com class id // Terminal.m_clsidCOM = *TermInfo.pClsidCOM; // // Set the other terminal fileds // CPTTerminal will deallocate the memory // Terminal.m_bstrName = SafeLoadString( TermInfo.nTerminalName ); if( Terminal.m_bstrName == NULL) { return E_OUTOFMEMORY; } LOG((MSP_TRACE, "PTRegisterTerminal - terminal [%S]", Terminal.m_bstrName)); Terminal.m_bstrCompany = SafeLoadString( TermInfo.nCompanyName ); if( Terminal.m_bstrCompany == NULL ) { return E_OUTOFMEMORY; } Terminal.m_bstrVersion = SafeLoadString( TermInfo.nVersion ); if( Terminal.m_bstrVersion == NULL ) { return E_OUTOFMEMORY; } Terminal.m_dwDirections = TermInfo.dwDirections; Terminal.m_dwMediaTypes = TermInfo.dwMediaTypes; // // Register terminal // hr = Terminal.Add( Superclass.m_clsidSuperclass ); return hr; } /*++ PTUnregisterTerminal Is called by PTUnregister, Read the information from global pluggable terminals array --*/ HRESULT PTUnregisterTerminal( IN int nTerminal ) { CPTSuperclass Superclass; { // // Get the superclass name // TCHAR szName[MAX_PATH+1]; int nRetVal = LoadString( _Module.GetResourceInstance(), g_PlugTerminals[nTerminal].nSuperclassName, szName, MAX_PATH ); if( 0 == nRetVal ) { return E_OUTOFMEMORY; } Superclass.m_bstrName = SysAllocString( szName ); } // // Get the superclass CLSID // HRESULT hr = CLSIDFromString( g_PlugTerminals[nTerminal].bstrSueprclassCLSID, &Superclass.m_clsidSuperclass); // // Unregister a terminal // CPTTerminal Terminal; Terminal.m_clsidTerminalClass = *g_PlugTerminals[nTerminal].pClsidTerminalClass; Terminal.Delete( Superclass.m_clsidSuperclass ); return S_OK; } ///////////////////////////////////////////////////////////////////////////// // PTRegister HRESULT PTRegister() { // // Register each pluggable terminal // for(int nItem = 0; nItem < (sizeof( g_PlugTerminals) / sizeof(PTInfo)); nItem++) { PTRegisterTerminal( nItem ); } return S_OK; } ///////////////////////////////////////////////////////////////////////////// // PTUnregister HRESULT PTUnregister() { // Unregister each pluggable terminal for(int nItem = 0; nItem < (sizeof( g_PlugTerminals) / sizeof(PTInfo)); nItem++) { PTUnregisterTerminal( nItem ); } return S_OK; } ///////////////////////////////////////////////////////////////////////////// // DLL Entry Point extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { lpReserved; #ifdef _MERGE_PROXYSTUB if (!PrxDllMain(hInstance, dwReason, lpReserved)) { return FALSE; } #endif if (dwReason == DLL_PROCESS_ATTACH) { #ifdef DEBUG_HEAPS // ZoltanS: turn on leak detection on process exit _CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF ); // ZoltanS: force a memory leak char * leak = new char [ 1977 ]; sprintf(leak, "termmgr.dll NORMAL leak"); leak = NULL; #endif // DEBUG_HEAPS _Module.Init(ObjectMap, hInstance); DisableThreadLibraryCalls(hInstance); // Register for trace output. MSPLOGREGISTER(_T("termmgr")); } else if (dwReason == DLL_PROCESS_DETACH) { // // do not deregister if the process is terminating -- working around // bugs in rtutils that could cause a "deadlock" if DeregisterTracing // is called from DllMain on process termination // if (NULL == lpReserved) { // Deregister for trace output. MSPLOGDEREGISTER(); } _Module.Term(); } return TRUE; // ok } ///////////////////////////////////////////////////////////////////////////// // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow(void) { #ifdef _MERGE_PROXYSTUB if ( PrxDllCanUnloadNow() != S_OK ) { return S_FALSE; } #endif if ( _Module.GetLockCount() == 0 ) { // // All references to COM objects in this DLL have been released, so // the DLL can now be safely unloaded. After this returns, DllMain // will be called with dwReason == DLL_PROCESS_DETACH. // return S_OK; } else { return S_FALSE; } } ///////////////////////////////////////////////////////////////////////////// // Returns a class factory to create an object of the requested type STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { #ifdef _MERGE_PROXYSTUB if ( PrxDllGetClassObject(rclsid, riid, ppv) == S_OK ) { return S_OK; } #endif return _Module.GetClassObject(rclsid, riid, ppv); } ///////////////////////////////////////////////////////////////////////////// // DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer(void) { // // Register terminals HRESULT hReg = PTRegister(); #ifdef _MERGE_PROXYSTUB HRESULT hRes = PrxDllRegisterServer(); if ( FAILED(hRes) ) { return hRes; } #endif // registers object, typelib and all interfaces in typelib HRESULT hr = _Module.RegisterServer(TRUE); if( FAILED(hr) ) { // // This is real bad // return hr; } if( FAILED(hReg) ) { // // Something was wrong with the // registration of pluggable terminals // return hReg; } // // Everything was OK // return S_OK; } ///////////////////////////////////////////////////////////////////////////// // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { // // Unregister terminals // PTUnregister(); #ifdef _MERGE_PROXYSTUB PrxDllUnregisterServer(); #endif _Module.UnregisterServer(); return S_OK; }