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.
634 lines
15 KiB
634 lines
15 KiB
//-------------------------------------------------------------------------
|
|
//
|
|
// 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 <dfheader.hxx>
|
|
#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;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|