Jump to content

How to check CRC32 value each other between two files?


Recommended Posts

Hi sir,

I created a test script which contains multiple files, of course the main program is built by AutoIT,  but I met a problem here, I just use below code to record every file CRC32 value into .sfv file.

#include <File.au3>
#include <Array.au3>

$directory_to_open = FileSelectFolder("Find directory to create checksum for?", @HomeDrive,2)

If @error Then
    Exit
Else
    $check = _ChecksumCreate($directory_to_open)
    If $check = -1 Then
        MsgBox(0, "Creation of Checksum - Failed", "Creating of Checksum have failed or was not possible.")
    Else
        MsgBox(0, "Creation of Checksum - Passed", "Creationg of Checksum is done.")
    EndIf
EndIf

Func _ChecksumCreate($sDirectory, $exceptions = ".CHM|.JPG|.BAT|.NFO|.M3U|.SFV")
    Local $sfv_file_name = StringTrimLeft($sDirectory, StringInStr($sDirectory, "\", 1, -1)) & ".sfv"
    Local $file_list = _FileListToArray($sDirectory, "*.*", 1)
    Local $sfv_create[1]
    $exceptions = StringSplit($exceptions, "|", 1)
    If @error = 1 Then Return SetError(-1, 0, 1)
    For $a = 1 To $file_list[0]
        Local $exception_status = False
        For $b = 1 To $exceptions[0]
            If StringRight($file_list[$a], 4) = $exceptions[$b] Then
                $exception_status = True
                ExitLoop
            EndIf
        Next
        If $exception_status = False Then
            $checksum_return = _ChecksumGetInfo($sDirectory & "\" & $file_list[$a])
            _ArrayAdd($sfv_create, $file_list[$a] & " " & $checksum_return)
        EndIf
    Next
    $sfv_create[0] = UBound($sfv_create) - 1
    _ArrayInsert ($sfv_create, 1, "; This file holds checksum for all the files in the directory.")
    _FileWriteFromArray($sDirectory & "\" & $sfv_file_name, $sfv_create, 1)
EndFunc   ;==>_ChecksumCreate

Func _ChecksumGetInfo($sFile)
    Local $nBufSize = 16384 * 8
    Local $CRC32 = 0
    If $sFile = "" Then Return SetError(1, 0, -1)
    Local $hFile = FileOpen($sFile, 16)
    For $i = 1 To Ceiling(FileGetSize($sFile) / $nBufSize)
        $CRC32 = _FastCRC32(FileRead($hFile, $nBufSize), BitNOT($CRC32))
    Next
    FileClose($hFile)
    Return Hex($CRC32, 8)
EndFunc   ;==>_ChecksumGetInfo

Func _FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)
    Local $nLen, $vTemp
    If DllStructGetSize($vBuffer) = 0 Then ; String passed
        If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
        Else
            $nLen = StringLen($vBuffer)
        EndIf
        $vTemp = DllStructCreate("byte[" & $nLen & "]")
        DllStructSetData($vTemp, 1, $vBuffer)
        $vBuffer = $vTemp
    EndIf

    ; Machine code hex strings (created by Laszlo)
    Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072DB5E8B4510F7D05DC3"

    ; Create machine code stubs
    Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)

    ; Structure for CRC32 Lookup table
    Local $CRC32LookupTable = DllStructCreate("int[" & 256 & "]")

    ; CallWindowProc under WinXP can have 0 or 4 parameters only, so pad remain params with zeros
    ; Execute stub for fill lookup table
    DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
            "ptr", DllStructGetPtr($CRC32LookupTable), _
            "int", 0, _
            "int", 0, _
            "int", 0)
    ; Execute main stub
    Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
            "ptr", DllStructGetPtr($vBuffer), _
            "uint", DllStructGetSize($vBuffer), _
            "uint", $nCRC32, _
            "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret[0]
EndFunc   ;==>_FastCRC32

 

For example, the folder name of the test script is "host", and by the above code it will generate a CRC32 data file "host.sfv", which contains all files(with some exceptions) and its checksum value, for example of the :

; This file holds checksum for all the files in the directory.
a.dll 35DCD9A9
b.exe DE55423E
launcher.exe CB90A349
<...etc.>

 

And, the "launcher.exe" is the main program for the test script and it contains in the host folder and also include its CRC32 value in host.sfv, also the executable is built by AutoIT, and the executable will check all files CRC32 value when executing it firstly, if any mismatch then the executable will pop a message box to remind operator to re-download the test script and then terminate itself(close).

Code is as below:

Func VerifyCRC32()
    MsgBox(262208, "Test Script Files CRC32 Verification", "Now verifying all files CRC32 checksum value.", 0, $hGUI)

    $file_to_open = "c:\host\host.sfv"

    If @error Then
        Exit
    Else
        $check = _ChecksumVerify($file_to_open)
        If $check = 0 Then
            MsgBox(262208, "Verification - Passed", "Verification of files OK.", 0, $hGUI)
        ElseIf $check = 1 Then
            MsgBox(262192, "Verification - Failed", "Verification of files was not possible. Probably file in wrong format or file doesn't exists!", 0, $hGUI)
            MsgBox(262160, "STOP", "Please re-download the test script, or contact Jacky for help. Closing the program.", 0, $hGUI)
            Exit
        Else
            Local $files
            If IsArray($check) Then
                For $a = 1 To $check[0]
                    $files = $files & " " & $check[$a]
                Next
                $files = StringReplace($files, " ", ",")
                MsgBox(262192, "Verification - Failed", "Verification of files failed. Following file(s) didn't pass veryfication: " & @CRLF & "[-] " & $files, 0, $hGUI)
                MsgBox(262160, "STOP", "Please re-download the test script, or contact Jacky for help. Closing the program.", 0, $hGUI)
                Exit
            Else
                MsgBox(262192, "Verification - Failed", "Verification of files was not possible. Probably file in wrong format or file doesn't exists!", 0, $hGUI)
                MsgBox(262160, "STOP", "Please re-download the test script, or contact Jacky for help. Closing the program.", 0, $hGUI)
                Exit
            EndIf

        EndIf
    EndIf
EndFunc

Func _ChecksumVerify($sFileSFV)
    ; Returns 0 if success
    ; Returns $array of failed files if there was at least one failure
    ; Return 1 if file doesn't exists or something else is wrong with the file
    Local $sfv_file_list
    Local $sfv_failed[1], $sfv_passed[1]
    Local $sFileSFVDirectory = StringLeft($sFileSFV, StringInStr($sFileSFV, "\", 1, -1) - 1)
    Local $status = _FileReadToArray($sFileSFV, $sfv_file_list)
    If $status = 0 Then Return SetError(1, 0, -1)
    For $a = 1 To $sfv_file_list[0]
        If StringLeft($sfv_file_list[$a], 1) <> ";" And StringLeft($sfv_file_list[$a], 1) <> "" Then
            $sfv_line_split = StringSplit($sfv_file_list[$a], " ", 1)
            If $sfv_line_split[0] = 2 Then
                $checksum_return = _ChecksumGetInfo($sFileSFVDirectory & "\" & $sfv_line_split[1])
                If $checksum_return = $sfv_line_split[2] Then
                    ;ConsoleWrite(@CR & $sfv_line_split[1] & " -> PASSED")
                    _ArrayAdd($sfv_passed, $sfv_line_split[1])
                Else
                    ;ConsoleWrite(@CR & $sfv_line_split[1] & " -> FAILED")
                    _ArrayAdd($sfv_failed, $sfv_line_split[1])
                EndIf
            EndIf
        EndIf
    Next
    $sfv_failed[0] = UBound($sfv_failed) - 1
    $sfv_passed[0] = UBound($sfv_passed) - 1
    If $sfv_failed[0] = 0 Then
        Return 0
    Else
        Return $sfv_failed
    EndIf
EndFunc   ;==>_ChecksumVerify

Func _ChecksumGetInfo($sFile)
    Local $nBufSize = 16384 * 8
    Local $CRC32 = 0
    If $sFile = "" Then Return SetError(1, 0, -1)
    Local $hFile = FileOpen($sFile, 16)
    For $i = 1 To Ceiling(FileGetSize($sFile) / $nBufSize)
        $CRC32 = _FastCRC32(FileRead($hFile, $nBufSize), BitNOT($CRC32))
    Next
    FileClose($hFile)
    Return Hex($CRC32, 8)
EndFunc   ;==>_ChecksumGetInfo

Func _FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)
    Local $nLen, $vTemp
    If DllStructGetSize($vBuffer) = 0 Then ; String passed
        If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
        Else
            $nLen = StringLen($vBuffer)
        EndIf
        $vTemp = DllStructCreate("byte[" & $nLen & "]")
        DllStructSetData($vTemp, 1, $vBuffer)
        $vBuffer = $vTemp
    EndIf
        ; Machine code hex strings (created by Laszlo)
    Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072DB5E8B4510F7D05DC3"
        ; Create machine code stubs
    Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)
        ; Structure for CRC32 Lookup table
    Local $CRC32LookupTable = DllStructCreate("int[" & 256 & "]")
        ; CallWindowProc under WinXP can have 0 or 4 parameters only, so pad remain params with zeros
    ; Execute stub for fill lookup table
    DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
            "ptr", DllStructGetPtr($CRC32LookupTable), _
            "int", 0, _
            "int", 0, _
            "int", 0)
    ; Execute main stub
    Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
            "ptr", DllStructGetPtr($vBuffer), _
            "uint", DllStructGetSize($vBuffer), _
            "uint", $nCRC32, _
            "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret[0]
EndFunc   ;==>_FastCRC32

 

But, as you can see that from above code the .SFV file is excluded in the CRC32 verification list(host.sfv), that means, if the operator delete the contain of the host.sfv file but keep file existed, then the launcher.exe still able to be executed, so, I just add a code into launcher.exe to ensure the host.sfv is not modified by CRC32 check as below:

VerifySFV()

Func VerifySFV()
    $file_to_open = "c:\host\host.sfv"
    $file_to_ignore = "c:\host\host_ignored.sfv"

    If Not FileExists($file_to_open) Then
        If Not FileExists($file_to_ignore) Then
            MsgBox(262160, "CRC32 Data Missing", "Could not find the CRC32 data, please re-download the test script, or contact Jacky for help. Closing the program.", 0, $hGUI)
            Exit
        ElseIf FileExists($file_to_ignore) Then
            MsgBox(262208, "Test Script Files CRC32 Verification Ignored", "The files CRC32 verification process has been ignored.", 0, $hGUI)
            Return
        EndIf
    EndIf

    $v1 = _CRC32ForFile($file_to_open)
    $v2 = "154FB3F1"

    If $v1 == $v2 Then
        Call("VerifyCRC32")
    Else
        MsgBox(262160, "CRC32 Data File Not Correct", "The CRC32 data file does not match its checksum value, please re-download the test script, or contact Jacky for help. Closing the program.", 0, $hGUI)
        Exit
    EndIf
EndFunc

Func _CRC32ForFile($sFilePath, $iPercentageRead = 100)
    $iPercentageRead = Int($iPercentageRead)
    If ($iPercentageRead > 100) Or ($iPercentageRead <= 0) Then
        $iPercentageRead = 100
    EndIf
    $iPercentageRead = ($iPercentageRead / 100) * FileGetSize($sFilePath)
    Local $iError = 0
    Local Const $hFilePath = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READ, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $SECURITY_ANONYMOUS, 0, 0)
    If @error Then
        Return SetError(1, 0, '')
    EndIf

    Local Const $hFilePathMappingObject = _WinAPI_CreateFileMapping($hFilePath, 0, 0, $PAGE_READONLY)
    $iError = @error
    _WinAPI_CloseHandle($hFilePath)
    If $iError Then
        Return SetError(2, 0, '')
    EndIf

    Local Const $pFilePath = _WinAPI_MapViewOfFile($hFilePathMappingObject, 0, $iPercentageRead, $FILE_MAP_READ)
    $iError = @error
    _WinAPI_CloseHandle($hFilePathMappingObject)
    If $iError Then
        Return SetError(3, 0, '')
    EndIf

    Local Const $iBufferSize = $iPercentageRead ; FileGetSize($sFilePath)
    Local Const $iCRC32 = _WinAPI_ComputeCrc32($pFilePath, $iBufferSize)
    $iError = @error
    _WinAPI_UnmapViewOfFile($pFilePath)
    _WinAPI_CloseHandle($hFilePathMappingObject)
    If $iError Then
        Return SetError(4, 0, '')
    EndIf
    Return SetError(0, 0, Hex($iCRC32, 8))
