Beispiel #1
0
		/// <summary>
		/// Test to determine whether the supplied firmware file matches something in the firmware database
		/// </summary>
		public bool CanFileBeImported(string f)
		{
			try
			{
				var fi = new FileInfo(f);
				if (!fi.Exists)
					return false;

				// weed out filesizes first to reduce the unnecessary overhead of a hashing operation
				if (FirmwareDatabase.FirmwareFiles.FirstOrDefault(a => a.Size == fi.Length) == null)
					return false;

				// check the hash
				using var reader = new RealFirmwareReader();
				reader.Read(fi);
				if (FirmwareDatabase.FirmwareFiles.FirstOrDefault(a => a.Hash == reader.Dict.FirstOrDefault().Value.Hash) != null)
					return true;
			}
			catch { }

			return false;
		}
		public void DoScanAndResolve()
		{
			//build a list of file sizes. Only those will be checked during scanning
			HashSet<long> sizes = new HashSet<long>();
			foreach (var ff in FirmwareDatabase.FirmwareFiles)
				sizes.Add(ff.size);

			using(var reader = new RealFirmwareReader())
			{
				// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
				var todo = new Queue<DirectoryInfo>();
				todo.Enqueue(new DirectoryInfo(PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null)));
	
				while (todo.Count != 0)
				{
					var di = todo.Dequeue();

					if (!di.Exists)
						continue;

					// we're going to allow recursing into subdirectories, now. its been verified to work OK
					foreach (var disub in di.GetDirectories())
					{
						todo.Enqueue(disub);
					}
				
					foreach (var fi in di.GetFiles())
					{
						if(sizes.Contains(fi.Length))
							reader.Read(fi);
					}
				}

				// now, for each firmware record, try to resolve it
				foreach (var fr in FirmwareDatabase.FirmwareRecords)
				{
					// clear previous resolution results
					_resolutionDictionary.Remove(fr);

					// get all options for this firmware (in order)
					var fr1 = fr;
					var options =
						from fo in FirmwareDatabase.FirmwareOptions
						where fo.systemId == fr1.systemId && fo.firmwareId == fr1.firmwareId && fo.IsAcceptableOrIdeal
						select fo;

					// try each option
					foreach (var fo in options)
					{
						var hash = fo.hash;

						// did we find this firmware?
						if (reader.dict.ContainsKey(hash))
						{
							// rad! then we can use it
							var ri = new ResolutionInfo
								{
									FilePath = reader.dict[hash].FileInfo.FullName,
									KnownFirmwareFile = FirmwareDatabase.FirmwareFilesByHash[hash],
									Hash = hash,
									Size = fo.size
								};
							_resolutionDictionary[fr] = ri;
							goto DONE_FIRMWARE;
						}
					}

				DONE_FIRMWARE: ;

				}

				// apply user overrides
				foreach (var fr in FirmwareDatabase.FirmwareRecords)
				{
					string userSpec;

					// do we have a user specification for this firmware record?
					if (Global.Config.FirmwareUserSpecifications.TryGetValue(fr.ConfigKey, out userSpec))
					{
						// flag it as user specified
						ResolutionInfo ri;
						if (!_resolutionDictionary.TryGetValue(fr, out ri))
						{
							ri = new ResolutionInfo();
							_resolutionDictionary[fr] = ri;
						}
						ri.UserSpecified = true;
						ri.KnownFirmwareFile = null;
						ri.FilePath = userSpec;
						ri.Hash = null;

						// check whether it exists
						var fi = new FileInfo(userSpec);
						if (!fi.Exists)
						{
							ri.Missing = true;
							continue;
						}

						// compute its hash 
						var rff = reader.Read(fi);
						ri.Size = fi.Length;
						ri.Hash = rff.Hash;

						// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesnt really use this information right now)
						FirmwareDatabase.FirmwareFile ff;
						if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out ff))
						{
							ri.KnownFirmwareFile = ff;

							// if the known firmware file is for a different firmware, flag it so we can show a warning
							var option =
								(from fo in FirmwareDatabase.FirmwareOptions
								 where fo.hash == rff.Hash && fo.ConfigKey != fr.ConfigKey
								 select fr).FirstOrDefault();

							if (option != null)
							{
								ri.KnownMismatching = true;
							}
						}
					}

				} //foreach(firmware record)
			} //using(new RealFirmwareReader())
		} //DoScanAndResolve()
Beispiel #3
0
		public void DoScanAndResolve(PathEntryCollection pathEntries, IDictionary<string, string> userSpecifications)
		{
			// build a list of file sizes. Only those will be checked during scanning
			var sizes = new HashSet<long>();
			foreach (var ff in FirmwareDatabase.FirmwareFiles)
			{
				sizes.Add(ff.Size);
			}

			using var reader = new RealFirmwareReader();

			// build a list of files under the global firmwares path, and build a hash for each of them while we're at it
			var todo = new Queue<DirectoryInfo>();
			todo.Enqueue(new DirectoryInfo(pathEntries.AbsolutePathFor(pathEntries.FirmwaresPathFragment, null)));
	
			while (todo.Count != 0)
			{
				var di = todo.Dequeue();

				if (!di.Exists)
				{
					continue;
				}

				// we're going to allow recursing into subdirectories, now. its been verified to work OK
				foreach (var subDir in di.GetDirectories())
				{
					todo.Enqueue(subDir);
				}
				
				foreach (var fi in di.GetFiles())
				{
					if (sizes.Contains(fi.Length))
					{
						reader.Read(fi);
					}
				}
			}

			// now, for each firmware record, try to resolve it
			foreach (var fr in FirmwareDatabase.FirmwareRecords)
			{
				// clear previous resolution results
				_resolutionDictionary.Remove(fr);

				// get all options for this firmware (in order)
				var fr1 = fr;
				var options = FirmwareDatabase.FirmwareOptions
						.Where(fo => fo.SystemId == fr1.SystemId
							&& fo.FirmwareId == fr1.FirmwareId
							&& fo.IsAcceptableOrIdeal);

				// try each option
				foreach (var fo in options)
				{
					var hash = fo.Hash;

					// did we find this firmware?
					if (reader.Dict.ContainsKey(hash))
					{
						// rad! then we can use it
						var ri = new ResolutionInfo
						{
							FilePath = reader.Dict[hash].FileInfo.FullName,
							KnownFirmwareFile = FirmwareDatabase.FirmwareFilesByHash[hash],
							Hash = hash,
							Size = fo.Size
						};
						_resolutionDictionary[fr] = ri;
						goto DONE_FIRMWARE;
					}
				}

				DONE_FIRMWARE: ;
			}

			// apply user overrides
			foreach (var fr in FirmwareDatabase.FirmwareRecords)
			{
				// do we have a user specification for this firmware record?
				if (userSpecifications.TryGetValue(fr.ConfigKey, out var userSpec))
				{
					// flag it as user specified
					if (!_resolutionDictionary.TryGetValue(fr, out ResolutionInfo ri))
					{
						ri = new ResolutionInfo();
						_resolutionDictionary[fr] = ri;
					}

					ri.UserSpecified = true;
					ri.KnownFirmwareFile = null;
					ri.FilePath = userSpec;
					ri.Hash = null;

					// check whether it exists
					var fi = new FileInfo(userSpec);
					if (!fi.Exists)
					{
						ri.Missing = true;
						continue;
					}

					// compute its hash
					RealFirmwareFile rff;
					// NDS's firmware file contains user settings; these are over-written by sync settings, so we shouldn't allow them to impact the hash
					if (fr.SystemId == "NDS" && fr.FirmwareId == "firmware")
						rff = reader.Read(new FileInfo(Emulation.Cores.Consoles.Nintendo.NDS.MelonDS.CreateModifiedFirmware(userSpec)));
					else
						rff = reader.Read(fi);
					ri.Size = fi.Length;
					ri.Hash = rff.Hash;

					// check whether it was a known file anyway, and go ahead and bind to the known file, as a perk (the firmwares config doesn't really use this information right now)
					if (FirmwareDatabase.FirmwareFilesByHash.TryGetValue(rff.Hash, out var ff))
					{
						ri.KnownFirmwareFile = ff;

						// if the known firmware file is for a different firmware, flag it so we can show a warning
						var option = FirmwareDatabase.FirmwareOptions
							.FirstOrDefault(fo => fo.Hash == rff.Hash && fo.ConfigKey != fr.ConfigKey);

						if (option != null)
						{
							ri.KnownMismatching = true;
						}
					}
				}
			} // foreach(firmware record)
		} // DoScanAndResolve()