//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1992. // // File: ilbmem.cx // // Contents: ILockBytes memory implementation // // Classes: CMapBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- #include "headers.cxx" #pragma hdrstop #include #include #if DBG == 1 DECLARE_INFOLEVEL(ol); #endif //+------------------------------------------------------------------------- // // Member: CMapBytes::CMapBytes, public // // Synopsis: constructor // // Effects: initialize member variables // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // // Notes: Returns a fully initialized CMapBytes (ref count == 1) // //-------------------------------------------------------------------------- CMapBytes::CMapBytes(void) { _ulSize = 0; _pv = 0; _ulRef = 1; } //+------------------------------------------------------------------------- // // Member: CMapBytes::QueryInterface, public // // Arguments: [riid] - interface id // [ppvObj] - place holder for interface // // Returns: Always fails // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // // Notes: Not used in tests // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) { *ppvObj = NULL; return ResultFromScode(STG_E_INVALIDFUNCTION); } //+------------------------------------------------------------------------- // // Member: CMapBytes::AddRef, public // // Synopsis: add reference // // Returns: post reference count // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CMapBytes::AddRef(void) { AtomicInc(&_ulRef); return(_ulRef); } //+------------------------------------------------------------------------- // // Member: CMapBytes::Release, public // // Synopsis: release reference // // Effects: deletes object when reference count reaches zero // // Returns: post reference count // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CMapBytes::Release(void) { AtomicDec(&_ulRef); if (_ulRef > 0) return(_ulRef); free(_pv); delete this; return(0); } //+------------------------------------------------------------------------- // // Member: CMapBytes::ReadAt // // Synopsis: Reads bytes from memory // // Arguments: [ulOffset] - byte offset // [pv] - input buffer // [cb] - count of bytes to read // [pcbRead] - count of bytes read // // Returns: SCODE // // Modifies: pv, pcbRead // // Derivation: ILockBytes // // History: 30-Oct-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::ReadAt(ULARGE_INTEGER uliOffset, VOID HUGEP *pv, ULONG cb, ULONG *pcbRead) { olAssert(ULIGetHigh(uliOffset) == 0); ULONG ulOffset = ULIGetLow(uliOffset); if (ulOffset >= _ulSize) { // truncate read cb = 0; } else if (cb > (_ulSize - ulOffset)) { // truncate range that exceeds size cb = _ulSize - ulOffset; } memcpy(pv, (void*)(((BYTE*)_pv) + ulOffset), (size_t) cb); *pcbRead = cb; return NOERROR; } //+------------------------------------------------------------------------- // // Member: CMapBytes::WriteAt, public // // Synopsis: Writes bytes to memory // // Effects: May change memory size // // Arguments: [uliOffset] - byte offset // [pv] - output buffer // [cb] - count of bytes to write // [pcbWritten] - count of bytes written // // Returns: SCODE // // Modifies: pcbWritten // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // // Notes: This implementation doesn't write partial buffers. // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::WriteAt(ULARGE_INTEGER uliOffset, VOID const HUGEP *pv, ULONG cb, ULONG FAR *pcbWritten) { olAssert(ULIGetHigh(uliOffset) == 0); ULONG ulOffset = ULIGetLow(uliOffset); HRESULT hr; if (ulOffset + cb > _ulSize) { // increase memory buffer to accomodate write ULARGE_INTEGER uliSize; ULISetHigh(uliSize, 0); ULISetLow(uliSize, ulOffset + cb); hr = SetSize(uliSize); if (FAILED(DfGetScode(hr))) { // don't bother writing partial buffers *pcbWritten = 0; return hr; } } memcpy((void *)(((BYTE*)_pv) + ulOffset), pv, (size_t) cb); *pcbWritten = cb; return NOERROR; } //+------------------------------------------------------------------------- // // Member: CMapBytes::Flush, public // // Synopsis: flushes memory - not appropriate for this implementation // // Effects: none // // Returns: SUCCESS_SUCCESS // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::Flush(void) { return NOERROR; } //+------------------------------------------------------------------------- // // Member: CMapBytes::GetSize, public // // Synopsis: gets memory buffer size // // Arguments: [pcb] - size place holder // // Returns: SUCCESS_SUCCESS // // Modifies: pcb // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::GetSize(ULARGE_INTEGER FAR *pcb) { ULISetHigh(*pcb, 0); ULISetLow(*pcb, _ulSize); return NOERROR; } //+------------------------------------------------------------------------- // // Member: CMapBytes::SetSize, public // // Synopsis: sets memory buffer size // // Effects: may change buffer size // // Arguments: [ulicb] - new memory size // // Returns: SCODE // // Derivation: ILockBytes // // Algorithm: realloc the buffer // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::SetSize(ULARGE_INTEGER ulicb) { olAssert(ULIGetHigh(ulicb) == 0); ULONG cb = ULIGetLow(ulicb); if (cb == _ulSize) return NOERROR; void *pv = realloc(_pv, (size_t) cb); if ((cb > 0) && (pv == NULL)) { // Unable to allocate memory // Leave current memory and size alone return ResultFromScode(E_OUTOFMEMORY); } _pv = pv; _ulSize = cb; return NOERROR; } //+------------------------------------------------------------------------- // // Member: CMapBytes::LockRegion, public // // Synopsis: not supported (intentionally) // // Effects: asserts if called // // Arguments: [libOffset] - lock range offset // [cb] - lock range size // [dwLockType] - lock type // // Returns: STG_E_INVALIDFUNCTION // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { olAssert(0 && "Can't lock CMapBytes"); return ResultFromScode(STG_E_INVALIDFUNCTION); } //+------------------------------------------------------------------------- // // Member: CMapBytes::UnLockRegion, public // // Synopsis: not supported (intentionally) // // Effects: asserts if called // // Arguments: [libOffset] - lock range offset // [cb] - lock range size // [dwLockType] - lock type // // Returns: STG_E_INVALIDFUNCTION // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { olAssert(0 && "Can't unlock CMapBytes"); return ResultFromScode(STG_E_INVALIDFUNCTION); } //+------------------------------------------------------------------------- // // Member: CMapBytes::Stat, public // // Synopsis: Provide instance information // // Arguments: [pstatstg] - status buffer // [grfStatFlag] - status flags // // Returns: SCODE // // Modifies: pstatstg // // Derivation: ILockBytes // // History: 06-Nov-92 AlexT Created // // Notes: No time stamps // //-------------------------------------------------------------------------- STDMETHODIMP CMapBytes::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag) { memset(pstatstg, 0, sizeof(STATSTG)); if ((grfStatFlag & STATFLAG_NONAME) == 0) { static char const abName[] = "Memory"; HRESULT hr; if (FAILED(DfGetScode(hr = drtMemAlloc(sizeof(abName), (void **) &pstatstg->pwcsName)))) return hr; memcpy(pstatstg->pwcsName, abName, sizeof(abName)); } pstatstg->type = STGTY_LOCKBYTES; ULISetHigh(pstatstg->cbSize, 0); ULISetLow(pstatstg->cbSize, _ulSize); pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE; return NOERROR; }