648 lines
15 KiB
C++
648 lines
15 KiB
C++
|
#include <io.h>
|
||
|
#include "tsupp.hxx"
|
||
|
|
||
|
#ifndef FLAT
|
||
|
typedef LONG LARGE_INTEGER;
|
||
|
typedef ULONG ULARGE_INTEGER;
|
||
|
#endif
|
||
|
|
||
|
#define MAKE_ERR(c) \
|
||
|
MAKE_SCODE(SEVERITY_ERROR, FACILITY_STORAGE, SCODE_CODE(c))
|
||
|
|
||
|
interface CFileStream : public ILockBytes
|
||
|
{
|
||
|
public:
|
||
|
CFileStream(DWORD const grfMode, char *pszPath);
|
||
|
~CFileStream(void);
|
||
|
|
||
|
// IUnknown
|
||
|
OLEMETHOD(QueryInterface)(REFIID iid, void **ppvObj);
|
||
|
OLEMETHOD_(ULONG, AddRef)(void);
|
||
|
OLEMETHOD_(ULONG, Release)(void);
|
||
|
|
||
|
// New methods
|
||
|
OLEMETHOD(ReadAt)(ULARGE_INTEGER ulOffset,
|
||
|
VOID *pv,
|
||
|
ULONG cb,
|
||
|
ULONG *pcbRead);
|
||
|
OLEMETHOD(WriteAt)(ULARGE_INTEGER ulOffset,
|
||
|
VOID *pv,
|
||
|
ULONG cb,
|
||
|
ULONG *pcbWritten);
|
||
|
OLEMETHOD(Flush)(void);
|
||
|
OLEMETHOD(GetSize)(ULARGE_INTEGER *pcb);
|
||
|
OLEMETHOD(SetSize)(ULARGE_INTEGER cb);
|
||
|
OLEMETHOD(LockRegion)(ULARGE_INTEGER libOffset,
|
||
|
ULARGE_INTEGER cb,
|
||
|
DWORD dwLockType);
|
||
|
OLEMETHOD(UnlockRegion)(ULARGE_INTEGER libOffset,
|
||
|
ULARGE_INTEGER cb,
|
||
|
DWORD dwLockType);
|
||
|
OLEMETHOD(Stat)(STATSTG *pstatstg);
|
||
|
|
||
|
private:
|
||
|
int _fd;
|
||
|
LONG _cReferences;
|
||
|
};
|
||
|
|
||
|
SCODE CFileStream::Init(DWORD const grfMode, char *pszPath)
|
||
|
{
|
||
|
char szPath[_MAX_PATH+1];
|
||
|
SCODE sc;
|
||
|
int iOpenMode;
|
||
|
OFSTRUCT of;
|
||
|
CFileStream *pfst;
|
||
|
BOOL fAddedAtom = FALSE;
|
||
|
|
||
|
// Open the file
|
||
|
if (!P_WRITE(_df))
|
||
|
iOpenMode = OF_READ;
|
||
|
else
|
||
|
iOpenMode = OF_READWRITE;
|
||
|
if (P_DENYWRITE(_df) && !P_WRITE(_df))
|
||
|
iOpenMode |= OF_SHARE_DENY_WRITE;
|
||
|
else
|
||
|
iOpenMode |= OF_SHARE_DENY_NONE;
|
||
|
|
||
|
_hFile = OpenFile(szPath, &of, iOpenMode);
|
||
|
if (_dwStartFlags & RSF_CREATE)
|
||
|
{
|
||
|
if (_hFile < 0)
|
||
|
_hFile = OpenFile(szPath, &of, iOpenMode | OF_CREATE);
|
||
|
else if ((_dwStartFlags & RSF_TRUNCATE) == 0)
|
||
|
olErr(EH_hFile, STG_E_FILEALREADYEXISTS);
|
||
|
if (_hFile < 0)
|
||
|
{
|
||
|
olErr(EH_atPath, MAKE_ERR(of.nErrCode));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
olVerify(_lclose(_hFile) != HFILE_ERROR);
|
||
|
_hFile = OpenFile(szPath, &of, iOpenMode);
|
||
|
}
|
||
|
}
|
||
|
if (_hFile < 0)
|
||
|
olErr(EH_atPath, MAKE_ERR(of.nErrCode));
|
||
|
if (_dwStartFlags & RSF_TRUNCATE)
|
||
|
{
|
||
|
hfChkTo(EH_hFile, _llseek(_hFile, 0, STREAM_SEEK_SET));
|
||
|
hfChkTo(EH_hFile, _lwrite(_hFile, szPath, 0));
|
||
|
}
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::Init\n"));
|
||
|
return S_OK;
|
||
|
|
||
|
EH_hFile:
|
||
|
olVerify(_lclose(_hFile) != HFILE_ERROR);
|
||
|
_hFile = INVALID_FH;
|
||
|
EH_atPath:
|
||
|
if (fAddedAtom)
|
||
|
{
|
||
|
olVerify(GlobalDeleteAtom(_atPath) == 0);
|
||
|
_atPath = 0;
|
||
|
}
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::~CFileStream, public
|
||
|
//
|
||
|
// Synopsis: Destructor
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
CFileStream::~CFileStream(void)
|
||
|
{
|
||
|
char szPath[_MAX_PATH];
|
||
|
int iRt;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::~CFileStream()\n"));
|
||
|
olAssert(_cReferences == 0);
|
||
|
_sig = CFILESTREAM_SIGDEL;
|
||
|
#ifndef NOPUBLIST
|
||
|
if (!_fCleanup)
|
||
|
{
|
||
|
#endif
|
||
|
if (_hFile >= 0)
|
||
|
olVerify(_lclose(_hFile) != HFILE_ERROR);
|
||
|
if (_atPath != 0)
|
||
|
{
|
||
|
if ((_dwStartFlags & RSF_DELETEONRELEASE) &&
|
||
|
GetNext() == this && GetPrev() == this)
|
||
|
{
|
||
|
olVerify(GlobalGetAtomName(_atPath, szPath, _MAX_PATH) != 0);
|
||
|
// Delete file
|
||
|
__asm
|
||
|
{
|
||
|
mov iRt, 0
|
||
|
push ds
|
||
|
mov ax, ss
|
||
|
mov ds, ax
|
||
|
lea dx, szPath
|
||
|
mov ah, 041h
|
||
|
int 21h
|
||
|
pop ds
|
||
|
jnc del_succ
|
||
|
mov iRt, ax
|
||
|
del_succ:
|
||
|
}
|
||
|
olAssert(iRt == 0);
|
||
|
}
|
||
|
olVerify(GlobalDeleteAtom(_atPath) == 0);
|
||
|
}
|
||
|
if (GetPrev())
|
||
|
GetPrev()->SetNext(GetNext());
|
||
|
if (GetNext())
|
||
|
GetNext()->SetPrev(GetPrev());
|
||
|
#ifndef NOPUBLIST
|
||
|
}
|
||
|
#endif
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::~CFileStream\n"));
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::ReadAt, public
|
||
|
//
|
||
|
// Synopsis: Reads bytes at a specific point in a stream
|
||
|
//
|
||
|
// Arguments: [ulPosition] - Offset in file to read at
|
||
|
// [pb] - Buffer
|
||
|
// [cb] - Count of bytes to read
|
||
|
// [pcbRead] - Return of bytes read
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [pcbRead]
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::ReadAt(ULARGE_INTEGER ulPosition,
|
||
|
VOID *pb,
|
||
|
ULONG cb,
|
||
|
ULONG *pcbRead)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
ULONG cbRead = 0;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::ReadAt(%lu, %p, %lu, %p)\n",
|
||
|
ULIGetLow(ulPosition), pb, cb, pcbRead));
|
||
|
TRY
|
||
|
{
|
||
|
if (pcbRead)
|
||
|
{
|
||
|
olChk(ValidateBuffer(pcbRead, sizeof(ULONG)));
|
||
|
*pcbRead = 0;
|
||
|
}
|
||
|
olChk(ValidateBuffer(pb, cb));
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
if (ULIGetHigh(ulPosition) != 0)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
hfChk(_llseek(_hFile, (LONG)ULIGetLow(ulPosition), STREAM_SEEK_SET));
|
||
|
negChk(cbRead = _hread(_hFile, (void HUGE *)pb, (long)cb));
|
||
|
if (pcbRead)
|
||
|
*pcbRead = cbRead;
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::ReadAt => %lu\n", cbRead));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::WriteAt, public
|
||
|
//
|
||
|
// Synopsis: Writes bytes at a specific point in a stream
|
||
|
//
|
||
|
// Arguments: [ulPosition] - Offset in file
|
||
|
// [pb] - Buffer
|
||
|
// [cb] - Count of bytes to write
|
||
|
// [pcbWritten] - Return of bytes written
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [pcbWritten]
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::WriteAt(ULARGE_INTEGER ulPosition,
|
||
|
VOID *pb,
|
||
|
ULONG cb,
|
||
|
ULONG *pcbWritten)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
ULONG cbWritten = 0;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::WriteAt(%lu, %p, %lu, %p)\n",
|
||
|
ULIGetLow(ulPosition), pb, cb, pcbWritten));
|
||
|
TRY
|
||
|
{
|
||
|
if (pcbWritten)
|
||
|
{
|
||
|
olChk(ValidateBuffer(pcbWritten, sizeof(ULONG)));
|
||
|
*pcbWritten = 0;
|
||
|
}
|
||
|
olChk(ValidateBuffer(pb, cb));
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
if (ULIGetHigh(ulPosition) != 0)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
if (cb == 0)
|
||
|
olErr(EH_Err, S_OK);
|
||
|
hfChk(_llseek(_hFile, (LONG)ULIGetLow(ulPosition), STREAM_SEEK_SET));
|
||
|
negChk(cbWritten = _hwrite(_hFile, (void HUGE *)pb, (long)cb));
|
||
|
// BUGBUG - This condition can also occur for invalid buffers
|
||
|
// We may need to do buffer validation before we know which
|
||
|
// error to return
|
||
|
if (cbWritten < cb)
|
||
|
olErr(EH_Err, STG_E_MEDIUMFULL);
|
||
|
if (pcbWritten)
|
||
|
*pcbWritten = cbWritten;
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::WriteAt => %lu\n",
|
||
|
cbWritten));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::Flush, public
|
||
|
//
|
||
|
// Synopsis: Flushes buffers
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 24-Mar-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::Flush(void)
|
||
|
{
|
||
|
int iRt, fd;
|
||
|
SCODE sc;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::Flush()\n"));
|
||
|
TRY
|
||
|
{
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
fd = _hFile;
|
||
|
// Commit file
|
||
|
__asm
|
||
|
{
|
||
|
mov iRt, 0
|
||
|
mov ah, 068h
|
||
|
mov bx, fd
|
||
|
int 21h
|
||
|
jnc flush_succ
|
||
|
mov iRt, ax
|
||
|
flush_succ:
|
||
|
}
|
||
|
if (iRt != 0)
|
||
|
olErr(EH_Err, MAKE_ERR(iRt));
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::Flush\n"));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::GetSize, public
|
||
|
//
|
||
|
// Synopsis: Returns the size of the LStream
|
||
|
//
|
||
|
// Arguments: [pulSize] - Return for size
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [pulSize]
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::GetSize(ULARGE_INTEGER *pulSize)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::GetSize(%p)\n", pulSize));
|
||
|
TRY
|
||
|
{
|
||
|
olChk(ValidateBuffer(pulSize, sizeof(ULARGE_INTEGER)));
|
||
|
ULISet32(*pulSize, 0);
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
hfChk(ULISetLow(*pulSize, _llseek(_hFile, 0, STREAM_SEEK_END)));
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::GetSize => %lu\n",
|
||
|
ULIGetLow(*pulSize)));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::SetSize, public
|
||
|
//
|
||
|
// Synopsis: Sets the size of the LStream
|
||
|
//
|
||
|
// Arguments: [ulSize] - New size
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::SetSize(ULARGE_INTEGER ulSize)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::SetSize(%lu)\n",
|
||
|
ULIGetLow(ulSize)));
|
||
|
TRY
|
||
|
{
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
if (ULIGetHigh(ulSize) != 0)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
|
||
|
ULARGE_INTEGER ulCurrentSize;
|
||
|
hfChk(ULISetLow(ulCurrentSize, _llseek(_hFile, 0, STREAM_SEEK_END)));
|
||
|
|
||
|
if (ULIGetLow(ulSize) > ULIGetLow(ulCurrentSize))
|
||
|
{
|
||
|
ULONG cbWritten;
|
||
|
hfChk(_llseek(_hFile, (LONG)ULIGetLow(ulSize) - 1, STREAM_SEEK_SET));
|
||
|
hfChk(cbWritten = _lwrite(_hFile, &sc, 1));
|
||
|
|
||
|
if (cbWritten != 1)
|
||
|
olErr(EH_Err, STG_E_MEDIUMFULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hfChk(_llseek(_hFile, (LONG)ULIGetLow(ulSize), STREAM_SEEK_SET));
|
||
|
hfChk(_lwrite(_hFile, &sc, 0));
|
||
|
}
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::SetSize\n"));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::LockRegion, public
|
||
|
//
|
||
|
// Synopsis: Gets a lock on a portion of the LStream
|
||
|
//
|
||
|
// Arguments: [ulStartOffset] - Lock start
|
||
|
// [cbLockLength] - Length
|
||
|
// [dwLockType] - Exclusive/Read only
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::LockRegion(ULARGE_INTEGER ulStartOffset,
|
||
|
ULARGE_INTEGER cbLockLength,
|
||
|
DWORD dwLockType)
|
||
|
{
|
||
|
int iRt, fd;
|
||
|
SCODE sc;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::LockRegion(%lu, %lu, %lu)\n",
|
||
|
ULIGetLow(ulStartOffset), ULIGetLow(cbLockLength),
|
||
|
dwLockType));
|
||
|
TRY
|
||
|
{
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
if (!VALID_LOCKTYPE(dwLockType))
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
if (ULIGetHigh(ulStartOffset) != 0 || ULIGetHigh(cbLockLength) != 0)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
if (dwLockType != LOCK_EXCLUSIVE && dwLockType != LOCK_ONLYONCE)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
fd = _hFile;
|
||
|
__asm
|
||
|
{
|
||
|
mov ax, 5C00H
|
||
|
mov bx, fd
|
||
|
// Assumes low DWORD is first in ULARGE_INTEGER
|
||
|
mov cx, WORD PTR ulStartOffset+2
|
||
|
mov dx, WORD PTR ulStartOffset
|
||
|
mov si, WORD PTR cbLockLength+2
|
||
|
mov di, WORD PTR cbLockLength
|
||
|
mov iRt, 0
|
||
|
int 21h
|
||
|
jnc grl_noerror
|
||
|
mov iRt, ax
|
||
|
grl_noerror:
|
||
|
}
|
||
|
if (iRt != 0)
|
||
|
{
|
||
|
if (iRt == 1)
|
||
|
{
|
||
|
// INVALID_FUNCTION is impossible because the
|
||
|
// function is hardcoded. This means locking
|
||
|
// isn't supported
|
||
|
olErr(EH_Err, STG_E_SHAREREQUIRED);
|
||
|
}
|
||
|
else
|
||
|
olErr(EH_Err, MAKE_ERR(iRt));
|
||
|
}
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::LockRegion\n"));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::UnlockRegion, public
|
||
|
//
|
||
|
// Synopsis: Releases an existing lock
|
||
|
//
|
||
|
// Arguments: [ulStartOffset] - Lock start
|
||
|
// [cbLockLength] - Length
|
||
|
// [dwLockType] - Lock type
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 20-Feb-92 DrewB Created
|
||
|
//
|
||
|
// Notes: Must match an existing lock exactly
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
OLEMETHODIMP CFileStream::UnlockRegion(ULARGE_INTEGER ulStartOffset,
|
||
|
ULARGE_INTEGER cbLockLength,
|
||
|
DWORD dwLockType)
|
||
|
{
|
||
|
int iRt, fd;
|
||
|
SCODE sc;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::UnlockRegion(%lu, %lu)\n",
|
||
|
ULIGetLow(ulStartOffset), ULIGetLow(cbLockLength),
|
||
|
dwLockType));
|
||
|
TRY
|
||
|
{
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
if (!VALID_LOCKTYPE(dwLockType))
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
if (ULIGetHigh(ulStartOffset) != 0 || ULIGetHigh(cbLockLength) != 0)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
if (dwLockType != LOCK_EXCLUSIVE && dwLockType != LOCK_ONLYONCE)
|
||
|
olErr(EH_Err, STG_E_INVALIDFUNCTION);
|
||
|
fd = _hFile;
|
||
|
__asm
|
||
|
{
|
||
|
mov ax, 5C01H
|
||
|
mov bx, fd
|
||
|
// Assumes low DWORD is first in ULARGE_INTEGER
|
||
|
mov cx, WORD PTR ulStartOffset+2
|
||
|
mov dx, WORD PTR ulStartOffset
|
||
|
mov si, WORD PTR cbLockLength+2
|
||
|
mov di, WORD PTR cbLockLength
|
||
|
mov iRt, 0
|
||
|
int 21h
|
||
|
jnc rrl_noerror
|
||
|
mov iRt, ax
|
||
|
rrl_noerror:
|
||
|
}
|
||
|
if (iRt != 0)
|
||
|
olErr(EH_Err, MAKE_ERR(iRt));
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::UnlockRegion\n"));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileStream::Stat, public
|
||
|
//
|
||
|
// Synopsis: Fills in a stat buffer for this object
|
||
|
//
|
||
|
// Arguments: [pstatstg] - Buffer
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [pstatstg]
|
||
|
//
|
||
|
// History: 25-Mar-92 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
SCODE CFileStream::Stat(STATSTGW *pstatstg)
|
||
|
{
|
||
|
int iRt, fd;
|
||
|
SCODE sc;
|
||
|
unsigned short tm, dt;
|
||
|
struct tm tmFile;
|
||
|
|
||
|
olFileStOut((DEB_ITRACE, "In CFileStream::Stat(%p)\n", pstatstg));
|
||
|
TRY
|
||
|
{
|
||
|
olChkTo(EH_RetSc, ValidateBuffer(pstatstg, sizeof(STATSTGW)));
|
||
|
olChk(Validate());
|
||
|
olChk(CheckHandle());
|
||
|
ULISetHigh(pstatstg->cbSize, 0);
|
||
|
hfChk(ULISetLow(pstatstg->cbSize,
|
||
|
_llseek(_hFile, 0, STREAM_SEEK_END)));
|
||
|
fd = _hFile;
|
||
|
// Retrieve file time
|
||
|
__asm
|
||
|
{
|
||
|
mov iRt, 0
|
||
|
mov bx, fd
|
||
|
mov ax, 05700h
|
||
|
int 21h
|
||
|
mov tm, cx
|
||
|
mov dt, dx
|
||
|
jnc time_succ
|
||
|
mov iRt, ax
|
||
|
time_succ:
|
||
|
}
|
||
|
if (iRt != 0)
|
||
|
olErr(EH_Err, MAKE_ERR(iRt));
|
||
|
tmFile.tm_sec = (tm&31)*2;
|
||
|
tmFile.tm_min = (tm>>5)&63;
|
||
|
tmFile.tm_hour = (tm>>11)&31;
|
||
|
tmFile.tm_mday = dt&31;
|
||
|
tmFile.tm_mon = ((dt>>5)&15)-1;
|
||
|
tmFile.tm_year = (dt>>9)+80;
|
||
|
pstatstg->atime.dwHighDateTime = pstatstg->mtime.dwHighDateTime =
|
||
|
pstatstg->ctime.dwHighDateTime = 0;
|
||
|
pstatstg->atime.dwLowDateTime = pstatstg->mtime.dwLowDateTime =
|
||
|
pstatstg->ctime.dwLowDateTime = (DWORD)mktime(&tmFile);
|
||
|
pstatstg->grfLocksSupported = LOCK_EXCLUSIVE_FLAG |
|
||
|
LOCK_ONLYONCE_FLAG;
|
||
|
pstatstg->type = STGTY_LOCKBYTES;
|
||
|
pstatstg->grfMode = DFlagsToMode(_df);
|
||
|
olChk(GetName(&pstatstg->pwcsName));
|
||
|
}
|
||
|
CATCH(CException, e)
|
||
|
{
|
||
|
sc = e.GetErrorCode();
|
||
|
}
|
||
|
END_CATCH
|
||
|
olFileStOut((DEB_ITRACE, "Out CFileStream::Stat\n"));
|
||
|
return S_OK;
|
||
|
|
||
|
EH_Err:
|
||
|
memset(pstatstg, 0, sizeof(STATSTGW));
|
||
|
EH_RetSc:
|
||
|
return sc;
|
||
|
}
|