Skip to content

Commit

Permalink
Merge pull request #11 from basharast/main
Browse files Browse the repository at this point in the history
Minor fixes
  • Loading branch information
fadilfadz01 authored Oct 14, 2024
2 parents eef3e7e + e733a63 commit f50cfcf
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 72 deletions.
Binary file not shown.
132 changes: 79 additions & 53 deletions Universal Updater/DownloadPackages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Net.NetworkInformation;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Universal_Updater
Expand Down Expand Up @@ -78,7 +79,7 @@ public static bool OnlineUpdate(string updateBuild)
return isFeatureInstalled;
}

public static void OfflineUpdate(string[] folderFiles, string pushFeature)
public static bool OfflineUpdate(string[] folderFiles, string pushFeature)
{
filterPackages:
filteredPackages.Clear();
Expand Down Expand Up @@ -130,8 +131,8 @@ public static void OfflineUpdate(string[] folderFiles, string pushFeature)

// Allow user to push all package if he want
Program.WriteLine("\nFilter packages options: ", ConsoleColor.Blue);
Program.WriteLine("1. Filter packages (Recommended)", ConsoleColor.Green);
Program.WriteLine("2. Push all", ConsoleColor.DarkYellow);
Program.WriteLine("1. Filter packages", ConsoleColor.Green);
Program.WriteLine("2. Include all", ConsoleColor.DarkYellow);
Program.Write("Choice: ", ConsoleColor.Magenta);
ConsoleKeyInfo packagesFilterAction;
do
Expand Down Expand Up @@ -255,30 +256,56 @@ public static void OfflineUpdate(string[] folderFiles, string pushFeature)
if (filteredPackages.Count > 0)
{
var testCabFile = filteredPackages.FirstOrDefault();
var certificateIssuer = "";
var certificateDate = "";
var certificateExpireDate = "";
var dtFmt = "";
bool isTestSigned = false;
try
{
X509Certificate cert = X509Certificate.CreateFromSignedFile(testCabFile);

certificateDate = cert.GetEffectiveDateString();
certificateExpireDate = cert.GetExpirationDateString();
certificateIssuer = cert.Issuer;
Match m = Regex.Match(certificateIssuer, @"CN=(.*?)(?=,)");
if (m.Success)
{
certificateIssuer = m.Groups[1].Value;
}

Program.WriteLine("\n[CERTIFICATE]", ConsoleColor.Green);
Program.Write("Issuer : ", ConsoleColor.DarkGray);
Program.WriteLine(certificateIssuer, ConsoleColor.DarkCyan);
Program.Write("Date : ", ConsoleColor.DarkGray);
Program.Write(certificateDate.ToDate(ref dtFmt).Value.ToString("d"), ConsoleColor.DarkGray);
Program.Write(" - ", ConsoleColor.DarkGray);
Program.WriteLine(certificateExpireDate.ToDate(ref dtFmt).Value.ToString("d"), ConsoleColor.DarkGray);
Program.Write("Type : ", ConsoleColor.DarkGray);

// Currently we do basic check using [Issuer]
// Test signed mostly contain `Development` or `Test`
// Production has mostly `Microsoft Code Signing`
Program.Write("Packages signature may ");
var hasDevelopmentKeyword = cert.Issuer.IndexOf("Development", StringComparison.OrdinalIgnoreCase) >= 0;
var hasTestKeyword = cert.Issuer.IndexOf("Test", StringComparison.OrdinalIgnoreCase) >= 0;
var hasSigningKeyword = cert.Issuer.IndexOf("Microsoft Code Signing", StringComparison.OrdinalIgnoreCase) >= 0;
if ((hasDevelopmentKeyword || hasTestKeyword) && !hasSigningKeyword)
var hasDevelopmentKeyword = certificateIssuer.IndexOf("Development", StringComparison.OrdinalIgnoreCase) >= 0;
var hasTestKeyword = certificateIssuer.IndexOf("Test", StringComparison.OrdinalIgnoreCase) >= 0;
if ((hasDevelopmentKeyword || hasTestKeyword))
{
Program.WriteLine("test signed.", ConsoleColor.DarkYellow);
Program.Write("Test signed", ConsoleColor.DarkYellow);
Program.WriteLine(" (Please double check)", ConsoleColor.DarkGray);
isTestSigned = true;
}
else
{
Program.WriteLine("production signed.", ConsoleColor.Green);
Program.Write("Production signed", ConsoleColor.Green);
Program.WriteLine(" (Please double check)", ConsoleColor.DarkGray);
}
}
catch (Exception ex)
{

}

DateTime? formatedDate = null;
var expectedDateFormat = "";
var dateModifiedString = "";
try
{
// Not sure how this works, but tested on Windows 11 and seems fine
Expand All @@ -288,39 +315,44 @@ public static void OfflineUpdate(string[] folderFiles, string pushFeature)

foreach (var item in cabFolder.Items())
{
var dateModifiedString = (string)cabFolder.GetDetailsOf(item, 3);
dateModifiedString = (string)cabFolder.GetDetailsOf(item, 3);
// Fix possible encoding crap
byte[] bytes = Encoding.Default.GetBytes(dateModifiedString);
dateModifiedString = Encoding.UTF8.GetString(bytes).Replace("?", "");
DateTime? formatedDate = dateModifiedString.ToDate(null);

if (formatedDate.HasValue)
{
var dateOnly = formatedDate.Value.Date;
Program.Write("\nIf you are updating with ", ConsoleColor.DarkYellow);
Program.Write("(Test Signed)", ConsoleColor.Blue);
Program.WriteLine(" packages,", ConsoleColor.DarkYellow);
Program.WriteLine("set your device to the date below", ConsoleColor.DarkYellow);
var datePlusTwoDays = dateOnly.AddDays(2);
Program.Write("Date: " + datePlusTwoDays.ToString("d"), ConsoleColor.Green);
Program.WriteLine(" (Packages date: " + dateOnly.ToString("d") + ")", ConsoleColor.DarkGray);
}
else
{
Program.WriteLine("\nCould not parse date: " + dateModifiedString, ConsoleColor.DarkGray);
Program.WriteLine("(Ignore this if packages are not test signed)", ConsoleColor.DarkGray);
}
formatedDate = dateModifiedString.ToDate(ref expectedDateFormat);
break;
}
}
catch (Exception ex)
{
}


if (formatedDate != null && formatedDate.HasValue)
{
var dateOnly = formatedDate.Value.Date;
Program.Write("Files : " + dateOnly.ToString("d"), ConsoleColor.DarkGray);
var datePlusTwoDays = dateOnly.AddDays(2);
Program.WriteLine($" ({dtFmt})", ConsoleColor.DarkGray);

if (isTestSigned)
{
// Show this red label if we expect that packages are test signed
Program.Write("\n[IMPORTANT] ", ConsoleColor.DarkRed);
Program.Write("\nPackages expected to be ", ConsoleColor.DarkYellow);
Program.WriteLine("(Test Signed)", ConsoleColor.Blue);
Program.WriteLine("Set your device to the required date", ConsoleColor.DarkYellow);
}
}
else
{
Program.WriteLine("\nCould not parse date: " + dateModifiedString, ConsoleColor.DarkGray);
Program.WriteLine("(Ignore this if packages are not test signed)", ConsoleColor.DarkGray);
}

Program.Write("\nTotal expected packages: ", ConsoleColor.DarkGray);
Program.WriteLine(filteredPackages.Count.ToString(), ConsoleColor.DarkYellow);
Program.WriteLine("1. Push packages");
Program.WriteLine("1. Push packages", ConsoleColor.Green);
Program.WriteLine("2. Retry");
Program.Write("Choice: ", ConsoleColor.Magenta);
ConsoleKeyInfo packagesAction;
Expand Down Expand Up @@ -363,11 +395,16 @@ public static void OfflineUpdate(string[] folderFiles, string pushFeature)
Program.WriteLine("");
goto filterPackages;
}
else
{
return false;
}
}

