Exemplo n.º 1
0
void
Test_RtlSetAllBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;
    ULONG BufferSize = 2 * sizeof(*Buffer);

    Buffer = AllocateGuarded(BufferSize);
    RtlInitializeBitMap(&BitMapHeader, Buffer, 19);
    memset(Buffer, 0xcc, BufferSize);
    RtlSetAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0xffffffff);
    ok_hex(Buffer[1], 0xcccccccc);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    memset(Buffer, 0xcc, BufferSize);
    RtlSetAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0xcccccccc);
    ok_hex(Buffer[1], 0xcccccccc);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    memset(Buffer, 0xcc, BufferSize);
    RtlSetAllBits(&BitMapHeader);
    ok_hex(Buffer[0], 0xffffffff);
    ok_hex(Buffer[1], 0xffffffff);
    FreeGuarded(Buffer);
}
Exemplo n.º 2
0
// Build IO bitmaps
_Use_decl_annotations_ static UCHAR *VmpBuildIoBitmaps() {
  PAGED_CODE();

  // Allocate two IO bitmaps as one contiguous 4K+4K page
  const auto io_bitmaps = reinterpret_cast<UCHAR *>(ExAllocatePoolWithTag(
      NonPagedPool, PAGE_SIZE * 2, kHyperPlatformCommonPoolTag));
  if (!io_bitmaps) {
    return nullptr;
  }

  const auto io_bitmap_a = io_bitmaps;              // for    0x0 - 0x7fff
  const auto io_bitmap_b = io_bitmaps + PAGE_SIZE;  // for 0x8000 - 0xffff
  RtlFillMemory(io_bitmap_a, PAGE_SIZE, 0);
  RtlFillMemory(io_bitmap_b, PAGE_SIZE, 0);

  // Activate VM-exit for IO port 0x10 - 0x2010 as an example
  RTL_BITMAP bitmap_a_header = {};
  RtlInitializeBitMap(&bitmap_a_header, reinterpret_cast<PULONG>(io_bitmap_a),
                      PAGE_SIZE * CHAR_BIT);
  // RtlSetBits(&bitmap_a_header, 0x10, 0x2000);

  RTL_BITMAP bitmap_b_header = {};
  RtlInitializeBitMap(&bitmap_b_header, reinterpret_cast<PULONG>(io_bitmap_b),
                      PAGE_SIZE * CHAR_BIT);
  // RtlSetBits(&bitmap_b_header, 0, 0x8000);
  return io_bitmaps;
}
Exemplo n.º 3
0
// Initialize shared processor data
_Use_decl_annotations_ static SharedProcessorData *VmpInitializeSharedData() {
  PAGED_CODE();

  const auto shared_data = reinterpret_cast<SharedProcessorData *>(
      ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(SharedProcessorData),
                            kHyperPlatformCommonPoolTag));
  if (!shared_data) {
    return nullptr;
  }
  RtlZeroMemory(shared_data, sizeof(SharedProcessorData));
  HYPERPLATFORM_LOG_DEBUG("SharedData=        %p", shared_data);

  // Set up the MSR bitmap
  const auto msr_bitmap = ExAllocatePoolWithTag(NonPagedPoolNx, PAGE_SIZE,
                                                kHyperPlatformCommonPoolTag);
  if (!msr_bitmap) {
    ExFreePoolWithTag(shared_data, kHyperPlatformCommonPoolTag);
    return nullptr;
  }
  RtlZeroMemory(msr_bitmap, PAGE_SIZE);
  shared_data->msr_bitmap = msr_bitmap;

  // Checks MSRs causing #GP and should not cause VM-exit from 0 to 0xfff.
  bool unsafe_msr_map[0x1000] = {};
  for (auto msr = 0ul; msr < RTL_NUMBER_OF(unsafe_msr_map); ++msr) {
    __try {
      UtilReadMsr(static_cast<Msr>(msr));
    } __except (EXCEPTION_EXECUTE_HANDLER) {
      unsafe_msr_map[msr] = true;
    }
  }

  // Activate VM-exit for RDMSR against all MSRs
  const auto bitmap_read_low = reinterpret_cast<UCHAR *>(msr_bitmap);
  const auto bitmap_read_high = bitmap_read_low + 1024;
  RtlFillMemory(bitmap_read_low, 1024, 0xff);   // read        0 -     1fff
  RtlFillMemory(bitmap_read_high, 1024, 0xff);  // read c0000000 - c0001fff

  // But ignore IA32_MPERF (000000e7) and IA32_APERF (000000e8)
  RTL_BITMAP bitmap_read_low_header = {};
  RtlInitializeBitMap(&bitmap_read_low_header,
                      reinterpret_cast<PULONG>(bitmap_read_low), 1024 * 8);
  RtlClearBits(&bitmap_read_low_header, 0xe7, 2);

  // Also ignore the unsage MSRs
  for (auto msr = 0ul; msr < RTL_NUMBER_OF(unsafe_msr_map); ++msr) {
    const auto ignore = unsafe_msr_map[msr];
    if (ignore) {
      RtlClearBits(&bitmap_read_low_header, msr, 1);
    }
  }

  // But ignore IA32_GS_BASE (c0000101) and IA32_KERNEL_GS_BASE (c0000102)
  RTL_BITMAP bitmap_read_high_header = {};
  RtlInitializeBitMap(&bitmap_read_high_header,
                      reinterpret_cast<PULONG>(bitmap_read_high), 1024 * 8);
  RtlClearBits(&bitmap_read_high_header, 0x101, 2);

  return shared_data;
}
Exemplo n.º 4
0
Arquivo: ksm.c Projeto: HideSand/ksm
static NTSTATUS init_msr_bitmap(struct ksm *k)
{
	void *msr_bitmap = ExAllocatePool(NonPagedPoolNx, PAGE_SIZE);
	if (!msr_bitmap)
		return STATUS_NO_MEMORY;

	k->msr_bitmap = msr_bitmap;
	RtlZeroMemory(msr_bitmap, PAGE_SIZE);

	/* For all MSRs...  */
	u8 *bitmap_read_lo = (u8 *)msr_bitmap;
	u8 *bitmap_read_hi = bitmap_read_lo + 1024;
	memset(bitmap_read_lo, 0xff, 1024);		// 0 -> 1fff
	memset(bitmap_read_hi, 0xff, 1024);		// c0000000 - c0001fff

	/* ... ignore MSR_IA32_MPERF and MSR_IA32_APERF  */
	RTL_BITMAP bitmap_read_lo_hdr;
	RtlInitializeBitMap(&bitmap_read_lo_hdr, (PULONG)bitmap_read_lo, 1024 * CHAR_BIT);
	RtlClearBits(&bitmap_read_lo_hdr, MSR_IA32_MPERF, 2);

	for (u32 msr = 0; msr < PAGE_SIZE; ++msr) {
		__try {
			__readmsr(msr);
		} __except (EXCEPTION_EXECUTE_HANDLER)
		{
			RtlClearBits(&bitmap_read_lo_hdr, msr, 1);
		}
	}

	/* ... and ignore MSR_IA32_GS_BASE and MSR_IA32_KERNEL_GS_BASE  */
	RTL_BITMAP bitmap_read_hi_hdr;
	RtlInitializeBitMap(&bitmap_read_hi_hdr, (PULONG)bitmap_read_hi, 1024 * CHAR_BIT);
	RtlClearBits(&bitmap_read_hi_hdr, 0x101, 2);
	return STATUS_SUCCESS;
}
Exemplo n.º 5
0
void
Test_RtlInitializeBitMap(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG Buffer[2];
    BOOLEAN Exception = FALSE;

    _SEH2_TRY
    {
        RtlInitializeBitMap(NULL, NULL, 0);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Exception = TRUE;
    }
    _SEH2_END;
    ok_int(Exception, 1);

    memset(Buffer, 0xcc, sizeof(Buffer));
    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(BitMapHeader.SizeOfBitMap, 0);
    ok_ptr(BitMapHeader.Buffer, Buffer);
    ok_hex(Buffer[0], 0xcccccccc);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(BitMapHeader.SizeOfBitMap, 8);
    ok_hex(Buffer[0], 0xcccccccc);
}
Exemplo n.º 6
0
void Test_RtlInitializeBitmap()
{
    RTL_BITMAP Bitmap;
    ULONG Buffer[5];

    Buffer[0] = 0x12345;
    Buffer[1] = 0x23456;
    Buffer[2] = 0x34567;
    Buffer[3] = 0x45678;
    Buffer[4] = 0x56789;

    RtlInitializeBitMap(&Bitmap, Buffer, 19);
    ok(Bitmap.Buffer == Buffer, "Buffer=%p\n", Bitmap.Buffer);
    ok(Bitmap.SizeOfBitMap == 19, "SizeOfBitMap=%ld\n", Bitmap.SizeOfBitMap);

    ok(Buffer[0] == 0x12345, "Buffer[0] == 0x%lx\n", Buffer[0]);
    ok(Buffer[1] == 0x23456, "Buffer[1] == 0x%lx\n", Buffer[1]);
    ok(Buffer[2] == 0x34567, "Buffer[2] == 0x%lx\n", Buffer[2]);
    ok(Buffer[3] == 0x45678, "Buffer[3] == 0x%lx\n", Buffer[3]);
    ok(Buffer[4] == 0x56789, "Buffer[4] == 0x%lx\n", Buffer[4]);

    RtlInitializeBitMap(&Bitmap, 0, -100);
    ok(Bitmap.Buffer == 0, "Buffer=%p\n", Bitmap.Buffer);
    ok(Bitmap.SizeOfBitMap == -100, "SizeOfBitMap=%ld\n", Bitmap.SizeOfBitMap);

}
Exemplo n.º 7
0
void
Test_RtlNumberOfClearBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0xff00fff0;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlNumberOfClearBits(&BitMapHeader), 0);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 4);
    ok_int(RtlNumberOfClearBits(&BitMapHeader), 4);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 31);
    ok_int(RtlNumberOfClearBits(&BitMapHeader), 12);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 56);
    ok_int(RtlNumberOfClearBits(&BitMapHeader), 26);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    ok_int(RtlNumberOfClearBits(&BitMapHeader), 28);
    FreeGuarded(Buffer);
}
Exemplo n.º 8
0
void
Test_RtlFindNextForwardRunClear(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;
    ULONG Index;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0xF9F078B2;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 0, &Index), 0);
    ok_int(Index, 0);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 1, &Index), 0);
    ok_int(Index, 1);

    Index = -1;
    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 0, &Index), 1);
    ok_int(Index, 0);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 1, &Index), 2);
    ok_int(Index, 2);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 7, &Index), 0);
    ok_int(Index, 8);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 17, &Index), 0);
    ok_int(Index, 17);
    ok_int(RtlFindNextForwardRunClear(&BitMapHeader, 39, &Index), 0);
    ok_int(Index, 39);
    FreeGuarded(Buffer);
}
Exemplo n.º 9
0
void
Test_RtlAreBitsSet(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    RtlInitializeBitMap(&BitMapHeader, Buffer, 19);
    Buffer[0] = 0xff00ff00;
    Buffer[1] = 0x3F303F30;

    ok_hex(RtlAreBitsSet(&BitMapHeader, 0, 8), FALSE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 8, 8), TRUE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 7, 8), FALSE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 8, 9), FALSE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 24, 1), FALSE);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 31);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 24, 1), TRUE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 24, 7), TRUE);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 24, 8), FALSE);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    ok_hex(RtlAreBitsSet(&BitMapHeader, 60, 4), FALSE);
    FreeGuarded(Buffer);
}
Exemplo n.º 10
0
void
Test_RtlFindClearBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0x060F874D;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 0), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 0), -1);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 1), -1);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 0), 1);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 1), 1);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 2), 4);

    ok_int(RtlFindClearBits(&BitMapHeader, 2, 0), 4);
    ok_int(RtlFindClearBits(&BitMapHeader, 3, 0), -1);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 32);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 21), 16);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 12), 8);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 31), 24);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 32), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 0, 39), 0);
    ok_int(RtlFindClearBits(&BitMapHeader, 4, 0), 11);
    ok_int(RtlFindClearBits(&BitMapHeader, 5, 0), 20);
    ok_int(RtlFindClearBits(&BitMapHeader, 4, 11), 11);
    ok_int(RtlFindClearBits(&BitMapHeader, 4, 12), 20);
    ok_int(RtlFindClearBits(&BitMapHeader, 2, 11), 11);
    ok_int(RtlFindClearBits(&BitMapHeader, 2, 12), 12);
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 32), 1);
    ok_int(RtlFindClearBits(&BitMapHeader, 4, 32), 11);
    ok_int(RtlFindClearBits(&BitMapHeader, 5, 32), 20);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    ok_int(RtlFindClearBits(&BitMapHeader, 5, 64), 20);
    ok_int(RtlFindClearBits(&BitMapHeader, 9, 28), 27);
    ok_int(RtlFindClearBits(&BitMapHeader, 10, 0), -1);
    Buffer[1] = 0xFF303F30;
    ok_int(RtlFindClearBits(&BitMapHeader, 1, 56), 1);
    FreeGuarded(Buffer);
}
Exemplo n.º 11
0
void
Test_RtlFindSetBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0xF9F078B2;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 0), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 0), -1);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 1), -1);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 0), 1);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 1), 1);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 2), 4);

    ok_int(RtlFindSetBits(&BitMapHeader, 2, 0), 4);
    ok_int(RtlFindSetBits(&BitMapHeader, 3, 0), -1);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 32);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 21), 16);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 12), 8);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 31), 24);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 32), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 0, 39), 0);
    ok_int(RtlFindSetBits(&BitMapHeader, 4, 0), 11);
    ok_int(RtlFindSetBits(&BitMapHeader, 5, 0), 20);
    ok_int(RtlFindSetBits(&BitMapHeader, 4, 11), 11);
    ok_int(RtlFindSetBits(&BitMapHeader, 4, 12), 20);
    ok_int(RtlFindSetBits(&BitMapHeader, 2, 11), 11);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 32), 1);
    ok_int(RtlFindSetBits(&BitMapHeader, 4, 32), 11);
    ok_int(RtlFindSetBits(&BitMapHeader, 5, 32), 20);

    RtlInitializeBitMap(&BitMapHeader, Buffer, 64);
    ok_int(RtlFindSetBits(&BitMapHeader, 5, 64), 20);
    ok_int(RtlFindSetBits(&BitMapHeader, 6, 57), 40);
    ok_int(RtlFindSetBits(&BitMapHeader, 7, 0), -1);
    ok_int(RtlFindSetBits(&BitMapHeader, 1, 62), 1);
    FreeGuarded(Buffer);
}
Exemplo n.º 12
0
INIT_FUNCTION
NTSTATUS
NTAPI
InitTimerImpl(VOID)
{
   ULONG BitmapBytes;

   ExInitializeFastMutex(&Mutex);

   BitmapBytes = ROUND_UP(NUM_WINDOW_LESS_TIMERS, sizeof(ULONG) * 8) / 8;
   WindowLessTimersBitMapBuffer = ExAllocatePoolWithTag(NonPagedPool, BitmapBytes, TAG_TIMERBMP);
   if (WindowLessTimersBitMapBuffer == NULL)
   {
      return STATUS_UNSUCCESSFUL;
   }

   RtlInitializeBitMap(&WindowLessTimersBitMap,
                       WindowLessTimersBitMapBuffer,
                       BitmapBytes * 8);

   /* yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
   RtlClearAllBits(&WindowLessTimersBitMap);

   ExInitializeResourceLite(&TimerLock);
   InitializeListHead(&TimersListHead);

   return STATUS_SUCCESS;
}
Exemplo n.º 13
0
void
Test_RtlFindSetBitsAndClear(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0xF9F078B2;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 0, 0), 0);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 1, 0), -1);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 1, 1), -1);
    ok_hex(Buffer[0], 0xF9F078B2);

    Buffer[0] = 0xF9F078B2;
    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 1, 0), 1);
    ok_hex(Buffer[0], 0xf9f078b0);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 1, 1), 4);
    ok_hex(Buffer[0], 0xf9f078a0);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 1, 2), 5);
    ok_hex(Buffer[0], 0xf9f07880);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 2, 0), -1);
    ok_hex(Buffer[0], 0xf9f07880);

    Buffer[0] = 0xF9F078B2;
    RtlInitializeBitMap(&BitMapHeader, Buffer, 32);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 4, 0), 11);
    ok_hex(Buffer[0], 0xf9f000b2);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 5, 0), 20);
    ok_hex(Buffer[0], 0xf80000b2);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 4, 11), 27);
    ok_hex(Buffer[0], 0x800000b2);

    Buffer[0] = 0xF9F078B2;
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 4, 12), 20);
    ok_hex(Buffer[0], 0xf90078b2);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 2, 11), 11);
    ok_hex(Buffer[0], 0xf90060b2);
    ok_int(RtlFindSetBitsAndClear(&BitMapHeader, 2, 12), 13);
    ok_hex(Buffer[0], 0xf90000b2);
    FreeGuarded(Buffer);
}
Exemplo n.º 14
0
void
Test_RtlFindClearBitsAndSet(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;

    Buffer = AllocateGuarded(2 * sizeof(*Buffer));
    Buffer[0] = 0x060F874D;
    Buffer[1] = 0x3F303F30;

    RtlInitializeBitMap(&BitMapHeader, Buffer, 0);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 0, 0), 0);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 0, 3), 0);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 1, 0), -1);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 1, 1), -1);
    ok_hex(Buffer[0], 0x060F874D);

    Buffer[0] = 0x060F874D;
    RtlInitializeBitMap(&BitMapHeader, Buffer, 8);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 1, 0), 1);
    ok_hex(Buffer[0], 0x60f874f);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 1, 1), 4);
    ok_hex(Buffer[0], 0x60f875f);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 1, 2), 5);
    ok_hex(Buffer[0], 0x60f877f);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 2, 0), -1);
    ok_hex(Buffer[0], 0x60f877f);

    Buffer[0] = 0x060F874D;
    RtlInitializeBitMap(&BitMapHeader, Buffer, 32);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 4, 0), 11);
    ok_hex(Buffer[0], 0x60fff4d);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 5, 0), 20);
    ok_hex(Buffer[0], 0x7ffff4d);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 4, 11), 27);
    ok_hex(Buffer[0], 0x7fffff4d);

    Buffer[0] = 0x060F874D;
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 4, 12), 20);
    ok_hex(Buffer[0], 0x6ff874d);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 2, 11), 11);
    ok_hex(Buffer[0], 0x6ff9f4d);
    ok_int(RtlFindClearBitsAndSet(&BitMapHeader, 2, 12), 13);
    ok_hex(Buffer[0], 0x6ffff4d);
    FreeGuarded(Buffer);
}
Exemplo n.º 15
0
// Build MSR bitmap
_Use_decl_annotations_ static void *VmpBuildMsrBitmap() {
  PAGED_CODE();

  const auto msr_bitmap = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE,
                                                kHyperPlatformCommonPoolTag);
  if (!msr_bitmap) {
    return nullptr;
  }
  RtlZeroMemory(msr_bitmap, PAGE_SIZE);

  // Activate VM-exit for RDMSR against all MSRs
  const auto bitmap_read_low = reinterpret_cast<UCHAR *>(msr_bitmap);
  const auto bitmap_read_high = bitmap_read_low + 1024;
  RtlFillMemory(bitmap_read_low, 1024, 0xff);   // read        0 -     1fff
  RtlFillMemory(bitmap_read_high, 1024, 0xff);  // read c0000000 - c0001fff

  // Ignore IA32_MPERF (000000e7) and IA32_APERF (000000e8)
  RTL_BITMAP bitmap_read_low_header = {};
  RtlInitializeBitMap(&bitmap_read_low_header,
                      reinterpret_cast<PULONG>(bitmap_read_low), 1024 * 8);
  RtlClearBits(&bitmap_read_low_header, 0xe7, 2);

  // Checks MSRs that cause #GP from 0 to 0xfff, and ignore all of them
  for (auto msr = 0ul; msr < 0x1000; ++msr) {
    __try {
      UtilReadMsr(static_cast<Msr>(msr));
    } __except (EXCEPTION_EXECUTE_HANDLER) {
      RtlClearBits(&bitmap_read_low_header, msr, 1);
    }
  }

  // Ignore IA32_GS_BASE (c0000101) and IA32_KERNEL_GS_BASE (c0000102)
  RTL_BITMAP bitmap_read_high_header = {};
  RtlInitializeBitMap(&bitmap_read_high_header,
                      reinterpret_cast<PULONG>(bitmap_read_high),
                      1024 * CHAR_BIT);
  RtlClearBits(&bitmap_read_high_header, 0x101, 2);

  return msr_bitmap;
}
Exemplo n.º 16
0
void
Test_RtlClearBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;
    ULONG BufferSize = 2 * sizeof(*Buffer);

    Buffer = AllocateGuarded(BufferSize);
    RtlInitializeBitMap(&BitMapHeader, Buffer, 19);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 0, 0);
    ok_hex(Buffer[0], 0xffffffff);
    ok_hex(Buffer[1], 0xffffffff);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 0, 1);
    ok_hex(Buffer[0], 0xfffffffe);
    ok_hex(Buffer[1], 0xffffffff);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 21, 1);
    ok_hex(Buffer[0], 0xffdfffff);
    ok_hex(Buffer[1], 0xffffffff);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 7, 9);
    ok_hex(Buffer[0], 0xffff007f);
    ok_hex(Buffer[1], 0xffffffff);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 13, 22);
    ok_hex(Buffer[0], 0x00001fff);
    ok_hex(Buffer[1], 0xfffffff8);

    memset(Buffer, 0xff, BufferSize);
    RtlClearBits(&BitMapHeader, 63, 1);
    ok_hex(Buffer[0], 0xffffffff);
    ok_hex(Buffer[1], 0x7fffffff);

    memset(Buffer, 0xcc, BufferSize);
    RtlClearBits(&BitMapHeader, 3, 6);
    RtlClearBits(&BitMapHeader, 11, 5);
    RtlClearBits(&BitMapHeader, 21, 7);
    RtlClearBits(&BitMapHeader, 37, 4);
    ok_hex(Buffer[0], 0xc00c0404);
    ok_hex(Buffer[1], 0xcccccc0c);
    FreeGuarded(Buffer);
}
Exemplo n.º 17
0
void
Test_RtlSetBits(void)
{
    RTL_BITMAP BitMapHeader;
    ULONG *Buffer;
    ULONG BufferSize = 2 * sizeof(*Buffer);

    Buffer = AllocateGuarded(BufferSize);
    RtlInitializeBitMap(&BitMapHeader, Buffer, 19);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 0, 0);
    ok_hex(Buffer[0], 0x00000000);
    ok_hex(Buffer[1], 0x00000000);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 0, 1);
    ok_hex(Buffer[0], 0x00000001);
    ok_hex(Buffer[1], 0x00000000);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 21, 1);
    ok_hex(Buffer[0], 0x00200000);
    ok_hex(Buffer[1], 0x00000000);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 7, 9);
    ok_hex(Buffer[0], 0x0000ff80);
    ok_hex(Buffer[1], 0x00000000);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 13, 22);
    ok_hex(Buffer[0], 0xffffe000);
    ok_hex(Buffer[1], 0x00000007);

    memset(Buffer, 0x00, BufferSize);
    RtlSetBits(&BitMapHeader, 63, 1);
    ok_hex(Buffer[0], 0x00000000);
    ok_hex(Buffer[1], 0x80000000);

    memset(Buffer, 0xcc, BufferSize);
    RtlSetBits(&BitMapHeader, 3, 6);
    RtlSetBits(&BitMapHeader, 11, 5);
    RtlSetBits(&BitMapHeader, 21, 7);
    RtlSetBits(&BitMapHeader, 37, 4);
    ok_hex(Buffer[0], 0xcfecfdfc);
    ok_hex(Buffer[1], 0xcccccdec);
    FreeGuarded(Buffer);
}
Exemplo n.º 18
0
VOID XmsInitialize(VOID)
{
    RtlZeroMemory(HandleTable, sizeof(HandleTable));
    RtlZeroMemory(BitmapBuffer, sizeof(BitmapBuffer));
    RtlInitializeBitMap(&AllocBitmap, BitmapBuffer, XMS_BLOCKS);

    Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
                             XMS_DEVICE_NAME,
                             sizeof(EntryProcedure));

    RegisterBop(BOP_XMS, XmsBopProcedure);

    /* Copy the entry routine to the device private area */
    RtlMoveMemory(FAR_POINTER(DEVICE_PRIVATE_AREA(Node->Driver)),
                  EntryProcedure,
                  sizeof(EntryProcedure));
}
Exemplo n.º 19
0
NTSTATUS PortsStartup( PPORT_SET PortSet,
		   UINT StartingPort,
		   UINT PortsToManage ) {
    PortSet->StartingPort = StartingPort;
    PortSet->PortsToOversee = PortsToManage;

    PortSet->ProtoBitBuffer =
	ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
                               PORT_SET_TAG );
    if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
    RtlInitializeBitMap( &PortSet->ProtoBitmap,
			 PortSet->ProtoBitBuffer,
			 PortSet->PortsToOversee );
    RtlClearAllBits( &PortSet->ProtoBitmap );
    KeInitializeSpinLock( &PortSet->Lock );
    return STATUS_SUCCESS;
}
Exemplo n.º 20
0
VOID test_bitmap()
{
	Pool		pool;
	ULONG		Bitmap_Size, Index;
	PULONG		Bitmap_Buffer;

	// Initialize
	Bitmap_Size = 13; // Number of bits
	Bitmap_Buffer = ExAllocatePoolWithTag (
		NonPagedPool,
		(ULONG)(((Bitmap_Size/8+1)/sizeof(ULONG) + 1)* sizeof(ULONG)),
		BITMAP_TAG
	);
	RtlInitializeBitMap(
		&pool.Bitmap, 
		(PULONG)(Bitmap_Buffer),
		(ULONG)(Bitmap_Size)
	);
	RtlClearAllBits(&pool.Bitmap);

	for (Index = 0; Index < 10; Index++)
		RtlSetBit(&pool.Bitmap, Index);
	if (RtlAreBitsSet(&pool.Bitmap, 0, 10) == TRUE)
		DbgPrint("bitmap: bit[0..9] is set\r\n");

	if (RtlCheckBit(&pool.Bitmap, 10))
		DbgPrint("bitmap: bit[10] is set\r\n");
	if (RtlCheckBit(&pool.Bitmap, 1024)) //Warning! Return 1 here
		DbgPrint("bitmap: bit[1024] is set\r\n");

	Index = 0;
	do
	{
		Index = RtlFindClearBitsAndSet (
			&pool.Bitmap,
			1, //NumberToFind
			Index //HintIndex
		);
		DbgPrint("%d\n", Index);
	}while (Index != -1);

	// Free
	ExFreePoolWithTag(pool.Bitmap.Buffer, BITMAP_TAG);
}
Exemplo n.º 21
0
static
PGDI_POOL_SECTION
GdiPoolAllocateSection(PGDI_POOL pPool)
{
    PGDI_POOL_SECTION pSection;
    PVOID pvBaseAddress;
    SIZE_T cjSize;
    NTSTATUS status;

    /* Allocate a section object */
    cjSize = sizeof(GDI_POOL_SECTION) + pPool->cSlotsPerSection / sizeof(ULONG);
    pSection = EngAllocMem(0, cjSize, pPool->ulTag);
    if (!pSection)
    {
        return NULL;
    }

    /* Reserve user mode memory */
    cjSize = GDI_POOL_ALLOCATION_GRANULARITY;
    pvBaseAddress = NULL;
    status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &pvBaseAddress,
                                     0,
                                     &cjSize,
                                     MEM_RESERVE,
                                     PAGE_READWRITE);
    if (!NT_SUCCESS(status))
    {
        EngFreeMem(pSection);
        return NULL;
    }

    /* Initialize the section */
    pSection->pvBaseAddress = pvBaseAddress;
    pSection->ulCommitBitmap = 0;
    pSection->cAllocCount = 0;
    RtlInitializeBitMap(&pSection->bitmap,
                        pSection->aulBits,
                        pPool->cSlotsPerSection);
    RtlClearAllBits(&pSection->bitmap);

    /* Return the section */
    return pSection;
}
Exemplo n.º 22
0
/***********************************************************************
 *           thread_init
 *
 * Setup the initial thread.
 *
 * NOTES: The first allocated TEB on NT is at 0x7ffde000.
 */
