Thanks to visit codestin.com
Credit goes to sourceforge.net

Menu

[r3]: / CompoundFileBinary / ZBiffHeader.cs  Maximize  Restore  History

Download this file

215 lines (190 with data), 8.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
using System;
using System.IO;
namespace CompoundFileBinary
{
public class ZBiffHeader
{
/// <summary>
/// Header Signature (8 bytes): Identification signature for the
/// compound file structure, and MUST be set to the value 0xD0, 0xCF,
/// 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.
/// </summary>
public byte[] abSig;
/// <summary>
/// Header CLSID (16 bytes): Reserved and unused class ID that MUST
/// be set to all zeros (CLSID_NULL).
/// </summary>
public Guid clid;
/// <summary>
/// Minor Version (2 bytes): Version number for non-breaking changes.
/// This field SHOULD be set to 0x003E if the major version field is
/// either 0x0003 or 0x0004.
/// </summary>
public UInt16 uMinorVersion;
/// <summary>
/// Major Version (2 bytes): Version number for breaking changes.
/// This field MUST be set to either 0x0003 (version 3) or 0x0004
/// (version 4).
/// </summary>
public UInt16 uDllVersion;
/// <summary>
/// Byte Order (2 bytes): This field MUST be set to 0xFFFE. This
/// field is a byte order mark for all integer fields, specifying
/// little-endian byte order.
/// </summary>
public UInt16 uByteOrder;
/// <summary>
/// Sector Shift (2 bytes): This field MUST be set to 0x0009, or
/// 0x000c, depending on the Major Version field. This field specifies
/// the sector size of the compound file as a power of 2.
/// *If Major Version is 3, then the Sector Shift MUST be 0x0009,
/// specifying a sector size of 512 bytes.
/// * If Major Version is 4, then the Sector Shift MUST be 0x000C,
/// specifying a sector size of 4096 bytes.
/// </summary>
public UInt16 uSectorShift;
/// <summary>
/// Mini Sector Shift (2 bytes): This field MUST be set to 0x0006. This
/// field specifies the sector size of the Mini Stream as a power of 2.
/// The sector size of the Mini Stream MUST be 64 bytes.
/// </summary>
public UInt16 uMiniSectorShift;
/// <summary>
/// Reserved (6 bytes): This field MUST be set to all zeros.
/// </summary>
public byte[] abReserved;
/// <summary>
/// Number of Directory Sectors (4 bytes): This integer field contains
/// the count of the number of directory sectors in the compound file.
/// * If Major Version is 3, then the Number of Directory Sectors MUST
/// be zero. This field is not supported for version 3 compound
/// files.
/// </summary>
public UInt32 csectDir;
/// <summary>
/// Number of FAT Sectors (4 bytes): This integer field contains the
/// count of the number of FAT sectors in the compound file.
/// </summary>
public UInt32 csectFat;
/// <summary>
/// First Directory Sector Location (4 bytes): This integer field
/// contains the starting sector number for the directory stream.
/// </summary>
public UInt32 sectDirStart;
/// <summary>
/// Transaction Signature Number (4 bytes): This integer field is
/// intended to contain a sequence number that is incremented every
/// time the compound file is saved. Forever this implementation does
/// not support transactions.
/// </summary>
public UInt32 signature;
/// <summary>
/// Mini Stream Cutoff Size (4 bytes): This integer field MUST be set
/// to 0x00001000. This field specifies the maximum size of a user-
/// defined data stream allocated from the mini FAT and mini stream,
/// and that cutoff is 4096 bytes. Any user-defined data stream larger
/// than or equal to this cutoff size must be allocated as normal
/// sectors from the FAT.
/// </summary>
public UInt32 ulMiniSectorCutoff;
/// <summary>
/// First Mini FAT Sector Location (4 bytes): This integer field
/// contains the starting sector number for the mini FAT.
/// </summary>
public UInt32 sectMiniFatStart;
/// <summary>
/// Number of Mini FAT Sectors (4 bytes): This integer field contains
/// the count of the number of mini FAT sectors in the compound file.
/// </summary>
public UInt32 csectMiniFat;
/// <summary>
/// First DIFAT Sector Location (4 bytes): This integer field contains
/// the starting sector number for the DIFAT.
/// </summary>
public UInt32 sectDifStart;
/// <summary>
/// Number of DIFAT Sectors (4 bytes): This integer field contains the
/// count of the number of DIFAT sectors in the compound file.
/// </summary>
public UInt32 csectDif;
/// <summary>
/// DIFAT (4 bytes): This array of 32-bit integer fields contains the
/// first 109 FAT sector locations of the compound file.
/// * For version 4 compound files, the header size (512 bytes) is less
/// than the sector size (4096 bytes), so the remaining part of the
/// header (3584 bytes) MUST be filled with all zeros.
/// </summary>
public UInt32[] sectFat;
public void Read(BinaryReader br)
{
abSig = br.ReadBytes(8);
clid = new Guid(br.ReadInt32(), br.ReadInt16(), br.ReadInt16(), br.ReadBytes(8));
if (clid != Guid.Empty)
throw new Exception("Reserved and unused class ID that MUST be set to all zeros (CLSID_NULL).");
uMinorVersion = br.ReadUInt16();
if (uMinorVersion != 0x003E)
throw new Exception("Only major version 3 and 4 are supported which mean that minor version must be 0x003E.");
uDllVersion = br.ReadUInt16();
if (uDllVersion != 0x0003 && uDllVersion != 0x0004)
throw new Exception("Only major version 3 and 4 are supported.");
uByteOrder = br.ReadUInt16();
if (uByteOrder != 0xFFFE)
throw new Exception("Only little-endian byte order is supported.");
uSectorShift = br.ReadUInt16();
if (uDllVersion == 0x0003 && uSectorShift != 0x0009)
throw new Exception("In Major Version 3, the Sector Shift MUST be 0x0009.");
if (uDllVersion == 0x0004 && uSectorShift != 0x000C)
throw new Exception("In Major Version 4, the Sector Shift MUST be 0x000C.");
uMiniSectorShift = br.ReadUInt16();
abReserved = br.ReadBytes(6);
if (!IsZero(abReserved))
throw new Exception("Reserve byte must be zeros.");
csectDir = br.ReadUInt32();
if (uDllVersion == 0x0003 && csectDir != 0)
throw new Exception("In Major Version 3, csectDir must be zero.");
csectFat = br.ReadUInt32();
sectDirStart = br.ReadUInt32();
signature = br.ReadUInt32();
ulMiniSectorCutoff = br.ReadUInt32();
if (ulMiniSectorCutoff != 0x00001000)
throw new Exception("ulMiniSectorCutoff MUST be set to 0x00001000.");
sectMiniFatStart = br.ReadUInt32();
csectMiniFat = br.ReadUInt32();
sectDifStart = br.ReadUInt32();
csectDif = br.ReadUInt32();
sectFat = new UInt32[109];
for (int i = 0; i < 109; i++)
sectFat[i] = br.ReadUInt32();
// Padding for major version 4.
if (uDllVersion == 0x0004)
br.ReadBytes(3584);
}
bool IsZero(byte[] bytearray)
{
foreach (byte b in bytearray)
if (b != 0)
return false;
return true;
}
public ulong SectorSize
{
get { return (ulong)(1 << (int)uSectorShift); }
}
public ulong MiniSectorSize
{
get { return (ulong)(1 << (int)uMiniSectorShift); }
}
public static ulong Pow(uint factor, uint power)
{
if (power == 0)
return 1;
ulong r = factor;
while (power > 1)
{
r *= factor;
power--;
}
return r;
}
}
}