/***************************************************************************\ * * 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 * \***************************************************************************/ 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 (GetFileSize((HANDLE) qfshr->fid, NULL) < 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; }