EndFunc   ;==>_CRC32ForFile

 

Then I ran into a logical problem, the host.sfv contains the CRC32 value of launcher.exe, but, the launcher.exe also checks the CRC32 value of host.sfv, that means, when I update the host.sfv to include the value for launcher.exe, the value of host.sfv should be changed, and then, I need to include the changed value for host.sfv in launcher.exe, but, since the launcher.exe has changed to include the new value of host.sfv, so, I need to change the host.sfv to include the new value of launcher.exe, infinite loop......

So, seems it is impossible to verify the CRC32 value each other between two files, I'd like to get your help to resolve this problem, does any alternative way can achieve my goal?

BTW, since I am new for AutoIT, and the code is referred from this forum, so, please make it easy way for me, or, modify my code directly, I'd appreciate your help!

Thanks,

Jacky

Link to comment
Share on other sites

The problem describes the "Chicken-Egg-Paradoxon"
Here is what you can do:

Create the host.sfv file with all crc checksums,with the launcher.exe crc as the last value.

When checking the host.sfv, make a temporary file of it, excluding the last crc entry.  The crc of the temporary file should go into your launcher.exe

 

 

Edited by Dan_555

Some of my script sourcecode

Link to comment
Share on other sites

11 hours ago, Dan_555 said:

The problem describes the "Chicken-Egg-Paradoxon"
Here is what you can do:

