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

702 lines
17 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: filllkb.cxx
//
// Contents: IFillLockBytes and ILockBytes wrapper for async docfiles
//
// Classes:
//
// Functions:
//
// History: 19-Dec-95 PhilipLa Created
//
//----------------------------------------------------------------------------
#include "astghead.cxx"
#pragma hdrstop
#include "filllkb.hxx"
#include <valid.h>
#include "filelkb.hxx"
#define ULIGetLow(x) x.LowPart
#define UNTERMINATED 0
#define TERMINATED_NORMAL 1
#define TERMINATED_ABNORMAL 2
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::CFillLockBytes, public
//
// Synopsis: Default constructor
//
// History: 28-Dec-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CFillLockBytes::CFillLockBytes(ILockBytes *pilb)
{
_pilb = pilb;
_ulHighWater = 0;
_ulFailurePoint = 0;
_dwTerminate = UNTERMINATED;
_hNotifyEvent = INVALID_HANDLE_VALUE;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::~CFillLockBytes, public
//
// Synopsis: Destructor
//
// History: 28-Dec-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CFillLockBytes::~CFillLockBytes()
{
astgAssert(_pilb == NULL);
if (_hNotifyEvent != INVALID_HANDLE_VALUE)
{
CloseHandle(_hNotifyEvent);
}
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::Init, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 11-Jan-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE CFillLockBytes::Init(void)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Init:%p()\n", this));
_hNotifyEvent = CreateEvent(NULL,
TRUE,
FALSE,
NULL);
if (_hNotifyEvent == NULL)
{
return Win32ErrorToScode(GetLastError());
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Init\n"));
return S_OK;
}
//+--------------------------------------------------------------
//
// Member: CFillLockBytes::QueryInterface, public
//
// Synopsis: Returns an object for the requested interface
//
// Arguments: [iid] - Interface ID
// [ppvObj] - Object return
//
// Returns: Appropriate status code
//
// Modifies: [ppvObj]
//
// History: 26-Mar-92 DrewB Created
//
//---------------------------------------------------------------
//BUGBUG: Delegate to wrapped ILockBytes? Probably not.
STDMETHODIMP CFillLockBytes::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::QueryInterface(?, %p)\n",
ppvObj));
astgChk(ValidateOutPtrBuffer(ppvObj));
*ppvObj = NULL;
sc = S_OK;
if (IsEqualIID(iid, IID_IUnknown))
{
*ppvObj = (ILockBytes *)this;
CFillLockBytes::AddRef();
}
else if (IsEqualIID(iid, IID_ILockBytes))
{
*ppvObj = (ILockBytes *)this;
CFillLockBytes::AddRef();
}
else if (IsEqualIID(iid, IID_IFillLockBytes))
{
*ppvObj = (IFillLockBytes *)this;
CFillLockBytes::AddRef();
}
else
{
sc = E_NOINTERFACE;
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::QueryInterface => %p\n",
ppvObj));
Err:
return ResultFromScode(sc);
}
//+--------------------------------------------------------------
//
// Member: CFillLockBytes::AddRef, public
//
// Synopsis: Increments the ref count
//
// Returns: Appropriate status code
//
// History: 16-Mar-92 DrewB Created
//
//---------------------------------------------------------------
STDMETHODIMP_(ULONG) CFillLockBytes::AddRef(void)
{
return _pilb->AddRef();
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::Release, public
//
// History: 28-Dec-95 PhilipLa Created
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CFillLockBytes::Release(void)
{
LONG lRet;
lRet = _pilb->Release();
if (lRet == 0)
{
_pilb = NULL;
delete this;
}
return lRet;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::ReadAt, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::ReadAt(ULARGE_INTEGER ulOffset,
VOID HUGEP *pv,
ULONG cb,
ULONG *pcbRead)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::ReadAt:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else if ((_dwTerminate == TERMINATED_NORMAL) ||
(ULIGetLow(ulOffset) + cb <= _ulHighWater))
{
sc = _pilb->ReadAt(ulOffset, pv, cb, pcbRead);
}
else
{
*pcbRead = 0;
_ulFailurePoint = cb + ULIGetLow(ulOffset);
sc = STG_E_PENDING;
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::ReadAt\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::WriteAt, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::WriteAt(ULARGE_INTEGER ulOffset,
VOID const HUGEP *pv,
ULONG cb,
ULONG *pcbWritten)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::WriteAt:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else if ((_dwTerminate == TERMINATED_NORMAL) ||
(ULIGetLow(ulOffset) + cb <= _ulHighWater))
{
sc = _pilb->WriteAt(ulOffset, pv, cb, pcbWritten);
}
else
{
*pcbWritten = 0;
_ulFailurePoint = cb + ULIGetLow(ulOffset);
sc = STG_E_PENDING;
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::WriteAt\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::Flush, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::Flush(void)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Flush:%p()\n", this));
sc = _pilb->Flush();
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Flush\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::SetSize, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::SetSize(ULARGE_INTEGER cb)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::SetSize:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else if ((_dwTerminate == TERMINATED_NORMAL) ||
(ULIGetLow(cb) <= _ulHighWater))
{
sc = _pilb->SetSize(cb);
}
else
{
_ulFailurePoint = ULIGetLow(cb);
sc = STG_E_PENDING;
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::SetSize\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::LockRegion, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::LockRegion(ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::LockRegion:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else
{
sc = _pilb->LockRegion(libOffset, cb, dwLockType);
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::LockRegion\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::UnlockRegion, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::UnlockRegion(ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::UnlockRegion:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else
{
sc = _pilb->UnlockRegion(libOffset, cb, dwLockType);
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::UnlockRegion\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::Stat, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Stat:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else
{
sc = _pilb->Stat(pstatstg, grfStatFlag);
//BUGBUG: Do we need any post-processing here?
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Stat\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::FillAppend, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::FillAppend(void const *pv,
ULONG cb,
ULONG *pcbWritten)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::FillAppend:%p()\n", this));
if (_dwTerminate != UNTERMINATED)
{
sc = STG_E_TERMINATED;
}
else
{
ULONG cbWritten;
ULARGE_INTEGER uli;
uli.QuadPart = _ulHighWater;
sc = _pilb->WriteAt(uli, pv, cb, &cbWritten);
_ulHighWater += cbWritten;
if (pcbWritten != NULL)
{
*pcbWritten = cbWritten;
}
if (!PulseEvent(_hNotifyEvent))
{
sc = Win32ErrorToScode(GetLastError());
}
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::FillAppend\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::FillAt, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::FillAt(ULARGE_INTEGER ulOffset,
void const *pv,
ULONG cb,
ULONG *pcbWritten)
{
//BUGBUG: Implement
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::FillAt:%p()\n", this));
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::FillAt\n"));
return STG_E_UNIMPLEMENTEDFUNCTION;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::SetFillSize, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::SetFillSize(ULARGE_INTEGER ulSize)
{
SCODE sc;
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::SetFillSize:%p()\n", this));
if (_dwTerminate == TERMINATED_ABNORMAL)
{
sc = STG_E_INCOMPLETE;
}
else
{
sc = _pilb->SetSize(ulSize);
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::SetFillSize\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::Terminate, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 28-Dec-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CFillLockBytes::Terminate(BOOL bCanceled)
{
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::Terminate:%p()\n", this));
_dwTerminate = (bCanceled) ? TERMINATED_ABNORMAL : TERMINATED_NORMAL;
if (!SetEvent(_hNotifyEvent))
{
return Win32ErrorToScode(GetLastError());
}
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::Terminate\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::GetFailureInfo, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 11-Jan-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE CFillLockBytes::GetFailureInfo(ULONG *pulWaterMark,
ULONG *pulFailurePoint)
{
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetFailureInfo:%p()\n", this));
*pulWaterMark = _ulHighWater;
*pulFailurePoint = _ulFailurePoint;
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetFailureInfo\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::GetNotificationEvent, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 11-Jan-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
HANDLE CFillLockBytes::GetNotificationEvent(void)
{
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetNotificationEvent:%p()\n", this));
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetNotificationEvent\n"));
return _hNotifyEvent;
}
//+---------------------------------------------------------------------------
//
// Member: CFillLockBytes::GetTerminationStatus, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 11-Jan-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE CFillLockBytes::GetTerminationStatus(DWORD *pdwFlags)
{
astgDebugOut((DEB_ITRACE, "In CFillLockBytes::GetTerminationStatus:%p()\n", this));
*pdwFlags = _dwTerminate;
astgDebugOut((DEB_ITRACE, "Out CFillLockBytes::GetTerminationStatus\n"));
return S_OK;
}