home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / BaseClasses / dllsetup.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  17.6 KB  |  652 lines

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