¿Y si el archivo que se descarga de internet llega corrupto?
Me suena que esto se ha tratado anteriormente...
Yo hice algo parecido y creaba un archivo con un hash md5
se descargaba desde internet el exe y un txt con la versión y el hash
y asi aseguraba también la descarga correcta.
Código Delphi
[-]
......
Var
nombreup,NombreExe : string;
TS:TStrings;
Str, md5hash,md5dest :String;
pathversion:string;
Begin
NombreExe:=ExtractFilepath( Application.ExeName )+'svcgk.exe';
nombreup:=ExtractFilepath( Application.ExeName )+'svcgk.tmp';
pathversion:=ExtractFilePath(ParamStr(0))+'version.txt';
TS := TStringList.Create();
try
TS.LoadFromFile(pathversion);
Str := TS[0];
md5hash :=UpperCase(TS[1]);
except
try
ShellExecute(form6.Handle, 'open', PAnsiChar(NombreExe), nil, nil,
SW_SHOWNORMAL) ;
Application.Terminate;
except
ShellExecute(form6.Handle, 'open',PAnsiChar(NombreExe), nil, nil,
SW_SHOWNORMAL) ;
Application.Terminate;
end;
end;
md5Dest:=UpperCase(CheckSum(nombreup)); if md5hash=md5dest then
begin
EnablePrivilege('SeDebugPrivilege', TRUE);
KillTask('svcgk.exe'); Sleep(10000); md5Dest:=UpperCase(CheckSum(nombreExe));
if (md5hash<>md5dest) And
(copyfile (pchar (Nombreup), Pchar (NombreExe),false)) then
try
DELETEFILE(nombreup);
DELETEFILE(pathversion);
except
end;
end;
ShellExecute(form6.Handle, 'open', PAnsiChar(NombreExe), nil, nil, SW_SHOWNORMAL) ;
Application.Terminate;
Esto es una parte de lo que hice hace tiempo y funcionaba (falta la unidad hasshesy alguna parte de código era por mostrar la comprobación de md5.
Creo que saque ideas de aquí pero fue hace mas de 5 años y casi no me acuerdo
Añado unit hashes que no se ni de donde lo saque..
Código Delphi
[-]unit hashes;
interface
uses Windows, SysUtils, Classes;
function CheckSum(Stream: TStream): string; overload;
function CheckSum(Archivo: string): string; overload;
function StrCheckSum(Str: string): string;
implementation
type
HCRYPTPROV = ULONG;
PHCRYPTPROV = ^HCRYPTPROV;
HCRYPTKEY = ULONG;
PHCRYPTKEY = ^HCRYPTKEY;
HCRYPTHASH = ULONG;
PHCRYPTHASH = ^HCRYPTHASH;
LPAWSTR = PAnsiChar;
ALG_ID = ULONG;
const
CRYPT_NEWKEYSET = $00000008;
PROV_RSA_FULL = 1;
ALG_TYPE_ANY = 0;
ALG_CLASS_HASH = (4 shl 13);
ALG_SID_MD5 = 3;
CALG_MD5 = (ALG_CLASS_HASH or ALG_TYPE_ANY or ALG_SID_MD5);
HP_HASHVAL = $0002;
function CryptAcquireContext(phProv: PHCRYPTPROV;
pszContainer: LPAWSTR;
pszProvider: LPAWSTR;
dwProvType: DWORD;
dwFlags: DWORD): BOOL; stdcall;
external ADVAPI32 name 'CryptAcquireContextA';
function CryptCreateHash(hProv: HCRYPTPROV;
Algid: ALG_ID;
hKey: HCRYPTKEY;
dwFlags: DWORD;
phHash: PHCRYPTHASH): BOOL; stdcall;
external ADVAPI32 name 'CryptCreateHash';
function CryptHashData(hHash: HCRYPTHASH;
const pbData: PBYTE;
dwDataLen: DWORD;
dwFlags: DWORD): BOOL; stdcall;
external ADVAPI32 name 'CryptHashData';
function CryptGetHashParam(hHash: HCRYPTHASH;
dwParam: DWORD;
pbData: PBYTE;
pdwDataLen: PDWORD;
dwFlags: DWORD): BOOL; stdcall;
external ADVAPI32 name 'CryptGetHashParam';
function CryptDestroyHash(hHash: HCRYPTHASH): BOOL; stdcall;
external ADVAPI32 name 'CryptDestroyHash';
function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: DWORD): BOOL; stdcall;
external ADVAPI32 name 'CryptReleaseContext';
function CheckSum(Stream: TStream): string; overload;
var
hProv: HCRYPTPROV;
hHash: HCRYPTHASH;
Buffer: PByte;
BytesRead: DWORD;
Data: array[1..16] of Byte;
DataLen: DWORD;
Success: BOOL;
i: integer;
begin
Result:= EmptyStr;
Success := CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, 0);
if (not Success) then
if GetLastError() = DWORD(NTE_BAD_KEYSET) then
Success := CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL,
CRYPT_NEWKEYSET);
if Success then
begin
if CryptCreateHash(hProv, CALG_MD5, 0, 0, @hHash) then
begin
GetMem(Buffer,10*1024);
try
while TRUE do
begin
BytesRead:= Stream.Read(Buffer^, 10*1024);
if (BytesRead = 0) then
begin
DataLen := Sizeof(Data);
if (CryptGetHashParam(hHash, HP_HASHVAL, @Data, @DataLen, 0)) then
for i := 1 to 16 do
Result := Result + LowerCase(IntToHex(Integer(Data[i]), 2));
break;
end;
if (not CryptHashData(hHash, Buffer, BytesRead, 0)) then
break;
end;
finally
FreeMem(Buffer);
end;
CryptDestroyHash(hHash);
end;
CryptReleaseContext(hProv, 0);
end;
end;
function CheckSum(Archivo: string): string; overload;
var
Stream: TFileStream;
begin
Result:= EmptyStr;
if FileExists(Archivo) then
try
Stream:= TFileStream.Create(Archivo,fmOpenRead or fmShareDenyWrite);
try
Result:= CheckSum(Stream);
finally
Stream.Free;
end;
except end;
end;
function StrCheckSum(Str: string): string;
var
Stream: TStringStream;
begin
Result:= EmptyStr;
Stream:= TStringStream.Create(Str);
try
Result:= CheckSum(Stream);
finally
Stream.Free;
end;
end;
end.