Beispiel #1
0
BOOLEAN CMAPI
HvSyncHive(
   PHHIVE RegistryHive)
{
   ASSERT(RegistryHive->ReadOnly == FALSE);

   if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0U)
   {
      return TRUE;
   }

   /* Update hive header modification time */
   KeQuerySystemTime(&RegistryHive->BaseBlock->TimeStamp);

   /* Update log file */
   if (!HvpWriteLog(RegistryHive))
   {
      return FALSE;
   }

   /* Update hive file */
   if (!HvpWriteHive(RegistryHive, TRUE))
   {
      return FALSE;
   }

   /* Clear dirty bitmap. */
   RtlClearAllBits(&RegistryHive->DirtyVector);
   RegistryHive->DirtyCount = 0;

   return TRUE;
}
Beispiel #2
0
static BOOLEAN CMAPI
HvpWriteHive(
   PHHIVE RegistryHive,
   BOOLEAN OnlyDirty)
{
   ULONG FileOffset;
   ULONG BlockIndex;
   ULONG LastIndex;
   PVOID BlockPtr;
   BOOLEAN Success;

   ASSERT(RegistryHive->ReadOnly == FALSE);
   ASSERT(RegistryHive->BaseBlock->Length ==
          RegistryHive->Storage[Stable].Length * HV_BLOCK_SIZE);

   DPRINT("HvpWriteHive called\n");

   if (RegistryHive->BaseBlock->Sequence1 !=
       RegistryHive->BaseBlock->Sequence2)
   {
      return FALSE;
   }

   /* Update first update counter and CheckSum */
   RegistryHive->BaseBlock->Type = HFILE_TYPE_PRIMARY;
   RegistryHive->BaseBlock->Sequence1++;
   RegistryHive->BaseBlock->CheckSum =
   HvpHiveHeaderChecksum(RegistryHive->BaseBlock);

   /* Write hive block */
   FileOffset = 0;
   Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
                                     &FileOffset, RegistryHive->BaseBlock,
                                     sizeof(HBASE_BLOCK));
   if (!Success)
   {
      return FALSE;
   }

   BlockIndex = 0;
   while (BlockIndex < RegistryHive->Storage[Stable].Length)
   {
      if (OnlyDirty)
      {
         LastIndex = BlockIndex;
         BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
         if (BlockIndex == ~0U || BlockIndex < LastIndex)
         {
            break;
         }
      }

      BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;
      FileOffset = (BlockIndex + 1) * HV_BLOCK_SIZE;

      /* Write hive block */
      Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
                                        &FileOffset, BlockPtr,
                                        HV_BLOCK_SIZE);
      if (!Success)
      {
         return FALSE;
      }

      BlockIndex++;
   }

   Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
   if (!Success)
   {
      DPRINT("FileFlush failed\n");
   }

   /* Update second update counter and CheckSum */
   RegistryHive->BaseBlock->Sequence2++;
   RegistryHive->BaseBlock->CheckSum =
      HvpHiveHeaderChecksum(RegistryHive->BaseBlock);

   /* Write hive block */
   FileOffset = 0;
   Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_PRIMARY,
                                     &FileOffset, RegistryHive->BaseBlock,
                                     sizeof(HBASE_BLOCK));
   if (!Success)
   {
      return FALSE;
   }

   Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_PRIMARY, NULL, 0);
   if (!Success)
   {
      DPRINT("FileFlush failed\n");
   }

   return TRUE;
}
Beispiel #3
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);
}
Beispiel #4
0
static BOOLEAN CMAPI
HvpWriteLog(
   PHHIVE RegistryHive)
{
   ULONG FileOffset;
   ULONG BufferSize;
   ULONG BitmapSize;
   PUCHAR Buffer;
   PUCHAR Ptr;
   ULONG BlockIndex;
   ULONG LastIndex;
   PVOID BlockPtr;
   BOOLEAN Success;

   UNIMPLEMENTED;
   return TRUE;

   ASSERT(RegistryHive->ReadOnly == FALSE);
   ASSERT(RegistryHive->BaseBlock->Length ==
          RegistryHive->Storage[Stable].Length * HV_BLOCK_SIZE);

   DPRINT("HvpWriteLog called\n");

   if (RegistryHive->BaseBlock->Sequence1 !=
       RegistryHive->BaseBlock->Sequence2)
   {
      return FALSE;
   }

   BitmapSize = RegistryHive->DirtyVector.SizeOfBitMap;
   BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize;
   BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE);

   DPRINT("Bitmap size %lu  buffer size: %lu\n", BitmapSize, BufferSize);

   Buffer = RegistryHive->Allocate(BufferSize, TRUE, TAG_CM);
   if (Buffer == NULL)
   {
      return FALSE;
   }

   /* Update first update counter and CheckSum */
   RegistryHive->BaseBlock->Type = HFILE_TYPE_LOG;
   RegistryHive->BaseBlock->Sequence1++;
   RegistryHive->BaseBlock->CheckSum =
      HvpHiveHeaderChecksum(RegistryHive->BaseBlock);

   /* Copy hive header */
   RtlCopyMemory(Buffer, RegistryHive->BaseBlock, HV_LOG_HEADER_SIZE);
   Ptr = Buffer + HV_LOG_HEADER_SIZE;
   RtlCopyMemory(Ptr, "DIRT", 4);
   Ptr += 4;
   RtlCopyMemory(Ptr, RegistryHive->DirtyVector.Buffer, BitmapSize);

   /* Write hive block and block bitmap */
   FileOffset = 0;
   Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
                                     &FileOffset, Buffer, BufferSize);
   RegistryHive->Free(Buffer, 0);

   if (!Success)
   {
      return FALSE;
   }

   /* Write dirty blocks */
   FileOffset = BufferSize;
   BlockIndex = 0;
   while (BlockIndex < RegistryHive->Storage[Stable].Length)
   {
      LastIndex = BlockIndex;
      BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
      if (BlockIndex == ~0U || BlockIndex < LastIndex)
      {
         break;
      }

      BlockPtr = (PVOID)RegistryHive->Storage[Stable].BlockList[BlockIndex].BlockAddress;

      /* Write hive block */
      Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
                                        &FileOffset, BlockPtr,
                                        HV_BLOCK_SIZE);
      if (!Success)
      {
         return FALSE;
      }

      BlockIndex++;
      FileOffset += HV_BLOCK_SIZE;
    }

   Success = RegistryHive->FileSetSize(RegistryHive, HFILE_TYPE_LOG, FileOffset, FileOffset);
   if (!Success)
   {
      DPRINT("FileSetSize failed\n");
      return FALSE;
    }

   /* Flush the log file */
   Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
   if (!Success)
   {
      DPRINT("FileFlush failed\n");
   }

   /* Update second update counter and CheckSum. */
   RegistryHive->BaseBlock->Sequence2++;
   RegistryHive->BaseBlock->CheckSum =
      HvpHiveHeaderChecksum(RegistryHive->BaseBlock);

   /* Write hive header again with updated sequence counter. */
   FileOffset = 0;
   Success = RegistryHive->FileWrite(RegistryHive, HFILE_TYPE_LOG,
                                     &FileOffset, RegistryHive->BaseBlock,
                                     HV_LOG_HEADER_SIZE);
   if (!Success)
   {
      return FALSE;
   }

   /* Flush the log file */
   Success = RegistryHive->FileFlush(RegistryHive, HFILE_TYPE_LOG, NULL, 0);
   if (!Success)
   {
      DPRINT("FileFlush failed\n");
   }

   return TRUE;
}
Beispiel #5
0
ULONG NtdllBitmap::FindSetBits( ULONG number_to_find, ULONG hint_index )
{
	assert(RtlFindSetBits != NULL);
	return RtlFindSetBits(this, number_to_find, hint_index);
}