windows-nt/Source/XPSP1/NT/base/ntsetup/oobe/msobcomm/webgate.cpp

470 lines
12 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include "webgate.h"
#include "msobcomm.h"
#include "commerr.h"
extern CObCommunicationManager* gpCommMgr;
HRESULT hrCallbackSet;
/////////////////////////////////////////////////////////////////////////////
// CWebGate
CWebGate::CWebGate()
{
m_pmk = NULL;
m_pstm = NULL;
m_pbc = NULL;
m_cRef = 0;
m_bstrCacheFileName = NULL;
m_hEventComplete = NULL;
m_hEventError = NULL;
m_bstrPath = NULL;
AddRef();
}
CWebGate::~CWebGate()
{
if(m_pbc)
{
m_pbc->Release();
m_pbc = NULL;
}
FlushCache();
}
// ---------------------------------------------------------------------------
// CWebGate::QueryInterface
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::QueryInterface(REFIID riid, void** ppv)
{
HRESULT hr = E_NOINTERFACE;
*ppv = NULL;
if (riid == IID_IUnknown)
{
AddRef();
*ppv = this;
hr = S_OK;
}
else if (riid == IID_IBindStatusCallback)
{
AddRef();
*ppv = (IBindStatusCallback*)this;
hr = S_OK;
}
else if (riid == IID_IHttpNegotiate)
{
AddRef();
*ppv = (IHttpNegotiate*)this;
hr = S_OK;
}
return hr;
}
// ---------------------------------------------------------------------------
// CWebGate::AddRef
// ---------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWebGate::AddRef()
{
return m_cRef++;
}
// ---------------------------------------------------------------------------
// CWebGate::Release
// ---------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CWebGate::Release()
{
--m_cRef;
if(m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
// ---------------------------------------------------------------------------
// CWebGate::put_Path
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::put_Path(BSTR newVal)
{
BSTR bstrTemp = SysAllocString(newVal);
if (NULL == bstrTemp)
{
return E_OUTOFMEMORY;
}
if (NULL != m_bstrPath)
{
SysFreeString(m_bstrPath);
}
m_bstrPath = bstrTemp;
bstrTemp = NULL;
return S_OK;
}
void CWebGate::FlushCache()
{
if(m_bstrCacheFileName)
{
DeleteFile(m_bstrCacheFileName);
SysFreeString(m_bstrCacheFileName);
m_bstrCacheFileName = NULL;
}
}
// ---------------------------------------------------------------------------
// CWebGate::FetchPage
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::FetchPage(DWORD dwDoWait, BOOL* pbRetVal)
{
HRESULT hr = E_FAIL;
IStream* pstm = NULL;
FlushCache();
if(SUCCEEDED(CreateBindCtx(0, &m_pbc)) && m_pbc)
{
RegisterBindStatusCallback(m_pbc,
this,
0,
0L);
}
if(SUCCEEDED(CreateURLMoniker(NULL, m_bstrPath, &m_pmk)) && m_pmk && m_pbc)
{
hr = m_pmk->BindToStorage(m_pbc, 0, IID_IStream, (void**)&pstm);
m_pmk->Release();
m_pmk = NULL;
}
if (dwDoWait)
{
MSG msg;
DWORD dwRetCode;
HANDLE hEventList[2];
m_hEventComplete = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventError = CreateEvent(NULL, TRUE, FALSE, NULL);
hEventList[0] = m_hEventComplete;
hEventList[1] = m_hEventError;
while(TRUE)
{
// We will wait on window messages and also the named event.
dwRetCode = MsgWaitForMultipleObjects(2,
&hEventList[0],
FALSE,
300000, // 5 minutes
QS_ALLINPUT);
if(dwRetCode == WAIT_TIMEOUT)
{
*pbRetVal = FALSE;
break;
}
else if(dwRetCode == WAIT_OBJECT_0)
{
*pbRetVal = TRUE;
break;
}
else if(dwRetCode == WAIT_OBJECT_0 + 1)
{
*pbRetVal = FALSE;
break;
}
else
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (WM_QUIT == msg.message)
{
*pbRetVal = FALSE;
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
CloseHandle(m_hEventComplete);
CloseHandle(m_hEventError);
m_hEventComplete = NULL;
m_hEventError = NULL;
}
else
*pbRetVal = TRUE;
if(m_pbc)
{
m_pbc->Release();
m_pbc = NULL;
}
return hr;
}
// ---------------------------------------------------------------------------
// CWebGate::get_DownloadFname
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::get_DownloadFname(BSTR *pVal)
{
if (pVal == NULL)
return(E_POINTER);
*pVal = SysAllocString(m_bstrCacheFileName);
return(S_OK);
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////// IBindStatusCallback
//////
//////
//////
// ---------------------------------------------------------------------------
// CWebGate::GetBindInfo
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
{
*pgrfBINDF = BINDF_PULLDATA |
BINDF_ASYNCHRONOUS |
BINDF_ASYNCSTORAGE |
BINDF_GETNEWESTVERSION |
BINDF_SILENTOPERATION |
BINDF_NOWRITECACHE;
pbindInfo->cbSize = sizeof(BINDINFO);
pbindInfo->szExtraInfo = NULL;
pbindInfo->grfBindInfoF = 0;
pbindInfo->dwBindVerb = BINDVERB_GET;
pbindInfo->szCustomVerb = NULL;
memset(&pbindInfo->stgmedData, 0, sizeof(STGMEDIUM));
return S_OK;
}
HANDLE g_hFile = NULL;
int g_nOBEFileCount = 0;
#define HTML_TAG_BASE_REF L"<BASE HREF=\"%s\">"
// ---------------------------------------------------------------------------
// CWebGate::OnStartBinding
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnStartBinding(DWORD dwReserved, IBinding* pbinding)
{
WCHAR szTempFileFullName[MAX_PATH];
WCHAR szTempFileName[MAX_PATH];
if(g_hFile)
CloseHandle(g_hFile);
GetTempPath(MAX_PATH, szTempFileFullName);
wsprintf( szTempFileName, L"OOBE%x.htm", g_nOBEFileCount++);
lstrcat(szTempFileFullName, szTempFileName);
if((g_hFile = CreateFile(szTempFileFullName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
m_bstrCacheFileName = SysAllocString(szTempFileFullName);
return S_OK;
}
// ---------------------------------------------------------------------------
// CWebGate::OnStopBinding
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnStopBinding(HRESULT hrStatus, LPCWSTR pszError)
{
if(g_hFile)
{
CloseHandle(g_hFile);
g_hFile = NULL;
}
if(S_OK == hrStatus)
{
if(m_hEventError)
SetEvent(m_hEventComplete);
else
gpCommMgr->Fire_DownloadComplete(m_bstrCacheFileName);
}
else
{
if(m_hEventError)
SetEvent(m_hEventError);
//else
// PostMessage(gpCommMgr->m_hwndCallBack, WM_OBCOMM_ONSERVERERROR, (WPARAM)0, (LPARAM)ERR_COMM_SERVER_BINDFAILED);
}
return S_OK;
}
// ---------------------------------------------------------------------------
// CWebGate::OnDataAvailable
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnDataAvailable
(
DWORD grfBSCF,
DWORD dwSize,
FORMATETC* pfmtetc,
STGMEDIUM* pstgmed
)
{
HRESULT hr;
DWORD dwActuallyRead = 0;
DWORD dwWritten = 0;
// Get the Stream passed
if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
{
if (!m_pstm && pstgmed->tymed == TYMED_ISTREAM)
{
m_pstm = pstgmed->pstm;
if (m_pstm)
m_pstm->AddRef();
}
}
if (m_pstm && dwSize)
{
BYTE* pszBuff = (BYTE*)malloc(dwSize);
do
{
dwActuallyRead = 0;
// Read what we can
hr = m_pstm->Read(pszBuff, dwSize, &dwActuallyRead);
if (g_hFile)
{
WriteFile(g_hFile, pszBuff, dwActuallyRead, &dwWritten, NULL);
}
} while (hr == E_PENDING || hr != S_FALSE);
free(pszBuff);
}
if (BSCF_LASTDATANOTIFICATION & grfBSCF)
{
if (m_pstm)
{
m_pstm->Release();
m_pstm = NULL;
}
}
return S_OK;
}
// ---------------------------------------------------------------------------
// CWebGate::OnProgress
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
return S_OK;
}
// ---------------------------------------------------------------------------
// CWebGate::OnObjectAvailable
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnObjectAvailable(REFIID riid, IUnknown* punk)
{
return E_NOTIMPL;
}
// ---------------------------------------------------------------------------
// CWebGate::GetPriority
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::GetPriority(LONG* pnPriority)
{
return E_NOTIMPL;
}
// ---------------------------------------------------------------------------
// CWebGate::OnLowResource
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnLowResource(DWORD dwReserved)
{
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////// IHttpNegotiate
//////
//////
//////
// ---------------------------------------------------------------------------
// CWebGate::BeginningTransaction
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::BeginningTransaction
(
LPCWSTR szURL,
LPCWSTR szHeaders,
DWORD dwReserved,
LPWSTR* pszAdditionalHeaders
)
{
// Here's our opportunity to add headers
if (!pszAdditionalHeaders)
{
return E_POINTER;
}
*pszAdditionalHeaders = NULL;
return NOERROR;
}
// ---------------------------------------------------------------------------
// CWebGate::BeginningTransaction
// ---------------------------------------------------------------------------
STDMETHODIMP CWebGate::OnResponse
(
DWORD dwResponseCode,
LPCWSTR szResponseHeaders,
LPCWSTR szRequestHeaders,
LPWSTR* pszAdditionalRequestHeaders)
{
if (!pszAdditionalRequestHeaders)
{
return E_POINTER;
}
*pszAdditionalRequestHeaders = NULL;
return NOERROR;
}