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.
239 lines
5.0 KiB
239 lines
5.0 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 "help.h"
|
|
#include "inc\fspriv.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* 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
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL STDCALL FPlungeQfshr(QFSHR qfshr)
|
|
{
|
|
if (qfshr->fid == HFILE_ERROR) {
|
|
qfshr->fid = FidOpenFm((qfshr->fm), (WORD)
|
|
(qfshr->fsh.bFlags & fFSOpenReadOnly ? 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 (_llseek(qfshr->fid, 0, FILE_END) < sizeof(FSH)) {
|
|
SetFSErrorRc(rcInvalid);
|
|
return FALSE;
|
|
}
|
|
else
|
|
_llseek(qfshr->fid, 0, FILE_BEGIN);
|
|
}
|
|
|
|
SetFSErrorRc(rcSuccess);
|
|
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.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LONG STDCALL LcbReadHf(HF hf, LPVOID qb, LONG lcb)
|
|
{
|
|
QRWFO qrwfo;
|
|
LONG lcbTotalRead;
|
|
FID fid;
|
|
LONG lifOffset;
|
|
|
|
ASSERT(hf != NULL);
|
|
qrwfo = PtrFromGh(hf);
|
|
|
|
SetFSErrorRc(rcSuccess);
|
|
|
|
if (lcb < 0) {
|
|
SetFSErrorRc(rcBadArg);
|
|
return (LONG) -1;
|
|
}
|
|
|
|
if (qrwfo->lifCurrent + lcb > qrwfo->lcbFile) {
|
|
lcb = qrwfo->lcbFile - qrwfo->lifCurrent;
|
|
if (lcb <= (LONG) 0) {
|
|
return (LONG) 0;
|
|
}
|
|
}
|
|
|
|
// position file pointer for read
|
|
|
|
if (qrwfo->bFlags & fFSDirty) {
|
|
fid = qrwfo->fidT;
|
|
lifOffset = (LONG) 0;
|
|
}
|
|
else {
|
|
QFSHR qfshr = PtrFromGh(qrwfo->hfs);
|
|
|
|
if (!FPlungeQfshr(qfshr)) {
|
|
return (LONG) -1;
|
|
}
|
|
|
|
fid = qfshr->fid;
|
|
lifOffset = qrwfo->lifBase;
|
|
}
|
|
#ifdef _X86_
|
|
if (LSeekFid(fid, lifOffset + sizeof(FH) + qrwfo->lifCurrent, SEEK_SET)
|
|
!=
|
|
lifOffset + (LONG) sizeof(FH) + qrwfo->lifCurrent) {
|
|
if (RcGetIOError() == rcSuccess)
|
|
SetFSErrorRc(rcInvalid);
|
|
else
|
|
SetFSErrorRc(RcGetIOError());
|
|
return (LONG) -1;
|
|
}
|
|
#else
|
|
{ LONG lcbSizeofFH;
|
|
lcbSizeofFH = LcbStructSizeSDFF( ISdffFileIdHfs( qrwfo->hfs ), SE_FH);
|
|
|
|
if (LSeekFid(fid, lifOffset + lcbSizeofFH + qrwfo->lifCurrent, SEEK_SET)
|
|
!=
|
|
lifOffset + (LONG) lcbSizeofFH + qrwfo->lifCurrent) {
|
|
if (RcGetIOError() == rcSuccess)
|
|
SetFSErrorRc(rcInvalid);
|
|
else
|
|
SetFSErrorRc(RcGetIOError());
|
|
return (LONG) -1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// 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.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
LONG STDCALL LSeekHf(HF hf, LONG lOffset, WORD wOrigin)
|
|
{
|
|
QRWFO qrwfo;
|
|
LONG lif;
|
|
|
|
ASSERT(hf != NULL);
|
|
qrwfo = PtrFromGh(hf);
|
|
|
|
switch (wOrigin) {
|
|
case wFSSeekSet:
|
|
lif = lOffset;
|
|
break;
|
|
|
|
case wFSSeekCur:
|
|
lif = qrwfo->lifCurrent + lOffset;
|
|
break;
|
|
|
|
case wFSSeekEnd:
|
|
lif = qrwfo->lcbFile + lOffset;
|
|
break;
|
|
|
|
default:
|
|
lif = (LONG)-1;
|
|
break;
|
|
|
|
}
|
|
|
|
if (lif >= 0) {
|
|
qrwfo->lifCurrent = lif;
|
|
SetFSErrorRc(rcSuccess);
|
|
}
|
|
else {
|
|
lif = (LONG) -1;
|
|
SetFSErrorRc(rcInvalid);
|
|
}
|
|
|
|
return lif;
|
|
}
|
|
|
|
/* EOF */
|