topical media & game development

talk show tell print

hush-src-multi-DLL-MultiVMR9.cpp / cpp



  //------------------------------------------------------------------------------
  // File: MultiVMR9.cpp
  //
  // Desc: DirectShow sample code - Implementation of DLL Exports.
  //
  // Copyright (c) Microsoft Corporation.  All rights reserved.
  //------------------------------------------------------------------------------
  
  include <stdafx.h>
  include <resource.h>
  include <MultiVMR9.h>
  
  include <stdio.h>
  include <tchar.h>
  
  include <Wizard.h>
  include <RenderEngine.h>
  include <UILayer.h>
  include <MixerControl.h>
  
  HINSTANCE g_hInst = NULL;
  
  class CCFMultiVMR9Wizard;
  class CCFMultiVMR9RenderEngine;
  class CCFMultiVMR9UILayer;
  class CCFMultiVMR9MixerControl;
  
  static CCFMultiVMR9Wizard       g_WizardFactory;
  static CCFMultiVMR9RenderEngine g_RenderEngineFactory;
  static CCFMultiVMR9UILayer      g_UILayerFactory;
  static CCFMultiVMR9MixerControl g_MixerControlFactory;
  
  // the com module's lock count + object count
  long g_CountWizard = 0; 
  long g_CountRenderEngine = 0; 
  long g_CountUILayer = 0; 
  long g_CountMixerControl = 0; 
  
  // forward declarations
  void MultiVMRRegisterClass( const CLSID& clsid, TCHAR *achClassName, BOOL bRegister);
  LONG recursiveDeleteKey(HKEY hKeyParent, TCHAR* achKeyChild);
  
  // DLL Entry Point
  BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  {
      if (DLL_PROCESS_ATTACH == dwReason )
      {
          g_hInst = hInstance;
      }
      return(TRUE);
  }
  
  //
  // stub entry points
  //
  
  STDAPI
  DllRegisterServer( void )
  {
      // now go register components; they are in HKEY_CLASSES_ROOT\CLSID{uuid}
      MultiVMRRegisterClass( CLSID_MultiVMR9Wizard,       TEXT("MultiVMR9 Wizard"), TRUE);
      MultiVMRRegisterClass( CLSID_MultiVMR9RenderEngine, TEXT("MultiVMR9 Render Engine"), TRUE);
      MultiVMRRegisterClass( CLSID_MultiVMR9UILayer,      TEXT("MultiVMR9 UI Layer"), TRUE);
      MultiVMRRegisterClass( CLSID_MultiVMR9MixerControl, TEXT("MultiVMR9 Mixer Control"), TRUE);
  
      return S_OK;
  }
  
  STDAPI
  DllUnregisterServer( void )
  {
      // now go register components; they are in HKEY_CLASSES_ROOT\CLSID{uuid}
      MultiVMRRegisterClass( CLSID_MultiVMR9Wizard,       TEXT("MultiVMR9 Wizard"), FALSE);
      MultiVMRRegisterClass( CLSID_MultiVMR9RenderEngine, TEXT("MultiVMR9 Render Engine"), FALSE);
      MultiVMRRegisterClass( CLSID_MultiVMR9UILayer,      TEXT("MultiVMR9 UI Layer"), FALSE);
      MultiVMRRegisterClass( CLSID_MultiVMR9MixerControl, TEXT("MultiVMR9 Mixer Control"), FALSE);
  
      return S_OK;
  }
  
  STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
  {
      if (CLSID_MultiVMR9Wizard == rclsid )
      {
          return g_WizardFactory.QueryInterface(riid, ppv);
      }
      else if( CLSID_MultiVMR9RenderEngine == rclsid )
      {
          return g_RenderEngineFactory.QueryInterface(riid, ppv);
      }
      else if( CLSID_MultiVMR9UILayer == rclsid )
      {
          return g_UILayerFactory.QueryInterface(riid, ppv);
      }
      else if( CLSID_MultiVMR9MixerControl == rclsid )
      {
          return g_MixerControlFactory.QueryInterface(riid, ppv);
      }
      else
      {
          *ppv = NULL;
          return CLASS_E_CLASSNOTAVAILABLE;
      }
  }
  
  STDAPI DllCanUnloadNow(void)
  {
      HRESULT hr = S_FALSE;
  
      if( 0 == g_CountWizard &&
          0 == g_CountRenderEngine &&
          0 == g_CountUILayer &&
          0 == g_CountMixerControl )
      {
          hr = S_OK;
      }
      return hr;
  }
  
  //
  // Add entry to the registry about CLSID object 
  //
  void MultiVMRRegisterClass( 
                             const CLSID& clsid, 
                             TCHAR *achClassName,
                             BOOL bRegister)
  {
      HRESULT hr = S_OK;
      TCHAR achModule[MAX_PATH];
      WCHAR wcModule[MAX_PATH];
      WCHAR wcKey[MAX_PATH];
      TCHAR achKey[MAX_PATH];
      TCHAR achThreadingModel[] = TEXT("Both");
      long err = 0;
      LPOLESTR wcCLSID = NULL;
      HKEY hKey = NULL;
      HKEY hSubKey = NULL;
  
      GetModuleFileName( g_hInst, achModule, sizeof(achModule) );
  
  ifdef UNICODE
      wcscpy( wcModule, achModule );
  else
      MultiByteToWideChar(CP_ACP, 0, achModule, -1, wcModule, MAX_PATH); 
  endif
  
      hr = StringFromCLSID(clsid, &wcCLSID);
  
      wcscpy( wcKey, L"CLSID\\");
      wcscat( wcKey, wcCLSID);
  
  ifdef UNICODE
      _tcscpy( achKey, wcKey);
  else
      WideCharToMultiByte(CP_ACP, 0, wcKey, -1, achKey, MAX_PATH, 0, 0);
  endif
  
      // first, delete wcKey if it exists
      err = recursiveDeleteKey( HKEY_CLASSES_ROOT, achKey);
  
      if( bRegister )
      {
          // create new key
          err = RegCreateKeyEx(   HKEY_CLASSES_ROOT,
                                  achKey, 
                                  NULL, 
                                  NULL, 
                                  REG_OPTION_NON_VOLATILE, 
                                  KEY_ALL_ACCESS, 
                                  NULL, 
                                  &hKey, 
                                  NULL);
          if (ERROR_SUCCESS == err)
          {
              err = RegSetValueEx( hKey, NULL, 0, REG_SZ,(BYTE *)achClassName, 
                                      sizeof(TCHAR) * ( _tcslen(achClassName)+1));
              err = RegCreateKeyEx(   hKey, 
                                      TEXT("InprocServer32"), 
                                      NULL,
                                      NULL,
                                      REG_OPTION_NON_VOLATILE, 
                                      KEY_ALL_ACCESS, 
                                      NULL, 
                                      &hSubKey, 
                                      NULL);
              if( ERROR_SUCCESS == err)
              {
                  err = RegSetValueEx( hSubKey, NULL, 0, REG_SZ,(BYTE *)achModule, 
                                      sizeof(TCHAR) * ( _tcslen(achModule)+1));
                  err = RegSetValueEx( hSubKey, TEXT("ThreadingModel"), 0, REG_SZ,(BYTE *)achThreadingModel, 
                                      sizeof(TCHAR) * ( _tcslen(achThreadingModel)+1));
                  RegCloseKey( hSubKey );
              }
              RegCloseKey( hKey );
          }
      }
      CoTaskMemFree(wcCLSID);
  }
  
  //
  // Delete a key and all of its descendents.
  //
  LONG recursiveDeleteKey(HKEY hKeyParent,     // Parent of key to delete
                          TCHAR* achKeyChild)  // Key to delete
  {
      // Open the child.
      HKEY hKeyChild;
      LONG lRes = RegOpenKeyEx(hKeyParent, achKeyChild, 0,
                                KEY_ALL_ACCESS, &hKeyChild);
      if (lRes != ERROR_SUCCESS)
      {
          return lRes;
      }
  
      // Enumerate all of the decendents of this child.
      FILETIME time;
      TCHAR achBuffer[256];
      DWORD dwSize = 256;
  
      while (RegEnumKeyEx(hKeyChild, 0, achBuffer, &dwSize, NULL,
             NULL, NULL, &time) == ERROR_SUCCESS)
      {
          // Delete the decendents of this child.
          lRes = recursiveDeleteKey(hKeyChild, achBuffer);
          if (lRes != ERROR_SUCCESS)
          {
              // Cleanup before exiting.
              RegCloseKey(hKeyChild);
              return lRes;
          }
          dwSize = 256;
      }
  
      // Close the child.
      RegCloseKey(hKeyChild);
  
      // Delete this child.
      return RegDeleteKey(hKeyParent, achKeyChild);
  }
  
  ifdef _DEBUG
      void DbgMsg( char* szMessage, ... )
      {
          char szFullMessage[MAX_PATH];
          char szFormatMessage[MAX_PATH];
  
          // format message
          va_list ap;
          va_start(ap, szMessage);
          _vsnprintf( szFormatMessage, MAX_PATH, szMessage, ap);
          va_end(ap);
          strncat( szFormatMessage, "\n", MAX_PATH);
          strcpy( szFullMessage, "~*~*~*~*~*~ ");
          strcat( szFullMessage, szFormatMessage );
          OutputDebugStringA( szFullMessage );
      }
  else
      void DbgMsg( char* szMessage, ... ){;}
  endif
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.