Example #1
0
    private string ChmFileToString(chmUnitInfo ui)
    {
        const ulong tmpBufSize = 1025;

        StringBuilder strb = new StringBuilder();


        ulong size = tmpBufSize - 1;
        ulong cur  = 0;


        IntPtr raw = Marshal.AllocCoTaskMem((int)tmpBufSize);

        do
        {
            size = chm_retrieve_object(chmfile, ui, raw, cur, tmpBufSize - 1);
            // If I dont create a copy of the string when i free 'raw' the builder data dissapear
            // the last  chunk readed dissapear (mono bug or mi endless stupidity)
            // I'll have to check it out
            strb.Append(Marshal.PtrToStringAuto(raw, (int)size));
            cur += size;
        }while(size == tmpBufSize - 1);

        Marshal.FreeCoTaskMem(raw);
        return(strb.ToString());
    }
Example #2
0
        static EnumerateStatus EnumeratorCallback(chmFile file, ref chmUnitInfo ui, ref Object context)
        {
            if (!ui.path.EndsWith("/"))
                Console.WriteLine(file.FileName + ": " + ui.path);

            if (ui.length > 0) {
                byte[] buf = new byte[ui.length];
                long ret = file.RetrieveObject(ui, ref buf, 0, buf.Length);

                if (ret > 0) {
                    try {
                        FileInfo fi =
                            new FileInfo(Path.Combine(_outdir, ui.path.Trim('/')));

                        List<DirectoryInfo> created;

                        fi.Directory.CreateDirectory(out created);
                        File.WriteAllBytes(fi.FullName, buf);
                    } catch (ArgumentException ex) {
                        Console.WriteLine(ex.Message);
                    }
                }
            }

            return EnumerateStatus.Continue;
        }
Example #3
0
    private int GetHtmlFiles(IntPtr chmFile,
                             chmUnitInfo info,
                             IntPtr context)
    {
        if (info.path.EndsWith(".html"))
        {
            htmlFiles.Add(info.path.Trim());
        }

        return(1);
    }
Example #4
0
    /*
     * TODO:
     * We should trow something like a FileNotFoundException
     */
    public TextReader GetFile(string path)
    {
        chmUnitInfo ui = new chmUnitInfo();

        if (chm_resolve_object(chmfile, path, ui) == ChmResolve.Failure)
        {
            //Console.WriteLine("Fails to Open: {0}",path);
            return(new StringReader(""));
        }

        return(new StringReader(ChmFileToString(ui)));
    }
Example #5
0
    public void ParseContents(ChmHtmlParseFunc Parse)
    {
        if (this.loaded)
        {
            foreach (string fileName in htmlFiles)
            {
                chmUnitInfo ui = new chmUnitInfo();

                chm_resolve_object(this.chmfile,
                                   fileName,
                                   ui);


                //Console.WriteLine("Parsing....{0}",ui.path);
                ///Logger.Log.Debug("CHMFile: Parsing {0}....",ui.path);
                Parse(new StringReader(ChmFileToString(ui).Trim()));
            }
        }
    }
Example #6
0
        /* parse a PMGL entry into a chmUnitInfo struct; return 1 on success. */
        public static bool ParsePgmlEntry(byte[] pEntry, ref uint os, ref chmUnitInfo ui)
        {
            char[] buf = new char[Storage.CHM_MAX_PATHLEN];
            UInt64 strLen;

            /* parse str len */
            strLen = Storage.ParseCWord(pEntry, ref os);
            if (strLen > Storage.CHM_MAX_PATHLEN)
                return false;

            /* parse path */
            if (!Storage.ParseUTF8(pEntry, ref os, strLen, ref buf))
                return false;

            /* parse info */
            ui.space  = (int)Storage.ParseCWord(pEntry, ref os);
            ui.start = Storage.ParseCWord(pEntry, ref os);
            ui.length = Storage.ParseCWord(pEntry, ref os);
            ui.path = new String(buf);

            return true;
        }
