/*++ Copyright (C) 2000-2001 Microsoft Corporation --*/ #ifndef __WMI_A51_LONG_STAGE__H_ #define __WMI_A51_LONG_STAGE__H_ #include #include #include #include #include "a51tools.h" #include "stagemgr.h" #define A51_MAX_FILES 5 class CFileCache; class CLongFileStagingFile; struct CFileLocation { int m_nFileId; TFileOffset m_lStartOffset; CFileLocation() : m_nFileId(0), m_lStartOffset(0) {} CFileLocation(int nFileId, TFileOffset lStartOffset) : m_nFileId(nFileId), m_lStartOffset(lStartOffset) {} }; class CLongFileInstruction : public CStageInstruction { protected: CFileLocation m_Location; public: CLongFileInstruction(CLongFileStagingFile* pFile); CLongFileInstruction(CLongFileStagingFile* pFile, int nFileId, TFileOffset lStartOffset); virtual ~CLongFileInstruction(){} virtual bool IsWrite() = 0; virtual void Dump(); protected: BYTE* WriteLocation(BYTE* pBuffer); DWORD ComputeSpaceForLocation(); long RecoverLocation(HANDLE hFile); friend class CLongFileStagingFile; }; class CWriteFileInstruction : public CLongFileInstruction { protected: DWORD m_dwLen; __int64 m_lZOrder; static __int64 mstatic_lNextZOrder; bool m_bReuse; public: CWriteFileInstruction(CLongFileStagingFile* pFile) : CLongFileInstruction(pFile), m_dwLen(0), m_lZOrder(mstatic_lNextZOrder++), m_bReuse(false) { } CWriteFileInstruction(CLongFileStagingFile* pFile, int nFileId, TFileOffset lStartOffset, DWORD dwLen) : CLongFileInstruction(pFile, nFileId, lStartOffset), m_dwLen(dwLen), m_lZOrder(mstatic_lNextZOrder++), m_bReuse(false) { } virtual ~CWriteFileInstruction(){} bool IsWrite() {return true;} virtual void Dump(); virtual long Execute(); virtual long RecoverData(HANDLE hFile); void MakeTopmost(); void SetReuseFlag() { m_bReuse = true; } public: long Write(TFileOffset lOffset, BYTE* pBuffer); DWORD ComputeNeededSpace(); void GetEnd(CFileLocation* pLocation); long GetData(HANDLE hFile, long lExtraOffset, DWORD dwLen, BYTE* pBuffer); TFileOffset ComputeOriginalOffset(); friend class CLongFileStagingFile; }; class CSetEndOfFileInstruction : public CLongFileInstruction { public: CSetEndOfFileInstruction(CLongFileStagingFile* pFile) : CLongFileInstruction(pFile) {} CSetEndOfFileInstruction(CLongFileStagingFile* pFile, int nFileId, TFileOffset lLength) : CLongFileInstruction(pFile, nFileId, lLength) {} virtual ~CSetEndOfFileInstruction(){} bool IsWrite() {return false;} virtual long Execute(); virtual long RecoverData(HANDLE hFile); public: long Write(TFileOffset lOffset); DWORD ComputeNeededSpace(); friend class CLongFileStagingFile; }; class CLongFileStagingFile : public CExecutableStageManager { class CCompareLocations { public: bool operator()(const CFileLocation& loc1, const CFileLocation& loc2) const { if(loc1.m_nFileId != loc2.m_nFileId) return (loc1.m_nFileId < loc2.m_nFileId); else return loc1.m_lStartOffset < loc2.m_lStartOffset; } }; protected: typedef std::multimap > TMap; typedef TMap::iterator TIterator; typedef TMap::value_type TValue; TMap m_mapStarts; TMap m_mapEnds; struct FileInfo { HANDLE m_h; bool m_bSupportsOverwrites; } m_aFiles[A51_MAX_FILES]; public: CLongFileStagingFile(long lMaxFileSize = 0, long lAbortTransactionFileSize = 0); virtual ~CLongFileStagingFile(); public: long Create(LPCWSTR wszStagingFileName); long Initialize(); long Uninitialize(DWORD dwShutDownFlags); long RegisterFile(int nFileId, HANDLE hFile, bool bSupportsOverwrites); long ReadFile(int nFileId, DWORD dwStartOffset, BYTE* pBuffer, DWORD dwLen, DWORD* pdwRead); long WriteFile(int nFileId, DWORD dwStartOffset, BYTE* pBuffer, DWORD dwLen, DWORD* pdwRead); long SetFileLength(int nFileId, DWORD dwLen); long GetFileLength(int nFileId, DWORD* pdwLength); long CloseAllFiles(); void Dump(FILE* f); void FlushDataFiles(); protected: virtual long AddInstructionToMap(CStageInstruction* pInst, CStageInstruction** ppUndoInst); virtual long RemoveInstructionFromMap(CStageInstruction* pInst); virtual long ConstructInstructionFromType(int nType, CStageInstruction** ppInst); virtual bool IsStillCurrent(CStageInstruction* pInst); bool DoesSupportOverwrites(int nFileId); virtual long WriteEmpty(); bool InjectFailure(); protected: // for instructions long WriteToActualFile(int nFileId, TFileOffset lFileOffset, BYTE* pBuffer, DWORD dwLen); long SetEndOfActualFile(int nFileId, TFileOffset lFileLength); friend class CWriteFileInstruction; friend class CSetEndOfFileInstruction; }; #endif