Ejemplo n.º 1
0
        public static bool UnmarshalLzxcResetTable(ref byte[] pData, ref uint pDataPos,
                                                   ref uint pDataLen, ref chmLzxcResetTable dest)
        {
            /* we only know how to deal with a 0x28 byte structures */
            if (pDataLen != CHM_LZXC_RESETTABLE_V1_LEN)
            {
                return(false);
            }

            /* unmarshal fields */
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.version);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.block_count);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.table_offset);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.uncompressed_len);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.compressed_len);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.block_len);

            /* check structure */
            if (dest.version != 2)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        public static bool UnmarshalPmglHeader(ref byte[] pData, ref uint pDataPos,
                                               ref uint pDataLen, ref chmPmglHeader dest)
        {
            /* we only know how to deal with a 0x14 byte structures */
            if (pDataLen != CHM_PMGL_LEN)
            {
                return(false);
            }

            InitialisePmglHeader(ref dest);

            /* unmarshal fields */
            Unmarshal.ToCharArray(ref pData, ref pDataPos, ref pDataLen, ref dest.signature, 4);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.free_space);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_0008);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.block_prev);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.block_next);

            /* check structure */
            if (new String(dest.signature, 0, 4).CompareTo(CHM_PMGL_MARKER) != 0)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 3
0
        public static bool UnmarshalLzxcControlData(ref byte[] pData, ref uint pDataPos,
                                                    ref uint pDataLen, ref chmLzxcControlData dest)
        {
            /* we want at least 0x18 bytes */
            if (pDataLen < CHM_LZXC_MIN_LEN)
            {
                return(false);
            }

            InitialiseLzxcControlData(ref dest);

            /* unmarshal fields */
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.size);
            Unmarshal.ToCharArray(ref pData, ref pDataPos, ref pDataLen, ref dest.signature, 4);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.version);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.resetInterval);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.windowSize);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.windowsPerReset);

            if (pDataLen >= CHM_LZXC_V2_LEN)
            {
                Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_18);
            }
            else
            {
                dest.unknown_18 = 0;
            }

            if (dest.version == 2)
            {
                dest.resetInterval *= 0x8000;
                dest.windowSize    *= 0x8000;
            }
            if (dest.windowSize == 0 || dest.resetInterval == 0)
            {
                return(false);
            }

            /* for now, only support resetInterval a multiple of windowSize/2 */
            if (dest.windowSize == 1)
            {
                return(false);
            }
            if ((dest.resetInterval % (dest.windowSize / 2)) != 0)
            {
                return(false);
            }

            /* check structure */
            if (new String(dest.signature).CompareTo("LZXC") != 0)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 4
0
        public static bool UnmarshalItpfHeader(ref byte[] pData, ref uint pDataPos,
                                               ref uint pDataLen, ref chmItspHeader dest)
        {
            /* we only know how to deal with a 0x54 byte structures */
            if (pDataLen != CHM_ITSP_V1_LEN)
            {
                return(false);
            }

            InitialiseItspHeader(ref dest);

            /* unmarshal fields */
            Unmarshal.ToCharArray(ref pData, ref pDataPos, ref pDataLen, ref dest.signature, 4);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.version);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.header_len);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_000c);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.block_len);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.blockidx_intvl);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.index_depth);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.index_root);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.index_head);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_0024);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.num_blocks);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_002c);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.lang_id);
            Unmarshal.ToUuid(ref pData, ref pDataPos, ref pDataLen, ref dest.system_uuid);
            Unmarshal.ToByteArray(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_0044, 16);

            /* error check the data */
            if (new String(dest.signature).CompareTo("ITSP\0") != 0)
            {
                return(false);
            }
            if (dest.version != 1)
            {
                return(false);
            }
            if (dest.header_len != CHM_ITSP_V1_LEN)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 5
0
        public static SystemFile Read(ChmFile f)
        {
            List <SystemFileEntry> sfelst = new List <SystemFileEntry>();
            ChmUnitInfo            ui     = new ChmUnitInfo();

            byte[] buf;
            uint   pos = 0, remaining = 0;

            if (!f.ResolveObject("/#SYSTEM", ref ui))
            {
                throw new InvalidOperationException("Could not find SYSTEM file in CHM!");
            }

            buf       = new byte[ui.length];
            remaining = (uint)buf.Length;

            if (f.RetrieveObject(ui, ref buf, 0, (long)ui.length) == 0)
            {
                throw new InvalidOperationException("Could not read SYSTEM file in CHM!");
            }

            Int32 version = 0;

            Unmarshal.ToInt32(ref buf, ref pos, ref remaining, ref version);

            for ( ; pos < buf.Length;)
            {
                SystemFileEntry sfe = new SystemFileEntry();

                Unmarshal.ToUInt16(ref buf, ref pos, ref remaining, ref sfe.code);
                Unmarshal.ToUInt16(ref buf, ref pos, ref remaining, ref sfe.length);

                sfe.data = new byte[sfe.length];
                Array.Copy(buf, pos, sfe.data, 0, sfe.length);

                pos       += sfe.length;
                remaining -= sfe.length;

                sfelst.Add(sfe);
            }

            return(new SystemFile(version, sfelst.ToArray()));
        }
