/// <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++; } } }
/// <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; } } }