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); }
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); }
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); }
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); }
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())); }
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); }
/* 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); }