//------------------------------------------------------------------------- // // Microsoft OLE // Copyright (C) Microsoft Corporation, 1994 - 1995. // // File: ilbfile.cxx // // Contents: Implementation of CFileBytes class methods - derived from // ILockBytes class. // // Derivation: ILockBytes // // Functions: // // History: 06-Nov-92 AlexT Created // 30-July-1996 NarindK Modified for stgbase tests. // //-------------------------------------------------------------------------- #include #pragma hdrstop #include "ilkbhdr.hxx" //------------------------------------------------------------------------- // // Member: CFileBytes::CFileBytes, public // // Synopsis: constructor // // Arguments: none // // Returns: none // // History: 30-July-96 Narindk Modified // // Notes: Returns a fully initialized CFileBytes (ref count == 1) // //-------------------------------------------------------------------------- CFileBytes::CFileBytes(void): _hf(HFILE_ERROR), _ulRef(1), _cFail0(0), _cWrite0(0), _pszFileName(NULL) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::CFileBytes")); } //------------------------------------------------------------------------- // // Member: CFileBytes::~CFileBytes, public // // Synopsis: Destructor // // Arguments: none // // Returns: none // // History: 30-July-96 Narindk Modified // // Notes: // //-------------------------------------------------------------------------- CFileBytes::~CFileBytes(void) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::~CFileBytes")); // Clean up if(NULL != _pszFileName) { delete _pszFileName; _pszFileName = NULL; } } //------------------------------------------------------------------------- // // Member: CFileBytes::Init, public // // Synopsis: Initialize function // // Arguments: [ptcPath] - Pointer to file name // [dwMode] - Mode to access/create file // // Returns: HRESULT // // History: 30-July-96 Narindk Modified // // Notes: // //-------------------------------------------------------------------------- HRESULT CFileBytes::Init(TCHAR *ptcPath, DWORD dwMode) { HRESULT hr = S_OK; LPSTR pszFileName = NULL; int bufferSize = 0; OFSTRUCT of; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Init")); if(S_OK == hr) { _pszFileName = (CHAR *) new TCHAR[_tcslen(ptcPath) + 1 * sizeof(TCHAR)]; if(NULL == _pszFileName) { hr = E_OUTOFMEMORY; } } // Copy ptcPath to _pszFileName. If NT, will need tp convert it to single // byte. if(S_OK == hr) { #if defined(_NT1X_) && !defined(_MAC) bufferSize = (_tcslen(ptcPath) + 1) * sizeof(TCHAR); if (0 == WideCharToMultiByte( CP_ACP, 0, ptcPath, -1, _pszFileName, bufferSize, NULL, NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); DH_HRCHECK(hr, TEXT("WideCharToMultiByte")) ; delete [] _pszFileName; _pszFileName = NULL; } #else _tcscpy(_pszFileName, ptcPath); #endif } if(S_OK == hr) { _hf = OpenFile(_pszFileName, &of, dwMode); if (HFILE_ERROR == _hf) { hr = E_FAIL; } } return hr; } //------------------------------------------------------------------------- // // Member: CFileBytes::FailWrite0, public // // Synopsis: Function to simulate Write failure // // Arguments: [cFail0] - failure value // // Returns: HRESULT // // History: 30-July-96 Narindk Modified // // Notes: // //------------------------------------------------------------------------- void CFileBytes::FailWrite0(int cFail0) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::FailWrite0")); _cWrite0 = 0; _cFail0 = cFail0; } //+------------------------------------------------------------------------- // // Member: CFileBytes::QueryInterface, public // // Synopsis: Given a riid, returns associated interface // // Arguments: [riid] - interface id // [ppvObj] - place holder for interface // // Returns: Always fails // // History: 30-July-96 Narindk Modified // // Notes: Not used in tests // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::QueryInterface( REFIID /* UNREF riid */, LPVOID FAR *ppvObj) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::QueryInterface")); *ppvObj = NULL; return STG_E_INVALIDFUNCTION; } //+------------------------------------------------------------------------- // // Member: CFileBytes::AddRef, public // // Synopsis: add reference // // Arguments: none // // Returns: ULONG post reference count // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CFileBytes::AddRef(void) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::AddRef")); _ulRef++; DH_TRACE( (DH_LVL_ADDREL, TEXT("AddRef - Object %lx, refs: %ld \n"), this, _ulRef)); return _ulRef; } //+------------------------------------------------------------------------- // // Member: CFileBytes::Release, public // // Synopsis: release reference // closes file when reference count reaches zero // // Arguments: void // // Returns: ULONG post reference count // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CFileBytes::Release(void) { ULONG ulTmp = 0; DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::Release")); if ( _ulRef > 0 ) { ulTmp = --_ulRef ; DH_TRACE( (DH_LVL_ADDREL, TEXT("Release - Object %lx, refs: %ld \n"), this, _ulRef)); if (0 == _ulRef) { if (HFILE_ERROR != _hf) { _lclose(_hf); } DH_TRACE( (DH_LVL_ADDREL, TEXT("Release - Deleting Object %lx"), this)); delete this; } } else { DH_ASSERT(!"Release() called on pointer with 0 refs!") ; ulTmp = 0 ; } return ulTmp; } //+------------------------------------------------------------------------- // // Member: CFileBytes::ReadAt // // Synopsis: Reads bytes from file // // Arguments: [ulOffset] - byte offset // [pv] - input buffer // [cb] - count of bytes to read // [pcbRead] - count of bytes read // // Returns: HRESULT // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::ReadAt( ULARGE_INTEGER uliOffset, VOID HUGEP *pv, ULONG cb, ULONG *pcbRead) { HRESULT hr = S_OK; LONG lOffset = 0; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::ReadAt")); DH_ASSERT(0 == ULIGetHigh(uliOffset)); DH_ASSERT(HFILE_ERROR != _hf); if(S_OK == hr) { lOffset = (LONG) ULIGetLow(uliOffset); _llseek(_hf, lOffset, 0); *pcbRead = _hread(_hf, pv, cb); if (HFILE_ERROR == *pcbRead) { *pcbRead = 0; hr = STG_E_READFAULT; } } return hr; } //+------------------------------------------------------------------------- // // Member: CFileBytes::WriteAt, public // // Synopsis: Writes bytes to file // // Arguments: [uliOffset] - byte offset // [pv] - output buffer // [cb] - count of bytes to write // [pcbWritten] - count of bytes written // // Returns: HRESULT // // History: 30-July-96 Narindk Modified // // Notes: This implementation doesn't write partial buffers. // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::WriteAt( ULARGE_INTEGER uliOffset, VOID const HUGEP *pv, ULONG cb, ULONG FAR *pcbWritten) { HRESULT hr = S_OK; LONG lOffset = 0; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::WriteAt")); DH_ASSERT(0 == ULIGetHigh(uliOffset)); DH_ASSERT(HFILE_ERROR != _hf); if(S_OK == hr) { lOffset = (LONG) ULIGetLow(uliOffset); if (0 == lOffset) { // Check for simulated write failures if (_cFail0 > 0) { _cWrite0++; if (_cWrite0 == _cFail0) { hr = STG_E_WRITEFAULT; } } } } if(S_OK == hr) { _llseek(_hf, lOffset, 0); *pcbWritten = _hwrite(_hf, (char *) pv, cb); if (HFILE_ERROR == *pcbWritten) { *pcbWritten = 0; hr = STG_E_WRITEFAULT; } } return hr; } //+------------------------------------------------------------------------- // // Member: CFileBytes::Flush, public // // Synopsis: flushes file; not implemented, always return S_OK // // Effects: none // // Returns: S_OK // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::Flush(void) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Flush")); DH_ASSERT(HFILE_ERROR != _hf); return hr; } //+------------------------------------------------------------------------- // // Member: CFileBytes::SetSize, public // // Synopsis: sets memory buffer size. May change buffer size // // Arguments: [ulicb] - new memory size // // Returns: HRESULT // // Algorithm: realloc the buffer // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::SetSize(ULARGE_INTEGER ulicb) { HRESULT hr = S_OK; BYTE ch = 0; ULONG cb = 0; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::SetSize")); DH_ASSERT(0 == ULIGetHigh(ulicb)); DH_ASSERT(HFILE_ERROR != _hf); if(S_OK == hr) { cb = ULIGetLow(ulicb); _llseek(_hf, cb, 0); _hwrite(_hf, (char *) &ch, 0); } return hr; } //+------------------------------------------------------------------------- // // Member: CFileBytes::LockRegion, public // // Synopsis: not supported (intentionally) // // Arguments: [libOffset] - lock range offset // [cb] - lock range size // [dwLockType] - lock type // // Returns: STG_E_INVALIDFUNCTION // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::LockRegion( ULARGE_INTEGER /* UNREF libOffset */, ULARGE_INTEGER /* UNREF cb */, DWORD /* UNREF dwLockType */) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::LockRegion")); DH_ASSERT(0 && !TEXT("Can't lock CFileBytes")); DH_ASSERT(HFILE_ERROR != _hf); return STG_E_INVALIDFUNCTION; } //+------------------------------------------------------------------------- // // Member: CFileBytes::UnLockRegion, public // // Synopsis: not supported (intentionally) // // Arguments: [libOffset] - lock range offset // [cb] - lock range size // [dwLockType] - lock type // // Returns: STG_E_INVALIDFUNCTION // // History: 30-July-96 Narindk Modified // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::UnlockRegion( ULARGE_INTEGER /* UNREF libOffset */, ULARGE_INTEGER /* cb */, DWORD /* dwLockType */) { DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::UnlockRegion")); DH_ASSERT(0 && !TEXT("Can't Unlock CFileBytes")); DH_ASSERT(HFILE_ERROR != _hf); return STG_E_INVALIDFUNCTION; } //+------------------------------------------------------------------------- // // Member: CFileBytes::Stat, public // // Synopsis: Provide instance information // // Arguments: [pstatstg] - status buffer // [grfStatFlag] - status flags // // Returns: HRESULT // // History: 30-July-96 Narindk Modified // // Notes: No time stamps. Modifies pstatstg. // //-------------------------------------------------------------------------- STDMETHODIMP CFileBytes::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag) { HRESULT hr = S_OK; DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("CFileBytes::Stat")); DH_ASSERT(HFILE_ERROR != _hf); if(S_OK == hr) { memset(pstatstg, 0, sizeof(STATSTG)); if (0 == (grfStatFlag & STATFLAG_NONAME)) { // MakeUnicode String doesn't do any parameter validation, so use // it correctly. #ifdef _MAC _tcscpy(pstatstg->pwcsName, _pszFileName); #else hr = MakeUnicodeString(_pszFileName, &(pstatstg->pwcsName)); #endif DH_HRCHECK(hr, TEXT("TStrToWstr")) ; if (NULL == pstatstg->pwcsName) { hr = E_OUTOFMEMORY; } } } if(S_OK == hr) { pstatstg->type = STGTY_LOCKBYTES; ULISet32(pstatstg->cbSize, _llseek(_hf, 0, 2)); pstatstg->grfMode = STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE; } return hr; } //------------------------------------------------------------------------- // // Member: CFileBytes::GetSize, public // // Synopsis: Function to return size // // Arguments: none // // Returns: ULARGE_INTEGER // // History: 30-July-96 Narindk Created // // Notes: // //------------------------------------------------------------------------- ULARGE_INTEGER CFileBytes::GetSize() { HRESULT hr = S_OK; ULARGE_INTEGER ulSize; DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("CFileBytes::GetSize")); DH_ASSERT(HFILE_ERROR != _hf); ulSize.LowPart = GetFileSize((HANDLE) _hf, &(ulSize.HighPart)); if(0xFFFFFFFF == ulSize.LowPart) { hr = HRESULT_FROM_WIN32(GetLastError()); DH_HRCHECK(hr, TEXT("GetFileSize")) ; } DH_ASSERT(0xFFFFFFFF != ulSize.LowPart); return ulSize; } //+-------------------------------------------------------------------------