508 lines
19 KiB
C++
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__
|