Jump to content
Sign in to follow this  
spudw2k

MD5 Folder Enumerator

Recommended Posts

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

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...