Beispiel #1
0
        public MacBinary(Stream input)
        {
            byte[] buf = new byte[128];
            if (input.Read(buf, 0, 128) != 128)
                throw new MacBinaryException("Could not read header.");

            version = Version.MacBinaryIII;
            // Version
            if (buf[0] != 0)
                throw new MacBinaryException("Incompatible version.");
            // Signature 'mBIN'
            if (buf[102] != 'm' || buf[103] != 'B' || buf[104] != 'I' || buf[105] != 'N')
                version = Version.MacBinaryII;
            // Zero padding
            if (buf[74] != 0 || buf[82] != 0 || buf[126] != 0 || buf[127] != 0)
                throw new MacBinaryException("Zero padding is not zero.");
            // MacBinary version of this file.
            if (version == Version.MacBinaryII && buf[122] != 129)
                throw new MacBinaryException("Version field corrupt for a MacBinary II file.");
            if (version == Version.MacBinaryIII && buf[122] != 130)
            {
                if (buf[122] == 129)
                    version = Version.MacBinaryII;
                else
                    throw new MacBinaryException("Version field corrupt for a MacBinary III file.");
            }
            // CRC at the end of the header
            int crc = MacUtil.read16(buf, 124);
            // FIXME: check CRC
            if (crc == 0)
                version = Version.MacBinaryI;

            // File name
            int namelen = buf[1];
            if (namelen < 1 || namelen > 63)
                throw new MacBinaryException("Invalid file length.");
            filename = MacUtil.readString(buf, 2, namelen);
            // File type
            filetype = MacUtil.readString(buf, 65, 4);
            // File creator
            filecreator = MacUtil.readString(buf, 69, 4);
            // Finder flags
            finderflags = buf[73];
            // Window position
            windowposy = MacUtil.read16(buf, 75);
            windowposx = MacUtil.read16(buf, 77);
            // Window or folder ID
            windowid = MacUtil.read16(buf, 79);
            // Protected flag
            protectedflag = (buf[81] & 1) == 1;
            // Data en resource fork lengths
            int datlen = MacUtil.read32(buf, 83);
            int reslen = MacUtil.read32(buf, 87);
            // Creation and modification dates
            ctime = MacUtil.read32(buf, 91);
            mtime = MacUtil.read32(buf, 95);

            int commentlen = 0;
            int secheaderlen = 0;
            if (version != Version.MacBinaryI)
            {
                // Get Info comment length
                commentlen = MacUtil.read16(buf, 99);
                // Finder flags
                finderflags2 = buf[101];
                if (version != Version.MacBinaryII)
                {
                    // Finder fxInfo fields
                    fxScript = buf[106];
                    fdXFlags = buf[107];
                }
                // Length of total files when packed files are unpacked. (never really used)
                //int unpackedlen = read32(buf, 117);
                // Length of secondary header.
                secheaderlen = MacUtil.read16(buf, 120);
                // Minimum version to support in order to read this file (ignored)
                //int minversion = buf[123];
            }

            // Skip the secondary header
            if (secheaderlen > 0)
            {
                // Round up to 128 bytes
                secheaderlen = (int)Math.Ceiling((double)secheaderlen / 128) * 128;
                input.Seek(secheaderlen, SeekOrigin.Current);
            }

            // Read data fork
            dat = new byte[datlen];
            if (input.Read(dat, 0, datlen) != datlen)
                throw new MacBinaryException("Could not read data fork.");
            // Round up to 128 bytes and skip padding
            long temp = (int)Math.Ceiling((double)datlen / 128) * 128 - datlen;
            input.Seek(temp, SeekOrigin.Current);

            // Read the resource fork
            temp = input.Position + (int)Math.Ceiling((double)reslen / 128) * 128;
            res = new MacResourceFork(input);
            input.Seek(temp, SeekOrigin.Begin);

            if (commentlen > 0)
            {
                buf = new byte[commentlen];
                if (input.Read(buf, 0, commentlen) != commentlen)
                    throw new MacBinaryException("Could not read Get Info comment.");
                comment = MacUtil.readString(buf, 0, commentlen);
            }
        }
