Option Explicit
'hi, mark ganson here (latest revision: 7/20/2015)
'reach me at mwganson@hotmail.com with comments (put md5.vbs in subject line please)
'source of this file: http://mwganson.freeyellow.com/md5/md5.vbs
'all of this stuff i found on the web, sources noted in the code where applicable
'i integrated it all into this script with very few modifications of my own

'this is a .vbs script for computing and displaying md5 hashes (along with sha1, sha256, sha384, sha512, and ripemd160)
'it uses a simple drag and drop interface (or you can use the send to context menu option -- read on)
'to wit: drag and drop your file(s) onto the MD5.vbs file and it will do the rest

'*should* work on all windows computers

'not the fastest way to do md5 hashes maybe, but still has its convenience advantages

'here's how to put this into your send to folder so you can right-click the file(s)
'you want to create md5 hashes for and send them to this script
'right-click on the md5.vbs script and choose create shortcut
'this produces a file named md5 shortuct.lnk or something similar
'rename it to md5.lnk (optional)

'paste this text into windows explorer address bar: %APPDATA%\Microsoft\Windows\SendTo
'you will now be in the send to folder -- simply move the shortcut md5.lnk file to this folder
'source of this information: http://www.howtogeek.com/howto/windows-vista/customize-the-windows-vista-send-to-menu/


'ENTRY POINT for this script
'users can double-click the script, drop files onto the script, or use the send to context menu option.  dropped files will be filenames as arguments
'parses command line arguments to get filename(s)
'following is something i modified from  the file copying script found at
'https://social.technet.microsoft.com/forums/scriptcenter/en-US/e032bc2e-31c4-4306-9f43-b5202d23e9d7/copy-files-using-drag-n-drop-on-vbs-file

Dim doMd5, doSha1, doSha256, doSha384, doSha512, doRipemd160
'set these values according to your needs
'setting unnecessary ones to False will greatly speed up the process
doMd5 = True
doSha1 = True
doSha256 = False
doSha384 = False
doSha512 = False
doRipemd160 = True

Dim objFile,objFolder,objFSO 
Dim Arg, strText 

strText ="" 
Set objFSO = CreateObject("Scripting.FileSystemObject") 

' > 0 arguments means files were dropped onto the md5.vbs script (or sent to via send to option)
 
If WScript.Arguments.Count > 0 Then 
    For Each Arg in Wscript.Arguments 
        Arg =  Trim(Arg) 
    If InStr(Arg,".") Then 
    ' Assume a File
	'comment/uncomment out these lines if you need/don't need any particular hash
   strText = strText & "Filename: " & Arg & vbNewLine 
   If doMd5 Then strText = strText & "MD5 --> " & md5(Arg) & vbNewLine End If
   If doSha1 Then strText = strText & "SHA1 --> "& sha1(Arg) & vbNewLine End If
   If doSha256 Then strText = strText & "SHA256 --> "& sha256(Arg) & vbNewLine End If
   If doSha384 Then strText = strText & "SHA384 --> "& sha384(Arg) & vbNewLine End If
   If doSha512 Then strText = strText & "SHA512 --> "& sha512(Arg) & vbNewLine End If
   If doRipemd160 Then strText = strText & "RIPEMD160 --> "& ripemd160(Arg) & vbNewLine End If
 

    End If 
    Next
 
 End If

 ' = 0 arguments means use double-clicked md5.vbs (or possible executed via the command line without filename arguments)
 
 Dim fName
 If WScript.Arguments.Count = 0 Then
   fName = ChooseFile(".")
   If fName <> "" Then
      strText = strText & "Filename: " & fName & vbNewLine 
      If doMd5 Then strText = strText & "MD5 --> " & md5(fName) & vbNewLine End If
      If doSha1 then strText = strText & "SHA1 --> "& sha1(fName) & vbNewLine End If
      If doSha256 Then strText = strText & "SHA256 --> "& sha256(fName) & vbNewLine End If
      If doSha384 Then strText = strText & "SHA384 --> "& sha384(fName) & vbNewLine End If
      If doSha512 Then strText = strText & "SHA512 --> "& sha512(fName) & vbNewLine End If
      If doRipemd160 Then strText = strText & "RIPEMD160 --> "& ripemd160(fName) & vbNewLine End If
      Wscript.echo strText 'need this to keep things from going crazy when inserting data into notepad (ensures notepad is top window somehow)
   End If

 End If


'now we can open notepad and put the text into it
'source for working with notepad in .vbs files: http://nerds-central.blogspot.com/2007/01/using-vbscript-to-paste-text-into.html
'or simply uncomment the next line to get a simple message box (and comment out notepad-related stuff below)

