Ejemplo n.º 1
0
        //=====================================================
        // Calculate map hash(reversed) and dump map signature(if any)
        // - return the starting pos of signature block(-1 if none)
        //=====================================================
        public static long MapGetSignatureInfo(string mappath, ref byte[] maphash, ref byte[] mapsignature)
        {
            long   signature_pos = -1;
            string mapname       = Path.GetFileName(mappath);

            byte[] mapnamebytes = Encoding.ASCII.GetBytes(mapname.ToUpper());   //upper filename

            System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
            Stream input = File.OpenRead(mappath);

            byte[] buffer_old = new byte[200];
            byte[] buffer = new byte[200];  //read 200 bytes each time
            int    bytesRead, bytesRead_old;
            bool   findblockheader = false;

            //Mpq is a vaild map
            bytesRead = input.Read(buffer, 0, buffer.Length);   //read mpq header
            if (buffer[0] == Convert.ToByte('H') && buffer[1] == Convert.ToByte('M') && buffer[2] == Convert.ToByte('3') && buffer[3] == Convert.ToByte('W'))
            {
                //sha1.TransformBlock(buffer, 0, buffer.Length, null, 0);
                Array.Copy(buffer, buffer_old, buffer.Length);
                bytesRead_old = bytesRead;
            }
            else
            {
                throw new Exception("Not a vaild map.");
            }

            while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                //Construct a new temporiary bytes of 2 trunks, in case the header sign is splited.
                byte[] temp = new byte[buffer_old.Length + buffer.Length];
                Array.Copy(buffer_old, 0, temp, 0, buffer_old.Length);
                Array.Copy(buffer, 0, temp, buffer_old.Length, buffer.Length);

                //search for the block header 'NGIS'
                int index;
                if ((index = IndexOfBytes(temp, SIGNATURE_HEADER)) != -1)
                {
                    //if found!
                    Console.WriteLine("Found Signature.");
                    sha1.TransformBlock(temp, 0, index, null, 0);
                    findblockheader = true;
                    //dump signature
                    input.Position = input.Position - temp.Length + index + SIGNATURE_HEADER.Length; //set the stream pos after 'NGIS'
                    signature_pos  = input.Position - SIGNATURE_HEADER.Length;                       //get the signature block starting pos
                    mapsignature   = new byte[input.Length - input.Position];
                    input.Read(mapsignature, 0, mapsignature.Length);
                    Array.Reverse(mapsignature);
                    break;
                }
                else
                {
                    sha1.TransformBlock(buffer_old, 0, bytesRead_old, null, 0);
                    Array.Copy(buffer, buffer_old, buffer.Length);
                    bytesRead_old = bytesRead;
                }
            }

            if (!findblockheader)
            {
                sha1.TransformBlock(buffer_old, 0, bytesRead_old, null, 0);
            }
            sha1.TransformBlock(mapnamebytes, 0, mapnamebytes.Length, null, 0); //Add upper file name to the end
            sha1.TransformFinalBlock(buffer, 0, 0);

            //Calculate Hash:
            Console.WriteLine("SHA1:");
            maphash = new byte[sha1.Hash.Length];
            sha1.Hash.CopyTo(maphash, 0);
            input.Close();
            input.Dispose();
            Array.Reverse(maphash);
            Console.WriteLine(BitConverter.ToString(maphash));
            return(signature_pos);
        }