unit uEncase;
interface
uses
Windows, SysUtils, Classes, Controls;
type
TSectionType = (stHeader, stVolume, stDisk, stTable, stSection, stData, stError2, stHash, stNext, stDone);
TEncaseHeader =
packed record
MagicBytes :
Array[0..7]
of Byte;
ID : Byte;
// Immer 0x01
SegmentNumber : Word;
ControlID : Word;
// Immer 0x0000
end;
TEncaseSection =
packed record
SectionType :
Array[0..15]
of AnsiChar;
Offset : Int64;
Size : Int64;
Reserved :
Array[0..39]
of Byte;
CRCValue : DWORD;
end;
TEncaseHeaderSection =
record
Aktenzahl,
BeweisID,
Beschreibung,
Ersteller,
Notizen,
ErstellDatum,
SystemZeit,
PwHash,
Compression,
EncaseVersion,
OSVersion :
String;
end;
TEncaseVolumeDiskSection =
packed record
Reserved : DWORD;
ClusterCount : DWORD;
SectorPerCluster: DWORD;
BytesPerSector : DWORD;
SectorCount : DWORD;
Reserved1 :
Array[0..19]
of Byte;
Fill :
Array of Byte;
CRCValue : DWORD;
end;
TEncaseTableSection =
packed record
Count : DWORD;
Fill :
Array[0..15]
of Byte;
CRCValue : DWORD;
Offset :
Array[Count * Word]
of Byte;
CRCValue2 : DWORD;
end;
TEncaseHashSection =
packed record
MD5Hash :
Array[0..15]
of Byte;
CRCValue : DWORD;
end;
function IsMagicEncase(MagicBytes :
Array of Byte) : Boolean;
function GetSectionType(SectionType :
Array of AnsiChar) : TSectionType;
function GetHeaderSection(Buffer : TBytes): TEncaseHeaderSection;
implementation
uses
zLib;
function CRC(
const sString:
String; iPrevKey: DWord = 1): DWord;
var
Buf:
String;
b, d: DWord;
i: Integer;
begin
Buf := sString;
b := iPrevKey
and $ffff;
d := (iPrevKey
shr 16)
and $ffff;
for i := 1
to Length(sString)
do begin
Inc(b, Ord(Buf[i]));
Inc(d, b);
if ( (i <> 0)
and ( (i
mod $15b0 = 0)
or (i = Length(sString)) ) )
then begin
b := b
mod $fff1;
d := d
mod $fff1;
end;
end;
Result := ((d
shl 16)
or b);
end;
function IsMagicEncase(MagicBytes :
Array of Byte) : Boolean;
begin
Result := false;
if Length(MagicBytes) = 8
then
begin
Result := ((MagicBytes[0] = 69)
and
(MagicBytes[1] = 86)
and
(MagicBytes[2] = 70)
and
(MagicBytes[3] = 9)
and
(MagicBytes[4] = 13)
and
(MagicBytes[5] = 10)
and
(MagicBytes[6] = 255)
and
(MagicBytes[7] = 0));
end;
end;
function GetSectionType(SectionType :
Array of AnsiChar) : TSectionType;
begin
if SectionType = '
header'
then Result := stHeader
else
if SectionType = '
volume'
then Result := stVolume
else
if SectionType = '
disk'
then Result := stDisk
else
if SectionType = '
table'
then Result := stTable
else
if SectionType = '
section'
then Result := stSection
else
if SectionType = '
data'
then Result := stData
else
if SectionType = '
error2'
then Result := stError2
else
if SectionType = '
hash'
then Result := stHash
else
if SectionType = '
next'
then Result := stNext
else
if SectionType = '
done'
then Result := stDone;
end;
function GetHeaderSection(Buffer :TBytes): TEncaseHeaderSection;
var
MS : TMemoryStream;
OS : TMemoryStream;
DS : TZDecompressionStream;
S :
String;
begin
MS := TMemoryStream.Create;
try
MS.
Write(Buffer, Length(Buffer));
MS.Position := 0;
OS := TMemoryStream.Create;
try
DS := TZDecompressionStream.Create(MS);
try
DS.Position := 0;
OS.CopyFrom(DS, DS.Size);
finally
DS.Free;
end;
OS.
Write(S, SizeOf(
String));
finally
OS.Free;
end;
finally
MS.Free;
end;
end;
end.