diff options
Diffstat (limited to 'private/ole32/stg/docfile/tests/lkb.cxx')
-rw-r--r-- | private/ole32/stg/docfile/tests/lkb.cxx | 647 |
1 files changed, 647 insertions, 0 deletions
diff --git a/private/ole32/stg/docfile/tests/lkb.cxx b/private/ole32/stg/docfile/tests/lkb.cxx new file mode 100644 index 000000000..dcbd65007 --- /dev/null +++ b/private/ole32/stg/docfile/tests/lkb.cxx @@ -0,0 +1,647 @@ +#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; +} |