aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Updater
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-12-15 16:52:30 +0200
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-12-15 16:52:30 +0200
commit66be0fdd579050375421ad54dc25cf35bac0845c (patch)
tree429ebbf390862a2cc1dcad40aecb96a1399c7ab0 /Software/Visual_Studio/PPC/Tango.PPC.Updater
parent97513f619e9778e8409831db04b29b0dcf53f1b9 (diff)
downloadTango-66be0fdd579050375421ad54dc25cf35bac0845c.tar.gz
Tango-66be0fdd579050375421ad54dc25cf35bac0845c.zip
Implemented several fallbacks to PPC update failure !
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Updater')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Updater/IdentityUtils.cs118
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs65
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Updater/Tango.PPC.Updater.csproj1
3 files changed, 171 insertions, 13 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Updater/IdentityUtils.cs b/Software/Visual_Studio/PPC/Tango.PPC.Updater/IdentityUtils.cs
new file mode 100644
index 000000000..3a43be6f9
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Updater/IdentityUtils.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Security.Principal;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Updater
+{
+ public static class IdentityUtils
+ {
+ [DllImport("advapi32.dll", SetLastError = true)]
+ static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);
+
+ /// <summary>
+ /// Passed to <see cref="GetTokenInformation"/> to specify what
+ /// information about the token to return.
+ /// </summary>
+ enum TokenInformationClass
+ {
+ TokenUser = 1,
+ TokenGroups,
+ TokenPrivileges,
+ TokenOwner,
+ TokenPrimaryGroup,
+ TokenDefaultDacl,
+ TokenSource,
+ TokenType,
+ TokenImpersonationLevel,
+ TokenStatistics,
+ TokenRestrictedSids,
+ TokenSessionId,
+ TokenGroupsAndPrivileges,
+ TokenSessionReference,
+ TokenSandBoxInert,
+ TokenAuditPolicy,
+ TokenOrigin,
+ TokenElevationType,
+ TokenLinkedToken,
+ TokenElevation,
+ TokenHasRestrictions,
+ TokenAccessInformation,
+ TokenVirtualizationAllowed,
+ TokenVirtualizationEnabled,
+ TokenIntegrityLevel,
+ TokenUiAccess,
+ TokenMandatoryPolicy,
+ TokenLogonSid,
+ MaxTokenInfoClass
+ }
+
+ /// <summary>
+ /// The elevation type for a user token.
+ /// </summary>
+ enum TokenElevationType
+ {
+ TokenElevationTypeDefault = 1,
+ TokenElevationTypeFull,
+ TokenElevationTypeLimited
+ }
+
+ public static bool IsElevated()
+ {
+ var identity = WindowsIdentity.GetCurrent();
+ if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity");
+ var principal = new WindowsPrincipal(identity);
+
+ // Check if this user has the Administrator role. If they do, return immediately.
+ // If UAC is on, and the process is not elevated, then this will actually return false.
+ //if (principal.IsInRole(WindowsBuiltInRole.Administrator)) return true;
+
+ //// If we're not running in Vista onwards, we don't have to worry about checking for UAC.
+ //if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
+ //{
+ // // Operating system does not support UAC; skipping elevation check.
+ // return false;
+ //}
+
+ int tokenInfLength = Marshal.SizeOf(typeof(int));
+ IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
+
+ try
+ {
+ var token = identity.Token;
+ var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);
+
+ if (!result)
+ {
+ var exception = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
+ throw new InvalidOperationException("Couldn't get token information", exception);
+ }
+
+ var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation);
+
+ switch (elevationType)
+ {
+ case TokenElevationType.TokenElevationTypeDefault:
+ // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
+ return false;
+ case TokenElevationType.TokenElevationTypeFull:
+ // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
+ return true;
+ case TokenElevationType.TokenElevationTypeLimited:
+ // TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator.
+ return false;
+ default:
+ // Unknown token elevation type.
+ return false;
+ }
+ }
+ finally
+ {
+ if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation);
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs b/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs
index 6615ededf..b821b332b 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Updater/MainWindow.xaml.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -69,6 +70,22 @@ namespace Tango.PPC.Updater
{
try
{
+ if (!IdentityUtils.IsElevated())
+ {
+ ShowError("The updater utility is not running under elevated permissions and cannot perform.\nThe process will restart.");
+ var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
+ ProcessStartInfo startInfo = new ProcessStartInfo(exeName);
+ startInfo.Arguments = String.Join(" ", App.StartupArgs);
+ startInfo.Verb = "runas";
+ Process.Start(startInfo);
+ Environment.Exit(0);
+ return;
+ }
+ }
+ catch { }
+
+ try
+ {
Init();
EnsureTangoIsDown();
RemoveOldDLLFiles();
@@ -78,30 +95,42 @@ namespace Tango.PPC.Updater
DoEvents();
Thread.Sleep(1000);
StartTango(true);
+ Exit();
}
catch (Exception ex)
{
- ShowError($"Update failed.\n{ex.Message}");
- StartTango(false);
+ if (ShowErrorRetry($"Update failed.\n{ex.Message}"))
+ {
+ Update();
+ }
+ else
+ {
+ txtStatus.Text = "Update failed. Restoring previous application state...";
+ DoEvents();
+ Thread.Sleep(1000);
+ StartTango(false);
+ Exit();
+ }
}
- finally
+ }
+
+ private void Exit()
+ {
+ try
{
- try
+ foreach (var file in Directory.GetFiles(_sourceFolder, "*.*", SearchOption.AllDirectories))
{
- foreach (var file in Directory.GetFiles(_sourceFolder, "*.*", SearchOption.AllDirectories))
+ try
{
- try
- {
- File.Delete(file);
- }
- catch { }
+ File.Delete(file);
}
+ catch { }
}
- catch { }
+ }
+ catch { }
- Environment.Exit(0);
- }
+ Environment.Exit(0);
}
private void Init()
@@ -137,6 +166,10 @@ namespace Tango.PPC.Updater
{
p.StartInfo.Arguments = "-update_ok";
}
+ else
+ {
+ p.StartInfo.Arguments = "-update_failed";
+ }
p.Start();
}
@@ -248,5 +281,11 @@ namespace Tango.PPC.Updater
{
MessageBox.Show(error, "Tango Update", MessageBoxButton.OK, MessageBoxImage.Error);
}
+
+ private bool ShowErrorRetry(String error)
+ {
+ var result = MessageBox.Show(error + "\n" + "Press yes to retry.", "Tango Update", MessageBoxButton.YesNo, MessageBoxImage.Error);
+ return result == MessageBoxResult.Yes;
+ }
}
}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Updater/Tango.PPC.Updater.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Updater/Tango.PPC.Updater.csproj
index 3f232c4d2..ec40d5887 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Updater/Tango.PPC.Updater.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Updater/Tango.PPC.Updater.csproj
@@ -67,6 +67,7 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
+ <Compile Include="IdentityUtils.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>