//+--------------------------------------------------------------------------- // // 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 #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; }