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

633 lines
15 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: resprot.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 11-07-1996 JohannP (Johann Posch) Created
//
//----------------------------------------------------------------------------
#include <eapp.h>
#include <tchar.h>
#define MAX_ID 10000
#define WITH_TAGS
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::Start
//
// Synopsis:
//
// Arguments: [pwzUrl] --
// [pTrans] --
// [pOIBindInfo] --
// [grfSTI] --
// [dwReserved] --
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::Start(LPCWSTR pwzUrl, IOInetProtocolSink *pTrans, IOInetBindInfo *pOIBindInfo,
DWORD grfSTI, DWORD dwReserved)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::Start\n", this));
HRESULT hr = NOERROR;
WCHAR wzURL[MAX_URL_SIZE];
EProtAssert((!_pProtSink && pOIBindInfo && pTrans));
EProtAssert((_pwzUrl == NULL));
hr = CBaseProtocol::Start(pwzUrl,pTrans, pOIBindInfo, grfSTI, dwReserved);
if ( (grfSTI & PI_PARSE_URL) )
{
hr = ParseAndBind(FALSE);
}
else if (hr == NOERROR)
{
// asked to go async as soon as possible
// use the switch mechanism which will \
// call back later on ::Continue
if (grfSTI & PI_FORCE_ASYNC)
{
hr = E_PENDING;
PROTOCOLDATA protdata;
protdata.grfFlags = PI_FORCE_ASYNC;
protdata.dwState = RES_STATE_BIND;
protdata.pData = 0;
protdata.cbData = 0;
_pProtSink->Switch(&protdata);
}
else
{
hr = ParseAndBind(TRUE);
}
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::Start (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::Continue
//
// Synopsis:
//
// Arguments: [pStateInfoIn] --
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::Continue(PROTOCOLDATA *pStateInfoIn)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::Continue\n", this));
HRESULT hr = E_FAIL;
EProtAssert((!pStateInfoIn->pData && pStateInfoIn->cbData && (pStateInfoIn->dwState == RES_STATE_BIND)));
if (pStateInfoIn->dwState == RES_STATE_BIND)
{
hr = ParseAndBind();
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::Continue (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::Read
//
// Synopsis:
//
// Arguments: [ULONG] --
// [ULONG] --
// [pcbRead] --
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::Read(void *pv,ULONG cb,ULONG *pcbRead)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::Read (cb:%ld)\n", this,cb));
HRESULT hr = NOERROR;
if (_cbBuffer > _cbPos)
{
ULONG cbCopy = (cb < (_cbBuffer - _cbPos)) ? cb : _cbBuffer - _cbPos;
memcpy((LPVOID)pv, ((LPBYTE)_pBuffer) + _cbPos, cbCopy);
_cbPos += cbCopy;
*pcbRead = cbCopy;
hr = (_cbPos < _cbBuffer) ? S_OK : S_FALSE;
}
else
{
hr = S_FALSE;
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::Read (pcbRead:%ld, hr:%lx)\n",this,*pcbRead, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::Seek
//
// Synopsis:
//
// Arguments: [DWORD] --
// [ULARGE_INTEGER] --
// [plibNewPosition] --
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes: WORK: not done
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::Seek\n", this));
HRESULT hr = NOERROR;
if (dwOrigin == STREAM_SEEK_SET)
{
if (dlibMove.LowPart >= 0)
{
_cbPos = dlibMove.LowPart;
if (plibNewPosition)
{
plibNewPosition->HighPart = 0;
plibNewPosition->LowPart = _cbPos;
}
}
else
{
hr = STG_E_INVALIDPOINTER;
}
}
else
{
hr = E_NOTIMPL;
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::Seek (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::LockRequest
//
// Synopsis:
//
// Arguments: [dwOptions] --
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::LockRequest(DWORD dwOptions)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::LockRequest\n", this));
HRESULT hr = NOERROR;
if (OpenTempFile())
{
DWORD dwWrite;
if (!WriteFile(_hFile, _pBuffer, _cbBuffer, &dwWrite,NULL))
{
hr = E_FAIL;
}
CloseTempFile();
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::LockRequest (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::UnlockRequest
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 10-29-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::UnlockRequest()
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::UnlockRequest\n", this));
HRESULT hr = NOERROR;
//CloseTempFile();
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::UnlockRequest (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::CResProtocol
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 1-27-96 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CResProtocol::CResProtocol(REFCLSID rclsid, IUnknown *pUnkOuter, IUnknown **ppUnkInner) : CBaseProtocol(rclsid, pUnkOuter, ppUnkInner)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::CResProtocol \n", this));
_hInst = NULL;
_cbBuffer = 0;
_pBuffer = 0;
_hgbl = 0;
_cbPos = 0;
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::CResProtocol \n", this));
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::~CResProtocol
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 11-09-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
CResProtocol::~CResProtocol()
{
if (_hgbl)
{
UnlockResource(_hgbl);
}
if (_hInst)
{
FreeLibrary(_hInst);
}
EProtDebugOut((DEB_PLUGPROT, "%p _IN/OUT CResProtocol::~CResProtocol \n", this));
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::GetResource
//
// Synopsis:
//
// Arguments: [pwzFileName] --
// [pwzResName] --
// [pwzResType] --
//
// Returns:
//
// History: 11-09-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::GetResource(LPCWSTR pwzFileName, LPCWSTR pwzResName, LPCWSTR pwzResType, LPCWSTR pwzMime)
{
EProtDebugOut((DEB_PLUGPROT, "CResProtocol::GetResource\n)"));
HRESULT hr = NOERROR;
DWORD dwError = 0;
HRSRC hrsrc;
LPSTR pszFileName = DupW2A(pwzFileName );
LPSTR pszResName = DupW2A(pwzResName );
LPSTR pszResType = DupW2A(pwzResType );
if (!pszFileName || !pszResName || !pszResType)
{
hr = E_OUTOFMEMORY;
}
else do
{
_pProtSink->ReportProgress(BINDSTATUS_SENDINGREQUEST, pwzResName);
_hInst = LoadLibraryEx(pszFileName, NULL, DONT_RESOLVE_DLL_REFERENCES);
if (!_hInst)
{
hr = INET_E_RESOURCE_NOT_FOUND;
dwError = GetLastError();
break;
}
if (!wcscmp(pwzResName, L"?"))
{
for (int i = 0 ; i < MAX_ID; i++)
{
hrsrc = FindResource(_hInst, (LPSTR)MAKEINTRESOURCE(i), pszResType);
if (hrsrc)
{
EProtDebugOut((DEB_PLUGPROT, "CResProtocol::GetResource (szResName:#%ld, wzRestype:%s\n)",i,pszResType));
i = MAX_ID;
}
}
}
else
{
hrsrc = FindResource(_hInst, pszResName, pszResType);
}
if (!hrsrc)
{
hr = INET_E_OBJECT_NOT_FOUND;
dwError = GetLastError();
break;
}
_hgbl = LoadResource(_hInst, hrsrc);
if (!_hgbl)
{
hr = INET_E_DATA_NOT_AVAILABLE;
dwError = GetLastError();
break;
}
_pBuffer = LockResource(_hgbl);
if (!_pBuffer)
{
hr = INET_E_DATA_NOT_AVAILABLE;
dwError = GetLastError();
break;
}
_cbBuffer = SizeofResource(_hInst, hrsrc);
if (_grfBindF & INTERNET_FLAG_NEED_FILE)
{
LockRequest(0);
}
#ifdef UNUSED
if (OpenTempFile())
{
DWORD dwWrite;
if (!WriteFile(_hFile, _pBuffer, _cbBuffer, &dwWrite,NULL))
{
dwError = GetLastError();
break;
}
CloseTempFile();
}
#endif //UNUSED
hr = NOERROR;
break;
} while (1);
if (dwError || (hr != NOERROR))
{
_pProtSink->ReportResult(hr, dwError, 0);
}
else
{
if (pwzMime)
{
_pProtSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, pwzMime);
}
_bscf |= BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE;
_pProtSink->ReportData(_bscf, _cbBuffer, _cbBuffer);
}
if (pszFileName)
{
delete pszFileName;
}
if (pszResName)
{
delete pszResName;
}
if (pszResType)
{
delete pszResType;
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::GetResource (hr:%lx)\n",this, hr));
return hr;
}
//+---------------------------------------------------------------------------
//
// Method: CResProtocol::ParseAndBind
//
// Synopsis:
//
// Arguments: (none)
//
// Returns:
//
// History: 11-09-1996 JohannP (Johann Posch) Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResProtocol::ParseAndBind(BOOL fBind)
{
EProtDebugOut((DEB_PLUGPROT, "%p _IN CResProtocol::ParseAndBind\n", this));
HRESULT hr = MK_E_SYNTAX;
WCHAR wzlURL[MAX_URL_SIZE];
wcscpy(wzlURL, _wzFullURL);
do
{
// check if protocol part
LPWSTR pwz = wcschr(wzlURL, ':');
pwz++;
if (wcsnicmp(pwz, L"//", 2) && wcsnicmp(pwz, L"\\\\", 2))
{
break;
}
// find the file name and path
LPWSTR pwzFileName = pwz + 2;
EProtAssert((pwzFileName));
// the file is
LPWSTR pwz1 = wcsrchr(wzlURL, '/');
if (!pwz1)
{
break;
}
*pwz1 = '\0';
pwz1++;
if (!*pwz1)
{
break;
}
#ifdef WITH_TAGS
LPWSTR pwzResDelimiter = wcschr(pwz1, '?');
if (!pwzResDelimiter)
{
break;
}
LPWSTR pwzResTag = wcsstr(pwz1, L"name:");
if (!pwzResTag)
{
break;
}
LPWSTR pwzTypeTag = wcsstr(pwz1, L"type:");
if (!pwzTypeTag)
{
break;
}
LPWSTR pwzMimeTag = wcsstr(pwz1, L"mime:");
// get the resource name
LPWSTR pwzResName = wcschr(pwzResTag, ':');
pwzResName++;
//find the end of the resource name
LPWSTR pwzResType = wcschr(pwzTypeTag, ':');
pwzResType++;
LPWSTR pwzMime = 0;
if (pwzMimeTag)
{
pwzMime = wcschr(pwzMimeTag, ':');
pwzMime++;
*pwzMimeTag = 0;
}
*pwzResTag = 0;
*pwzTypeTag = 0;
#else
// find the delimiter for the private part
LPWSTR pwzResName = wcschr(pwz1, '?');
if (!pwzResName)
{
break;
}
// get the resource name
pwzResName++;
//find the end of the resource name
LPWSTR pwzResType = wcschr(pwzResName, ' ');
if (!pwzResType)
{
break;
}
*pwzResType = '\0';
pwzResType++;
EProtDebugOut((DEB_PLUGPROT, "CResProtocol::GetResource (wzResName:%ws,pwzResType:%ws\n)",pwzResName,pwzResType));
/*
{
pwzResType = (LPWSTR)MAKEINTRESOURCE(RT_ICON);
EProtDebugOut((DEB_PLUGPROT, "CResProtocol::GetResource (wzResName:%ws,pwzResType:RT_ICON\n)",pwzResName));
}
*/
#endif //WITH_TAGS
EProtAssert(((WCHAR *)pwzFileName && (WCHAR *)pwzResName));
if (fBind && pwzFileName && pwzResName && pwzResType)
{
hr = GetResource(pwzFileName, pwzResName, pwzResType, pwzMime);
}
break;
} while (1);
if (hr == MK_E_SYNTAX)
{
_pProtSink->ReportResult(hr, 0, 0);
}
EProtDebugOut((DEB_PLUGPROT, "%p OUT CResProtocol::ParseAndBind (hr:%lx)\n", this,hr));
return hr;
}