|
|
// 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__
|