HANDLE thread_init(void)
{
    TEB *teb;
    void *addr;
    SIZE_T size, info_size;
    HANDLE exe_file = 0;
    LARGE_INTEGER now;
    NTSTATUS status;
    struct ntdll_thread_data *thread_data;
    static struct debug_info debug_info;  /* debug info for initial thread */

    virtual_init();

    /* reserve space for shared user data */

    addr = (void *)0x7ffe0000;
    size = 0x10000;
    status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
                                      MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
    if (status)
    {
        MESSAGE( "wine: failed to map the shared user data: %08x\n", status );
        exit(1);
    }
    user_shared_data = addr;

    /* allocate and initialize the PEB */

    addr = NULL;
    size = sizeof(*peb);
    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 1, &size,
                             MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
    peb = addr;

    peb->ProcessParameters  = &params;
    peb->TlsBitmap          = &tls_bitmap;
    peb->TlsExpansionBitmap = &tls_expansion_bitmap;
    peb->FlsBitmap          = &fls_bitmap;
    peb->LdrData            = &ldr;
    params.CurrentDirectory.DosPath.Buffer = current_dir;
    params.CurrentDirectory.DosPath.MaximumLength = sizeof(current_dir);
    params.wShowWindow = 1; /* SW_SHOWNORMAL */
    ldr.Length = sizeof(ldr);
    RtlInitializeBitMap( &tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8 );
    RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
                         sizeof(peb->TlsExpansionBitmapBits) * 8 );
    RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 );
    InitializeListHead( &peb->FlsListHead );
    InitializeListHead( &ldr.InLoadOrderModuleList );
    InitializeListHead( &ldr.InMemoryOrderModuleList );
    InitializeListHead( &ldr.InInitializationOrderModuleList );
