mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Adding manifest generation tool
This commit is contained in:
parent
cc96803548
commit
c319f01838
269
ManifestTool/ManifestGenerationAlgorithms.au3
Normal file
269
ManifestTool/ManifestGenerationAlgorithms.au3
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
#include <GUIConstantsEx.au3>
|
||||||
|
#include <MsgBoxConstants.au3>
|
||||||
|
#include <ProgressConstants.au3>
|
||||||
|
#include <File.au3>
|
||||||
|
#include <WinAPIFiles.au3>
|
||||||
|
#include <ScrollBarConstants.au3>
|
||||||
|
#include <GuiEdit.au3>
|
||||||
|
#include <Date.au3>
|
||||||
|
|
||||||
|
;Get the list of names of algorithms
|
||||||
|
Global $algorithms[3] ;increase size of array when adding new algorithms
|
||||||
|
$algorithms[0] = "Single Data Source"
|
||||||
|
$algorithms[1] = "Folder of Logical Files"
|
||||||
|
$algorithms[2] = "One Data Source Per Folder"
|
||||||
|
|
||||||
|
; $algorithms[2] = "All Files In One Folder"
|
||||||
|
Global $progressArea = Null
|
||||||
|
Global $manifestFileNameEnd = "Manifest"
|
||||||
|
Global $manifestExtension = ".xml"
|
||||||
|
|
||||||
|
|
||||||
|
;Return an array containing the names of all algorithms
|
||||||
|
Func GetAlgorithmNames()
|
||||||
|
Return $algorithms
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Return the name of the first algorithm as a default algorithm
|
||||||
|
Func GetDefaultAlgorithmName()
|
||||||
|
Return $algorithms[0]
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Run the function that corresponds to the specified Algorithm name
|
||||||
|
;Use Null for $progressArea if not called from a GUI with a $progressArea
|
||||||
|
Func RunAlgorithm($selectedAlgorithm, $settings, ByRef $progressAreaRef)
|
||||||
|
$progressArea = $progressAreaRef
|
||||||
|
UpdateProgressArea("Analyzing: " & $settings[0])
|
||||||
|
if ($selectedAlgorithm == $algorithms[2]) Then
|
||||||
|
OneDataSourcePerFolder($settings)
|
||||||
|
ElseIf ($selectedAlgorithm == $algorithms[0]) Then
|
||||||
|
SingleDataSource($settings)
|
||||||
|
ElseIf ($selectedAlgorithm == $algorithms[1]) Then
|
||||||
|
SingleDataSource($settings)
|
||||||
|
; ElseIf ($selectedAlgorithm == $algorithms[2]) Then
|
||||||
|
; AllFilesInOneFolder($settings)
|
||||||
|
EndIf
|
||||||
|
UpdateProgressArea("-------------------------------------------------------------------------------------------") ;blank line for some
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Create a manifest file in the specified $caseDir named $manifestDir _Manifest.xml
|
||||||
|
;if the $manifestFile is specified the datasource included will be the file instead of the entire folder
|
||||||
|
Func GenerateCaseNameAndWriteManifestFile($caseDir, $subDirName, $manifestFile)
|
||||||
|
Local $manifestName = ""
|
||||||
|
Local $caseName = ""
|
||||||
|
Local $dataSourcePath = ""
|
||||||
|
;If the manifestDirectory is not Null use it for the file name
|
||||||
|
if ($subDirName <> Null) Then
|
||||||
|
$manifestName = $subDirName
|
||||||
|
$dataSourcePath = $manifestName
|
||||||
|
if ($manifestFile <> Null) Then
|
||||||
|
$dataSourcePath = $dataSourcePath & "\" & $manifestFile
|
||||||
|
EndIf
|
||||||
|
;If the manifestDirectory was Null then use the file name
|
||||||
|
ElseIf ($manifestFile <> Null) Then
|
||||||
|
$manifestName = $manifestFile
|
||||||
|
$dataSourcePath = $manifestName
|
||||||
|
Else
|
||||||
|
UpdateProgressArea("ERROR: Invalid arguements provided, unable to create manifest file")
|
||||||
|
Return
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
Local $splitCaseDir = StringSplit($caseDir, "\", $STR_ENTIRESPLIT)
|
||||||
|
$caseName = $splitCaseDir[$splitCaseDir[0]]
|
||||||
|
|
||||||
|
Local $manfiestFilePath = $caseDir & "\" & $manifestName & "_" & $manifestFileNameEnd & $manifestExtension
|
||||||
|
WriteManifestFile($manfiestFilePath, $manifestName, $caseName, $dataSourcePath)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Write the specified manifest file.
|
||||||
|
Func WriteManifestFile($manifestFilePath, $manifestName, $caseName, $dataSourcePath)
|
||||||
|
_FileCreate($manifestFilePath)
|
||||||
|
Local $fileHandle = FileOpen($manifestFilePath, $FO_APPEND)
|
||||||
|
If $fileHandle == -1 Then
|
||||||
|
UpdateProgressArea("ERROR: " & $manifestName & " Unable to create manifest file")
|
||||||
|
Return
|
||||||
|
EndIf
|
||||||
|
FileWrite($fileHandle,'<?xml version="1.0" encoding="UTF-8" standalone="no"?>' & @CRLF)
|
||||||
|
FileWrite($fileHandle,'<AutopsyManifest>' & @CRLF)
|
||||||
|
FileWrite($fileHandle,'<CaseName>' & $caseName &'</CaseName>' & @CRLF)
|
||||||
|
;Device ID is not a required field
|
||||||
|
FileWrite($fileHandle,'<DataSource>' & $dataSourcePath & '</DataSource>' & @CRLF)
|
||||||
|
FileWrite($fileHandle,'</AutopsyManifest>' & @CRLF)
|
||||||
|
FileClose($fileHandle)
|
||||||
|
UpdateProgressArea($manifestName & " manifest created")
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;get the extension of a file
|
||||||
|
Func GetFileExtension($fileName)
|
||||||
|
Local $fileExtension
|
||||||
|
_PathSplit ($fileName, "", "", "", $fileExtension)
|
||||||
|
Return $fileExtension
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Return 0 for false if no manifest files exist in the caseDir, or 1 for true if manifest files do exist
|
||||||
|
Func ManifestFilesAlreadyExist($fileList)
|
||||||
|
Local $fileName
|
||||||
|
Local $fileExtension
|
||||||
|
For $i = 1 To $fileList[0] Step 1
|
||||||
|
_PathSplit ($fileList[$i], "", "", $fileName, $fileExtension)
|
||||||
|
If StringCompare($fileExtension, $manifestExtension, $STR_NOCASESENSE) == 0 Then
|
||||||
|
Local $splitFileName = StringSplit($fileName, "_", $STR_ENTIRESPLIT)
|
||||||
|
if $splitFileName[0] > 1 Then ;It split into more than one chunk so the last chunk should match our _Manifest
|
||||||
|
If StringCompare($splitFileName[$splitFileName[0]], $manifestFileNameEnd, $STR_NOCASESENSE) == 0 Then
|
||||||
|
UpdateProgressArea("Folder already contains manifest file: " & $fileList[$i])
|
||||||
|
Return 1
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
Next
|
||||||
|
Return 0
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Check if a manifest file already exists for a specific datasource in the case Dir
|
||||||
|
;Return 1 if a manifest exists
|
||||||
|
;Return 0 if no manifest exists
|
||||||
|
Func ManifestAlreadyExists($manifestFilePath)
|
||||||
|
If FileExists($manifestFilePath) == 1 Then
|
||||||
|
Return 1
|
||||||
|
Else
|
||||||
|
Return 0
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
|
||||||
|
;Algorithm for the "One Data Source Per Folder"
|
||||||
|
;Creates manifest files
|
||||||
|
Func OneDataSourcePerFolder($settings)
|
||||||
|
Local $validDirectory = 1
|
||||||
|
Local $caseDir = $settings[0]
|
||||||
|
;_FileListToArray returns the count of files/folders as the first value then the contents
|
||||||
|
Local $fileList = _FileListToArray($caseDir, Default, $FLTA_FILES, False)
|
||||||
|
Local $caseDirSplit = StringSplit($caseDir, "\", $STR_ENTIRESPLIT)
|
||||||
|
Local $caseDirName
|
||||||
|
if ($caseDirSplit[0] > 1) Then
|
||||||
|
;if case folder is longer than one directory display just the directory name in progress messages
|
||||||
|
$caseDirName = $caseDirSplit[$caseDirSplit[0]]
|
||||||
|
Else
|
||||||
|
;if there is only one directory use the entire case dir path
|
||||||
|
EndIf
|
||||||
|
If (@error == 1) Then
|
||||||
|
$validDirectory = 0
|
||||||
|
UpdateProgressArea("ERROR: " & $caseDirName & " not found")
|
||||||
|
MsgBox($MB_OK, "Directory Not Found", "Selected directory " & $caseDirName & " was not found.")
|
||||||
|
ElseIf (@error > 0) Then
|
||||||
|
;An acceptable condition as no files means no manifest files
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
Local $dirList = _FileListToArray($caseDir, Default, $FLTA_FOLDERS, True)
|
||||||
|
If (@error ==4) Then
|
||||||
|
UpdateProgressArea($caseDirName & " no folders found")
|
||||||
|
MsgBox($MB_OK, "Selected Directory Empty", "Selected directory " & $caseDirName & " did not contain any subfolders to use as data sources for manifest files.")
|
||||||
|
$validDirectory = 0
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
If $validDirectory = 1 Then
|
||||||
|
Local $validExtensions[4] = [".e01", ".l01", ".001", ".ad1"] ;valid extensions for the One Data Source Per Folder algorithm
|
||||||
|
Local $subDirectoryFileList
|
||||||
|
Local $validSubDirectory
|
||||||
|
For $fileNumber = 1 TO $dirList[0] Step 1
|
||||||
|
Local $manifestFile = Null
|
||||||
|
Local $manifestDir = $dirList[$fileNumber]
|
||||||
|
Local $splitManifestDir = StringSplit($manifestDir, "\", $STR_ENTIRESPLIT)
|
||||||
|
Local $manifestDirName = $splitManifestDir[$splitManifestDir[0]]
|
||||||
|
$subDirectoryFileList = _FileListToArray($dirList[$fileNumber], Default, Default, False)
|
||||||
|
$validSubDirectory = 1
|
||||||
|
If (@error == 1) Then
|
||||||
|
$validSubDirectory = 0
|
||||||
|
UpdateProgressArea("ERROR: " & $dirList[$fileNumber] & " not found")
|
||||||
|
ElseIf (@error ==4) Then
|
||||||
|
UpdateProgressArea($manifestDirName & " empty, no manifest created")
|
||||||
|
$validSubDirectory = 0
|
||||||
|
EndIf
|
||||||
|
If $validSubDirectory == 1 Then
|
||||||
|
For $i = 1 TO $subDirectoryFileList[0] Step 1
|
||||||
|
Local $currentFilesExtension = GetFileExtension($subDirectoryFileList[$i])
|
||||||
|
For $extension IN $validExtensions
|
||||||
|
;should only be one file or directory in this folder since we checked the number of contents previously
|
||||||
|
If StringCompare($extension, $currentFilesExtension, $STR_NOCASESENSE) == 0 Then
|
||||||
|
$manifestFile = $subDirectoryFileList[$i]
|
||||||
|
ExitLoop 2 ;match was found no reason to check remaining extensions or files in a One Data Source Per Folder algorithm
|
||||||
|
EndIf
|
||||||
|
Next
|
||||||
|
Next
|
||||||
|
Local $manifestFilePath = $caseDir & "\" & $manifestDirName & "_" & $manifestFileNameEnd & $manifestExtension
|
||||||
|
If (ManifestAlreadyExists($manifestFilePath) <> 1) Then
|
||||||
|
;should only be one file and it should end with a valid extension add as image file, or the whole directory is added as a logical file set
|
||||||
|
GenerateCaseNameAndWriteManifestFile($caseDir, $manifestDirName, $manifestFile)
|
||||||
|
Else
|
||||||
|
UpdateProgressArea($manifestDirName & " manifest exists, skipping")
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
Next
|
||||||
|
UpdateProgressArea($caseDirName & " manifest generation complete")
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Create a manifest file for a single data source in the same directory that contains the data source (also used for Folder of Logical Files)
|
||||||
|
Func SingleDataSource($settings)
|
||||||
|
Local $dataSourcePath = $settings[0]
|
||||||
|
Local $caseDir = ""
|
||||||
|
Local $caseDrive = ""
|
||||||
|
Local $dsName = ""
|
||||||
|
Local $dsExtension = ""
|
||||||
|
_PathSplit ($dataSourcePath, $caseDrive, $caseDir, $dsName, $dsExtension)
|
||||||
|
$caseDir = $caseDrive & $caseDir
|
||||||
|
Local $caseName = $settings[1]
|
||||||
|
Local $manfiestFilePath = $caseDir & "\" & $dsName & "_" & $manifestFileNameEnd & $manifestExtension
|
||||||
|
If (ManifestAlreadyExists($manfiestFilePath) <> 1) Then
|
||||||
|
;should only be one file and it should end with a valid extension add as image file, or the whole directory is added as a logical file set
|
||||||
|
WriteManifestFile($manfiestFilePath, $dsName, $caseName, $dsName & $dsExtension)
|
||||||
|
Else
|
||||||
|
UpdateProgressArea($dsName & " manifest exists, skipping")
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Algorithm for the All Files in One Folder
|
||||||
|
;Creates manifest files for all files and directories in a single directory
|
||||||
|
Func AllFilesInOneFolder($settings)
|
||||||
|
Local $validDirectory = 1
|
||||||
|
Local $caseDir = $settings[0]
|
||||||
|
;_FileListToArray returns the count of files/folders as the first value then the contents
|
||||||
|
Local $fileList = _FileListToArray($caseDir, Default, $FLTA_FILES, False)
|
||||||
|
If (@error == 1) Then
|
||||||
|
$validDirectory = 0
|
||||||
|
UpdateProgressArea("Selected directory " & $caseDir & " was not found")
|
||||||
|
MsgBox($MB_OK, "Directory Not Found", "Selected directory " & $caseDir & " was not found")
|
||||||
|
ElseIf (@error > 0) Then
|
||||||
|
Local $dirList = _FileListToArray($caseDir, Default, $FLTA_FOLDERS, True)
|
||||||
|
If (@error ==4) Then
|
||||||
|
UpdateProgressArea("Selected directory " & $caseDir & " was empty and contained nothing to generate manifest files for")
|
||||||
|
MsgBox($MB_OK, "Selected Directory Empty", "Selected directory " & $caseDir & " was empty and contained nothing to generate manifest files for")
|
||||||
|
$validDirectory = 0
|
||||||
|
EndIf
|
||||||
|
;An acceptable condition as no files means no manifest files
|
||||||
|
ElseIf ManifestFilesAlreadyExist($fileList) == 1 Then
|
||||||
|
UpdateProgressArea("Selected directory " & $caseDir & " already contains manifest files, they must be deleted before generating new ones")
|
||||||
|
MsgBox($MB_OK, "Manifest Files Exist", "Selected directory " & $caseDir & " already contains manifest files, they must be deleted before generating new ones")
|
||||||
|
$validDirectory = 0
|
||||||
|
EndIf
|
||||||
|
Local $contentsList = _FileListToArray ($caseDir, Default, Default, False)
|
||||||
|
If $validDirectory = 1 Then
|
||||||
|
For $fileNumber = 1 TO $contentsList[0] Step 1
|
||||||
|
Local $manifestDir = Null
|
||||||
|
Local $manifestFile = $contentsList[$fileNumber]
|
||||||
|
GenerateCaseNameAndWriteManifestFile($caseDir, $manifestDir, $manifestFile)
|
||||||
|
Next
|
||||||
|
UpdateProgressArea($caseDir & " manifest generation complete")
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;If the progress area is Null it will not be updated
|
||||||
|
Func UpdateProgressArea($textToAdd)
|
||||||
|
if ($progressArea <> Null) Then
|
||||||
|
Local $currentProgressAreaText = GUICtrlRead($progressArea)
|
||||||
|
$currentProgressAreaText = $currentProgressAreaText & @CRLF & "--" & $textToAdd
|
||||||
|
GUICtrlSetData($progressArea, $currentProgressAreaText)
|
||||||
|
_GUICtrlEdit_Scroll($progressArea, $SB_SCROLLCARET)
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
298
ManifestTool/ManifestTool.au3
Normal file
298
ManifestTool/ManifestTool.au3
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
#include <GUIConstantsEx.au3>
|
||||||
|
#include <MsgBoxConstants.au3>
|
||||||
|
#include<ComboConstants.au3>
|
||||||
|
#include <EditConstants.au3>
|
||||||
|
#include<WindowsConstants.au3>
|
||||||
|
#include <ManifestGenerationAlgorithms.au3>
|
||||||
|
|
||||||
|
|
||||||
|
Opt("GUIOnEventMode", 1) ; Change to OnEvent mode
|
||||||
|
;==============================================
|
||||||
|
;
|
||||||
|
;Draw GUI and declare variables
|
||||||
|
;
|
||||||
|
;==============================================
|
||||||
|
local $windowHeight = 500
|
||||||
|
local $windowWidth = 400
|
||||||
|
local $windowTitle = "Autopsy AutoIngest Manifest File Generator"
|
||||||
|
Global $hMainGUI = GUICreate($windowTitle, $windowWidth, $windowHeight) ;To make GUI resize add following args -1, -1, $WS_OVERLAPPEDWINDOW)
|
||||||
|
;GUICtrlSetResizing ($hMainGUI, $GUI_DOCKBORDERS)
|
||||||
|
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton")
|
||||||
|
|
||||||
|
Global $propertiesFile = "ManifestTool.settings"
|
||||||
|
Global $workingDir = @WorkingDir
|
||||||
|
|
||||||
|
local $topMargin = 12
|
||||||
|
local $leftMargin = 12
|
||||||
|
local $labelOffset = 1
|
||||||
|
local $buttonOffset = -3
|
||||||
|
local $progressAreaInset = 8
|
||||||
|
local $distanceFromTop = $topMargin
|
||||||
|
local $distanceFromLeft = $leftMargin
|
||||||
|
Global $defaultDirectory = @MyDocumentsDir & "\"
|
||||||
|
local $labelWidth = 58
|
||||||
|
local $fieldWidth = 235
|
||||||
|
local $buttonWidth = 60
|
||||||
|
local $fieldHeight = 20
|
||||||
|
local $progressAreaWidth = $windowWidth - 2*($progressAreaInset+$leftMargin)
|
||||||
|
local $gapBetweenWidth = 10
|
||||||
|
local $gapBetweenHeight = 10
|
||||||
|
|
||||||
|
;Draw the GUI Code
|
||||||
|
GUICtrlCreateLabel("Algorithm", $distanceFromLeft, $distanceFromTop+$labelOffset)
|
||||||
|
$distanceFromLeft = $distanceFromLeft+$labelWidth+$gapBetweenWidth
|
||||||
|
|
||||||
|
Global $algorithmComboBox = GUICtrlCreateCombo(GetDefaultAlgorithmName(), $distanceFromLeft, $distanceFromTop, $fieldWidth, $fieldHeight, $CBS_DROPDOWNLIST)
|
||||||
|
GUICtrlSetOnEvent($algorithmComboBox, "Redraw")
|
||||||
|
Global $allAlgorithmNames = GetAlgorithmNames()
|
||||||
|
for $algorithmName IN $allAlgorithmNames
|
||||||
|
; Add additional items to the combobox.
|
||||||
|
GUICtrlSetData($algorithmComboBox, $algorithmName)
|
||||||
|
Next
|
||||||
|
|
||||||
|
|
||||||
|
$distanceFromLeft = $leftMargin
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight
|
||||||
|
|
||||||
|
Global $rootFolderLabel = GUICtrlCreateLabel("Root Folder", $distanceFromLeft, $distanceFromTop+$labelOffset)
|
||||||
|
$distanceFromLeft = $distanceFromLeft+$labelWidth+$gapBetweenWidth
|
||||||
|
Global $rootFolderField = GUICtrlCreateInput("", $distanceFromLeft, $distanceFromTop, $fieldWidth, $fieldHeight)
|
||||||
|
$distanceFromLeft = $distanceFromLeft +$fieldWidth+$gapBetweenWidth
|
||||||
|
Global $browseButton = GUICtrlCreateButton("Browse", $distanceFromLeft, $distanceFromTop+$buttonOffset, $buttonWidth)
|
||||||
|
$distanceFromLeft = $leftMargin
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight
|
||||||
|
|
||||||
|
Global $caseNameLabel = GUICtrlCreateLabel("Case Name", $distanceFromLeft, $distanceFromTop+$labelOffset)
|
||||||
|
$distanceFromLeft = $distanceFromLeft+$labelWidth+$gapBetweenWidth
|
||||||
|
Global $caseNameField = GUICtrlCreateInput("", $distanceFromLeft, $distanceFromTop, $fieldWidth, $fieldHeight)
|
||||||
|
$distanceFromLeft = $leftMargin
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight
|
||||||
|
|
||||||
|
$distanceFromTop = $distanceFromTop + $gapBetweenHeight ;add an extra gap before run button
|
||||||
|
Global $runButton = GUICtrlCreateButton("Run", $distanceFromLeft, $distanceFromTop+$buttonOffset, $buttonWidth)
|
||||||
|
GUICtrlSetOnEvent($runButton, "AlgorithmRunAction")
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight
|
||||||
|
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight ;add extra gap before progress area
|
||||||
|
local $ProgressLabel = GUICtrlCreateLabel("Progress", $distanceFromLeft, $distanceFromTop+$labelOffset)
|
||||||
|
$distanceFromTop = $distanceFromTop + $fieldHeight + $gapBetweenHeight
|
||||||
|
|
||||||
|
$distanceFromLeft = $distanceFromLeft + $progressAreaInset
|
||||||
|
$progressAreaHeight = $windowHeight -$distanceFromTop - $gapBetweenHeight - $gapBetweenHeight - $fieldHeight ;calculate height of progress area to use remaining space minus space for exit button
|
||||||
|
Global $progressField = GUICtrlCreateEdit("", $distanceFromLeft, $distanceFromTop, $progressAreaWidth, $progressAreaHeight, BitOr($ES_READONLY,$WS_VSCROLL, $ES_MULTILINE))
|
||||||
|
|
||||||
|
$distanceFromLeft = $distanceFromLeft + $progressAreaWidth - $buttonWidth
|
||||||
|
$distanceFromTop = $distanceFromTop + $progressAreaHeight + $gapBetweenHeight
|
||||||
|
Local $exitButton = GUICtrlCreateButton("Exit", $distanceFromLeft, $distanceFromTop+$buttonOffset, $buttonWidth)
|
||||||
|
GUICtrlSetOnEvent($exitButton, "CLOSEButton")
|
||||||
|
|
||||||
|
|
||||||
|
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton")
|
||||||
|
GUISwitch($hMainGUI)
|
||||||
|
GUISetState(@SW_SHOW)
|
||||||
|
ChangeToDefaultGUI()
|
||||||
|
|
||||||
|
ReadPropertiesFile()
|
||||||
|
|
||||||
|
Local $oldCaseName = GUICtrlRead($caseNameField)
|
||||||
|
local $oldRootFolder = GUICtrlRead($rootFolderField)
|
||||||
|
While 1
|
||||||
|
Sleep(100) ; Sleep to reduce CPU usage
|
||||||
|
ValidateFields($oldCaseName, $oldRootFolder) ;validate here so that we check the current value of any input areas without requiring a change in focus
|
||||||
|
$oldCaseName = GUICtrlRead($caseNameField)
|
||||||
|
$oldRootFolder = GUICtrlRead($rootFolderField)
|
||||||
|
WEnd
|
||||||
|
|
||||||
|
|
||||||
|
;==============================================
|
||||||
|
;
|
||||||
|
;Functions
|
||||||
|
;
|
||||||
|
;==============================================
|
||||||
|
|
||||||
|
; Read the saved properties file, if none exist make one with the current settings
|
||||||
|
Func ReadPropertiesFile()
|
||||||
|
If FileExists($propertiesFile) <> 1 Then
|
||||||
|
FileChangeDir($workingDir)
|
||||||
|
_FileCreate($propertiesFile)
|
||||||
|
WritePropertiesFile()
|
||||||
|
Endif
|
||||||
|
Local $propertiesFileHandle = FileOpen($propertiesFile, $FO_READ)
|
||||||
|
Local $savedSelection = FileReadLine($propertiesFileHandle, 1)
|
||||||
|
Local $indexOfSelection = _ArraySearch($allAlgorithmNames, $savedSelection)
|
||||||
|
if ($indexOfSelection >= 0) Then
|
||||||
|
GUICtrlSetData($algorithmComboBox, $savedSelection, $savedSelection)
|
||||||
|
EndIf
|
||||||
|
Local $savedDirectory = FileReadLine($propertiesFileHandle, 2)
|
||||||
|
if (FileExists($savedDirectory)) Then
|
||||||
|
$defaultDirectory = $savedDirectory
|
||||||
|
EndIf
|
||||||
|
FileClose($propertiesFileHandle)
|
||||||
|
Redraw()
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
; Write the current settings to the properties file
|
||||||
|
Func WritePropertiesFile()
|
||||||
|
FileChangeDir($workingDir)
|
||||||
|
Local $propertiesFileHandle = FileOpen($propertiesFile, $FO_OVERWRITE)
|
||||||
|
If $propertiesFileHandle == -1 Then ;can't access the properties file so exit
|
||||||
|
Return
|
||||||
|
EndIf
|
||||||
|
FileWrite($propertiesFileHandle, GUICtrlRead($algorithmComboBox) & @CRLF)
|
||||||
|
FileWrite($propertiesFileHandle, $defaultDirectory & @CRLF)
|
||||||
|
FileClose($propertiesFileHandle)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;Make only the settings and labels relevent to the selected Algorithm visible using $GUI_SHOW and $GUI_HIDE
|
||||||
|
Func Redraw()
|
||||||
|
; Note: At this point @GUI_CtrlId would equal algorithmComboBox
|
||||||
|
Local $selectedAlgName = GUICtrlRead($algorithmComboBox)
|
||||||
|
;Move controls based on what is hidden or shown using ControlGetPos() and GUICtrlSetPos()
|
||||||
|
If $selectedAlgName == $allAlgorithmNames[2] Then ;"One Data Source Per Folder"
|
||||||
|
ChangeToDefaultGUI()
|
||||||
|
ElseIf $selectedAlgName == $allAlgorithmNames[0] Then ;"Single Data Source"
|
||||||
|
ChangeToSingleDataSourceGUI()
|
||||||
|
ElseIf $selectedAlgName == $allAlgorithmNames[1] Then ;"Folder of Logical Files"
|
||||||
|
ChangeToFolderOfLogicalFilesGUI()
|
||||||
|
EndIf
|
||||||
|
EndFunc ;==>AlgorithmComboBox
|
||||||
|
|
||||||
|
;Change the controls displayed in the GUI to the ones needed for the Single Data Source algorithm
|
||||||
|
Func ChangeToSingleDataSourceGUI()
|
||||||
|
ClearFields()
|
||||||
|
GUICtrlSetData($rootFolderLabel, "Data Source")
|
||||||
|
GUICtrlSetState($caseNameField, $GUI_SHOW)
|
||||||
|
GUICtrlSetState($caseNameLabel, $GUI_SHOW)
|
||||||
|
GUICtrlSetOnEvent($browseButton, "BrowseForDataSourceFile")
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Change the controls displayed in the GUI to the ones needed for the Folder of Logical Files algorithm
|
||||||
|
Func ChangeToFolderOfLogicalFilesGUI()
|
||||||
|
ClearFields()
|
||||||
|
GUICtrlSetData($rootFolderLabel, "Data Source")
|
||||||
|
GUICtrlSetData($rootFolderLabel, "Data Source")
|
||||||
|
GUICtrlSetState($caseNameField, $GUI_SHOW)
|
||||||
|
GUICtrlSetState($caseNameLabel, $GUI_SHOW)
|
||||||
|
GUICtrlSetOnEvent($browseButton, "Browse")
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Change the controls displayed in the GUI to the ones needed for One
|
||||||
|
Func ChangeToDefaultGUI()
|
||||||
|
ClearFields()
|
||||||
|
GUICtrlSetData($rootFolderLabel, "Root Folder")
|
||||||
|
GUICtrlSetState($rootFolderField, $GUI_SHOW)
|
||||||
|
GUICtrlSetState($rootFolderLabel, $GUI_SHOW)
|
||||||
|
GUICtrlSetState($caseNameField, $GUI_HIDE)
|
||||||
|
GUICtrlSetState($caseNameLabel, $GUI_HIDE)
|
||||||
|
GUICtrlSetOnEvent($browseButton, "Browse")
|
||||||
|
;rename to RootDirectory to root directory
|
||||||
|
;hide case name field
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;ensure that all fields for the selected algorithm are valid
|
||||||
|
Func ValidateFields($oldCaseName, $oldRootFolder)
|
||||||
|
Local $dataSourcePath = GUICtrlRead($rootFolderField)
|
||||||
|
Local $caseName = GUICtrlRead($caseNameField)
|
||||||
|
if ($dataSourcePath <> $oldRootFolder Or $caseName <> $oldCaseName) Then
|
||||||
|
Local $selectedAlgName = GUICtrlRead($algorithmComboBox)
|
||||||
|
If $selectedAlgName == $allAlgorithmNames[2] Then ;"One Data Source Per Folder"
|
||||||
|
ValidateDefaultFields($dataSourcePath)
|
||||||
|
ElseIf $selectedAlgName == $allAlgorithmNames[0] Then ;"Single Data Source"
|
||||||
|
ValidateSingleDataSourceFields($dataSourcePath, $caseName)
|
||||||
|
ElseIf $selectedAlgName == $allAlgorithmNames[1] Then ;"Folder of Logical Files"
|
||||||
|
ValidateSingleDataSourceFields($dataSourcePath, $caseName)
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;ensure that the settings for the default algorithm are valid before enabling it
|
||||||
|
Func ValidateDefaultFields($rootFolderPath)
|
||||||
|
if ($rootFolderPath <> "" And FileExists($rootFolderPath)) Then
|
||||||
|
GUICtrlSetState($runButton, $GUI_ENABLE)
|
||||||
|
Else
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;ensure that the settings for the Single Data Source and Folder of Logical Files algorithms are valid
|
||||||
|
Func ValidateSingleDataSourceFields($dataSourcePath, $caseName)
|
||||||
|
if ($dataSourcePath <> "" And FileExists($dataSourcePath) And $caseName <> "") Then
|
||||||
|
GUICtrlSetState($runButton, $GUI_ENABLE)
|
||||||
|
Else
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
EndIf
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;clear all input fields, and reset them to an empty string
|
||||||
|
Func ClearFields()
|
||||||
|
GUICtrlSetData($rootFolderField, "")
|
||||||
|
GUICtrlSetData($caseNameField, "")
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Open a directory chooser
|
||||||
|
Func Browse()
|
||||||
|
; Note: At this point @GUI_CtrlId would equal $browseButton
|
||||||
|
GUICtrlSetState($browseButton, $GUI_DISABLE)
|
||||||
|
Local $selectedDirectory = FileSelectFolder("Select Folder", $defaultDirectory)
|
||||||
|
Local $caseDir = ""
|
||||||
|
Local $caseDrive = ""
|
||||||
|
If (FileExists($selectedDirectory)) Then
|
||||||
|
_PathSplit($selectedDirectory, $caseDrive, $caseDir, "", "")
|
||||||
|
$defaultDirectory = $caseDrive & $caseDir
|
||||||
|
GUICtrlSetData($rootFolderField, $selectedDirectory)
|
||||||
|
EndIf
|
||||||
|
GUICtrlSetState($caseNameField, $GUI_FOCUS)
|
||||||
|
GUICtrlSetState($browseButton, $GUI_ENABLE)
|
||||||
|
EndFunc ;==>BrowseButton
|
||||||
|
|
||||||
|
; Open a file chooser
|
||||||
|
Func BrowseForDataSourceFile()
|
||||||
|
; Note: At this point @GUI_CtrlId would equal $browseButton
|
||||||
|
GUICtrlSetState($browseButton, $GUI_DISABLE)
|
||||||
|
Local $selectedDataSource = FileOpenDialog("Select Data Source", $defaultDirectory, "All Supported Types (*.img; *.dd; *.001; *.aa; *.raw; *.bin; *.E01; *.vmdk; *.vhd) |Raw Images (*.img; *.dd; *.001; *.aa; *.raw; *.bin) |Encase Images (*.E01) |Virtual Machines (*.vmdk; *.vhd) |Logical Evidence File (*.L01) |All Files (*.*)", $FD_FILEMUSTEXIST)
|
||||||
|
Local $caseDir = ""
|
||||||
|
Local $caseDrive = ""
|
||||||
|
If (FileExists($selectedDataSource)) Then
|
||||||
|
_PathSplit ($selectedDataSource, $caseDrive, $caseDir, "", "")
|
||||||
|
$defaultDirectory = $caseDrive & $caseDir
|
||||||
|
GUICtrlSetData($rootFolderField, $selectedDataSource)
|
||||||
|
EndIf
|
||||||
|
GUICtrlSetState($caseNameField, $GUI_FOCUS)
|
||||||
|
GUICtrlSetState($browseButton, $GUI_ENABLE)
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Perform the action associated with the run button which should be defined in ManifestGenerationAlgorithms.au3
|
||||||
|
Func AlgorithmRunAction()
|
||||||
|
; Note: At this point @GUI_CtrlId would equal $runButton
|
||||||
|
GUICtrlSetState($runButton, $GUI_DISABLE)
|
||||||
|
RunAlgorithm(GUICtrlRead($algorithmComboBox), GetSettings(), $progressField)
|
||||||
|
GUICtrlSetState($runButton, $GUI_ENABLE)
|
||||||
|
EndFunc ;==>RunButton
|
||||||
|
|
||||||
|
;Get an array of settings as they are set on this panel
|
||||||
|
Func GetSettings()
|
||||||
|
Local $settings[2]
|
||||||
|
$settings[0] = GUICtrlRead($rootFolderField)
|
||||||
|
$settings[1] = GUICtrlRead($caseNameField)
|
||||||
|
Return $settings
|
||||||
|
EndFunc
|
||||||
|
|
||||||
|
;Close the tool
|
||||||
|
Func CLOSEButton()
|
||||||
|
; Note: at this point @GUI_CtrlId would equal $GUI_EVENT_CLOSE,
|
||||||
|
; @GUI_WinHandle will be either $hMainGUI or $hDummyGUI
|
||||||
|
GUICtrlSetState($exitButton, $GUI_DISABLE)
|
||||||
|
If @GUI_WinHandle = $hMainGUI Then
|
||||||
|
Local $msgBoxAnswer = MsgBox(1, "Close Tool Confirmation", "Press OK to confirm closing the tool")
|
||||||
|
if $msgBoxAnswer == 1 Then
|
||||||
|
WritePropertiesFile()
|
||||||
|
Exit
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
GUICtrlSetState($exitButton, $GUI_ENABLE)
|
||||||
|
EndFunc ;==>CLOSEButton
|
BIN
ManifestTool/ManifestTool.exe
Normal file
BIN
ManifestTool/ManifestTool.exe
Normal file
Binary file not shown.
@ -102,6 +102,7 @@
|
|||||||
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
|
<copy file="${basedir}/NEWS.txt" tofile="${zip-tmp}/${app.name}/NEWS.txt"/>
|
||||||
<copy file="${basedir}/Running_Linux_OSX.txt" tofile="${zip-tmp}/${app.name}/Running_Linux_OSX.txt"/>
|
<copy file="${basedir}/Running_Linux_OSX.txt" tofile="${zip-tmp}/${app.name}/Running_Linux_OSX.txt"/>
|
||||||
<copy file="${basedir}/unix_setup.sh" tofile="${zip-tmp}/${app.name}/unix_setup.sh"/>
|
<copy file="${basedir}/unix_setup.sh" tofile="${zip-tmp}/${app.name}/unix_setup.sh"/>
|
||||||
|
<copy file="${basedir}/ManifestTool/ManifestTool.exe" todir="${zip-tmp}/${app.name}/bin"/>
|
||||||
|
|
||||||
|
|
||||||
<copy file="${basedir}/icons/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
|
<copy file="${basedir}/icons/icon.ico" tofile="${zip-tmp}/${app.name}/icon.ico" overwrite="true"/>
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
docs/doxygen-user/images/AutoIngest/manifest_tool_ui.png
Normal file
BIN
docs/doxygen-user/images/AutoIngest/manifest_tool_ui.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
62
docs/doxygen-user/manifest_tool.dox
Normal file
62
docs/doxygen-user/manifest_tool.dox
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*! \page manifest_tool_page Manifest Tool
|
||||||
|
|
||||||
|
\section manifest_tool_overview Overview
|
||||||
|
|
||||||
|
Manifest Tool is an executable designed to assist in the automated creation of manifest files which are necessary to run Auto Ingest on a data source. There is no installation necessary. To use the tool double click on Manifest Tool executable, when it opens select the option with the algorithm you wish to run from the combo box, and fill in all the available settings before clicking the Run button. A log with the success or failure of each manifest file it attempts to create will appear in the progress area.
|
||||||
|
|
||||||
|
\section manifest_tool_output Output
|
||||||
|
|
||||||
|
The output of the Manifest Tool will be XML files ending in _Manifest.xml.
|
||||||
|
|
||||||
|
\subsection manifest_tool_one_ds_per_folder One Data Source Per Folder
|
||||||
|
|
||||||
|
The One Data Source Per Folder algorithm is designed for a specific use case when the case folder contains multiple subfolders, with each generally containing one data data source of a short list of types. Please see \ref manifest_tool_algorithm_specifics for details on this algorithm.
|
||||||
|
|
||||||
|
To use this algorithm, use the Browse button to select a root folder as the case directory. Then select the Run button to generate manifest files for each of the data sources detected. A manifest file will be generated for each subfolder of the selected root folder, the manifest files will be placed inside the selected root folder.
|
||||||
|
|
||||||
|
\subsection manifest_tool_single_ds Single Data Source
|
||||||
|
|
||||||
|
The Single Data Source algorithm is for creating a manifest file for a single image or logical file with a user specified case name.
|
||||||
|
|
||||||
|
To use this algorithm, use the Browse button to select a file to use as your data source, and enter a case name in the case name field. Then select the Run button to generate a manifest file. The manifest file will be created in the same folder as your selected data source.
|
||||||
|
|
||||||
|
\subsection manifest_tool_logical_file_folder Folder of Logical Files
|
||||||
|
|
||||||
|
The Folder of Logical Files algorithm is for creating a single manifest file for an entire folder of files which will all be ingested as logical files.
|
||||||
|
|
||||||
|
To use this algorithm, use the Browse button to select a folder to add as a folder of logical files, and enter a case name in the case name field. Then select the Run button to generate a manifest file. The manifest file will be created in the parent folder of your selected folder of logical files.
|
||||||
|
|
||||||
|
\section manifest_tol_example Example
|
||||||
|
|
||||||
|
Given a root folder that looks like this:
|
||||||
|
|
||||||
|
\image html AutoIngest/manifest_tool_root_folder.png
|
||||||
|
|
||||||
|
A user having selected the One Data Source Per Folder algorithm will get output that looks like the following, where a manifest now exists for each non-empty subfolder. The root folder's name will be used as the case name in the manifest files (in this example the case name will be TestCaseFolder.)
|
||||||
|
|
||||||
|
\image html AutoIngest/manifest_tool_ui.png
|
||||||
|
|
||||||
|
The contents of an XML file will have the following format:
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<AutopsyManifest>
|
||||||
|
<CaseName>TestCaseFolder</CaseName>
|
||||||
|
<DataSource>interestingL01\interesting_files2.L01</DataSource>
|
||||||
|
</AutopsyManifest>
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
\section manifest_tool_algorithm_specifics One Data Source Per Folder Algorithm Specifics
|
||||||
|
<ul>
|
||||||
|
<li>The only configuration setting the user needs to choose is a root folder.
|
||||||
|
<li>The name of the specified root folder will become the case name used in the manifest files.
|
||||||
|
<li>Each non-empty subfolder in the root folder will have a manifest file created for it.
|
||||||
|
<li>All manifest files will be created in the root folder.
|
||||||
|
<li>Files directly in the root folder will be ignored and remain unprocessed.
|
||||||
|
<li>Subfolders which contain an .E01, .L01, .001, or .AD1 file, will have the first file of this type used as the data source in the manifest file.
|
||||||
|
<li>Subfolders which have more than one .E01, .L01, .001, or .AD1 file will have the additional files ignored and they will remain unprocessed.
|
||||||
|
<li>Subfolders without an .E01, .L01, .001, or .AD1 file will have the entire subfolder added as the data source.
|
||||||
|
<li>If the root folder already contains a specific _Manifest.xml file then it will not be replaced or modified.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
*/
|
Loading…
x
Reference in New Issue
Block a user