windows-nt/Source/XPSP1/NT/com/ole32/stg/h/dir.hxx
2020-09-26 16:20:57 +08:00

423 lines
11 KiB
C++

//+-------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: dir.hxx
//
// Contents: Directory header for Mstream project
//
// Classes: CDirEntry - Information on a single stream
// CDirSect - Sector sized array of DirEntry
// CDirVector - Resizable array of CDirSect
// CDirectory - Grouping of DirSectors
//
// History: 18-Jul-91 PhilipLa Created.
//
// Notes:
//
//--------------------------------------------------------------------
#ifndef __DIR_HXX__
#define __DIR_HXX__
#include <wchar.h>
#include <vect.hxx>
#define DIR_HIT 0x01
#if _MSC_VER >= 700
#pragma pack(1)
#endif
struct SPreDirEntry
{
protected:
CDfName _dfn; // Name (word-aligned)
BYTE _mse; // STGTY_...
BYTE _bflags;
SID _sidLeftSib; // Siblings
SID _sidRightSib; // Siblings
SID _sidChild; // Storage - Child list
GUID _clsId; // Storage - Class id
DWORD _dwUserFlags; // Storage - User flags
TIME_T _time[2]; // Storage - time stamps
SECT _sectStart; // Stream - start
ULARGE_INTEGER _ulSize; // Stream - size
};
#if _MSC_VER >= 700
#pragma pack()
#endif
#define STGTY_INVALID 0
#define STGTY_ROOT 5
// Macros which tell whether a direntry has stream fields,
// storage fields or property fields
#define STREAMLIKE(mse) \
(((mse) & STGTY_REAL) == STGTY_STREAM || (mse) == STGTY_ROOT)
#define STORAGELIKE(mse) \
(((mse) & STGTY_REAL) == STGTY_STORAGE || (mse) == STGTY_ROOT)
//+----------------------------------------------------------------------
//
// Class: CDirEntry (de)
//
// Purpose: Holds information on one stream
//
// Interface: GetName - returns name of stream
// GetStart - return first sector for stream
// GetSize - returns size of stream
// GetFlags - returns flag byte
//
// SetName - sets name
// SetStart - sets first sector
// SetSize - sets size
// SetFlags - sets flag byte
//
// IsFree - returns 1 if element is not in use
// IsEntry - returns 1 is element name matches argument
//
// History: 18-Jul-91 PhilipLa Created.
// 26-May-95 SusiA Added GetAllTimes
// 22-Noc-95 SusiA Added SetAllTimes
//
// Notes: B-flat,C-sharp
//
//-----------------------------------------------------------------------
const CBDIRPAD = (const)(DIRENTRYSIZE - sizeof(SPreDirEntry));
// DirEntry bit flags are used for the following private state
// Usage Bit
#define DECOLORBIT 0x01
#define DERESERVED 0xfe
typedef enum
{
DE_RED = 0,
DE_BLACK = 1
} DECOLOR;
class CDirEntry: private SPreDirEntry
{
public:
CDirEntry();
inline void Init(MSENTRYFLAGS mse);
inline CDfName const * GetName(VOID) const;
inline SECT GetStart(VOID) const;
#ifdef LARGE_STREAMS
inline ULONGLONG GetSize(BOOL fLarge) const;
#else
inline ULONG GetSize(VOID) const;
#endif
inline SID GetLeftSib(VOID) const;
inline SID GetRightSib(VOID) const;
inline SID GetChild(VOID) const;
inline MSENTRYFLAGS GetFlags(VOID) const;
inline DECOLOR GetColor(VOID) const;
inline TIME_T GetTime(WHICHTIME tt) const;
inline void GetAllTimes(TIME_T *patm, TIME_T *pmtm, TIME_T *pctm);
inline void SetAllTimes(TIME_T atm, TIME_T mtm, TIME_T ctm);
inline GUID GetClassId(VOID) const;
inline DWORD GetUserFlags(VOID) const;
inline void SetName(const CDfName *pdfn);
inline void SetStart(const SECT);
#ifdef LARGE_STREAMS
inline void SetSize(const ULONGLONG);
#else
inline void SetSize(const ULONG);
#endif
inline void SetLeftSib(const SID);
inline void SetRightSib(const SID);
inline void SetChild(const SID);
inline void SetFlags(const MSENTRYFLAGS mse);
inline void SetColor(DECOLOR);
inline void SetTime(WHICHTIME tt, TIME_T nt);
inline void SetClassId(GUID cls);
inline void SetUserFlags(DWORD dwUserFlags, DWORD dwMask);
inline BOOL IsFree(VOID) const;
inline BOOL IsEntry(CDfName const *pdfn) const;
private:
inline BYTE GetBitFlags(VOID) const;
inline void SetBitFlags(BYTE bValue, BYTE bMask);
// BYTE _bpad[CBDIRPAD]; // no more padding left
};
//+-------------------------------------------------------------------------
//
// Class: CDirSect (ds)
//
// Purpose: Provide sector sized block of DirEntries
//
// Interface:
//
// History: 18-Jul-91 PhilipLa Created.
// 27-Dec-91 PhilipLa Converted from const size to
// variable sized sectors.
//
// Notes:
//
//--------------------------------------------------------------------------
#if _MSC_VER == 700
#pragma warning(disable:4001)
#elif _MSC_VER >= 800
#pragma warning(disable:4200)
#endif
class CDirSect
{
public:
SCODE Init(USHORT cbSector);
SCODE InitCopy(USHORT cbSector,
const CDirSect *pdsOld);
inline CDirEntry * GetEntry(DIROFFSET iEntry);
private:
CDirEntry _adeEntry[];
};
#if _MSC_VER == 700
#pragma warning(default:4001)
#elif _MSC_VER >= 800
#pragma warning(default:4200)
#endif
//+-------------------------------------------------------------------------
//
// Class: CDirVector (dv)
//
// Purpose: Provide resizable array of DirSectors.
//
// Interface:
//
// History: 27-Dec-91 PhilipLa Created.
//
// Notes:
//
//--------------------------------------------------------------------------
class CDirVector: public CPagedVector
{
public:
inline CDirVector(VOID);
inline void InitCommon(USHORT cbSector);
inline SCODE GetTable(
const DIRINDEX iTable,
const DWORD dwFlags,
CDirSect **ppds);
private:
USHORT _cbSector;
};
inline void CDirVector::InitCommon(USHORT cbSector)
{
_cbSector = cbSector;
}
//+----------------------------------------------------------------------
//
// Class: CDirectory (dir)
//
// Purpose: Main interface for directory functionality
//
// Interface: GetFree - returns an SID for a free DirEntry
// Find - finds its argument in the directory list
// SetEntry - sets up a DirEntry and writes out its sector
// GetName - returns the name of a DirEntry
// GetStart - returns the start sector of a DirEntry
// GetSize - returns the size of a DirEntry
// GetFlags - returns the flag byte of a DirEntry
//
//
// History: 18-Jul-91 PhilipLa Created.
// 26-Aug-91 PhilipLa Added support for iterators
// 26-Aug-92 t-chrisy Added init function for
// corrupted directory object
// Notes:
//
//-----------------------------------------------------------------------
typedef enum DIRENTRYOP
{
DEOP_FIND = 0,
DEOP_REMOVE = 1
} DIRENTRYOP;
class CDirectory
{
public:
CDirectory();
VOID Empty(VOID);
SCODE Init(CMStream *pmsParent, DIRINDEX cSect);
SCODE InitNew(CMStream *pmsParent);
void InitCopy(CDirectory *pdirOld);
SCODE FindGreaterEntry(
SID sidChildRoot,
CDfName const *pdfn,
SID *psidResult);
SCODE SetStart(const SID sid, const SECT sect);
SCODE SetTime(const SID sid, WHICHTIME tt, TIME_T nt);
SCODE SetAllTimes(SID const sid, TIME_T atm,TIME_T mtm, TIME_T ctm);
SCODE SetChild(const SID sid, const SID sidChild);
#ifdef LARGE_STREAMS
SCODE SetSize(const SID sid, const ULONGLONG cbSize);
#else
SCODE SetSize(const SID sid, const ULONG cbSize);
#endif
SCODE SetClassId(const SID sid, const GUID cls);
SCODE SetFlags(const SID sid, const MSENTRYFLAGS mse);
SCODE SetUserFlags(const SID sid,
DWORD dwUserFlags,
DWORD dwMask);
inline SCODE GetName(const SID sid, CDfName *pdfn);
inline SCODE GetStart(const SID sid, SECT * psect);
#ifdef LARGE_STREAMS
inline SCODE GetSize(const SID sid, ULONGLONG *pulSize);
#else
inline SCODE GetSize(const SID sid, ULONG *pulSize);
#endif
inline SCODE GetChild(const SID sid, SID *psid);
inline SCODE GetFlags(const SID sid, MSENTRYFLAGS *pmse);
inline SCODE GetClassId(const SID sid, GUID *pcls);
inline SCODE GetTime(const SID sid, WHICHTIME tt, TIME_T *ptime);
inline SCODE GetAllTimes(SID const sid, TIME_T *patm,TIME_T *pmtm, TIME_T *pctm);
inline SCODE GetUserFlags(const SID sid, DWORD *pdwUserFlags);
SCODE GetDirEntry(
const SID sid,
const DWORD dwFlags,
CDirEntry **ppde);
void ReleaseEntry(SID sid);
SCODE CreateEntry(
SID sidParent,
CDfName const *pdfn,
MSENTRYFLAGS mef,
SID *psidNew);
SCODE RenameEntry(
SID const sidParent,
CDfName const *pdfn,
CDfName const *pdfnNew);
inline SCODE IsEntry(
SID const sidParent,
CDfName const *pdfn,
SEntryBuffer *peb);
SCODE DestroyAllChildren(
SID const sidParent,
ULONG ulDepth);
SCODE DestroyChild(
SID const sidParent,
CDfName const *pdfn,
ULONG ulDepth);
SCODE StatEntry(
SID const sid,
SIterBuffer *pib,
STATSTGW *pstatstg);
inline SCODE Flush(VOID);
inline void SetParent(CMStream * pmsParent);
static int NameCompare(
CDfName const *pdfn1,
CDfName const *pdfn2);
// Get the length of the Directory Stream in Sectors.
inline ULONG GetNumDirSects(void) const;
// Get the length of the Directory Stream in Entries.
inline ULONG GetNumDirEntries(void) const;
inline BOOL IsLargeSector () const;
private:
CDirVector _dv;
DIRINDEX _cdsTable;
CBasedMStreamPtr _pmsParent;
DIROFFSET _cdeEntries;
SID _sidFirstFree;
SCODE Resize(DIRINDEX);
inline DIRINDEX SidToTable(SID sid) const;
inline SID PairToSid(
DIRINDEX iTable,
DIROFFSET iEntry) const;
inline SCODE SidToPair(
SID sid,
DIRINDEX* pipds,
DIROFFSET* pide) const;
SCODE GetFree(SID * psid);
SCODE InsertEntry(
SID sidParent,
SID sidInsert,
CDfName const *pdfnInsert);
SCODE FindEntry(
SID sidParent,
CDfName const *pdfnFind,
DIRENTRYOP deop,
SEntryBuffer *peb);
SCODE SplitEntry(
CDfName const *pdfn,
SID sidTree,
SID sidGreat,
SID sidGrand,
SID sidParent,
SID sidChild,
SID *psid);
SCODE RotateEntry(
CDfName const *pdfn,
SID sidTree,
SID sidParent,
SID *psid);
SCODE SetColorBlack(const SID sid);
};
#endif //__DIR_HXX__