Files
Client/Library/dxx8/samples/Multimedia/DirectShow/BaseClasses/dllsetup.cpp
LGram16 e067522598 Initial commit: ROW Client source code
Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 16:24:34 +09:00

652 lines
17 KiB
C++

//------------------------------------------------------------------------------
// File: DllSetup.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.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, LPTSTR 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;
wsprintf(achTemp, TEXT("CLSID\\%ls"), szCLSID);
LONG lreturn = RegCreateKey(HKEY_CLASSES_ROOT
, (LPCTSTR)achTemp
, &hkey);
if(ERROR_SUCCESS != lreturn) {
return AmHresultFromWin32(lreturn);
}
// set description string
//
wsprintf(achTemp, TEXT("%ls"), szDescription);
lreturn = RegSetValue(hkey
, (LPCTSTR)NULL
, REG_SZ
, achTemp
, sizeof(achTemp)/sizeof(achTemp[0]));
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;
wsprintf(achTemp, TEXT("%ls"), szServerType);
lreturn = RegCreateKey(hkey
, achTemp
, &hsubkey);
if(ERROR_SUCCESS != lreturn) {
RegCloseKey(hkey);
return AmHresultFromWin32(lreturn);
}
// set Server string
//
wsprintf(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);
}
wsprintf(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];
wsprintf(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
, sizeof(achFileName)/sizeof(TCHAR));
}
//
// 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
, sizeof(achFileName)/sizeof(TCHAR));
}
// 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;
}