Windows2003-3790/inetcore/urlmon/eapp/ccodeft.cxx
2020-09-30 16:53:55 +02:00

741 lines
19 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: CCodeFt.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 04-29-97 DanpoZ (Danpo Zhang) Created
//
//----------------------------------------------------------------------------
#include <eapp.h>
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) + 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");
}