return true;
}

public static async Task DownloadUpdate(string update)
public static async Task<bool> DownloadUpdate(string update)
{
WebClient client = new WebClient();
Process downloadProcess = new Process();
Expand Down Expand Up @@ -413,6 +450,8 @@ public static async Task DownloadUpdate(string update)
while (fileSize != new FileInfo($@"{Environment.CurrentDirectory}\{GetDeviceInfo.SerialNumber[0]}\Packages\{downloadFile.LocalPath.Split('/').Last()}").Length);
}
}

return true;
}

private static void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs downloadProgressChangedEventArgs)
Expand Down Expand Up @@ -454,28 +493,15 @@ public static bool shouldSkip(string package, bool onlinePackage = false)
}
public static class Extensions
{
/// Extension method parsing a date string to a DateTime? <para/>
/// <summary>
/// </summary>
/// <param name="dateTimeStr">The date string to parse</param>
/// <param name="dateFmt">dateFmt is optional and allows to pass
/// a parsing pattern array or one or more patterns passed
/// as string parameters</param>
/// <returns>Parsed DateTime or null</returns>
public static DateTime? ToDate(this string dateTimeStr, params string[] dateFmt)
public static DateTime? ToDate(this string dateTimeStr, ref string fmtOut)
{
// example: var dt = "2011-03-21 13:26".ToDate(new string[]{"yyyy-MM-dd HH:mm",
// "M/d/yyyy h:mm:ss tt"});
// or simpler:
// var dt = "2011-03-21 13:26".ToDate("yyyy-MM-dd HH:mm", "M/d/yyyy h:mm:ss tt");
const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces;
if (dateFmt == null)
{
var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
dateFmt = dateInfo.GetAllDateTimePatterns();
}
var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
style, out var dt) ? dt : null as DateTime?;

DateTime? result = null;
CultureInfo currentCulture = CultureInfo.CurrentCulture;
fmtOut = currentCulture.DateTimeFormat.ShortDatePattern;
result = DateTime.TryParse(dateTimeStr, CultureInfo.InvariantCulture,
style, out var dt) ? dt : null as DateTime?;
return result;
}
}
Expand Down
2 changes: 1 addition & 1 deletion Universal Updater/GetDeviceInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static int GetLog()
getDeviceInfoProcess.StartInfo.UseShellExecute = false;
getDeviceInfoProcess.Start();
// Better to set timeout and retry?
if (getDeviceInfoProcess.WaitForExit(15000))
if (getDeviceInfoProcess.WaitForExit(30000))
{
return getDeviceInfoProcess.ExitCode;
}
Expand Down
51 changes: 33 additions & 18 deletions Universal Updater/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ static async void StartUpdater()
{
string formattedErrorCode = "0x" + exitCode.ToString("X");
ConsoleStyle($"Cannot read device info ({formattedErrorCode}), retrying . . .", 0, ConsoleColor.Red);
if(formattedErrorCode == "0x8000FFFF")
{
// Usually appear if device is not connected
WriteLine("");
WriteLine("Ensure the device is connected properly", ConsoleColor.Red);
}
// Give user more time to read and copy error
await Task.Delay(3000);
}
Expand Down Expand Up @@ -127,6 +133,8 @@ static async void StartUpdater()
WriteLine("\nAVAILABLE UPDATES", ConsoleColor.DarkGray);
WriteLine(availableUpdates);

