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.
 
 
 
 
 
 

307 lines
7.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 <windows.h>
#include <orkin.h>
#include "_mvfs.h"
#include "imvfs.h"
#include "fspriv.h"
/***************************************************************************\
* *
* Private Functions *
* *
\***************************************************************************/
/***************************************************************************\
*
* 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 PASCAL
FPlungeQfshr( qfshr )
#ifdef SCROLL_TUNE
#pragma alloc_text(SCROLLER_TEXT, FPlungeQfshr)
#endif
QFSHR qfshr;
{
if ( qfshr->fid == fidNil )
{
qfshr->fid = FidOpenFm( (qfshr->fm),
qfshr->fsh.bFlags & fFSOpenReadOnly
? wReadOnly | wShareRead
: wReadWrite | wShareRead );
if ( qfshr->fid == fidNil )
{
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 ( LSeekFid( qfshr->fid, 0L, wSeekEnd ) < sizeof(FSH) )
{
SetFSErrorRc( rcInvalid );
return FALSE;
}
LSeekFid( qfshr->fid, 0L, wSeekSet );
}
SetFSErrorRc( rcSuccess );
return TRUE;
}
/***************************************************************************\
* *
* Public Functions *
* *
\***************************************************************************/
/***************************************************************************\
*
* 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 PASCAL
LcbReadHf( hf, qb, lcb )
#ifdef SCROLL_TUNE
#pragma alloc_text(SCROLLER_TEXT,LcbReadHf)
#endif
HF hf;
QV qb;
LONG lcb;
{
QRWFO qrwfo;
LONG lcbTotalRead;
FID fid;
LONG lifOffset;
DPF3("LcbRead hf %u, bytes %lu ", hf, lcb);
assert( hf != NULL );
qrwfo = QLockGh( hf );
assert( qrwfo != NULL );
DPF3(" current %ld ", qrwfo->lifCurrent);
SetFSErrorRc( rcSuccess );
if ( lcb < (LONG)0 )
{
SetFSErrorRc( rcBadArg );
UnlockGh( hf );
DPF3(" error, lcb<0\n");
return (LONG)-1;
}
if ( qrwfo->lifCurrent + lcb > qrwfo->lcbFile )
{
lcb = qrwfo->lcbFile - qrwfo->lifCurrent;
if ( lcb <= (LONG)0 )
{
UnlockGh( hf );
DPF3(" error, returning 0\n");
return (LONG)0;
}
}
/* position file pointer for read */
if ( qrwfo->bFlags & fFSDirty )
{
fid = qrwfo->fidT;
lifOffset = (LONG)0;
}
else
{
QFSHR qfshr = QLockGh( qrwfo->hfs );
if ( !FPlungeQfshr( qfshr ) )
{
UnlockGh( qrwfo->hfs );
UnlockGh( hf );
DPF3(" error, returning -1\n");
return (LONG)-1;
}
fid = qfshr->fid;
lifOffset = qrwfo->lifBase;
UnlockGh( qrwfo->hfs );
}
if ( LSeekFid( fid, lifOffset + sizeof( FH ) + qrwfo->lifCurrent, wSeekSet )
!=
lifOffset + sizeof( FH ) + qrwfo->lifCurrent )
{
if ( RcGetIOError() == rcSuccess )
SetFSErrorRc( rcInvalid );
else
SetFSErrorRc( RcGetIOError() );
UnlockGh( hf );
DPF3(" error 2, returning -1\n");
return (LONG)-1;
}
/* read the data */
lcbTotalRead = LcbReadFid( fid, qb, lcb );
SetFSErrorRc( RcGetIOError() );
/* update file pointer */
if ( lcbTotalRead >= 0 )
{
qrwfo->lifCurrent += lcbTotalRead;
assert(qrwfo->lifCurrent>=0);
}
UnlockGh( hf );
DPF3(" now %ld ", qrwfo->lifCurrent);
DPF3(" read %ld\n", lcbTotalRead);
return lcbTotalRead;
}
/***************************************************************************\
*
* Function: LSeekHf( hf, lOffset, wOrigin )
*
* Purpose: set current file pointer
*
* ASSUMES
*
* args IN: hf - file
* lOffset - offset from origin
* wOrigin - origin (wSeekSet, wSeekCur, or wSeekEnd)
*
* 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 PASCAL
LSeekHf(
HF hf,
LONG lOffset, /* should this be named li? */
WORD wOrigin)
{
QRWFO qrwfo;
LONG lif;
DPF3("LSeekHf %u, offs %ld, origin %u ", hf, lOffset, wOrigin);
assert( hf != NULL );
qrwfo = QLockGh( hf );
assert( qrwfo != NULL );
DPF3(" current %ld ", qrwfo->lifCurrent);
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 >= (LONG)0 )
{
qrwfo->lifCurrent = lif;
assert(qrwfo->lifCurrent>=0);
SetFSErrorRc( rcSuccess );
}
else
{
lif = (LONG)-1;
SetFSErrorRc( rcInvalid );
}
DPF3(" now %ld ", qrwfo->lifCurrent);
UnlockGh( hf );
DPF3(" returning %ld\n", lif);
return lif;
}