dllsetup.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:19k
源码类别:

P2P编程

开发平台:

Visual C++

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