Create the host.sfv file with all crc checksums,with the launcher.exe crc as the last value.

When checking the host.sfv, make a temporary file of it, excluding the last crc entry.  The crc of the temporary file should go into your launcher.exe

 

 

Hi @Dan_555

Could you have example code so that I could understand it, thanks!

Link to comment
Share on other sites

This is how you put the launcher.exe as the last entry:

#include <File.au3>
#include <Array.au3>

$directory_to_open = FileSelectFolder("Find directory to create checksum for?", @HomeDrive,2)

If @error Then
    Exit
Else
    $check = _ChecksumCreate($directory_to_open)
    If $check = -1 Then
        MsgBox(0, "Creation of Checksum - Failed", "Creating of Checksum have failed or was not possible.")
    Else
        MsgBox(0, "Creation of Checksum - Passed", "Creationg of Checksum is done.")
    EndIf
EndIf

Func _ChecksumCreate($sDirectory, $exceptions = ".CHM|.JPG|.BAT|.NFO|.M3U|.SFV")
    Local $sfv_file_name = StringTrimLeft($sDirectory, StringInStr($sDirectory, "\", 1, -1)) & ".sfv"
    Local $file_list = _FileListToArray($sDirectory, "*.*", 1)
    Local $sfv_create[1]
    $exceptions = StringSplit($exceptions, "|", 1)
    If @error = 1 Then Return SetError(-1, 0, 1)
    For $a = 1 To $file_list[0]
        Local $exception_status = False
        For $b = 1 To $exceptions[0]
            If StringRight($file_list[$a], 4) = $exceptions[$b] Then
                $exception_status = True
                ExitLoop
            EndIf
            If StringLower($file_list[$a]) = "launcher.exe" Then
                $exception_status = True
                ExitLoop
            EndIf
        Next
        If $exception_status = False Then
            $checksum_return = _ChecksumGetInfo($sDirectory & "\" & $file_list[$a])
            _ArrayAdd($sfv_create, $file_list[$a] & " " & $checksum_return)
        EndIf
    Next
    
    ;Add launcher.exe as the last entry
    if fileexists($sDirectory & "\" & "launcher.exe") then
      $checksum_return = _ChecksumGetInfo($sDirectory & "\" & "launcher.exe")
      _ArrayAdd($sfv_create, "launcher.exe" & " " & $checksum_return)
    EndIf
    
    $sfv_create[0] = UBound($sfv_create) - 1
    _ArrayInsert ($sfv_create, 1, "; This file holds checksum for all the files in the directory.")
    _FileWriteFromArray($sDirectory & "\" & $sfv_file_name, $sfv_create, 1)
EndFunc   ;==>_ChecksumCreate

Func _ChecksumGetInfo($sFile)
    Local $nBufSize = 16384 * 8
    Local $CRC32 = 0
    If $sFile = "" Then Return SetError(1, 0, -1)
    Local $hFile = FileOpen($sFile, 16)
    For $i = 1 To Ceiling(FileGetSize($sFile) / $nBufSize)
        $CRC32 = _FastCRC32(FileRead($hFile, $nBufSize), BitNOT($CRC32))
    Next
    FileClose($hFile)
    Return Hex($CRC32, 8)
EndFunc   ;==>_ChecksumGetInfo

Func _FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)
    Local $nLen, $vTemp
    If DllStructGetSize($vBuffer) = 0 Then ; String passed
        If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
        Else
            $nLen = StringLen($vBuffer)
        EndIf
        $vTemp = DllStructCreate("byte[" & $nLen & "]")
        DllStructSetData($vTemp, 1, $vBuffer)
        $vBuffer = $vTemp
    EndIf

    ; Machine code hex strings (created by Laszlo)
    Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072DB5E8B4510F7D05DC3"

    ; Create machine code stubs
    Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)

    ; Structure for CRC32 Lookup table
    Local $CRC32LookupTable = DllStructCreate("int[" & 256 & "]")

    ; CallWindowProc under WinXP can have 0 or 4 parameters only, so pad remain params with zeros
    ; Execute stub for fill lookup table
    DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
            "ptr", DllStructGetPtr($CRC32LookupTable), _
            "int", 0, _
            "int", 0, _
            "int", 0)
    ; Execute main stub
    Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
            "ptr", DllStructGetPtr($vBuffer), _
            "uint", DllStructGetSize($vBuffer), _
            "uint", $nCRC32, _
            "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret[0]
EndFunc   ;==>_FastCRC32

and this is how you can make the temporary copy of the sfv file excluding the launcher.exe

#include <FileConstants.au3>

$fin=FileOpen ("1.sfv", $FO_READ)
$fou=FileOpen ("tmp.sfv", $FO_OVERWRITE)

While 1
$txt=FileReadLine ($fin)
if @error<>0 or StringInStr ($txt,"launcher.exe") then ExitLoop
FileWriteLine ($fou,$txt)
ConsoleWrite ($txt & @crlf)
WEnd

FileClose ($fin)
FileClose ($fou)

 

Edited by Dan_555
Sleeping ewwors

Some of my script sourcecode

Link to comment
Share on other sites

15 hours ago, Dan_555 said:

This is how you put the launcher.exe as the last entry:

#include <File.au3>
#include <Array.au3>

$directory_to_open = FileSelectFolder("Find directory to create checksum for?", @HomeDrive,2)

If @error Then
    Exit
Else
    $check = _ChecksumCreate($directory_to_open)
    If $check = -1 Then
        MsgBox(0, "Creation of Checksum - Failed", "Creating of Checksum have failed or was not possible.")
    Else
        MsgBox(0, "Creation of Checksum - Passed", "Creationg of Checksum is done.")
    EndIf
EndIf

Func _ChecksumCreate($sDirectory, $exceptions = ".CHM|.JPG|.BAT|.NFO|.M3U|.SFV")
    Local $sfv_file_name = StringTrimLeft($sDirectory, StringInStr($sDirectory, "\", 1, -1)) & ".sfv"
    Local $file_list = _FileListToArray($sDirectory, "*.*", 1)
    Local $sfv_create[1]
    $exceptions = StringSplit($exceptions, "|", 1)
    If @error = 1 Then Return SetError(-1, 0, 1)
    For $a = 1 To $file_list[0]
        Local $exception_status = False
        For $b = 1 To $exceptions[0]
            If StringRight($file_list[$a], 4) = $exceptions[$b] Then
                $exception_status = True
                ExitLoop
            EndIf
            If StringLower($file_list[$a]) = "launcher.exe" Then
                $exception_status = True
                ExitLoop
            EndIf
        Next
        If $exception_status = False Then
            $checksum_return = _ChecksumGetInfo($sDirectory & "\" & $file_list[$a])
            _ArrayAdd($sfv_create, $file_list[$a] & " " & $checksum_return)
        EndIf
    Next
    
    ;Add launcher.exe as the last entry
    if fileexists($sDirectory & "\" & "launcher.exe") then
      $checksum_return = _ChecksumGetInfo($sDirectory & "\" & "launcher.exe")
      _ArrayAdd($sfv_create, "launcher.exe" & " " & $checksum_return)
    EndIf
    
    $sfv_create[0] = UBound($sfv_create) - 1
    _ArrayInsert ($sfv_create, 1, "; This file holds checksum for all the files in the directory.")
    _FileWriteFromArray($sDirectory & "\" & $sfv_file_name, $sfv_create, 1)
EndFunc   ;==>_ChecksumCreate

Func _ChecksumGetInfo($sFile)
    Local $nBufSize = 16384 * 8
    Local $CRC32 = 0
    If $sFile = "" Then Return SetError(1, 0, -1)
    Local $hFile = FileOpen($sFile, 16)
    For $i = 1 To Ceiling(FileGetSize($sFile) / $nBufSize)
        $CRC32 = _FastCRC32(FileRead($hFile, $nBufSize), BitNOT($CRC32))
    Next
    FileClose($hFile)
    Return Hex($CRC32, 8)
EndFunc   ;==>_ChecksumGetInfo

Func _FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF)
    Local $nLen, $vTemp
    If DllStructGetSize($vBuffer) = 0 Then ; String passed
        If IsBinary($vBuffer) Then
            $nLen = BinaryLen($vBuffer)
        Else
            $nLen = StringLen($vBuffer)
        EndIf
        $vTemp = DllStructCreate("byte[" & $nLen & "]")
        DllStructSetData($vTemp, 1, $vBuffer)
        $vBuffer = $vTemp
    EndIf

    ; Machine code hex strings (created by Laszlo)
    Local $CRC32Init = "0x33C06A088BC85AF6C101740AD1E981F12083B8EDEB02D1E94A75EC8B542404890C82403D0001000072D8C3"
    Local $CRC32Exec = "0x558BEC33C039450C7627568B4D080FB60C08334D108B55108B751481E1FF000000C1EA0833148E403B450C89551072DB5E8B4510F7D05DC3"

    ; Create machine code stubs
    Local $CRC32InitCode = DllStructCreate("byte[" & BinaryLen($CRC32Init) & "]")
    DllStructSetData($CRC32InitCode, 1, $CRC32Init)
    Local $CRC32ExecCode = DllStructCreate("byte[" & BinaryLen($CRC32Exec) & "]")
    DllStructSetData($CRC32ExecCode, 1, $CRC32Exec)

    ; Structure for CRC32 Lookup table
    Local $CRC32LookupTable = DllStructCreate("int[" & 256 & "]")

    ; CallWindowProc under WinXP can have 0 or 4 parameters only, so pad remain params with zeros
    ; Execute stub for fill lookup table
    DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CRC32InitCode), _
            "ptr", DllStructGetPtr($CRC32LookupTable), _
            "int", 0, _
            "int", 0, _
            "int", 0)
    ; Execute main stub
    Local $ret = DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($CRC32ExecCode), _
            "ptr", DllStructGetPtr($vBuffer), _
            "uint", DllStructGetSize($vBuffer), _
            "uint", $nCRC32, _
            "ptr", DllStructGetPtr($CRC32LookupTable))
    Return $ret[0]
EndFunc   ;==>_FastCRC32

 

Hi @Dan_555

That code works for me, but I met another problem, when I change the file name from "launcher.exe" to "SUT_test_generator.exe", then it didn't work, I cannot see the "SUT_test_generator.exe" listed in the .sfv file, please help.

Here is the code, I've also changed the CRC32 generator.

$directory_to_open = FileSelectFolder("Find directory to create checksum for?", @HomeDrive,2)

If @error Then
    Exit
Else
    $check = _ChecksumCreate($directory_to_open)
    If $check = -1 Then
        MsgBox(0, "Creation of Checksum - Failed", "Creating of Checksum have failed or was not possible.")
    Else
        MsgBox(0, "Creation of Checksum - Passed", "Creationg of Checksum is done.")
    EndIf
EndIf

Func _ChecksumCreate($sDirectory, $exceptions = ".CHM|.JPG|.BAT|.NFO|.M3U|.SFV")
    Local $sfv_file_name = StringTrimLeft($sDirectory, StringInStr($sDirectory, "\", 1, -1)) & ".sfv"
    Local $file_list = _FileListToArray($sDirectory, "*.*", 1)
    Local $sfv_create[1]
    $exceptions = StringSplit($exceptions, "|", 1)
    If @error = 1 Then Return SetError(-1, 0, 1)
    For $a = 1 To $file_list[0]
        Local $exception_status = False
        For $b = 1 To $exceptions[0]
            If StringRight($file_list[$a], 4) = $exceptions[$b] Then
                $exception_status = True
                ExitLoop
            EndIf
            ;If StringLower($file_list[$a]) = "launcher.exe" Then
            ;    $exception_status = True
            ;    ExitLoop
            ;EndIf
            If StringLower($file_list[$a]) = "SUT_test_generator.exe" Then
                $exception_status = True
                ExitLoop
            EndIf
        Next
        If $exception_status = False Then
            $checksum_return = _CRC32ForFile($sDirectory & "\" & $file_list[$a])
            _ArrayAdd($sfv_create, $file_list[$a] & " " & $checksum_return)
        EndIf
    Next

    ;Add launcher.exe as the last entry
    ;If FileExists($sDirectory & "\" & "launcher.exe") Then
    ;   $checksum_return = _CRC32ForFile($sDirectory & "\" & "launcher.exe")
    ;   _ArrayAdd($sfv_create, "launcher.exe" & " " & $checksum_return)
    ;EndIf
    If FileExists($sDirectory & "\" & "SUT_test_generator.exe.exe") Then
        $checksum_return = _CRC32ForFile($sDirectory & "\" & "SUT_test_generator.exe")
        _ArrayAdd($sfv_create, "SUT_test_generator.exe" & " " & $checksum_return)
    EndIf

    $sfv_create[0] = UBound($sfv_create) - 1
    _ArrayInsert ($sfv_create, 1, "; This file holds checksum for all the files in the directory.")
    _FileWriteFromArray($sDirectory & "\" & $sfv_file_name, $sfv_create, 1)
EndFunc   ;==>_ChecksumCreate

Func _CRC32ForFile($sFilePath, $iPercentageRead = 100)
    $iPercentageRead = Int($iPercentageRead)
    If ($iPercentageRead > 100) Or ($iPercentageRead <= 0) Then
        $iPercentageRead = 100
    EndIf
    $iPercentageRead = ($iPercentageRead / 100) * FileGetSize($sFilePath)
    Local $iError = 0
    Local Const $hFilePath = _WinAPI_CreateFileEx($sFilePath, $OPEN_EXISTING, $GENERIC_READ, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $SECURITY_ANONYMOUS, 0, 0)
    If @error Then
        Return SetError(1, 0, '')
    EndIf

    Local Const $hFilePathMappingObject = _WinAPI_CreateFileMapping($hFilePath, 0, 0, $PAGE_READONLY)
    $iError = @error
    _WinAPI_CloseHandle($hFilePath)
    If $iError Then
        Return SetError(2, 0, '')
    EndIf

    Local Const $pFilePath = _WinAPI_MapViewOfFile($hFilePathMappingObject, 0, $iPercentageRead, $FILE_MAP_READ)
    $iError = @error
    _WinAPI_CloseHandle($hFilePathMappingObject)
    If $iError Then
        Return SetError(3, 0, '')
    EndIf

    Local Const $iBufferSize = $iPercentageRead ; FileGetSize($sFilePath)
    Local Const $iCRC32 = _WinAPI_ComputeCrc32($pFilePath, $iBufferSize)
    $iError = @error
    _WinAPI_UnmapViewOfFile($pFilePath)
    _WinAPI_CloseHandle($hFilePathMappingObject)
    If $iError Then
        Return SetError(4, 0, '')
    EndIf
    Return SetError(0, 0, Hex($iCRC32, 8))
EndFunc   ;==>_CRC32ForFile

 

===================================================================

Update, my fault, the "SUT_test_generator.exe.exe" is wrong, I need to delete extra ".exe" from code.

Edited by jackylee0908
Link to comment
Share on other sites

On 6/6/2023 at 5:24 AM, jackylee0908 said:

if any mismatch then the executable will pop a message box to remind operator to re-download the test script and then terminate itself(close).

If you distribute your files as a zip file, then a corruption is obvious.
If you wanna check anyways, use MD5/SHAxxx. Don't have/must to use CRC.
In any case, read the SFV file as data, with the last 2 entries as the hash of  everything minus the last entry and the one before with the priors, that way you can eat your cake and have it too. Since you're gonna ask to what do I mean, here it goes :

file to chech1=hash
file to chechx=hash
hash EntryOf the above as string=hash ; makes sure the above are correct
hash EntryOf the above as string, Again=hash ; makes sure all above are correct, including the hash of the prior hash was correct

Don't over engineer code. Is not worth it. 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

2 hours ago, argumentum said:

If you distribute your files as a zip file, then a corruption is obvious.
If you wanna check anyways, use MD5/SHAxxx. Don't have/must to use CRC.
In any case, read the SFV file as data, with the last 2 entries as the hash of  everything minus the last entry and the one before with the priors, that way you can eat your cake and have it too. Since you're gonna ask to what do I mean, here it goes :

file to chech1=hash
file to chechx=hash
hash EntryOf the above as string=hash ; makes sure the above are correct
hash EntryOf the above as string, Again=hash ; makes sure all above are correct, including the hash of the prior hash was correct

Don't over engineer code. Is not worth it. 

Hi @argumentum

Thanks and sorry, it is too profound for me lol.

Anyway, I decided to ignore the launcher.exe for itself CRC32 file check when executing it, just only to check other files by launcher.exe thru .sfv list.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...