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;
 | 
						|
}
 |