|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 1996.
//
// File: msf.hxx
//
// Contents: Header for MSF for external use
//
// Classes: CMStream - Main multi-stream object
//
//--------------------------------------------------------------------------
#ifndef __MSF_HXX__
#define __MSF_HXX__
#include "ref.hxx"
#include "error.hxx"
#define SECURE
#define msfErr(l, e) ErrJmp(msf, l, e, sc)
#define msfChkTo(l, e) if (FAILED(sc = (e))) msfErr(l, sc) else 1
#define msfHChkTo(l, e) if (FAILED(sc = GetScode(e))) msfErr(l, sc) else 1
#define msfChk(e) msfChkTo(Err, e)
#define msfHChk(e) msfHChkTo(Err, e)
#define msfMemTo(l, e) if (!(e)) msfErr(l, STG_E_INSUFFICIENTMEMORY) else 1
#define msfMem(e) msfMemTo(Err, e)
#if DEVL == 1
DECLARE_DEBUG(msf);
#endif
#if DBG == 1
#define msfDebugOut(x) msfInlineDebugOut x
#include <assert.h>
#define msfAssert(e) assert(e)
#define msfVerify(e) assert(e)
#else
#define msfDebugOut(x)
#define msfAssert(e)
#define msfVerify(e) (e)
#endif
// MSF entry flags type
typedef DWORD MSENTRYFLAGS;
// MEF_ANY refers to all entries regardless of type
const MSENTRYFLAGS MEF_ANY = 255;
//CWCSTREAMNAME is the maximum length (in wide characters) of
// a stream name.
const USHORT CWCSTREAMNAME = 32;
//OFFSET and SECT are used to determine positions within
//a file.
typedef SHORT OFFSET; typedef ULONG SECT;
#define MAXINDEXTYPE ULONG
//FSINDEX and FSOFFSET are used to determine the position of a sector
//within the Fat.
typedef ULONG FSINDEX; typedef USHORT FSOFFSET;
// DIRINDEX and DIROFFSET and used to index directory tables
typedef ULONG DIRINDEX; typedef USHORT DIROFFSET;
//Size of a mini sector in bytes.
const USHORT MINISECTORSHIFT = 6; const USHORT MINISECTORSIZE = 1 << MINISECTORSHIFT; //64
//Maximum size of a ministream.
const USHORT MINISTREAMSIZE=4096;
//Size of a single sector in bytes.
const USHORT SECTORSHIFT512 = 9; const USHORT SECTORSHIFT4K = 12;
//Size of header.
const USHORT HEADERSIZE = 1 << SECTORSHIFT512; //512
//Size of single DirEntry
const USHORT DIRENTRYSIZE = HEADERSIZE / 4;
//
// Predefined Sector Indices
//
const SECT MAXREGSECT = 0xFFFFFFFB; const SECT DIFSECT=0xFFFFFFFC; const SECT FATSECT=0xFFFFFFFD; const SECT ENDOFCHAIN=0xFFFFFFFE; const SECT FREESECT=0xFFFFFFFF;
//Start of Fat chain
const SECT SECTFAT = 0;
//Start of directory chain
const SECT SECTDIR = 1;
class CDirectStream; class CMSFIterator; class CMSFPageTable;
class CStreamCache;
#define FLUSH_ILB TRUE
// ----------------------
// Byte swapping routines
// ----------------------
#include "../byteordr.hxx"
#include "dfmsp.hxx"
class CMStream;
#include "header.hxx"
#include "fat.hxx"
#include "dir.hxx"
#include "difat.hxx"
//
// Predefined Stream ID's
//
//Return code for Directory
//Used to signal a 'Stream Not Found' condition
const SID NOSTREAM=0xFFFFFFFF;
//Stream ID of FAT chain
const SID SIDFAT=0xFFFFFFFE;
//Stream ID of Directory chain
const SID SIDDIR=0xFFFFFFFD;
//SID for root level object
const SID SIDROOT = 0;
//SID of MiniFat
const SID SIDMINIFAT = 0xFFFFFFFC;
//SID of Double-indirect Fat
const SID SIDDIF = 0xFFFFFFFB;
//Stream ID for MiniStream chain
const SID SIDMINISTREAM = SIDROOT;
//SID of the largest regular (non-control) SID
const SID MAXREGSID = 0xFFFFFFFA;
extern "C" WCHAR const wcsContents[];
//+----------------------------------------------------------------------
//
// Class: CMStream (ms)
//
// Purpose: Main interface to multi-streams
//
// Interface: See below
//
// Notes:
//
//-----------------------------------------------------------------------
class CMStream { public:
CMStream( ILockBytes **pplstParent, USHORT uSectorShift);
~CMStream();
SCODE Init(VOID);
SCODE InitNew(VOID); SCODE InitConvert(VOID);
void Empty(void); inline SCODE CreateEntry( SID const sidParent, CDfName const *pdfn, MSENTRYFLAGS const mefFlags, SID *psid);
// No implementation, currently unused, placeholder
void ReleaseEntry(SID const sid);
inline SCODE DestroyEntry( SID const sidParent, CDfName const *pdfn);
inline SCODE KillStream( SECT sectStart, ULONGLONG ulSize);
inline SCODE RenameEntry( SID const sidParent, CDfName const *pdfn, CDfName const *pdfnNew); inline SCODE IsEntry( SID const sidParent, CDfName const *pdfn, SEntryBuffer *peb);
inline SCODE StatEntry( SID const sid, CDfName *pName, STATSTGW *pstatstg); inline SCODE GetChild( SID const sid, SID *psid);
inline SCODE FindGreaterEntry( SID sidParent, CDfName const *pdfnKey, SID *psid);
inline SCODE GetTime( SID const sid, WHICHTIME const tt, TIME_T *pnt); inline SCODE SetTime( SID const sid, WHICHTIME const tt, TIME_T nt); inline SCODE GetClass( SID const sid, CLSID *pclsid);
inline SCODE SetClass(SID const sid, REFCLSID clsid);
inline SCODE GetStateBits(SID const sd, DWORD *pgrfStateBits);
inline SCODE SetStateBits(SID const sid, DWORD grfStateBits, DWORD grfMask);
inline SCODE GetEntrySize( SID const sid, ULONGLONG *pcbSize);
SCODE GetIterator( SID const sidParent, CMSFIterator **pit);
inline SCODE SetSize(VOID); inline SCODE SetMiniSize(VOID);
SCODE MWrite( SID sid, BOOL fIsMiniStream, ULONGLONG ulOffset, VOID const HUGEP *pBuffer, ULONG ulCount, CStreamCache *pstmc, ULONG *pulRetVal);
SCODE GetName(SID const sid, CDfName *pdfn);
inline CMSFHeader * GetHeader(VOID) const; inline CFat * GetFat(VOID) const; inline CFat * GetMiniFat(VOID) const; inline CDIFat * GetDIFat(VOID) const; inline CDirectory * GetDir(VOID) const; inline CMSFPageTable * GetPageTable(VOID) const;
inline USHORT GetSectorSize(VOID) const; inline USHORT GetSectorShift(VOID) const; inline USHORT GetSectorMask(VOID) const;
SCODE Flush(BOOL fFlushILB); SCODE FlushHeader(USHORT uForce);
inline CDirectStream * GetMiniStream(VOID) const; inline ILockBytes * GetILB(VOID) const;
inline SCODE GetSect(SID sid, SECT sect, SECT *psect); SCODE GetESect(SID sid, SECT sect, SECT *psect);
SCODE SecureSect( const SECT sect, const ULONGLONG ulSize, const BOOL fIsMini); private:
ILockBytes **_pplstParent; CMSFHeader _hdr;
CMSFPageTable *_pmpt;
CDirectory _dir; CFat _fat; CDIFat _fatDif; CFat _fatMini; CDirectStream* _pdsministream;
USHORT _uSectorSize; USHORT _uSectorShift; USHORT _uSectorMask;
SCODE InitCommon(VOID);
SECT GetStart(SID sid) const;
SCODE ConvertILB(SECT sectMax); friend SCODE DllGetScratchMultiStream( CMStream **ppms, ILockBytes **pplstStream, CMStream *pmsMaster);
#ifdef _MSC_VER
#pragma warning(disable:4512)
// default assignment operator could not be generated, which is fine
// since we are not using it.
#endif // _MSC_VER
};
#ifdef _MSC_VER
#pragma warning(default:4512)
#endif // _MSC_VER
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetSectorSize, public
//
// Synopsis: Returns the current sector size
//
//--------------------------------------------------------------------------
inline USHORT CMStream::GetSectorSize(VOID) const { return _uSectorSize; }
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetSectorShift, public
//
// Synopsis: Returns the current shift for sector math
//
//--------------------------------------------------------------------------
inline USHORT CMStream::GetSectorShift(VOID) const { return _uSectorShift; }
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetSectorMask, public
//
// Synopsis: Returns the current mask for sector math
//
//--------------------------------------------------------------------------
inline USHORT CMStream::GetSectorMask(VOID) const { return _uSectorMask; }
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetHeader, public
//
// Synopsis: Returns a pointer to the current header.
//
//--------------------------------------------------------------------------
inline CMSFHeader * CMStream::GetHeader(VOID) const { return (CMSFHeader *)(&_hdr); }
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetFat, public
//
// Synopsis: Returns a pointer to the current Fat
//
//--------------------------------------------------------------------------
inline CFat * CMStream::GetFat(VOID) const { return (CFat *)&_fat; }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetMiniFat
//
// Synopsis: Returns a pointer to the current minifat
//
//--------------------------------------------------------------------------
inline CFat * CMStream::GetMiniFat(VOID) const { return (CFat *)&_fatMini; }
//+-------------------------------------------------------------------------
//
// Method: CMStream::GetDIFat, public
//
// Synopsis: Returns pointer to the current Double Indirect Fat
//
//--------------------------------------------------------------------------
inline CDIFat * CMStream::GetDIFat(VOID) const { return (CDIFat *)&_fatDif; }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetDir
//
// Synopsis: Returns a pointer to the current directory
//
//--------------------------------------------------------------------------
inline CDirectory * CMStream::GetDir(VOID) const { return (CDirectory *)&_dir; }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetMiniStream
//
// Synopsis: Returns pointer to the current ministream
//
//--------------------------------------------------------------------------
inline CDirectStream * CMStream::GetMiniStream(VOID) const { return(_pdsministream); }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetILB
//
// Synopsis: Returns a pointer to the current parent ILockBytes
//
//--------------------------------------------------------------------------
inline ILockBytes * CMStream::GetILB(VOID) const { return(*_pplstParent); }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetPageTable
//
// Synopsis: Returns a pointer to the current page table
//
//--------------------------------------------------------------------------
inline CMSFPageTable * CMStream::GetPageTable(VOID) const { return _pmpt; }
//+-------------------------------------------------------------------------
//
// Method: CMStream::StatEntry
//
// Synopsis: For a given handle, fill in the Multistream specific
// information of a STATSTG.
//
// Arguments: [sid] -- SID that information is requested on.
// [pName] -- Name of entry to fill in (if not null)
// [pstatstg] -- STATSTG to fill in (if not null)
//
// Returns: S_OK
//
//--------------------------------------------------------------------------
inline SCODE CMStream::StatEntry(SID const sid, CDfName *pName, STATSTGW *pstatstg) { return _dir.StatEntry(sid, pName, pstatstg); }
//+-------------------------------------------------------------------------
//
// Member: CMStream::GetChild, public
//
// Synposis: Return the child SID for a directory entry
//
// Arguments: [sid] - Parent
// [psid] - Child SID return
//
// Returns: Appropriate status code
//
//---------------------------------------------------------------------------
inline SCODE CMStream::GetChild( SID const sid, SID *psid) { return _dir.GetChild(sid, psid); }
//+---------------------------------------------------------------------------
//
// Member: CMStream::FindGreaterEntry, public
//
// Synopsis: Returns the next greater entry for the given parent SID
//
// Arguments: [sidParent] - SID of parent storage
// [CDfName *pdfnKey] - Previous key
// [psid] - Result
//
// Returns: Appropriate status code
//
// Modifies: [psid]
//
//----------------------------------------------------------------------------
inline SCODE CMStream::FindGreaterEntry(SID sidParent, CDfName const *pdfnKey, SID *psid) { return _dir.FindGreaterEntry(sidParent, pdfnKey, psid); }
extern SCODE DllMultiStreamFromStream( CMStream **ppms, ILockBytes **pplstStream, DWORD dwFlags);
extern SCODE DllMultiStreamFromCorruptedStream( CMStream **ppms, ILockBytes **pplstStream, DWORD dwFlags);
extern void DllReleaseMultiStream(CMStream *pms);
extern SCODE DllIsMultiStream(ILockBytes *plstStream);
extern SCODE DllGetCommitSig(ILockBytes *plst, DFSIGNATURE *psig);
extern SCODE DllSetCommitSig(ILockBytes *plst, DFSIGNATURE sig);
#if DEVL == 1
extern VOID SetInfoLevel(ULONG x); #endif
#endif //__MSF_HXX__
|