Пример #1
0
BOOLEAN CMAPI
HvpVerifyHiveHeader(
   PHBASE_BLOCK BaseBlock)
{
   if (BaseBlock->Signature != HV_SIGNATURE ||
       BaseBlock->Major != HSYS_MAJOR ||
       BaseBlock->Minor < HSYS_MINOR ||
       BaseBlock->Type != HFILE_TYPE_PRIMARY ||
       BaseBlock->Format != HBASE_FORMAT_MEMORY ||
       BaseBlock->Cluster != 1 ||
       BaseBlock->Sequence1 != BaseBlock->Sequence2 ||
       HvpHiveHeaderChecksum(BaseBlock) != BaseBlock->CheckSum)
   {
      DPRINT1("Verify Hive Header failed: \n");
      DPRINT1("    Signature: 0x%x, expected 0x%x; Major: 0x%x, expected 0x%x\n",
          BaseBlock->Signature, HV_SIGNATURE, BaseBlock->Major, HSYS_MAJOR);
      DPRINT1("    Minor: 0x%x is not >= 0x%x; Type: 0x%x, expected 0x%x\n",
          BaseBlock->Minor, HSYS_MINOR, BaseBlock->Type, HFILE_TYPE_PRIMARY);
      DPRINT1("    Format: 0x%x, expected 0x%x; Cluster: 0x%x, expected 1\n",
          BaseBlock->Format, HBASE_FORMAT_MEMORY, BaseBlock->Cluster);
      DPRINT1("    Sequence: 0x%x, expected 0x%x; Checksum: 0x%x, expected 0x%x\n",
          BaseBlock->Sequence1, BaseBlock->Sequence2,
          HvpHiveHeaderChecksum(BaseBlock), BaseBlock->CheckSum);

      return FALSE;
   }

   return TRUE;
}
Пример #2
0
NTSTATUS CMAPI
HvpCreateHive(
   PHHIVE RegistryHive,
   PCUNICODE_STRING FileName OPTIONAL)
{
   PHBASE_BLOCK BaseBlock;
   ULONG Index;

   BaseBlock = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE, TAG_CM);
   if (BaseBlock == NULL)
      return STATUS_NO_MEMORY;

   RtlZeroMemory(BaseBlock, sizeof(HBASE_BLOCK));

   BaseBlock->Signature = HV_SIGNATURE;
   BaseBlock->Major = HSYS_MAJOR;
   BaseBlock->Minor = HSYS_MINOR;
   BaseBlock->Type = HFILE_TYPE_PRIMARY;
   BaseBlock->Format = HBASE_FORMAT_MEMORY;
   BaseBlock->Cluster = 1;
   BaseBlock->RootCell = HCELL_NIL;
   BaseBlock->Length = 0;
   BaseBlock->Sequence1 = 1;
   BaseBlock->Sequence2 = 1;

   /* Copy the 31 last characters of the hive file name if any */
   if (FileName)
   {
      if (FileName->Length / sizeof(WCHAR) <= HIVE_FILENAME_MAXLEN)
      {
         RtlCopyMemory(BaseBlock->FileName,
                       FileName->Buffer,
                       FileName->Length);
      }
      else
      {
         RtlCopyMemory(BaseBlock->FileName,
                       FileName->Buffer +
                       FileName->Length / sizeof(WCHAR) - HIVE_FILENAME_MAXLEN,
                       HIVE_FILENAME_MAXLEN * sizeof(WCHAR));
      }

      /* NULL-terminate */
      BaseBlock->FileName[HIVE_FILENAME_MAXLEN] = L'\0';
   }

   BaseBlock->CheckSum = HvpHiveHeaderChecksum(BaseBlock);

   RegistryHive->BaseBlock = BaseBlock;
   for (Index = 0; Index < 24; Index++)
   {
      RegistryHive->Storage[Stable].FreeDisplay[Index] = HCELL_NIL;
      RegistryHive->Storage[Volatile].FreeDisplay[Index] = HCELL_NIL;
   }

   return STATUS_SUCCESS;
}
Пример #3
0
BOOLEAN
HvIsInPlaceBaseBlockValid (
    _In_ PHBASE_BLOCK BaseBlock
    )
{
    ULONG HiveLength, HeaderSum;
    BOOLEAN Valid;

    /* Assume failure */
    Valid = FALSE;

    /* Check for incorrect signature, type, version, or format */
    if ((BaseBlock->Signature == 'fger') &&
        (BaseBlock->Type == 0) &&
        (BaseBlock->Major <= 1) &&
        (BaseBlock->Minor <= 5) &&
        (BaseBlock->Minor >= 3) &&
        (BaseBlock->Format == 1))
    {
        /* Check for invalid hive size */
        HiveLength = BaseBlock->Length;
        if (HiveLength)
        {
            /* Check for misaligned or too large hive size */
            if (!(HiveLength & 0xFFF) && HiveLength <= 0x7FFFE000)
            {
                /* Check for invalid header checksum */
                HeaderSum = HvpHiveHeaderChecksum(BaseBlock);
                if (HeaderSum == BaseBlock->CheckSum)
                {
                    /* All good */
                    Valid = TRUE;
                }
            }
        }
    }

    /* Return validity */
    return Valid;
}
Пример #4
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;
}
Пример #5
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;
}