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.
701 lines
17 KiB
701 lines
17 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|