mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
42bdeaf52c
Original repo is here: https://github.com/microsoft/Windows-classic-samples Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1577>
693 lines
18 KiB
C++
693 lines
18 KiB
C++
//------------------------------------------------------------------------------
|
|
// 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;
|
|
}
|