Beispiel #2
0
        public MacBinary(Stream input)
        {
            byte[] buf = new byte[128];
            if (input.Read(buf, 0, 128) != 128)
            {
                throw new MacBinaryException("Could not read header.");
            }

            version = Version.MacBinaryIII;
            // Version
            if (buf[0] != 0)
            {
                throw new MacBinaryException("Incompatible version.");
            }
            // Signature 'mBIN'
            if (buf[102] != 'm' || buf[103] != 'B' || buf[104] != 'I' || buf[105] != 'N')
            {
                version = Version.MacBinaryII;
            }
            // Zero padding
            if (buf[74] != 0 || buf[82] != 0 || buf[126] != 0 || buf[127] != 0)
            {
                throw new MacBinaryException("Zero padding is not zero.");
            }
            // MacBinary version of this file.
            if (version == Version.MacBinaryII && buf[122] != 129)
            {
                throw new MacBinaryException("Version field corrupt for a MacBinary II file.");
            }
            if (version == Version.MacBinaryIII && buf[122] != 130)
            {
                if (buf[122] == 129)
                {
                    version = Version.MacBinaryII;
                }
                else
                {
                    throw new MacBinaryException("Version field corrupt for a MacBinary III file.");
                }
            }
            // CRC at the end of the header
            int crc = MacUtil.read16(buf, 124);

            // FIXME: check CRC
            if (crc == 0)
            {
                version = Version.MacBinaryI;
            }

            // File name
            int namelen = buf[1];

            if (namelen < 1 || namelen > 63)
            {
                throw new MacBinaryException("Invalid file length.");
            }
            filename = MacUtil.readString(buf, 2, namelen);
            // File type
            filetype = MacUtil.readString(buf, 65, 4);
            // File creator
            filecreator = MacUtil.readString(buf, 69, 4);
            // Finder flags
            finderflags = buf[73];
            // Window position
            windowposy = MacUtil.read16(buf, 75);
            windowposx = MacUtil.read16(buf, 77);
            // Window or folder ID
            windowid = MacUtil.read16(buf, 79);
            // Protected flag
            protectedflag = (buf[81] & 1) == 1;
            // Data en resource fork lengths
            int datlen = MacUtil.read32(buf, 83);
            int reslen = MacUtil.read32(buf, 87);

            // Creation and modification dates
            ctime = MacUtil.read32(buf, 91);
            mtime = MacUtil.read32(buf, 95);

            int commentlen   = 0;
            int secheaderlen = 0;

            if (version != Version.MacBinaryI)
            {
                // Get Info comment length
                commentlen = MacUtil.read16(buf, 99);
                // Finder flags
                finderflags2 = buf[101];
                if (version != Version.MacBinaryII)
                {
                    // Finder fxInfo fields
                    fxScript = buf[106];
                    fdXFlags = buf[107];
                }
                // Length of total files when packed files are unpacked. (never really used)
                //int unpackedlen = read32(buf, 117);
                // Length of secondary header.
                secheaderlen = MacUtil.read16(buf, 120);
                // Minimum version to support in order to read this file (ignored)
                //int minversion = buf[123];
            }

            // Skip the secondary header
            if (secheaderlen > 0)
            {
                // Round up to 128 bytes
                secheaderlen = (int)Math.Ceiling((double)secheaderlen / 128) * 128;
                input.Seek(secheaderlen, SeekOrigin.Current);
            }

            // Read data fork
            dat = new byte[datlen];
            if (input.Read(dat, 0, datlen) != datlen)
            {
                throw new MacBinaryException("Could not read data fork.");
            }
            // Round up to 128 bytes and skip padding
            long temp = (int)Math.Ceiling((double)datlen / 128) * 128 - datlen;

            input.Seek(temp, SeekOrigin.Current);

            // Read the resource fork
            temp = input.Position + (int)Math.Ceiling((double)reslen / 128) * 128;
            res  = new MacResourceFork(input);
            input.Seek(temp, SeekOrigin.Begin);

            if (commentlen > 0)
            {
                buf = new byte[commentlen];
                if (input.Read(buf, 0, commentlen) != commentlen)
                {
                    throw new MacBinaryException("Could not read Get Info comment.");
                }
                comment = MacUtil.readString(buf, 0, commentlen);
            }
        }