mirror of https://github.com/lianthony/NT4.0
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.
459 lines
11 KiB
459 lines
11 KiB
//+---------------------------------------------------------------------
|
|
//
|
|
// File: fatstg.hxx
|
|
//
|
|
// Contents: IStream on top of a DOS (non-docfile) file
|
|
//
|
|
//----------------------------------------------------------------------
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
#define _hread _lread
|
|
#define _hwrite _lwrite
|
|
|
|
|
|
//REVIEW: this file is substantially incomplete!
|
|
//REVIEW: this will either be completed or (hopefully) replaced!
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Class: FatStream
|
|
//
|
|
// Purpose: Provide an IStream interface to a DOS file
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
class FatStream: public IStream
|
|
{
|
|
friend HRESULT CreateStreamOnFile(LPCSTR, DWORD, LPSTREAM FAR* ppstrm);
|
|
|
|
public:
|
|
DECLARE_STANDARD_IUNKNOWN(FatStream);
|
|
|
|
// *** IStream methods ***
|
|
STDMETHOD(Read) (VOID HUGEP *pv, ULONG cb, ULONG FAR *pcbRead);
|
|
STDMETHOD(Write) (VOID const HUGEP *pv, ULONG cb, ULONG FAR *pcbWritten);
|
|
STDMETHOD(Seek) (LARGE_INTEGER dlibMove, DWORD dwOrigin,
|
|
ULARGE_INTEGER FAR *plibNewPosition);
|
|
STDMETHOD(SetSize) (ULARGE_INTEGER libNewSize);
|
|
STDMETHOD(CopyTo) (IStream FAR *pstm, ULARGE_INTEGER cb,
|
|
ULARGE_INTEGER FAR *pcbRead, ULARGE_INTEGER FAR *pcbWritten);
|
|
STDMETHOD(Commit) (DWORD grfCommitFlags);
|
|
STDMETHOD(Revert) (void);
|
|
STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
|
|
DWORD dwLockType);
|
|
STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
|
|
DWORD dwLockType);
|
|
STDMETHOD(Stat) (STATSTG FAR *pstatstg, DWORD grfStatFlag);
|
|
STDMETHOD(Clone)(IStream FAR * FAR *ppstm);
|
|
|
|
private:
|
|
FatStream(HFILE hfile)
|
|
{ _hfile = hfile; }
|
|
|
|
~FatStream() // destroying the stream closes the file.
|
|
{ _lclose(_hfile); }
|
|
|
|
HFILE _hfile;
|
|
};
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: CreateStreamOnFile, public
|
|
//
|
|
// Synopsis: Provides an IStream interface to a DOS file
|
|
//
|
|
// Arguments: [lpstrFile] -- the DOS file
|
|
// [stgm] -- the storage modes for opening
|
|
// [ppstrm] -- where the opened stream is returned
|
|
//
|
|
// Returns: Success iff the stream interface could be provided
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CreateStreamOnFile(LPCSTR lpstrFile, DWORD stgm, LPSTREAM FAR* ppstrm)
|
|
{
|
|
HRESULT r;
|
|
HFILE hfile;
|
|
OFSTRUCT ofstruct;
|
|
|
|
FatStream *pStrm;
|
|
|
|
if ((stgm & 0x0000FFFF) != stgm)
|
|
{
|
|
#if DBG
|
|
DOUT(L"o2base/fatstg/CreateStreamOnFile E_INVALIDARG\r\n");
|
|
#endif
|
|
r = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
|
|
hfile = OpenFile(lpstrFile, &ofstruct, (UINT)(stgm & 0x0000FFFF));
|
|
if (hfile != HFILE_ERROR)
|
|
{
|
|
|
|
//pStrm = new (NullOnFail) FatStream(hfile);
|
|
pStrm = new FatStream(hfile);
|
|
if (pStrm!=NULL)
|
|
{
|
|
*ppstrm = (IStream *)pStrm;
|
|
r = NOERROR;
|
|
}
|
|
else
|
|
{
|
|
DOUT(L"o2base/fatstg/CreateStreamOnFile failed\r\n");
|
|
r = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
#if DBG
|
|
DOUT(L"o2base/fatstg/CreateStreamOnFile E_FAIL\r\n");
|
|
#endif
|
|
r = E_FAIL;
|
|
}
|
|
}
|
|
return(r);
|
|
}
|
|
|
|
IMPLEMENT_STANDARD_IUNKNOWN(FatStream)
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::QueryInterface
|
|
//
|
|
// Synopsis: method from IUnknown interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::QueryInterface(REFIID riid, LPVOID FAR* ppv)
|
|
{
|
|
if (IsEqualIID(riid,IID_IUnknown))
|
|
{
|
|
*ppv = (LPVOID)this;
|
|
}
|
|
else if (IsEqualIID(riid,IID_IStream))
|
|
{
|
|
*ppv = (LPVOID)(LPSTREAM)this;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
#if DBG
|
|
DOUT(L"FatStream::QueryInterface E_NOINTERFACE\r\n");
|
|
#endif
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
// Important: we must addref on the pointer that we are returning,
|
|
// because that pointer is what will be released!
|
|
((IUnknown FAR*) *ppv)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Read
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Read(VOID HUGEP *pv,
|
|
ULONG cb,
|
|
ULONG FAR *pcbRead)
|
|
{
|
|
ULONG cbRead = _hread(_hfile, pv, cb);
|
|
if (pcbRead != NULL)
|
|
*pcbRead = cbRead;
|
|
|
|
if (cbRead == -1)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Read E_FAIL\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Write
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Write(VOID const HUGEP *pv,
|
|
ULONG cb,
|
|
ULONG FAR *pcbWritten)
|
|
{
|
|
// we have to cast to char ptr because Win32 uses LPCSTR as
|
|
// 2nd argument to _hwrite.
|
|
ULONG cbWritten = _hwrite(_hfile, (char const HUGEP *)pv, cb);
|
|
if (pcbWritten != NULL)
|
|
*pcbWritten = cbWritten;
|
|
|
|
if (cbWritten == -1)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Write E_FAIL\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Seek
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Seek(LARGE_INTEGER dlibMove,
|
|
DWORD dwOrigin,
|
|
ULARGE_INTEGER FAR *plibNewPosition)
|
|
{
|
|
if (dlibMove.HighPart != 0 && dlibMove.HighPart != -1)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Seek E_FAIL\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
|
|
// cast below is bad under certain circumstances!
|
|
LONG newpos = _llseek(_hfile, (LONG)dlibMove.LowPart, (int)dwOrigin);
|
|
if (plibNewPosition != NULL)
|
|
ULISet32(*plibNewPosition, newpos);
|
|
|
|
if (newpos == HFILE_ERROR)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Seek E_FAIL(2)\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::SetSize
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::SetSize(ULARGE_INTEGER libNewSize)
|
|
{
|
|
if (libNewSize.HighPart != 0)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::SetSize E_FAIL\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
|
|
// below is a bad cast under certain circumstances!
|
|
if (_chsize(_hfile, (long)libNewSize.LowPart) == 0)
|
|
{
|
|
return NOERROR;
|
|
}
|
|
else
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::SetSize E_FAIL(2)\r\n");
|
|
#endif
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::CopyTo
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::CopyTo(IStream FAR *pstm,
|
|
ULARGE_INTEGER cb,
|
|
ULARGE_INTEGER FAR *pcbRead,
|
|
ULARGE_INTEGER FAR *pcbWritten)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::CopyTo E_NOTIMPL\r\n");
|
|
#endif
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Commit
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Commit(DWORD grfCommitFlags)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Commit STG_E_INVALIDFUNCTION\r\n");
|
|
#endif
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Revert
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Revert(void)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Revert STG_E_INVALIDFUNCTION\r\n");
|
|
#endif
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::LockRegion
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::LockRegion(ULARGE_INTEGER libOffset,
|
|
ULARGE_INTEGER cb,
|
|
DWORD dwLockType)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::LockRegion STG_E_INVALIDFUNCTION\r\n");
|
|
#endif
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::UnlockRegion
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP FatStream::UnlockRegion(ULARGE_INTEGER libOffset,
|
|
ULARGE_INTEGER cb,
|
|
DWORD dwLockType)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::UnLockRegion STG_E_INVALIDFUNCTION\r\n");
|
|
#endif
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Stat
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Stat(STATSTG FAR *pstatstg, DWORD grfStatFlag)
|
|
{
|
|
|
|
if (pstatstg != NULL)
|
|
{
|
|
pstatstg->pwcsName = NULL;
|
|
pstatstg->type = STGTY_STREAM;
|
|
ULISet32(pstatstg->cbSize,_filelength(_hfile));
|
|
//pstatstg->mtime = fstatus.m_mtime;
|
|
//pstatstg->ctime = fstatus.m_ctime;
|
|
//pstatstg->atime = fstatus.m_atime;
|
|
//pstatstg->grfMode = ;
|
|
pstatstg->grfLocksSupported = 0; // no locking supported
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Member: FatStream::Clone
|
|
//
|
|
// Synopsis: method of IStream interface
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
FatStream::Clone(IStream FAR * FAR *ppstm)
|
|
{
|
|
#if DBG
|
|
DOUT(L"FatStream::Clone E_NOTIMPL\r\n");
|
|
#endif
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
#if 0
|
|
//REVIEW: this could get integrated into CopyTo!
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: CopyFileIntoStream
|
|
//
|
|
//---------------------------------------------------------------
|
|
void
|
|
CopyFileIntoStream( LPSTREAM lpStream, int fh )
|
|
{
|
|
int sChunk = 4096;
|
|
//LPBYTE pbBuffer = new (NullOnFail) BYTE[sChunk];
|
|
LPBYTE pbBuffer = new BYTE[sChunk];
|
|
for(int i = 0; i < 8; i++)
|
|
{
|
|
if(pbBuffer != NULL)
|
|
break;
|
|
sChunk >>= 1;
|
|
//pbBuffer = new (NullOnFail) BYTE[sChunk];
|
|
pbBuffer = new BYTE[sChunk];
|
|
}
|
|
if(pbBuffer == NULL)
|
|
return; // fatal error condition
|
|
int sRead;
|
|
ULONG ulWritten;
|
|
for( ; (sRead = _lread( fh, pbBuffer, sChunk )) >= 0; )
|
|
{
|
|
lpStream->Write( (VOID FAR *)pbBuffer, (ULONG)sRead, &ulWritten );
|
|
if(sRead < sChunk)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(pbBuffer != NULL)
|
|
delete pbBuffer;
|
|
}
|
|
#endif
|