Click here to Skip to main content
13,633,451 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

3.9K views
55 downloads
6 bookmarked
Posted 15 Jan 2018
Licenced CPOL

An Autoit Program for Automatic BackUp and Encryption of Files

, 15 Jan 2018
Rate this:
Please Sign up or sign in to vote.
A program for automatic backup with possibly encrypt

Introduction

This is the third article on the use of some advanced features of the Autoit[1] language for receiving notifications from the Operating System (OS) on writing files and to be able to make a copy of these (possibly encrypted).

The previous articles deal with the use of COM (Component Object Model) objects, the first shows how to grab data from an MSWord document by COM objects for MSWord and send them to an internet application using WinHttpRequest COM object which implements the Ajax protocol; the second besides the COM objects for MSWord uses properties and methods of the COM objects for Power Point.

Steps to Receive Notifications from the File System

(See also the article of Thomas Caudal Shell Notifications in C#)

  • Register a message, this should be a string unique in the system:
    Local $iMsg = _WinAPI_RegisterWindowMessage('CHANGENOTIFY')
  • Associates the message with an Autoit function:
    GUIRegisterMsg($iMsg, 'WM_CHANGENOTIFY') ; the message is associated to function WM_CHANGENOTIFY
  • Registers a window that receive notifications from the file system:
    $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd,$iMsg,$SHCNE_ALLEVENTS,BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $Path)

The program below is a step to develop the program BackUp object of this article; I used it to test the operation in the case of several contemporary folders.

#include <APIShellExConstants.au3>
#include <WinAPI.au3>
#include <WinAPIShellEx.au3>
#include <GUIConstantsEx.au3>
Opt('TrayAutoPause', 0)
OnAutoItExitRegister('Deregister')
Global $hWnd = GUICreate("Try change on folders", 400, 300)
GUISetState(@SW_SHOW, $hWnd)
Global $ID1 = Guard("D:\Condor", 1)
Global $ID2 = Guard("C:\www", 2)
While 1
	If GUIGetMsg() = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
Func Guard($path, $indx)
	$Message = 'CHANGENOTIFY' & $indx
	Local $iMsg = _WinAPI_RegisterWindowMessage($Message)
	GUIRegisterMsg($iMsg, 'WM_CHANGENOTIFY') ; the message is associated to function WM_CHANGENOTIFY
	;	local $g_iID = _WinAPI_ShellChangeNotifyRegister_
        ($hWnd,$iMsg,  $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, _
         $SHCNRF_RECURSIVEINTERRUPT), $Path, true)
	Local $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, $SHCNE_UPDATEITEM, _
         BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $path)
	If @error Then
		MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Window does not registered.')
		Exit
	EndIf
	Return $g_iID
EndFunc   ;==>Guard
Func WM_CHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate
                   ('dword Item1; dword Item2', $wParam), 'Item1'))
	If $SHCNE_UPDATEITEM = $lParam Then ConsoleWrite($sPath & " writed" & @CRLF)
EndFunc   ;==>WM_CHANGENOTIFY
Func Deregister()
	ConsoleWrite("Deregister" & @CRLF)
	If $ID1 Then _WinAPI_ShellChangeNotifyDeregister($ID2)
	If $ID2 Then _WinAPI_ShellChangeNotifyDeregister($ID2)
EndFunc   ;==>Deregister

The Backup Program

As already anticipated in the overlying introduction, the script deals with automatic backup of files when they are modified: a form permits to choose the file(s) to guard, where to backup and a possible encrypt of the copy; this last option is for those who do not trust the storage of their data on the cloud.

Some clarifications on the data and on the operation of the program:

  • The buttons of the form are associated with the functions invoked with the pressure of the same
  • The data in the form is accessible through a dictionary where the key is the name associated to a control, for example, the name of the backup folder is Folder;
  • Finally, every file to watch is stored in a dictionary where the key is fileName to backup (with path) and the value is an array containing:
    • the origin folder
    • the backup file (complete path)
    • the possible encryption password
    • the handle returned by _WinAPI_ShellUPDATENOTIFYRegister
    • the fileName

