Subversion Repositories decoder

Compare Revisions

Regard whitespace Rev 1 → Rev 2

/trunk/Build-Res.bat
0,0 → 1,6
brc32 Quelltext\Coder.rc
brc32 Quelltext\Activator.rc
brc32 Quelltext\ShlExt.rc
brc32 Quelltext\ShlErase.rc
brc32 Quelltext\SecureMoveExt.rc
pause
/trunk/Cleanup.bat
0,0 → 1,21
del Includes\*.dcu
 
del Quelltext\*.dcu
del Quelltext\*.local
del Quelltext\*.identcache
 
del VCL_DEC\*.dcu
del VCL_DEC\*.local
del VCL_DEC\*.identcache
 
del VCL_DRAGDROP\*.dcu
del VCL_DRAGDROP\*.local
del VCL_DRAGDROP\*.identcache
 
del VCL_KAZIP\*.dcu
del VCL_KAZIP\*.local
del VCL_KAZIP\*.identcache
 
del *.local
 
pause
/trunk/Coder.bdsgroup
0,0 → 1,21
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<PersonalityInfo>
<Option>
<Option Name="Personality">Default.Personality</Option>
<Option Name="ProjectType"></Option>
<Option Name="Version">1.0</Option>
<Option Name="GUID">{00261C37-1D74-466D-B1FF-6EDFDFBEAF93}</Option>
</Option>
</PersonalityInfo>
<Default.Personality> <Projects>
<Projects Name="Activator.exe">Quelltext\Activator.bdsproj</Projects>
<Projects Name="Coder.exe">Quelltext\Coder.bdsproj</Projects>
<Projects Name="SecureMoveExt.dll">Quelltext\SecureMoveExt.bdsproj</Projects>
<Projects Name="ShlErase.dll">Quelltext\ShlErase.bdsproj</Projects>
<Projects Name="ShlExt.dll">Quelltext\ShlExt.bdsproj</Projects>
<Projects Name="Targets">Activator.exe Coder.exe SecureMoveExt.dll ShlErase.dll ShlExt.dll</Projects>
</Projects>
<Dependencies/>
</Default.Personality>
</BorlandProject>
/trunk/Coder.groupproj
0,0 → 1,74
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{32976f92-0add-45c8-aa18-5ae5c4912a66}</ProjectGuid>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<Projects Include="Quelltext\Activator.dproj" />
<Projects Include="Quelltext\Coder.dproj" />
<Projects Include="Quelltext\SecureMoveExt.dproj" />
<Projects Include="Quelltext\ShlErase.dproj" />
<Projects Include="Quelltext\ShlExt.dproj" />
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Default.Personality> </Default.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Target Name="Activator">
<MSBuild Projects="Quelltext\Activator.dproj" Targets="" />
</Target>
<Target Name="Activator:Clean">
<MSBuild Projects="Quelltext\Activator.dproj" Targets="Clean" />
</Target>
<Target Name="Activator:Make">
<MSBuild Projects="Quelltext\Activator.dproj" Targets="Make" />
</Target>
<Target Name="Coder">
<MSBuild Projects="Quelltext\Coder.dproj" Targets="" />
</Target>
<Target Name="Coder:Clean">
<MSBuild Projects="Quelltext\Coder.dproj" Targets="Clean" />
</Target>
<Target Name="Coder:Make">
<MSBuild Projects="Quelltext\Coder.dproj" Targets="Make" />
</Target>
<Target Name="SecureMoveExt">
<MSBuild Projects="Quelltext\SecureMoveExt.dproj" Targets="" />
</Target>
<Target Name="SecureMoveExt:Clean">
<MSBuild Projects="Quelltext\SecureMoveExt.dproj" Targets="Clean" />
</Target>
<Target Name="SecureMoveExt:Make">
<MSBuild Projects="Quelltext\SecureMoveExt.dproj" Targets="Make" />
</Target>
<Target Name="ShlErase">
<MSBuild Projects="Quelltext\ShlErase.dproj" Targets="" />
</Target>
<Target Name="ShlErase:Clean">
<MSBuild Projects="Quelltext\ShlErase.dproj" Targets="Clean" />
</Target>
<Target Name="ShlErase:Make">
<MSBuild Projects="Quelltext\ShlErase.dproj" Targets="Make" />
</Target>
<Target Name="ShlExt">
<MSBuild Projects="Quelltext\ShlExt.dproj" Targets="" />
</Target>
<Target Name="ShlExt:Clean">
<MSBuild Projects="Quelltext\ShlExt.dproj" Targets="Clean" />
</Target>
<Target Name="ShlExt:Make">
<MSBuild Projects="Quelltext\ShlExt.dproj" Targets="Make" />
</Target>
<Target Name="Build">
<CallTarget Targets="Activator;Coder;SecureMoveExt;ShlErase;ShlExt" />
</Target>
<Target Name="Clean">
<CallTarget Targets="Activator:Clean;Coder:Clean;SecureMoveExt:Clean;ShlErase:Clean;ShlExt:Clean" />
</Target>
<Target Name="Make">
<CallTarget Targets="Activator:Make;Coder:Make;SecureMoveExt:Make;ShlErase:Make;ShlExt:Make" />
</Target>
<Import Condition="Exists('$(MSBuildBinPath)\Borland.Group.Targets')" Project="$(MSBuildBinPath)\Borland.Group.Targets" />
</Project>
/trunk/Disclaimer.txt
0,0 → 1,18
 