#ifdef __APPLE__
    peb->Reserved[0] = get_dyld_image_info_addr();
#endif

    /* allocate and initialize the initial TEB */

    signal_alloc_thread( &teb );
    teb->Peb = peb;
    teb->Tib.StackBase = (void *)~0UL;
    teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
    teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);

    thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
    thread_data->request_fd = -1;
    thread_data->reply_fd   = -1;
    thread_data->wait_fd[0] = -1;
    thread_data->wait_fd[1] = -1;
    thread_data->debug_info = &debug_info;
    InsertHeadList( &tls_links, &teb->TlsLinks );

    signal_init_thread( teb );
    virtual_init_threading();

    debug_info.str_pos = debug_info.strings;
    debug_info.out_pos = debug_info.output;
    debug_init();

    /* setup the server connection */
    server_init_process();
    info_size = server_init_thread( peb );

    /* create the process heap */
    if (!(peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL )))
    {
        MESSAGE( "wine: failed to create the process heap\n" );
        exit(1);
    }

    /* allocate user parameters */
    if (info_size)
    {
        init_user_process_params( info_size, &exe_file );
    }
    else
    {
        if (isatty(0) || isatty(1) || isatty(2))
            params.ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */
        if (!isatty(0))
            wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE,  OBJ_INHERIT, &params.hStdInput );
        if (!isatty(1))
            wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdOutput );
        if (!isatty(2))
            wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdError );
    }

    /* initialize time values in user_shared_data */
    NtQuerySystemTime( &now );
    user_shared_data->SystemTime.LowPart = now.u.LowPart;
    user_shared_data->SystemTime.High1Time = user_shared_data->SystemTime.High2Time = now.u.HighPart;
    user_shared_data->u.TickCountQuad = (now.QuadPart - server_start_time) / 10000;
    user_shared_data->u.TickCount.High2Time = user_shared_data->u.TickCount.High1Time;
    user_shared_data->TickCountLowDeprecated = user_shared_data->u.TickCount.LowPart;
    user_shared_data->TickCountMultiplier = 1 << 24;

    fill_cpu_info();

    NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );

    return exe_file;
}
Exemplo n.º 23
0
/******************************************************************
 *              macho_map_file
 *
 * Maps a Mach-O file into memory (and checks it's a real Mach-O file)
 */
