private void VerifySignature(RepoB.RepoVersion version) { if (string.IsNullOrEmpty(version.Signature)) { return; } if (version.Signature.ToLower() != version.CalculateSignature().ToLower()) { string file = Folder + version.Version + ".repo"; if (System.IO.File.Exists(file)) { System.IO.File.Delete(file); } throw new Exception("UpdateWrongSignature"); } }
private RepoB.RepoVersion GetVersionIndex(string version) { Globals.Root.Log.WriteLine("Fetching version index: " + version); string file = Folder + version + ".repo"; if (!System.IO.File.Exists(file)) { byte[] data = m_Server.Fetch(Server.Software, RepoB.RepoVersion.StoredAtRel(Server.PRODUCT, version)); System.IO.File.WriteAllBytes(file, data); } RepoB.RepoVersion create = RepoB.RepoList.LoadVersionFile(file); VerifySignature(create); create.SetLocalPath(Globals.Root.InternalFolder + System.IO.Path.DirectorySeparatorChar); create.SetLocalPath("%shared%", Globals.Root.SharedFolder + System.IO.Path.DirectorySeparatorChar); return(create); }
public void VerifyVersion(RepoB.RepoVersion version, bool includeUpdateFolder, ref System.Text.StringBuilder sb, ref int wrong) { // checks our currently installed files against the version, and returns the number of errors and a report in the ByRef parameters // if includeUpdateFolder then files available in the update folder are counted // sb can be nothing if the report is not required if (sb == null) { sb = new System.Text.StringBuilder(); } wrong = 0; foreach (RepoB.RepoFile file in version.Files) { if (!file.Delete) { var statusInt = version.CheckFile(file); if (statusInt != 0 && includeUpdateFolder && FileAvailableInUpdate(file)) { statusInt = 0; } switch (statusInt) { case RepoB.RepoVersion.FileState.Missing: sb.Append(file.Destination).Append(": Missing").Append("\r\n"); wrong += 1; break; case RepoB.RepoVersion.FileState.OK: break; case RepoB.RepoVersion.FileState.Wrong: sb.Append(file.Destination).Append(": Mismatch - current is "); sb.Append(RepoB.FileHash.GetFileHash(version.LocalFilePath(file))); sb.Append(", required ").Append(file.MD5).Append("\r\n"); wrong += 1; break; default: sb.Append(file.Destination).Append("!unknown status!").Append("\r\n"); break; } } Application.DoEvents(); } sb.Append("\r\n").Append(version.Files.Length.ToString()).Append(" total files.").Append("\r\n"); sb.Append(wrong.ToString()).Append(" wrong.").Append("\r\n"); }
public void tmrStart_Tick(object sender, EventArgs e) { // finds which is the latest version available, and gets the index file for it tmrStart.Enabled = false; this.Cursor = Cursors.WaitCursor; string errorAction = "Update_Contact_Failed"; // first part of error message - changes throughout function try { txtLatest.Text = "?"; // will be left in place if fn fails early m_Server = new Repo2SoapClient("Repo2Soap", Server.TechURL + "repo2.asmx"); string latest = m_Server.LastVersionB(Server.Software, Server.PRODUCT, SoftwareVersion.VersionString, "", false, Server.Language2, RootApplication.GetNetVersion(), RootApplication.GetMachineID()); // if it is prefixed with "w", then it needs to be downloaded from the website m_RequiresWeb = false; if (latest.StartsWith("w", StringComparison.InvariantCultureIgnoreCase)) { m_RequiresWeb = true; latest = latest.Substring(1); } latest = latest.Split('#')[0]; // other info can be appended after #. Not used here txtLatest.Text = latest; m_LatestNumber = SoftwareVersion.VersionNumberFromString(latest); errorAction = "Update_Version_Fetch_Failed"; m_Latest = null; if (!m_RequiresWeb) { m_Latest = GetVersionIndex(latest); } errorAction = "Update_Check_Failed"; //MessageBox.Show("m_LatestNumber=" + m_LatestNumber + ", SoftwareVersion.Version=" + SoftwareVersion.Version); if (m_LatestNumber <= SoftwareVersion.Version + 0.001) // the +0.001 added as bizarrely this condition was failing on 32 bit machines when both were "700.7" { lblStatus.Text = Strings.Item("Update_Latest_Installed"); btnDownload.Visible = false; int errors = 0; System.Text.StringBuilder sb = new System.Text.StringBuilder(); VerifyVersion(m_Latest, false, ref sb, ref errors); //Clipboard.SetText(sb.ToString()); if (errors > 0) { lblStatus.Text = Strings.Item("Update_Installation_Damaged"); btnDownload.Text = Strings.Item("Update_Reinstall"); btnDownload.Visible = true; } } else if (m_RequiresWeb) { lblStatus.Text = Strings.Item("Update_Newer_Manual"); btnDownload.Text = Strings.Item("Update_Show_Website"); btnDownload.Visible = true; } else { lblStatus.Text = Strings.Item("Update_Newer_Available"); btnDownload.Text = Strings.Item("Update_Download_Install").Replace("%0", latest); btnDownload.Visible = true; } } catch (Exception ex) { lblStatus.Text = Strings.Item(errorAction).Trim() + " " + ex.Message; } finally { this.Cursor = Cursors.Default; } }
/// <summary>download all the files in the version which are neither already in the update folder, nor match the currently installed files /// Returns true if all of the files were downloaded successfully</summary> private bool FetchVersionFiles(RepoB.RepoVersion version) { try { // generate a list of required files... Globals.Root.LogPermanent.WriteLine("Starting fetch version " + version.Version); StartAsync(Strings.Item("Update_Checking_Files")); RepoB.XferList updateList = new RepoB.XferList(); foreach (RepoB.RepoFile file in version.Files) { if (!file.IsFolder() && !FileAvailableInUpdate(file) && version.CheckFile(file) != RepoB.RepoVersion.FileState.OK) { updateList.Add(file); } Application.DoEvents(); } if (m_Cancel) { return(false); } // Download the actual files... StartAsync(Strings.Item("Update_Downloading"), updateList.Count(), updateList.TotalSize()); foreach (RepoB.RepoFile file in updateList.Files) { string localPath = Folder + file.StoredName(); if (file.Delete == false && (!System.IO.File.Exists(localPath) || RepoB.FileHash.GetFileHash(localPath).ToLower() != file.MD5.ToLower())) { if (System.IO.File.Exists(localPath)) { // needs to ensure that the file is writable System.IO.File.SetAttributes(localPath, System.IO.FileAttributes.Normal); } FetchFile("Files\\" + file.StoredName(), localPath, file.Size); if (m_Cancel) { return(false); } } else { AsyncProgress(1, file.Size); } } if (m_Cancel) { return(false); } // Verify the integrity of the files StartAsync(Strings.Item("Update_Verifying"), updateList.Count(), 0); int fails = 0; foreach (RepoB.RepoFile file in updateList.Files) { if (!file.Delete) { string localPath = Folder + file.StoredName(); if (!System.IO.File.Exists(localPath) || RepoB.FileHash.GetFileHash(localPath).ToLower() != file.MD5.ToLower()) { fails += 1; Globals.Root.Log.WriteLine("Failed, file missing or corrupt: " + file.Destination + " (stored at " + localPath + ")"); } } AsyncProgress(1, 0); if (m_Cancel) { return(false); } } // Report the result to the user if (fails == 0) { StartInstall(version.Version); } else { MessageBox.Show(Strings.Item("Update_Verify_Failed").Replace("%0", fails.ToString())); } } catch (Exception ex) { Utilities.LogSubError(ex); MessageBox.Show(ex.Message); } finally { EndAsync(); } return(true); }