DISCLAIMER FOR VIATHINKSOFT (DE)CODER
 
Deutsch
 
Die Benutzung unserer Software geschieht auf eigene Gefahr! Insbesondere bei der Verschlüsselung führt z.B. eine beschädigte Datei oder ein versehentlich falsch eingegebenes oder vergessenes Passwort zum unwiderruflichen Verlust Ihrer Daten. ViaThinkSoft haftet nicht für Programmfehler und/oder verlorene Daten. Führen Sie stets ein Backup der Originaldateien durch, bevor Sie (De)Coder nutzen.
Bitte installieren Sie die Software nicht, wenn Sie mit den Bedingungen nicht einverstanden sind.
Bitte beachten Sie des Weiteren, dass aufgrund einer technischen Limitation des ZIP-Dateiformats die Gesamtgröße auf 4 GB beschränkt ist.
Um Datenverlust zu vermeiden, verschlüsseln Sie bitte nicht mehr als 1 GB an Daten.
Diese Beta-Version prüft die Dateigröße nicht!
 
English
 
Use this software at your own risk! Especially when encrypting files, a damaged file, a forgotten password or a mistyped password will lead to an irreversible loss of your data. ViaThinkSoft is not liable for any program bugs or data loss. Please always backup your unencrypted data before using (De)Coder.
Do not install the software if you do not agree with these conditions.
Please note that the ZIP file format can only handle archives of 4 GB size.
To avoid data loss, please only encrypt 1 GB in total.
In this beta version, the file size will not be checked!
/trunk/INCLUDES/OneInst.pas
0,0 → 1,147
// Abgeändert für (De)Coder 4.1
 
unit OneInst;
 
interface
 
uses
Windows, Messages, SysUtils, DCConst;
 
var
SecondInstMsgId: UINT = 0;
 
function ParamBlobToStr(lpData: Pointer): string;
function ParamStrToBlob(out cbData: DWORD): Pointer;
 
implementation
 
const
TimeoutWaitForReply = 5000;
 
var
UniqueName: array [0..MAX_PATH] of Char = 'ViaThinkSoft-DeCoder4100'#0;
MutexHandle: THandle = 0;
 
function ParamBlobToStr(lpData: Pointer): string;
var
pStr: PChar;
begin
Result := '';
pStr := lpData;
while pStr[0] <> #0 do
begin
if pStr <> '/newinstance' then
Result := Result + string(pStr) + #13#10;
pStr := @pStr[lstrlen(pStr) + 1];
end;
end;
 
