// DatService.cpp : Implementation of cDatService #include "stdafx.h" #include "DecalDat.h" #include "DatService.h" #include "DatLibrary.h" #include ///////////////////////////////////////////////////////////////////////////// // cDatService HANDLE WINAPI CreateFileF( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { dwShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE; return cDatService::g_fn_CreateFile( lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile ); } static cHookDescriptor _hooks[] = { { eByName, _T( "kernel32.dll" ), _T( "CreateFileA" ), 0, reinterpret_cast< DWORD >( CreateFileF ), 0 }, }; cDatService::cFileFilter *cDatService::getFilter( LPTSTR szFilter, int nLength ) { std::string strFilter( szFilter, nLength ); for( cFileFilterList::iterator i = m_filters.begin(); i != m_filters.end(); ++ i ) { if( strFilter == i->m_strName ) return &(*(i)); } return NULL; } HRESULT cDatService::createFilter( cDatService::cFileFilter *pFilter, REFIID iid, LPVOID *ppvItf ) { static _bstr_t _strFilter( _T( "FileFilters" ) ); CComPtr< IDecalEnum > pEnumFilter; if( m_pDecal->get_Configuration( _strFilter, pFilter->m_clsid, &pEnumFilter ) != S_OK ) return E_FAIL; return pEnumFilter->CreateInstance( iid, ppvItf ); } HRESULT cDatService::onInitialize() { USES_CONVERSION; static _bstr_t _strPortal( _T( "%ac%\\portal.dat" ) ), _strCell( _T( "%ac%\\cell.dat" ) ); if( g_p == NULL ) { hookFunctions( _hooks, 1, true ); g_fn_CreateFile = reinterpret_cast< fn_CreateFile >( _hooks[ 0 ].m_pOldFunction ); g_p = this; } CComObject< cDatLibrary > *pComCell, *pComPortal; CComObject< cDatLibrary >::CreateInstance( &pComCell ); CComObject< cDatLibrary >::CreateInstance( &pComPortal ); pComCell->AddRef(); pComPortal->AddRef(); m_pCell = pComCell; m_pPortal = pComPortal; m_pCell->load( this, _strCell, eCell, 256 ); m_pPortal->load( this, _strPortal, ePortal, 1024 ); // Load the list of filters static _bstr_t _strFilter( _T( "FileFilters" ) ), _strPrefix( _T( "Prefix" ) ), _strCache( _T( "Cache" ) ); CComPtr< IDecalEnum > pEnum; m_pDecal->get_Configuration( _strFilter, GUID_NULL, &pEnum ); while( pEnum->Next() == S_OK ) { CComVariant vPrefix, vCache; cFileFilter; cFileFilter ff; pEnum->get_ComClass( &ff.m_clsid ); HRESULT hRes = pEnum->get_Property( _strPrefix, &vPrefix ); if( !SUCCEEDED( hRes ) || vPrefix.vt != VT_BSTR ) { _ASSERT( FALSE ); continue; } hRes = pEnum->get_Property( _strCache, &vCache ); if( !SUCCEEDED( hRes ) || vCache.vt != VT_I4 ) { _ASSERT( FALSE ); continue; } ff.m_bCache = !!vCache.lVal; LPTSTR szPrefix = OLE2T( vPrefix.bstrVal ); ::_tcslwr( szPrefix ); ff.m_strName = szPrefix; m_filters.push_back( ff ); } return S_OK; } void cDatService::onTerminate() { m_cache.clear(); m_filters.clear(); if( g_p == this ) { hookFunctions( _hooks, 1, false ); g_p = NULL; } m_pCell->Release(); m_pPortal->Release(); m_pCell = NULL; m_pPortal = NULL; } cDatService *cDatService::g_p = NULL; cDatService::fn_CreateFile cDatService::g_fn_CreateFile = NULL; STDMETHODIMP cDatService::Lookup( BSTR strName, IUnknown **ppItf ) { static _bstr_t _strPortal( _T( "portal" ) ), _strCell( _T( "cell" ) ); if( ::VarBstrCmp( strName, _strPortal, 0, NORM_IGNORECASE ) == VARCMP_EQ ) return m_pPortal->QueryInterface( IID_IUnknown, reinterpret_cast< void ** >( ppItf ) ); if( ::VarBstrCmp( strName, _strCell, 0, NORM_IGNORECASE ) == VARCMP_EQ ) return m_pCell->QueryInterface( IID_IUnknown, reinterpret_cast< void ** >( ppItf ) ); // None of the above return E_INVALIDARG; }