Example #7
0
        /* retrieve (part of) an object */
        public LONGINT64 RetrieveObject(chmUnitInfo ui, ref byte[] buf, LONGUINT64 addr, LONGINT64 len)
        {
            /* must be valid file handle */
            if (_h.fd == null)
                return (Int64)0;

            /* starting address must be in correct range */
            if (addr < 0  ||  addr >= ui.length)
                return (Int64)0;

            /* clip length */
            if (addr + (ulong)len > ui.length)
                len = (LONGINT64)(ui.length - addr);

            /* if the file is uncompressed, it's simple */
            if (ui.space == Storage.CHM_UNCOMPRESSED) {
                /* read data */
                return Storage.FetchBytes(ref _h, ref buf,
                                  (UInt64)_h.data_offset + (UInt64)ui.start + (UInt64)addr,
                                  len);
            }

            /* else if the file is compressed, it's a little trickier */
            else /* ui->space == CHM_COMPRESSED */
            {
                Int64 swath = 0, total = 0;
                UInt64 bufpos = 0;

                /* if compression is not enabled for this file... */
                if (!_h.compression_enabled)
                    return total;

                do {
                    /* swill another mouthful */
                    swath = Lzxc.DecompressRegion(ref _h, ref buf, bufpos + ui.start + addr, len);

                    /* if we didn't get any... */
                    if (swath == 0)
                        return total;

                    /* update stats */
                    total += swath;
                    len -= swath;
                    addr += (LONGUINT64)swath;
                    bufpos += (LONGUINT64)swath;    /* TODO bobc: this might not be right */

                } while (len != 0);

                return total;
            }
        }
Example #8
0
    private bool WindowsInfo()
    {
        int    entries;
        int    entrySize;
        IntPtr windowsData;
        long   size = 0;
        uint   block;

        const int headerLen = 0x8;


        IntPtr      buf = Marshal.AllocCoTaskMem(bufSize);
        chmUnitInfo ui  = new chmUnitInfo();


        if (chm_resolve_object(chmfile, "/#WINDOWS", ui) == ChmResolve.Failure)
        {
            return(false);
        }

        if (chm_retrieve_object(chmfile, ui, buf, 0, headerLen) == 0)
        {
            return(false);
        }

        entries   = Marshal.ReadInt32(buf);
        entrySize = Marshal.ReadInt32(buf, 0x4);

        //Console.WriteLine ("entries -> {0}\nsize = {1}",entries,entrySize);

        windowsData = Marshal.AllocCoTaskMem(entries * entrySize);


        size = (long)chm_retrieve_object(chmfile,
                                         ui,
                                         windowsData,
                                         headerLen,
                                         (ulong)(entries * entrySize));
        if (size == 0)
        {
            return(false);
        }

        size = 0;


        if (chm_resolve_object(chmfile, "/#STRINGS", ui) == ChmResolve.Failure)
        {
            return(false);
        }


        /*
         * From Pabs' CHM Spec:
         * "(STRINGS)This file is a list of ANSI/UTF-8 NT strings.
         * The first is just a NIL character so that offsets to this file can specify
         * zero & get a valid string.
         * The strings are sliced up into blocks that are 4096 bytes in length."
         */



        for (int i = 0; i < entries; i++)
        {
            int offset = i * entrySize;


            uint offTitle = (uint)Marshal.ReadInt32(windowsData,
                                                    offset + 0x14);

            uint offTocFile = (uint)Marshal.ReadInt32(windowsData,
                                                      offset + 0x60);
            uint offDefaultFile = (uint)Marshal.ReadInt32(windowsData,
                                                          offset + 0x68);


            //Console.WriteLine("offTocFile = {0}",offTocFile);


            block = offTitle / 4096;


            if (size == 0)
            {
                size = (long)chm_retrieve_object(chmfile,
                                                 ui,
                                                 buf,
                                                 block * 4096,
                                                 (ulong)bufSize);
            }


            if (size > 0 && offTitle > 0)
            {
                this.title = ChmGetString(buf, (int)offTitle, 4096);
            }


            if (block != offTocFile / 4096)
            {
                block = offTocFile / 4096;
                size  = (long)chm_retrieve_object(chmfile,
                                                  ui,
                                                  buf,
                                                  block * 4096,
                                                  (ulong)bufSize);
            }


            if (size > 0 && offTocFile > 0)
            {
                topicsFile = "/" + ChmGetString(buf,
                                                (int)offTocFile % 4096,
                                                4096);
                hasTopics = true;
            }


            if (block != offDefaultFile / 4096)
            {
                block = offDefaultFile / 4096;
                size  = (long)chm_retrieve_object(chmfile,
                                                  ui,
                                                  buf,
                                                  block * 4096,
                                                  (ulong)bufSize);
            }


            if (size > 0 && offDefaultFile > 0)
            {
                defaultFile = ("/" + ChmGetString(buf,
                                                  (int)offDefaultFile % 4096,
                                                  4096));
            }
        }

        Marshal.FreeCoTaskMem(buf);
        Marshal.FreeCoTaskMem(windowsData);
        return(true);
    }
