summaryrefslogtreecommitdiff
path: root/third_party/BaseClasses/dllsetup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/BaseClasses/dllsetup.cpp')
-rw-r--r--third_party/BaseClasses/dllsetup.cpp693
1 files changed, 693 insertions, 0 deletions
diff --git a/third_party/BaseClasses/dllsetup.cpp b/third_party/BaseClasses/dllsetup.cpp
new file mode 100644
index 00000000..ede9c3fd
--- /dev/null
+++ b/third_party/BaseClasses/dllsetup.cpp
@@ -0,0 +1,693 @@
+//------------------------------------------------------------------------------
+// File: DllSetup.cpp
+//
+// Desc: DirectShow base classes.
+//
+// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------------------------
+
+
+#include <streams.h>
+#include <strsafe.h>
+
+//---------------------------------------------------------------------------
+// defines
+
+#define MAX_KEY_LEN 260
+
+
+//---------------------------------------------------------------------------
+// externally defined functions/variable
+
+extern int g_cTemplates;
+extern CFactoryTemplate g_Templates[];
+
+//---------------------------------------------------------------------------
+//
+// EliminateSubKey
+//
+// Try to enumerate all keys under this one.
+// if we find anything, delete it completely.
+// Otherwise just delete it.
+//
+// note - this was pinched/duplicated from
+// Filgraph\Mapper.cpp - so should it be in
+// a lib somewhere?
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+EliminateSubKey( HKEY hkey, LPCTSTR strSubKey )
+{
+ HKEY hk;
+ if (0 == lstrlen(strSubKey) ) {
+ // defensive approach
+ return E_FAIL;
+ }
+
+ LONG lreturn = RegOpenKeyEx( hkey
+ , strSubKey
+ , 0
+ , MAXIMUM_ALLOWED
+ , &hk );
+
+ ASSERT( lreturn == ERROR_SUCCESS
+ || lreturn == ERROR_FILE_NOT_FOUND
+ || lreturn == ERROR_INVALID_HANDLE );
+
+ if( ERROR_SUCCESS == lreturn )
+ {
+ // Keep on enumerating the first (zero-th)
+ // key and deleting that
+
+ for( ; ; )
+ {
+ TCHAR Buffer[MAX_KEY_LEN];
+ DWORD dw = MAX_KEY_LEN;
+ FILETIME ft;
+
+ lreturn = RegEnumKeyEx( hk
+ , 0
+ , Buffer
+ , &dw
+ , NULL
+ , NULL
+ , NULL
+ , &ft);
+
+ ASSERT( lreturn == ERROR_SUCCESS
+ || lreturn == ERROR_NO_MORE_ITEMS );
+
+ if( ERROR_SUCCESS == lreturn )
+ {
+ EliminateSubKey(hk, Buffer);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ RegCloseKey(hk);
+ RegDeleteKey(hkey, strSubKey);
+ }
+
+ return NOERROR;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieSetupRegisterServer()
+//
+// registers specfied file "szFileName" as server for
+// CLSID "clsServer". A description is also required.
+// The ThreadingModel and ServerType are optional, as
+// they default to InprocServer32 (i.e. dll) and Both.
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+AMovieSetupRegisterServer( CLSID clsServer
+ , LPCWSTR szDescription
+ , LPCWSTR szFileName
+ , LPCWSTR szThreadingModel = L"Both"
+ , LPCWSTR szServerType = L"InprocServer32" )
+{
+ // temp buffer
+ //
+ TCHAR achTemp[MAX_PATH];
+
+ // convert CLSID uuid to string and write
+ // out subkey as string - CLSID\{}
+ //
+ OLECHAR szCLSID[CHARS_IN_GUID];
+ HRESULT hr = StringFromGUID2( clsServer
+ , szCLSID
+ , CHARS_IN_GUID );
+ ASSERT( SUCCEEDED(hr) );
+
+ // create key
+ //
+ HKEY hkey;
+ (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("CLSID\\%ls"), szCLSID );
+ LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT
+ , (LPCTSTR)achTemp
+ , &hkey );
+ if( ERROR_SUCCESS != lreturn )
+ {
+ return AmHresultFromWin32(lreturn);
+ }
+
+ // set description string
+ //
+
+ (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szDescription );
+ lreturn = RegSetValue( hkey
+ , (LPCTSTR)NULL
+ , REG_SZ
+ , achTemp
+ , sizeof(achTemp) );
+ if( ERROR_SUCCESS != lreturn )
+ {
+ RegCloseKey( hkey );
+ return AmHresultFromWin32(lreturn);
+ }
+
+ // create CLSID\\{"CLSID"}\\"ServerType" key,
+ // using key to CLSID\\{"CLSID"} passed back by
+ // last call to RegCreateKey().
+ //
+ HKEY hsubkey;
+
+ (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szServerType );
+ lreturn = RegCreateKey( hkey
+ , achTemp
+ , &hsubkey );
+ if( ERROR_SUCCESS != lreturn )
+ {
+ RegCloseKey( hkey );
+ return AmHresultFromWin32(lreturn);
+ }
+
+ // set Server string
+ //
+ (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szFileName );
+ lreturn = RegSetValue( hsubkey
+ , (LPCTSTR)NULL
+ , REG_SZ
+ , (LPCTSTR)achTemp
+ , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
+ if( ERROR_SUCCESS != lreturn )
+ {
+ RegCloseKey( hkey );
+ RegCloseKey( hsubkey );
+ return AmHresultFromWin32(lreturn);
+ }
+
+ (void)StringCchPrintf( achTemp, NUMELMS(achTemp), TEXT("%ls"), szThreadingModel );
+ lreturn = RegSetValueEx( hsubkey
+ , TEXT("ThreadingModel")
+ , 0L
+ , REG_SZ
+ , (CONST BYTE *)achTemp
+ , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
+
+ // close hkeys
+ //
+ RegCloseKey( hkey );
+ RegCloseKey( hsubkey );
+
+ // and return
+ //
+ return HRESULT_FROM_WIN32(lreturn);
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieSetupUnregisterServer()
+//
+// default ActiveMovie dll setup function
+// - to use must be called from an exported
+// function named DllRegisterServer()
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+AMovieSetupUnregisterServer( CLSID clsServer )
+{
+ // convert CLSID uuid to string and write
+ // out subkey CLSID\{}
+ //
+ OLECHAR szCLSID[CHARS_IN_GUID];
+ HRESULT hr = StringFromGUID2( clsServer
+ , szCLSID
+ , CHARS_IN_GUID );
+ ASSERT( SUCCEEDED(hr) );
+
+ TCHAR achBuffer[MAX_KEY_LEN];
+ (void)StringCchPrintf( achBuffer, NUMELMS(achBuffer), TEXT("CLSID\\%ls"), szCLSID );
+
+ // delete subkey
+ //
+
+ hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer );
+ ASSERT( SUCCEEDED(hr) );
+
+ // return
+ //
+ return NOERROR;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieSetupRegisterFilter through IFilterMapper2
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
+ , IFilterMapper2 * pIFM2
+ , BOOL bRegister )
+{
+ DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));
+
+ // check we've got data
+ //
+ if( NULL == psetupdata ) return S_FALSE;
+
+
+ // unregister filter
+ // (as pins are subkeys of filter's CLSID key
+ // they do not need to be removed separately).
+ //
+ DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
+ HRESULT hr = pIFM2->UnregisterFilter(
+ 0, // default category
+ 0, // default instance name
+ *psetupdata->clsID );
+
+
+ if( bRegister )
+ {
+ REGFILTER2 rf2;
+ rf2.dwVersion = 1;
+ rf2.dwMerit = psetupdata->dwMerit;
+ rf2.cPins = psetupdata->nPins;
+ rf2.rgPins = psetupdata->lpPin;
+
+ // register filter
+ //
+ DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
+ hr = pIFM2->RegisterFilter(*psetupdata->clsID
+ , psetupdata->strName
+ , 0 // moniker
+ , 0 // category
+ , NULL // instance
+ , &rf2);
+ }
+
+ // handle one acceptable "error" - that
+ // of filter not being registered!
+ // (couldn't find a suitable #define'd
+ // name for the error!)
+ //
+ if( 0x80070002 == hr)
+ return NOERROR;
+ else
+ return hr;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// RegisterAllServers()
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+RegisterAllServers( LPCWSTR szFileName, BOOL bRegister )
+{
+ HRESULT hr = NOERROR;
+
+ for( int i = 0; i < g_cTemplates; i++ )
+ {
+ // get i'th template
+ //
+ const CFactoryTemplate *pT = &g_Templates[i];
+
+ DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"),
+ (LPCWSTR)pT->m_Name ));
+
+ // register CLSID and InprocServer32
+ //
+ if( bRegister )
+ {
+ hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
+ , (LPCWSTR)pT->m_Name
+ , szFileName );
+ }
+ else
+ {
+ hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
+ }
+
+ // check final error for this pass
+ // and break loop if we failed
+ //
+ if( FAILED(hr) )
+ break;
+ }
+
+ return hr;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieDllRegisterServer2()
+//
+// default ActiveMovie dll setup function
+// - to use must be called from an exported
+// function named DllRegisterServer()
+//
+// this function is table driven using the
+// static members of the CFactoryTemplate
+// class defined in the dll.
+//
+// it registers the Dll as the InprocServer32
+// and then calls the IAMovieSetup.Register
+// method.
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+AMovieDllRegisterServer2( BOOL bRegister )
+{
+ HRESULT hr = NOERROR;
+
+ DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()")));
+
+ // get file name (where g_hInst is the
+ // instance handle of the filter dll)
+ //
+ WCHAR achFileName[MAX_PATH];
+
+ // WIN95 doesn't support GetModuleFileNameW
+ //
+ {
+ char achTemp[MAX_PATH];
+
+ DbgLog((LOG_TRACE, 2, TEXT("- get module file name")));
+
+ // g_hInst handle is set in our dll entry point. Make sure
+ // DllEntryPoint in dllentry.cpp is called
+ ASSERT(g_hInst != 0);
+
+ if( 0 == GetModuleFileNameA( g_hInst
+ , achTemp
+ , sizeof(achTemp) ) )
+ {
+ // we've failed!
+ DWORD dwerr = GetLastError();
+ return AmHresultFromWin32(dwerr);
+ }
+
+ MultiByteToWideChar( CP_ACP
+ , 0L
+ , achTemp
+ , lstrlenA(achTemp) + 1
+ , achFileName
+ , NUMELMS(achFileName) );
+ }
+
+ //
+ // first registering, register all OLE servers
+ //
+ if( bRegister )
+ {
+ DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
+ hr = RegisterAllServers( achFileName, TRUE );
+ }
+
+ //
+ // next, register/unregister all filters
+ //
+
+ if( SUCCEEDED(hr) )
+ {
+ // init is ref counted so call just in case
+ // we're being called cold.
+ //
+ DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize")));
+ hr = CoInitialize( (LPVOID)NULL );
+ ASSERT( SUCCEEDED(hr) );
+
+ // get hold of IFilterMapper2
+ //
+ DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2")));
+ IFilterMapper2 *pIFM2 = 0;
+ IFilterMapper *pIFM = 0;
+ hr = CoCreateInstance( CLSID_FilterMapper2
+ , NULL
+ , CLSCTX_INPROC_SERVER
+ , IID_IFilterMapper2
+ , (void **)&pIFM2 );
+ if(FAILED(hr))
+ {
+ DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead")));
+
+ hr = CoCreateInstance(
+ CLSID_FilterMapper,
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ IID_IFilterMapper,
+ (void **)&pIFM);
+ }
+ if( SUCCEEDED(hr) )
+ {
+ // scan through array of CFactoryTemplates
+ // registering servers and filters.
+ //
+ DbgLog((LOG_TRACE, 2, TEXT("- register Filters")));
+ for( int i = 0; i < g_cTemplates; i++ )
+ {
+ // get i'th template
+ //
+ const CFactoryTemplate *pT = &g_Templates[i];
+
+ if( NULL != pT->m_pAMovieSetup_Filter )
+ {
+ DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name ));
+
+ if(pIFM2)
+ {
+ hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister );
+ }
+ else
+ {
+ hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister );
+ }
+ }
+
+ // check final error for this pass
+ // and break loop if we failed
+ //
+ if( FAILED(hr) )
+ break;
+ }
+
+ // release interface
+ //
+ if(pIFM2)
+ pIFM2->Release();
+ else
+ pIFM->Release();
+
+ }
+
+ // and clear up
+ //
+ CoFreeUnusedLibraries();
+ CoUninitialize();
+ }
+
+ //
+ // if unregistering, unregister all OLE servers
+ //
+ if( SUCCEEDED(hr) && !bRegister )
+ {
+ DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
+ hr = RegisterAllServers( achFileName, FALSE );
+ }
+
+ DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr));
+ return hr;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieDllRegisterServer()
+//
+// default ActiveMovie dll setup function
+// - to use must be called from an exported
+// function named DllRegisterServer()
+//
+// this function is table driven using the
+// static members of the CFactoryTemplate
+// class defined in the dll.
+//
+// it registers the Dll as the InprocServer32
+// and then calls the IAMovieSetup.Register
+// method.
+//
+//---------------------------------------------------------------------------
+
+
+STDAPI
+AMovieDllRegisterServer( void )
+{
+ HRESULT hr = NOERROR;
+
+ // get file name (where g_hInst is the
+ // instance handle of the filter dll)
+ //
+ WCHAR achFileName[MAX_PATH];
+
+ {
+ // WIN95 doesn't support GetModuleFileNameW
+ //
+ char achTemp[MAX_PATH];
+
+ if( 0 == GetModuleFileNameA( g_hInst
+ , achTemp
+ , sizeof(achTemp) ) )
+ {
+ // we've failed!
+ DWORD dwerr = GetLastError();
+ return AmHresultFromWin32(dwerr);
+ }
+
+ MultiByteToWideChar( CP_ACP
+ , 0L
+ , achTemp
+ , lstrlenA(achTemp) + 1
+ , achFileName
+ , NUMELMS(achFileName) );
+ }
+
+ // scan through array of CFactoryTemplates
+ // registering servers and filters.
+ //
+ for( int i = 0; i < g_cTemplates; i++ )
+ {
+ // get i'th template
+ //
+ const CFactoryTemplate *pT = &g_Templates[i];
+
+ // register CLSID and InprocServer32
+ //
+ hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
+ , (LPCWSTR)pT->m_Name
+ , achFileName );
+
+ // instantiate all servers and get hold of
+ // IAMovieSetup, if implemented, and call
+ // IAMovieSetup.Register() method
+ //
+ if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) )
+ {
+ // instantiate object
+ //
+ PAMOVIESETUP psetup;
+ hr = CoCreateInstance( *(pT->m_ClsID)
+ , 0
+ , CLSCTX_INPROC_SERVER
+ , IID_IAMovieSetup
+ , reinterpret_cast<void**>(&psetup) );
+ if( SUCCEEDED(hr) )
+ {
+ hr = psetup->Unregister();
+ if( SUCCEEDED(hr) )
+ hr = psetup->Register();
+ psetup->Release();
+ }
+ else
+ {
+ if( (E_NOINTERFACE == hr )
+ || (VFW_E_NEED_OWNER == hr ) )
+ hr = NOERROR;
+ }
+ }
+
+ // check final error for this pass
+ // and break loop if we failed
+ //
+ if( FAILED(hr) )
+ break;
+
+ } // end-for
+
+ return hr;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// AMovieDllUnregisterServer()
+//
+// default ActiveMovie dll uninstall function
+// - to use must be called from an exported
+// function named DllRegisterServer()
+//
+// this function is table driven using the
+// static members of the CFactoryTemplate
+// class defined in the dll.
+//
+// it calls the IAMovieSetup.Unregister
+// method and then unregisters the Dll
+// as the InprocServer32
+//
+//---------------------------------------------------------------------------
+
+STDAPI
+AMovieDllUnregisterServer()
+{
+ // initialize return code
+ //
+ HRESULT hr = NOERROR;
+
+ // scan through CFactory template and unregister
+ // all OLE servers and filters.
+ //
+ for( int i = g_cTemplates; i--; )
+ {
+ // get i'th template
+ //
+ const CFactoryTemplate *pT = &g_Templates[i];
+
+ // check method exists
+ //
+ if( NULL != pT->m_lpfnNew )
+ {
+ // instantiate object
+ //
+ PAMOVIESETUP psetup;
+ hr = CoCreateInstance( *(pT->m_ClsID)
+ , 0
+ , CLSCTX_INPROC_SERVER
+ , IID_IAMovieSetup
+ , reinterpret_cast<void**>(&psetup) );
+ if( SUCCEEDED(hr) )
+ {
+ hr = psetup->Unregister();
+ psetup->Release();
+ }
+ else
+ {
+ if( (E_NOINTERFACE == hr )
+ || (VFW_E_NEED_OWNER == hr ) )
+ hr = NOERROR;
+ }
+ }
+
+ // unregister CLSID and InprocServer32
+ //
+ if( SUCCEEDED(hr) )
+ {
+ hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
+ }
+
+ // check final error for this pass
+ // and break loop if we failed
+ //
+ if( FAILED(hr) )
+ break;
+ }
+
+ return hr;
+}