function ParamStrToBlob(out cbData: DWORD): Pointer;
var
Loop: Integer;
pStr: PChar;
begin
cbData := Length(ParamStr(1)) + 3;
for Loop := 2 to ParamCount do
cbData := cbData + DWORD(Length(ParamStr(Loop)) + 1);
Result := GetMemory(cbData);
ZeroMemory(Result, cbData);
pStr := Result;
for Loop := 1 to ParamCount do
begin
lstrcpy(pStr, PChar(ParamStr(Loop)));
pStr := @pStr[lstrlen(pStr) + 1];
end;
end;
 
procedure HandleSecondInstance;
var
Run: DWORD;
Now: DWORD;
Msg: TMsg;
Wnd: HWND;
Dat: TCopyDataStruct;
begin
SendMessage(HWND_BROADCAST, SecondInstMsgId, GetCurrentThreadId, 0);
 
Wnd := 0;
Run := GetTickCount;
while True do
begin
if PeekMessage(Msg, 0, SecondInstMsgId, SecondInstMsgId, PM_NOREMOVE) then
begin
GetMessage(Msg, 0, SecondInstMsgId, SecondInstMsgId);
if Msg.message = SecondInstMsgId then
begin
Wnd := Msg.wParam;
Break;
end;
end;
Now := GetTickCount;
if Now < Run then
Run := Now;
if Now - Run > TimeoutWaitForReply then
Break;
end;
 
if (Wnd <> 0) and IsWindow(Wnd) then
begin
Dat.dwData := SecondInstMsgId;
Dat.lpData := ParamStrToBlob(Dat.cbData);
SendMessage(Wnd, WM_COPYDATA, 0, LPARAM(@Dat));
FreeMemory(Dat.lpData);
end;
end;
 
procedure CheckForSecondInstance;
var
Loop: Integer;
begin
for Loop := lstrlen(UniqueName) to MAX_PATH - 1 do
begin
MutexHandle := CreateMutex(nil, False, UniqueName);
if (MutexHandle = 0) and (GetLastError = INVALID_HANDLE_VALUE) then
lstrcat(UniqueName, '_')
else
Break;
end;
 
case GetLastError of
0:
begin
 
end;
ERROR_ALREADY_EXISTS:
begin
try
HandleSecondInstance;
finally
Halt(10);
end;
end;
else
 
end;
end;
 
initialization
 
SecondInstMsgId := RegisterWindowMessage(UniqueName);
 
if (paramstr_firstposition('/newinstance') = -1) and
(paramstr_firstposition('/c') = -1) and
(paramstr_firstposition('/x') = -1) and
(paramstr_firstposition('/e') = -1) and
(paramstr_firstposition('/?') = -1) and
(paramstr_firstposition('/clean') = -1) then
CheckForSecondInstance;
 
finalization
 
if MutexHandle <> 0 then
begin
ReleaseMutex(MutexHandle);
MutexHandle := 0;
end;
 
end.
/trunk/INCLUDES/base64.pas
0,0 → 1,572
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Unit Name : uBase64Codec
* Author : Daniel Wischnewski
* Copyright : Copyright © 2001-2003 by gate(n)etwork GmbH. All Rights Reserved.
* Creator : Daniel Wischnewski
* Contact : Daniel Wischnewski (e-mail: delphi3000(at)wischnewski.tv);
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
 
// * * * License * * *
//
// The contents of this file are used with permission, subject to the Mozilla
// Public License Version 1.1 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://www.mozilla.org/MPL/MPL-1.1.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
// the specific language governing rights and limitations under the License.
//
 
// * * * My Wish * * *
//
// If you come to use this unit for your work, I would like to know about it.
// Drop me an e-mail and let me know how it worked out for you. If you wish, you
// can send me a copy of your work. No obligations!
// My e-mail address: delphi3000(at)wischnewski.tv
//
 
// * * * History * * *
//
// Version 1.0 (Oct-10 2002)
// first published on Delphi-PRAXiS (www.delphipraxis.net)
//
// Version 1.1 (May-13 2003)
// introduced a compiler switch (SpeedDecode) to switch between a faster
// decoding variant (prior version) and a litte less fast, but secure variant
// to work around bad formatted data (decoding only!)
//
// Version 1.2 (Juni-09 2004)
// included compiler switch {$0+}. In Delphi 6 and 7 projects using this code
// with compiler optimizations turned off will raise an access violation
// {$O+} will ensure that this unit runs with compiler optimizations.
// This option does *not* influence other parts of the project including this
// unit.
// Thanks to Ralf Manschewski for pointing out this problem.
//
 
