Sign in to follow this  
Followers 0
spudw2k

MD5 Folder Enumerator

3 posts in this topic

#1 ·  Posted (edited)

Simple yet efficient MD5 tool. Calculates the MD5 for all files within a selected directory (including subdirectories).

Crypt Library Functions written by Monoceres.

#region - Globals and Variables
Global Const $PROV_RSA_FULL = 0x1
Global Const $PROV_RSA_AES = 24
Global Const $CRYPT_VERIFYCONTEXT = 0xF0000000
Global Const $HP_HASHSIZE = 0x0004
Global Const $HP_HASHVAL = 0x0002
Global Const $CRYPT_USERDATA = 1
Global Const $CALG_MD5 = 0x00008003
Global $__g_aCryptInternalData[3]
#endregion

#region - Main Code Routine
$dir = FileSelectFolder("Select Folder to Traverse","",4)
$output = FileSaveDialog("Save Output To...",@ScriptDir,"Comma Separated Values (*.CSV)",18,"md5.csv")
If Not $output Then Exit
$output = FileOpen($output,2)
_EnumerDir($dir)
msgbox(0,"MD5 Complete","")
#endregion

#region - Enumeration Functions
Func _EnumerDir($dir)  ;Enumerate Directory and SubDirectories and Perform MD5 Checksum on Contents
    $files = _FileListToArray($dir,"*",1)
    If IsArray($files) Then
        For $i = 1 to $files[0]
            $file = $dir & "\" & $files[$i]
            $md5 = _Crypt_HashFile($file,$CALG_MD5)
            If @error then
                FileWriteLine($output,'"' & $file & '","Error:' & @error & '"')
            Else
                FileWriteLine($output,'"' & $file & '","' & $md5 & '"')
            EndIf
        Next
    EndIf
    $subfldrs = _FileListToArray($dir,"*",2)
    If IsArray($subfldrs) Then
        For $i = 1 to $subfldrs[0]
            _EnumerDir($dir & "\" & $subfldrs[$i])  ;Recursive Enumeration
        Next
    EndIf
EndFunc;==>EnumerDir

Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)  ;Find Files/Directories Function
    Local $hSearch, $sFile, $sFileList, $sDelim = "|"
    $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "") & "\" ; ensure single trailing backslash
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    If StringRegExp($sFilter, "[\\/:><\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
    $hSearch = FileFindFirstFile($sPath & $sFilter)
    If @error Then Return SetError(4, 4, "")
    While 1
        $sFile = FileFindNextFile($hSearch)
        If @error Then ExitLoop
        If ($iFlag + @extended = 2) Then ContinueLoop
        $sFileList &= $sDelim & $sFile
    WEnd
    FileClose($hSearch)
    If Not $sFileList Then Return SetError(4, 4, "")
    Return StringSplit(StringTrimLeft($sFileList, 1), "|")
EndFunc;==>_FileListToArray
#endregion

#region - Encryption Functions
Func _Crypt_HashData($vData, $iALG_ID, $fFinal = True, $hCryptHash = 0)
    Local $iError
    Local $vReturn = 0
    Local $iHashSize
    Local $aRet
    Local $hBuff = 0

    _Crypt_Startup()
    Do
        If $hCryptHash = 0 Then
            ; Create Hash object
            $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptCreateHash", "handle", __Crypt_Context(), "uint", $iALG_ID, "ptr", 0, "dword", 0, "handle*", 0)
            If @error Or Not $aRet[0] Then
                $iError = 1
                $vReturn = -1
                ExitLoop
            EndIf
            $hCryptHash = $aRet[5]
        EndIf

        $hBuff = DllStructCreate("byte[" & BinaryLen($vData) & "]")
        DllStructSetData($hBuff, 1, $vData)

        $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptHashData", "handle", $hCryptHash, "ptr", DllStructGetPtr($hBuff), "dword", DllStructGetSize($hBuff), "dword", $CRYPT_USERDATA)
        If @error Or Not $aRet[0] Then
            $iError = 2
            $vReturn = -1
            ExitLoop
        EndIf

        If $fFinal Then
            $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptGetHashParam", "handle", $hCryptHash, "dword", $HP_HASHSIZE, "dword*", 0, "dword*", 4, "dword", 0)
            If @error Or Not $aRet[0] Then
                $iError = 3
                $vReturn = -1
                ExitLoop
            EndIf
            $iHashSize = $aRet[3]

            ; Get Hash
            $hBuff = DllStructCreate("byte[" & $iHashSize & "]")
            $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptGetHashParam", "handle", $hCryptHash, "dword", $HP_HASHVAL, "ptr", DllStructGetPtr($hBuff), "dword*", DllStructGetSize($hBuff), "dword", 0)
            If @error Or Not $aRet[0] Then
                $iError = 4
                $vReturn = -1
                ExitLoop
            EndIf
            $iError = 0
            $vReturn = DllStructGetData($hBuff, 1)
        Else
            $vReturn = $hCryptHash
        EndIf
    Until True

    ; Cleanup and return hash
    If $hCryptHash <> 0 And $fFinal Then DllCall(__Crypt_DllHandle(), "bool", "CryptDestroyHash", "handle", $hCryptHash)

    _Crypt_Shutdown()
    Return SetError($iError, 0, $vReturn)
EndFunc;==>_Crypt_HashData

Func _Crypt_HashFile($sFile, $iALG_ID)
    Local $hFile
    Local $iError, $vReturn
    Local $hHashObject = 0
    Local $bTempData
    _Crypt_Startup()

    Do
        $hFile = FileOpen($sFile, 16)
        If $hFile = -1 Then
            $iError = 1
            $vReturn = -1
            ExitLoop
        EndIf

        Do
            $bTempData = FileRead($hFile, 512 * 1024)
            If @error Then
                $vReturn = _Crypt_HashData($bTempData, $iALG_ID, True, $hHashObject)
                If @error Then
                    $vReturn = -1
                    $iError = 2
                    ExitLoop 2
                EndIf
                ExitLoop 2
            Else
                $hHashObject = _Crypt_HashData($bTempData, $iALG_ID, False, $hHashObject)
                If @error Then
                    $vReturn = -1
                    $iError = 3
                    ExitLoop 2
                EndIf
            EndIf
        Until False
    Until True

    _Crypt_Shutdown()
    If $hFile <> -1 Then FileClose($hFile)
    Return SetError($iError, 0, $vReturn)
EndFunc;==>_Crypt_HashFile

Func _Crypt_Startup()
    If __Crypt_RefCount() = 0 Then
        Local $hAdvapi32 = DllOpen("Advapi32.dll")
        If @error Then Return SetError(1, 0, False)
        __Crypt_DllHandleSet($hAdvapi32)
        Local $aRet
        Local $iProviderID = $PROV_RSA_AES
        If @OSVersion = "WIN_2000" Then $iProviderID = $PROV_RSA_FULL ; Provide backwards compatibility with win2000
        $aRet = DllCall(__Crypt_DllHandle(), "bool", "CryptAcquireContext", "handle*", 0, "ptr", 0, "ptr", 0, "dword", $iProviderID, "dword", $CRYPT_VERIFYCONTEXT)
        If @error Or Not $aRet[0] Then
            DllClose(__Crypt_DllHandle())
            Return SetError(2, 0, False)
        Else
            __Crypt_ContextSet($aRet[1])
            ; Fall through to success.
        EndIf
    EndIf
    __Crypt_RefCountInc()
    Return True
EndFunc;==>_Crypt_Startup

Func _Crypt_Shutdown()
    __Crypt_RefCountDec()
    If __Crypt_RefCount() = 0 Then
        DllCall(__Crypt_DllHandle(), "bool", "CryptReleaseContext", "handle", __Crypt_Context(), "dword", 0)
        DllClose(__Crypt_DllHandle())
    EndIf
EndFunc;==>_Crypt_Shutdown

Func __Crypt_RefCount()
    Return $__g_aCryptInternalData[0]
EndFunc

Func __Crypt_RefCountInc()
    $__g_aCryptInternalData[0] += 1
EndFunc

Func __Crypt_RefCountDec()
    If $__g_aCryptInternalData[0] > 0 Then $__g_aCryptInternalData[0] -= 1
EndFunc

Func __Crypt_DllHandle()
    Return $__g_aCryptInternalData[1]
EndFunc

Func __Crypt_DllHandleSet($hAdvapi32)
    $__g_aCryptInternalData[1] = $hAdvapi32
EndFunc

Func __Crypt_Context()
    Return $__g_aCryptInternalData[2]
EndFunc

Func __Crypt_ContextSet($hCryptContext)
    $__g_aCryptInternalData[2] = $hCryptContext
EndFunc
#endregion
Edited by spudw2k

Share this post


Link to post
Share on other sites



Excellent example script, i'll check it out.

Share this post


Link to post
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
Sign in to follow this  
Followers 0