All pastes #905555 Raw Edit

Untitled

public cpp v1 · immutable
·published 2008-02-15 21:28 UTC
rendered paste body
#include <vector>typedef unsigned long ULONG;    // 4 Bytestypedef unsigned short USHORT;  // 2 Bytestypedef short OFFSET;           // 2 Bytestypedef ULONG SECT;             // 4 Bytestypedef ULONG FSINDEX;          // 4 Bytestypedef USHORT FSOFFSET;        // 2 Bytestypedef USHORT WCHAR;           // 2 Bytestypedef ULONG DFSIGNATURE;      // 4 Bytestypedef unsigned char BYTE;     // 1 Bytetypedef unsigned short WORD;    // 2 Bytestypedef unsigned long DWORD;    // 4 Bytestypedef ULONG SID;              // 4 Bytestypedef __int64 TMSTMP; // 8 bytestypedef struct _GUID {    unsigned long  Data1;    unsigned short Data2;    unsigned short Data3;    unsigned char  Data4[ 8 ];} GUID;typedef GUID CLSID;             // 16 Bytesenum E_DIRECTORY_TYPE{	EDT_EMPTY = 0,	EDT_USER_STORAGE=1,	EDT_USER_STREAM=2,	EDT_LOCK_BYTES=3,	EDT_PROPERTY=4,	EDT_ROOT_STORAGE=5};struct StructuredStorageHeader {                               // [offset from start (bytes), length (bytes)]    BYTE _abSig[8];             // [00H,08] {0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1,                                // 0x1a, 0xe1} for current version    CLSID _clsid;               // [08H,16] reserved must be zero (WriteClassStg/                                // GetClassFile uses root directory class id)    USHORT _uMinorVersion;      // [18H,02] minor version of the format: 33 is                                // written by reference implementation    USHORT _uDllVersion;        // [1AH,02] major version of the dll/format: 3 for                                // 512-byte sectors, 4 for 4 KB sectors    USHORT _uByteOrder;         // [1CH,02] 0xFFFE: indicates Intel byte-ordering    USHORT _uSectorShift;       // [1EH,02] size of sectors in power-of-two;                                // typically 9 indicating 512-byte sectors    USHORT _uMiniSectorShift;   // [20H,02] size of mini-sectors in power-of-two;                                // typically 6 indicating 64-byte mini-sectors    USHORT _usReserved;         // [22H,02] reserved, must be zero    ULONG _ulReserved1;         // [24H,04] reserved, must be zero    FSINDEX _csectDir;          // [28H,04] must be zero for 512-byte sectors,                                // number of SECTs in directory chain for 4 KB                                // sectors    FSINDEX _csectFat;          // [2CH,04] number of SECTs in the FAT chain    SECT _sectDirStart;         // [30H,04] first SECT in the directory chain    DFSIGNATURE _signature;     // [34H,04] signature used for transactions; must                                // be zero. The reference implementation                                // does not support transactions    ULONG _ulMiniSectorCutoff;  // [38H,04] maximum size for a mini stream;                                // typically 4096 bytes    SECT _sectMiniFatStart;     // [3CH,04] first SECT in the MiniFAT chain    FSINDEX _csectMiniFat;      // [40H,04] number of SECTs in the MiniFAT chain    SECT _sectDifStart;         // [44H,04] first SECT in the DIFAT chain    FSINDEX _csectDif;          // [48H,04] number of SECTs in the DIFAT chain	SECT _sectFat[109];         // [4CH,436] the SECTs of first 109 FAT sectors	void dump()	{		printf("Header is %s\n", isValid() ? "valid" : "invalid" );		printf("%d bytes long\n", sizeof(StructuredStorageHeader));		if (isValid())		{			printf("Microsoft Compound File Binary Format v%d.%d (%s)\n", 				_uDllVersion, _uMinorVersion, (_uByteOrder == 0xFFFE) ? "Intel" : "Big Endian");			printf("Sector size: %d (%db)\n", _uSectorShift, 1<<_uSectorShift );			printf("Mini sector size: %d (%db)\n", _uMiniSectorShift, 1<<_uMiniSectorShift );			if (_ulReserved1 != 0 || _usReserved != 0 || _signature != 0)				printf("Should be 0: %d, %d, %d\n", _ulReserved1, _usReserved, _signature);			printf("SECTs in directory chain: %d\nFirst directory SECT: #%d\n", _csectDir, _sectDirStart);			printf("Size of SAT in sectors: %d\n", _csectFat);			printf("Max mini-stream size: %d\n", _ulMiniSectorCutoff);			printf("First mini-SAT SECT: %d\nMini SAT count: %d\n", _sectMiniFatStart, _csectMiniFat);			printf("DIFAT SECT start: %d\nDIFAT SECT count: %d\n\n", _sectDifStart, _csectDif);		}	}	bool isValid()	{		return(_abSig[0] == 0xd0 && _abSig[1] == 0xcf && _abSig[2] == 0x11 && _abSig[3] == 0xe0 &&			   _abSig[4] == 0xa1 && _abSig[5] == 0xb1 && _abSig[6] == 0x1a && _abSig[7] == 0xe1);	}};struct DirectoryStructureNode{	wchar_t Name[32];    // name of the entry	USHORT  NameSize;    // size of name in bytes not chars	BYTE	Type;        // type of the entry: 0=empty,             1=user storage (dir),	                     //                    2=user stream (file) 3=lock bytes	                     //                    4=property           5=root storage	BYTE    Colour;      // Node colour in tree: 0=red, 1=black	DWORD	LeftChild;   // Left child in the tree, or -1	DWORD	RightChild;  // Left child in the tree, or -1	DWORD	RootNode;    // ID of the root	CLSID   UniqueID;    // GUID	DWORD   UserFlags;   // 0	TMSTMP  Created;     // usually 0s	TMSTMP  Modified;    // usually 0s	SECT    StreamStart; // sector id of stream or short stream 	DWORD   StreamLength;// length of the stream in bytes	DWORD	NotUsed;     // 0	void dump()	{		wprintf(L"Name: %s\n", Name);	}};struct Sector{	Sector(	char *data, unsigned int index, unsigned int size)		: Start(data), Data(data+index*size), Index(index), Size(size) { }	char& operator[](unsigned int idx) 	{ 		return (char&)(Data[Index*Size + idx]); 	}	union	{		char *Data;		SECT *SectorList;		DirectoryStructureNode* DirectoryList;	};	char *Start; // start of all sectors	unsigned int Index; // index of this sector	unsigned int Size; // size of sector};// list of sectorsstruct SStream{	SStream() : Data() { }	char& getChar(int idx) 	{		int i=0;		int max = Data[0]->Size;		while (idx > max)			idx -= Data[i++]->Size;		return Data[i]->Data[idx];	}	int size()	{		if (!Data.size())			return 0;		else			return int(Data.size()) * Data[0]->Size;	}	std::vector<Sector*> Data;};struct SAllocationTable : public SStream{	SAllocationTable() : SStream() { }	~SAllocationTable()	{		// delete streams	}	void dump()	{	}	SECT& operator [](int idx)	{		int i=0;		int max = Data[0]->Size / 4;		while (idx > max)			idx -= Data[i++]->Size / 4;		return Data[i]->SectorList[idx];	}	void buildStream( SStream* stream, SECT start)	{		Data.push_back();	}};class MSCFBFFile{public:	MSCFBFFile(char* data, unsigned int size) 		: Data(data), DataSize(size), Header((StructuredStorageHeader*)data), 		  Sector0(&Data[0x204]), 		  SectorSize(1<<(Header->_uSectorShift))	{		Header->dump();		SAT = new SAllocationTable();		int i=0;				//while MSAT[i] !=		//Sector s(Data[512], , );		//SAT.push_back(Sector(Sector0, i, SectorSize)); 		// add all sectors to AllSectors array		int count=0;		for (i=0x204; i<int(DataSize)-0x204; i += SectorSize)		{			AllSectors.push_back( new Sector(Sector0, count, SectorSize));			count++;		}		// build sat from header		for (i=0; i<109; ++i)		{			if (Header->_sectFat[i] != -1)				SAT->Data.push_back( AllSectors[ Header->_sectFat[i] ] ); 		}				// continue adding from fragmented sectors		int nextSect = Header->_sectFat[i];		while (nextSect != -3)		{			Sector *s = AllSectors[nextSect];			for (i=0; i < (s->Size/4)-1; ++i)			{				int sec = s->SectorList[i];				if (sec != -1)					SAT->Data.push_back( AllSectors[sec] );			}			nextSect = AllSectors[nextSect]->SectorList[i];		}		// build the mini sat		MiniSAT  = new SAllocationTable();		MiniSat->buildStream(MiniSat		RootDirectory = (DirectoryStructureNode*)(&AllSectors[Header->_sectDirStart]);	}	~MSCFBFFile()	{		// destroy sat		delete SAT;		// destroy mini-sat		delete MiniSAT;		// destroy filesystem		// destroy all sectors		for (int i=0; i<AllSectors.size(); ++i)			delete AllSectors[i];	}private:	char *Data;	unsigned int DataSize;	StructuredStorageHeader *Header;	DirectoryStructureNode *RootDirectory;	SAllocationTable *SAT;	SAllocationTable *MiniSAT;	char *Sector0;	unsigned int SectorSize;	std::vector<Sector*> AllSectors;};