unit Base64;
 
{$O+}
 
interface
 
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !! THE COMPILER SWITCH MAY BE USED TO ADJUST THE BEHAVIOR !!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
// enable "SpeedDecode"
// the switch to gain speed while decoding the message, however, the codec
// will raise different exceptions/access violations or invalid output if
// the incoming data is invalid or missized.
 
// disable "SpeedDecode"
// the switch to enable a data check, that will scan the data to decode to
// be valid. This method is to be used if you cannot guarantee to validity
// of the data to be decoded.
 
{.DEFINE SpeedDecode}
 
{$IFNDEF SpeedDecode}
{$DEFINE ValidityCheck}
{$ENDIF}
 
 
uses SysUtils;
 
// codiert einen String in die zugehörige Base64-Darstellung
function Base64Encode(const InText: AnsiString): AnsiString; overload;
// decodiert die Base64-Darstellung eines Strings in den zugehörigen String
function Base64Decode(const InText: AnsiString): AnsiString; overload;
 
// bestimmt die Größe der Base64-Darstellung
function CalcEncodedSize(InSize: Cardinal): Cardinal;
// bestimmt die Größe der binären Darstellung
function CalcDecodedSize(const InBuffer; InSize: Cardinal): Cardinal;
 
// codiert einen Buffer in die zugehörige Base64-Darstellung
procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer); overload; register;
// decodiert die Base64-Darstellung in einen Buffer
{$IFDEF SpeedDecode}
procedure Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer); overload; register;
{$ENDIF}
{$IFDEF ValidityCheck}
function Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer): Boolean; overload; register;
{$ENDIF}
 
// codiert einen String in die zugehörige Base64-Darstellung
procedure Base64Encode(const InText: PAnsiChar; var OutText: PAnsiChar); overload;
// decodiert die Base64-Darstellung eines Strings in den zugehörigen String
procedure Base64Decode(const InText: PAnsiChar; var OutText: PAnsiChar); overload;
 
// codiert einen String in die zugehörige Base64-Darstellung
procedure Base64Encode(const InText: AnsiString; var OutText: AnsiString); overload;
// decodiert die Base64-Darstellung eines Strings in den zugehörigen String
procedure Base64Decode(const InText: AnsiString; var OutText: AnsiString); overload;
 
 
implementation
 
const
cBase64Codec: array[0..63] of AnsiChar =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
Base64Filler = '=';
 
function Base64Encode(const InText: string): string; overload;
begin
Base64Encode(InText, Result);
end;
 
function Base64Decode(const InText: string): string; overload;
begin
Base64Decode(InText, Result);
end;
 
function CalcEncodedSize(InSize: Cardinal): Cardinal;
begin
// no buffers passed along, calculate outbuffer size needed
Result := (InSize div 3) shl 2;
if ((InSize mod 3) > 0)
then Inc(Result, 4);
end;
 
function CalcDecodedSize(const InBuffer; InSize: Cardinal): Cardinal;
type
BA = array of Byte;
begin
Result := 0;
if InSize = 0 then
Exit;
if InSize mod 4 <> 0 then
Exit;
Result := InSize div 4 * 3;
if (BA(InBuffer)[InSize - 2] = Ord(Base64Filler))
then Dec(Result, 2)
else if BA(InBuffer)[InSize - 1] = Ord(Base64Filler)
then Dec(Result);
end;
 
procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer
); register;
var
ByThrees, LeftOver: Cardinal;
// reset in- and outbytes positions
asm
// load addresses for source and destination
// PBYTE(InBuffer);
mov ESI, [EAX]
// PBYTE(OutBuffer);
mov EDI, [ECX]
// ByThrees := InSize div 3;
// LeftOver := InSize mod 3;
// load InSize (stored in EBX)
mov EAX, EBX
// load 3
mov ECX, $03
// clear upper 32 bits
xor EDX, EDX
// divide by ECX
div ECX
// save result
mov ByThrees, EAX
// save remainder
mov LeftOver, EDX
// load addresses
lea ECX, cBase64Codec[0]
// while I < ByThrees do
// begin
xor EAX, EAX
xor EBX, EBX
xor EDX, EDX
cmp ByThrees, 0
jz @@LeftOver
@@LoopStart:
// load the first two bytes of the source triplet
LODSW
// write Bits 0..5 to destination
mov BL, AL
shr BL, 2
mov DL, BYTE PTR [ECX + EBX]
// save the Bits 12..15 for later use [1]
mov BH, AH
and BH, $0F
// save Bits 6..11
rol AX, 4
and AX, $3F
mov DH, BYTE PTR [ECX + EAX]
mov AX, DX
// store the first two bytes of the destination quadruple
STOSW
// laod last byte (Bits 16..23) of the source triplet
LODSB
// extend bits 12..15 [1] with Bits 16..17 and save them
mov BL, AL
shr BX, 6
mov DL, BYTE PTR [ECX + EBX]
// save bits 18..23
and AL, $3F
xor AH, AH
mov DH, BYTE PTR [ECX + EAX]
mov AX, DX
// store the last two bytes of the destination quadruple
STOSW
dec ByThrees
jnz @@LoopStart
@@LeftOver:
// there are up to two more bytes to encode
cmp LeftOver, 0
jz @@Done
// clear result
xor EAX, EAX
xor EBX, EBX
xor EDX, EDX
// get left over 1
LODSB
// load the first six bits
shl AX, 6
mov BL, AH
// save them
mov DL, BYTE PTR [ECX + EBX]
// another byte ?
dec LeftOver
jz @@SaveOne
// save remaining two bits
shl AX, 2
and AH, $03
// get left over 2
LODSB
// load next 4 bits
shl AX, 4
mov BL, AH
// save all 6 bits
mov DH, BYTE PTR [ECX + EBX]
shl EDX, 16
// save last 4 bits
shr AL, 2
mov BL, AL
// save them
mov DL, BYTE PTR [ECX + EBX]
// load base 64 'no more data flag'
mov DH, Base64Filler
jmp @@WriteLast4
@@SaveOne:
// adjust the last two bits
shr AL, 2
mov BL, AL
// save them
mov DH, BYTE PTR [ECX + EBX]
shl EDX, 16
// load base 64 'no more data flags'
mov DH, Base64Filler
mov DL, Base64Filler
// ignore jump, as jump reference is next line !
// jmp @@WriteLast4
@@WriteLast4:
// load and adjust result
mov EAX, EDX
ror EAX, 16
// save it to destination
STOSD
@@Done:
end;
 
