1635 lines
46 KiB
C++
1635 lines
46 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
||
|
//
|
||
|
// File: transact.cxx
|
||
|
//
|
||
|
// Contents: Class that performs the download of a particular request.
|
||
|
//
|
||
|
// Classes:
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// History: 12-04-95 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
#include <trans.h>
|
||
|
#include <shlwapi.h>
|
||
|
|
||
|
#include "oinet.hxx"
|
||
|
|
||
|
PerfDbgTag(tagCTransaction, "Urlmon", "Log CTransaction", DEB_TRANS);
|
||
|
DbgTag(tagCTransactionErr, "Urlmon", "Log CTransaction Errors", DEB_TRANS|DEB_ERROR);
|
||
|
|
||
|
HRESULT GetClassDocFileBuffer(LPVOID pbuffer, DWORD dwSize, CLSID *pclsid);
|
||
|
HRESULT GetCodeBaseFromDocFile(LPBYTE pBuffer, ULONG ulSize, LPWSTR *pwzClassStr,
|
||
|
LPWSTR pwzBaseUrl, DWORD *lpdwVersionMS, DWORD *lpdwVersionLS);
|
||
|
HRESULT IsHandlerAvailable(LPWSTR pwzUrl, LPWSTR pwzMime, CLSID *pclsid,
|
||
|
LPBYTE pBuffer, ULONG cbSize);
|
||
|
|
||
|
#if 0
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProtSnk::QueryInterface
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [riid] --
|
||
|
// [ppvObj] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProtSnk::QueryInterface(REFIID riid, void **ppvObj)
|
||
|
{
|
||
|
VDATEPTROUT(ppvObj, void *);
|
||
|
VDATETHIS(this);
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::QueryInterface");
|
||
|
|
||
|
*ppvObj = NULL;
|
||
|
if (_pUnk)
|
||
|
{
|
||
|
hr = _pUnk->QueryInterface(riid, ppvObj);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( (riid == IID_IUnknown)
|
||
|
|| (riid == IID_IOInetProtocol))
|
||
|
{
|
||
|
*ppvObj = (IOInetProtocol *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (riid == IID_IOInetProtocolSink)
|
||
|
{
|
||
|
*ppvObj = (IOInetProtocolSink *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::QueryInterface (hr:%lx)", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: COInetProtSnk::AddRef
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [ULONG] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP_(ULONG) COInetProtSnk::AddRef(void)
|
||
|
{
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::AddRef");
|
||
|
|
||
|
LONG lRet = _pProtSnk->AddRef();
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::AddRef (cRefs:%ld)", lRet);
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: COInetProtSnk::Release
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [ULONG] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP_(ULONG) COInetProtSnk::Release(void)
|
||
|
{
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::Release");
|
||
|
|
||
|
LONG lRet = _pProtSnk->Release();
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::Release (cRefs:%ld)", lRet);
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProtSnk::Switch
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [pStateInfo] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProtSnk::Switch(PROTOCOLDATA *pStateInfo)
|
||
|
{
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::Switch");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->Switch(pStateInfo);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::Switch (hr:%lx)", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProtSnk::ReportProgress
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [NotMsg] --
|
||
|
// [szStatusText] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProtSnk::ReportProgress(ULONG NotMsg, LPCWSTR pwzStatusText)
|
||
|
{
|
||
|
PerfDbgLog1(tagCTransaction, this, "+COInetProtSnk::ReportProgress pwzStatusText:%ws", pwzStatusText);
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
|
||
|
|
||
|
PerfDbgLog2(tagCTransaction, this, "-COInetProtSnk::ReportProgress (pwzStatusText:%ws, hr:%lx)", pwzStatusText, hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProtSnk::ReportData
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [grfBSCF] --
|
||
|
// [ULONG] --
|
||
|
// [ulProgressMax] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProtSnk::ReportData(DWORD grfBSCF, ULONG ulProgress,ULONG ulProgressMax)
|
||
|
{
|
||
|
PerfDbgLog3(tagCTransaction, this, "+COInetProtSnk::ReportData(grfBSCF:%lx, ulProgress:%ld, ulProgressMax:%ld)",
|
||
|
grfBSCF, ulProgress, ulProgressMax);
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::ReportData (hr:%lx)", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProtSnk::ReportResult
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [DWORD] --
|
||
|
// [dwError] --
|
||
|
// [wzResult] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProtSnk::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR wzResult)
|
||
|
{
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProtSnk::ReportResult");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->ReportResult(hrResult, dwError, wzResult);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProtSnk::ReportResult (hr:%lx)", hr);
|
||
|
return hr;
|
||
|
}
|
||
|
#endif // 0
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::QueryInterface
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [riid] --
|
||
|
// [ppvObj] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::QueryInterface(REFIID riid, void **ppvObj)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IUnknown::QueryInterface",
|
||
|
"this=%#x, %#x, %#x",
|
||
|
this, &riid, ppvObj
|
||
|
));
|
||
|
|
||
|
VDATEPTROUT(ppvObj, void *);
|
||
|
VDATETHIS(this);
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::QueryInterface");
|
||
|
|
||
|
*ppvObj = NULL;
|
||
|
|
||
|
if (_pUnk)
|
||
|
{
|
||
|
hr = _pUnk->QueryInterface(riid, ppvObj);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( (riid == IID_IUnknown)
|
||
|
|| (riid == IID_IOInetProtocol))
|
||
|
{
|
||
|
*ppvObj = (IOInetProtocol *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (riid == IID_IOInetProtocolSink)
|
||
|
{
|
||
|
*ppvObj = (IOInetProtocolSink *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (riid == IID_IServiceProvider)
|
||
|
{
|
||
|
*ppvObj = (IServiceProvider *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else if (riid == IID_IOInetPriority)
|
||
|
{
|
||
|
*ppvObj = (IOInetPriority *) this;
|
||
|
AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::QueryInterface (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: COInetProt::AddRef
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [ULONG] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP_(ULONG) COInetProt::AddRef(void)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Dword,
|
||
|
"COInetProt::IUnknown::AddRef",
|
||
|
"this=%#x",
|
||
|
this
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::AddRef");
|
||
|
|
||
|
LONG lRet;
|
||
|
|
||
|
if (_pUnk)
|
||
|
{
|
||
|
lRet = _pUnk->AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lRet = ++_CRefs;
|
||
|
}
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::AddRef (cRefs:%ld)", lRet);
|
||
|
|
||
|
DEBUG_LEAVE(lRet);
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: COInetProt::Release
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [ULONG] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP_(ULONG) COInetProt::Release(void)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Dword,
|
||
|
"COInetProt::IUnknown::Release",
|
||
|
"this=%#x",
|
||
|
this
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Release");
|
||
|
|
||
|
LONG lRet;
|
||
|
if (_pUnk)
|
||
|
{
|
||
|
lRet = _pUnk->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lRet = --_CRefs;
|
||
|
if (_CRefs == 0)
|
||
|
{
|
||
|
//
|
||
|
// release all objects
|
||
|
if (_pProtSnk)
|
||
|
{
|
||
|
_pProtSnk->Release();
|
||
|
}
|
||
|
if (_pProt)
|
||
|
{
|
||
|
_pProt->Release();
|
||
|
}
|
||
|
|
||
|
if (_dwMode & PP_DELETE)
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Release (cRefs:%ld)", lRet);
|
||
|
|
||
|
DEBUG_LEAVE(lRet);
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Start
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [pwzUrl] --
|
||
|
// [pTrans] --
|
||
|
// [pOIBindInfo] --
|
||
|
// [grfSTI] --
|
||
|
// [dwReserved] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Start(LPCWSTR pwzUrl, IOInetProtocolSink *pOInetProtSnk, IOInetBindInfo *pOIBindInfo,
|
||
|
DWORD grfSTI, DWORD_PTR dwReserved)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Start",
|
||
|
"this=%#x, %.80wq, %#x, %#x, %#x, %#x",
|
||
|
this, pwzUrl, pOInetProtSnk, pOIBindInfo, grfSTI, dwReserved
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Start\n");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
TransAssert((pOIBindInfo && pOInetProtSnk && pwzUrl));
|
||
|
|
||
|
// Just before starting the transaction give it the priority.
|
||
|
|
||
|
IOInetPriority * pOInetPriority = NULL;
|
||
|
if (_pProt->QueryInterface(IID_IOInetPriority, (void **) &pOInetPriority) == S_OK)
|
||
|
{
|
||
|
pOInetPriority->SetPriority(_nPriority);
|
||
|
pOInetPriority->Release();
|
||
|
}
|
||
|
|
||
|
delete [] _pwzUrl;
|
||
|
_pwzUrl = OLESTRDuplicate(pwzUrl);
|
||
|
|
||
|
hr = _pProt->Start(pwzUrl, pOInetProtSnk, pOIBindInfo, grfSTI, dwReserved);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Start (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Continue
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [pStateInfoIn] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Continue(PROTOCOLDATA *pStateInfoIn)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Continue",
|
||
|
"this=%#x, %#x",
|
||
|
this, pStateInfoIn
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Continue\n");
|
||
|
|
||
|
HRESULT hr = _pProt->Continue(pStateInfoIn);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Continue (hr:%lx)\n",hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Abort
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [hrReason] --
|
||
|
// [dwOptions] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-09-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Abort(HRESULT hrReason, DWORD dwOptions)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Abort",
|
||
|
"this=%#x, %#x, %#x",
|
||
|
this, hrReason, dwOptions
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Abort\n");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProt->Abort(hrReason, dwOptions);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Abort (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Terminate
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [dwOptions] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Terminate(DWORD dwOptions)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Terminate",
|
||
|
"this=%#x, %#x",
|
||
|
this, dwOptions
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Terminate\n");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
TransAssert((_pProt));
|
||
|
|
||
|
hr = _pProt->Terminate(dwOptions);
|
||
|
SetProtocolSink(0);
|
||
|
SetServiceProvider(0);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Terminate (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Suspend
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Suspend()
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Suspend",
|
||
|
"this=%#x",
|
||
|
this
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Suspend\n");
|
||
|
|
||
|
HRESULT hr = _pProt->Suspend();
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Suspend (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Resume
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Resume()
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolRoot::Resume",
|
||
|
"this=%#x",
|
||
|
this
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Resume\n");
|
||
|
|
||
|
HRESULT hr = _pProt->Resume();
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Resume (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Read
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [ULONG] --
|
||
|
// [ULONG] --
|
||
|
// [pcbRead] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Read(void *pBuffer, ULONG cbBuffer,ULONG *pcbRead)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocol::Read",
|
||
|
"this=%#x, %#x, %#x, %#x",
|
||
|
this, pBuffer, cbBuffer, pcbRead
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Read\n");
|
||
|
HRESULT hr = E_FAIL;
|
||
|
|
||
|
BOOL fRead = TRUE;
|
||
|
DWORD dwCopy = 0;
|
||
|
DWORD dwCopyNew = 0;
|
||
|
|
||
|
if ((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP))
|
||
|
&& _cbBufferUnread)
|
||
|
{
|
||
|
fRead = FALSE;
|
||
|
|
||
|
// copy data form the local buffer to the provide buffer
|
||
|
if (cbBuffer <= _cbBufferUnread)
|
||
|
{
|
||
|
dwCopy = cbBuffer;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwCopy = _cbBufferUnread;
|
||
|
fRead = TRUE;
|
||
|
}
|
||
|
memcpy(pBuffer, _pBuffer+(_cbBufferFilled-_cbBufferUnread), dwCopy);
|
||
|
_cbBufferUnread -= dwCopy;
|
||
|
}
|
||
|
|
||
|
if (fRead)
|
||
|
{
|
||
|
if (_pProt)
|
||
|
{
|
||
|
hr = _pProt->Read( ((LPBYTE)pBuffer) + dwCopy, cbBuffer - dwCopy, &dwCopyNew);
|
||
|
_cbTotalBytesRead += dwCopyNew;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pcbRead)
|
||
|
{
|
||
|
*pcbRead = dwCopy + dwCopyNew;
|
||
|
}
|
||
|
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Read (hr:%lx)\n",hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Seek
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [DWORD] --
|
||
|
// [ULARGE_INTEGER] --
|
||
|
// [plibNewPosition] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocol::Seek",
|
||
|
"this=%#x, %#x, %#x, %#x",
|
||
|
this, dlibMove, dwOrigin, plibNewPosition
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Seek\n");
|
||
|
|
||
|
HRESULT hr = _pProt->Seek(dlibMove, dwOrigin, plibNewPosition);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Seek (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::LockRequest
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [dwOptions] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::LockRequest(DWORD dwOptions)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocol::LockRequest",
|
||
|
"this=%#x, %#x",
|
||
|
this, dwOptions
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::LockRequest\n");
|
||
|
|
||
|
HRESULT hr = hr = _pProt->LockRequest(dwOptions);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::LockRequest (hr:%lx)\n",hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::UnlockRequest
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 10-29-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::UnlockRequest()
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocol::UnlockRequest",
|
||
|
"this=%#x",
|
||
|
this
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::UnlockRequest\n");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProt->UnlockRequest();
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::UnlockRequest (hr:%lx)\n", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: CTransaction::OnDataReceived
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [grfBSC] --
|
||
|
// [cbBytesAvailable] --
|
||
|
// [dwTotalSize] --
|
||
|
// [pcbNewAvailable] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 4-15-1997 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::OnDataReceived(DWORD *pgrfBSC, DWORD *pcbBytesAvailable, DWORD *pdwTotalSize)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::OnDataReceived",
|
||
|
"this=%#x, %#x, %#x, %#x",
|
||
|
this, pgrfBSC, pcbBytesAvailable, pdwTotalSize
|
||
|
));
|
||
|
|
||
|
PerfDbgLog3(tagCTransaction, this, "+COInetProt::OnDataReceived (grfBSC:%lx, *pcbBytesAvailable:%ld, _cbTotalBytesRead:%ld)",
|
||
|
*pgrfBSC, *pcbBytesAvailable, _cbTotalBytesRead);
|
||
|
HRESULT hr = NOERROR;
|
||
|
DWORD grfBSC = *pgrfBSC;
|
||
|
BOOL fEndOfData = FALSE;
|
||
|
|
||
|
if (_fWaitOnHandler)
|
||
|
{
|
||
|
hr = S_NEEDMOREDATA;
|
||
|
}
|
||
|
else if (
|
||
|
((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
|
||
|
&& (!_fMimeVerified || _fNeedMoreData))
|
||
|
||
|
||
|
((_dwOInetBdgFlags & PI_CLASSINSTALL) && !_fClassInstallChecked)
|
||
|
)
|
||
|
{
|
||
|
DWORD dwNewData = 0;
|
||
|
TransAssert((_pProt && _cbDataSniffMin));
|
||
|
|
||
|
//TransAssert((pcbBytesAvailable && *pcbBytesAvailable));
|
||
|
//TransAssert((pdwTotalSize));
|
||
|
|
||
|
// _cbTotalBytesRead = # of bytes read so far
|
||
|
if (_cbBufferFilled < _cbDataSniffMin)
|
||
|
{
|
||
|
// no bytes read so far
|
||
|
TransAssert((_cbTotalBytesRead < _cbDataSniffMin));
|
||
|
// read data into buffer and report progess
|
||
|
do
|
||
|
{
|
||
|
PProtAssert((_pBuffer && (_pBuffer + _cbBufferFilled) ));
|
||
|
hr = _pProt->Read(_pBuffer + _cbBufferFilled, _cbBufferSize - _cbBufferFilled, &dwNewData);
|
||
|
_cbTotalBytesRead += dwNewData;
|
||
|
_cbBufferFilled += dwNewData;
|
||
|
_cbBufferUnread += dwNewData;
|
||
|
} while ((hr == S_OK) && (_cbBufferFilled < _cbDataSniffMin));
|
||
|
|
||
|
// now check if this is docfile
|
||
|
// if so download at least 2k
|
||
|
if (!_fDocFile && _cbBufferFilled && (IsDocFile(_pBuffer, _cbBufferFilled) == S_OK))
|
||
|
{
|
||
|
_fDocFile = TRUE;
|
||
|
|
||
|
// we may need to sniff to maximum to find handler
|
||
|
|
||
|
if (_cbBufferSize < DATASNIFSIZEDOCFILE_MAX)
|
||
|
{
|
||
|
LPBYTE pBufferTemp;
|
||
|
|
||
|
pBufferTemp = (LPBYTE) new BYTE[DATASNIFSIZEDOCFILE_MAX];
|
||
|
if (pBufferTemp)
|
||
|
{
|
||
|
memcpy(pBufferTemp, _pBuffer, _cbBufferFilled);
|
||
|
delete [] _pBuffer;
|
||
|
_pBuffer = pBufferTemp;
|
||
|
_cbBufferSize = DATASNIFSIZEDOCFILE_MAX;
|
||
|
|
||
|
if (hr == NOERROR)
|
||
|
{
|
||
|
//since we increased the buffersize and we want to drain DATASNIFSIZEDOCFILE_MAX bytes.
|
||
|
do
|
||
|
{
|
||
|
PProtAssert((_pBuffer && (_pBuffer + _cbBufferFilled) ));
|
||
|
hr = _pProt->Read(_pBuffer + _cbBufferFilled, _cbBufferSize - _cbBufferFilled, &dwNewData);
|
||
|
_cbTotalBytesRead += dwNewData;
|
||
|
_cbBufferFilled += dwNewData;
|
||
|
_cbBufferUnread += dwNewData;
|
||
|
} while ((hr == S_OK) && (_cbBufferFilled < _cbBufferSize));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_cbDataSniffMin = (*pdwTotalSize && *pdwTotalSize < _cbBufferSize) ? *pdwTotalSize : _cbBufferSize;
|
||
|
}
|
||
|
|
||
|
if ((hr == E_PENDING) && (_cbBufferFilled < _cbDataSniffMin))
|
||
|
{
|
||
|
// do not report anything - wait until we get more data
|
||
|
// a request is pending at this time
|
||
|
// need more data to sniff properly
|
||
|
hr = S_NEEDMOREDATA;
|
||
|
}
|
||
|
else if (hr == NOERROR || hr == E_PENDING)
|
||
|
{
|
||
|
TransAssert((_cbTotalBytesRead != 0));
|
||
|
|
||
|
// report the data we have in the buffer or
|
||
|
// the available #
|
||
|
DWORD cbBytesReport = (*pcbBytesAvailable > _cbTotalBytesRead) ? *pcbBytesAvailable : _cbTotalBytesRead + 1;
|
||
|
|
||
|
if (*pdwTotalSize && ((cbBytesReport > *pdwTotalSize)))
|
||
|
{
|
||
|
cbBytesReport = *pdwTotalSize;
|
||
|
}
|
||
|
*pcbBytesAvailable = cbBytesReport;
|
||
|
}
|
||
|
else if (hr == S_FALSE)
|
||
|
{
|
||
|
// end of stream
|
||
|
*pgrfBSC |= (BSCF_LASTDATANOTIFICATION & BSCF_DATAFULLYAVAILABLE);
|
||
|
*pcbBytesAvailable = *pdwTotalSize = _cbTotalBytesRead;
|
||
|
fEndOfData = TRUE;
|
||
|
}
|
||
|
|
||
|
if ( (!_fMimeVerified)
|
||
|
&& ( (*pcbBytesAvailable >= _cbDataSniffMin)
|
||
|
|| (hr == S_FALSE)) )
|
||
|
{
|
||
|
// enough data or end of stream
|
||
|
_fMimeVerified = TRUE;
|
||
|
LPWSTR pwzStr = 0;
|
||
|
DWORD dwMimeFlags = FMFD_DEFAULT;
|
||
|
if( !_pwzFileName )
|
||
|
{
|
||
|
dwMimeFlags = FMFD_URLASFILENAME;
|
||
|
}
|
||
|
hr = FindMimeFromData(NULL, (_pwzFileName) ? _pwzFileName : _pwzUrl, _pBuffer, _cbBufferFilled, _pwzMimeSuggested, dwMimeFlags, &pwzStr, 0);
|
||
|
|
||
|
TransAssert(pwzStr);
|
||
|
|
||
|
// note: _pwzUrl & _pwzFileName may be used later for composing URL
|
||
|
// in code base attribute of active document (deleted in destructor)
|
||
|
|
||
|
if (pwzStr)
|
||
|
{
|
||
|
_fMimeReported = 1;
|
||
|
_pProtSnk->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, pwzStr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TransAssert((!_pwzMimeSuggested));
|
||
|
}
|
||
|
|
||
|
if (pwzStr)
|
||
|
{
|
||
|
delete [] _pwzMimeSuggested;
|
||
|
_pwzMimeSuggested = pwzStr;
|
||
|
pwzStr = 0;
|
||
|
}
|
||
|
|
||
|
if ( _fDocFile
|
||
|
&& (_dwOInetBdgFlags & PI_DOCFILECLSIDLOOKUP))
|
||
|
{
|
||
|
// find the class id and send it on
|
||
|
CLSID clsid;
|
||
|
|
||
|
HRESULT hr1 = GetClassDocFileBuffer(_pBuffer, _cbBufferFilled, &clsid);
|
||
|
if (hr1 == NOERROR)
|
||
|
{
|
||
|
if (_pwzStrClsId)
|
||
|
{
|
||
|
delete [] _pwzStrClsId;
|
||
|
_pwzStrClsId = NULL;
|
||
|
}
|
||
|
StringFromCLSID(clsid, &_pwzStrClsId);
|
||
|
if (_pwzStrClsId)
|
||
|
{
|
||
|
_fReportedClassId = TRUE;
|
||
|
_pProtSnk->ReportProgress(BINDSTATUS_CLASSIDAVAILABLE, _pwzStrClsId);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//On a BTS->BTO scenario, we should get into this loop with the lesser of DATASNIFSIZEDOCFILE_MIN or TOTAL_SIZE.
|
||
|
//On a BTO scenario, the situation is the same as before, except hr=S_NEEDMOREDATA if size<DATASNIF_MIN.
|
||
|
//On a BTS scenario, this block will not be entered.
|
||
|
if ( (_dwOInetBdgFlags & PI_CLASSINSTALL)
|
||
|
&& !_fGotHandler )
|
||
|
{
|
||
|
_fClassInstallChecked = TRUE;
|
||
|
|
||
|
BOOL fIgnoreMimeClsid = FALSE;
|
||
|
DWORD dwVersionMS = 0, dwVersionLS = 0;
|
||
|
LPWSTR pwzCodeBase = 0, pwzVerInfo = 0;
|
||
|
CLSID clsid;
|
||
|
HRESULT hr1;
|
||
|
|
||
|
if (!_fReportedClassId && _pwzStrClsId && _pProtSnk)
|
||
|
{
|
||
|
_fReportedClassId = TRUE;
|
||
|
_pProtSnk->ReportProgress(BINDSTATUS_CLASSIDAVAILABLE, _pwzStrClsId);
|
||
|
}
|
||
|
|
||
|
if (IsHandlerAvailable((_pwzFileName) ? _pwzFileName : _pwzUrl, _pwzMimeSuggested, &clsid, _pBuffer, _cbBufferFilled) == S_OK)
|
||
|
{
|
||
|
_fGotHandler = TRUE;
|
||
|
}
|
||
|
else if (_fDocFile)
|
||
|
{
|
||
|
// try get code base + version information
|
||
|
// even if handler is installed, a newer version may be required for this doc file
|
||
|
|
||
|
hr1 = GetCodeBaseFromDocFile(_pBuffer, _cbBufferFilled, &pwzCodeBase, _pwzUrl, &dwVersionMS, &dwVersionLS);
|
||
|
|
||
|
// convert version info. to string
|
||
|
if (SUCCEEDED(hr1) && (dwVersionMS || dwVersionLS))
|
||
|
{
|
||
|
CHAR szVerInfo[MAX_PATH];
|
||
|
|
||
|
wsprintfA(szVerInfo,"%ld,%ld", dwVersionMS, dwVersionLS);
|
||
|
pwzVerInfo = DupA2W(szVerInfo);
|
||
|
}
|
||
|
|
||
|
// if failed to get codebase, keep sniffing
|
||
|
// if we are at end of bits then go with out a code base
|
||
|
|
||
|
_fNeedMoreData = FAILED(hr1) && (_cbBufferFilled < _cbDataSniffMin) && (!fEndOfData);
|
||
|
}
|
||
|
|
||
|
//BUGBUG #51944: This currently requires a DocFile and CodeBase property
|
||
|
|
||
|
if (!_fNeedMoreData && !_fGotHandler && _fDocFile && pwzCodeBase)
|
||
|
{
|
||
|
LPOLESTR pwzClsId = 0;
|
||
|
|
||
|
if (!IsEqualCLSID(clsid, CLSID_NULL))
|
||
|
{
|
||
|
StringFromCLSID(clsid, &pwzClsId);
|
||
|
}
|
||
|
else if (_pwzMimeSuggested)
|
||
|
{
|
||
|
// this is an optimization, if no CLSID and only this as mime type
|
||
|
// then we won't find anything in ObjectStore
|
||
|
if (!StrCmpNIW(_pwzMimeSuggested, L"application/octet-stream", 24))
|
||
|
{
|
||
|
_fGotHandler = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!_fGotHandler && (pwzClsId || _pwzMimeSuggested))
|
||
|
{
|
||
|
LPWSTR pwzClassStr = 0;
|
||
|
int cbClassStr;
|
||
|
|
||
|
cbClassStr = (pwzCodeBase ? lstrlenW(pwzCodeBase) : 0)
|
||
|
+ (pwzClsId ? lstrlenW(pwzClsId) : 0)
|
||
|
+ (_pwzMimeSuggested ? lstrlenW(_pwzMimeSuggested) : 0)
|
||
|
+ (pwzVerInfo ? (lstrlenW(pwzVerInfo) + 1) : 0)
|
||
|
+ 3;
|
||
|
|
||
|
pwzClassStr = new WCHAR[cbClassStr];
|
||
|
|
||
|
if (pwzClassStr)
|
||
|
{
|
||
|
//BUGBUG: This is a bit of a hack, we have a collection of
|
||
|
//info to pass into filter, we concatenate it into one long
|
||
|
//string and send it in.
|
||
|
|
||
|
*pwzClassStr = '\0';
|
||
|
if (pwzCodeBase && *pwzCodeBase)
|
||
|
{
|
||
|
StrCpyW(pwzClassStr, pwzCodeBase);
|
||
|
}
|
||
|
|
||
|
StrCatW(pwzClassStr, L"?");
|
||
|
|
||
|
if (pwzClsId)
|
||
|
{
|
||
|
StrCatW(pwzClassStr, pwzClsId);
|
||
|
}
|
||
|
else if (_pwzMimeSuggested)
|
||
|
{
|
||
|
StrCatW(pwzClassStr, _pwzMimeSuggested);
|
||
|
}
|
||
|
|
||
|
if (pwzVerInfo)
|
||
|
{
|
||
|
StrCatW(pwzClassStr, L"?");
|
||
|
StrCatW(pwzClassStr, pwzVerInfo);
|
||
|
}
|
||
|
|
||
|
_pCTrans->ReportProgress(BINDSTATUS_CLASSINSTALLLOCATION,
|
||
|
pwzClassStr);
|
||
|
|
||
|
delete [] pwzClassStr;
|
||
|
|
||
|
// don't process this code branch again
|
||
|
_fGotHandler = TRUE;
|
||
|
|
||
|
// wait on more data now
|
||
|
hr = S_NEEDMOREDATA;
|
||
|
|
||
|
// wait on more data for future calls
|
||
|
_fWaitOnHandler = TRUE;
|
||
|
|
||
|
// wait for more data to sniff
|
||
|
_fNeedMoreData = TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
delete [] pwzClsId;
|
||
|
|
||
|
} // pwzClsId || _pwzMimeSuggested
|
||
|
} // !_fNeedMoreData
|
||
|
|
||
|
if (pwzCodeBase)
|
||
|
{
|
||
|
CoTaskMemFree(pwzCodeBase);
|
||
|
}
|
||
|
|
||
|
if (pwzVerInfo)
|
||
|
{
|
||
|
delete [] pwzVerInfo;
|
||
|
}
|
||
|
|
||
|
// if we don't need to sniff any more, curb _cbDataSniffMin
|
||
|
if (_fDocFile && _fGotHandler)
|
||
|
{
|
||
|
_cbDataSniffMin = (*pdwTotalSize && *pdwTotalSize < DATASNIFSIZEDOCFILE_MIN) ? *pdwTotalSize : DATASNIFSIZEDOCFILE_MIN;
|
||
|
}
|
||
|
|
||
|
// once we have a handler we can release pwzUrl & pwzFilename
|
||
|
if (_fGotHandler)
|
||
|
{
|
||
|
delete [] _pwzUrl;
|
||
|
_pwzUrl = 0;
|
||
|
delete [] _pwzFileName;
|
||
|
_pwzFileName = 0;
|
||
|
}
|
||
|
|
||
|
// report the data we have in the buffer or
|
||
|
// the available #
|
||
|
*pcbBytesAvailable = (*pcbBytesAvailable > _cbTotalBytesRead) ? *pcbBytesAvailable : _cbTotalBytesRead + 1;
|
||
|
} // PI_CLASSINSTALL && !_fGotHandler
|
||
|
|
||
|
if (*pdwTotalSize && (*pdwTotalSize < *pcbBytesAvailable))
|
||
|
{
|
||
|
*pcbBytesAvailable = *pdwTotalSize;
|
||
|
}
|
||
|
|
||
|
if (hr == S_FALSE)
|
||
|
{
|
||
|
hr = NOERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
CLock lck(_mxs);
|
||
|
_cbBytesReported = *pcbBytesAvailable;
|
||
|
}
|
||
|
//TransAssert((pcbBytesAvailable && *pcbBytesAvailable));
|
||
|
//TransAssert((hr == NOERROR || hr == S_NEEDMOREDATA));
|
||
|
|
||
|
PerfDbgLog2(tagCTransaction, this, "-COInetProt::OnDataReceived (hr:%lx, _cbBufferFilled:%ld)", hr, _cbBufferFilled);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Switch
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [pStateInfo] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Switch(PROTOCOLDATA *pStateInfo)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolSink::Switch",
|
||
|
"this=%#x, %#x",
|
||
|
this, pStateInfo
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::Switch");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->Switch(pStateInfo);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::Switch (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::ReportProgress
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [NotMsg] --
|
||
|
// [szStatusText] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::ReportProgress(ULONG NotMsg, LPCWSTR pwzStatusText)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolSink::ReportProgress",
|
||
|
"this=%#x, %#x, %.80wq",
|
||
|
this, NotMsg, pwzStatusText
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::ReportProgress");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
switch (NotMsg)
|
||
|
{
|
||
|
case BINDSTATUS_FILTERREPORTMIMETYPE:
|
||
|
{
|
||
|
if( _pCTrans && pwzStatusText )
|
||
|
{
|
||
|
// mime filter sending signal to tell us the true mime type
|
||
|
_pCTrans->UpdateVerifiedMimeType(pwzStatusText);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
case BINDSTATUS_MIMETYPEAVAILABLE:
|
||
|
if (_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
|
||
|
{
|
||
|
// report the mime later after sniffing data
|
||
|
_pwzMimeSuggested = OLESTRDuplicate(pwzStatusText);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
|
||
|
{
|
||
|
// disable mime sniffing
|
||
|
_dwOInetBdgFlags &= (~PI_MIMEVERIFICATION &~PI_DOCFILECLSIDLOOKUP &~PI_CLASSINSTALL);
|
||
|
hr = _pProtSnk->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, pwzStatusText);
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case BINDSTATUS_CACHEFILENAMEAVAILABLE :
|
||
|
_pwzFileName = OLESTRDuplicate(pwzStatusText);
|
||
|
hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
|
||
|
break;
|
||
|
|
||
|
case BINDSTATUS_DIRECTBIND:
|
||
|
_fMimeVerified = TRUE;
|
||
|
break;
|
||
|
|
||
|
case BINDSTATUS_ENDDOWNLOADCOMPONENTS :
|
||
|
if (_fWaitOnHandler)
|
||
|
{
|
||
|
// don't stall ReportData any more
|
||
|
_fWaitOnHandler = FALSE;
|
||
|
|
||
|
// we're done with our stuff, skip sniffing
|
||
|
_fNeedMoreData = FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
hr = _pProtSnk->ReportProgress(NotMsg, pwzStatusText);
|
||
|
}
|
||
|
|
||
|
} // end switch
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportProgress (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::ReportData
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [grfBSCF] --
|
||
|
// [ULONG] --
|
||
|
// [ulProgressMax] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::ReportData(DWORD grfBSCF, ULONG ulProgress,ULONG ulProgressMax)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolSink::ReportData",
|
||
|
"this=%#x, %#x, %#x, %#x",
|
||
|
this, grfBSCF, ulProgress, ulProgressMax
|
||
|
));
|
||
|
|
||
|
PerfDbgLog3(tagCTransaction, this, "+COInetProt::ReportData(grfBSCF:%lx, ulProgress:%ld, ulProgressMax:%ld)",
|
||
|
grfBSCF, ulProgress, ulProgressMax);
|
||
|
HRESULT hr = NOERROR, hr2;
|
||
|
|
||
|
TransAssert((ulProgress));
|
||
|
|
||
|
if ( ((_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP | PI_CLASSINSTALL))
|
||
|
&& (!_fMimeVerified || _fNeedMoreData))
|
||
|
||
|
||
|
((_dwOInetBdgFlags & PI_CLASSINSTALL) && !_fClassInstallChecked)
|
||
|
)
|
||
|
{
|
||
|
if ( (OnDataReceived(&grfBSCF, &ulProgress, &ulProgressMax) == NOERROR)
|
||
|
&& _pProtSnk
|
||
|
&& (ulProgress || (!ulProgress && !ulProgressMax)) )
|
||
|
{
|
||
|
// OnDataReceived sniffs data and calls Read - EOF with ReportResult might occure
|
||
|
//TransAssert((ulProgress));
|
||
|
TransAssert((_fMimeReported));
|
||
|
hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TransAssert((ulProgress));
|
||
|
hr = _pProtSnk->ReportData( grfBSCF, ulProgress, ulProgressMax);
|
||
|
}
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportData (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::ReportResult
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [DWORD] --
|
||
|
// [dwError] --
|
||
|
// [wzResult] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR wzResult)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetProtocolSink::ReportResult",
|
||
|
"this=%#x, %#x, %#x, %.80wq",
|
||
|
this, hrResult, dwError, wzResult
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::ReportResult");
|
||
|
HRESULT hr = NOERROR;
|
||
|
|
||
|
hr = _pProtSnk->ReportResult(hrResult, dwError, wzResult);
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::ReportResult (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::Initialize
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [pCTrans] --
|
||
|
// [dwMode] --
|
||
|
// [dwOptions] --
|
||
|
// [pUnk] --
|
||
|
// [pProt] --
|
||
|
// [pProtSnk] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
STDMETHODIMP COInetProt::Initialize(CTransaction *pCTrans,IServiceProvider *pSrvPrv, DWORD dwMode, DWORD dwOptions,
|
||
|
IUnknown *pUnk, IOInetProtocol *pProt, IOInetProtocolSink *pProtSnk, LPWSTR pwzUrl)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::Initialize",
|
||
|
"this=%#x, %#x, %#x, %#x, %#x, %#x, %#x, %#x, %.80wq",
|
||
|
this, pCTrans, pSrvPrv, dwMode, dwOptions, pUnk, pProt, pProtSnk, pwzUrl
|
||
|
));
|
||
|
|
||
|
HRESULT hr = NOERROR;
|
||
|
_dwMode = dwMode;
|
||
|
_pUnk = pUnk;
|
||
|
//_pProt = pProt;
|
||
|
//_pProtSnk = pProtSnk;
|
||
|
_pCTrans = pCTrans;
|
||
|
_pSrvPrv = pSrvPrv;
|
||
|
if (_pSrvPrv)
|
||
|
{
|
||
|
_pSrvPrv->AddRef();
|
||
|
}
|
||
|
SetProtocolSink(pProtSnk);
|
||
|
SetProtocol(pProt);
|
||
|
|
||
|
_dwOInetBdgFlags = dwOptions;
|
||
|
if (_dwOInetBdgFlags & (PI_MIMEVERIFICATION | PI_DOCFILECLSIDLOOKUP))
|
||
|
{
|
||
|
ULONG cbBufferSize;
|
||
|
|
||
|
TransAssert(( DATASNIFSIZE_MIN <= DATASNIFSIZEDOCFILE_MIN));
|
||
|
|
||
|
if (_dwOInetBdgFlags & PI_CLASSINSTALL)
|
||
|
{
|
||
|
cbBufferSize = DATASNIFSIZEDOCFILE_MAX;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cbBufferSize = DATASNIFSIZEDOCFILE_MIN; //DATASNIFSIZE_MIN;
|
||
|
}
|
||
|
|
||
|
if (cbBufferSize != _cbBufferSize)
|
||
|
{
|
||
|
_cbBufferSize = cbBufferSize;
|
||
|
delete [] _pBuffer;
|
||
|
_pBuffer = (LPBYTE) new BYTE[_cbBufferSize];
|
||
|
}
|
||
|
|
||
|
if (!_pBuffer)
|
||
|
{
|
||
|
_cbBufferSize = 0;
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_cbDataSniffMin = DATASNIFSIZE_MIN;
|
||
|
}
|
||
|
|
||
|
if (pwzUrl)
|
||
|
{
|
||
|
delete [] _pwzUrl;
|
||
|
_pwzUrl = OLESTRDuplicate(pwzUrl);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
TransAssert((_pProt && _pProtSnk));
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: COInetProt::QueryService
|
||
|
//
|
||
|
// Synopsis:
|
||
|
//
|
||
|
// Arguments: [rsid] --
|
||
|
// [riid] --
|
||
|
// [ppvObj] --
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 11-07-1996 JohannP (Johann Posch) Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT IUnknown_QueryService(IUnknown* punk, REFGUID rsid, REFIID riid, void ** ppvObj);
|
||
|
|
||
|
HRESULT COInetProt::QueryService(REFGUID rsid, REFIID riid, void ** ppvObj)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IServiceProvider::QueryService",
|
||
|
"this=%#x, %#x, %#x, %#x",
|
||
|
this, &rsid, &riid, ppvObj
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::QueryService");
|
||
|
HRESULT hr = NOERROR;
|
||
|
VDATETHIS(this);
|
||
|
TransAssert((ppvObj));
|
||
|
|
||
|
if (_pSrvPrv)
|
||
|
{
|
||
|
hr = _pSrvPrv->QueryService(rsid,riid, ppvObj);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = IUnknown_QueryService(_pProtSnk, rsid, riid, ppvObj);
|
||
|
}
|
||
|
|
||
|
TransAssert(( ((hr == E_NOINTERFACE) && !*ppvObj) || ((hr == NOERROR) && *ppvObj) ));
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::QueryService (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP COInetProt::SetPriority(LONG nPriority)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetPriority::SetPriority",
|
||
|
"this=%#x, %#x",
|
||
|
this, nPriority
|
||
|
));
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "+COInetProt::SetPriority (%ld)", nPriority);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
_nPriority = nPriority;
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::SetPriority (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP COInetProt::GetPriority(LONG * pnPriority)
|
||
|
{
|
||
|
DEBUG_ENTER((DBG_TRANS,
|
||
|
Hresult,
|
||
|
"COInetProt::IInternetPriority::GetPriority",
|
||
|
"this=%#x, %#x",
|
||
|
this, pnPriority
|
||
|
));
|
||
|
|
||
|
PerfDbgLog(tagCTransaction, this, "+COInetProt::GetPriority");
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (!pnPriority)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pnPriority = _nPriority;
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
|
||
|
PerfDbgLog1(tagCTransaction, this, "-COInetProt::GetPriority (hr:%lx)", hr);
|
||
|
|
||
|
DEBUG_LEAVE(hr);
|
||
|
return hr;
|
||
|
}
|