mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
335 lines
13 KiB
C#
335 lines
13 KiB
C#
|
// Decompiled with JetBrains decompiler
|
|||
|
// Type: Microsoft.InfoCards.SecondaryIndex
|
|||
|
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
|
|||
|
// MVID: 516D8B44-4448-4D2C-8B8E-FFBB3FFE472B
|
|||
|
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\Virus.Win32.Expiro.w-69bb73081eac86b8cf86f45e33515d0095855636967076e2b593d7a30cd80a07.exe
|
|||
|
|
|||
|
using Microsoft.InfoCards.Diagnostics;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace Microsoft.InfoCards
|
|||
|
{
|
|||
|
internal class SecondaryIndex
|
|||
|
{
|
|||
|
private byte[] m_buffer;
|
|||
|
private int m_lastIndex;
|
|||
|
private IComparer<IntPtr> m_searchComparer;
|
|||
|
private IComparer<IntPtr> m_sortComparer;
|
|||
|
private SecondaryIndexDefinition m_definition;
|
|||
|
private bool m_isOpen;
|
|||
|
|
|||
|
public SecondaryIndex(
|
|||
|
SecondaryIndexDefinition definition,
|
|||
|
IComparer<IntPtr> search,
|
|||
|
IComparer<IntPtr> sort)
|
|||
|
{
|
|||
|
if (definition == null)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (definition));
|
|||
|
if (search == null)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (search));
|
|||
|
if (sort == null)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (sort));
|
|||
|
this.m_definition = definition;
|
|||
|
this.m_searchComparer = search;
|
|||
|
this.m_sortComparer = sort;
|
|||
|
this.Clear();
|
|||
|
this.m_isOpen = true;
|
|||
|
}
|
|||
|
|
|||
|
public SecondaryIndexDefinition Definition
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_definition;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public int LastIndex
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_lastIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public byte[] GetBuffer()
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
return this.m_buffer;
|
|||
|
}
|
|||
|
|
|||
|
internal void SetValuesForId(int id, DataRowIndexBuffer indexBuffer, bool remove)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id <= 0)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
IndexObject[] array = indexBuffer[this.m_definition.Name].ToArray();
|
|||
|
if (remove)
|
|||
|
this.RemoveForIdAndShiftData(id);
|
|||
|
if (array == null || array.Length == 0)
|
|||
|
return;
|
|||
|
for (int index = 0; index < array.Length; ++index)
|
|||
|
{
|
|||
|
if (!array[index].IsCompiled)
|
|||
|
{
|
|||
|
if (!array[index].CanCompile)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException(SR.GetString("StoreIndexObjectCanNotBeCompiled")));
|
|||
|
array[index].Compile(this.m_definition);
|
|||
|
}
|
|||
|
this.ValidateIndexValue(array[index].CompiledForm);
|
|||
|
this.ShiftAndInsertValues(id, array[index].CompiledForm);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void RemoveAllValuesForId(int id)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id <= 0)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
this.RemoveForIdAndShiftData(id);
|
|||
|
}
|
|||
|
|
|||
|
public unsafe void PopulateRowIndexBuffer(DataRowIndexBuffer buffer, int id)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
if (id <= 0)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (id), SR.GetString("StoreLocalIdOutOfRange")));
|
|||
|
if (-1 == this.m_lastIndex)
|
|||
|
return;
|
|||
|
List<IndexObject> indexObjectList = new List<IndexObject>();
|
|||
|
fixed (byte* numPtr = &this.m_buffer[0])
|
|||
|
{
|
|||
|
for (int index = 0; index < this.m_lastIndex + 1; ++index)
|
|||
|
{
|
|||
|
if (((SecondaryIndexItem*) numPtr)[index].LocalId == id)
|
|||
|
{
|
|||
|
byte[] numArray = new byte[60];
|
|||
|
Marshal.Copy((IntPtr) (void*) &((SecondaryIndexItem*) numPtr)[index].HashValue, numArray, 0, 60);
|
|||
|
indexObjectList.Add(new IndexObject(numArray));
|
|||
|
}
|
|||
|
}
|
|||
|
if (indexObjectList.Count > 0)
|
|||
|
buffer.SetIndexValues(this.m_definition.Name, indexObjectList.ToArray());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Close()
|
|||
|
{
|
|||
|
if (!this.m_isOpen)
|
|||
|
return;
|
|||
|
this.Clear();
|
|||
|
this.m_buffer = (byte[]) null;
|
|||
|
this.m_isOpen = false;
|
|||
|
}
|
|||
|
|
|||
|
public void ValidateIndexValue(byte[] indexValue)
|
|||
|
{
|
|||
|
if (SecondaryIndexSettings.Nullable != (this.m_definition.Settings & SecondaryIndexSettings.Nullable) && SecondaryIndex.IsBufferEmpty(indexValue))
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException(SR.GetString("StoreNullIndexValueNotPermitted", (object) this.m_definition.Name)));
|
|||
|
}
|
|||
|
|
|||
|
public void SetBuffer(byte[] buffer, int lastIndex)
|
|||
|
{
|
|||
|
this.ThrowIfNotOpen();
|
|||
|
this.m_buffer = buffer;
|
|||
|
this.m_lastIndex = lastIndex;
|
|||
|
}
|
|||
|
|
|||
|
public unsafe int Match(IndexObject obj, LocalIdCollection collection, int low, int high)
|
|||
|
{
|
|||
|
if (obj == null)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (obj));
|
|||
|
if (collection == null)
|
|||
|
throw InfoCardTrace.ThrowHelperArgumentNull(nameof (collection));
|
|||
|
if ((uint) low > (uint) high)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (low), (object) low, SR.GetString("StoreLowValueOutOfRange")));
|
|||
|
if ((uint) high > (uint) this.m_lastIndex)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ArgumentOutOfRangeException(nameof (high), (object) high, SR.GetString("StoreHighValueOutOfRange")));
|
|||
|
if (!obj.IsCompiled)
|
|||
|
{
|
|||
|
if (!obj.CanCompile)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException(SR.GetString("StoreIndexObjectCanNotBeCompiled")));
|
|||
|
obj.Compile(this.m_definition);
|
|||
|
}
|
|||
|
this.ValidateIndexValue(obj.CompiledForm);
|
|||
|
SecondaryIndexItem secondaryIndexItem;
|
|||
|
Marshal.Copy(obj.CompiledForm, 0, (IntPtr) (void*) &secondaryIndexItem.HashValue, 60);
|
|||
|
return this.Match(&secondaryIndexItem, collection, low, high);
|
|||
|
}
|
|||
|
|
|||
|
public void Clear()
|
|||
|
{
|
|||
|
this.m_buffer = new byte[sizeof (SecondaryIndexItem) * this.m_definition.InitialSize];
|
|||
|
this.m_lastIndex = -1;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void RemoveForIdAndShiftData(int id)
|
|||
|
{
|
|||
|
if (-1 == this.m_lastIndex)
|
|||
|
return;
|
|||
|
int num1 = this.m_lastIndex + 1;
|
|||
|
int num2 = 0;
|
|||
|
int index = 0;
|
|||
|
fixed (byte* numPtr = &this.m_buffer[0])
|
|||
|
{
|
|||
|
do
|
|||
|
{
|
|||
|
InfoCardTrace.Assert((uint) num2 < (uint) this.m_buffer.Length, "currentOffset is invalid or has been corrupted.");
|
|||
|
InfoCardTrace.Assert(0 == num2 % sizeof (SecondaryIndexItem), "currentOffset is not aligned proppertly. This can cause data corruption.");
|
|||
|
InfoCardTrace.Assert((SecondaryIndexItem*) numPtr + index - (SecondaryIndexItem*) numPtr <= (long) (num1 * sizeof (SecondaryIndexItem)), "Current IndexPointer has walked beyond the total count of valid data.");
|
|||
|
index = num2 / sizeof (SecondaryIndexItem);
|
|||
|
InfoCardTrace.Assert((SecondaryIndexItem*) numPtr + index - (SecondaryIndexItem*) numPtr < (long) this.m_buffer.Length, "Current IndexPointer has walked beyond the allocated buffer");
|
|||
|
if (((SecondaryIndexItem*) numPtr)[index].LocalId == id)
|
|||
|
{
|
|||
|
if (num1 != index + 1)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(this.m_lastIndex >= 0, "LastIndex indicates an invalid state for the index");
|
|||
|
Array.Copy((Array) this.m_buffer, num2 + sizeof (SecondaryIndexItem), (Array) this.m_buffer, num2, (num1 - (index + 1)) * sizeof (SecondaryIndexItem));
|
|||
|
Array.Clear((Array) this.m_buffer, this.m_lastIndex * sizeof (SecondaryIndexItem), sizeof (SecondaryIndexItem));
|
|||
|
}
|
|||
|
else
|
|||
|
Array.Clear((Array) this.m_buffer, num2, sizeof (SecondaryIndexItem));
|
|||
|
--this.m_lastIndex;
|
|||
|
--num1;
|
|||
|
}
|
|||
|
else
|
|||
|
num2 += sizeof (SecondaryIndexItem);
|
|||
|
}
|
|||
|
while (num2 / sizeof (SecondaryIndexItem) < num1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void ShiftAndInsertValues(int id, byte[] indexValue)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(id > 0, "Invalid LocalId");
|
|||
|
InfoCardTrace.Assert(null != indexValue, "Null indev value passed");
|
|||
|
InfoCardTrace.Assert(indexValue.Length == 60, "Index buffer is not correct size.");
|
|||
|
SecondaryIndexItem secondaryIndexItem;
|
|||
|
secondaryIndexItem.LocalId = id;
|
|||
|
Marshal.Copy(indexValue, 0, (IntPtr) (void*) &secondaryIndexItem.HashValue, 60);
|
|||
|
this.AddItem(&secondaryIndexItem);
|
|||
|
}
|
|||
|
|
|||
|
private static bool IsBufferEmpty(byte[] hash)
|
|||
|
{
|
|||
|
for (int index = 0; index < hash.Length; ++index)
|
|||
|
{
|
|||
|
if (hash[index] != (byte) 0)
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int BSearch(
|
|||
|
SecondaryIndexItem* pMatch,
|
|||
|
IComparer<IntPtr> comp,
|
|||
|
int lowStart,
|
|||
|
int highStart)
|
|||
|
{
|
|||
|
int num1 = lowStart;
|
|||
|
int num2 = highStart;
|
|||
|
fixed (byte* numPtr = &this.m_buffer[0])
|
|||
|
{
|
|||
|
while (num1 <= num2)
|
|||
|
{
|
|||
|
int num3 = (num2 + num1) / 2;
|
|||
|
int num4 = comp.Compare((IntPtr) (void*) pMatch, (IntPtr) (void*) ((SecondaryIndexItem*) numPtr + num3));
|
|||
|
if (num4 == 0)
|
|||
|
{
|
|||
|
num2 = num3;
|
|||
|
if (num2 == num1)
|
|||
|
return num2;
|
|||
|
}
|
|||
|
else if (num4 < 0)
|
|||
|
num2 = num3 - 1;
|
|||
|
else
|
|||
|
num1 = num3 + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
return ~num1;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe int Match(
|
|||
|
SecondaryIndexItem* pMatch,
|
|||
|
LocalIdCollection results,
|
|||
|
int lowStart,
|
|||
|
int highStart)
|
|||
|
{
|
|||
|
int index = this.BSearch(pMatch, this.m_searchComparer, lowStart, highStart);
|
|||
|
if (index >= 0)
|
|||
|
{
|
|||
|
fixed (byte* numPtr = &this.m_buffer[0])
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(index * sizeof (SecondaryIndexItem) < this.m_buffer.Length, "Index has moved beyond the allocated buffer.");
|
|||
|
do
|
|||
|
{
|
|||
|
results.Add(((SecondaryIndexItem*) numPtr)[index].LocalId);
|
|||
|
++index;
|
|||
|
}
|
|||
|
while (index <= this.m_lastIndex && this.m_searchComparer.Compare((IntPtr) (void*) ((SecondaryIndexItem*) numPtr + index), (IntPtr) (void*) pMatch) == 0);
|
|||
|
}
|
|||
|
--index;
|
|||
|
}
|
|||
|
return index;
|
|||
|
}
|
|||
|
|
|||
|
private unsafe void AddItem(SecondaryIndexItem* pMatch)
|
|||
|
{
|
|||
|
InfoCardTrace.Assert(IntPtr.Zero != (IntPtr) pMatch, "Match pointer is null");
|
|||
|
InfoCardTrace.Assert(pMatch->LocalId > 0, "Match pointer has invalid local id");
|
|||
|
int num1;
|
|||
|
if (SecondaryIndexSettings.Unique == (this.m_definition.Settings & SecondaryIndexSettings.Unique))
|
|||
|
{
|
|||
|
num1 = this.BSearch(pMatch, this.m_searchComparer, 0, this.m_lastIndex);
|
|||
|
if (num1 >= 0)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException(SR.GetString("StoreUniqueIndexConstraintBroken", (object) this.m_definition.Name)));
|
|||
|
}
|
|||
|
else
|
|||
|
num1 = this.BSearch(pMatch, this.m_sortComparer, 0, this.m_lastIndex);
|
|||
|
if (num1 >= 0)
|
|||
|
return;
|
|||
|
int index = ~num1;
|
|||
|
int num2 = this.m_lastIndex + 1;
|
|||
|
int num3 = this.m_buffer.Length / sizeof (SecondaryIndexItem);
|
|||
|
if (num2 + 1 >= num3)
|
|||
|
this.GrowIndex();
|
|||
|
if (index < num2)
|
|||
|
{
|
|||
|
int num4 = num2 * sizeof (SecondaryIndexItem);
|
|||
|
int sourceIndex = index * sizeof (SecondaryIndexItem);
|
|||
|
int destinationIndex = sourceIndex + sizeof (SecondaryIndexItem);
|
|||
|
int length = num4 - sourceIndex;
|
|||
|
InfoCardTrace.Assert(length > 0, "No Bytes to copy into index.");
|
|||
|
Array.Copy((Array) this.m_buffer, sourceIndex, (Array) this.m_buffer, destinationIndex, length);
|
|||
|
}
|
|||
|
fixed (byte* numPtr = &this.m_buffer[0])
|
|||
|
{
|
|||
|
InfoCardTrace.Assert((SecondaryIndexItem*) numPtr + index - (SecondaryIndexItem*) numPtr < (long) this.m_buffer.Length, "IndexPointer is beyond the end of the allocated buffer");
|
|||
|
((SecondaryIndexItem*) numPtr)[index] = *pMatch;
|
|||
|
}
|
|||
|
++this.m_lastIndex;
|
|||
|
}
|
|||
|
|
|||
|
private void GrowIndex()
|
|||
|
{
|
|||
|
int increaseByPercent = Utility.CalculateIncreaseByPercent(this.m_buffer.Length, sizeof (SecondaryIndexItem), 5);
|
|||
|
InfoCardTrace.Assert(increaseByPercent > this.m_buffer.Length && 0 == increaseByPercent % sizeof (SecondaryIndexItem), "New size calculated for index is invalid.");
|
|||
|
int length = (this.m_lastIndex + 1) * sizeof (SecondaryIndexItem);
|
|||
|
byte[] destinationArray = new byte[increaseByPercent];
|
|||
|
Array.Copy((Array) this.m_buffer, 0, (Array) destinationArray, 0, length);
|
|||
|
Array.Clear((Array) this.m_buffer, 0, length);
|
|||
|
this.m_buffer = destinationArray;
|
|||
|
}
|
|||
|
|
|||
|
private void ThrowIfNotOpen()
|
|||
|
{
|
|||
|
if (!this.m_isOpen)
|
|||
|
throw InfoCardTrace.ThrowHelperError((Exception) new ObjectDisposedException(nameof (SecondaryIndex)));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|