mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.3 KiB
198 lines
5.3 KiB
/*++
|
|
|
|
Copyright (C) 2000-2001 Microsoft Corporation
|
|
|
|
--*/
|
|
|
|
#ifndef __WMI_A51_LONG_STAGE__H_
|
|
#define __WMI_A51_LONG_STAGE__H_
|
|
|
|
#include <queue>
|
|
#include <map>
|
|
#include <list>
|
|
#include <sync.h>
|
|
#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<CFileLocation, CWriteFileInstruction*,
|
|
CCompareLocations,
|
|
CPrivateTempAllocator<CWriteFileInstruction*> > 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
|