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.
230 lines
4.7 KiB
230 lines
4.7 KiB
/***************************************************************************\
|
|
*
|
|
* FSREAD.C
|
|
*
|
|
* Copyright (C) Microsoft Corporation 1990.
|
|
* All Rights reserved.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Program Description: File System Manager functions for read and seek
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Revision History: Created 03/12/90 by JohnSc
|
|
*
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* Known Bugs: None
|
|
*
|
|
\***************************************************************************/
|
|
#include "stdafx.h"
|
|
|
|
#include "fspriv.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* Function: FPlungeQfshr( qfshr )
|
|
*
|
|
* Purpose: Get back a qfshr->fid that was flushed
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: qfshr - fid need not be valid
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: fTruth of success
|
|
*
|
|
* args OUT: qfshr->fid is valid (or we return FALSE)
|
|
*
|
|
* globals OUT: rcFSError
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#include <io.h> // for _filelength
|
|
|
|
BOOL STDCALL FPlungeQfshr(QFSHR qfshr)
|
|
{
|
|
if (qfshr->fid == HFILE_ERROR) {
|
|
qfshr->fid = FidOpenFm((qfshr->fm),
|
|
qfshr->fsh.bFlags & FS_OPEN_READ_ONLY ?
|
|
OF_READ : OF_READWRITE);
|
|
|
|
if (qfshr->fid == HFILE_ERROR) {
|
|
SetFSErrorRc(RcGetIOError());
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* Check size of file, then reset file pointer. Certain 0-length
|
|
* files (eg con) give us no end of grief if we try to read from
|
|
* them, and since a 0-length file could not possibly be a valid FS,
|
|
* we reject the notion.
|
|
*/
|
|
|
|
if (_filelength(qfshr->fid) < sizeof(FSH)) {
|
|
SetFSErrorRc(RC_Invalid);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
SetFSErrorRc(RC_Success);
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* Function: LcbReadHf()
|
|
*
|
|
* Purpose: read bytes from a file in a file system
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: hf - file
|
|
* lcb - number of bytes to read
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: number of bytes actually read; -1 on error
|
|
*
|
|
* args OUT: qb - data read from file goes here (must be big enough)
|
|
*
|
|
* Notes: These are signed longs we're dealing with. This means
|
|
* behaviour is different from read() when < 0.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
int STDCALL LcbReadHf(HF hf, LPVOID qb, int lcb)
|
|
{
|
|
int lcbTotalRead;
|
|
FID fid;
|
|
int lifOffset;
|
|
|
|
ASSERT(hf);
|
|
QRWFO qrwfo = (QRWFO) hf;
|
|
|
|
SetFSErrorRc(RC_Success);
|
|
|
|
if (lcb < 0) {
|
|
SetFSErrorRc(RC_BadArg);
|
|
return (int) -1;
|
|
}
|
|
|
|
if (qrwfo->lifCurrent + lcb > qrwfo->lcbFile) {
|
|
lcb = qrwfo->lcbFile - qrwfo->lifCurrent;
|
|
if (lcb <= 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// position file pointer for read
|
|
|
|
if (qrwfo->bFlags & FS_DIRTY) {
|
|
fid = USE_CTMPFILE;
|
|
lifOffset = 0;
|
|
}
|
|
else {
|
|
QFSHR qfshr = (QFSHR) qrwfo->hfs;
|
|
|
|
if (!FPlungeQfshr(qfshr))
|
|
return (int) -1;
|
|
|
|
fid = qfshr->fid;
|
|
lifOffset = qrwfo->lifBase;
|
|
}
|
|
|
|
if (fid == USE_CTMPFILE) {
|
|
qrwfo->pTmpFile->seek(lifOffset + sizeof(FH) + qrwfo->lifCurrent,
|
|
SEEK_SET);
|
|
lcbTotalRead = qrwfo->pTmpFile->read(qb, lcb);
|
|
}
|
|
else {
|
|
if (LSeekFid(fid, lifOffset + sizeof(FH) + qrwfo->lifCurrent, SEEK_SET)
|
|
!= lifOffset + (int) sizeof(FH) + qrwfo->lifCurrent) {
|
|
ForceFSError();
|
|
return HFILE_ERROR;
|
|
}
|
|
|
|
// read the data
|
|
|
|
lcbTotalRead = LcbReadFid(fid, qb, lcb);
|
|
|
|
SetFSErrorRc(RcGetIOError());
|
|
}
|
|
|
|
// update file pointer
|
|
|
|
if (lcbTotalRead >= 0)
|
|
qrwfo->lifCurrent += lcbTotalRead;
|
|
|
|
return lcbTotalRead;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* Function: LSeekHf( hf, lOffset, wOrigin )
|
|
*
|
|
* Purpose: set current file pointer
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: hf - file
|
|
* lOffset - offset from origin
|
|
* wOrigin - origin (SEEK_SET, SEEK_CUR, or SEEK_END)
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: new position offset in bytes from beginning of file
|
|
* if successful, or -1L if not
|
|
*
|
|
* state OUT: File pointer is set to new position unless error occurs,
|
|
* in which case it stays where it was.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
int STDCALL LSeekHf(HF hf, int lOffset, WORD wOrigin)
|
|
{
|
|
int lif;
|
|
|
|
ASSERT(hf);
|
|
QRWFO qrwfo = (QRWFO) hf;
|
|
|
|
switch (wOrigin) {
|
|
case SEEK_SET:
|
|
lif = lOffset;
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
lif = qrwfo->lifCurrent + lOffset;
|
|
break;
|
|
|
|
case SEEK_END:
|
|
lif = qrwfo->lcbFile + lOffset;
|
|
break;
|
|
|
|
default:
|
|
lif = (int)-1;
|
|
break;
|
|
}
|
|
|
|
if (lif >= 0) {
|
|
|
|
// REVIEW: should we update qrwfo->pTmpFile.FilePtr ??
|
|
|
|
qrwfo->lifCurrent = lif;
|
|
SetFSErrorRc(RC_Success);
|
|
}
|
|
else {
|
|
lif = (int) -1;
|
|
SetFSErrorRc(RC_Invalid);
|
|
}
|
|
|
|
return lif;
|
|
}
|