Example #9
0
		private int GetHtmlFiles(IntPtr chmFile,
					 chmUnitInfo info,
					 IntPtr context) 
		{
			if(info.path.EndsWith(".html"))
				htmlFiles.Add(info.path.Trim());
			
			return 1;
			
		}
Example #10
0
    /**
     *
     * From the #SYSTEM File we are interested in the title (for now).
     *
     */

    private bool SystemInfo()
    {
        ChmResolve res;
        ulong      size;
        bool       gottitle = false;



        if (!loaded)
        {
            return(false);
        }


        IntPtr buf = Marshal.AllocCoTaskMem(bufSize);

        chmUnitInfo ui = new chmUnitInfo();


        res = chm_resolve_object(this.chmfile, "/#SYSTEM", ui);


        if (res == ChmResolve.Failure)
        {
            return(false);
        }

        size = chm_retrieve_object(this.chmfile, ui, buf, 4, (ulong)bufSize);

        int    index = 0;
        ushort value = 0;
        long   tol   = (long)size - 2;

        while (index < tol)
        {
            value = (ushort)Marshal.ReadInt16(buf, index);

            if (value == 3)
            {
                index += 2;
                ushort len = (ushort)Marshal.ReadInt16(buf, (int)index);

                if (this.title == "")
                {
                    this.title = ChmGetString(buf, index + 2, (int)len);
                }
                gottitle = true;
                break;
            }
            else
            {
                index += 2;
            }


            value = (ushort)Marshal.ReadInt16(buf, (int)index);

            index += (int)value + 2;
        }

        Marshal.FreeCoTaskMem(buf);
        return(gottitle);
    }
Example #11
0
		private string ChmFileToString(chmUnitInfo ui) 
		{
			
			
			const ulong tmpBufSize = 1025;
			
			StringBuilder strb = new StringBuilder();
			
		
			ulong size = tmpBufSize -1;
			ulong cur = 0;
			
			
			IntPtr raw = Marshal.AllocCoTaskMem ((int)tmpBufSize);
			
			do {
				size = chm_retrieve_object(chmfile,ui,raw,cur,tmpBufSize-1);
				// If I dont create a copy of the string when i free 'raw' the builder data dissapear
				// the last  chunk readed dissapear (mono bug or mi endless stupidity)
				// I'll have to check it out 
				strb.Append(Marshal.PtrToStringAuto(raw,(int)size));
				cur += size;
			}
			while(size == tmpBufSize-1);
			
			Marshal.FreeCoTaskMem (raw);
			return strb.ToString();
			
		}
