home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / directshow / baseclasses / dllsetup.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-02  |  17.7 KB  |  693 lines

  1. //------------------------------------------------------------------------------
  2. // File: DllSetup.cpp
  3. //
  4. // Desc: DirectShow base classes.
  5. //
  6. // Copyright (c) 1992 - 2000, Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9.  
  10. #include <streams.h>
  11.  
  12. //---------------------------------------------------------------------------
  13. // defines
  14.  
  15. #define MAX_KEY_LEN  260
  16.  
  17.  
  18. //---------------------------------------------------------------------------
  19. // externally defined functions/variable
  20.  
  21. extern int g_cTemplates;
  22. extern CFactoryTemplate g_Templates[];
  23.  
  24. //---------------------------------------------------------------------------
  25. //
  26. // EliminateSubKey
  27. //
  28. // Try to enumerate all keys under this one.
  29. // if we find anything, delete it completely.
  30. // Otherwise just delete it.
  31. //
  32. // note - this was pinched/duplicated from
  33. // Filgraph\Mapper.cpp - so should it be in
  34. // a lib somewhere?
  35. //
  36. //---------------------------------------------------------------------------
  37.  
  38. STDAPI
  39. EliminateSubKey( HKEY hkey, LPTSTR strSubKey )
  40. {
  41.   HKEY hk;
  42.   if (0 == lstrlen(strSubKey) ) {
  43.       // defensive approach
  44.       return E_FAIL;
  45.   }
  46.  
  47.   LONG lreturn = RegOpenKeyEx( hkey
  48.                              , strSubKey
  49.                              , 0
  50.                              , MAXIMUM_ALLOWED
  51.                              , &hk );
  52.  
  53.   ASSERT(    lreturn == ERROR_SUCCESS
  54.           || lreturn == ERROR_FILE_NOT_FOUND
  55.           || lreturn == ERROR_INVALID_HANDLE );
  56.  
  57.   if( ERROR_SUCCESS == lreturn )
  58.   {
  59.     // Keep on enumerating the first (zero-th)
  60.     // key and deleting that
  61.  
  62.     for( ; ; )
  63.     {
  64.       TCHAR Buffer[MAX_KEY_LEN];
  65.       DWORD dw = MAX_KEY_LEN;
  66.       FILETIME ft;
  67.  
  68.       lreturn = RegEnumKeyEx( hk
  69.                             , 0
  70.                             , Buffer
  71.                             , &dw
  72.                             , NULL
  73.                             , NULL
  74.                             , NULL
  75.                             , &ft);
  76.  
  77.       ASSERT(    lreturn == ERROR_SUCCESS
  78.               || lreturn == ERROR_NO_MORE_ITEMS );
  79.  
  80.       if( ERROR_SUCCESS == lreturn )
  81.       {
  82.         EliminateSubKey(hk, Buffer);
  83.       }
  84.       else
  85.       {
  86.         break;
  87.       }
  88.     }
  89.  
  90.     RegCloseKey(hk);
  91.     RegDeleteKey(hkey, strSubKey);
  92.   }
  93.  
  94.   return NOERROR;
  95. }
  96.  
  97.  
  98. //---------------------------------------------------------------------------
  99. //
  100. // AMovieSetupRegisterServer()
  101. //
  102. // registers specfied file "szFileName" as server for
  103. // CLSID "clsServer".  A description is also required.
  104. // The ThreadingModel and ServerType are optional, as
  105. // they default to InprocServer32 (i.e. dll) and Both.
  106. //
  107. //---------------------------------------------------------------------------
  108.  
  109. STDAPI
  110. AMovieSetupRegisterServer( CLSID   clsServer
  111.                          , LPCWSTR szDescription
  112.                          , LPCWSTR szFileName
  113.                          , LPCWSTR szThreadingModel = L"Both"
  114.                          , LPCWSTR szServerType     = L"InprocServer32" )
  115. {
  116.   // temp buffer
  117.   //
  118.   TCHAR achTemp[MAX_PATH];
  119.  
  120.   // convert CLSID uuid to string and write
  121.   // out subkey as string - CLSID\{}
  122.   //
  123.   OLECHAR szCLSID[CHARS_IN_GUID];
  124.   HRESULT hr = StringFromGUID2( clsServer
  125.                               , szCLSID
  126.                               , CHARS_IN_GUID );
  127.   ASSERT( SUCCEEDED(hr) );
  128.  
  129.   // create key
  130.   //
  131.   HKEY hkey;
  132.   wsprintf( achTemp, TEXT("CLSID\\%ls"), szCLSID );
  133.   LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT
  134.                              , (LPCTSTR)achTemp
  135.                              , &hkey              );
  136.   if( ERROR_SUCCESS != lreturn )
  137.   {
  138.     return AmHresultFromWin32(lreturn);
  139.   }
  140.  
  141.   // set description string
  142.   //
  143.  
  144.   wsprintf( achTemp, TEXT("%ls"), szDescription );
  145.   lreturn = RegSetValue( hkey
  146.                        , (LPCTSTR)NULL
  147.                        , REG_SZ
  148.                        , achTemp
  149.                        , sizeof(achTemp) );
  150.   if( ERROR_SUCCESS != lreturn )
  151.   {
  152.     RegCloseKey( hkey );
  153.     return AmHresultFromWin32(lreturn);
  154.   }
  155.  
  156.   // create CLSID\\{"CLSID"}\\"ServerType" key,
  157.   // using key to CLSID\\{"CLSID"} passed back by
  158.   // last call to RegCreateKey().
  159.   //
  160.   HKEY hsubkey;
  161.  
  162.   wsprintf( achTemp, TEXT("%ls"), szServerType );
  163.   lreturn = RegCreateKey( hkey
  164.                         , achTemp
  165.                         , &hsubkey     );
  166.   if( ERROR_SUCCESS != lreturn )
  167.   {
  168.     RegCloseKey( hkey );
  169.     return AmHresultFromWin32(lreturn);
  170.   }
  171.  
  172.   // set Server string
  173.   //
  174.   wsprintf( achTemp, TEXT("%ls"), szFileName );
  175.   lreturn = RegSetValue( hsubkey
  176.                        , (LPCTSTR)NULL
  177.                        , REG_SZ
  178.                        , (LPCTSTR)achTemp
  179.                        , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
  180.   if( ERROR_SUCCESS != lreturn )
  181.   {
  182.     RegCloseKey( hkey );
  183.     RegCloseKey( hsubkey );
  184.     return AmHresultFromWin32(lreturn);
  185.   }
  186.  
  187.   wsprintf( achTemp, TEXT("%ls"), szThreadingModel );
  188.   lreturn = RegSetValueEx( hsubkey
  189.                          , TEXT("ThreadingModel")
  190.                          , 0L
  191.                          , REG_SZ
  192.                          , (CONST BYTE *)achTemp
  193.                          , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
  194.  
  195.   // close hkeys
  196.   //
  197.   RegCloseKey( hkey );
  198.   RegCloseKey( hsubkey );
  199.  
  200.   // and return
  201.   //
  202.   return HRESULT_FROM_WIN32(lreturn);
  203.  
  204. }
  205.  
  206.  
  207. //---------------------------------------------------------------------------
  208. //
  209. // AMovieSetupUnregisterServer()
  210. //
  211. // default ActiveMovie dll setup function
  212. // - to use must be called from an exported
  213. //   function named DllRegisterServer()
  214. //
  215. //---------------------------------------------------------------------------
  216.  
  217. STDAPI
  218. AMovieSetupUnregisterServer( CLSID clsServer )
  219. {
  220.   // convert CLSID uuid to string and write
  221.   // out subkey CLSID\{}
  222.   //
  223.   OLECHAR szCLSID[CHARS_IN_GUID];
  224.   HRESULT hr = StringFromGUID2( clsServer
  225.                               , szCLSID
  226.                               , CHARS_IN_GUID );
  227.   ASSERT( SUCCEEDED(hr) );
  228.  
  229.   TCHAR achBuffer[MAX_KEY_LEN];
  230.   wsprintf( achBuffer, TEXT("CLSID\\%ls"), szCLSID );
  231.  
  232.   // delete subkey
  233.   //
  234.  
  235.   hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer );
  236.   ASSERT( SUCCEEDED(hr) );
  237.  
  238.   // return
  239.   //
  240.   return NOERROR;
  241. }
  242.  
  243.  
  244. //---------------------------------------------------------------------------
  245. //
  246. // AMovieSetupRegisterFilter through IFilterMapper2
  247. //
  248. //---------------------------------------------------------------------------
  249.  
  250. STDAPI
  251. AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
  252.                           , IFilterMapper2 *                 pIFM2
  253.                           , BOOL                             bRegister  )
  254. {
  255.   DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));
  256.  
  257.   // check we've got data
  258.   //
  259.   if( NULL == psetupdata ) return S_FALSE;
  260.  
  261.  
  262.   // unregister filter
  263.   // (as pins are subkeys of filter's CLSID key
  264.   // they do not need to be removed separately).
  265.   //
  266.   DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
  267.   HRESULT hr = pIFM2->UnregisterFilter(
  268.       0,                        // default category
  269.       0,                        // default instance name
  270.       *psetupdata->clsID );
  271.  
  272.  
  273.   if( bRegister )
  274.   {
  275.     REGFILTER2 rf2;
  276.     rf2.dwVersion = 1;
  277.     rf2.dwMerit = psetupdata->dwMerit;
  278.     rf2.cPins = psetupdata->nPins;
  279.     rf2.rgPins = psetupdata->lpPin;
  280.     
  281.     // register filter
  282.     //
  283.     DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
  284.     hr = pIFM2->RegisterFilter(*psetupdata->clsID
  285.                              , psetupdata->strName
  286.                              , 0 // moniker
  287.                              , 0 // category
  288.                              , NULL // instance
  289.                              , &rf2);
  290.   }
  291.  
  292.   // handle one acceptable "error" - that
  293.   // of filter not being registered!
  294.   // (couldn't find a suitable #define'd
  295.   // name for the error!)
  296.   //
  297.   if( 0x80070002 == hr)
  298.     return NOERROR;
  299.   else
  300.     return hr;
  301. }
  302.  
  303.  
  304. //---------------------------------------------------------------------------
  305. //
  306. // RegisterAllServers()
  307. //
  308. //---------------------------------------------------------------------------
  309.  
  310. STDAPI
  311. RegisterAllServers( LPCWSTR szFileName, BOOL bRegister )
  312. {
  313.   HRESULT hr = NOERROR;
  314.  
  315.   for( int i = 0; i < g_cTemplates; i++ )
  316.   {
  317.     // get i'th template
  318.     //
  319.     const CFactoryTemplate *pT = &g_Templates[i];
  320.  
  321.     DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"),
  322.            (LPCWSTR)pT->m_Name ));
  323.  
  324.     // register CLSID and InprocServer32
  325.     //
  326.     if( bRegister )
  327.     {
  328.       hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
  329.                                     , (LPCWSTR)pT->m_Name
  330.                                     , szFileName );
  331.     }
  332.     else
  333.     {
  334.       hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
  335.     }
  336.  
  337.     // check final error for this pass
  338.     // and break loop if we failed
  339.     //
  340.     if( FAILED(hr) )
  341.       break;
  342.   }
  343.  
  344.   return hr;
  345. }
  346.  
  347.  
  348. //---------------------------------------------------------------------------
  349. //
  350. // AMovieDllRegisterServer2()
  351. //
  352. // default ActiveMovie dll setup function
  353. // - to use must be called from an exported
  354. //   function named DllRegisterServer()
  355. //
  356. // this function is table driven using the
  357. // static members of the CFactoryTemplate
  358. // class defined in the dll.
  359. //
  360. // it registers the Dll as the InprocServer32
  361. // and then calls the IAMovieSetup.Register
  362. // method.
  363. //
  364. //---------------------------------------------------------------------------
  365.  
  366. STDAPI
  367. AMovieDllRegisterServer2( BOOL bRegister )
  368. {
  369.   HRESULT hr = NOERROR;
  370.  
  371.   DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()")));
  372.  
  373.   // get file name (where g_hInst is the
  374.   // instance handle of the filter dll)
  375.   //
  376.   WCHAR achFileName[MAX_PATH];
  377.  
  378.   // WIN95 doesn't support GetModuleFileNameW
  379.   //
  380.   {
  381.     char achTemp[MAX_PATH];
  382.  
  383.     DbgLog((LOG_TRACE, 2, TEXT("- get module file name")));
  384.  
  385.     // g_hInst handle is set in our dll entry point. Make sure
  386.     // DllEntryPoint in dllentry.cpp is called
  387.     ASSERT(g_hInst != 0);
  388.  
  389.     if( 0 == GetModuleFileNameA( g_hInst
  390.                               , achTemp
  391.                               , sizeof(achTemp) ) )
  392.     {
  393.       // we've failed!
  394.       DWORD dwerr = GetLastError();
  395.       return AmHresultFromWin32(dwerr);
  396.     }
  397.  
  398.     MultiByteToWideChar( CP_ACP
  399.                        , 0L
  400.                        , achTemp
  401.                        , lstrlenA(achTemp) + 1
  402.                        , achFileName
  403.                        , sizeof(achFileName) );
  404.   }
  405.  
  406.   //
  407.   // first registering, register all OLE servers
  408.   //
  409.   if( bRegister )
  410.   {
  411.     DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
  412.     hr = RegisterAllServers( achFileName, TRUE );
  413.   }
  414.  
  415.   //
  416.   // next, register/unregister all filters
  417.   //
  418.  
  419.   if( SUCCEEDED(hr) )
  420.   {
  421.     // init is ref counted so call just in case
  422.     // we're being called cold.
  423.     //
  424.     DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize")));
  425.     hr = CoInitialize( (LPVOID)NULL );
  426.     ASSERT( SUCCEEDED(hr) );
  427.  
  428.     // get hold of IFilterMapper2
  429.     //
  430.     DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2")));
  431.     IFilterMapper2 *pIFM2 = 0;
  432.     IFilterMapper *pIFM = 0;
  433.     hr = CoCreateInstance( CLSID_FilterMapper2
  434.                          , NULL
  435.                          , CLSCTX_INPROC_SERVER
  436.                          , IID_IFilterMapper2
  437.                          , (void **)&pIFM2       );
  438.     if(FAILED(hr))
  439.     {
  440.         DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead")));
  441.  
  442.         hr = CoCreateInstance(
  443.             CLSID_FilterMapper,
  444.             NULL,
  445.             CLSCTX_INPROC_SERVER,
  446.             IID_IFilterMapper,
  447.             (void **)&pIFM);
  448.     }
  449.     if( SUCCEEDED(hr) )
  450.     {
  451.       // scan through array of CFactoryTemplates
  452.       // registering servers and filters.
  453.       //
  454.       DbgLog((LOG_TRACE, 2, TEXT("- register Filters")));
  455.       for( int i = 0; i < g_cTemplates; i++ )
  456.       {
  457.         // get i'th template
  458.         //
  459.         const CFactoryTemplate *pT = &g_Templates[i];
  460.  
  461.         if( NULL != pT->m_pAMovieSetup_Filter )
  462.         {
  463.           DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name ));
  464.  
  465.           if(pIFM2)
  466.           {
  467.               hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister );
  468.           }
  469.           else
  470.           {
  471.               hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister );
  472.           }
  473.         }
  474.  
  475.         // check final error for this pass
  476.         // and break loop if we failed
  477.         //
  478.         if( FAILED(hr) )
  479.           break;
  480.       }
  481.  
  482.       // release interface
  483.       //
  484.       if(pIFM2)
  485.           pIFM2->Release();
  486.       else
  487.           pIFM->Release();
  488.  
  489.     }
  490.  
  491.     // and clear up
  492.     //
  493.     CoFreeUnusedLibraries();
  494.     CoUninitialize();
  495.   }
  496.  
  497.   //
  498.   // if unregistering, unregister all OLE servers
  499.   //
  500.   if( SUCCEEDED(hr) && !bRegister )
  501.   {
  502.     DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
  503.     hr = RegisterAllServers( achFileName, FALSE );
  504.   }
  505.  
  506.   DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr));
  507.   return hr;
  508. }
  509.  
  510.  
  511. //---------------------------------------------------------------------------
  512. //
  513. // AMovieDllRegisterServer()
  514. //
  515. // default ActiveMovie dll setup function
  516. // - to use must be called from an exported
  517. //   function named DllRegisterServer()
  518. //
  519. // this function is table driven using the
  520. // static members of the CFactoryTemplate
  521. // class defined in the dll.
  522. //
  523. // it registers the Dll as the InprocServer32
  524. // and then calls the IAMovieSetup.Register
  525. // method.
  526. //
  527. //---------------------------------------------------------------------------
  528.  
  529.  
  530. STDAPI
  531. AMovieDllRegisterServer( void )
  532. {
  533.   HRESULT hr = NOERROR;
  534.  
  535.   // get file name (where g_hInst is the
  536.   // instance handle of the filter dll)
  537.   //
  538.   WCHAR achFileName[MAX_PATH];
  539.  
  540.   {
  541.     // WIN95 doesn't support GetModuleFileNameW
  542.     //
  543.     char achTemp[MAX_PATH];
  544.  
  545.     if( 0 == GetModuleFileNameA( g_hInst
  546.                               , achTemp
  547.                               , sizeof(achTemp) ) )
  548.     {
  549.       // we've failed!
  550.       DWORD dwerr = GetLastError();
  551.       return AmHresultFromWin32(dwerr);
  552.     }
  553.  
  554.     MultiByteToWideChar( CP_ACP
  555.                        , 0L
  556.                        , achTemp
  557.                        , lstrlenA(achTemp) + 1
  558.                        , achFileName
  559.                        , sizeof(achFileName) );
  560.   }
  561.  
  562.   // scan through array of CFactoryTemplates
  563.   // registering servers and filters.
  564.   //
  565.   for( int i = 0; i < g_cTemplates; i++ )
  566.   {
  567.     // get i'th template
  568.     //
  569.     const CFactoryTemplate *pT = &g_Templates[i];
  570.  
  571.     // register CLSID and InprocServer32
  572.     //
  573.     hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
  574.                                   , (LPCWSTR)pT->m_Name
  575.                                   , achFileName );
  576.  
  577.     // instantiate all servers and get hold of
  578.     // IAMovieSetup, if implemented, and call
  579.     // IAMovieSetup.Register() method
  580.     //
  581.     if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) )
  582.     {
  583.       // instantiate object
  584.       //
  585.       PAMOVIESETUP psetup;
  586.       hr = CoCreateInstance( *(pT->m_ClsID)
  587.                            , 0
  588.                            , CLSCTX_INPROC_SERVER
  589.                            , IID_IAMovieSetup
  590.                            , reinterpret_cast<void**>(&psetup) );
  591.       if( SUCCEEDED(hr) )
  592.       {
  593.         hr = psetup->Unregister();
  594.         if( SUCCEEDED(hr) )
  595.           hr = psetup->Register();
  596.         psetup->Release();
  597.       }
  598.       else
  599.       {
  600.         if(    (E_NOINTERFACE      == hr )
  601.             || (VFW_E_NEED_OWNER == hr ) )
  602.           hr = NOERROR;
  603.       }
  604.     }
  605.  
  606.     // check final error for this pass
  607.     // and break loop if we failed
  608.     //
  609.     if( FAILED(hr) )
  610.       break;
  611.  
  612.   } // end-for
  613.  
  614.   return hr;
  615. }
  616.  
  617.  
  618. //---------------------------------------------------------------------------
  619. //
  620. // AMovieDllUnregisterServer()
  621. //
  622. // default ActiveMovie dll uninstall function
  623. // - to use must be called from an exported
  624. //   function named DllRegisterServer()
  625. //
  626. // this function is table driven using the
  627. // static members of the CFactoryTemplate
  628. // class defined in the dll.
  629. //
  630. // it calls the IAMovieSetup.Unregister
  631. // method and then unregisters the Dll
  632. // as the InprocServer32
  633. //
  634. //---------------------------------------------------------------------------
  635.  
  636. STDAPI
  637. AMovieDllUnregisterServer()
  638. {
  639.   // initialize return code
  640.   //
  641.   HRESULT hr = NOERROR;
  642.  
  643.   // scan through CFactory template and unregister
  644.   // all OLE servers and filters.
  645.   //
  646.   for( int i = g_cTemplates; i--; )
  647.   {
  648.     // get i'th template
  649.     //
  650.     const CFactoryTemplate *pT = &g_Templates[i];
  651.  
  652.     // check method exists
  653.     //
  654.     if( NULL != pT->m_lpfnNew )
  655.     {
  656.       // instantiate object
  657.       //
  658.       PAMOVIESETUP psetup;
  659.       hr = CoCreateInstance( *(pT->m_ClsID)
  660.                            , 0
  661.                            , CLSCTX_INPROC_SERVER
  662.                            , IID_IAMovieSetup
  663.                            , reinterpret_cast<void**>(&psetup) );
  664.       if( SUCCEEDED(hr) )
  665.       {
  666.         hr = psetup->Unregister();
  667.         psetup->Release();
  668.       }
  669.       else
  670.       {
  671.         if(    (E_NOINTERFACE      == hr )
  672.             || (VFW_E_NEED_OWNER == hr ) )
  673.            hr = NOERROR;
  674.       }
  675.     }
  676.  
  677.     // unregister CLSID and InprocServer32
  678.     //
  679.     if( SUCCEEDED(hr) )
  680.     {
  681.       hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
  682.     }
  683.  
  684.     // check final error for this pass
  685.     // and break loop if we failed
  686.     //
  687.     if( FAILED(hr) )
  688.       break;
  689.   }
  690.  
  691.   return hr;
  692. }
  693.