static void Main(string[] args) { Console.WriteLine( @"WUDetector - Windows Update checker Brought to you by Team Gnome Developers Team. Copyright (C) Team Gnome community, 2014 - 2015. "); Debug.PrintMessage("Reading arguments passed to program."); SeekArguments(args); if (GetFiles) DataStore.RetrieveESDFiles(DisplayFlag); if (DeleteOldEsd) { ServiceManager svcMgr = new ServiceManager(); svcMgr.StopService(); //Attempt to delete the file. consoleWrite("Deleting cached DataStore"); try { File.Delete(Environment.SystemDirectory.Substring(0, Environment.SystemDirectory.Length - 8) + @"SoftwareDistribution\DataStore\DataStore.edb"); Console.WriteLine("Done."); } catch (IOException ex) { Console.WriteLine("An error occured while deleting cached DataStore."); Console.WriteLine("HResult = {0} ({1})", ex.HResult, ex.Message); } svcMgr.StartService(); } //Save old lab and priority to be restored upon finishing execution. OriginalFlightLevel = FlightRegistry.FlightLevel; OriginalBranch = FlightRegistry.Branch; if (string.IsNullOrEmpty(ArgumentFlightLevel)) ArgumentFlightLevel = FlightRegistry.FlightLevel; Debug.PrintMessage("Checking Threshold flags for detecting internal builds."); FlightRegistry.SetRequiredKeys(); Debug.PrintMessage("Original Branch, Flight Level were saved in memory for restoration upon finishing current task."); Debug.PrintMessage(string.Format("OriginalBranch = \"{0}\"; OriginalFlightLevel = \"{1}\"", OriginalBranch, OriginalFlightLevel)); Debug.PrintMessage(string.Format("Given Lab = \"{0}\" and Priority = \"{1}\"", (ArgumentBranch == null) ? "None" : ArgumentBranch, ArgumentFlightLevel)); var updates = new List<UpdateItem>(); if (TestAllLabs) { var labsToSearch = LabStore.LoadLabs(); Debug.PrintMessage("Labs to be checked were loaded into memory."); Debug.PrintMessage("Checking each lab."); Console.WriteLine("\r\n {0,-48} {1,-35} Total size", "Title", "Update ID"); Console.WriteLine(" {0}", new string('_', 109)); foreach (string lab in labsToSearch) { updates.Add(UpdateService.ProcessCheck(lab, ArgumentFlightLevel, UpdateId)); } //Clean up empty updates. updates.RemoveAll(sC => sC == null); Debug.PrintMessage("Showing final results."); Console.WriteLine("*** Latest builds list from {0} branches ***", updates.Count); Console.WriteLine("{0,-48} {1,-40} Total size", "Title", "Update ID"); Console.WriteLine(new string('_', 115)); foreach (UpdateItem update in updates) { if (update == null) continue; Console.WriteLine("{0,-48} {1,-40} {2:#,###,###,###} bytes", update.updateTitle, update.updateID, update.updateSize); } } else { if (CheckAllSKUs) { string originalSKU = FlightRegistry.SKU; UpdateItem uItem; Debug.PrintMessage(string.Format("originalSKU = \"{0}\"; Given SKU = \"Core\"", originalSKU)); Console.WriteLine("Currently checking all available SKUs through Core."); Console.Write(" "); FlightRegistry.SKU = "Core"; uItem = UpdateService.ProcessCheck( !string.IsNullOrEmpty(ArgumentBranch) ? ArgumentBranch : OriginalBranch, !string.IsNullOrEmpty(ArgumentFlightLevel) ? ArgumentFlightLevel : OriginalFlightLevel, UpdateId); updates.Add(uItem); FlightRegistry.SKU = originalSKU; Debug.PrintMessage("Restored original SKU."); } else updates.Add(UpdateService.ProcessCheck( !string.IsNullOrEmpty(ArgumentBranch) ? ArgumentBranch : OriginalBranch, !string.IsNullOrEmpty(ArgumentFlightLevel) ? ArgumentFlightLevel : OriginalFlightLevel, UpdateId)); } //Restore back current BranchName and RiskLevel. Debug.PrintMessage("Restored Original Branch, Flight Level."); FlightRegistry.FlightLevel = OriginalFlightLevel; FlightRegistry.Branch = OriginalBranch; if (!TerminateOnExit) { Console.WriteLine("\r\nThis program has finished doing its job.\r\nPress any key to exit."); Console.ReadKey(true); } Environment.Exit(0); }
public static void RetrieveESDFiles(int displayFlag) { //Part A: Stop wuauserv service ServiceManager svcMgr = new ServiceManager(); svcMgr.StopService(); Program.consoleWrite("Initializing WU DataStore"); //Part B: Create Jet instance to %systemroot%\SoftwareDistribution\DataStore\DataStore.edb DataTable dTable = new DataTable(); JET_INSTANCE instance; JET_SESID sesid; JET_DBID dbid; JET_TABLEID tableid; string edbFilename = Environment.GetEnvironmentVariable("SystemRoot") + @"\SoftwareDistribution\DataStore\DataStore.edb"; string tempDir = Environment.GetEnvironmentVariable("Temp") + @"\"; Debug.PrintMessage(string.Format("edbFilename = {0}", edbFilename)); //Sets Database Page Size gathered from the database. int dbPageSize; Api.JetGetDatabaseFileInfo(edbFilename, out dbPageSize, JET_DbInfo.PageSize); SystemParameters.DatabasePageSize = dbPageSize; Api.JetCreateInstance(out instance, "instance"); Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.CircularLog, 1, null); Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.LogFilePath, 0, tempDir); Api.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.TempPath, 0, tempDir); Api.JetInit(ref instance); Api.JetBeginSession(instance, out sesid, "", ""); //Attaches the database to SessionID and opens it. Api.JetAttachDatabase(sesid, edbFilename, AttachDatabaseGrbit.ReadOnly); Api.JetOpenDatabase(sesid, edbFilename, "", out dbid, OpenDatabaseGrbit.ReadOnly); Api.JetBeginTransaction(sesid); //Opens the table inside the database for read access only. Api.JetOpenTable(sesid, dbid, "tbFiles", null, 0, OpenTableGrbit.ReadOnly, out tableid); //For the time being, we need filename + size + two hashes + modification date //from the table. Thus 5 columns. JET_COLUMNDEF columnInfo = new JET_COLUMNDEF { }; JET_COLUMNID[] tbColumnID = new JET_COLUMNID[5]; Api.JetGetColumnInfo(sesid, dbid, "tbFiles", "Name", out columnInfo); tbColumnID[0] = columnInfo.columnid; Api.JetGetColumnInfo(sesid, dbid, "tbFiles", "Size", out columnInfo); tbColumnID[1] = columnInfo.columnid; Api.JetGetColumnInfo(sesid, dbid, "tbFiles", "Modified", out columnInfo); tbColumnID[2] = columnInfo.columnid; Api.JetGetColumnInfo(sesid, dbid, "tbFiles", "Digest", out columnInfo); tbColumnID[3] = columnInfo.columnid; Api.JetGetColumnInfo(sesid, dbid, "tbFiles", "StrongDigest", out columnInfo); tbColumnID[4] = columnInfo.columnid; Console.WriteLine("Done."); byte[] buffer = new byte[0x400]; byte[] sha1Buffer = new byte[0x14]; byte[] sha256Buffer = new byte[0x20]; int dataSize; List<string> arFiles = new List<string>(); List<long?> arSize = new List<long?>(); List<DateTime> arModified = new List<DateTime>(); List<string> arDigest = new List<string>(); List<string> arStrongDigest = new List<string>(); Program.consoleWrite("Reading data"); Api.JetMove(sesid, tableid, JET_Move.First, 0); while (Api.TryMoveNext(sesid, tableid)) { Api.JetRetrieveColumn(sesid, tableid, tbColumnID[0], buffer, 0x400, out dataSize, 0, null); if (Encoding.Unicode.GetString(buffer).Replace("\0", "").ToLower().EndsWith(".esd")) { arFiles.Add(Encoding.Unicode.GetString(buffer).Replace("\0", "")); arSize.Add(Api.RetrieveColumnAsInt64(sesid, tableid, tbColumnID[1])); arModified.Add(DateTime.FromFileTimeUtc(Api.RetrieveColumnAsInt64(sesid, tableid, tbColumnID[2]).Value)); Api.JetRetrieveColumn(sesid, tableid, tbColumnID[3], sha1Buffer, 0x14, out dataSize, 0, null); arDigest.Add(BitConverter.ToString(sha1Buffer).Replace("-", "")); Api.JetRetrieveColumn(sesid, tableid, tbColumnID[4], sha256Buffer, 0x20, out dataSize, 0, null); arStrongDigest.Add(BitConverter.ToString(sha256Buffer).Replace("-", "")); buffer = new byte[0x400]; sha1Buffer = new byte[0x14]; sha256Buffer = new byte[0x20]; } } Console.WriteLine("Done."); //Now, save all information to DataTable for easier management. Program.consoleWrite("Sorting results"); dTable.Columns.Add("BuildNumber", typeof(int)); dTable.Columns.Add("File", typeof(string)); dTable.Columns.Add("Size", typeof(long)); dTable.Columns.Add("ModifiedDate", typeof(DateTime)); dTable.Columns.Add("SHA1", typeof(string)); dTable.Columns.Add("SHA256", typeof(string)); DataRow dRow; for (int i = 0; i < arFiles.Count; i++) { //Critical for not throwing exception over 'install.esd' file in file entries. if (!Regex.Match(arFiles[i], @"^([0-9]){4}[0-9]?\.").Success) continue; dRow = dTable.NewRow(); dRow["BuildNumber"] = Convert.ToInt32(arFiles[i].Substring(0, arFiles[i].IndexOf('.', 0))); dRow["File"] = arFiles[i]; dRow["Size"] = arSize[i]; dRow["ModifiedDate"] = arModified[i]; dRow["SHA1"] = arDigest[i]; dRow["SHA256"] = arStrongDigest[i]; dTable.Rows.Add(dRow); } dTable.DefaultView.Sort = "BuildNumber, File ASC"; dTable = dTable.DefaultView.ToTable(); Console.WriteLine("Done."); //And finally it's the end of hard code! Closes the handles, end the sessions and terminate the instances. Api.JetCloseTable(sesid, tableid); Api.JetCloseDatabase(sesid, dbid, CloseDatabaseGrbit.None); Api.JetEndSession(sesid, EndSessionGrbit.None); Api.JetStopServiceInstance(instance); Api.JetTerm(instance); Debug.PrintMessage("Closed table and database handlers."); //Now we have all data in dTable. Show them. string[] ExplodedTag; int curBuildNumber = 0; ExplodedTag = dTable.Rows[0]["File"].ToString().Split('.'); if (dTable.Rows.Count > 0) curBuildNumber = Convert.ToInt32(ExplodedTag[0]); Console.WriteLine("\r\nRESULTS: [{0} file(s) were found.]", dTable.Rows.Count); Console.WriteLine("--------------------------------------------------------------------------"); foreach (DataRow dR in dTable.Rows) { switch (displayFlag) { case 0: case 1: Console.WriteLine(" File: {0}\r\n Size: {1:0,000,000,000} bytes\t\tModification date: {2}\r\n SHA-1: {3}\r\n SHA-256: {4}\r\n", dR["File"], dR["Size"], dR["ModifiedDate"], dR["SHA1"], dR["SHA256"]); break; case 2: ExplodedTag = dR["File"].ToString().Split('.'); if (Convert.ToInt32(ExplodedTag[0]) != curBuildNumber) Console.WriteLine(""); Console.WriteLine("{0}", dR["File"]); break; case 3: Console.WriteLine("{0}", dR["Size"]); break; case 4: Console.WriteLine("{0}", dR["ModifiedDate"]); break; case 5: Console.WriteLine("{0}", dR["SHA1"]); break; case 6: Console.WriteLine("{0}", dR["SHA256"]); break; } curBuildNumber = Convert.ToInt32(ExplodedTag[0]); } //Clean up edb*.* files created during reading. foreach (string fName in Directory.GetFiles(tempDir, "edbres*.jrs")) File.Delete(fName); if (File.Exists(tempDir + "edb.chk")) File.Delete(tempDir + "edb.chk"); if (File.Exists(tempDir + "edbtmp.log")) File.Delete(tempDir + "edbtmp.log"); if (File.Exists(tempDir + "edb.log")) File.Delete(tempDir + "edb.log"); svcMgr.StartService(); Environment.Exit(0); }