Example #12
0
		/**
		   
		From the #SYSTEM File we are interested in the title (for now).
		
		*/

		private bool SystemInfo() 
		{
			ChmResolve res; 
			ulong  size;
			bool gottitle = false;
			
			
			
			if(!loaded)
				return false;
			
			
			IntPtr buf = Marshal.AllocCoTaskMem (bufSize);
			
			chmUnitInfo ui = new chmUnitInfo() ;
		
			
			res = chm_resolve_object (this.chmfile,"/#SYSTEM", ui);
			
			
			if(res == ChmResolve.Failure)
				return false;
			
			size  =  chm_retrieve_object (this.chmfile, ui,buf, 4, (ulong)bufSize);
			
			int index = 0;
			ushort value = 0;
			long tol = (long)size - 2;
			
			while(index < tol) {
				
				
				value =  (ushort)Marshal.ReadInt16 (buf, index);
				
				if(value == 3) {
					
					
					index += 2;
					ushort len = (ushort)Marshal.ReadInt16 (buf, (int)index);
					
					if(this.title == "") 
						this.title = ChmGetString (buf,index+2, (int)len);
					gottitle = true;
					break;
					
					
				}
				else 
					index += 2;
				
				
				value = (ushort) Marshal.ReadInt16(buf,(int)index);
				
				index += (int)value + 2;
				
			}
			
			Marshal.FreeCoTaskMem (buf);
			return gottitle;
			
		}
Example #13
0
 private static extern UInt64 chm_retrieve_object(IntPtr raw,
                                                  [In, Out] chmUnitInfo ui,
                                                  IntPtr buf,
                                                  UInt64 addr,
                                                  UInt64 len);
Example #14
0
 private static extern ChmResolve chm_resolve_object(IntPtr raw,
                                                     string objPath,
                                                     [Out] chmUnitInfo ui);
