// Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // File: CCodeFt.cxx // Contents: // Classes: // Functions: // History: 04-29-97 DanpoZ (Danpo Zhang) Created #include PerfDbgTag(tagDft, "Pluggable MF", "Log CDataFt", DEB_PROT) DbgTag(tagDftErr, "Pluggable MF", "Log CDataFtErrors", DEB_PROT|DEB_ERROR) #define SZDFILTERROOT "PROTOCOLS\\Filter\\Data Filter\\" // Method: CStdZFilter::QueryInterface // Synopsis: // Arguments: // Returns: // History: 06-26-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CStdZFilter::QueryInterface(REFIID riid, void **ppvObj) { PerfDbgLog(tagDft, this, "+CStdFilter::QueryInterface"); VDATEPTROUT(ppvObj, void*); VDATETHIS(this); HRESULT hr = NOERROR; if( riid == IID_IUnknown || riid == IID_IDataFilter ) { *ppvObj = this; AddRef(); } else hr = E_NOINTERFACE; PerfDbgLog1( tagDft, this, "-CStdZFilter::QueryInterface(hr:%1x)", hr); return hr; } // Method: CStdZFilter::AddRef // Synopsis: // Arguments: // Returns: // History: 06-26-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP_(ULONG) CStdZFilter::AddRef() { PerfDbgLog(tagDft, this, "+CStdZFilter::AddRef"); LONG lRet = ++_CRefs; DllAddRef(); PerfDbgLog1(tagDft, this, "-CStdZFilter::AddRef(cRef:%1d)", lRet); return lRet; } // Method: CStdZFilter::Release // Synopsis: // Arguments: // Returns: // History: 06-26-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP_(ULONG) CStdZFilter::Release() { PerfDbgLog(tagDft, this, "+CStdZFilter::Release"); LONG lRet = --_CRefs; if(!lRet) delete this; DllRelease(); PerfDbgLog1(tagDft, this, "-CStdZFilter::Release(cRef:%1d)", lRet); return lRet; } // Method: CStdZFilter::DoEncode // Synopsis: // Arguments: [dwFlags] - flags // [lInBufferSize] - Input Buffer Size // [pbInBuffer] - Input Buffer // [lOutBufferSize] - Output Buffer Size // [pbOutBuffer] - Output Buffer // [lInBytesAvailable] - Data available in Input Buffer // [plInBytesRead] - Total data read from input buffer // [plOutBytesWritten] - Total data written to output buffer // [dwReserved] - currently not used // Returns: NOERROR or E_FAIL // History: 06-27-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CStdZFilter::DoEncode( DWORD dwFlags, LONG lInBufferSize, BYTE* pbInBuffer, LONG lOutBufferSize, BYTE* pbOutBuffer, LONG lInBytesAvailable, LONG* plInBytesRead, LONG* plOutBytesWritten, DWORD dwReserved ) { PerfDbgLog(tagDft, this, "+CStdZFilter::DoEncode"); HRESULT hr = NOERROR; if( !_pEncodeCtx ) hr = CreateCompression(&_pEncodeCtx, _ulSchema); if( _pEncodeCtx && !FAILED(hr) ) { PProtAssert( pbInBuffer && pbOutBuffer && plInBytesRead && plOutBytesWritten); hr = Compress( _pEncodeCtx, pbInBuffer, lInBytesAvailable, pbOutBuffer, lOutBufferSize, plInBytesRead, plOutBytesWritten, _cEncLevel ); } PerfDbgLog1(tagDft, this, "-CStdZFilter::DoEncode(hr:%1x)", hr); return hr; } // Method: CStdZFilter::DoDecode // Synopsis: // Arguments: [dwFlags] - flags // [lInBufferSize] - Input Buffer Size // [pbInBuffer] - Input Buffer // [lOutBufferSize] - Output Buffer Size // [pbOutBuffer] - Output Buffer // [lInBytesAvailable] - Data available in Input Buffer // [plInBytesRead] - Total data read from input buffer // [plOutBytesWritten] - Total data written to output buffer // [dwReserved] - reserved // Returns: NOERROR or E_FAIL // History: 06-27-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CStdZFilter::DoDecode( DWORD dwFlags, LONG lInBufferSize, BYTE* pbInBuffer, LONG lOutBufferSize, BYTE* pbOutBuffer, LONG lInBytesAvailable, LONG* plInBytesRead, LONG* plOutBytesWritten, DWORD dwReserved ) { PerfDbgLog(tagDft, this, "+CStdZFilter::DoDecode"); HRESULT hr = NOERROR; if( !_pDecodeCtx ) hr = CreateDecompression(&_pDecodeCtx, _ulSchema); if( _pDecodeCtx && !FAILED(hr) ) { PProtAssert( pbInBuffer && pbOutBuffer && plInBytesRead && plOutBytesWritten); hr = Decompress( _pDecodeCtx, pbInBuffer, lInBytesAvailable, pbOutBuffer, lOutBufferSize, plInBytesRead, plOutBytesWritten ); } PerfDbgLog1(tagDft, this, "-CStdZFilter::DoDecode(hr:%1x)", hr); return hr; } // Method: CStdZFilter::SetEncodingLevel // Synopsis: // Arguments: [cEncLevel] - encoding level (between 1-100) // Returns: NOERROR or E_FAIL // History: 06-27-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CStdZFilter::SetEncodingLevel(DWORD dwEncLevel) { PerfDbgLog(tagDft, this, "+CStdZFilter::SetEncodingLevel"); HRESULT hr = NOERROR; if( dwEncLevel >= 1 && dwEncLevel <= 100 ) { // input value should be between 1 - 100] // our formula is _cEncLevel = dwEncLevel * 10 / 100 _cEncLevel = (dwEncLevel * 10) / 100; if( !_cEncLevel ) ++_cEncLevel; } else hr = E_INVALIDARG; PerfDbgLog1( tagDft, this, "-CStdZFilter::SetEncodingLevel(hr:%1x)", hr); return hr; } // Method: CStdZFilter::InitFilter // Synopsis: // Arguments: // Returns: NOERROR or E_FAIL (dll init failed) // History: 06-27-97 DanpoZ (Danpo Zhang) Created // Notes: HRESULT CStdZFilter::InitFilter() { PerfDbgLog(tagDft, this, "+CStdZFilter::InitFilter"); HRESULT hr = NOERROR; // init the compressor if (FAILED(InitCompression())) hr = E_FAIL; // init the decompressor if (FAILED(InitDecompression())) hr = E_FAIL; PerfDbgLog(tagDft, this, "-CStdZFilter::InitFilter"); return hr; } // Method: CStdZFilter::CStdZFilter // Synopsis: // Arguments: // Returns: // History: 06-26-97 DanpoZ (Danpo Zhang) Created // Notes: CStdZFilter::CStdZFilter(ULONG ulSchema) : _CRefs() { PerfDbgLog(tagDft, this, "+CStdZFilter::CStdZFilter"); _pEncodeCtx = NULL; _pDecodeCtx = NULL; // accepts the number between 1[fastest] - 10[most compres] // the formula is _cEncLevel/10 = 50/100 _cEncLevel= 5; _ulSchema = ulSchema; PerfDbgLog(tagDft, this, "-CStdZFilter::CStdZFilter"); } // Method: CStdZFilter::~CStdZFilter // Synopsis: // Arguments: // Returns: // History: 06-26-97 DanpoZ (Danpo Zhang) Created // Notes: CStdZFilter::~CStdZFilter() { PerfDbgLog(tagDft, this, "+CStdZFilter::~CStdZFilter"); if( _pEncodeCtx ) DestroyCompression(_pEncodeCtx); if( _pDecodeCtx ) DestroyDecompression(_pDecodeCtx); PerfDbgLog(tagDft, this, "-CStdZFilter::~CStdZFilter"); } // Method: CEncodingFilterFactory::QueryInterface // Synopsis: // Arguments: // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CEncodingFilterFactory::QueryInterface(REFIID riid, void **ppvObj) { PerfDbgLog(tagDft, this, "+CEncodingFilterFactory::QueryInterface"); VDATEPTROUT(ppvObj, void*); VDATETHIS(this); HRESULT hr = NOERROR; if( riid == IID_IUnknown || riid == IID_IEncodingFilterFactory ) { *ppvObj = this; AddRef(); } else hr = E_NOINTERFACE; PerfDbgLog1( tagDft, this, "-CEncodingFilterFactory::QueryInterface(hr:%1x)", hr); return hr; } // Method: CEncodingFilterFactory::AddRef // Synopsis: // Arguments: // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP_(ULONG) CEncodingFilterFactory::AddRef() { PerfDbgLog(tagDft, this, "+CEncodingFilterFactory::AddRef"); LONG lRet = ++_CRefs; PerfDbgLog1( tagDft, this, "-CEncodingFilterFactory::AddRef(cRef:%1d)", lRet); return lRet; } // Method: CEncodingFilterFactory::Release // Synopsis: // Arguments: // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP_(ULONG) CEncodingFilterFactory::Release() { PerfDbgLog(tagDft, this, "+CEncodingFilterFactory::Release"); LONG lRet = --_CRefs; if(!lRet) delete this; PerfDbgLog1( tagDft, this, "-CEncodingFilterFactory::Release(cRef:%1d)", lRet); return lRet; } // Method: CEncodingFilterFactory::FindBestFilter // Synopsis: // Arguments: [grfETYPEIn] - input encoding type // [grfETYPEOut] - output encoding type // [info] - DATAINFO (what the data looks like) // [ppDF] - output DataFilter pointer // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: currently it calls FindDefaultFilter() STDMETHODIMP CEncodingFilterFactory::FindBestFilter( LPCWSTR pwzCodeIn, LPCWSTR pwzCodeOut, DATAINFO info, IDataFilter** ppDF ) { PerfDbgLog(tagDft, this, "+CEncodingFilterFactory::FindBestFilter"); HRESULT hr = NOERROR; hr = GetDefaultFilter(pwzCodeIn, pwzCodeOut, ppDF); PerfDbgLog1( tagDft, this, "-CEncodingFilterFactory::FindBestFilter(hr:%1x)", hr); return hr; } // Method: CEncodingFilterFactory::GetDefaultFilter // Synopsis: // Arguments: [tIn] - input encoding type // [tOut] - output encoding type // [ppDF] - output DataFilter pointer // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CEncodingFilterFactory::GetDefaultFilter( LPCWSTR pwzCodeIn, LPCWSTR pwzCodeOut, IDataFilter** ppDF ) { PerfDbgLog(tagDft, this, "+CEncodingFilterFactory::GetDefaultFilter"); VDATEPTROUT(ppDF, void*); *ppDF = NULL; HRESULT hr = E_FAIL; BOOL fBuiltIn = FALSE; if( (!_wcsicmp(pwzCodeIn, L"gzip") && !_wcsicmp(pwzCodeOut, L"text")) || (!_wcsicmp(pwzCodeIn, L"text") && !_wcsicmp(pwzCodeOut, L"gzip") ) ) { // GZIP *ppDF = new CStdZFilter(COMPRESSION_FLAG_GZIP); fBuiltIn = TRUE; if( !(*ppDF) ) { hr = E_OUTOFMEMORY; } } else if((!_wcsicmp(pwzCodeIn, L"deflate") && !_wcsicmp(pwzCodeOut, L"text"))|| (!_wcsicmp(pwzCodeIn, L"text") && !_wcsicmp(pwzCodeOut, L"deflate")) ) { // deflate *ppDF = new CStdZFilter(COMPRESSION_FLAG_DEFLATE); fBuiltIn = TRUE; if( !(*ppDF) ) { hr = E_OUTOFMEMORY; } } else { // lookup reg to find out the class CLSID clsid = CLSID_NULL; hr = LookupClsIDFromReg(pwzCodeIn, pwzCodeOut, &clsid, 0); if( hr == NOERROR ) { // Get Clsid IClassFactory* pCF = NULL; hr = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pCF ); if( hr == NOERROR ) { // Get Class Fac IUnknown* pUnk = NULL; hr = pCF->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk); if( hr == NOERROR ) { // Created Instance hr = pUnk->QueryInterface(IID_IDataFilter, (void**)ppDF); pUnk->Release(); } // Created Instance pCF->Release(); } // Get Class Fac } // Get Clsid } // lookup reg to find out the class // only do this for built-in filter (this is not universal) if( (*ppDF) && fBuiltIn ) { hr = ((CStdZFilter*)(*ppDF))->InitFilter(); } PerfDbgLog1( tagDft, this, "-CEncodingFilterFactory::GetDefaultFilter(hr:%1x)",hr); return hr; } // Method: CEncodingFilterFactory::LookupClsIDFromReg // Synopsis: // Arguments: // Returns: // History: 08-20-97 DanpoZ (Danpo Zhang) Created // Notes: STDMETHODIMP CEncodingFilterFactory::LookupClsIDFromReg( LPCWSTR pwzCodeIn, LPCWSTR pwzCodeOut, CLSID* pclsid, DWORD dwFlags ) { HRESULT hr = E_FAIL; CHAR szCodeIn[ULPROTOCOLLEN]; CHAR szCodeOut[ULPROTOCOLLEN]; CHAR szCodeKey[2*ULPROTOCOLLEN+1]; DWORD dwLen = 256; CHAR szDFilterKey[MAX_PATH]; BOOL fFoundKey = FALSE; HKEY hDFKey = NULL; DWORD dwType; W2A(pwzCodeIn, szCodeIn, ULPROTOCOLLEN); W2A(pwzCodeOut, szCodeOut, ULPROTOCOLLEN); // check buffer overrun if( (strlen(szCodeIn) + strlen(szCodeOut) + strlen(szDFilterKey) + 2) <= MAX_PATH ) { // try key#1 strcpy(szDFilterKey, SZDFILTERROOT); strcat(szDFilterKey, szCodeIn); strcat(szDFilterKey, "#"); strcat(szDFilterKey, szCodeOut); if( RegOpenKeyEx(HKEY_CLASSES_ROOT, szDFilterKey, 0, KEY_QUERY_VALUE, &hDFKey ) == ERROR_SUCCESS) { if( RegQueryValueEx(hDFKey, SZCLASS, NULL, &dwType, (LPBYTE)szDFilterKey, &dwLen) == ERROR_SUCCESS) { hr = CLSIDFromStringA(szDFilterKey, pclsid); fFoundKey = TRUE; } RegCloseKey(hDFKey); } // try key#2 if( !fFoundKey ) { strcpy(szDFilterKey, SZDFILTERROOT); strcat(szDFilterKey, szCodeOut); strcat(szDFilterKey, "#"); strcat(szDFilterKey, szCodeIn); if( RegOpenKeyEx(HKEY_CLASSES_ROOT, szDFilterKey, 0, KEY_QUERY_VALUE, &hDFKey ) == ERROR_SUCCESS ) { if( RegQueryValueEx(hDFKey, SZCLASS, NULL, &dwType, (LPBYTE)szDFilterKey, &dwLen) == ERROR_SUCCESS) { hr = CLSIDFromStringA(szDFilterKey, pclsid); } RegCloseKey(hDFKey); } } } return hr; } // Method: CEncodingFilterFactory::CEncodingFilterFactory // Synopsis: // Arguments: // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: CEncodingFilterFactory::CEncodingFilterFactory() : _CRefs() { PerfDbgLog( tagDft, this, "+CEncodingFilterFactory::CEncodingFilterFactory"); PerfDbgLog( tagDft, this, "-CEncodingFilterFactory::CEncodingFilterFactory"); } // Method: CEncodingFilterFactory::~CEncodingFilterFactory // Synopsis: // Arguments: // Returns: // History: 04-29-97 DanpoZ (Danpo Zhang) Created // Notes: CEncodingFilterFactory::~CEncodingFilterFactory() { PerfDbgLog( tagDft, this, "+CEncodingFilterFactory::~CEncodingFilterFactory"); PerfDbgLog( tagDft, this, "-CEncodingFilterFactory::~CEncodingFilterFactory"); }