Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

289 lines
6.8 KiB

#include "Status.h"
#include "..\\inc\\urlmon.hxx"
#define TIMEOUT 600000 // 10 minutes
/******************************************************************************
Constructor and destructor and helper functions
******************************************************************************/
CSilentCodeDLSink::CSilentCodeDLSink()
{
m_cRef = 1;
m_pBinding = NULL;
m_hOnStopBindingEvt = CreateEvent(NULL, TRUE, FALSE, NULL);
m_fAbort = FALSE;
}
CSilentCodeDLSink::~CSilentCodeDLSink()
{
if(m_hOnStopBindingEvt)
CloseHandle(m_hOnStopBindingEvt);
}
VOID CSilentCodeDLSink::Abort()
{
m_fAbort = TRUE;
}
HRESULT CSilentCodeDLSink::WaitTillNotified()
{
if (m_hOnStopBindingEvt == NULL)
return E_FAIL;
HRESULT hr = E_FAIL;
DWORD dwResult = 0;
const DWORD MORE_INPUT = WAIT_OBJECT_0 + 1;
MSG msg;
// Test state of event
dwResult = WaitForSingleObject(m_hOnStopBindingEvt, 0);
if (dwResult == WAIT_FAILED)
return HRESULT_FROM_WIN32(GetLastError());
// Note that MsgWaitForMultipleObjects doesn't return
// if there was previously unread input of the specified
// type in the queue. It only wakes up when input arrives.
for (dwResult = MORE_INPUT; dwResult == MORE_INPUT; )
{
if (dwResult == MORE_INPUT)
{
// more input in queue
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if (dwResult == WAIT_OBJECT_0)
{
// event has been signaled
hr = S_OK;
}
else if (dwResult == 0xFFFFFFFF)
{
// error has occurred
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
// timeout or wait abondaned
hr = E_FAIL;
}
dwResult = MsgWaitForMultipleObjects(
1, &m_hOnStopBindingEvt,
FALSE, TIMEOUT, QS_ALLINPUT);
}
if (FAILED(hr))
Abort();
return hr;
}
/******************************************************************************
IUnknown Methods
******************************************************************************/
STDMETHODIMP CSilentCodeDLSink::QueryInterface(REFIID riid, void **ppv)
{
*ppv = NULL;
if (riid == IID_IUnknown || riid == IID_IBindStatusCallback)
{
*ppv = (IBindStatusCallback*)this;
}
else if (riid == IID_ICodeInstall)
{
*ppv = (ICodeInstall*)this;
}
else if (riid == IID_IWindowForBindingUI)
{
*ppv = (IWindowForBindingUI*)this;
}
if (*ppv != NULL)
{
((IUnknown*)*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CSilentCodeDLSink::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CSilentCodeDLSink::Release()
{
if (--m_cRef)
return m_cRef;
delete this;
return 0;
}
/******************************************************************************
IBindStatusCallback Methods
******************************************************************************/
STDMETHODIMP CSilentCodeDLSink::OnStartBinding(DWORD grfBSCOption, IBinding *pib)
{
if (m_pBinding != NULL)
m_pBinding->Release();
m_pBinding = pib;
if (m_pBinding != NULL)
m_pBinding->AddRef();
if (m_fAbort)
m_pBinding->Abort();
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::GetPriority(LONG *pnPriority)
{
if (m_fAbort)
m_pBinding->Abort();
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::OnLowResource(DWORD reserved)
{
if (m_fAbort)
m_pBinding->Abort();
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::OnProgress(
ULONG ulProgress,
ULONG ulProgressMax,
ULONG ulStatusCode,
LPCWSTR szStatusText)
{
if (m_fAbort)
m_pBinding->Abort();
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::OnStopBinding(
HRESULT hresult,
LPCWSTR szError)
{
if (m_pBinding)
{
m_pBinding->Release();
m_pBinding = NULL;
}
if(m_hOnStopBindingEvt)
SetEvent(m_hOnStopBindingEvt);
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::GetBindInfo(
DWORD* pgrfBINDF,
BINDINFO* pbindInfo)
{
if (!pgrfBINDF || !pbindInfo || !pbindInfo->cbSize)
return E_INVALIDARG;
*pgrfBINDF = BINDF_ASYNCHRONOUS|BINDF_SILENTOPERATION;
// clear BINDINFO but keep its size
DWORD cbSize = pbindInfo->cbSize;
ZeroMemory( pbindInfo, cbSize );
pbindInfo->cbSize = cbSize;
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::OnDataAvailable(
DWORD grfBSCF,
DWORD dwSize,
FORMATETC *pformatetc,
STGMEDIUM *pstgmed)
{
if (m_fAbort)
m_pBinding->Abort();
return S_OK;
}
STDMETHODIMP CSilentCodeDLSink::OnObjectAvailable(
REFIID riid,
IUnknown *punk)
{
return S_OK;
}
/******************************************************************************
ICodeInstall Methods
******************************************************************************/
STDMETHODIMP CSilentCodeDLSink::GetWindow(
REFGUID rguidReason,
HWND *phwnd)
{
*phwnd = (HWND)INVALID_HANDLE_VALUE;
if (m_fAbort)
m_pBinding->Abort();
return S_FALSE;
}
STDMETHODIMP CSilentCodeDLSink::OnCodeInstallProblem(
ULONG ulStatusCode,
LPCWSTR szDestination,
LPCWSTR szSource,
DWORD dwReserved)
{
switch (ulStatusCode)
{
case CIP_ACCESS_DENIED:
case CIP_DISK_FULL:
return E_ABORT;
case CIP_OLDER_VERSION_EXISTS:
return S_OK; // always update
case CIP_NEWER_VERSION_EXISTS:
return S_FALSE; // don't update
case CIP_NAME_CONFLICT:
return E_ABORT;
case CIP_EXE_SELF_REGISTERATION_TIMEOUT:
return S_OK;
case CIP_TRUST_VERIFICATION_COMPONENT_MISSING:
return E_ABORT;
case CIP_UNSAFE_TO_ABORT:
return S_OK;
default:
return E_ABORT;
}
return S_OK;
}