Example #15
0
        public static chmFile Open(string filename)
        {
            byte[] sbuffer = new byte[256];
            uint sremain;
            uint sbufpos;
            chmItsfHeader itsfHeader = new chmItsfHeader();
            chmItspHeader itspHeader = new chmItspHeader();
            chmUnitInfo uiLzxc = new chmUnitInfo();
            chmLzxcControlData ctlData = new chmLzxcControlData();
            chmFile chmf = new chmFile(filename);

            /* allocate handle */
            chmf._h.fd = null;
            chmf._h.lzx_state = null;
            chmf._h.cache_blocks = null;
            chmf._h.cache_block_indices = null;
            chmf._h.cache_num_blocks = 0;

            /* open file */
            chmf._h.fd = File.Open(filename, FileMode.Open, FileAccess.Read);

            /* initialize mutexes, if needed */
            chmf._h.mutex = new Mutex();
            chmf._h.lzx_mutex = new Mutex();
            chmf._h.cache_mutex = new Mutex();

            /* read and verify header */
            sremain = Itsf.CHM_ITSF_V3_LEN;
            sbufpos = 0;
            if (Storage.FetchBytes(ref chmf._h, ref sbuffer, 0, sremain) != sremain ||
                !Itsf.UnmarshalItsfHeader(ref sbuffer, ref sbufpos, ref sremain, ref itsfHeader))
            {
                chmf.Close();
                throw new InvalidDataException();
            }

            /* stash important values from header */
            chmf._h.dir_offset = itsfHeader.dir_offset;
            chmf._h.dir_len = itsfHeader.dir_len;
            chmf._h.data_offset = itsfHeader.data_offset;

            /* now, read and verify the directory header chunk */
            sremain = Itsp.CHM_ITSP_V1_LEN;
            sbufpos = 0;
            if (Storage.FetchBytes(ref chmf._h, ref sbuffer,
                           (UInt64)itsfHeader.dir_offset, sremain) != sremain ||
                !Itsp.UnmarshalItpfHeader(ref sbuffer, ref sbufpos, ref sremain, ref itspHeader))
            {
                chmf.Close();
                throw new InvalidDataException();
            }

            /* grab essential information from ITSP header */
            chmf._h.dir_offset += (ulong)itspHeader.header_len;
            chmf._h.dir_len -= (ulong)itspHeader.header_len;
            chmf._h.index_root = itspHeader.index_root;
            chmf._h.index_head = itspHeader.index_head;
            chmf._h.block_len = itspHeader.block_len;

            /* if the index root is -1, this means we don't have any PMGI blocks.
             * as a result, we must use the sole PMGL block as the index root
             */
            if (chmf._h.index_root <= -1)
                chmf._h.index_root = chmf._h.index_head;

            /* By default, compression is enabled. */
            chmf._h.compression_enabled = true;

            /* prefetch most commonly needed unit infos */
            if (!chmf.ResolveObject(Storage.CHMU_RESET_TABLE, ref chmf._h.rt_unit) ||
                chmf._h.rt_unit.space == Storage.CHM_COMPRESSED ||
                !chmf.ResolveObject(Storage.CHMU_CONTENT, ref chmf._h.cn_unit) ||
                chmf._h.cn_unit.space == Storage.CHM_COMPRESSED ||
                !chmf.ResolveObject(Storage.CHMU_LZXC_CONTROLDATA, ref uiLzxc) ||
                uiLzxc.space == Storage.CHM_COMPRESSED)
            {
                chmf._h.compression_enabled = false;
            }

            /* read reset table info */
            if (chmf._h.compression_enabled) {
                sremain = Lzxc.CHM_LZXC_RESETTABLE_V1_LEN;
                sbufpos = 0;  /* TODO bobc: is sbuffer actually at index 0?? */
                if (chmf.RetrieveObject(chmf._h.rt_unit, ref sbuffer,
                                        0, sremain) != sremain              ||
                    !Lzxc.UnmarshalLzxcResetTable(ref sbuffer, ref sbufpos, ref sremain,
                                                 ref chmf._h.reset_table))
                {
                    chmf._h.compression_enabled = false;
                }
            }

            /* read control data */
            if (chmf._h.compression_enabled) {
                sremain = (uint)uiLzxc.length;
                if (uiLzxc.length > (ulong)sbuffer.Length) {
                    chmf.Close();
                    throw new InvalidDataException();
                }

                sbufpos = 0;  /* TODO bobc: is sbuffer actually at index 0?? */
                if (chmf.RetrieveObject(uiLzxc, ref sbuffer,
                                        0, sremain) != sremain              ||
                    !Lzxc.UnmarshalLzxcControlData(ref sbuffer, ref sbufpos, ref sremain,
                                                  ref ctlData))
                {
                    chmf._h.compression_enabled = false;
                }

                chmf._h.window_size = ctlData.windowSize;
                chmf._h.reset_interval = ctlData.resetInterval;

                /* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */
                /*       must be multiplied by this formerly unknown ctrl data field in   */
                /*       order to decompress some files.                                  */
                chmf._h.reset_blkcount = chmf._h.reset_interval    /
                                            (chmf._h.window_size / 2) *
                                            ctlData.windowsPerReset;
            }

            /* initialize cache */
            chmf.SetParam(CHM_PARAM_MAX_BLOCKS_CACHED, CHM_MAX_BLOCKS_CACHED);

            return chmf;
        }
Example #16
0
        /* resolve a particular object from the archive */
        public bool ResolveObject(string objPath, ref chmUnitInfo ui)
        {
            /*
             * XXX: implement caching scheme for dir pages
             */

            Int32 curPage;

            /* buffer to hold whatever page we're looking at */
            /* RWE 6/12/2003 */
            byte[] page_buf = new byte[_h.block_len];

            /* starting page */
            curPage = _h.index_root;

            /* until we have either returned or given up */
            while (curPage != -1) {
                /* try to fetch the index page */
                if (Storage.FetchBytes(ref _h, ref page_buf,
                               (UInt64)_h.dir_offset + (UInt64)curPage * _h.block_len,
                               _h.block_len) != _h.block_len)
                    return false;

                /* now, if it is a leaf node: */
                if (ASCIIEncoding.UTF8.GetString(page_buf, 0, 4).CompareTo(Pmgl.CHM_PMGL_MARKER) == 0) {
                    /* scan block */
                    uint pEntry = (uint)Pmgl.FindInPmgl(page_buf, _h.block_len, objPath);
                    if (pEntry < 0)
                        return false;

                    /* parse entry and return */
                    Pmgl.ParsePgmlEntry(page_buf, ref pEntry, ref ui);
                    return true;
                }

                /* else, if it is a branch node: */
                else if (ASCIIEncoding.UTF8.GetString(page_buf, 0, 4).CompareTo(Pmgi.CHM_PMGI_MARKER) == 0)
                    curPage = Pmgi.FindInPmgi(page_buf, _h.block_len, objPath);

                /* else, we are confused.  give up. */
                else
                    return false;
            }

            /* didn't find anything.  fail. */
            return false;
        }