var packagesReady = false;

Write("Choice: ", ConsoleColor.Magenta);
if (CheckForUpdates.Choice == 7)
{
Expand Down Expand Up @@ -221,7 +229,7 @@ static async void StartUpdater()
}

WriteLine("\nPREPARING PACKAGES", ConsoleColor.DarkGray);
DownloadPackages.OfflineUpdate(folderFiles, featureChoice.KeyChar.ToString().ToUpper());
packagesReady = DownloadPackages.OfflineUpdate(folderFiles, featureChoice.KeyChar.ToString().ToUpper());
}
else
{
Expand Down Expand Up @@ -280,27 +288,34 @@ static async void StartUpdater()
}

ConsoleStyle("\nDOWNLOADING PACKAGES", 1, ConsoleColor.DarkGray);
await DownloadPackages.DownloadUpdate(updateStructure[CheckForUpdates.Choice - 1, Convert.ToInt32(Program.selectedUpdate.KeyChar.ToString()) - 1]);
packagesReady = await DownloadPackages.DownloadUpdate(updateStructure[CheckForUpdates.Choice - 1, Convert.ToInt32(Program.selectedUpdate.KeyChar.ToString()) - 1]);
}

Write("\nPUSHING PACKAGES", ConsoleColor.DarkGray);
PushPackages.StartUpdate();
await Task.Delay(15000);
if (!PushPackages.updateProcess.HasExited)
if (packagesReady)
{
var commonErrors = "\n\nCommon Errors:";
commonErrors += "\n0x800b010a: Signature Verification Issue\nSolution: Enable flight signing";
commonErrors += "\n\n0x800b0101: Incorrect Date and Time\nSolution: Change date";
commonErrors += "\n\n0x80188302: Package already present on the image";
commonErrors += "\n\n0x80188305: Duplicate packages found in update set";
commonErrors += "\n\n0x80188306: File Collision or Not Found\nSolution: ensure list match InstalledPackages.csv";
commonErrors += "\n\n0x80188307: Package DSM; or contents are invalid\nSolution: Keep only one type in the folder CBS or SPKG,\nChoose the correct packages type";
commonErrors += "\n\n0x80188308: Not enough space";
commonErrors += "\n\n0x800b0114: Certificate has an invalid name\nSolution: Enable flight signing";
commonErrors += "\n\n0x80004005: E_FAIL\nSolution: Reboot the phone and try again";
commonErrors += "\n\n0x802A0006: Try with another PC";
Write("\nPUSHING PACKAGES", ConsoleColor.DarkGray);
PushPackages.StartUpdate();
await Task.Delay(10000);
if (!PushPackages.updateProcess.HasExited)
{
var commonErrors = "\n\nCommon Errors:";
commonErrors += "\n0x800b010a: Signature Verification Issue\nSolution: Enable flight signing";
commonErrors += "\n\n0x800b0101: Incorrect Date and Time\nSolution: Change date";
commonErrors += "\n\n0x80188302: Package already present on the image";
commonErrors += "\n\n0x80188305: Duplicate packages found in update set";
commonErrors += "\n\n0x80188306: File Collision or Not Found\nSolution: ensure list match InstalledPackages.csv";
commonErrors += "\n\n0x80188307: Package DSM; or contents are invalid\nSolution: Keep only one type in the folder CBS or SPKG,\nChoose the correct packages type";
commonErrors += "\n\n0x80188308: Not enough space";
commonErrors += "\n\n0x800b0114: Certificate has an invalid name\nSolution: Enable flight signing";
commonErrors += "\n\n0x80004005: E_FAIL\nSolution: Reboot the phone and try again";
commonErrors += "\n\n0x802A0006: Try with another PC";

MessageBox((IntPtr)0, $"Please navigate to update settings on your phone. As soon as the update shows progression, you can safely disconnect your phone from the PC.\n{commonErrors}", "Universal Updater.exe", 0);
MessageBox((IntPtr)0, $"Please navigate to update settings on your phone. As soon as the update shows progression, you can safely disconnect your phone from the PC.\n{commonErrors}", "Universal Updater.exe", 0);
}
}
else
{
WriteLine("\nOperation cancelled", ConsoleColor.Red);
}
return;
}
Expand Down
6 changes: 6 additions & 0 deletions Universal Updater/Universal Updater.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Dakirby309-Windows-8-Metro-Other-Update-Metro.256.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down Expand Up @@ -70,5 +73,8 @@
<EmbeddedResource Include="Updates\15063.297.txt" />
<EmbeddedResource Include="Updates\15254.603.txt" />
</ItemGroup>
<ItemGroup>
<Content Include="Dakirby309-Windows-8-Metro-Other-Update-Metro.256.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

0 comments on commit f50cfcf

Please sign in to comment.