windows-nt/Source/XPSP1/NT/enduser/stuff/itss/itsfs.h
2020-09-26 16:20:57 +08:00

508 lines
19 KiB
C++

// ITSFS.H -- Declaration of the CITFileSystem class
#ifndef __ITSFS_H__
#define __ITSFS_H__
const UINT MAGIC_ITS_FILE = 'I' | ('T' << 8) | ('S' << 16) | ('F' << 24);
const UINT FirstReleasedVersion = 2;
const UINT RelativeOffsetVersion = 3;
const UINT CurrentFileFormatVersion = 3;
#define MAX_TABLE_RECS_INCACHE 1024
typedef struct _ITSFileHeaderV2
{
UINT uMagic; // Should be set to MAGIC_ITS_FILE;
UINT uFormatVersion; // Version number for file format
UINT cbHeaderSize; // Size of this header in bytes.
UINT fFlags; // State flag bits for the ITS file.
DWORD dwStamp; // Content Version stamp; changes on every write.
LCID lcid; // Locale Id for file.
CLSID clsidFreeList; // Class id for the free list manager interface used in the file
CLSID clsidPathMgr; // Class id for the path manager interface used in the file
CULINT offFreeListData; // Offset in bytes to free list data
CULINT cbFreeListData; // Size of free list data in bytes
CULINT offPathMgrData; // Offset in bytes to Path Manager data
CULINT cbPathMgrData; // Size of Path Manager data in bytes
} ITSFileHeaderV2, *PITSFileHeaderV2;
// In the ITSFileHeader structure each items is aligned on a natural boundary.
// That is WCHARs are on 2-byte boundarides, UINTs are on 4-byte boundaries,
// CULINTs are on 8-byte boundaries, and CLSIDs are on 16-byte boundaries.
// Keeping them that way will avoid any alignment problems on RISC machines.
typedef struct _ITSFileHeader
{
UINT uMagic; // Should be set to MAGIC_ITS_FILE;
UINT uFormatVersion; // Version number for file format
UINT cbHeaderSize; // Size of this header in bytes.
UINT fFlags; // State flag bits for the ITS file.
DWORD dwStamp; // Content Version stamp; changes on every write.
LCID lcid; // Locale Id for file.
CLSID clsidFreeList; // Class id for the free list manager interface used in the file
CLSID clsidPathMgr; // Class id for the path manager interface used in the file
CULINT offFreeListData; // Offset in bytes to free list data
CULINT cbFreeListData; // Size of free list data in bytes
CULINT offPathMgrData; // Offset in bytes to Path Manager data
CULINT cbPathMgrData; // Size of Path Manager data in bytes
CULINT offPathMgrOrigin;// Coordinate origin offset wrapped around path manager offsets
} ITSFileHeader, *PITSFileHeader;
const DWORD ITSFS_CONTROL_VERSION = 1;
const DWORD DEFAULT_DIR_BLOCK_SIZE = 8192;
const DWORD DEFAULT_MIN_CACHE_ENTRIES = 20;
// Bit flag definitions for ITSFileHeader::fFlags
enum { Compacting = 0x80, // file is being compacted
VALID_OPEN_FLAGS = fDefaultIsCompression // valid flag set when opening a file.
};
class CITFileSystem : public CITUnknown
{
public:
// Creators:
static HRESULT __stdcall CreateITFileSystem(IUnknown *punkOuter, const WCHAR * pwcsName,
DWORD grfMode,
PITS_Control_Data pControlData,
LCID lcid,
IStorage ** ppstgOpen
);
static HRESULT __stdcall CreateITFSOnLockBytes(IUnknown *punkOuter, ILockBytes * pLKB,
DWORD grfMode,
PITS_Control_Data pControlData,
LCID lcid,
IStorage ** ppstgOpen
);
static HRESULT __stdcall QueryFileStampAndLocale
(const WCHAR *pwcsName, DWORD *pFileStamp, DWORD *pFileLocale);
static HRESULT __stdcall QueryLockByteStampAndLocale
(ILockBytes * plkbyt, DWORD *pFileStamp, DWORD *pFileLocale);
static HRESULT __stdcall IsITFile(const WCHAR * pwcsName);
static HRESULT __stdcall IsITLockBytes(ILockBytes * plkbyt);
static HRESULT __stdcall OpenITFileSystem(IUnknown *punkOuter, const WCHAR * pwcsName,
DWORD grfMode,
IStorageITEx ** ppstgOpen
);
static HRESULT __stdcall OpenITFSOnLockBytes(IUnknown *punkOuter, ILockBytes * pLKB,
DWORD grfMode,
IStorageITEx ** ppstgOpen
);
static HRESULT __stdcall SetITFSTimes(WCHAR const * pwcsName, FILETIME const * pctime,
FILETIME const * patime, FILETIME const * pmtime
);
static HRESULT __stdcall DefaultControlData(PITS_Control_Data *ppControlData);
static HRESULT __stdcall Compact(const WCHAR * pwcsName, ECompactionLev iLev);
// Destructor:
~CITFileSystem();
private:
CITFileSystem(IUnknown *pUnkOuter);
class CImpITFileSystem : public IITFileSystem
{
public:
// Constructor:
CImpITFileSystem(CITFileSystem *pITFileSystem, IUnknown *punkOuter);
// Destructor:
~CImpITFileSystem(void);
// Finding an active file system:
static IITFileSystem *FindFileSystem(const WCHAR *pwcsPath);
IStorageITEx *FindActiveStorage (const WCHAR *pwcsPath);
ILockBytes *FindActiveLockBytes(const WCHAR *pwcsPath);
// Initialers:
HRESULT __stdcall InitCreateOnLockBytes(ILockBytes * pLKB, DWORD grfMode,
PITS_Control_Data pControlData, LCID lcid
);
HRESULT __stdcall InitOpenOnLockBytes(ILockBytes * pLKB, DWORD grfMode);
//garbage collection routines
HRESULT GetFirstRecord(SEntry *prec,
IStreamITEx *pRecTblStrm,
int cTblRecsInCache,
int cTblRecsTotal,
SEntry *pRecTblCache);
HRESULT GetNextRecord(ULONG ulCurRec,
SEntry *prec,
IStreamITEx *pRecTblStrm,
int cTblRecsInCache,
int cTblRecsTotal,
SEntry *pRecTblCache);
HRESULT SortRecTable(ESortField eSField,
IStreamITEx *pRecTblStrm,
int cTblRecsInCache,
int cTblRecsTotal,
SEntry *pRecTblCache,
CITSortRecords **ppSort);
HRESULT AppendToRecTbl(SEntry *prec,
IStreamITEx *pRecTblStrm,
int *pcTblRecsInCache,
int *pcTblRecsTotal,
SEntry *pRecTblCache);
static int CompareEntries(SEntry e1, SEntry e2, ESortField eSField);
HRESULT CreateTempStm(IStreamITEx **ppRecTblStrm);
HRESULT InitRecTable( IStreamITEx **ppRecTblStrm,
int *pcTblRecsInCache,
int *pcTblRecsTotal,
SEntry **ppRecTblCache);
HRESULT BuildUpEntryTable(ULONG *pulRecNum,
IStreamITEx *pRecTblStrm,
int *pcTblRecsInCache,
int *pcTblRecsTotal,
SEntry *pRecTblCache,
BOOL *pfNeedFileSort);
HRESULT CompactData(LPBYTE pRecTableCache, ULONG cEntries, CULINT *pullCompactedOffset, IStreamITEx *pTempDataStrm);
HRESULT UpdatePathDB(IStreamITEx *pRecTblStrm, int cTblRecsInCache,
int cTblRecsTotal, SEntry *pRecTblCache, CITSortRecords *pSort);
HRESULT GetPathDB(IStreamITEx *pTempPDBStrm, BOOL fCompact);
HRESULT ForceClearDirty();
void SetCompaction(BOOL fSet);
HRESULT Compact(ECompactionLev iLev);
HRESULT CompactFileSystem(IStreamITEx *pTempPDBStrm, IStreamITEx *pTempDataStrm);
HRESULT CopyStream(IStreamITEx *pTempStrm, CULINT *pullCompactedOffset);
void VerifyData(LPBYTE pRecTableCache, ULONG cEntries, ESortField eSType, BOOL fReset);
HRESULT DumpStream(IStreamITEx *pTempStrm, LPSTR pFileName);
// IUnknown methods:
STDMETHODIMP_(ULONG) Release(void);
// IITFileSystem methods:
HRESULT __stdcall DeactivateSpace(UINT iSpace);
CITCriticalSection& CriticalSection();
HRESULT __stdcall FlushToLockBytes();
HRESULT __stdcall CreateStorage (IUnknown *pUnkOuter, const WCHAR *pwcsPathPrefix,
DWORD grfMode, IStorageITEx **ppStg);
HRESULT __stdcall OpenStorage (IUnknown *pUnkOuter, const WCHAR *pwcsPath,
DWORD grfMode, IStorageITEx **ppstg);
HRESULT __stdcall CreateLockBytes(IUnknown *pUnkOuter, const WCHAR *pwcsPath,
const WCHAR *pwcsDataSpaceName,
BOOL fOverwrite, ILockBytes **ppLKB);
HRESULT __stdcall OpenLockBytes(IUnknown *pUnkOuter, const WCHAR *pwcsPath,
ILockBytes **ppLKB);
HRESULT __stdcall CreateStream(IUnknown *pUnkOuter, const WCHAR *pwcsPath,
DWORD grfMode, IStreamITEx **ppStrm);
HRESULT __stdcall CreateStream
(IUnknown *pUnkOuter, const WCHAR * pwcsName, const WCHAR *pwcsDataSpaceName,
DWORD grfMode, IStreamITEx ** ppstm
);
HRESULT __stdcall OpenStream(IUnknown *pUnkOuter, const WCHAR *pwcsPath,
DWORD grfMode, IStreamITEx **ppStream);
HRESULT __stdcall ConnectStorage(CImpITUnknown *pStg);
HRESULT __stdcall ConnectLockBytes(CImpITUnknown *pStg);
HRESULT __stdcall DeleteItem(WCHAR const *pwcsName);
HRESULT __stdcall RenameItem(WCHAR const *pwcsOldName, WCHAR const *pwcsNewName);
HRESULT __stdcall UpdatePathInfo(PathInfo *pPathInfo);
HRESULT __stdcall SetITFSTimes(FILETIME const * pctime,
FILETIME const * patime,
FILETIME const * pmtime
);
HRESULT __stdcall GetITFSTimes(FILETIME * pctime,
FILETIME * patime,
FILETIME * pmtime
);
HRESULT __stdcall ReallocEntry(PathInfo *pPathInfo, CULINT ullcbNew,
BOOL fCopyContent
);
HRESULT __stdcall ReallocInPlace(PathInfo *pPathInfo, CULINT ullcbNew);
HRESULT __stdcall EnumeratePaths(WCHAR const *pwcsPathPrefix,
IEnumSTATSTG **ppEnumStatStg
);
HRESULT __stdcall IsWriteable();
HRESULT __stdcall FSObjectReleased();
BOOL __stdcall IsCompacting() { return (m_itfsh.fFlags & Compacting);};
HRESULT __stdcall QueryFileStampAndLocale(DWORD *pFileStamp, DWORD *pFileLocale);
HRESULT __stdcall CountWrites();
private:
class CSystemPathManager : public CITUnknown
{
public:
static HRESULT Create(IUnknown *punkOuter, CImpITFileSystem *pITFS,
IITPathManager **ppPathMgr
);
~CSystemPathManager();
class CImpIPathManager : public IITPathManager
{
public:
CImpIPathManager(CSystemPathManager *pBackObj, IUnknown *punkOuter);
~CImpIPathManager();
HRESULT STDMETHODCALLTYPE Init(CImpITFileSystem *pITFS);
// IPersist Method:
HRESULT STDMETHODCALLTYPE GetClassID(
/* [out] */ CLSID __RPC_FAR *pClassID);
// IITPathManager interfaces:
HRESULT STDMETHODCALLTYPE FlushToLockBytes();
HRESULT STDMETHODCALLTYPE FindEntry (PPathInfo pPI );
HRESULT STDMETHODCALLTYPE CreateEntry(PPathInfo pPINew,
PPathInfo pPIOld,
BOOL fReplace );
HRESULT STDMETHODCALLTYPE DeleteEntry(PPathInfo pPI );
HRESULT STDMETHODCALLTYPE UpdateEntry(PPathInfo pPI );
HRESULT STDMETHODCALLTYPE EnumFromObject(IUnknown *punkOuter,
const WCHAR *pwszPrefix,
UINT cwcPrefix,
REFIID riid,
PVOID *ppv
);
HRESULT STDMETHODCALLTYPE GetPathDB(IStreamITEx *pTempPDBStrm, BOOL fCompact);
HRESULT STDMETHODCALLTYPE ForceClearDirty();
private:
CImpITFileSystem *m_pIITFS;
};
private:
CSystemPathManager(IUnknown *pUnkOuter);
CImpIPathManager m_PathManager;
};
friend CSystemPathManager::CImpIPathManager;
class CEnumFSItems : public CITUnknown
{
public:
static HRESULT NewFSEnumerator(CImpITFileSystem *pITFS,
const WCHAR *pwszPathPrefix,
UINT cwcPathPrefix,
IEnumSTATSTG **ppEnumSTATSTG
);
~CEnumFSItems();
class CImpIEnumSTATSTG : public IITEnumSTATSTG
{
friend CEnumFSItems;
public:
CImpIEnumSTATSTG(CEnumFSItems *pBackObj, IUnknown *punkOuter);
~CImpIEnumSTATSTG();
HRESULT InitFSEnumerator(CImpITFileSystem *pITFS,
const WCHAR *pwszPathPrefix,
UINT cwcPathPrefix
);
HRESULT InitNewCloneOf(CImpIEnumSTATSTG *pImpEnumFS);
HRESULT STDMETHODCALLTYPE GetNextEntryInSeq(ULONG celt, PathInfo *rgelt, ULONG *pceltFetched);
HRESULT STDMETHODCALLTYPE GetFirstEntryInSeq(PathInfo *rgelt);
HRESULT STDMETHODCALLTYPE Next(
/* [in] */ ULONG celt,
/* [in] */ STATSTG __RPC_FAR *rgelt,
/* [out] */ ULONG __RPC_FAR *pceltFetched);
HRESULT STDMETHODCALLTYPE Skip(
/* [in] */ ULONG celt);
HRESULT STDMETHODCALLTYPE Reset( void);
HRESULT STDMETHODCALLTYPE Clone(
/* [out] */ IEnumSTATSTG __RPC_FAR *__RPC_FAR *ppenum);
private:
IEnumSTATSTG *m_pEnumPathMgr;
CImpITFileSystem *m_pITFS;
};
static HRESULT NewCloneOf(CImpIEnumSTATSTG *pImpEnumFS,
IEnumSTATSTG **ppEnumSTATSTG
);
private:
CEnumFSItems(IUnknown *pUnkOuter);
CImpIEnumSTATSTG m_ImpEnumSTATSTG;
};
friend CEnumFSItems;
friend CEnumFSItems::CImpIEnumSTATSTG;
enum { PENDING_CHANGE_LIMIT = 100 };
void CopyPath(PathInfo &PI, const WCHAR *pwcsPath);
IITPathManager *PathMgr(PathInfo *pPathInfo);
HRESULT CreateSpaceNameList();
HRESULT OpenSpaceNameList();
HRESULT FlushSpaceNameList();
HRESULT FindSpaceName(const WCHAR *pwcsSpaceName);
HRESULT AddSpaceName(const WCHAR *pwcsSpaceName);
HRESULT DeleteSpaceName(const WCHAR *pwcsSpaceName);
HRESULT ActivateDataSpace(ULONG iSpace);
HRESULT DeactivateDataSpace(ULONG iSpace);
HRESULT CreateDefaultDataSpace(PITSFS_Control_Data pITCD);
HRESULT WriteToStream(const WCHAR *pwcsStreamPath, PVOID pvData, ULONG cbData);
HRESULT CreateTransformedLockBytes
(IUnknown *pUnkOuter, const WCHAR *pwcsPath,
const WCHAR *pwcsDataSpaceName,
BOOL fOverwrite, ILockBytes **ppLKB
);
HRESULT OpenTransformedLockbytes(PathInfo *pPI, ILockBytes **ppLKB);
HRESULT __stdcall LookForActivity(WCHAR const *pwcsName, IEnumSTATSTG *pEnum);
enum { MAX_SPACES = 256 };
ITSFileHeader m_itfsh;
CITCriticalSection m_cs;
UINT m_StartingFileStamp;
ILockBytes *m_pLKBMedium;
IITPathManager *m_pPathManager;
IITPathManager *m_pSysPathManager;
IITFreeList *m_pFreeListManager;
ITransformServices *m_pTransformServices;
CImpITUnknown *m_pActiveStorageList;
CImpITUnknown *m_pActiveLockBytesList;
BOOL m_fHeaderIsDirty;
BOOL m_fInitialed;
BOOL m_fReadOnly;
BOOL m_fDefaultIsCompression;
WCHAR *m_pwscDataSpaceNames;
TransformDescriptor **m_papTransformDescriptors;
IStreamITEx *m_pStrmSpaceNames;
UINT m_cFSObjectRefs; // Count of circular refs through
// ":" storages and streams.
UINT m_cwcFileName;
WCHAR m_awszFileName[MAX_PATH];
};
CImpITFileSystem m_ImpITFileSystem;
};
inline CITFileSystem::CITFileSystem(IUnknown *pUnkOuter)
: m_ImpITFileSystem(this, pUnkOuter),
CITUnknown(&IID_ITFileSystem, 1, &m_ImpITFileSystem)
{
}
inline CITFileSystem::~CITFileSystem() { }
inline CITFileSystem::CImpITFileSystem::CSystemPathManager::CSystemPathManager(IUnknown *pUnkOuter)
: m_PathManager(this, pUnkOuter),
CITUnknown(aIID_CPathManager, cInterfaces_CPathManager, &m_PathManager)
{
}
inline CITFileSystem::CImpITFileSystem::CSystemPathManager::~CSystemPathManager(void)
{
}
inline CITFileSystem::CImpITFileSystem::CSystemPathManager::CImpIPathManager::~CImpIPathManager()
{
}
inline CITFileSystem::CImpITFileSystem::CEnumFSItems::CEnumFSItems(IUnknown *pUnkOuter)
: m_ImpEnumSTATSTG(this, pUnkOuter),
CITUnknown(&IID_IEnumSTATSTG, 1, &m_ImpEnumSTATSTG)
{
}
inline CITFileSystem::CImpITFileSystem::CEnumFSItems::~CEnumFSItems(void)
{
}
extern const WCHAR *pwscSpaceNameListStream;
extern const WCHAR *pwcsSpaceNameStorage;
extern const WCHAR *pwcsSpaceContentSuffix;
extern const WCHAR *pwcsTransformListSuffix;
extern const WCHAR *pwcsSpanInfoSuffix;
extern const WCHAR *pwcsTransformSubStorage;
extern const WCHAR *pwcsControlDataSuffix;
extern const WCHAR *pwcsInstanceSubStorage;
extern const WCHAR *pwcsTransformStorage;
extern const WCHAR *pwcsUncompressedSpace;
extern const WCHAR *pwcsLZXSpace;
#endif // __ITSFS_H__