Example #17
0
        /* enumerate the objects in the .chm archive */
        public bool Enumerate(EnumerateLevel what, chmEnumerator e, ref object context)
        {
            Int32 curPage;

            /* buffer to hold whatever page we're looking at */
            /* RWE 6/12/2003 */
            byte[] page_buf = new byte[_h.block_len];
            chmPmglHeader header = new chmPmglHeader();
            uint end;
            uint cur;
            uint lenRemain;
            UInt64 ui_path_len;

            /* the current ui */
            chmUnitInfo ui = new chmUnitInfo();
            int type_bits = ((int)what & 0x7);
            int filter_bits = ((int)what & 0xF8);

            /* starting page */
            curPage = _h.index_head;

            /* until we have either returned or given up */
            while (curPage != -1) {
                /* try to fetch the index page */
                if (Storage.FetchBytes(ref _h,
                                     ref page_buf,
                                     (UInt64)_h.dir_offset + (UInt64)curPage * _h.block_len,
                                     _h.block_len) != _h.block_len)
                    return false;

                /* figure out start and end for this page */
                cur = 0;
                lenRemain = Pmgl.CHM_PMGL_LEN;
                if (!Pmgl.UnmarshalPmglHeader(ref page_buf, ref cur, ref lenRemain, ref header))
                    return false;
                end = _h.block_len - (header.free_space);

                /* loop over this page */
                while (cur < end) {
                    ui.flags = 0;

                    if (!Pmgl.ParsePgmlEntry(page_buf, ref cur,  ref ui))
                        return false;

                    /* get the length of the path */
                    ui_path_len = (ulong)ui.path.Length;

                    /* check for DIRS */
                    if (ui.path.EndsWith("/"))
                        ui.flags |= (int)EnumerateLevel.Directories;

                    /* check for FILES */
                    if (!ui.path.EndsWith("/"))
                        ui.flags |= (int)EnumerateLevel.Files;

                    /* check for NORMAL vs. META */
                    if (ui.path.StartsWith("/")) {
                        /* check for NORMAL vs. SPECIAL */
                        if (ui.path.Length > 1 && (ui.path[1] == '#' || ui.path[1] == '$'))
                            ui.flags |= (int)EnumerateLevel.Special;
                        else
                            ui.flags |= (int)EnumerateLevel.Normal;
                    }
                    else
                        ui.flags |= (int)EnumerateLevel.Meta;

                    if (!Convert.ToBoolean(type_bits & ui.flags))
                        continue;

                    if (filter_bits != 0 && (filter_bits & ui.flags) == 0)
                        continue;

                    /* call the enumerator */
                    EnumerateStatus status = e(this, ref ui, ref context);
                    switch (status) {
                        case EnumerateStatus.Failure:
                            return false;

                        case EnumerateStatus.Continue:
                            break;

                        case EnumerateStatus.Success:
                            return true;

                        default:
                            break;
                    }
                }

                /* advance to next page */
                curPage = header.block_next;
            }

            return true;
        }
Example #18
0
		public void ParseContents(ChmHtmlParseFunc Parse)
		{
			
						
			if(this.loaded)
				foreach(string fileName in htmlFiles) {
					chmUnitInfo ui = new chmUnitInfo();
					
					chm_resolve_object(this.chmfile,
							   fileName,
							   ui) ;
					
					
					//Console.WriteLine("Parsing....{0}",ui.path);
					///Logger.Log.Debug("CHMFile: Parsing {0}....",ui.path);
					Parse( new StringReader(ChmFileToString(ui).Trim()) );
					
					
				}
			
			
			
		}
