// Decompiled with JetBrains decompiler // Type: Microsoft.InfoCards.IndexedDataBuffer // Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 // MVID: ADE0A079-11DB-4A46-8BDE-D2A592CA8DEA // Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00001-msil\Virus.Win32.Expiro.w-1f15ee7e9f7da02b6bfb4c5a5e6484eb9fa71b82d3699c54bcc7a31794b4a66d.exe using Microsoft.InfoCards.Diagnostics; using System; using System.IO; using System.Runtime.InteropServices; namespace Microsoft.InfoCards { internal class IndexedDataBuffer { private byte[] m_buffer; private byte[] m_masterIndex; private FreeIndexList m_freeList; private int m_dataLength; private bool m_isOpen; private DataSource m_owner; public unsafe IndexedDataBuffer( byte[] masterIndex, byte[] buffer, int dataLength, DataSource owner) { if (masterIndex == null || masterIndex.Length == 0) throw InfoCardTrace.ThrowHelperArgumentNull(nameof (masterIndex), SR.GetString("StoreIndexedDataBufferNullOrEmptyMasterIndexBuffer")); if (buffer == null || buffer.Length == 0) throw InfoCardTrace.ThrowHelperArgumentNull(nameof (buffer), SR.GetString("StoreIndexedDataBufferNullOrEmptyDataIndexBuffer")); if (dataLength < 0 || dataLength > buffer.Length) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (dataLength), (object) dataLength, SR.GetString("StoreIndexDataBufferDataLengthOutOfRange"))); this.m_owner = owner; this.m_masterIndex = masterIndex; this.m_buffer = buffer; this.m_dataLength = dataLength; this.m_freeList = new FreeIndexList(20); fixed (byte* numPtr = &this.m_masterIndex[0]) { for (int index = 1; index < this.m_masterIndex.Length / 4; ++index) { if (((int*) numPtr)[index] <= 0) this.m_freeList.Put(index); } } this.m_isOpen = true; } public byte[] Index { get { this.ThrowIfNotOpen(); return this.m_masterIndex; } } public byte[] Data { get { this.ThrowIfNotOpen(); return this.m_buffer; } } public int DataLength { get { this.ThrowIfNotOpen(); return this.m_dataLength; } } public void Close() { this.ThrowIfNotOpen(); this.Clear(); this.m_buffer = (byte[]) null; this.m_masterIndex = (byte[]) null; this.m_isOpen = false; } public unsafe DataRow CreateDataRow(int id) { this.ThrowIfNotOpen(); if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id)) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); fixed (byte* pHeader = &this.m_buffer[this.GetOffset(ref id)]) return DataRow.Create((EncryptedObjectHeader*) pHeader, this.m_owner); } public unsafe void CopyIVFromObject(int id, byte[] iv, int index) { this.ThrowIfNotOpen(); if (iv == null || iv.Length == 0) throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv)); if (index < 0 || index > this.DataLength - iv.Length) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (index), (object) index, SR.GetString("StoreIndexDataBufferIndexOutOfRange"))); if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id)) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); int offset = this.GetOffset(ref id); InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset."); fixed (byte* numPtr = &this.m_buffer[offset]) Marshal.Copy(new IntPtr((void*) &((EncryptedObjectHeader*) numPtr)->IV), iv, 0, iv.Length); } public Stream GetStreamForObjectData(int id) { this.ThrowIfNotOpen(); if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id)) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); int offset = this.GetOffset(ref id); InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset."); int objectDataSize = this.GetObjectDataSize(offset); InfoCardTrace.Assert(objectDataSize <= this.m_buffer.Length - offset, "The length the stored object is invalid"); return (Stream) new MemoryStream(this.m_buffer, offset + sizeof (EncryptedObjectHeader), objectDataSize, false, false); } public void RemoveObject(int id) { this.ThrowIfNotOpen(); if (id > this.m_masterIndex.Length / 4 || this.m_freeList.Contains(id)) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); int offset = this.GetOffset(ref id); InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset."); this.RemoveFromMasterIndex(id); this.EnsureSpaceForData(offset, 0); } public unsafe int WriteObject( int id, byte[] iv, byte[] data, int objectType, long lastChange, GlobalId globalId) { this.ThrowIfNotOpen(); if (iv == null || iv.Length == 0) throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv)); if (data == null || data.Length == 0) throw InfoCardTrace.ThrowHelperArgumentNull(nameof (iv)); if (id > this.m_masterIndex.Length / 4) throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); int offset = id <= 0 || !this.m_freeList.Contains(id) ? this.GetOffset(ref id) : throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), (object) id, SR.GetString("StoreLocalIdOutOfRange"))); InfoCardTrace.Assert(id >= 0, "Invalid ID was returned by GetOffset."); this.EnsureSpaceForData(offset, data.Length); fixed (byte* numPtr1 = &this.m_buffer[offset]) { byte* numPtr2 = (byte*) ((EncryptedObjectHeader*) numPtr1 + 1); ((EncryptedObjectHeader*) numPtr1)->LastChange = lastChange; ((EncryptedObjectHeader*) numPtr1)->DataSize = data.Length; ((EncryptedObjectHeader*) numPtr1)->ObjectType = objectType; ((EncryptedObjectHeader*) numPtr1)->LocalId = id; ((EncryptedObjectHeader*) numPtr1)->GlobalId = globalId; InfoCardTrace.Assert(iv.Length <= 32, "IV Length is invalid"); Marshal.Copy(iv, 0, new IntPtr((void*) &((EncryptedObjectHeader*) numPtr1)->IV), iv.Length); Marshal.Copy(data, 0, new IntPtr((void*) numPtr2), data.Length); } return id; } private unsafe int GetObjectDataSize(int offset) { fixed (byte* numPtr = &this.m_buffer[offset]) return ((EncryptedObjectHeader*) numPtr)->DataSize; } private void Clear() { Array.Clear((Array) this.m_buffer, 0, this.m_dataLength); Array.Clear((Array) this.m_masterIndex, 0, this.m_masterIndex.Length); this.m_dataLength = 0; } private unsafe int EnsureSpaceForData(int offset, int dataSize) { InfoCardTrace.Assert((uint) offset <= (uint) this.m_dataLength, "offset specified is outside the range of the data buffer"); InfoCardTrace.Assert(dataSize >= 0, "The requested data size must be greater than or equal to 0"); int num1 = 0; if (dataSize != 0) num1 = dataSize + sizeof (EncryptedObjectHeader); if (num1 % 8 != 0) num1 += 8 - num1 % 8; int num2; if (offset == this.m_dataLength) { num2 = 0; } else { fixed (byte* numPtr = &this.m_buffer[offset]) { num2 = ((EncryptedObjectHeader*) numPtr)->DataSize + sizeof (EncryptedObjectHeader); if (num2 % 8 != 0) num2 += 8 - num2 % 8; } } InfoCardTrace.Assert(num2 <= this.m_dataLength, "currentSize can not be more "); if (num2 == num1) return num1; int num3 = offset + num2; int diff = num1 - num2; int num4 = num3 + diff; if (diff > 0 && this.m_dataLength + diff >= this.m_buffer.Length) this.GrowBuffer(this.m_dataLength + diff); InfoCardTrace.Assert((uint) num3 <= (uint) this.m_buffer.Length && num3 >= offset, "NextIndex value is corrupt when attempting to ensure space for object"); InfoCardTrace.Assert((uint) num4 <= (uint) this.m_buffer.Length, "NextNewIndex value is corrupt when attempting to ensure space for object"); if (this.m_dataLength != num3) { InfoCardTrace.Assert(this.m_dataLength - num3 > 0, "NextIndex data is corrupt when attempting to ensure space for object in middle of content."); Array.Copy((Array) this.m_buffer, num3, (Array) this.m_buffer, num4, this.m_dataLength - num3); this.m_dataLength += diff; InfoCardTrace.Assert(this.m_dataLength >= 0, "DataLength has been corrupted."); if (diff < 0) { InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength is larger than allocated buffer."); Array.Clear((Array) this.m_buffer, this.m_dataLength, Math.Abs(diff)); } this.UpdateMasterIndex(Math.Min(num3, num4), diff); } else this.m_dataLength += diff; InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength is larger than allocated buffer."); return num1; } private void GrowMasterIndex() { int num1 = this.m_masterIndex.Length / 4; int increaseByPercent = Utility.CalculateIncreaseByPercent(this.m_masterIndex.Length, 4, 5); InfoCardTrace.Assert(increaseByPercent > this.m_masterIndex.Length, "NewSize must be greater than old size to grow master index buffer"); byte[] destinationArray = new byte[increaseByPercent]; Array.Copy((Array) this.m_masterIndex, 0, (Array) destinationArray, 0, this.m_masterIndex.Length); Array.Clear((Array) this.m_masterIndex, 0, this.m_masterIndex.Length); this.m_masterIndex = destinationArray; int num2 = this.m_masterIndex.Length / 4; for (int index = num1 + 1; index < num2; ++index) this.m_freeList.Put(index); } private void GrowBuffer(int spaceRequired) { InfoCardTrace.Assert(spaceRequired >= this.m_buffer.Length, "RequireSpace must be greater than old size to grow data buffer"); int num = spaceRequired; int length = num + num / 20; InfoCardTrace.Assert(length >= spaceRequired, "NewLength must be greater than required space to grow data buffer"); byte[] destinationArray = new byte[length]; Array.Copy((Array) this.m_buffer, 0, (Array) destinationArray, 0, this.m_buffer.Length); Array.Clear((Array) this.m_buffer, 0, this.m_buffer.Length); this.m_buffer = destinationArray; InfoCardTrace.Assert(this.m_dataLength <= this.m_buffer.Length, "DataLength Corrupt or buffer growth failed."); } private unsafe int GetOffset(ref int id) { if (id <= 0) { if (this.m_dataLength <= 0) this.m_dataLength = 8; int dataLength = this.m_dataLength; id = this.GetNextLocalId(dataLength); return dataLength; } fixed (byte* numPtr = &this.m_masterIndex[0]) { InfoCardTrace.Assert(((int*) numPtr)[id] >= 0, "Master Index offset value is invalid"); return ((int*) numPtr)[id]; } } private unsafe void RemoveFromMasterIndex(int id) { InfoCardTrace.Assert(id > 0, "LocalId is invalid"); fixed (byte* numPtr = &this.m_masterIndex[0]) { *(int*) (numPtr + ((IntPtr) id * 4).ToInt64()) = 0; this.m_freeList.Put(id); } } private unsafe void UpdateMasterIndex(int offset, int diff) { InfoCardTrace.Assert(offset > 0, "Offset is invalid"); InfoCardTrace.Assert(diff != 0, "Difference is invalid"); int num = this.m_masterIndex.Length / 4; fixed (byte* numPtr1 = &this.m_masterIndex[0]) { for (int index = 1; index < num; ++index) { InfoCardTrace.Assert((int*) numPtr1 + index - (int*) numPtr1 <= (long) this.m_masterIndex.Length, "Pointer has walked past the end of the allocated buffer."); if (((int*) numPtr1)[index] > 0 && ((int*) numPtr1)[index] >= offset) { int* numPtr2 = (int*) numPtr1 + index; *numPtr2 = *numPtr2 + diff; } } } } private unsafe int GetNextLocalId(int offset) { InfoCardTrace.Assert(offset >= 0, "The offset can not be negative."); int next = this.m_freeList.GetNext(); if (next > 0) { InfoCardTrace.Assert(null != this.m_masterIndex, "m_masterIndex must not be null by now"); InfoCardTrace.Assert(this.m_masterIndex.Length > 0, "m_masterIndex must not be empty."); fixed (byte* numPtr = &this.m_masterIndex[0]) { *(int*) (numPtr + ((IntPtr) next * 4).ToInt64()) = offset; return next; } } else { int nextLocalId = this.m_masterIndex.Length / 4; this.GrowMasterIndex(); InfoCardTrace.Assert(this.m_masterIndex.Length / 4 > nextLocalId && nextLocalId > 0, "Calculated count is corrupt or invalid."); fixed (byte* numPtr = &this.m_masterIndex[0]) *(int*) (numPtr + ((IntPtr) nextLocalId * 4).ToInt64()) = offset; return nextLocalId; } } public void ThrowIfNotOpen() { if (!this.m_isOpen) throw InfoCardTrace.ThrowHelperError((Exception) new ObjectDisposedException(nameof (IndexedDataBuffer))); } } }