jackylee0908 Posted June 1, 2023 Share Posted June 1, 2023 (edited) Hi sir, I can run below code normally on Intel 12th generation processor platform with Windows 11 Pro OS, below code is about to create CRC32 checksum data from selected folder. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** ;#AutoIt3Wrapper_icon=..\..\Project.ICONS\Key.ico ;#AutoIt3Wrapper_outfile=checksum_creator_1.0.exe ;#AutoIt3Wrapper_Res_Description=Checksum Creator ;#AutoIt3Wrapper_Res_Fileversion=1.0.0.0 ;#AutoIt3Wrapper_Res_LegalCopyright=Checksum Creator ;#AutoIt3Wrapper_Run_Au3Stripper=y ;#Au3Stripper_Parameters=/mo /soi #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #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 _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 Â >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\SynologyDrive\Test Tools\AutoIt3 codes\checksum_creator_1.0.au3" /UserParams +>16:57:46 Starting AutoIt3Wrapper (21.316.1639.1) from:SciTE.exe (4.4.6.0) Keyboard:00000404 OS:WIN_11/2009 CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\s5814\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\s5814\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.16.1) from:C:\Program Files (x86)\AutoIt3 input:C:\SynologyDrive\Test Tools\AutoIt3 codes\checksum_creator_1.0.au3 +>16:57:47 AU3Check ended.rc:0 >Running:(3.3.16.1):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\SynologyDrive\Test Tools\AutoIt3 codes\checksum_creator_1.0.au3" +>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart or Ctrl+BREAK to Stop. +>16:57:52 AutoIt3.exe ended.rc:0 +>16:57:52 AutoIt3Wrapper Finished. >Exit code: 0 Time: 5.807 Â But, when I try to run same code on HPE DL380p Gen8 Server which is the product launched in year 2012(pretty old), the code couldn't executed properly with Windows Server 2022 Datacenter, and there is an error message appeared from console. >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\Users\Administrator\Desktop\checksum_creator_1.0.au3" /UserParams +>16:55:14 Starting AutoIt3Wrapper (21.316.1639.1) from:SciTE.exe (4.4.6.0) Keyboard:00000409 OS:WIN_2022/2009 CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\Administrator\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\Administrator\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.16.1) from:C:\Program Files (x86)\AutoIt3 input:C:\Users\Administrator\Desktop\checksum_creator_1.0.au3 +>16:55:14 AU3Check ended.rc:0 >Running:(3.3.16.1):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\Administrator\Desktop\checksum_creator_1.0.au3" +>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart or Ctrl+BREAK to Stop. !>16:55:22 AutoIt3.exe ended.rc:-1073741819 +>16:55:22 AutoIt3Wrapper Finished. >Exit code: 3221225477 Time: 9.418 Â I just googled and found similar issue which happened years ago(see below links), and from that topic it seems that related heavy usage of DllCallbackRegister. https://github.com/genius257/AutoItObject-Internal/issues/5 I've no idea if my code also is limited with the HW, say that the code could not work with older platform which is with lower performance than recent computers. Or, does it related to the OS? But no matter on Windows 11 Pro or Windows Server 2022 Datacenter, both are with x64. Â Below is the simple information about the old platform. Â Do you have any suggestion for me to resolve this problem? Thanks, Jacky Edited June 1, 2023 by jackylee0908 Link to comment Share on other sites More sharing options...
Danp2 Posted June 1, 2023 Share Posted June 1, 2023 Quote   Local $file_list = _FileListToArray($sDirectory, "*.*", 1) You should add some error checking here because your subsequent code will fail if the user selected an empty directory. Beyond that, I would suggest that you add some logging to the code so that you can identify which line is causing the crash. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
argumentum Posted June 1, 2023 Share Posted June 1, 2023 (edited) 8 hours ago, jackylee0908 said: Func _FastCRC32($vBuffer, $nCRC32 = 0xFFFFFFFF) #include <WinAPISys.au3> Func _CRC32ofStr($sStr) Local $bData = StringToBinary($sStr) Local $iLength = BinaryLen($bData), $tData If $iLength = 0 Then Return SetError(1, 0, 0) $tData = DllStructCreate('byte data[' & $iLength & ']') $tData.data = $bData Return Hex(_WinAPI_ComputeCrc32(DllStructGetPtr($tData), $iLength), 8) EndFunc ;==>_CRC32ofStr hope this fixes it ( have not tried your code but I figure that may be it ) Edit: look at this topic/204067-file-checksum  Edited June 1, 2023 by argumentum oops Zedna 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
jackylee0908 Posted June 5, 2023 Author Share Posted June 5, 2023 On 6/2/2023 at 1:10 AM, argumentum said: #include <WinAPISys.au3> Func _CRC32ofStr($sStr) Local $bData = StringToBinary($sStr) Local $iLength = BinaryLen($bData), $tData If $iLength = 0 Then Return SetError(1, 0, 0) $tData = DllStructCreate('byte data[' & $iLength & ']') $tData.data = $bData Return Hex(_WinAPI_ComputeCrc32(DllStructGetPtr($tData), $iLength), 8) EndFunc ;==>_CRC32ofStr hope this fixes it ( have not tried your code but I figure that may be it ) Edit: look at this topic/204067-file-checksum  Hi @argumentum Thanks for your comment, but since I am new on AutoIT, and the code was referred from this forum, do you mind help to modify the code I posted on above, then I can try it directly. Appreciated your help! Link to comment Share on other sites More sharing options...
Solution argumentum Posted June 5, 2023 Solution Share Posted June 5, 2023 expandcollapse popup#include <APIConstants.au3> #include <WinAPIEx.au3> ConsoleWrite(@CRLF & _CRC32ForFile(@ScriptFullPath) & @CRLF & @CRLF) ; basically this. You code the rest. ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CRC32ForFile ; Description ...: Calculates CRC32 value for the specific file. ; Syntax ........: _CRC32ForFile($sFilePath) ; Parameters ....: $sFilePath - Full path to the file to process. ; $iPercentageRead - [optional] Percentage of file to read. Default is 100. ; Return values .: Success - Returns CRC32 value in the form of a hex string ; - Sets @error to 0 ; Failure - Returns empty string and sets @error: ; |1 - CreateFile function or call to it failed. ; |2 - CreateFileMapping function or call to it failed. ; |3 - MapViewOfFile function or call to it failed. ; |4 - RtlComputeCrc32 function or call to it failed. ; Author ........: trancexx ; Modified ......: guinness ; Link ..........: http://www.autoitscript.com/forum/topic/95558-crc32-md4-md5-sha1-for-files/ ; Example .......: No ; =============================================================================================================================== 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 This CRC32 should work without crashing if the file will fit in memory. Other than that, I'd use something coded just for that. You'll have to search online. Now if you like to use MD5 or SHA1 then you can use the _Crypt_HashFile() functions from the help file. That will give you a better collision resolution than CRC32. Musashi 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
jackylee0908 Posted June 6, 2023 Author Share Posted June 6, 2023 (edited) Hi @argumentum Thanks, it works for me, but when I add to check a file checksum by "If", and seems it does not work for me, the part code is as below. $file_to_open = "c:\dmcheck\dmcheck.sfv" ConsoleWrite(@CRLF & _CRC32ForFile($file_to_open) & @CRLF & @CRLF) ; basically this. You code the rest. $v1 = _CRC32ForFile($file_to_open) ConsoleWrite($v1) If Not $v1 = "E1866101" Then MsgBox(262160, "FAIL", "File check failed.") Else MsgBox(262160, "PASS", "File check passed.") EndIf And here is the output. >"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\SynologyDrive\Test Tools\AutoIt3 codes\temp36-crc32 for file.au3" /UserParams +>09:27:46 Starting AutoIt3Wrapper (21.316.1639.1) from:SciTE.exe (4.4.6.0) Keyboard:00000404 OS:WIN_11/2009 CPU:X64 OS:X64 Environment(Language:0409) CodePage:0 utf8.auto.check:4 +> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\s5814\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\s5814\AppData\Local\AutoIt v3\SciTE >Running AU3Check (3.3.16.1) from:C:\Program Files (x86)\AutoIt3 input:C:\SynologyDrive\Test Tools\AutoIt3 codes\temp36-crc32 for file.au3 +>09:27:47 AU3Check ended.rc:0 >Running:(3.3.16.1):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\SynologyDrive\Test Tools\AutoIt3 codes\temp36-crc32 for file.au3" +>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart or Ctrl+BREAK to Stop. CBB2BF83 CBB2BF83+>09:27:55 AutoIt3.exe ended.rc:0 +>09:27:55 AutoIt3Wrapper Finished. >Exit code: 0 Time: 9.729 I set the file checksum value = E1866101, but the file checksum actually is with value CBB2BF83, but it always show PASS result, please digit me where the code is wrong, thanks! Edited June 6, 2023 by jackylee0908 Link to comment Share on other sites More sharing options...
argumentum Posted June 6, 2023 Share Posted June 6, 2023 ..use this ( https://www.nirsoft.net/utils/hash_my_files.html ) and if the 2 values are different then something is wrong. Furthermore, I'll give you another, slower but similar code. See how all the outputs match or not #include <APIConstants.au3> #include <WinAPIEx.au3> ConsoleWrite(@CRLF & _CRC32ofFile(@AutoItExe) & @CRLF & @CRLF & TimerDiff($hTimer) & @CRLF) Func _CRC32ofFile($sFileFullPath) Local $sFile, $hFile = FileOpen($sFileFullPath, 512) ; Use ANSI reading mode. $sFile = FileRead($hFile) FileClose($hFile) Return _CRC32ofStr($sFile) EndFunc Func _CRC32ofStr($sStr) Local $bData = StringToBinary($sStr) Local $iLength = BinaryLen($bData), $tData If $iLength = 0 Then Return SetError(1, 0, 0) $tData = DllStructCreate('byte data[' & $iLength & ']') $tData.data = $bData Return Hex(_WinAPI_ComputeCrc32(DllStructGetPtr($tData), $iLength), 8) EndFunc ;==>_CRC32ofStr  Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
argumentum Posted June 6, 2023 Share Posted June 6, 2023 I'd use this command line utility ( CRC32.EXE ) to check the files. Is fast and does not have to read the file to memory. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
jackylee0908 Posted June 6, 2023 Author Share Posted June 6, 2023 Hi @argumentum Thanks, I have found what problem it is, below is the workable code. $file_to_open = "c:\dmcheck\dmcheck.sfv" ConsoleWrite(@CRLF & _CRC32ForFile($file_to_open) & @CRLF & @CRLF) ; basically this. You code the rest. $v1 = _CRC32ForFile($file_to_open) $v2 = "E1866101" If $v1 == $v2 Then MsgBox(262160, "PASS", "File check passed.") Else MsgBox(262160, "FAIL", "File check failed.") EndIf The "If" should with "==" but not "=". Anyway, thanks for your suggestion, I appreciated. argumentum 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now