/// <summary>
        /// Write page from buffer: n - page number; nbuf - buffer number
        /// !!! NOT APPLICABLE TO IMO
        /// </summary>
        /// <param name="n"></param>
        /// <param name="nbuf"></param>
        private void page_write(long n, int nbuf)
        {
            for (int i = 0; i < pd.Length; i++)
            {
                if ((n >= pd[i].start_page) & (n <= pd[i].end_page))
                {
                    long addr = (long)((n - pd[i].start_page) * (DESCRIPTOR.PageSize + DEFS.SYSTEM_USED_PAGE_SPACE));

                    uint crc32 = VSCRC32.CountCrc(segment_table[0].cache[nbuf].buf);

                    pd[i].fs.Write(addr + 4, crc32);                         // CRC32

                    if (DESCRIPTOR.CATALOG.ENCRYPT)
                    {
                        pd[i].fs.Write(addr, DEFS.DATA_ENCRYPTED);           // Encryption
                        VSCrypto.Encrypt(ref segment_table[0].cache[nbuf].buf, ref e_buf, e_key, 0);
                        pd[i].fs.Write(addr + DEFS.SYSTEM_USED_PAGE_SPACE, ref e_buf);
                    }
                    else
                    {
                        pd[i].fs.Write(addr, DEFS.DATA_NOT_ENCRYPTED);       // Encryption
                        pd[i].fs.Write(addr + DEFS.SYSTEM_USED_PAGE_SPACE, ref segment_table[0].cache[nbuf].buf);
                    }

                    PGWrite++;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Calculate CRC32
        /// </summary>
        /// <param name="position">Start position, -1 - from the current position</param>
        /// <param name="length">Length, -1 to end of stream</param>
        /// <returns></returns>
        public uint GetCRC32(long position, long length)
        {
            const int chunk = 1024;

            // Save position
            long save_pos = fs.Position;

            // Calculate pos
            long pos = (position < 0) ? fs.Position : position;

            if (pos >= fs.Length)
            {
                pos = 0;
            }

            // Calculate len
            long len = (length < 0) ? (fs.Length - pos) : length;

            if ((pos + len) > fs.Length)
            {
                len = fs.Length - pos;
            }

            if (len == 0)
            {
                return(0);
            }

            // Calculate CRC32
            uint c = VSCRC32.BeginCRC();

            byte[] b = new byte[chunk];

            fs.Seek(pos, SeekOrigin.Begin);

            while (len > 0)
            {
                int l = (int)((len <= chunk) ? len : chunk);

                this.ReadBytes(0, l);

                c = VSCRC32.AddCRC(c, b);

                len -= l;
            }

            // Restore position
            fs.Seek(save_pos, SeekOrigin.Begin);

            return(VSCRC32.EndCRC(c));
        }
        /// <summary>
        /// Read page into buffer: n - page number; nbuf - buffer number
        /// !!! NOT APPLICABLE TO IMO
        /// </summary>
        /// <param name="n"></param>
        /// <param name="nbuf"></param>
        private void page_read(long n, int sg, int pg, int nbuf)
        {
            for (int i = 0; i < pd.Length; i++)
            {
                if ((n >= pd[i].start_page) & (n <= pd[i].end_page))
                {
                    // Absolute address (beginning of system area
                    long addr = (long)((n - pd[i].start_page) * (DESCRIPTOR.PageSize + DEFS.SYSTEM_USED_PAGE_SPACE));

                    uint encr = pd[i].fs.ReadUInt(addr);        // Encryption

                    uint old_crc = pd[i].fs.ReadUInt(addr + 4); // Crc32

                    if (encr == DEFS.DATA_ENCRYPTED)
                    {
                        e_buf = pd[i].fs.ReadBytes(addr + DEFS.SYSTEM_USED_PAGE_SPACE, (int)page_size);

                        VSCrypto.Decrypt(ref e_buf, ref segment_table[0].cache[nbuf].buf, e_key, 0);
                    }
                    else
                    {
                        segment_table[0].cache[nbuf].buf = pd[i].fs.ReadBytes(addr + DEFS.SYSTEM_USED_PAGE_SPACE, (int)page_size);
                    }

                    if (old_crc != 0)
                    {
                        uint new_crc = VSCRC32.CountCrc(segment_table[0].cache[nbuf].buf);
                        if (old_crc != new_crc)
                        {
                            throw new VSException(DEFS.E0033_INVALID_CRC_CODE, "Space: " + DESCRIPTOR.name + ", Page#: " + n.ToString());
                        }
                    }

                    PGRead++;

                    // Update page table entry by but# ans sett 'read' state
                    segment_table[sg].page_table[pg].page_state = DEFS.PAGE_READ;
                    segment_table[sg].page_table[pg].bufno      = nbuf;

                    // Update cache entry by page#
                    segment_table[0].cache[nbuf].page_no = n;
                }
            }
        }