summaryrefslogtreecommitdiffstats
path: root/private/ole32/stg/docfile/tests/lkb.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'private/ole32/stg/docfile/tests/lkb.cxx')
-rw-r--r--private/ole32/stg/docfile/tests/lkb.cxx647
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;
+}