Example #19
0
		private bool WindowsInfo() 
		{
			
			int  entries;
			int entrySize;
			IntPtr windowsData;
			long size = 0;
			uint block;
			
			const int headerLen = 0x8;
			
		
			IntPtr buf = Marshal.AllocCoTaskMem (bufSize);
			chmUnitInfo ui = new chmUnitInfo ();
			
			
			if(chm_resolve_object (chmfile,"/#WINDOWS",ui) == ChmResolve.Failure)
				return false;
			
			if(chm_retrieve_object (chmfile,ui,buf,0,headerLen) == 0)
				return false;
			
			entries = Marshal.ReadInt32 (buf);
			entrySize = Marshal.ReadInt32 (buf,0x4);
			
			//Console.WriteLine ("entries -> {0}\nsize = {1}",entries,entrySize);
			
			windowsData  = Marshal.AllocCoTaskMem(entries * entrySize);
			
		
			size = (long)chm_retrieve_object (chmfile,
							  ui,
							  windowsData,
							  headerLen,
							  (ulong)(entries * entrySize));
			if(size == 0)
				return false;
			
			size = 0;
			
			
			if(chm_resolve_object (chmfile,"/#STRINGS",ui) == ChmResolve.Failure)
				return false;
			
			
		/*
		  From Pabs' CHM Spec: 
		  "(STRINGS)This file is a list of ANSI/UTF-8 NT strings.
		  The first is just a NIL character so that offsets to this file can specify 
		  zero & get a valid string.
		  The strings are sliced up into blocks that are 4096 bytes in length."
		*/
			
			
			
			for(int i = 0; i < entries; i++) {
				
				int offset = i * entrySize;
				
				
				uint offTitle  = (uint)Marshal.ReadInt32(windowsData,
									 offset + 0x14);
				
				uint offTocFile = (uint)Marshal.ReadInt32(windowsData,
									  offset + 0x60);
				uint offDefaultFile = (uint)Marshal.ReadInt32(windowsData,
									      offset + 0x68);
				
								
				//Console.WriteLine("offTocFile = {0}",offTocFile);
				
				
				block = offTitle / 4096;
				
				
				if(size == 0) 
					size = (long)chm_retrieve_object(chmfile, 
									 ui, 
									 buf, 
									 block * 4096, 
									 (ulong)bufSize);
				
				
				if(size > 0 && offTitle > 0) 
					this.title = ChmGetString(buf,(int)offTitle,4096);
				
				
				if(block != offTocFile / 4096) {
					block = offTocFile / 4096;
					size = (long)chm_retrieve_object(chmfile, 
									 ui, 
									 buf, 
									 block * 4096, 
									 (ulong)bufSize);
					
				}
				
				
				if(size > 0 && offTocFile > 0){ 				
					topicsFile = "/" + ChmGetString(buf,
									(int)offTocFile % 4096 ,
									4096);
					hasTopics = true;
				}
				
				
				if(block != offDefaultFile / 4096) {
					block = offDefaultFile / 4096;
					size = (long)chm_retrieve_object(chmfile, 
									 ui, 
									 buf, 
									 block * 4096, 
									 (ulong)bufSize);
					
				}
				
				
				if(size > 0 && offDefaultFile > 0) 				
					defaultFile = ("/" + ChmGetString(buf,
									  (int)offDefaultFile % 4096 ,
									  4096) );
												
				

			}
		
			Marshal.FreeCoTaskMem (buf);
			Marshal.FreeCoTaskMem (windowsData);
			return true;
			
		}
Example #20
0
		/*
		  TODO:
		  We should trow something like a FileNotFoundException
		*/
		public TextReader GetFile(string path) 
		{

			chmUnitInfo ui = new chmUnitInfo();
			
			if(chm_resolve_object (chmfile,path,ui)  == ChmResolve.Failure) {
				//Console.WriteLine("Fails to Open: {0}",path);
				return new StringReader("");
				

			}
			
			return (new StringReader(ChmFileToString(ui)));
						
		}