{$IFDEF SpeedDecode}
procedure Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer);
overload; register;
{$ENDIF}
{$IFDEF ValidityCheck}
function Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer):
Boolean; overload; register;
{$ENDIF}
const
{$IFDEF SpeedDecode}
cBase64Codec: array[0..127] of Byte =
{$ENDIF}
{$IFDEF ValidityCheck}
cBase64Codec: array[0..255] of Byte =
{$ENDIF}
(
$FF, $FF, $FF, $FF, $FF, {005>} $FF, $FF, $FF, $FF, $FF, // 000..009
$FF, $FF, $FF, $FF, $FF, {015>} $FF, $FF, $FF, $FF, $FF, // 010..019
$FF, $FF, $FF, $FF, $FF, {025>} $FF, $FF, $FF, $FF, $FF, // 020..029
$FF, $FF, $FF, $FF, $FF, {035>} $FF, $FF, $FF, $FF, $FF, // 030..039
$FF, $FF, $FF, $3E, $FF, {045>} $FF, $FF, $3F, $34, $35, // 040..049
$36, $37, $38, $39, $3A, {055>} $3B, $3C, $3D, $FF, $FF, // 050..059
$FF, $FF, $FF, $FF, $FF, {065>} $00, $01, $02, $03, $04, // 060..069
$05, $06, $07, $08, $09, {075>} $0A, $0B, $0C, $0D, $0E, // 070..079
$0F, $10, $11, $12, $13, {085>} $14, $15, $16, $17, $18, // 080..089
$19, $FF, $FF, $FF, $FF, {095>} $FF, $FF, $1A, $1B, $1C, // 090..099
$1D, $1E, $1F, $20, $21, {105>} $22, $23, $24, $25, $26, // 100..109
$27, $28, $29, $2A, $2B, {115>} $2C, $2D, $2E, $2F, $30, // 110..119
$31, $32, $33, $FF, $FF, {125>} $FF, $FF, $FF // 120..127
 
{$IFDEF ValidityCheck}
{125>} , $FF, $FF, // 128..129
$FF, $FF, $FF, $FF, $FF, {135>} $FF, $FF, $FF, $FF, $FF, // 130..139
$FF, $FF, $FF, $FF, $FF, {145>} $FF, $FF, $FF, $FF, $FF, // 140..149
$FF, $FF, $FF, $FF, $FF, {155>} $FF, $FF, $FF, $FF, $FF, // 150..159
$FF, $FF, $FF, $FF, $FF, {165>} $FF, $FF, $FF, $FF, $FF, // 160..169
$FF, $FF, $FF, $FF, $FF, {175>} $FF, $FF, $FF, $FF, $FF, // 170..179
$FF, $FF, $FF, $FF, $FF, {185>} $FF, $FF, $FF, $FF, $FF, // 180..189
$FF, $FF, $FF, $FF, $FF, {195>} $FF, $FF, $FF, $FF, $FF, // 190..199
$FF, $FF, $FF, $FF, $FF, {205>} $FF, $FF, $FF, $FF, $FF, // 200..209
$FF, $FF, $FF, $FF, $FF, {215>} $FF, $FF, $FF, $FF, $FF, // 210..219
$FF, $FF, $FF, $FF, $FF, {225>} $FF, $FF, $FF, $FF, $FF, // 220..229
$FF, $FF, $FF, $FF, $FF, {235>} $FF, $FF, $FF, $FF, $FF, // 230..239
$FF, $FF, $FF, $FF, $FF, {245>} $FF, $FF, $FF, $FF, $FF, // 240..249
$FF, $FF, $FF, $FF, $FF, {255>} $FF // 250..255
{$ENDIF}
);
asm
push EBX
mov ESI, [EAX]
mov EDI, [ECX]
{$IFDEF ValidityCheck}
mov EAX, InSize
and EAX, $03
cmp EAX, $00
jz @@DecodeStart
jmp @@ErrorDone
@@DecodeStart:
{$ENDIF}
mov EAX, InSize
shr EAX, 2
jz @@Done
lea ECX, cBase64Codec[0]
xor EBX, EBX
dec EAX
jz @@LeftOver
push EBP
mov EBP, EAX
@@LoopStart:
// load four bytes into EAX
LODSD
// save them to EDX as AX is used to store results
mov EDX, EAX
// get bits 0..5
mov BL, DL
// decode
mov AH, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AH, $FF
jz @@ErrorDoneAndPopEBP
{$ENDIF}
// get bits 6..11
mov BL, DH
// decode
mov AL, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AL, $FF
jz @@ErrorDoneAndPopEBP
{$ENDIF}
// align last 6 bits
shl AL, 2
// get first 8 bits
ror AX, 6
// store first byte
STOSB
// align remaining 4 bits
shr AX, 12
// get next two bytes from source quad
shr EDX, 16
// load bits 12..17
mov BL, DL
// decode
mov AH, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AH, $FF
jz @@ErrorDoneAndPopEBP
{$ENDIF}
// align ...
shl AH, 2
// ... and adjust
rol AX, 4
// get last bits 18..23
mov BL, DH
// decord
mov BL, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp BL, $FF
jz @@ErrorDoneAndPopEBP
{$ENDIF}
// enter in destination word
or AH, BL
// and store to destination
STOSW
// more coming ?
dec EBP
jnz @@LoopStart
pop EBP
// no
// last four bytes are handled separately, as special checking is needed
// on the last two bytes (may be end of data signals '=' or '==')
@@LeftOver:
// get the last four bytes
LODSD
// save them to EDX as AX is used to store results
mov EDX, EAX
// get bits 0..5
mov BL, DL
// decode
mov AH, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AH, $FF
jz @@ErrorDone
{$ENDIF}
// get bits 6..11
mov BL, DH
// decode
mov AL, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AL, $FF
jz @@ErrorDone
{$ENDIF}
// align last 6 bits
shl AL, 2
// get first 8 bits
ror AX, 6
// store first byte
STOSB
// get next two bytes from source quad
shr EDX, 16
// check DL for "end of data signal"
cmp DL, Base64Filler
jz @@SuccessDone
// align remaining 4 bits
shr AX, 12
// load bits 12..17
mov BL, DL
// decode
mov AH, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp AH, $FF
jz @@ErrorDone
{$ENDIF}
// align ...
shl AH, 2
// ... and adjust
rol AX, 4
// store second byte
STOSB
// check DH for "end of data signal"
cmp DH, Base64Filler
jz @@SuccessDone
// get last bits 18..23
mov BL, DH
// decord
mov BL, BYTE PTR [ECX + EBX]
{$IFDEF ValidityCheck}
// check valid code
cmp BL, $FF
jz @@ErrorDone
{$ENDIF}
// enter in destination word
or AH, BL
// AH - AL for saving last byte
mov AL, AH
// store third byte
STOSB
@@SuccessDone:
{$IFDEF ValidityCheck}
mov Result, $01
jmp @@Done
@@ErrorDoneAndPopEBP:
pop EBP
@@ErrorDone:
mov Result, $00
{$ENDIF}
@@Done:
pop EBX
end;
 
