diff --git a/GBM/Classes/clsGame.vb b/GBM/Classes/clsGame.vb
index 7c30b7b..3a4f9a8 100644
--- a/GBM/Classes/clsGame.vb
+++ b/GBM/Classes/clsGame.vb
@@ -112,7 +112,12 @@ Public Class clsGame
bAbsolutePath = value
End Set
Get
- Return bAbsolutePath
+ 'This makes sure a registry key path isn't seen as a relative path.
+ If mgrPath.IsSupportedRegistryPath(TruePath) Then
+ Return True
+ Else
+ Return bAbsolutePath
+ End If
End Get
End Property
diff --git a/GBM/Forms/frmMain.vb b/GBM/Forms/frmMain.vb
index f17c515..703b50a 100644
--- a/GBM/Forms/frmMain.vb
+++ b/GBM/Forms/frmMain.vb
@@ -221,10 +221,14 @@ Public Class frmMain
bOSVerified = VerifyBackupForOS(oGame, oRestoreInfo.RestorePath)
- If mgrRestore.CheckPath(oRestoreInfo, oGame, bTriggerReload) Then
+ If mgrPath.IsSupportedRegistryPath(oRestoreInfo.TruePath) Then
bPathVerified = True
Else
- UpdateLog(mgrCommon.FormatString(frmMain_ErrorRestorePath, oRestoreInfo.Name), False, ToolTipIcon.Error, True)
+ If mgrRestore.CheckPath(oRestoreInfo, oGame, bTriggerReload) Then
+ bPathVerified = True
+ Else
+ UpdateLog(mgrCommon.FormatString(frmMain_ErrorRestorePath, oRestoreInfo.Name), False, ToolTipIcon.Error, True)
+ End If
End If
If bOSVerified And bPathVerified Then
@@ -2112,16 +2116,16 @@ Public Class frmMain
If DoMultiGameCheck() Then
UpdateLog(mgrCommon.FormatString(frmMain_GameEnded, oProcess.GameInfo.Name), False)
If oProcess.WineProcess Then
+ oProcess.WineData.MonitorID = oProcess.GameInfo.ID
'Attempt a path conversion if the game configuration is using an absolute windows path that we can convert
If mgrVariables.CheckForReservedVariables(oProcess.GameInfo.TruePath) Then
- oProcess.WineData.MonitorID = oProcess.GameInfo.ID
oProcess.WineData.SavePath = mgrPath.GetWineSavePath(oProcess.WineData.Prefix, oProcess.GameInfo.TruePath)
If Not oProcess.WineData.SavePath = oProcess.GameInfo.TruePath Then
oProcess.GameInfo.TruePath = oProcess.WineData.SavePath
- mgrWineData.DoWineDataAddUpdate(oProcess.WineData)
UpdateLog(mgrCommon.FormatString(frmMain_WineSavePath, oProcess.WineData.SavePath), False)
End If
End If
+ mgrWineData.DoWineDataAddUpdate(oProcess.WineData)
'This does required mods to include/exclude data and relative paths (if required)
mgrPath.ModWinePathData(oProcess.GameInfo)
End If
diff --git a/GBM/Managers/mgrBackup.vb b/GBM/Managers/mgrBackup.vb
index 511e5cf..7d9e4d0 100644
--- a/GBM/Managers/mgrBackup.vb
+++ b/GBM/Managers/mgrBackup.vb
@@ -120,47 +120,64 @@ Public Class mgrBackup
Dim lAvailableSpace As Long
Dim lFolderSize As Long = 0
Dim sDeepFolder As String
+ Dim bRegistry As Boolean
+ Dim sExtension As String
+
+ 'Check if this is a registry backup
+ bRegistry = mgrPath.IsSupportedRegistryPath(oGame.TruePath)
+
+ If bRegistry Then
+ 'If this is a registry backup, we need to have elevated permissions in Windows to use regedit
+ If Not mgrCommon.IsUnix And Not mgrCommon.IsElevated Then
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorRegBackupElevation, oGame.Name), False, ToolTipIcon.Info, True)
+ Return False
+ End If
+ sExtension = ".reg"
+ Else
+ 'Verify saved game path
+ sSavePath = VerifySavePath(oGame)
+
+ 'Check if disk space check should be disabled (UNC path or Setting)
+ If Not mgrPath.IsPathUNC(oSettings.BackupFolder) And Not Settings.DisableDiskSpaceCheck Then
+ 'Calculate space
+ lAvailableSpace = mgrCommon.GetAvailableDiskSpace(oSettings.BackupFolder)
+
+ 'If any includes are using a deep path and we aren't using recursion, we need to go directly to folders to do file size calculations or they will be missed.
+ If Not oGame.RecurseSubFolders Then
+ For Each s As String In oGame.IncludeArray
+ If s.Contains(Path.DirectorySeparatorChar) Then
+ sDeepFolder = Path.GetDirectoryName(sSavePath & Path.DirectorySeparatorChar & s)
+ If Directory.Exists(sDeepFolder) Then
+ lFolderSize += mgrCommon.GetFolderSize(sDeepFolder, oGame.IncludeArray, oGame.ExcludeArray, oGame.RecurseSubFolders)
+ End If
+ End If
+ Next
+ End If
+ lFolderSize += mgrCommon.GetFolderSize(sSavePath, oGame.IncludeArray, oGame.ExcludeArray, oGame.RecurseSubFolders)
+
+ 'Show Available Space
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrCommon_AvailableDiskSpace, mgrCommon.FormatDiskSpace(lAvailableSpace)), False, ToolTipIcon.Info, True)
+
+ 'Show Save Folder Size
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrCommon_SavedGameFolderSize, New String() {oGame.Name, mgrCommon.FormatDiskSpace(lFolderSize)}), False, ToolTipIcon.Info, True)
+
+ If lFolderSize >= lAvailableSpace Then
+ If mgrCommon.ShowMessage(mgrBackup_ConfirmDiskSpace, MsgBoxStyle.YesNo) = MsgBoxResult.No Then
+ RaiseEvent UpdateLog(mgrBackup_ErrorDiskSpace, False, ToolTipIcon.Error, True)
+ Return False
+ End If
+ End If
+ Else
+ 'Show that disk space check was skipped due to UNC path
+ If Not Settings.DisableDiskSpaceCheck Then RaiseEvent UpdateLog(mgrBackup_ErrorBackupPathIsUNC, False, ToolTipIcon.Info, True)
+ End If
+
+ sExtension = ".7z"
+ End If
If oSettings.CreateSubFolder Then sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame)
- sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & ".7z"
- 'Verify saved game path
- sSavePath = VerifySavePath(oGame)
-
- 'Check if disk space check should be disabled (UNC path or Setting)
- If Not mgrPath.IsPathUNC(oSettings.BackupFolder) And Not Settings.DisableDiskSpaceCheck Then
- 'Calculate space
- lAvailableSpace = mgrCommon.GetAvailableDiskSpace(oSettings.BackupFolder)
-
- 'If any includes are using a deep path and we aren't using recursion, we need to go directly to folders to do file size calculations or they will be missed.
- If Not oGame.RecurseSubFolders Then
- For Each s As String In oGame.IncludeArray
- If s.Contains(Path.DirectorySeparatorChar) Then
- sDeepFolder = Path.GetDirectoryName(sSavePath & Path.DirectorySeparatorChar & s)
- If Directory.Exists(sDeepFolder) Then
- lFolderSize += mgrCommon.GetFolderSize(sDeepFolder, oGame.IncludeArray, oGame.ExcludeArray, oGame.RecurseSubFolders)
- End If
- End If
- Next
- End If
- lFolderSize += mgrCommon.GetFolderSize(sSavePath, oGame.IncludeArray, oGame.ExcludeArray, oGame.RecurseSubFolders)
-
- 'Show Available Space
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrCommon_AvailableDiskSpace, mgrCommon.FormatDiskSpace(lAvailableSpace)), False, ToolTipIcon.Info, True)
-
- 'Show Save Folder Size
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrCommon_SavedGameFolderSize, New String() {oGame.Name, mgrCommon.FormatDiskSpace(lFolderSize)}), False, ToolTipIcon.Info, True)
-
- If lFolderSize >= lAvailableSpace Then
- If mgrCommon.ShowMessage(mgrBackup_ConfirmDiskSpace, MsgBoxStyle.YesNo) = MsgBoxResult.No Then
- RaiseEvent UpdateLog(mgrBackup_ErrorDiskSpace, False, ToolTipIcon.Error, True)
- Return False
- End If
- End If
- Else
- 'Show that disk space check was skipped due to UNC path
- If Not Settings.DisableDiskSpaceCheck Then RaiseEvent UpdateLog(mgrBackup_ErrorBackupPathIsUNC, False, ToolTipIcon.Info, True)
- End If
+ sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & sExtension
'A manifest check is only required when "Save Multiple Backups" is disabled
If Not oGame.AppendTimeStamp Then
@@ -185,7 +202,7 @@ Public Class mgrBackup
End If
End If
- Return True
+ Return True
End Function
Private Sub CheckOldBackups(ByVal oGame As clsGame)
@@ -292,23 +309,166 @@ Public Class mgrBackup
Next
End Sub
+ Private Function RunRegistryBackup(ByVal oGame As clsGame, ByVal sBackupFile As String) As Boolean
+ Dim prsReg As New Process
+ Dim sBinaryPath As String
+ Dim sArguments As String
+ Dim oWineData As clsWineData
+ Dim sWineRegEdit As String
+ Dim bPathVerified As Boolean = False
+ Dim bBackupCompleted As Boolean = False
+
+ sArguments = "export """ & oGame.TruePath & """ """ & sBackupFile & """"
+
+ If mgrCommon.IsUnix Then
+ oWineData = mgrWineData.DoWineDataGetbyID(oGame.ID)
+ sBinaryPath = oWineData.BinaryPath & Path.DirectorySeparatorChar & "wine"
+ sWineRegEdit = oWineData.Prefix & Path.DirectorySeparatorChar & "drive_c/windows/system32/reg.exe"
+ sArguments = """" & sWineRegEdit & """ " & sArguments
+ If File.Exists(sBinaryPath) Then
+ If File.Exists(sWineRegEdit) Then
+ bPathVerified = True
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorRegNotFound, sWineRegEdit), False, ToolTipIcon.Error, True)
+ End If
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorWineNotFound, sBinaryPath), False, ToolTipIcon.Error, True)
+ End If
+ Else
+ sBinaryPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) & Path.DirectorySeparatorChar & "system32\reg.exe"
+ If File.Exists(sBinaryPath) Then
+ bPathVerified = True
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorRegNotFound, sBinaryPath), False, ToolTipIcon.Error, True)
+ End If
+ End If
+
+ If bPathVerified Then
+ Try
+ 'Need to delete any prior file if it exists, otherwise reg.exe will get stuck waiting for input it'll never get.
+ If File.Exists(sBackupFile) Then
+ File.Delete(sBackupFile)
+ End If
+
+ prsReg.StartInfo.Arguments = sArguments
+ prsReg.StartInfo.FileName = sBinaryPath
+ prsReg.StartInfo.UseShellExecute = False
+ prsReg.StartInfo.RedirectStandardOutput = True
+ prsReg.StartInfo.CreateNoWindow = True
+ prsReg.Start()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupInProgress, oGame.TruePath), False, ToolTipIcon.Info, True)
+ While Not prsReg.StandardOutput.EndOfStream
+ If CancelOperation Then
+ prsReg.Kill()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorFullAbort, oGame.Name), True, ToolTipIcon.Error, True)
+ Exit While
+ End If
+ RaiseEvent UpdateLog(prsReg.StandardOutput.ReadLine, False, ToolTipIcon.Info, False)
+ End While
+ prsReg.WaitForExit()
+ Select Case prsReg.ExitCode
+ Case 0
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupComplete, New String() {oGame.Name, mgrCommon.FormatDiskSpace(mgrCommon.GetFileSize(sBackupFile))}), False, ToolTipIcon.Info, True)
+ bBackupCompleted = True
+ Case Else
+ RaiseEvent UpdateLog(mgrBackup_ErrorRegBackupFailed, False, ToolTipIcon.Info, True)
+ End Select
+ prsReg.Dispose()
+ Catch ex As Exception
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorOtherFailure, New String() {oGame.Name, ex.Message}), False, ToolTipIcon.Error, True)
+ End Try
+ End If
+
+ Return bBackupCompleted
+ End Function
+
+ Private Function Run7zBackup(ByVal oGame As clsGame, ByVal sBackupFile As String) As Boolean
+ Dim prs7z As New Process
+ Dim sSavePath As String
+ Dim sArguments As String
+ Dim bBackupCompleted As Boolean = False
+
+ sSavePath = VerifySavePath(oGame)
+
+ If oGame.FolderSave = True Then
+ BuildFileList("*", mgrPath.IncludeFileLocation)
+ Else
+ BuildFileList(oGame.FileType, mgrPath.IncludeFileLocation)
+ End If
+
+ BuildFileList(oGame.ExcludeList, mgrPath.ExcludeFileLocation)
+
+ sArguments = "a" & oSettings.Prepared7zArguments & "-t7z -mx" & oSettings.CompressionLevel & " -i@""" & mgrPath.IncludeFileLocation & """ -x@""" & mgrPath.ExcludeFileLocation & """ """ & sBackupFile & """"
+
+ If oGame.RecurseSubFolders Then sArguments &= " -r"
+
+ Try
+ If Directory.Exists(sSavePath) Then
+ If Settings.Is7zUtilityValid Then
+ 'Need to delete any prior archive if it exists, the 7za utility does not support overwriting or deleting existing archives.
+ 'If we let 7za update existing archives it will lead to excessive bloat with games that routinely add and remove files with many different file names.
+ If File.Exists(sBackupFile) Then
+ File.Delete(sBackupFile)
+ End If
+
+ prs7z.StartInfo.Arguments = sArguments
+ prs7z.StartInfo.FileName = oSettings.Utility7zLocation
+ prs7z.StartInfo.WorkingDirectory = sSavePath
+ prs7z.StartInfo.UseShellExecute = False
+ prs7z.StartInfo.RedirectStandardOutput = True
+ prs7z.StartInfo.CreateNoWindow = True
+ prs7z.Start()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupInProgress, sSavePath), False, ToolTipIcon.Info, True)
+ While Not prs7z.StandardOutput.EndOfStream
+ If CancelOperation Then
+ prs7z.Kill()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorFullAbort, oGame.Name), True, ToolTipIcon.Error, True)
+ Exit While
+ End If
+ RaiseEvent UpdateLog(prs7z.StandardOutput.ReadLine, False, ToolTipIcon.Info, False)
+ End While
+ prs7z.WaitForExit()
+ If Not CancelOperation Then
+ Select Case prs7z.ExitCode
+ Case 0
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupComplete, New String() {oGame.Name, mgrCommon.FormatDiskSpace(mgrCommon.GetFileSize(sBackupFile))}), False, ToolTipIcon.Info, True)
+ bBackupCompleted = True
+ Case 1
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zWarnings, oGame.Name), True, ToolTipIcon.Warning, True)
+ bBackupCompleted = True
+ Case 2
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zFatalError, oGame.Name), True, ToolTipIcon.Error, True)
+ Case 7
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zCommandFailure, oGame.Name), True, ToolTipIcon.Error, True)
+ End Select
+ End If
+ prs7z.Dispose()
+ Else
+ RaiseEvent UpdateLog(App_Invalid7zDetected, True, ToolTipIcon.Error, True)
+ End If
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorNoSavePath, oGame.Name), True, ToolTipIcon.Error, True)
+ End If
+ Catch ex As Exception
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorOtherFailure, New String() {oGame.Name, ex.Message}), False, ToolTipIcon.Error, True)
+ End Try
+
+ Return bBackupCompleted
+ End Function
+
Public Sub DoBackup(ByVal oBackupList As List(Of clsGame))
Dim oGame As clsGame
Dim bDoBackup As Boolean
- Dim bBackupCompleted As Boolean
- Dim prs7z As Process
Dim sBackupFile As String
- Dim sSavePath As String
+ Dim sBackupExt As String
Dim dTimeStamp As DateTime
Dim sTimeStamp As String
Dim sHash As String
- Dim sArguments As String
+ Dim bBackupCompleted As Boolean
For Each oGame In oBackupList
'Init
- prs7z = New Process
sBackupFile = oSettings.BackupFolder
- sSavePath = String.Empty
dTimeStamp = Date.Now
sTimeStamp = BuildFileTimeStamp(dTimeStamp)
sHash = String.Empty
@@ -322,100 +482,42 @@ Public Class mgrBackup
bDoBackup = HandleSubFolder(oGame, sBackupFile)
End If
+ If mgrPath.IsSupportedRegistryPath(oGame.TruePath) Then
+ sBackupExt = ".reg"
+ Else
+ sBackupExt = ".7z"
+ End If
+
If oGame.AppendTimeStamp Then
If oGame.BackupLimit > 0 Then CheckOldBackups(oGame)
- sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & sTimeStamp & ".7z"
+ sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & sTimeStamp & sBackupExt
Else
- sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & ".7z"
+ sBackupFile = sBackupFile & Path.DirectorySeparatorChar & GetFileName(oGame) & sBackupExt
End If
If bDoBackup Then
-
- sSavePath = VerifySavePath(oGame)
-
- If oGame.FolderSave = True Then
- BuildFileList("*", mgrPath.IncludeFileLocation)
+ 'Choose Backup Type
+ If mgrPath.IsSupportedRegistryPath(oGame.TruePath) Then
+ bBackupCompleted = RunRegistryBackup(oGame, sBackupFile)
Else
- BuildFileList(oGame.FileType, mgrPath.IncludeFileLocation)
+ bBackupCompleted = Run7zBackup(oGame, sBackupFile)
End If
- BuildFileList(oGame.ExcludeList, mgrPath.ExcludeFileLocation)
+ 'Write Main Manifest
+ If bBackupCompleted Then
+ 'Generate checksum for new backup
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_GenerateHash, oGame.Name), False, ToolTipIcon.Info, True)
+ sHash = mgrHash.Generate_SHA256_Hash(sBackupFile)
- sArguments = "a" & oSettings.Prepared7zArguments & "-t7z -mx" & oSettings.CompressionLevel & " -i@""" & mgrPath.IncludeFileLocation & """ -x@""" & mgrPath.ExcludeFileLocation & """ """ & sBackupFile & """"
-
- If oGame.RecurseSubFolders Then sArguments &= " -r"
-
- Try
- If Directory.Exists(sSavePath) Then
- If Settings.Is7zUtilityValid Then
- 'Need to delete any prior archive if it exists, the 7za utility does not support overwriting or deleting existing archives.
- 'If we let 7za update existing archives it will lead to excessive bloat with games that routinely add and remove files with many different file names.
- If File.Exists(sBackupFile) Then
- File.Delete(sBackupFile)
- End If
-
- prs7z.StartInfo.Arguments = sArguments
- prs7z.StartInfo.FileName = oSettings.Utility7zLocation
- prs7z.StartInfo.WorkingDirectory = sSavePath
- prs7z.StartInfo.UseShellExecute = False
- prs7z.StartInfo.RedirectStandardOutput = True
- prs7z.StartInfo.CreateNoWindow = True
- prs7z.Start()
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupInProgress, sSavePath), False, ToolTipIcon.Info, True)
- While Not prs7z.StandardOutput.EndOfStream
- If CancelOperation Then
- prs7z.Kill()
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorFullAbort, oGame.Name), True, ToolTipIcon.Error, True)
- Exit While
- End If
- RaiseEvent UpdateLog(prs7z.StandardOutput.ReadLine, False, ToolTipIcon.Info, False)
- End While
- prs7z.WaitForExit()
- If Not CancelOperation Then
- Select Case prs7z.ExitCode
- Case 0
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_BackupComplete, New String() {oGame.Name, mgrCommon.FormatDiskSpace(mgrCommon.GetFileSize(sBackupFile))}), False, ToolTipIcon.Info, True)
- bBackupCompleted = True
- Case 1
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zWarnings, oGame.Name), True, ToolTipIcon.Warning, True)
- bBackupCompleted = True
- Case 2
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zFatalError, oGame.Name), True, ToolTipIcon.Error, True)
- bBackupCompleted = False
- Case 7
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_7zCommandFailure, oGame.Name), True, ToolTipIcon.Error, True)
- bBackupCompleted = False
- End Select
- End If
- prs7z.Dispose()
- Else
- RaiseEvent UpdateLog(App_Invalid7zDetected, True, ToolTipIcon.Error, True)
- bBackupCompleted = False
- End If
- Else
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorNoSavePath, oGame.Name), True, ToolTipIcon.Error, True)
- bBackupCompleted = False
+ If Not DoManifestUpdate(oGame, sBackupFile, dTimeStamp, sHash) Then
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorManifestFailure, oGame.Name), True, ToolTipIcon.Error, True)
End If
- 'Write Main Manifest
- If bBackupCompleted Then
-
- 'Generate checksum for new backup
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_GenerateHash, oGame.Name), False, ToolTipIcon.Info, True)
- sHash = mgrHash.Generate_SHA256_Hash(sBackupFile)
-
- If Not DoManifestUpdate(oGame, sBackupFile, dTimeStamp, sHash) Then
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorManifestFailure, oGame.Name), True, ToolTipIcon.Error, True)
- End If
-
- 'Write the process path if we have it
- If oGame.AbsolutePath = False Then
- mgrMonitorList.DoListFieldUpdate("ProcessPath", oGame.ProcessPath, oGame.ID)
- End If
+ 'Write the process path if we have it
+ If oGame.AbsolutePath = False Then
+ mgrMonitorList.DoListFieldUpdate("ProcessPath", oGame.ProcessPath, oGame.ID)
End If
- Catch ex As Exception
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrBackup_ErrorOtherFailure, New String() {oGame.Name, ex.Message}), False, ToolTipIcon.Error, True)
- End Try
+ End If
End If
If bBackupCompleted Then
diff --git a/GBM/Managers/mgrPath.vb b/GBM/Managers/mgrPath.vb
index 1542b70..f3a4647 100644
--- a/GBM/Managers/mgrPath.vb
+++ b/GBM/Managers/mgrPath.vb
@@ -485,6 +485,16 @@ Public Class mgrPath
Return sValue
End Function
+ Public Shared Function IsSupportedRegistryPath(ByVal sPath As String)
+ If sPath.StartsWith("HKEY_CURRENT_USER") Then
+ Return True
+ ElseIf sPath.StartsWith("HKEY_LOCAL_MACHINE") Then
+ Return True
+ End If
+
+ Return False
+ End Function
+
Public Shared Function IsPathUNC(sPath As String) As Boolean
Dim sPrefix As String = Path.DirectorySeparatorChar & Path.DirectorySeparatorChar
If sPath.StartsWith(sPrefix) Then Return True
diff --git a/GBM/Managers/mgrRestore.vb b/GBM/Managers/mgrRestore.vb
index 3f89ac9..697ac6a 100644
--- a/GBM/Managers/mgrRestore.vb
+++ b/GBM/Managers/mgrRestore.vb
@@ -122,31 +122,43 @@ Public Class mgrRestore
Public Function CheckRestorePrereq(ByVal oBackupInfo As clsBackup, ByVal bCleanFolder As Boolean) As Boolean
Dim sHash As String
Dim sExtractPath As String
+ Dim bRegistry As Boolean
Dim sBackupFile As String = oSettings.BackupFolder & Path.DirectorySeparatorChar & oBackupInfo.FileName
- If oBackupInfo.AbsolutePath Then
- sExtractPath = oBackupInfo.RestorePath
- Else
- sExtractPath = oBackupInfo.RelativeRestorePath
- End If
+ 'Check if this is a registry backup
+ bRegistry = mgrPath.IsSupportedRegistryPath(oBackupInfo.TruePath)
- 'Check if restore location exists, prompt to create if it doesn't.
- If Not Directory.Exists(sExtractPath) Then
- If mgrCommon.ShowMessage(mgrRestore_ConfirmCreatePath, sExtractPath, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
- Try
- Directory.CreateDirectory(sExtractPath)
- Catch ex As Exception
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorCreatePath, ex.Message), False, ToolTipIcon.Error, True)
- Return False
- End Try
- Else
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorNoPath, sExtractPath), False, ToolTipIcon.Error, True)
+ If bRegistry Then
+ 'If this is a registry backup, we need to have elevated permissions in Windows to use regedit
+ If Not mgrCommon.IsUnix And Not mgrCommon.IsElevated Then
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorRegBackupElevation, oBackupInfo.Name), False, ToolTipIcon.Info, True)
Return False
End If
Else
- If bCleanFolder Then
- mgrCommon.DeleteDirectory(sExtractPath, True)
- Directory.CreateDirectory(sExtractPath)
+ If oBackupInfo.AbsolutePath Then
+ sExtractPath = oBackupInfo.RestorePath
+ Else
+ sExtractPath = oBackupInfo.RelativeRestorePath
+ End If
+
+ 'Check if restore location exists, prompt to create if it doesn't.
+ If Not Directory.Exists(sExtractPath) Then
+ If mgrCommon.ShowMessage(mgrRestore_ConfirmCreatePath, sExtractPath, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ Try
+ Directory.CreateDirectory(sExtractPath)
+ Catch ex As Exception
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorCreatePath, ex.Message), False, ToolTipIcon.Error, True)
+ Return False
+ End Try
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorNoPath, sExtractPath), False, ToolTipIcon.Error, True)
+ Return False
+ End If
+ Else
+ If bCleanFolder Then
+ mgrCommon.DeleteDirectory(sExtractPath, True)
+ Directory.CreateDirectory(sExtractPath)
+ End If
End If
End If
@@ -170,77 +182,144 @@ Public Class mgrRestore
Return True
End Function
+ Private Function RunRegistryRestore(ByVal oBackupInfo As clsBackup, ByVal sBackupFile As String) As Boolean
+ Dim prsReg As New Process
+ Dim sBinaryPath As String
+ Dim sArguments As String
+ Dim oWineData As clsWineData
+ Dim sWineRegEdit As String
+ Dim bPathVerified As Boolean
+ Dim bRestoreCompleted As Boolean = False
+
+ sArguments = "import """ & sBackupFile & """"
+
+ If mgrCommon.IsUnix Then
+ oWineData = mgrWineData.DoWineDataGetbyID(oBackupInfo.MonitorID)
+ sBinaryPath = oWineData.BinaryPath & Path.DirectorySeparatorChar & "wine"
+ sWineRegEdit = oWineData.Prefix & Path.DirectorySeparatorChar & "drive_c/windows/system32/reg.exe"
+ sArguments = """" & sWineRegEdit & """ " & sArguments
+ If File.Exists(sBinaryPath) Then
+ If File.Exists(sWineRegEdit) Then
+ bPathVerified = True
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorRegNotFound, sWineRegEdit), False, ToolTipIcon.Error, True)
+ End If
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorWineNotFound, sBinaryPath), False, ToolTipIcon.Error, True)
+ End If
+ Else
+ sBinaryPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) & Path.DirectorySeparatorChar & "system32\reg.exe"
+ If File.Exists(sBinaryPath) Then
+ bPathVerified = True
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorRegNotFound, sBinaryPath), False, ToolTipIcon.Error, True)
+ End If
+ End If
+
+ If bPathVerified Then
+ Try
+ prsReg.StartInfo.Arguments = sArguments
+ prsReg.StartInfo.FileName = sBinaryPath
+ prsReg.StartInfo.UseShellExecute = False
+ prsReg.StartInfo.RedirectStandardOutput = True
+ prsReg.StartInfo.CreateNoWindow = True
+ prsReg.Start()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreInProgress, oBackupInfo.TruePath), False, ToolTipIcon.Info, True)
+ prsReg.WaitForExit()
+ Select Case prsReg.ExitCode
+ Case 0
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreComplete, oBackupInfo.Name), False, ToolTipIcon.Info, True)
+ bRestoreCompleted = True
+ Case Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreWarnings, oBackupInfo.Name), True, ToolTipIcon.Warning, True)
+ End Select
+ prsReg.Dispose()
+ Catch ex As Exception
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorOtherFailure, ex.Message), False, ToolTipIcon.Error, True)
+ End Try
+ End If
+
+ Return bRestoreCompleted
+ End Function
+
+ Private Function Run7zRestore(ByVal oBackupInfo As clsBackup, ByVal sBackupFile As String) As Boolean
+ Dim prs7z As New Process
+ Dim sExtractPath As String
+ Dim bRestoreCompleted As Boolean = False
+
+ If oBackupInfo.AbsolutePath Then
+ sExtractPath = oBackupInfo.RestorePath
+ Else
+ sExtractPath = oBackupInfo.RelativeRestorePath
+ End If
+
+ Try
+ If File.Exists(sBackupFile) Then
+ If Settings.Is7zUtilityValid Then
+ prs7z.StartInfo.Arguments = "x" & oSettings.Prepared7zArguments & """" & sBackupFile & """ -o""" & sExtractPath & Path.DirectorySeparatorChar & """ -aoa -r"
+ prs7z.StartInfo.FileName = oSettings.Utility7zLocation
+ prs7z.StartInfo.UseShellExecute = False
+ prs7z.StartInfo.RedirectStandardOutput = True
+ prs7z.StartInfo.CreateNoWindow = True
+ prs7z.Start()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreInProgress, sExtractPath), False, ToolTipIcon.Info, True)
+ While Not prs7z.StandardOutput.EndOfStream
+ If CancelOperation Then
+ prs7z.Kill()
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorFullAbort, oBackupInfo.Name), True, ToolTipIcon.Error, True)
+ Exit While
+ End If
+ RaiseEvent UpdateLog(prs7z.StandardOutput.ReadLine, False, ToolTipIcon.Info, False)
+ End While
+ prs7z.WaitForExit()
+ If Not CancelOperation Then
+ If prs7z.ExitCode = 0 Then
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreComplete, oBackupInfo.Name), False, ToolTipIcon.Info, True)
+ bRestoreCompleted = True
+ Else
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreWarnings, oBackupInfo.Name), True, ToolTipIcon.Warning, True)
+ End If
+ End If
+ prs7z.Dispose()
+ Else
+ RaiseEvent UpdateLog(App_Invalid7zDetected, True, ToolTipIcon.Error, True)
+ End If
+ Else
+ RaiseEvent UpdateLog(mgrRestore_ErrorNoBackup, True, ToolTipIcon.Error, True)
+ End If
+ Catch ex As Exception
+ RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorOtherFailure, ex.Message), False, ToolTipIcon.Error, True)
+ End Try
+
+ Return bRestoreCompleted
+ End Function
+
Public Sub DoRestore(ByVal oRestoreList As List(Of clsBackup))
- Dim prs7z As Process
Dim sBackupFile As String
Dim sExtractPath As String
Dim bRestoreCompleted As Boolean
For Each oBackupInfo In oRestoreList
'Init
- prs7z = New Process
sBackupFile = oSettings.BackupFolder & Path.DirectorySeparatorChar & oBackupInfo.FileName
sExtractPath = String.Empty
bRestoreCompleted = False
CancelOperation = False
RaiseEvent UpdateRestoreInfo(oBackupInfo)
- If oBackupInfo.AbsolutePath Then
- sExtractPath = oBackupInfo.RestorePath
+ If mgrPath.IsSupportedRegistryPath(oBackupInfo.TruePath) Then
+ bRestoreCompleted = RunRegistryRestore(oBackupInfo, sBackupFile)
Else
- sExtractPath = oBackupInfo.RelativeRestorePath
+ bRestoreCompleted = Run7zRestore(oBackupInfo, sBackupFile)
End If
- Try
- If File.Exists(sBackupFile) Then
- If Settings.Is7zUtilityValid Then
- prs7z.StartInfo.Arguments = "x" & oSettings.Prepared7zArguments & """" & sBackupFile & """ -o""" & sExtractPath & Path.DirectorySeparatorChar & """ -aoa -r"
- prs7z.StartInfo.FileName = oSettings.Utility7zLocation
- prs7z.StartInfo.UseShellExecute = False
- prs7z.StartInfo.RedirectStandardOutput = True
- prs7z.StartInfo.CreateNoWindow = True
- prs7z.Start()
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreInProgress, sExtractPath), False, ToolTipIcon.Info, True)
- While Not prs7z.StandardOutput.EndOfStream
- If CancelOperation Then
- prs7z.Kill()
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorFullAbort, oBackupInfo.Name), True, ToolTipIcon.Error, True)
- Exit While
- End If
- RaiseEvent UpdateLog(prs7z.StandardOutput.ReadLine, False, ToolTipIcon.Info, False)
- End While
- prs7z.WaitForExit()
- If Not CancelOperation Then
- If prs7z.ExitCode = 0 Then
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreComplete, oBackupInfo.Name), False, ToolTipIcon.Info, True)
- bRestoreCompleted = True
- Else
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_RestoreWarnings, oBackupInfo.Name), True, ToolTipIcon.Warning, True)
- bRestoreCompleted = False
- End If
- End If
- prs7z.Dispose()
- Else
- RaiseEvent UpdateLog(App_Invalid7zDetected, True, ToolTipIcon.Error, True)
- bRestoreCompleted = False
- End If
- Else
- RaiseEvent UpdateLog(mgrRestore_ErrorNoBackup, True, ToolTipIcon.Error, True)
- End If
-
- If bRestoreCompleted Then
- 'Save Local Manifest
- If mgrManifest.DoManifestCheck(oBackupInfo.MonitorID, mgrSQLite.Database.Local) Then
- mgrManifest.DoManifestUpdateByMonitorID(oBackupInfo, mgrSQLite.Database.Local)
- Else
- mgrManifest.DoManifestAdd(oBackupInfo, mgrSQLite.Database.Local)
- End If
- End If
- Catch ex As Exception
- RaiseEvent UpdateLog(mgrCommon.FormatString(mgrRestore_ErrorOtherFailure, ex.Message), False, ToolTipIcon.Error, True)
- End Try
-
If bRestoreCompleted Then
+ 'Save Local Manifest
+ If mgrManifest.DoManifestCheck(oBackupInfo.MonitorID, mgrSQLite.Database.Local) Then
+ mgrManifest.DoManifestUpdateByMonitorID(oBackupInfo, mgrSQLite.Database.Local)
+ Else
+ mgrManifest.DoManifestAdd(oBackupInfo, mgrSQLite.Database.Local)
+ End If
RaiseEvent SetLastAction(mgrCommon.FormatString(mgrRestore_ActionComplete, oBackupInfo.CroppedName))
Else
RaiseEvent SetLastAction(mgrCommon.FormatString(mgrRestore_ActionFailed, oBackupInfo.CroppedName))
diff --git a/GBM/My Project/Resources.Designer.vb b/GBM/My Project/Resources.Designer.vb
index b39afad..e6b3f8a 100644
--- a/GBM/My Project/Resources.Designer.vb
+++ b/GBM/My Project/Resources.Designer.vb
@@ -6123,6 +6123,33 @@ Namespace My.Resources
End Get
End Property
+ '''
+ ''' Looks up a localized string similar to [PARAM] stores saved games in the Windows registry, accessing the registry requires elevated permissions. Please restart GBM as Administrator to perform this backup..
+ '''
+ Friend ReadOnly Property mgrBackup_ErrorRegBackupElevation() As String
+ Get
+ Return ResourceManager.GetString("mgrBackup_ErrorRegBackupElevation", resourceCulture)
+ End Get
+ End Property
+
+ '''
+ ''' Looks up a localized string similar to The backup has failed, please ensure the registry path is correct..
+ '''
+ Friend ReadOnly Property mgrBackup_ErrorRegBackupFailed() As String
+ Get
+ Return ResourceManager.GetString("mgrBackup_ErrorRegBackupFailed", resourceCulture)
+ End Get
+ End Property
+
+ '''
+ ''' Looks up a localized string similar to The regedit utility could not be located at [PARAM]. The backup cannot continue..
+ '''
+ Friend ReadOnly Property mgrBackup_ErrorRegNotFound() As String
+ Get
+ Return ResourceManager.GetString("mgrBackup_ErrorRegNotFound", resourceCulture)
+ End Get
+ End Property
+
'''
''' Looks up a localized string similar to A failure occured while creating a backup sub-folder for [PARAM].[BR][PARAM].
'''
@@ -6132,6 +6159,15 @@ Namespace My.Resources
End Get
End Property
+ '''
+ ''' Looks up a localized string similar to The wine binary could not be located at [PARAM]. The backup cannot continue..
+ '''
+ Friend ReadOnly Property mgrBackup_ErrorWineNotFound() As String
+ Get
+ Return ResourceManager.GetString("mgrBackup_ErrorWineNotFound", resourceCulture)
+ End Get
+ End Property
+
'''
''' Looks up a localized string similar to Generating SHA-256 hash for [PARAM] backup file..
'''
@@ -6636,6 +6672,33 @@ Namespace My.Resources
End Get
End Property
+ '''
+ ''' Looks up a localized string similar to [PARAM] stores saved games in the Windows registry, accessing the registry requires elevated permissions. Please restart GBM as Administrator to restore this backup..
+ '''
+ Friend ReadOnly Property mgrRestore_ErrorRegBackupElevation() As String
+ Get
+ Return ResourceManager.GetString("mgrRestore_ErrorRegBackupElevation", resourceCulture)
+ End Get
+ End Property
+
+ '''
+ ''' Looks up a localized string similar to The regedit utility could not be located at [PARAM]. The restore cannot continue..
+ '''
+ Friend ReadOnly Property mgrRestore_ErrorRegNotFound() As String
+ Get
+ Return ResourceManager.GetString("mgrRestore_ErrorRegNotFound", resourceCulture)
+ End Get
+ End Property
+
+ '''
+ ''' Looks up a localized string similar to The wine binary could not be located at [PARAM]. The restore cannot continue..
+ '''
+ Friend ReadOnly Property mgrRestore_ErrorWineNotFound() As String
+ Get
+ Return ResourceManager.GetString("mgrRestore_ErrorWineNotFound", resourceCulture)
+ End Get
+ End Property
+
'''
''' Looks up a localized string similar to [PARAM] has no stored checksum, verification has been skipped..
'''
diff --git a/GBM/My Project/Resources.resx b/GBM/My Project/Resources.resx
index 0ce53fa..9fd943c 100644
--- a/GBM/My Project/Resources.resx
+++ b/GBM/My Project/Resources.resx
@@ -2347,4 +2347,25 @@
An error occured while creating the autostart link:[BR][BR][PARAM]
+
+ [PARAM] stores saved games in the Windows registry, accessing the registry requires elevated permissions. Please restart GBM as Administrator to perform this backup.
+
+
+ The backup has failed, please ensure the registry path is correct.
+
+
+ The regedit utility could not be located at [PARAM]. The backup cannot continue.
+
+
+ The wine binary could not be located at [PARAM]. The backup cannot continue.
+
+
+ The regedit utility could not be located at [PARAM]. The restore cannot continue.
+
+
+ The wine binary could not be located at [PARAM]. The restore cannot continue.
+
+
+ [PARAM] stores saved games in the Windows registry, accessing the registry requires elevated permissions. Please restart GBM as Administrator to restore this backup.
+
\ No newline at end of file