Windows NT 4.0 source code leak
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

/***************************************************************************\
*
* 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 */