Ejemplo n.º 6
0
        public static bool UnmarshalItsfHeader(ref byte[] pData, ref uint pDataPos,
                                               ref uint pDataLen, ref chmItsfHeader dest)
        {
            /* we only know how to deal with the 0x58 and 0x60 byte structures */
            if (pDataLen != CHM_ITSF_V2_LEN && pDataLen != CHM_ITSF_V3_LEN)
            {
                return(false);
            }

            InitialiseItsfHeader(ref dest);

            /* unmarshal common fields */
            Unmarshal.ToCharArray(ref pData, ref pDataPos, ref pDataLen, ref dest.signature, 4);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.version);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.header_len);
            Unmarshal.ToInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_000c);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.last_modified);
            Unmarshal.ToUInt32(ref pData, ref pDataPos, ref pDataLen, ref dest.lang_id);
            Unmarshal.ToUuid(ref pData, ref pDataPos, ref pDataLen, ref dest.dir_uuid);
            Unmarshal.ToUuid(ref pData, ref pDataPos, ref pDataLen, ref dest.stream_uuid);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_offset);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.unknown_len);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.dir_offset);
            Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.dir_len);

            /* error check the data */

            /* XXX: should also check UUIDs, probably, though with a version 3 file,
             * current MS tools do not seem to use them.
             */
            if (new String(dest.signature).CompareTo("ITSF") != 0)
            {
                return(false);
            }
            if (dest.version == 2)
            {
                if (dest.header_len < CHM_ITSF_V2_LEN)
                {
                    return(false);
                }
            }
            else if (dest.version == 3)
            {
                if (dest.header_len < CHM_ITSF_V3_LEN)
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }

            /* now, if we have a V3 structure, unmarshal the rest.
             * otherwise, compute it
             */
            if (dest.version == 3)
            {
                if (pDataLen != 0)
                {
                    Unmarshal.ToUInt64(ref pData, ref pDataPos, ref pDataLen, ref dest.data_offset);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                dest.data_offset = dest.dir_offset + dest.dir_len;
            }

            return(true);
        }
Ejemplo n.º 7
0
        /* get the bounds of a compressed block.  return 0 on failure */
        public static bool GetCmpBlockBounds(ref ChmFileInfo h, UInt64 block,
                                             ref UInt64 start, ref Int64 len)
        {
            byte[] buffer = new byte[8];
            uint   remain;
            uint   pos = 0;

            /* for all but the last block, use the reset table */
            if (block < h.reset_table.block_count - 1)
            {
                /* unpack the start address */
                pos    = 0;
                remain = 8;
                if (Storage.FetchBytes(ref h, ref buffer,
                                       (UInt64)h.data_offset
                                       + (UInt64)h.rt_unit.start
                                       + (UInt64)h.reset_table.table_offset
                                       + (UInt64)block * 8,
                                       remain) != remain ||
                    !Unmarshal.ToUInt64(ref buffer, ref pos, ref remain, ref start))
                {
                    return(false);
                }

                /* unpack the end address */
                pos    = 0;
                remain = 8;
                if (Storage.FetchBytes(ref h, ref buffer,
                                       (UInt64)h.data_offset
                                       + (UInt64)h.rt_unit.start
                                       + (UInt64)h.reset_table.table_offset
                                       + (UInt64)block * 8 + 8,
                                       remain) != remain ||
                    !Unmarshal.ToInt64(ref buffer, ref pos, ref remain, ref len))
                {
                    return(false);
                }
            }

            /* for the last block, use the span in addition to the reset table */
            else
            {
                /* unpack the start address */
                pos    = 0;
                remain = 8;
                if (Storage.FetchBytes(ref h, ref buffer,
                                       (UInt64)h.data_offset
                                       + (UInt64)h.rt_unit.start
                                       + (UInt64)h.reset_table.table_offset
                                       + (UInt64)block * 8,
                                       remain) != remain ||
                    !Unmarshal.ToUInt64(ref buffer, ref pos, ref remain, ref start))
                {
                    return(false);
                }

                len = (Int64)h.reset_table.compressed_len;
            }

            /* compute the length and absolute start address */
            len   -= (Int64)start;
            start += h.data_offset + h.cn_unit.start;

            return(true);
        }