Windows2000/private/inet/urlmon/wcheckcb/wcheckcb.cxx
2020-09-30 17:12:32 +02:00

320 lines
7.6 KiB
C++

#include <urlmon.h>
#include <htmlguid.h>
#include <ocidl.h>
#include "..\\inc\\urlint.h"
#include "..\\inc\\wcheckcb.h"
#include "..\\inc\\debug.h"
#include "..\\download\\cdl.h"
#include "Status.h"
// {5DFE9E81-46E4-11d0-94E8-00AA0059CE02}
const CLSID CLSID_ControlRefreshCallback = {
0x5dfe9e81, 0x46e4, 0x11d0,
0x94, 0xe8, 0x0, 0xaa, 0x0,
0x59, 0xce, 0x2
};
const static TCHAR *g_pszUpdateInfo = TEXT("UpdateInfo");
const static TCHAR *g_pszNewControlInCache = TEXT("NewControlInCache");
#define CLSID_MAX_LENGTH 50
#define CONTENT_MAX_LENGTH 1024
/*
Constructor, Destructor and helper methods
*/
CControlRefreshCallback::CControlRefreshCallback()
{
DllAddRef();
m_cRef = 1;
m_clsidCtrl = CLSID_NULL;
m_wszURL[0] = '\0';
}
CControlRefreshCallback::~CControlRefreshCallback()
{
Assert(m_cRef == 0);
DllRelease();
}
// Give this object information such as the clsid and url of the control
// it's dealing with
STDMETHODIMP CControlRefreshCallback::SetInfo(
REFCLSID rclsidControl,
LPCWSTR lpwszURL)
{
m_clsidCtrl = rclsidControl;
// copy wide strings
#ifdef UNICODE
lstrcpyW(m_wszURL, lpwszURL); // only works in Win32 mode
// fails on Win95
#else
INT i = 0;
for(; lpwszURL[i]; i++)
m_wszURL[i] = lpwszURL[i];
m_wszURL[i] = '\0';
#endif
Assert(lstrlenW(m_wszURL) == lstrlenW(lpwszURL));
return S_OK;
}
/*
HRESULT CControlRefreshCallback::UpdateControlInCacheFlag(
SCODE scReason) const
{
// update flag in registry so that IE initiates a new
// download when the control is visited.
LONG lResult = ERROR_SUCCESS;
TCHAR szKey[MAX_PATH];
LPOLESTR pwcsClsid = NULL;
BOOL fChanged = (scReason == S_OK);
lstrcpy(szKey, TEXT("CLSID\\"));
if (SUCCEEDED(::StringFromCLSID(m_clsidCtrl, &pwcsClsid)))
{
HKEY hKey = NULL;
int nLen = lstrlen(szKey);
if (WideCharToMultiByte(CP_ACP, 0, pwcsClsid, -1, szKey + nLen, MAX_PATH - nLen, NULL, NULL) > 0)
{
lstrcat(szKey, "\\");
lstrcat(szKey, g_pszUpdateInfo);
lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, szKey, 0, KEY_ALL_ACCESS, &hKey);
if (lResult == ERROR_SUCCESS)
{
DWORD dwKeySet = 0;
DWORD dwSize = sizeof(DWORD);
lResult = RegQueryValueEx(hKey, g_pszNewControlInCache, NULL, NULL, (LPBYTE)&dwKeySet, &dwSize);
if (lResult != ERROR_SUCCESS || (dwKeySet == 0 && fChanged))
{
dwKeySet = (fChanged ? 1 : 0);
lResult = RegSetValueEx(hKey, g_pszNewControlInCache, 0, REG_DWORD, (LPBYTE)&dwKeySet, sizeof(DWORD));
}
RegCloseKey(hKey);
}
}
delete pwcsClsid;
}
return (lResult == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32(lResult));
}
*/
HRESULT CControlRefreshCallback::DownloadControl() const
{
HRESULT hr = S_OK;
CSilentCodeDLSink *pscdls = NULL;
LPBC pbc = NULL;
Assert(lstrlenW(m_wszURL) > 0);
Assert(m_clsidCtrl != CLSID_NULL);
pscdls = new CSilentCodeDLSink;
if (pscdls == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
hr = CreateBindCtx(0, &pbc);
if (SUCCEEDED(hr))
hr = RegisterBindStatusCallback(pbc, pscdls, NULL, 0);
if (FAILED(hr))
goto Exit;
hr = AsyncGetClassBits(
m_clsidCtrl, NULL, NULL,
(DWORD)-1, (DWORD)-1, m_wszURL,
pbc, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
NULL, IID_IClassFactory, 0);
if (hr == MK_S_ASYNCHRONOUS)
hr = pscdls->WaitTillNotified();
RevokeBindStatusCallback(pbc, pscdls);
Exit:
if (pbc)
pbc->Release();
if (pscdls)
pscdls->Release();
return hr;
}
/*
IUnknown Methods
*/
STDMETHODIMP CControlRefreshCallback::QueryInterface(
REFIID iid,
void** ppvObject)
{
*ppvObject = NULL;
if (iid == IID_IUnknown)
{
*ppvObject = (void*)this;
}
else if (iid == IID_IPersistStream)
{
*ppvObject = (void*)(IPersistStream*)this;
}
else if (iid == IID_IWebCheckAdviseSink)
{
*ppvObject = (void*)(IWebCheckAdviseSink*)this;
}
if (*ppvObject)
{
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CControlRefreshCallback::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CControlRefreshCallback::Release()
{
if (--m_cRef)
return m_cRef;
delete this;
return 0;
}
/*
IPersistStream Methods
*/
STDMETHODIMP CControlRefreshCallback::GetClassID(CLSID* pClsssID)
{
*pClsssID = CLSID_ControlRefreshCallback;
return S_OK;
}
STDMETHODIMP CControlRefreshCallback::IsDirty(void)
{
Assert(m_clsidCtrl != CLSID_NULL);
return (m_clsidCtrl != CLSID_NULL ? S_OK : S_FALSE);
}
STDMETHODIMP CControlRefreshCallback::Load(IStream* pStm)
{
DWORD dwLen = 0;
ULONG cb = sizeof(CLSID);
ULONG cbRead = 0;
pStm->Read((void*)&m_clsidCtrl, cb, &cbRead);
Assert(cb == cbRead);
if (cb != cbRead)
goto Exit;
cb = sizeof(DWORD);
cbRead = 0;
pStm->Read((void*)&dwLen, cb, &cbRead);
Assert(cb == cbRead);
if (cb != cbRead)
goto Exit;
cb = dwLen * sizeof(WCHAR);
cbRead = 0;
pStm->Read((void*)&m_wszURL, cb, &cbRead);
Assert(cb == cbRead);
Assert((DWORD)lstrlenW(m_wszURL) == dwLen - 1);
Exit:
return (cbRead == cb ? S_OK : E_FAIL);
}
STDMETHODIMP CControlRefreshCallback::Save(IStream* pStm, BOOL fClearDirty)
{
DWORD dwLen = lstrlenW(m_wszURL) + 1; // add 1 for NULL char
ULONG cb = sizeof(CLSID);
ULONG cbSaved = 0;
pStm->Write((void*)&m_clsidCtrl, cb, &cbSaved);
Assert(cb == cbSaved);
if (cb != cbSaved)
goto Exit;
cb = sizeof(DWORD);
cbSaved = 0;
pStm->Write((void*)&dwLen, cb, &cbSaved);
Assert(cb == cbSaved);
if (cb != cbSaved)
goto Exit;
cb = dwLen * sizeof(WCHAR);
cbSaved = 0;
pStm->Write((void*)m_wszURL, cb, &cbSaved);
Assert(cb == cbSaved);
Exit:
return (cbSaved == cb ? S_OK : E_FAIL);
}
STDMETHODIMP CControlRefreshCallback::GetSizeMax(ULARGE_INTEGER* pcbSize)
{
pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD) + sizeof(m_wszURL);
return S_OK;
}
/*
IWebCheckAdviseSink Methods
*/
STDMETHODIMP CControlRefreshCallback::UpdateBegin(
long lCookie,
SCODE scReason,
BSTR lpURL)
{
return S_OK;
}
// scReason -- S_OK means changed, S_FALSE means no changes
STDMETHODIMP CControlRefreshCallback::UpdateEnd(
long lCookie,
SCODE scReason)
{
Assert(m_clsidCtrl != CLSID_NULL);
LONG lResult = ERROR_SUCCESS;
if (scReason == S_OK)
{
DownloadControl();
// UpdateControlInCacheFlag(scReason);
}
return S_OK;
}
STDMETHODIMP CControlRefreshCallback::UpdateProgress(
long lCookie,
long lCurrent,
long lMax)
{
return S_OK;
}