'exit gracefully if the user canceled file selection in the open file dialog
If strText = "" Then
    Dim strExit
    strExit = "No file selected, exiting gracefully..." & vbNewLine
    strExit = strExit + "Don't forget you can drag and drop files onto this script, too." & vbNewLine
    strExit = strExit + "Or use the 'Send To' right-context menu as detailed in the script." & vbNewLine
    msgbox  strExit,0,"MD5.VBS"
    WScript.Quit
End If


dim WshShell

' Open notepad 
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "notepad",3

' Give Notepad time to load
WScript.Sleep 500 

' Do The Paste into notepad
WshShell.SendKeys strText








'improved md5 function uses .net md5 component (formerly had code here to do the hashing in the script)
'source: https://github.com/falconws/wshLib/blob/master/lib/MD5.vbs

Function md5(filename)
	Dim MSXML, EL, MD5Obj

    Set MD5Obj = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")
	MD5Obj.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = MD5Obj.Hash
	md5 = EL.Text
End Function

Function sha1(filename)
	Dim MSXML, EL
	Set SHA1 = CreateObject("System.Security.Cryptography.SHA1CryptoServiceProvider")
	SHA1.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = SHA1.Hash
	sha1 = EL.Text
End Function

Function sha256(filename)
	Dim MSXML, EL
	Set SHA256 = CreateObject("System.Security.Cryptography.SHA256Managed")
	SHA256.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = SHA256.Hash
	sha256 = EL.Text
End Function

Function sha384(filename)
	Dim MSXML, EL
	Set SHA384 = CreateObject("System.Security.Cryptography.SHA384Managed")
	SHA384.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = SHA384.Hash
	sha384 = EL.Text
End Function


Function sha512(filename)
	Dim MSXML, EL
	Set SHA512 = CreateObject("System.Security.Cryptography.SHA512Managed")
	SHA512.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = SHA512.Hash
	sha512 = EL.Text
End Function


Function ripemd160(filename)
	Dim MSXML, EL
	Set ripemd160 = CreateObject("System.Security.Cryptography.ripemd160Managed")
	ripemd160.ComputeHash_2(readBinaryFile(filename))

	Set MSXML = CreateObject("MSXML2.DOMDocument")
	Set EL = MSXML.CreateElement("tmp")
	EL.DataType = "bin.hex"
	EL.NodeTypedValue = ripemd160.Hash
	ripemd160 = EL.Text
End Function

Function readBinaryFile(filename)
	Const adTypeBinary = 1
	Dim objStream
	Set objStream = CreateObject("ADODB.Stream")
	objStream.Type = adTypeBinary
	objStream.Open
	If filename <> "" Then objStream.LoadFromFile filename End If 'slight modification here to prevent error msg if no file selected
	readBinaryFile = objStream.Read
	objStream.Close
	Set objStream = Nothing
End Function

'this function we use only if the user simply double-clicked on the md5.vbs script file
'instead of dragging and dropping or using the send to interface
'argument count will be 0
'source: http://todayguesswhat.blogspot.com/2012/08/windows-7-replacement-for.html

dim shell, defaultLocalDir, objWMIService, colItems, objItem, ex

Set shell = CreateObject( "WScript.Shell" )
defaultLocalDir = shell.ExpandEnvironmentStrings("%USERPROFILE%") & "\Desktop"
Set shell = Nothing



Function ChooseFile (ByVal initialDir)
    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

    Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    Dim winVersion

    ' This collection should contain just the one item
    For Each objItem in colItems
        'Caption e.g. Microsoft Windows 7 Professional
        'Name e.g. Microsoft Windows 7 Professional |C:\windows|...
        'OSType e.g. 18 / OSArchitecture e.g 64-bit
        'Version e.g 6.1.7601 / BuildNumber e.g 7601
        winVersion = CInt(Left(objItem.version, 1))
    Next
    Set objWMIService = Nothing
    Set colItems = Nothing

    If (winVersion <= 5) Then
        ' Then we are running XP and can use the original mechanism
        Set cd = CreateObject("UserAccounts.CommonDialog")
        cd.InitialDir = initialDir
        cd.Filter = "ZIP files|*.zip|Text Documents|*.txt|Shell Scripts|*.*sh|All Files|*.*"
        ' filter index 4 would show all files by default
        ' filter index 1 would show zip files by default
        cd.FilterIndex = 4
        If cd.ShowOpen = True Then
            ChooseFile = cd.FileName
        Else
            ChooseFile = ""
        End If
        Set cd = Nothing    

    Else
        ' We are running Windows 7 or later
        Set shell = CreateObject( "WScript.Shell" )
        Set ex = shell.Exec( "mshta.exe ""about: <input type=file id=X><script>X.click();new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(X.value);close();resizeTo(0,0);</script>""" )
        ChooseFile = Replace( ex.StdOut.ReadAll, vbCRLF, "" )

        Set ex = Nothing
        Set shell = Nothing
    End If
End Function    



