WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Samples from Users
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

MD5 - MD4 Checksum Using the Crypto Api


MD5 / MD4 checksum with progress and cancel option, using the crypto api. It should work with files bigger than the available disk space(not posible with binarychecksum() ), i think is also faster than using binarychecksum().

The script is a running example, asks for a file and makes a MD5 reading chunks of 10MB.

;MD5/MD4 with progress and cancel option
;to use another algoritms CryptGetHashVal() will need to modified
;for the new len of the hash value, now it is set to 16 bytes for MD4/MD5.
;Guido 12/03

;CryptAcquireDefContext : Gets a handle to a default CSP
;dwProvType   : The type of provider to acquire
;Returns      : A handle to a provider
#DefineFunction CryptAcquireDefContext(provtype)
	advapi32=StrCat(DirWindows(1), "advapi32.dll")
	phProv=BinaryAlloc(4)
	DLLCall(advapi32,long:"CryptAcquireContextA",lpbinary:phProv,lpnull,lpnull,long:provtype,long:0)
	hprovider=BinaryPeek4(phProv, 0)
	BinaryFree(phProv)
	Return hprovider
#EndFunction

;CryptCreateHash : Initializes the hashing of a stream of data
;hProv   : A handle to the CSP to use
;Algid   : An algorithm identifier of the hash algorithm to use
;Returns : Handle to the new hash object
#DefineFunction CryptCreateHash(hProv,Algid)
	phHash=BinaryAlloc(4)
	advapi32=StrCat(DirWindows(1),"advapi32.dll")
	DLLCall(advapi32,long:"CryptCreateHash",long:hProv,long:Algid,long:0,long:0,lpbinary:phhash) 
	hhash=BinaryPeek4(phhash, 0)
	BinaryFree(phHash)
	Return hhash
#EndFunction

;CryptHashData : Adds data to a specified hash object
;hHash   : A handle to the hash object
;Data    : Pointer to the data to be hashed
;DataLen : The number of bytes of data to be hashed
;Returns : If the function succeeds, the return value is nonzero
#DefineFunction CryptHashData(hHash,pData,DataLen)
	advapi32=StrCat(DirWindows(1),"advapi32.dll")
	return DLLCall(advapi32,long:"CryptHashData",long:hHash,long:pData,long:DataLen,long:0)
#EndFunction

;CryptGetHashVal : Gets the hash value of a hash object
;hhash   : hash object
;Returns : hash value
;Note : hash len set to 16 bytes for MD5/MD4
#definefunction CryptGetHashVal(hHash)
	advapi32=StrCat(DirWindows(1),"advapi32.dll")
	HP_HASHVAL = 2
	datalen=16
	bData=binaryalloc(datalen)
	bdatalen=binaryalloc(4)
	binarypoke4(bdatalen,0,datalen)
	DLLCall(advapi32,long:"CryptGetHashParam",long:hHash,long:HP_HASHVAL,lpbinary:bData,lpbinary:bdatalen,long:0)
	binaryeodset(bData,datalen)
	hval=BinaryPeekHex(bdata,0,datalen)
	binaryfree(bData)
	binaryfree(bdatalen)
	Return hval
#endfunction

;CryptDestroyHash : Destroys a hash object
;hHash   : A handle to the hash object to be destroyed
;Returns : If the function succeeds, the return value is nonzero.
#DefineFunction CryptDestroyHash(hHash)
	advapi32=StrCat(DirWindows(1), "advapi32.dll")
	return DLLCall(advapi32,long:"CryptDestroyHash",long:hHash)
#EndFunction

;CryptReleaseContext : Releases a handle to a CSP and a key container.
;hProv   : A handle to the application’s CSP.
;Returns : If the function succeeds, the return value is nonzero.
#DefineFunction CryptReleaseContext(hProv)
	advapi32=StrCat(DirWindows(1), "advapi32.dll")
	return DLLCall(advapi32,long:"CryptReleaseContext",long:hProv,long:0)
#EndFunction

;+----------------------------------
;TEST
;API Constants
PROV_RSA_FULL = 1

ALG_CLASS_HASH = 4 << 13
ALG_TYPE_ANY = 0
ALG_SID_MD5 = 3
ALG_SID_MD4 = 2

CALG_MD5 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5
CALG_MD4 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4

;Get handle to default CSP
hProv=CryptAcquireDefContext(PROV_RSA_FULL)
if !hprov
	message('error','unable to get CSP handle')
	exit
endif

;Create hash object
hHash=CryptCreateHash(hProv,CALG_MD5)
if !hhash
	message('error','unable to create hash object')
	exit
endif

file=askfilename('','','','',1)
fsize=filesize(file)
chunksize=10000000 ;10 MB

if fsize<chunksize then chunksize=fsize 
lastchunksize=chunksize

nchunks=fsize / chunksize
rest=fsize mod chunksize
if rest<>0
	nchunks=nchunks+1
	lastchunksize=rest
endif

boxopen('Hashing','')
idcancel=1
BoxButtonDraw(1,idcancel,"Cancel","700,664,950,858")
foffset=0
canceled=0
for x=1 to nchunks
	boxtext('%x% / %nchunks%')
	if x==nchunks then datasize=lastchunksize
	else datasize=chunksize
	
	bdata=binaryalloc(datasize)
	pdata=intcontrol(42,bdata,0,0,0)
	BinaryReadEx(bdata,0,file,foffset,datasize)   
	CryptHashData(hHash,pData,datasize)
	binaryfree(bdata)
	foffset=foffset+datasize
	
	if BoxButtonStat(1,idcancel) ;canceled
		canceled=1
		break
	endif
next

if !canceled
	val=CryptGetHashVal(hHash)
	message('Checksum',val)
else 
	message('Checksum','Canceled by user')
endif

;free
CryptDestroyHash(hHash)
CryptReleaseContext(hProv)

;Using binary functions
;bdata=binaryalloc(fsize)
;binaryread(bdata,file)
;val2=BinaryCheckSum(bdata,0)
;binaryfree(bdata)
;message('',val2)
exit

Article ID:   W16194
File Created: 2005:11:14:09:01:32
Last Updated: 2005:11:14:09:01:32