|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: mread.hxx
//
// Contents: Multistream inline functions
//
// Classes: None.
//
// Functions: None
//
// History: 21-Apr-92 PhilipLa Created.
//
//--------------------------------------------------------------------------
#ifndef __MREAD_HXX__
#define __MREAD_HXX__
#include <difat.hxx>
#include <sstream.hxx>
//+-------------------------------------------------------------------------
//
// Function: ConvertSectAndOffset
//
// Synopsis: Convert a sector and offset into a byte offset in
// a stream.
//
// Arguments: [sect] -- Sector
// [off] -- Offset
// [uShift] -- Shift count for sectorsize
//
// Returns: Byte offset into stream.
//
// Algorithm: The byte offset is sect left-shifted uShift times,
// plus the offset, plus SECTORSIZE bytes for the
// header.
//
// History: 21-Apr-92 PhilipLa Created.
// 05-May-92 PhilipLa Changed to use << instead of *
//
//--------------------------------------------------------------------------
#ifdef LARGE_DOCFILE
inline ULONGLONG ConvertSectOffset(SECT sect, OFFSET off, USHORT uShift) { ULONGLONG ulTemp = ((ULONGLONG)(sect+1) << uShift) + (ULONG)off; msfDebugOut((DEB_ITRACE,"Convert got %Lu\n",ulTemp)); return ulTemp; } #else
inline ULONG ConvertSectOffset(SECT sect, OFFSET off, USHORT uShift) { ULONG ulTemp = ((ULONG)sect << uShift) + HEADERSIZE + (ULONG)off; msfDebugOut((DEB_ITRACE,"Convert got %lu\n",ulTemp)); return ulTemp; } #endif
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetStart, public
//
// Synopsis: Given an SID, return the starting sector
//
// Arguments: [sid] -- Sid to find start for
//
// Returns: Starting sector for given SID.
//
// History: 21-Apr-92 PhilipLa Created.
//
// Notes: This function only works for controls structures,
// not for ordinary streams.
//
//--------------------------------------------------------------------------
inline SECT CMStream::GetStart(SID sid) const { SECT sectRet = ENDOFCHAIN; msfAssert(sid > MAXREGSID);
switch (sid) { case SIDFAT: sectRet = _hdr.GetFatStart(); break; case SIDDIR: sectRet = _hdr.GetDirStart(); break; case SIDDIF: sectRet = _hdr.GetDifStart(); break; case SIDMINIFAT: sectRet = _hdr.GetMiniFatStart(); break; default: msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetStart()")); } return sectRet; }
//+---------------------------------------------------------------------------
//
// Member: CMStream::GetSize, public
//
// Synopsis: Return the size (in bytes) of a control structure chain
//
// Arguments: [sid] -- SID of chain
// [pulSize] -- Location for return
//
// Returns: Appropriate status code
//
// History: 01-Jun-94 PhilipLa Created
//
// Notes: SID must be SIDDIR or SIDMINIFAT - other structures
// do not have chains.
//
//----------------------------------------------------------------------------
#ifdef LARGE_STREAMS
inline SCODE CMStream::GetSize(SID sid, ULONGLONG *pulSize) #else
inline SCODE CMStream::GetSize(SID sid, ULONG *pulSize) #endif
{ msfAssert(((sid == SIDDIR) || (sid == SIDMINIFAT)) && aMsg("Bad SID passed to CMStream::GetSize()"));
ULONG csect;
if (SIDDIR == sid) { csect = _dir.GetNumDirSects(); } else { csect = _hdr.GetMiniFatLength(); }
*pulSize = csect * GetSectorSize(); return S_OK; }
//+---------------------------------------------------------------------------
//
// Member: CMStream::GetSect, private
//
// Synopsis: For a given SID and sect, return the location of that
// sector in the multistream.
//
// Arguments: [sid] -- SID of sector to locate
// [sect] -- Offset into chain to locate
// [psect] -- Pointer to return location.
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 22-Oct-92 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline SCODE CMStream::GetSect(SID sid, SECT sect, SECT *psect) { SCODE sc = S_OK; SECT start = ENDOFCHAIN;
switch (sid) { case SIDFAT: msfChk(_fatDif.GetFatSect(sect, &start)); break; case SIDDIF: msfChk(_fatDif.GetSect(sect, &start)); break; case SIDMINIFAT: case SIDDIR: CStreamCache *pstmc; pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat; msfChk(pstmc->GetSect(sect, &start)); break; default: msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetSect()")); }
*psect = start; Err: return sc; }
//+---------------------------------------------------------------------------
//
// Member: CMStream::GetESect, private
//
// Synopsis: For a given SID and sect, return the location of that
// sector in the multistream.
//
// Arguments: [sid] -- SID of sector to locate
// [sect] -- Offset into chain to locate
// [psect] -- Pointer to return location.
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 22-Oct-92 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
inline SCODE CMStream::GetESect(SID sid, SECT sect, SECT *psect) { SCODE sc = S_OK;
SECT start = ENDOFCHAIN; SECT sectNewStart, sectOldStart, sectNewEnd, sectOldEnd;
if ((_fBlockHeader) && (!_fBlockWrite)) { switch (sid) { case SIDFAT: SECT sectTest; msfChk(_fatDif.Remap(sect, §Test));
if (sectTest != ENDOFCHAIN) { msfChk(_fatDif.Fixup(BP_TO_P(CMStream *, _pmsShadow))); } break; case SIDMINIFAT: case SIDDIR: CStreamCache *pstmc; pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat;
if (sect != 0) { msfChk(pstmc->GetSect(sect - 1, &start)); msfChk(_fat.Remap( start, 1, 1, §OldStart, §NewStart, §OldEnd, §NewEnd)); } else { start = GetStart(sid); msfChk(_fat.Remap( start, 0, 1, §OldStart, §NewStart, §OldEnd, §NewEnd)); } //Must drop this value from the cache if it's in there.
if (sc != S_FALSE) { pstmc->EmptyRegion(sect, sect + 1); } break; case SIDDIF: break; default: msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetESect()")); } }
switch (sid) { case SIDFAT: msfChk(_fatDif.GetFatSect(sect, &start)); break; case SIDDIF: msfChk(_fatDif.GetSect(sect, &start)); break; case SIDMINIFAT: case SIDDIR: CStreamCache *pstmc; pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat;
msfChk(pstmc->GetESect(sect, &start)); break; default: msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetESect()")); }
*psect = start; Err: return sc; }
//+-------------------------------------------------------------------------
//
// Member: CMStream::SetSize, public
//
// Synposis: Sets the size of the parent LStream to match
// current Fat information.
//
// Arguments: None.
//
// Returns: Error code from call to parent LStream SetSize()
//
// Algorithm: Query the Fat for the last sector used.
// Convert that sector into a byte offset.
// Call SetSize on the parent LStream.
//
// History: 30-Jul-91 PhilipLa Created.
// 07-Jan-92 PhilipLa Converted to use handles.
// 14-May-92 AlexT Move code to CDirectStream::SetSize
//
//
//---------------------------------------------------------------------------
inline SCODE CMStream::SetSize(VOID) { SCODE sc = S_OK; #ifdef LARGE_DOCFILE
ULONGLONG ulSize; #else
ULONG ulSize; #endif
ULARGE_INTEGER cbSize;
msfDebugOut((DEB_ITRACE, "In CMStream::SetSize()\n"));
SECT sectMax;
if (!_fBlockWrite) { msfChk(_fat.GetMaxSect(§Max)); ulSize = ConvertSectOffset(sectMax, 0, GetSectorShift());
if (ulSize > _ulParentSize) { #ifdef LARGE_DOCFILE
cbSize.QuadPart = ulSize; #else
ULISet32(cbSize, ulSize); #endif
msfHChk((*_pplstParent)->SetSize(cbSize)); } }
msfDebugOut((DEB_ITRACE, "Out CMStream::SetSize()\n"));
Err: return sc; }
//+-------------------------------------------------------------------------
//
// Member: CMStream::SetMiniSize, public
//
// Synposis: Sets the size of the MiniFat storage stream to match
// current Fat information.
//
// Arguments: None.
//
// Returns: Error code from call to stream SetSize()
//
// Algorithm: Query the Fat for the last sector used.
// Convert that sector into a byte offset.
// Call SetSize on the Minifat storage stream.
//
// History: 14-May-92 AlexT Created.
//
//
//---------------------------------------------------------------------------
inline SCODE CMStream::SetMiniSize(VOID) { SCODE sc; ULONG ulNewSize;
SECT sectMax; msfChk(_fatMini.GetMaxSect(§Max)); ulNewSize = sectMax << MINISECTORSHIFT; msfChk(_pdsministream->CDirectStream::SetSize(ulNewSize));
Err: return sc; }
#endif //__MREAD_HXX__
|