513 lines
12 KiB
C++
513 lines
12 KiB
C++
/*++
|
|
|
|
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 <initguid.h>
|
|
#include <uuids.h>
|
|
|
|
#include <vfwmsgs.h>
|
|
|
|
#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 <statreg.h>
|
|
#include <statreg.cpp>
|
|
#endif
|
|
|
|
#include <atlimpl.cpp>
|
|
|
|
#ifdef _MERGE_PROXYSTUB
|
|
extern "C" HINSTANCE hProxyDll;
|
|
#endif
|
|
|
|
#ifdef DEBUG_HEAPS
|
|
// ZoltanS: for heap debugging
|
|
#include <crtdbg.h>
|
|
#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;
|
|
}
|
|
|
|
|