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