When the button Guard is pressed, the code below is executed:

Func genGuard($data)
	Local $sDrive = "", $sDir = "", $sExtension = "", $Path = "", $file = ""
	$psw = $data.item("Password")
	$fileToGuard = $data.item("File")
	Local $aPathSplit = _PathSplit($fileToGuard, $sDrive, $Path, $File, $sExtension)
	$destFolder = $data.item("Folder")
	if StringRight($destFolder,1) <> "\" then $destFolder = $destFolder & "\"
	$Path = $sDrive & $Path
	Local $dataFile[] = [$Path,$destFolder,$psw, 0,$File & $sExtension]
	if $data.item("runProgram") = "1" Then ShellExecute($data.item("File"),@SW_MAXIMIZE)
	if isNewFolder($Path) Then
		Local $iMsg = _WinAPI_RegisterWindowMessage('UPDATENOTIFY' & $fileDict.count)
		GUIRegisterMsg($iMsg, 'WM_UPDATENOTIFY')	; the message is associated to _
                                function WM_UPDATENOTIFY
		$dataFile[3] =  _WinAPI_ShellChangeNotifyRegister($data.item("fg_winhandle"), _
						$iMsg, _
						$SHCNE_UPDATEITEM, _	; guard update file system
						BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), _
						$Path)
		If @error Then
			MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL),'Error','Window does not registered.')
			Exit
		EndIf
	EndIf
	ConsoleWrite("Folder " & $path & " guarded" & @CRLF)
	$fileDict.Item($fileToGuard) = $dataFile
EndFunc

For every folder to guard must be created a new message by the function _WinAPI_RegisterWindowMessage, this is achieved by creating a message with a constant part and a variable number: 'UPDATENOTIFY' & $fileDict.count.

The file can be opened if the Check Box runProgram is checked by its associated program through the function ShellExecute.

With the function _WinAPI_ShellChangeNotifyRegister, the program tells the Operating System (OS) to call the function WM_UPDATENOTIFY when the event $SHCNE_UPDATEITEM[2] i.e., an update on the folder $Path occurs.

When the event occurs, the OS calls the function WM_UPDATENOTIFY:

Func WM_UPDATENOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData_
                   (DllStructCreate('dword Item1; dword Item2', $wParam), 'Item1'))
	If $sPath Then
		if $fileDict.Exists($sPath) Then		; a file has been updated
			Local $dataFile = $fileDict.Item($sPath)
			If $dataFile[2] = "" Then		; there is a password?
				FileCopy($sPath,$dataFile[1], $FC_OVERWRITE + $FC_CREATEPATH)
			Else
				_Crypt_EncryptFile($sPath, $dataFile[1] & $dataFile[4], _
                              $dataFile[2],$CALG_AES_192)	; Encrypt the file.
				If @error <> 0 Then
					consoleWrite("Error when encrypting: " & @error & @CRLF)
				EndIf
			EndIf
			consoleWrite($sPath & " saved")
			if $dataFile[2] <> "" Then ConsoleWrite(" and encrypted")
			ConsoleWrite(@CRLF)
		EndIf
	EndIf
EndFunc   ;==>WM_UPDATENOTIFY

If the event is related to a file under control, this is copied to the backup folder or it is copied encrypted[3] if there is a keyword.

Other Features of the Program

I added a subform to recover the encrypted files and in the menu, under File, the sub menu Show guarded which shows the files currently under control:

...
	& "BL,Restore,Restore,,,Restore the file,Restore;" _
	& "Menu,File,&File;" _
	& "SubMenu,Showguard,&Show guarded,Showguard;" _
...
Func showGuard()
	$aDict = getIniFormat($fileDict)
	Local $iOrgWidth = 500, $iHeight = 300
	Local $hGUI = GUICreate("Files on guard", $iOrgWidth, $iHeight)
	Local $aiGUISize = WinGetClientSize($hGUI)
	Local $idListview = GUICtrlCreateListView(StringFormat_
           ("File   %40s |Folder %40s |Encript key","",""), 10, 10, 480, 240)
	For $i=1 to $aDict[0][0]
		$a = $aDict[$i][1]
		Local $idItem = GUICtrlCreateListViewItem_
           ($aDict[$i][0] & "|" & $a[1] & "|"  & $a[2],$idListview)
	Next
	GUISetState(@SW_SHOW, $hGUI)
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
	GUIDelete()