static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap)
{
    struct fat_header   fat_header;
    struct stat         statbuf;
    int                 i;
    char*               filename;
    unsigned            len;
    BOOL                ret = FALSE;

    TRACE("(%s, %p)\n", debugstr_w(filenameW), fmap);

    fmap->fd = -1;
    fmap->load_commands = MACHO_NO_MAP;
    RtlInitializeBitMap(&fmap->sect_is_code, fmap->sect_is_code_buff, MAX_SECT + 1);

    len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL);
    if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE;
    WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, filename, len, NULL, NULL);

    /* check that the file exists */
    if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;

    /* Now open the file, so that we can mmap() it. */
    if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done;

    if (read(fmap->fd, &fat_header, sizeof(fat_header)) != sizeof(fat_header))
        goto done;
    TRACE("... got possible fat header\n");

    /* Fat header is always in big-endian order. */
    if (swap_ulong_be_to_host(fat_header.magic) == FAT_MAGIC)
    {
        int narch = swap_ulong_be_to_host(fat_header.nfat_arch);
        for (i = 0; i < narch; i++)
        {
            struct fat_arch fat_arch;
            if (read(fmap->fd, &fat_arch, sizeof(fat_arch)) != sizeof(fat_arch))
                goto done;
            if (swap_ulong_be_to_host(fat_arch.cputype) == CPU_TYPE_X86)
            {
                fmap->arch_offset = swap_ulong_be_to_host(fat_arch.offset);
                fmap->arch_size = swap_ulong_be_to_host(fat_arch.size);
                break;
            }
        }
        if (i >= narch) goto done;
        TRACE("... found x86 arch\n");
    }
    else
    {
        fmap->arch_offset = 0;
        fmap->arch_size = statbuf.st_size;
        TRACE("... not a fat header\n");
    }

    /* Individual architecture (standalone or within a fat file) is in its native byte order. */
    lseek(fmap->fd, fmap->arch_offset, SEEK_SET);
    if (read(fmap->fd, &fmap->mach_header, sizeof(fmap->mach_header)) != sizeof(fmap->mach_header))
        goto done;
    TRACE("... got possible Mach header\n");
    /* and check for a Mach-O header */
    if (fmap->mach_header.magic != MH_MAGIC ||
        fmap->mach_header.cputype != CPU_TYPE_X86) goto done;
    /* Make sure the file type is one of the ones we expect. */
    switch (fmap->mach_header.filetype)
    {
        case MH_EXECUTE:
        case MH_DYLIB:
        case MH_DYLINKER:
        case MH_BUNDLE:
            break;
        default:
            goto done;
    }
    TRACE("... verified Mach x86 header\n");

    fmap->segs_size = 0;
    fmap->segs_start = ~0L;

    if (macho_enum_load_commands(fmap, LC_SEGMENT, macho_accum_segs_range, NULL) < 0)
        goto done;

    fmap->segs_size -= fmap->segs_start;
    TRACE("segs_start: 0x%08x, segs_size: 0x%08x\n", (unsigned)fmap->segs_start,
            (unsigned)fmap->segs_size);

    ret = TRUE;
done:
    if (!ret)
        macho_unmap_file(fmap);
    HeapFree(GetProcessHeap(), 0, filename);
    return ret;
}
Exemplo n.º 24
0
_Use_decl_annotations_ EXTERN_C static bool VminitpSetupVMCS(
    const PER_PROCESSOR_DATA *ProcessorData, ULONG_PTR GuestStackPointer,
    ULONG_PTR GuestInstructionPointer, ULONG_PTR VmmStackPointer) {
  unsigned char error = 0;

  GDTR gdtr = {};
  __sgdt(&gdtr);

  IDTR idtr = {};
  __sidt(&idtr);

  VMX_VM_ENTER_CONTROLS vmEnterCtlRequested = {};
  vmEnterCtlRequested.Fields.IA32eModeGuest = true;
  VMX_VM_ENTER_CONTROLS vmEnterCtl = {
      VminitpAdjustControlValue(IA32_VMX_ENTRY_CTLS, vmEnterCtlRequested.All)};

  VMX_VM_EXIT_CONTROLS vmExitCtlRequested = {};
  vmExitCtlRequested.Fields.AcknowledgeInterruptOnExit = true;
  vmExitCtlRequested.Fields.HostAddressSpaceSize = true;
  VMX_VM_EXIT_CONTROLS vmExitCtl = {
      VminitpAdjustControlValue(IA32_VMX_EXIT_CTLS, vmExitCtlRequested.All)};

  VMX_PIN_BASED_CONTROLS vmPinCtlRequested = {};
  VMX_PIN_BASED_CONTROLS vmPinCtl = {
      VminitpAdjustControlValue(IA32_VMX_PINBASED_CTLS, vmPinCtlRequested.All)};

  VMX_CPU_BASED_CONTROLS vmCpuCtlRequested = {};
  vmCpuCtlRequested.Fields.RDTSCExiting = true;
  vmCpuCtlRequested.Fields.CR3LoadExiting = true;  // MOV to CR3
  vmCpuCtlRequested.Fields.CR8LoadExiting = true;  // MOV to CR8
  vmCpuCtlRequested.Fields.MovDRExiting = true;
  vmCpuCtlRequested.Fields.UseMSRBitmaps = true;
  vmCpuCtlRequested.Fields.ActivateSecondaryControl = true;
  VMX_CPU_BASED_CONTROLS vmCpuCtl = {VminitpAdjustControlValue(
      IA32_VMX_PROCBASED_CTLS, vmCpuCtlRequested.All)};

  VMX_SECONDARY_CPU_BASED_CONTROLS vmCpuCtl2Requested = {};
  vmCpuCtl2Requested.Fields.EnableRDTSCP = true;
  vmCpuCtl2Requested.Fields.DescriptorTableExiting = true;
  VMX_CPU_BASED_CONTROLS vmCpuCtl2 = {VminitpAdjustControlValue(
      IA32_VMX_PROCBASED_CTLS2, vmCpuCtl2Requested.All)};

  // Set up the MSR bitmap

  // Activate VM-exit for RDMSR against all MSRs
  const auto bitMapReadLow =
      reinterpret_cast<UCHAR *>(ProcessorData->MsrBitmap);
  const auto bitMapReadHigh = bitMapReadLow + 1024;
  RtlFillMemory(bitMapReadLow, 1024, 0xff);   // read        0 -     1fff
  RtlFillMemory(bitMapReadHigh, 1024, 0xff);  // read c0000000 - c0001fff

  // But ignore IA32_MPERF (000000e7) and IA32_APERF (000000e8)
  RTL_BITMAP bitMapReadLowHeader = {};
  RtlInitializeBitMap(&bitMapReadLowHeader,
                      reinterpret_cast<PULONG>(bitMapReadLow), 1024 * 8);
  RtlClearBits(&bitMapReadLowHeader, 0xe7, 2);

  // But ignore IA32_GS_BASE (c0000101) and IA32_KERNEL_GS_BASE (c0000102)
  RTL_BITMAP bitMapReadHighHeader = {};
  RtlInitializeBitMap(&bitMapReadHighHeader,
                      reinterpret_cast<PULONG>(bitMapReadHigh), 1024 * 8);
  RtlClearBits(&bitMapReadHighHeader, 0x101, 2);

  const auto msrBitmapPA = MmGetPhysicalAddress(ProcessorData->MsrBitmap);

  // Set up CR0 and CR4 bitmaps

  // Where a bit is     masked, the shadow bit appears
  // Where a bit is not masked, the actual bit appears
  CR0_REG cr0mask = {};
  cr0mask.Fields.WP = true;
  CR4_REG cr4mask = {};
  cr4mask.Fields.PGE = true;

  // clang-format off
  /* 16-Bit Control Field */

  /* 16-Bit Guest-State Fields */
  error |= __vmx_vmwrite(GUEST_ES_SELECTOR, AsmReadES());
  error |= __vmx_vmwrite(GUEST_CS_SELECTOR, AsmReadCS());
  error |= __vmx_vmwrite(GUEST_SS_SELECTOR, AsmReadSS());
  error |= __vmx_vmwrite(GUEST_DS_SELECTOR, AsmReadDS());
  error |= __vmx_vmwrite(GUEST_FS_SELECTOR, AsmReadFS());
  error |= __vmx_vmwrite(GUEST_GS_SELECTOR, AsmReadGS());
  error |= __vmx_vmwrite(GUEST_LDTR_SELECTOR, AsmReadLDTR());
  error |= __vmx_vmwrite(GUEST_TR_SELECTOR, AsmReadTR());

  /* 16-Bit Host-State Fields */
  error |= __vmx_vmwrite(HOST_ES_SELECTOR, AsmReadES() & 0xf8); // RPL and TI 
  error |= __vmx_vmwrite(HOST_CS_SELECTOR, AsmReadCS() & 0xf8); // have to be 0
  error |= __vmx_vmwrite(HOST_SS_SELECTOR, AsmReadSS() & 0xf8);
  error |= __vmx_vmwrite(HOST_DS_SELECTOR, AsmReadDS() & 0xf8);
  error |= __vmx_vmwrite(HOST_FS_SELECTOR, AsmReadFS() & 0xf8);
  error |= __vmx_vmwrite(HOST_GS_SELECTOR, AsmReadGS() & 0xf8);
  error |= __vmx_vmwrite(HOST_TR_SELECTOR, AsmReadTR() & 0xf8);

  /* 64-Bit Control Fields */
  error |= __vmx_vmwrite(IO_BITMAP_A, 0);
  error |= __vmx_vmwrite(IO_BITMAP_B, 0);
  error |= __vmx_vmwrite(MSR_BITMAP, msrBitmapPA.QuadPart);
  error |= __vmx_vmwrite(TSC_OFFSET, 0);

  /* 64-Bit Guest-State Fields */
  error |= __vmx_vmwrite(VMCS_LINK_POINTER, 0xffffffffffffffff);
  error |= __vmx_vmwrite(GUEST_IA32_DEBUGCTL, __readmsr(IA32_DEBUGCTL));

  /* 32-Bit Control Fields */
  error |= __vmx_vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmPinCtl.All);
  error |= __vmx_vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmCpuCtl.All);
  error |= __vmx_vmwrite(SECONDARY_VM_EXEC_CONTROL, vmCpuCtl2.All);
  error |= __vmx_vmwrite(EXCEPTION_BITMAP, 0);
  error |= __vmx_vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
  error |= __vmx_vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
  error |= __vmx_vmwrite(CR3_TARGET_COUNT, 0);
  error |= __vmx_vmwrite(VM_EXIT_CONTROLS, vmExitCtl.All);
  error |= __vmx_vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
  error |= __vmx_vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
  error |= __vmx_vmwrite(VM_ENTRY_CONTROLS, vmEnterCtl.All);
  error |= __vmx_vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
  error |= __vmx_vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);

  /* 32-Bit Guest-State Fields */
  error |= __vmx_vmwrite(GUEST_ES_LIMIT, GetSegmentLimit(AsmReadES()));
  error |= __vmx_vmwrite(GUEST_CS_LIMIT, GetSegmentLimit(AsmReadCS()));
  error |= __vmx_vmwrite(GUEST_SS_LIMIT, GetSegmentLimit(AsmReadSS()));
  error |= __vmx_vmwrite(GUEST_DS_LIMIT, GetSegmentLimit(AsmReadDS()));
  error |= __vmx_vmwrite(GUEST_FS_LIMIT, GetSegmentLimit(AsmReadFS()));
  error |= __vmx_vmwrite(GUEST_GS_LIMIT, GetSegmentLimit(AsmReadGS()));
  error |= __vmx_vmwrite(GUEST_LDTR_LIMIT, GetSegmentLimit(AsmReadLDTR()));
  error |= __vmx_vmwrite(GUEST_TR_LIMIT, GetSegmentLimit(AsmReadTR()));
  error |= __vmx_vmwrite(GUEST_GDTR_LIMIT, gdtr.Limit);
  error |= __vmx_vmwrite(GUEST_IDTR_LIMIT, idtr.Limit);
  error |= __vmx_vmwrite(GUEST_ES_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadES()));
  error |= __vmx_vmwrite(GUEST_CS_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadCS()));
  error |= __vmx_vmwrite(GUEST_SS_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadSS()));
  error |= __vmx_vmwrite(GUEST_DS_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadDS()));
  error |= __vmx_vmwrite(GUEST_FS_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadFS()));
  error |= __vmx_vmwrite(GUEST_GS_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadGS()));
  error |= __vmx_vmwrite(GUEST_LDTR_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadLDTR()));
  error |= __vmx_vmwrite(GUEST_TR_AR_BYTES, VminitpGetSegmentAccessRight(AsmReadTR()));
  error |= __vmx_vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
  error |= __vmx_vmwrite(GUEST_ACTIVITY_STATE, 0);
  error |= __vmx_vmwrite(GUEST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));

  /* 32-Bit Host-State Field */
  error |= __vmx_vmwrite(HOST_IA32_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));

  /* Natural-Width Control Fields */
  error |= __vmx_vmwrite(CR0_GUEST_HOST_MASK, cr0mask.All);
  error |= __vmx_vmwrite(CR4_GUEST_HOST_MASK, cr4mask.All);
  error |= __vmx_vmwrite(CR0_READ_SHADOW, __readcr0());
  error |= __vmx_vmwrite(CR4_READ_SHADOW, __readcr4());
  error |= __vmx_vmwrite(CR3_TARGET_VALUE0, 0);
  error |= __vmx_vmwrite(CR3_TARGET_VALUE1, 0);
  error |= __vmx_vmwrite(CR3_TARGET_VALUE2, 0);
  error |= __vmx_vmwrite(CR3_TARGET_VALUE3, 0);

  /* Natural-Width Guest-State Fields */
  error |= __vmx_vmwrite(GUEST_CR0, __readcr0());
  error |= __vmx_vmwrite(GUEST_CR3, __readcr3());
  error |= __vmx_vmwrite(GUEST_CR4, __readcr4());
  error |= __vmx_vmwrite(GUEST_ES_BASE, 0);
  error |= __vmx_vmwrite(GUEST_CS_BASE, 0);
  error |= __vmx_vmwrite(GUEST_SS_BASE, 0);
  error |= __vmx_vmwrite(GUEST_DS_BASE, 0);
  error |= __vmx_vmwrite(GUEST_FS_BASE, __readmsr(IA32_FS_BASE));
  error |= __vmx_vmwrite(GUEST_GS_BASE, __readmsr(IA32_GS_BASE));
  error |= __vmx_vmwrite(GUEST_LDTR_BASE, VminitpGetSegmentBase(gdtr.Address, AsmReadLDTR()));
  error |= __vmx_vmwrite(GUEST_TR_BASE, VminitpGetSegmentBase(gdtr.Address, AsmReadTR()));
  error |= __vmx_vmwrite(GUEST_GDTR_BASE, gdtr.Address);
  error |= __vmx_vmwrite(GUEST_IDTR_BASE, idtr.Address);
  error |= __vmx_vmwrite(GUEST_DR7, __readdr(7));
  error |= __vmx_vmwrite(GUEST_RSP, GuestStackPointer);
  error |= __vmx_vmwrite(GUEST_RIP, GuestInstructionPointer);
  error |= __vmx_vmwrite(GUEST_RFLAGS, __readeflags());
  error |= __vmx_vmwrite(GUEST_SYSENTER_ESP, __readmsr(IA32_SYSENTER_ESP));
  error |= __vmx_vmwrite(GUEST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));

  /* Natural-Width Host-State Fields */
  error |= __vmx_vmwrite(HOST_CR0, __readcr0());
  error |= __vmx_vmwrite(HOST_CR3, __readcr3());
  error |= __vmx_vmwrite(HOST_CR4, __readcr4());
  error |= __vmx_vmwrite(HOST_FS_BASE, __readmsr(IA32_FS_BASE));
  error |= __vmx_vmwrite(HOST_GS_BASE, __readmsr(IA32_GS_BASE));
  error |= __vmx_vmwrite(HOST_TR_BASE, VminitpGetSegmentBase(gdtr.Address, AsmReadTR()));
  error |= __vmx_vmwrite(HOST_GDTR_BASE, gdtr.Address);
  error |= __vmx_vmwrite(HOST_IDTR_BASE, idtr.Address);
  error |= __vmx_vmwrite(HOST_IA32_SYSENTER_ESP, __readmsr(IA32_SYSENTER_ESP));
  error |= __vmx_vmwrite(HOST_IA32_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));
  error |= __vmx_vmwrite(HOST_RSP, VmmStackPointer);
  error |= __vmx_vmwrite(HOST_RIP, reinterpret_cast<size_t>(AsmVmmEntryPoint));
  // clang-format on

  const auto vmxStatus = static_cast<VMX_STATUS>(error);
  return vmxStatus == VMX_OK;
}
Exemplo n.º 25
0
VOID
D3DKMTInitialize()
{
    VOID *gdi32 = NULL;
    VOID *deviceInfoSet;
    UINT32 result;
    UINT32 memberIndex;
    UINT32 detailDataSize;
    SP_DEVICE_INTERFACE_DATA            deviceInterfaceData;
    SP_DEVICE_INTERFACE_DETAIL_DATA_W   *detailData;
    SP_DEVINFO_DATA                     deviceInfoData;
    //D3DKMT_OPENADAPTERFROMDEVICENAME    openAdapterFromDeviceName;
    D3DKMT_QUERYSTATISTICS              queryStatistics;

    gdi32 = Module::Load(L"gdi32.dll");

    if (!gdi32)
    {
        return;
    }

    D3DKMTOpenAdapterFromDeviceName = (TYPE_D3DKMTOpenAdapterFromDeviceName) Module::GetProcedureAddress(
                                                                                gdi32,
                                                                                "D3DKMTOpenAdapterFromDeviceName"
                                                                                );

    D3DKMTQueryStatistics = (TYPE_D3DKMTQueryStatistics) Module::GetProcedureAddress(gdi32, "D3DKMTQueryStatistics");

    if (!D3DKMTOpenAdapterFromDeviceName || !D3DKMTQueryStatistics)
    {
        return;
    }

    deviceInfoSet = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL_I,
                                         NULL, NULL,
                                         DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    if (!deviceInfoSet)
    {
        return;
    }

    memberIndex = 0;
    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    while (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DISPLAY_DEVICE_ARRIVAL_I, memberIndex, &deviceInterfaceData))
    {
        detailDataSize = 0x100;
		detailData = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*) Memory::Allocate(detailDataSize);
        detailData->cbSize = 6; /*sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)*/
        deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

        result = SetupDiGetDeviceInterfaceDetailW(
                    deviceInfoSet,
                    &deviceInterfaceData,
                    detailData,
                    detailDataSize,
                    &detailDataSize,
                    &deviceInfoData
                    );

        if (result)
        {
            openAdapterFromDeviceName.pDeviceName = detailData->DevicePath;

            if (NT_SUCCESS(D3DKMTOpenAdapterFromDeviceName(&openAdapterFromDeviceName)))
            {
                memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));

                queryStatistics.Type = D3DKMT_QUERYSTATISTICS_ADAPTER;
                queryStatistics.AdapterLuid = openAdapterFromDeviceName.AdapterLuid;

                if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                {
                    UINT32 i;

                    D3dkmt_GpuAdapter = AllocateGpuAdapter(queryStatistics.QueryResult.AdapterInformation.NbSegments);

                    D3dkmt_GpuAdapter->AdapterLuid       = openAdapterFromDeviceName.AdapterLuid;
                    D3dkmt_GpuAdapter->NodeCount     = queryStatistics.QueryResult.AdapterInformation.NodeCount;
                    D3dkmt_GpuAdapter->SegmentCount  = queryStatistics.QueryResult.AdapterInformation.NbSegments;

                    RtlInitializeBitMap(
                        &D3dkmt_GpuAdapter->ApertureBitMap,
                        D3dkmt_GpuAdapter->ApertureBitMapBuffer,
                        queryStatistics.QueryResult.AdapterInformation.NbSegments
                        );

                    EtGpuTotalNodeCount += D3dkmt_GpuAdapter->NodeCount;

                    EtGpuTotalSegmentCount += D3dkmt_GpuAdapter->SegmentCount;

                    D3dkmt_GpuAdapter->FirstNodeIndex = EtGpuNextNodeIndex;
                    EtGpuNextNodeIndex += D3dkmt_GpuAdapter->NodeCount;

                    for (i = 0; i < D3dkmt_GpuAdapter->SegmentCount; i++)
                    {
                        memset(&queryStatistics, 0, sizeof(D3DKMT_QUERYSTATISTICS));

                        queryStatistics.Type = D3DKMT_QUERYSTATISTICS_SEGMENT;
                        queryStatistics.AdapterLuid = D3dkmt_GpuAdapter->AdapterLuid;
                        queryStatistics.QuerySegment.SegmentId = i;

                        if (NT_SUCCESS(D3DKMTQueryStatistics(&queryStatistics)))
                        {
                            UINT64 commitLimit;
                            UINT32 aperature;

                            commitLimit = queryStatistics.QueryResult.SegmentInformationV1.CommitLimit;
                            aperature = queryStatistics.QueryResult.SegmentInformationV1.Aperture;

                            if (aperature)
                                RtlSetBits(&D3dkmt_GpuAdapter->ApertureBitMap, i, 1);
                            else
                                EtGpuDedicatedLimit += commitLimit;
                        }
                    }
                }
            }
        }

		Memory::Free(detailData);

        memberIndex++;
    }

    SetupDiDestroyDeviceInfoList(deviceInfoSet);

    EtGpuNodeBitMapBuffer = (UINT32*) Memory::Allocate(BYTES_NEEDED_FOR_BITS(EtGpuTotalNodeCount));
    
	RtlInitializeBitMap(&EtGpuNodeBitMap, EtGpuNodeBitMapBuffer, EtGpuTotalNodeCount);

    EtGpuNodesTotalRunningTimeDelta = (PPH_UINT64_DELTA) Memory::Allocate(sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);

    memset(EtGpuNodesTotalRunningTimeDelta, 0, sizeof(PH_UINT64_DELTA) * EtGpuTotalNodeCount);
}
Exemplo n.º 26
0
/***********************************************************************
 *           thread_init
 *
 * Setup the initial thread.
 *
 * NOTES: The first allocated TEB on NT is at 0x7ffde000.
 */
HANDLE thread_init(void)
{
    TEB *teb;
    void *addr;
    SIZE_T size, info_size;
    HANDLE exe_file = 0;
    NTSTATUS status;
    struct ntdll_thread_data *thread_data;
    static struct debug_info debug_info;  /* debug info for initial thread */
#ifdef __APPLE__
    ULONG64 dyld_image_info;
#endif

    virtual_init();
    signal_init_early();

    /* reserve space for shared user data */

    addr = (void *)0x7ffe0000;
    size = 0x10000;
    status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
                                      MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
    if (status)
    {
        MESSAGE( "wine: failed to map the shared user data: %08x\n", status );
        exit(1);
    }
    user_shared_data = addr;

    /* allocate and initialize the PEB */

    addr = NULL;
    size = sizeof(*peb);
    NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 1, &size,
                             MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
    peb = addr;

    peb->ProcessParameters  = &params;
    peb->TlsBitmap          = &tls_bitmap;
    peb->TlsExpansionBitmap = &tls_expansion_bitmap;
    peb->FlsBitmap          = &fls_bitmap;
    peb->LdrData            = &ldr;
    peb->OSMajorVersion     = 5;
    peb->OSMinorVersion     = 1;
    peb->OSBuildNumber      = 0xA28;
    peb->OSPlatformId       = VER_PLATFORM_WIN32_NT;
    params.CurrentDirectory.DosPath.Buffer = current_dir;
    params.CurrentDirectory.DosPath.MaximumLength = sizeof(current_dir);
    params.wShowWindow = 1; /* SW_SHOWNORMAL */
    ldr.Length = sizeof(ldr);
    RtlInitializeBitMap( &tls_bitmap, peb->TlsBitmapBits, sizeof(peb->TlsBitmapBits) * 8 );
    RtlInitializeBitMap( &tls_expansion_bitmap, peb->TlsExpansionBitmapBits,
                         sizeof(peb->TlsExpansionBitmapBits) * 8 );
    RtlInitializeBitMap( &fls_bitmap, peb->FlsBitmapBits, sizeof(peb->FlsBitmapBits) * 8 );
    RtlSetBits( peb->TlsBitmap, 0, 1 ); /* TLS index 0 is reserved and should be initialized to NULL. */
    RtlSetBits( peb->FlsBitmap, 0, 1 );
    InitializeListHead( &peb->FlsListHead );
    InitializeListHead( &ldr.InLoadOrderModuleList );
    InitializeListHead( &ldr.InMemoryOrderModuleList );
    InitializeListHead( &ldr.InInitializationOrderModuleList );
#ifdef __APPLE__
    dyld_image_info = get_dyld_image_info_addr();
#ifdef __LP64__
#ifdef WORDS_BIGENDIAN
    peb->Reserved[1] = dyld_image_info & 0xFFFFFFFF;
    peb->Reserved[0] = dyld_image_info >> 32;
#else
    peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF;
    peb->Reserved[1] = dyld_image_info >> 32;
#endif
#else
    peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF;
#endif
#endif

    /*
     * Starting with Vista, the first user to log on has session id 1.
     * Session id 0 is for processes that don't interact with the user (like services).
     */
    peb->SessionId = 1;

    /* allocate and initialize the initial TEB */

    signal_alloc_thread( &teb );
    teb->Peb = peb;
    teb->Tib.StackBase = (void *)~0UL;
    teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
    teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);

    thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
    thread_data->request_fd = -1;
    thread_data->reply_fd   = -1;
    thread_data->wait_fd[0] = -1;
    thread_data->wait_fd[1] = -1;
    thread_data->debug_info = &debug_info;
    InsertHeadList( &tls_links, &teb->TlsLinks );

    signal_init_thread( teb );
    virtual_init_threading();

    debug_info.str_pos = debug_info.strings;
    debug_info.out_pos = debug_info.output;
    debug_init();

    /* setup the server connection */
    server_init_process();
    info_size = server_init_thread( peb );

    /* create the process heap */
    if (!(peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE, NULL, 0, 0, NULL, NULL )))
    {
        MESSAGE( "wine: failed to create the process heap\n" );
        exit(1);
    }

    /* allocate user parameters */
    if (info_size)
    {
        init_user_process_params( info_size, &exe_file );
    }
    else
    {
        if (isatty(0) || isatty(1) || isatty(2))
            params.ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */
        if (!isatty(0))
            wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE,  OBJ_INHERIT, &params.hStdInput );
        if (!isatty(1))
            wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdOutput );
        if (!isatty(2))
            wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, &params.hStdError );
    }

    /* initialize user_shared_data */
    __wine_user_shared_data();
    fill_cpu_info();

    NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );

    return exe_file;
}
Exemplo n.º 27
0
/// <summary>
/// Setup VMCS fields
/// </summary>
/// <param name="VpData">Virtual CPU data</param>
VOID VmxSetupVMCS( IN PVCPU VpData )
{
    PKPROCESSOR_STATE state = &VpData->HostState;
    VMX_GDTENTRY64 vmxGdtEntry = { 0 };
    VMX_VM_ENTER_CONTROLS vmEnterCtlRequested = { 0 };
    VMX_VM_EXIT_CONTROLS vmExitCtlRequested = { 0 };
    VMX_PIN_BASED_CONTROLS vmPinCtlRequested = { 0 };
    VMX_CPU_BASED_CONTROLS vmCpuCtlRequested = { 0 };
    VMX_SECONDARY_CPU_BASED_CONTROLS vmCpuCtl2Requested = { 0 };

    // As we exit back into the guest, make sure to exist in x64 mode as well.
    vmEnterCtlRequested.Fields.IA32eModeGuest = TRUE;

    // If any interrupts were pending upon entering the hypervisor, acknowledge
    // them when we're done. And make sure to enter us in x64 mode at all times
    vmExitCtlRequested.Fields.AcknowledgeInterruptOnExit = TRUE;
    vmExitCtlRequested.Fields.HostAddressSpaceSize = TRUE;

    // In order for our choice of supporting RDTSCP and XSAVE/RESTORES above to
    // actually mean something, we have to request secondary controls. We also
    // want to activate the MSR bitmap in order to keep them from being caught.
    vmCpuCtlRequested.Fields.UseMSRBitmaps = TRUE;
    vmCpuCtlRequested.Fields.ActivateSecondaryControl = TRUE;
    //vmCpuCtlRequested.Fields.UseTSCOffseting = TRUE;
    //vmCpuCtlRequested.Fields.RDTSCExiting = TRUE;

    // VPID caches must be invalidated on CR3 change
    if(g_Data->Features.VPID)
        vmCpuCtlRequested.Fields.CR3LoadExiting = TRUE;

    // Enable support for RDTSCP and XSAVES/XRESTORES in the guest. Windows 10
    // makes use of both of these instructions if the CPU supports it. By using
    // VmxpAdjustMsr, these options will be ignored if this processor does
    // not actually support the instructions to begin with.
    vmCpuCtl2Requested.Fields.EnableRDTSCP = TRUE;
    vmCpuCtl2Requested.Fields.EnableXSAVESXSTORS = TRUE;

    // Begin by setting the link pointer to the required value for 4KB VMCS.
    __vmx_vmwrite( VMCS_LINK_POINTER, MAXULONG64 );

    __vmx_vmwrite(
        PIN_BASED_VM_EXEC_CONTROL, 
        VmxpAdjustMsr( VpData->MsrData[VMX_MSR( MSR_IA32_VMX_TRUE_PINBASED_CTLS )], vmPinCtlRequested.All ) 
        );
    __vmx_vmwrite( 
        CPU_BASED_VM_EXEC_CONTROL, 
        VmxpAdjustMsr( VpData->MsrData[VMX_MSR( MSR_IA32_VMX_TRUE_PROCBASED_CTLS )], vmCpuCtlRequested.All ) 
        );
    __vmx_vmwrite( 
        SECONDARY_VM_EXEC_CONTROL, 
        VmxpAdjustMsr( VpData->MsrData[VMX_MSR( MSR_IA32_VMX_PROCBASED_CTLS2 )], vmCpuCtl2Requested.All ) 
        );
    __vmx_vmwrite(
        VM_EXIT_CONTROLS, 
        VmxpAdjustMsr( VpData->MsrData[VMX_MSR( MSR_IA32_VMX_TRUE_EXIT_CTLS )], vmExitCtlRequested.All ) 
        );
    __vmx_vmwrite( 
        VM_ENTRY_CONTROLS, 
        VmxpAdjustMsr( VpData->MsrData[VMX_MSR( MSR_IA32_VMX_TRUE_ENTRY_CTLS )], vmEnterCtlRequested.All ) 
        );

    // Load the MSR bitmap. Unlike other bitmaps, not having an MSR bitmap will
    // trap all MSRs, so have to allocate an empty one.
    PUCHAR bitMapReadLow = g_Data->MSRBitmap;       // 0x00000000 - 0x00001FFF
    PUCHAR bitMapReadHigh = bitMapReadLow + 1024;   // 0xC0000000 - 0xC0001FFF

    RTL_BITMAP bitMapReadLowHeader = { 0 };
    RTL_BITMAP bitMapReadHighHeader = { 0 };
    RtlInitializeBitMap( &bitMapReadLowHeader, (PULONG)bitMapReadLow, 1024 * 8 );
    RtlInitializeBitMap( &bitMapReadHighHeader, (PULONG)bitMapReadHigh, 1024 * 8 );

    RtlSetBit( &bitMapReadLowHeader, MSR_IA32_FEATURE_CONTROL );    // MSR_IA32_FEATURE_CONTROL
    RtlSetBit( &bitMapReadLowHeader,  MSR_IA32_DEBUGCTL );          // MSR_DEBUGCTL
    RtlSetBit( &bitMapReadHighHeader, MSR_LSTAR - 0xC0000000 );     // MSR_LSTAR

    // VMX MSRs
    for (ULONG i = MSR_IA32_VMX_BASIC; i <= MSR_IA32_VMX_VMFUNC; i++)
        RtlSetBit( &bitMapReadLowHeader, i );

    __vmx_vmwrite( MSR_BITMAP, MmGetPhysicalAddress( g_Data->MSRBitmap ).QuadPart );

    // Exception bitmap
    ULONG ExceptionBitmap = 0;
    //ExceptionBitmap |= 1 << VECTOR_DEBUG_EXCEPTION;
    ExceptionBitmap |= 1 << VECTOR_BREAKPOINT_EXCEPTION;

    __vmx_vmwrite( EXCEPTION_BITMAP, ExceptionBitmap );

    // CS (Ring 0 Code)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegCs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_CS_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_CS_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_CS_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_CS_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_CS_SELECTOR, state->ContextFrame.SegCs & ~RPL_MASK );

    // SS (Ring 0 Data)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegSs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_SS_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_SS_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_SS_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_SS_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_SS_SELECTOR, state->ContextFrame.SegSs & ~RPL_MASK );

    // DS (Ring 3 Data)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegDs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_DS_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_DS_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_DS_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_DS_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_DS_SELECTOR, state->ContextFrame.SegDs & ~RPL_MASK );

    // ES (Ring 3 Data)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegEs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_ES_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_ES_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_ES_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_ES_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_ES_SELECTOR, state->ContextFrame.SegEs & ~RPL_MASK );

    // FS (Ring 3 Compatibility-Mode TEB)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegFs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_FS_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_FS_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_FS_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_FS_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_FS_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_FS_SELECTOR, state->ContextFrame.SegFs & ~RPL_MASK );

    // GS (Ring 3 Data if in Compatibility-Mode, MSR-based in Long Mode)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->ContextFrame.SegGs, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_GS_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_GS_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_GS_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_GS_BASE, state->SpecialRegisters.MsrGsBase );
    __vmx_vmwrite( HOST_GS_BASE, state->SpecialRegisters.MsrGsBase );
    __vmx_vmwrite( HOST_GS_SELECTOR, state->ContextFrame.SegGs & ~RPL_MASK );

    // Task Register (Ring 0 TSS)
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->SpecialRegisters.Tr, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_TR_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_TR_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_TR_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_TR_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_TR_BASE, vmxGdtEntry.Base );
    __vmx_vmwrite( HOST_TR_SELECTOR, state->SpecialRegisters.Tr & ~RPL_MASK );

    // LDT
    VmxpConvertGdtEntry( state->SpecialRegisters.Gdtr.Base, state->SpecialRegisters.Ldtr, &vmxGdtEntry );
    __vmx_vmwrite( GUEST_LDTR_SELECTOR, vmxGdtEntry.Selector );
    __vmx_vmwrite( GUEST_LDTR_LIMIT, vmxGdtEntry.Limit );
    __vmx_vmwrite( GUEST_LDTR_AR_BYTES, vmxGdtEntry.AccessRights );
    __vmx_vmwrite( GUEST_LDTR_BASE, vmxGdtEntry.Base );

    // GDT
    __vmx_vmwrite( GUEST_GDTR_BASE, (ULONG_PTR)state->SpecialRegisters.Gdtr.Base );
    __vmx_vmwrite( GUEST_GDTR_LIMIT, state->SpecialRegisters.Gdtr.Limit );
    __vmx_vmwrite( HOST_GDTR_BASE, (ULONG_PTR)state->SpecialRegisters.Gdtr.Base );

    // IDT
    __vmx_vmwrite( GUEST_IDTR_BASE, (ULONG_PTR)state->SpecialRegisters.Idtr.Base );
    __vmx_vmwrite( GUEST_IDTR_LIMIT, state->SpecialRegisters.Idtr.Limit );
    __vmx_vmwrite( HOST_IDTR_BASE, (ULONG_PTR)state->SpecialRegisters.Idtr.Base );

    // CR0
    __vmx_vmwrite( CR0_READ_SHADOW, state->SpecialRegisters.Cr0 );
    __vmx_vmwrite( HOST_CR0, state->SpecialRegisters.Cr0 );
    __vmx_vmwrite( GUEST_CR0, state->SpecialRegisters.Cr0 );

    // CR3 -- do not use the current process' address space for the host,
    // because we may be executing in an arbitrary user-mode process right now
    // as part of the DPC interrupt we execute in.
    __vmx_vmwrite( HOST_CR3, VpData->SystemDirectoryTableBase );
    __vmx_vmwrite( GUEST_CR3, state->SpecialRegisters.Cr3 );

    // CR4
    __vmx_vmwrite( HOST_CR4, state->SpecialRegisters.Cr4 );
    __vmx_vmwrite( GUEST_CR4, state->SpecialRegisters.Cr4 );
    __vmx_vmwrite( CR4_GUEST_HOST_MASK, 0x2000 );
    __vmx_vmwrite( CR4_READ_SHADOW, state->SpecialRegisters.Cr4 & ~0x2000 );

    // Debug MSR and DR7
    __vmx_vmwrite( GUEST_IA32_DEBUGCTL, state->SpecialRegisters.DebugControl );
    __vmx_vmwrite( GUEST_DR7, state->SpecialRegisters.KernelDr7 );

    // Finally, load the guest stack, instruction pointer, and rflags, which
    // corresponds exactly to the location where RtlCaptureContext will return
    // to inside of VmxInitializeCPU.
    __vmx_vmwrite( GUEST_RSP, state->ContextFrame.Rsp );
    __vmx_vmwrite( GUEST_RIP, state->ContextFrame.Rip );
    __vmx_vmwrite( GUEST_RFLAGS, state->ContextFrame.EFlags );

    // Load the hypervisor entrypoint and stack. We give ourselves a standard
    // size kernel stack (24KB) and bias for the context structure that the
    // hypervisor entrypoint will push on the stack, avoiding the need for RSP
    // modifying instructions in the entrypoint. Note that the CONTEXT pointer
    // and thus the stack itself, must be 16-byte aligned for ABI compatibility
    // with AMD64 -- specifically, XMM operations will fail otherwise, such as
    // the ones that RtlCaptureContext will perform.
    NT_ASSERT( (KERNEL_STACK_SIZE - sizeof( CONTEXT )) % 16 == 0 );
    __vmx_vmwrite( HOST_RSP, (ULONG_PTR)VpData->VMMStack + KERNEL_STACK_SIZE - sizeof( CONTEXT ) );
    __vmx_vmwrite( HOST_RIP, (ULONG_PTR)VmxVMEntry );
}
Exemplo n.º 28
0
ULONGLONG
NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt)
{
    NTSTATUS Status;
    PFILE_RECORD_HEADER BitmapRecord;
    PNTFS_ATTR_CONTEXT DataContext;
    ULONGLONG BitmapDataSize;
    PCHAR BitmapData;
    ULONGLONG FreeClusters = 0;
    ULONG Read = 0;
    RTL_BITMAP Bitmap;

    DPRINT1("NtfsGetFreeClusters(%p)\n", DeviceExt);

    BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
    if (BitmapRecord == NULL)
    {
        return 0;
    }

    Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
    if (!NT_SUCCESS(Status))
    {
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return 0;
    }

    Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
    if (!NT_SUCCESS(Status))
    {
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return 0;
    }

    BitmapDataSize = AttributeDataLength(DataContext->pRecord);
    ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
    BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
    if (BitmapData == NULL)
    {
        ReleaseAttributeContext(DataContext);
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return 0;
    }

    /* FIXME: Totally underoptimized! */
    for (; Read < BitmapDataSize; Read += DeviceExt->NtfsInfo.BytesPerSector)
    {
        ReadAttribute(DeviceExt, DataContext, Read, (PCHAR)((ULONG_PTR)BitmapData + Read), DeviceExt->NtfsInfo.BytesPerSector);
    }
    ReleaseAttributeContext(DataContext);

    DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
    DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
    DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);

    RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
    FreeClusters = RtlNumberOfClearBits(&Bitmap);

    ExFreePoolWithTag(BitmapData, TAG_NTFS);
    ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);

    return FreeClusters;
}
Exemplo n.º 29
0
/** 
* NtfsAllocateClusters 
* Allocates a run of clusters. The run allocated might be smaller than DesiredClusters.
*/
NTSTATUS
NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt,
                     ULONG FirstDesiredCluster,
                     ULONG DesiredClusters, 
                     PULONG FirstAssignedCluster, 
                     PULONG AssignedClusters)
{
    NTSTATUS Status;
    PFILE_RECORD_HEADER BitmapRecord;
    PNTFS_ATTR_CONTEXT DataContext;
    ULONGLONG BitmapDataSize;
    PUCHAR BitmapData;
    ULONGLONG FreeClusters = 0;
    RTL_BITMAP Bitmap;
    ULONG AssignedRun;
    ULONG LengthWritten;

    DPRINT1("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters);

    BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
    if (BitmapRecord == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
    if (!NT_SUCCESS(Status))
    {
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return Status;
    }

    Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
    if (!NT_SUCCESS(Status))
    {
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return Status;
    }

    BitmapDataSize = AttributeDataLength(DataContext->pRecord);
    BitmapDataSize = min(BitmapDataSize, 0xffffffff);
    ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
    BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
    if (BitmapData == NULL)
    {
        ReleaseAttributeContext(DataContext);
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return  STATUS_INSUFFICIENT_RESOURCES;
    }

    DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
    DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
    DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);

    ReadAttribute(DeviceExt, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize);

    RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
    FreeClusters = RtlNumberOfClearBits(&Bitmap);

    if (FreeClusters < DesiredClusters)
    {
        ReleaseAttributeContext(DataContext);

        ExFreePoolWithTag(BitmapData, TAG_NTFS);
        ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
        return STATUS_DISK_FULL;
    }
    
    // TODO: Observe MFT reservation zone

    // Can we get one contiguous run?
    AssignedRun = RtlFindClearBitsAndSet(&Bitmap, DesiredClusters, FirstDesiredCluster);

    if (AssignedRun != 0xFFFFFFFF)
    {
        *FirstAssignedCluster = AssignedRun;
        *AssignedClusters = DesiredClusters;
    }
    else
    {
        // we can't get one contiguous run
        *AssignedClusters = RtlFindNextForwardRunClear(&Bitmap, FirstDesiredCluster, FirstAssignedCluster);
        
        if (*AssignedClusters == 0)
        {
            // we couldn't find any runs starting at DesiredFirstCluster
            *AssignedClusters = RtlFindLongestRunClear(&Bitmap, FirstAssignedCluster);
        }
            
    }
                
    Status = WriteAttribute(DeviceExt, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten, BitmapRecord);
    
    ReleaseAttributeContext(DataContext);

    ExFreePoolWithTag(BitmapData, TAG_NTFS);
    ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);

    return Status;
}
Exemplo n.º 30
0
BOOLEAN
FFSCheckSetBlock(
	PFFS_IRP_CONTEXT IrpContext,
	PFFS_VCB         Vcb,
	ULONG            Block)
{
#if 0
	ULONG           Group, dwBlk, Length;

	RTL_BITMAP      BlockBitmap;
	PVOID           BitmapCache;
	PBCB            BitmapBcb;

	LARGE_INTEGER   Offset;

	BOOLEAN         bModified = FALSE;


	//Group = (Block - FFS_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;

	dwBlk = (Block - FFS_FIRST_DATA_BLOCK) % BLOCKS_PER_GROUP;


	Offset.QuadPart = (LONGLONG) Vcb->BlockSize;
	Offset.QuadPart = Offset.QuadPart * Vcb->ffs_group_desc[Group].bg_block_bitmap;

	if (Group == Vcb->ffs_groups - 1)
	{
		Length = TOTAL_BLOCKS % BLOCKS_PER_GROUP;

		/* s_blocks_count is integer multiple of s_blocks_per_group */
		if (Length == 0)
			Length = BLOCKS_PER_GROUP;
	}
	else
	{
		Length = BLOCKS_PER_GROUP;
	}

	if (dwBlk >= Length)
		return FALSE;

	if (!CcPinRead(Vcb->StreamObj,
				&Offset,
				Vcb->BlockSize,
				PIN_WAIT,
				&BitmapBcb,
				&BitmapCache))
	{
		FFSPrint((DBG_ERROR, "FFSDeleteBlock: PinReading error ...\n"));
		return FALSE;
	}

	RtlInitializeBitMap(&BlockBitmap,
			BitmapCache,
			Length);

	if (RtlCheckBit(&BlockBitmap, dwBlk) == 0)
	{
		FFSBreakPoint();
		RtlSetBits(&BlockBitmap, dwBlk, 1);
		bModified = TRUE;
	}

	if (bModified)
	{
		CcSetDirtyPinnedData(BitmapBcb, NULL);

		FFSRepinBcb(IrpContext, BitmapBcb);

		FFSAddMcbEntry(Vcb, Offset.QuadPart, (LONGLONG)Vcb->BlockSize);
	}

	{
		CcUnpinData(BitmapBcb);
		BitmapBcb = NULL;
		BitmapCache = NULL;

		RtlZeroMemory(&BlockBitmap, sizeof(RTL_BITMAP));
	}

	return (!bModified);
#endif
	return FALSE;
}