コード例 #1
0
        /// <summary>
        /// Given a HashFlags value, applies DB hints provided in DB config
        /// </summary>
        /// <remarks>Some Examples: CRC32 will be converted to RomHash | CRC32 for No-Intro,
        /// or RomHash_ByteSwapped | CRC32 for No-Intro N64</remarks>
        private HashFlags GetHashFlags(HashFlags hashFlags)
        {
            if ((hashFlags & (HashFlags.FileHash | HashFlags.RomHash)) == 0)
            {
                // File or ROM not specified? Use DB default.
                if ((info.Hints & DBHints.ByteSwapped) != 0)
                {
                    return(hashFlags | HashFlags.RomHash_ByteSwap);
                }
                else if ((info.Hints & DBHints.DefaultHash_ROM) != 0)
                {
                    return(hashFlags | HashFlags.RomHash);
                }
                else if ((info.Hints & DBHints.DefaultHash_File) != 0)
                {
                    return(hashFlags | HashFlags.FileHash);
                }

                // No specified for DB? Guess.
                return(hashFlags | HashFlags.FileHash);
            }
            else
            {
                return(hashFlags);
            }
        }
コード例 #2
0
        /// <summary>
        /// Adds hashes to specified string builder for summary box. SB.
        /// </summary>
        /// <param name="hashes">A list of hashes to add. This list will be destroyed.</param>
        /// <param name="prefix">A string to prefix to hash name, e.g. "Patched" -> "Patched File MD5:..."</param>
        /// <param name="sb"></param>
        private void AddHashesToSB(StringBuilder sb, List <RomHash> hashes, string prefix)
        {
            // Why do I make things more complicated than they need to be?

            if (string.IsNullOrEmpty(prefix))
            {
                prefix = string.Empty;
            }
            else
            {
                prefix += " ";
            }

            while (hashes.Count > 0)
            {
                // Grab last hash
                var hash = hashes[0];
                hashes.RemoveAt(0);

                // For ROM/FILE hashes, if two are the same, we want to report them as one
                // Example: a headerless SNES ROM will have identical file and ROM hashes because the file is a plain ROM image,
                // so we can report it as a "File/ROM SHA-1" rather than as two seprate hashes with identical values

                // Get the desired type of hash we want to check, e.g. for ROM SHA-1, we want to see if File SHA-1 is the same.
                HashFlags altHashType = 0;
                if (hash.Type.GetContents() == HashFlags.FileHash)
                {
                    altHashType = HashFlags.RomHash | hash.Type.GetAlgorithm();
                }
                else if (hash.Type.GetContents() == HashFlags.RomHash)
                {
                    altHashType = HashFlags.FileHash | hash.Type.GetAlgorithm();
                }

                RomHash altHash = null;
                if (altHashType != 0)
                {
                    for (int i = 0; i < hashes.Count; i++)
                    {
                        // Find the right hash, and check its value
                        if (hashes[i].Type == altHashType && CompareByteArrays(hash.Value, hashes[i].Value))
                        {
                            // Match? Cool beans
                            altHash = hashes[i];
                            hashes.RemoveAt(i);
                            break; // for
                        }
                    }
                }

                var hashType = hash.Type;
                if (altHash != null)
                {
                    hashType |= altHash.Type;
                }
                string hashname = RomHash.GetHashName(hashType);
                sb.AppendLine(prefix + hashname + ": " + Hex.FormatHex(hash.Value));
            }
        }
コード例 #3
0
ファイル: RomHash.cs プロジェクト: snarfblam/ROM-Hasher
        /// <summary>
        /// Gets a friendly name for a ROM hash type
        /// </summary>
        /// <param name="flags">Hash type</param>
        /// <returns>A string representation of the hash type</returns>
        public static string GetHashName(HashFlags flags)
        {
            string result;

            if (NamedHashFlags.TryGetValue(flags, out result))
            {
                return(result);
            }

            return("(" + flags.ToString() + ")");
        }
コード例 #4
0
        /// <summary>
        /// Returns a ROM hash specified, or null if it is not found. If multiple applicable hashes are found, the first one is returned.
        /// </summary>
        /// <param name="hashType">The hash to retreive.</param>
        /// <returns>A RomHash object.</returns>
        public RomHash GetHash(HashFlags hashType)
        {
            for (int i = 0; i < Hashes.Count; i++)
            {
                if (Hashes[i].Type == hashType)
                {
                    return(Hashes[i]);
                }
            }

            return(null);
        }
コード例 #5
0
        /// <summary>
        /// Returns a set of hashes that match the specified filter.
        /// </summary>
        /// <param name="filter">A filter that specifies which flags are required for a hash.</param>
        /// <returns></returns>
        public IList <RomHash> GetHashes(HashFlags filter)
        {
            List <RomHash> result = new List <RomHash>();

            if ((int)filter != 0)
            {
                for (int i = 0; i < Hashes.Count; i++)
                {
                    if ((Hashes[i].Type & filter) != 0)
                    {
                        result.Add(Hashes[i]);
                    }
                }
            }
            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Attempts to find the specified hash and append it to the string builder for RHDN-specific output.
        /// </summary>
        /// <param name="hashtype">The hash type (i.e. CRC32/MD5/SHA1). File/ROM/PRG/CHR should NOT be specified.</param>
        /// <returns>True if ANYTHING was appended to the string builder.</returns>
        /// <param name="rom"></param>
        /// <param name="sb"></param>
        private static bool AddHashToSB(StringBuilder sb, RomData rom, HashFlags hashtype)
        {
            string hashname = RomHash.GetHashName(HashFlags.RomHash | hashtype);
            var    hash     = rom.GetHash(HashFlags.RomHash | hashtype);

            if (hash == null)
            {
                hashname = hashname = RomHash.GetHashName(HashFlags.FileHash | hashtype);;
                hash     = rom.GetHash(HashFlags.FileHash | hashtype);
            }

            if (hash == null)
            {
                return(false);
            }

            sb.AppendLine(hashname + ": " + Hex.FormatHex(hash.Value));
            return(true);
        }
コード例 #7
0
ファイル: RomHash.cs プロジェクト: snarfblam/ROM-Hasher
        /// <summary>
        /// Identifies whether the program configuration requres the specified hash for a given platform
        /// </summary>
        /// <param name="p">The platform in question</param>
        /// <param name="hash">The hash algorithm and type</param>
        /// <returns>True if the hash is required, otherwise false.</returns>
        public static bool IsHashRequired(Platform p, HashFlags hash)
        {
            if (Program.Config.SkipExtraHashes)
            {
                // Skip PRG, CHR, and
                if ((hash & HashFlags.SHA256) != 0)
                {
                    return(false);
                }
                if ((hash & (HashFlags.ChrHash | HashFlags.PrgHash)) != 0)
                {
                    return(false);
                }

                return(true);
            }
            else
            {
                return(true);
            }
        }
コード例 #8
0
        /// <summary>
        /// Converts a bit-field into an array of single-bit values
        /// </summary>
        /// <param name="allAlgos"></param>
        /// <returns></returns>
        IList <HashFlags> getAlgos(HashFlags allAlgos)
        {
            List <HashFlags> result = new List <HashFlags>();

            if ((allAlgos & HashFlags.CRC32) != 0)
            {
                result.Add(HashFlags.CRC32);
            }
            if ((allAlgos & HashFlags.SHA1) != 0)
            {
                result.Add(HashFlags.SHA1);
            }
            if ((allAlgos & HashFlags.SHA256) != 0)
            {
                result.Add(HashFlags.SHA256);
            }
            if ((allAlgos & HashFlags.MD5) != 0)
            {
                result.Add(HashFlags.MD5);
            }

            return(result);
        }
コード例 #9
0
        void IHashWorkManager.AddHashes(byte[] buffer, int start, int len, HASH.Platform.AsyncCancelCheck cancelCheck, HashFlags algos, HashFlags type, params HashFlags[] additionalTypes)
        {
            var allalgos = getAlgos(algos);

            if (allalgos.Count == 0)
            {
                throw new ArgumentException("Hash algorithm not specified.");
            }

            foreach (var algo in allalgos)
            {
                if (RomHash.IsHashRequired(Platform, algo | type))
                {
                    byte[] hash = null;
                    if (cancelCheck == null || cancelCheck() == false)
                    {
                        switch (algo)
                        {
                        case HashFlags.MD5:
                            hash = CalculateMD5(buffer, start, len);
                            break;

                        case HashFlags.SHA1:
                            hash = CalculateSha1(buffer, start, len, cancelCheck);
                            break;

                        case HashFlags.SHA256:
                            hash = CalculateSha256(buffer, start, len, cancelCheck);
                            break;

                        case HashFlags.CRC32:
                            hash = CalculateCRC32(buffer, start, len);
                            break;
                        }
                    }

                    if (hash != null)
                    {
                        lock (HashesLock) {
                            _Hashes.Add(new RomHash(hash, algo | type));

                            if (additionalTypes != null)
                            {
                                for (int i = 0; i < additionalTypes.Length; i++)
                                {
                                    _Hashes.Add(new RomHash(hash, algo | additionalTypes[i]));
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #10
0
 void IHashWorkManager.AddHashes(byte[] buffer, int start, int len, HashFlags algso, HashFlags type)
 {
     ((IHashWorkManager)this).AddHashes(buffer, start, len, null, algso, type);
 }
コード例 #11
0
ファイル: RomHash.cs プロジェクト: snarfblam/ROM-Hasher
 /// <summary>
 /// Gets the content this hash is for, i.e. ROM, entire file, etc
 /// </summary>
 public static HashFlags GetContents(this HashFlags h)
 {
     return(h & HashContentFilter);
 }
コード例 #12
0
ファイル: RomHash.cs プロジェクト: snarfblam/ROM-Hasher
 /// <summary>
 /// Creates a RomHash object with the specified data
 /// </summary>
 /// <param name="value">Hash value</param>
 /// <param name="type">Hash type</param>
 public RomHash(byte[] value, HashFlags type)
 {
     this.Value = value;
     this.Type  = type;
 }
コード例 #13
0
ファイル: RomHash.cs プロジェクト: snarfblam/ROM-Hasher
 /// <summary>
 /// Gets the algorithm for this hash, i.e. MD5, SHA1, etc
 /// </summary>
 public static HashFlags GetAlgorithm(this HashFlags h)
 {
     return(h & HashAlgorithmFilter);
 }
コード例 #14
0
ファイル: Platform_N64.cs プロジェクト: snarfblam/ROM-Hasher
            public override void CalculateHashes(byte[] rom, IHashWorkManager worker, float startProgress, float endProgress)
            {
                // N64 hashes are calculated using the thread pool because the ROMs tend to be large

                bool byteswapped = N64.IsByteswapped(rom) == N64ByteSwap.Swapped;

                byte[] swappedRom = new byte[rom.Length];
                // Watch out for odd # of bytes!
                int len = rom.Length & (~1);

                for (int i = 0; i < len; i += 2)
                {
                    swappedRom[i]     = rom[i + 1];
                    swappedRom[i + 1] = rom[i];
                }

                HashFlags originalType = byteswapped ? HashFlags.RomHash_ByteSwap : HashFlags.RomHash;
                HashFlags swappedType  = byteswapped ? HashFlags.RomHash : HashFlags.RomHash_ByteSwap;

                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.SHA256, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.SHA1, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.CRC32, originalType, HashFlags.FileHash);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(rom, 0, rom.Length, () => worker.AbortPending, HashFlags.MD5, originalType, HashFlags.FileHash);
                    }
                });

                // We can not byte-swap the ROM while it is being hashed
                worker.WaitAll();


                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.SHA256, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.SHA1, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.CRC32, swappedType);
                    }
                });
                worker.QueueTask((SimpleDelegate) delegate {
                    if (!worker.AbortPending)
                    {
                        worker.AddHashes(swappedRom, 0, swappedRom.Length, () => worker.AbortPending, HashFlags.MD5, swappedType);
                    }
                });

                // We can not return until all hashes are calculated
                worker.WaitAll();
            }