EndFunc
Func Restore($data)
	$psw = $data.item("PasswordR")
	$fileToRestore = $data.item("FileR")
	Local $sDrive = "", $sDir = "", $sExtension = "", $Pth = "", $file
	Local $aPathSplit = _PathSplit($fileToRestore, $sDrive, $Pth, $File, $sExtension)
	$File = $File & $sExtension
	$destFile = $data.item("FolderR")
	if StringRight($destFile,1) <> "\" then $destFile = $destFile & "\"
	$destFile = $destFile & $File
	if $psw = "" Then
		FileCopy($fileToRestore,$destFile, $FC_OVERWRITE + $FC_CREATEPATH)
	Else
		_Crypt_DecryptFile($fileToRestore, $destFile, $psw,$CALG_AES_192)	; Decrypt the file.
	EndIf
	msgbox(0,"Restore",$fileToRestore,1.5)
	ConsoleWrite("Restored file " & $fileToRestore & " from " & $Pth & @CRLF)
EndFunc

Notes

  1. ^AutoIt is a free-ware BASIC-like scripting language, an alternative to PowerShell, designed in origin for automating the interaction with Windows GUI. AutoIt can run on Windows interpreted or compiled. It comes with many libraries that enable, among other things, access COM objects and create graphical interfaces; those task are greatly enhanced by the rich Help with examples.
  2. ^In the documentation we can find a list of all events, in particular $SHCNE_ALLEVENTS matches all events.
  3. ^I used the AES (192bit) algorithm but AutoIt supports some others that can be found in the documentation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Member 4206974
Software Developer Condor Informatique
Italy Italy
Computer literacy (software) : Languages: PHP, Javascript, SQL Autoit,Basic4Android; Frameworks: JOOMLA!
Teaching/Training skills on Office, WEB site development and programming languages.
Others : WEB site development.
UNDP Missions
feb – may 2003 Congo DR Bukavu: ground IT computer course
nov 2003 Burundi Bujumbura: Oracle Data Base course
feb 2005 Burundi Bujumbura: JAVA course
mar 2005 Mali Kati: MS Office course
oct 2006 Mali Kati: MS Office course
jun 2006 Burkina Faso Bobo Dioulasso: MS Office course
jun 2007 Burkina Faso Bobo Dioulasso: MS Office course
may 2007 Argentina Olavarria hospital: Internet application for access to medical records
apr 2008 Burkina Faso Ouagadougou: MS ACCESS and dynamic Internet applications
jun 2008 Niger Niamey: analysis of the computing needs of the Niamey hospital
may 2009 Burkina Faso Ouagadougou: MS ACCESS and dynamic Internet applications
oct 2010 Niger Niamey: analysis of the computing needs of the Niamey hospital (following)
Region Piedmont project Evaluation
mar 2006 Burkina Faso, Niger
mar 2007 Benin, Burkina Faso, Niger
sep 2008 Benin, Burkina Faso, Niger
Others
feb 2010 Burundi Kiremba hospital: MS Office course
feb 2011 Congo DR Kampene hospital: MS Office course

You may also be interested in...

Pro

Comments and Discussions

 
QuestionLanguage Pin
Michael Haephrati15-Jan-18 11:38
mvpMichael Haephrati15-Jan-18 11:38 
AnswerRe: Language Pin
Jim Meadors16-Jan-18 15:54
memberJim Meadors16-Jan-18 15:54 
AnswerRe: Language Pin
Michael Haephrati17-Jan-18 4:39
mvpMichael Haephrati17-Jan-18 4:39 
GeneralRe: Language Pin
Jim Meadors17-Jan-18 16:27
memberJim Meadors17-Jan-18 16:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.180712.1 | Last Updated 15 Jan 2018
Article Copyright 2018 by Member 4206974
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid