Windows NT 4.0 source code leak
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

//+---------------------------------------------------------------------
//
// 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