forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			694 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			694 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; | ||
|  | } |