procedure Base64Encode(const InText: PAnsiChar; var OutText: PAnsiChar);
var
InSize, OutSize: Cardinal;
begin
// get size of source
InSize := Length(InText);
// calculate size for destination
OutSize := CalcEncodedSize(InSize);
// reserve memory
OutText := StrAlloc(Succ(OutSize));
OutText[OutSize] := #0;
// encode !
Base64Encode(InText, InSize, OutText);
end;
 
procedure Base64Encode(const InText: AnsiString; var OutText: AnsiString);
overload;
var
InSize, OutSize: Cardinal;
PIn, POut: Pointer;
begin
// get size of source
InSize := Length(InText);
// calculate size for destination
OutSize := CalcEncodedSize(InSize);
// prepare string length to fit result data
SetLength(OutText, OutSize);
PIn := @InText[1];
POut := @OutText[1];
// encode !
Base64Encode(PIn, InSize, POut);
end;
 
procedure Base64Decode(const InText: PAnsiChar; var OutText: PAnsiChar);
overload;
var
InSize, OutSize: Cardinal;
begin
// get size of source
InSize := Length(InText);
// calculate size for destination
OutSize := CalcDecodedSize(InText, InSize);
// reserve memory
OutText := StrAlloc(Succ(OutSize));
OutText[OutSize] := #0;
// encode !
{$IFDEF SpeedDecode}
Base64Decode(InText, InSize, OutText);
{$ENDIF}
{$IFDEF ValidityCheck}
if not Base64Decode(InText, InSize, OutText) then
OutText[0] := #0;
{$ENDIF}
end;
 
procedure Base64Decode(const InText: AnsiString; var OutText: AnsiString);
overload;
var
InSize, OutSize: Cardinal;
PIn, POut: Pointer;
begin
// get size of source
InSize := Length(InText);
// calculate size for destination
PIn := @InText[1];
OutSize := CalcDecodedSize(PIn, InSize);
// prepare string length to fit result data
SetLength(OutText, OutSize);
FillChar(OutText[1], OutSize, '.');
POut := @OutText[1];
// encode !
{$IFDEF SpeedDecode}
Base64Decode(PIn, InSize, POut);
{$ENDIF}
{$IFDEF ValidityCheck}
if not Base64Decode(PIn, InSize, POut) then
SetLength(OutText, 0);
{$ENDIF}
end;
 
end.