⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 binhive.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  FreeLoader
 *
 *  Copyright (C) 2001  Rex Jolliff
 *  Copyright (C) 2001  Eric Kohl
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <freeldr.h>
#include <cmlib.h>
#include <debug.h>

/* FUNCTIONS ****************************************************************/

static PVOID
NTAPI
CmpAllocate (SIZE_T Size, BOOLEAN Paged)
{
  return MmAllocateMemory(Size);
}


static VOID
NTAPI
CmpFree (PVOID Ptr)
{
  return MmFreeMemory(Ptr);
}


static BOOLEAN
CmiAllocateHashTableCell (PHHIVE Hive,
			  PHCELL_INDEX HBOffset,
			  ULONG SubKeyCount)
{
  PHASH_TABLE_CELL HashCell;
  ULONG NewHashSize;

  NewHashSize = sizeof(HASH_TABLE_CELL) +
		(SubKeyCount * sizeof(HASH_RECORD));
  *HBOffset = HvAllocateCell (Hive, NewHashSize, HvStable);
  if (*HBOffset == HCELL_NULL)
    {
      return FALSE;
    }

  HashCell = HvGetCell (Hive, *HBOffset);
  HashCell->Id = REG_HASH_TABLE_CELL_ID;
  HashCell->HashTableSize = SubKeyCount;

  return TRUE;
}


static BOOLEAN
CmiAddKeyToParentHashTable (PHHIVE Hive,
			    HCELL_INDEX Parent,
			    PCM_KEY_NODE NewKeyCell,
			    HCELL_INDEX NKBOffset)
{
  PHASH_TABLE_CELL HashBlock;
  PCM_KEY_NODE ParentKeyCell;
  ULONG i;

  ParentKeyCell = HvGetCell (Hive, Parent);
  HashBlock = HvGetCell (Hive, ParentKeyCell->SubKeyLists[HvStable]);

  for (i = 0; i < HashBlock->HashTableSize; i++)
    {
      if (HashBlock->Table[i].KeyOffset == 0)
	{
	  HashBlock->Table[i].KeyOffset = NKBOffset;
	  memcpy (&HashBlock->Table[i].HashValue,
		  NewKeyCell->Name,
		  min(NewKeyCell->NameSize, sizeof(ULONG)));
	  ParentKeyCell->SubKeyCounts[HvStable]++;
	  return TRUE;
	}
    }

  return FALSE;
}


static BOOLEAN
CmiAllocateValueListCell (PHHIVE Hive,
			  PHCELL_INDEX ValueListOffset,
			  ULONG ValueCount)
{
  ULONG ValueListSize;

  ValueListSize = sizeof(VALUE_LIST_CELL) +
		  (ValueCount * sizeof(HCELL_INDEX));
  *ValueListOffset = HvAllocateCell (Hive, ValueListSize, HvStable);
  if (*ValueListOffset == HCELL_NULL)
    {
      DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
      return FALSE;
    }

  return TRUE;
}


static BOOLEAN
CmiAllocateValueCell(PHHIVE Hive,
		     PCM_KEY_VALUE *ValueCell,
		     HCELL_INDEX *ValueCellOffset,
		     PWCHAR ValueName)
{
  PCM_KEY_VALUE NewValueCell;
  ULONG NameSize;
  BOOLEAN Packable = TRUE;
  ULONG i;

  NameSize = (ValueName == NULL) ? 0 : wcslen (ValueName);
  for (i = 0; i < NameSize; i++)
    {
      if (ValueName[i] & 0xFF00)
        {
          NameSize *= sizeof(WCHAR);
          Packable = FALSE;
          break;
        }
    }
  *ValueCellOffset = HvAllocateCell (Hive, sizeof(CM_KEY_VALUE) + NameSize, HvStable);
  if (*ValueCellOffset == HCELL_NULL)
    {
      DbgPrint((DPRINT_REGISTRY, "CmiAllocateCell() failed\n"));
      return FALSE;
    }

  NewValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, *ValueCellOffset);
  NewValueCell->Id = REG_VALUE_CELL_ID;
  NewValueCell->NameSize = NameSize;
  NewValueCell->Flags = 0;
  if (NameSize > 0)
    {
      if (Packable)
        {
          for (i = 0; i < NameSize; i++)
            {
              ((PCHAR)NewValueCell->Name)[i] = (CHAR)ValueName[i];
            }
          NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
        }
      else
        {
          memcpy (NewValueCell->Name,
	          ValueName,
	          NameSize);
        }
    }
  NewValueCell->DataType = 0;
  NewValueCell->DataSize = 0;
  NewValueCell->DataOffset = -1;

  *ValueCell = NewValueCell;

  return TRUE;
}


static BOOLEAN
CmiAddValueToKeyValueList(PHHIVE Hive,
			  HCELL_INDEX KeyCellOffset,
			  HCELL_INDEX ValueCellOffset)
{
  PVALUE_LIST_CELL ValueListCell;
  PCM_KEY_NODE KeyCell;

  KeyCell = HvGetCell (Hive, KeyCellOffset);
  if (KeyCell == NULL)
    {
      DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
      return FALSE;
    }

  ValueListCell = HvGetCell (Hive, KeyCell->ValueList.List);
  if (ValueListCell == NULL)
    {
      DbgPrint((DPRINT_REGISTRY, "HvGetCell() failed\n"));
      return FALSE;
    }

  ValueListCell->ValueOffset[KeyCell->ValueList.Count] = ValueCellOffset;
  KeyCell->ValueList.Count++;

  return TRUE;
}

static BOOLEAN
CmiExportValue (PHHIVE Hive,
		HCELL_INDEX KeyCellOffset,
		FRLDRHKEY Key,
		PVALUE Value)
{
  HCELL_INDEX ValueCellOffset;
  HCELL_INDEX DataCellOffset;
  PCM_KEY_VALUE ValueCell;
  PVOID DataCell;
  ULONG DataSize;
  ULONG DataType;
  PCHAR Data;

  DbgPrint((DPRINT_REGISTRY, "CmiExportValue('%S') called\n",
	   (Value == NULL) ? "<default>" : (PCHAR)Value->Name));
  DbgPrint((DPRINT_REGISTRY, "DataSize %lu\n",
	   (Value == NULL) ? Key->DataSize : Value->DataSize));

  /* Allocate value cell */
  if (!CmiAllocateValueCell(Hive, &ValueCell, &ValueCellOffset, (Value == NULL) ? NULL : Value->Name))
    {
      return FALSE;
    }

  if (!CmiAddValueToKeyValueList(Hive, KeyCellOffset, ValueCellOffset))
    {
      return FALSE;
    }

  if (Value == NULL)
    {
      DataType = Key->DataType;
      DataSize = Key->DataSize;
      Data = Key->Data;
    }
  else
    {
      DataType = Value->DataType;
      DataSize = Value->DataSize;
      Data = Value->Data;
    }

  if (DataSize <= sizeof(HCELL_INDEX))
    {
      ValueCell->DataSize = DataSize | REG_DATA_IN_OFFSET;
      ValueCell->DataType = DataType;
      memcpy (&ValueCell->DataOffset,
	      &Data,
	      DataSize);
    }
  else
    {
      /* Allocate data cell */
      DataCellOffset = HvAllocateCell (Hive, DataSize, HvStable);
      if (DataCellOffset == HCELL_NULL)
	{
	  return FALSE;
	}

      ValueCell->DataOffset = DataCellOffset;
      ValueCell->DataSize = DataSize;
      ValueCell->DataType = DataType;

      DataCell = HvGetCell (Hive, DataCellOffset);
      memcpy (DataCell,
	      Data,
	      DataSize);
    }

  return TRUE;
}


static BOOLEAN
CmiExportSubKey (PHHIVE Hive,
		 HCELL_INDEX Parent,
		 FRLDRHKEY ParentKey,
		 FRLDRHKEY Key)
{
  HCELL_INDEX NKBOffset;
  PCM_KEY_NODE NewKeyCell;
  ULONG KeyCellSize;
  ULONG SubKeyCount;
  ULONG ValueCount;
  PLIST_ENTRY Entry;
  FRLDRHKEY SubKey;
  PVALUE Value;
  BOOLEAN Packable = TRUE;
  ULONG i;
  ULONG NameSize;

  DbgPrint((DPRINT_REGISTRY, "CmiExportSubKey('%S') called\n", Key->Name));

  /* Don't export links */
  if (Key->DataType == REG_LINK)
    return TRUE;

  NameSize = (Key->NameSize - sizeof(WCHAR)) / sizeof(WCHAR);
  for (i = 0; i < NameSize; i++)
    {
      if (Key->Name[i] & 0xFF00)
        {
          Packable = FALSE;
          NameSize *= sizeof(WCHAR);
          break;
        }
    }
          
  /* Allocate key cell */
  KeyCellSize = sizeof(CM_KEY_NODE) + NameSize;
  NKBOffset = HvAllocateCell (Hive, KeyCellSize, HvStable);
  if (NKBOffset == HCELL_NULL)
    {
      DbgPrint((DPRINT_REGISTRY, "HvAllocateCell() failed\n"));
      return FALSE;
    }

  /* Initialize key cell */
  NewKeyCell = (PCM_KEY_NODE) HvGetCell (Hive, NKBOffset);
  NewKeyCell->Id = REG_KEY_CELL_ID;
  NewKeyCell->Flags = 0;
  NewKeyCell->LastWriteTime.QuadPart = 0ULL;
  NewKeyCell->Parent = Parent;
  NewKeyCell->SubKeyCounts[HvStable] = 0;
  NewKeyCell->SubKeyLists[HvStable] = -1;
  NewKeyCell->ValueList.Count = 0;
  NewKeyCell->ValueList.List = -1;
  NewKeyCell->SecurityKeyOffset = -1;
  NewKeyCell->ClassNameOffset = -1;
  NewKeyCell->NameSize = NameSize;
  NewKeyCell->ClassSize = 0;
  if (Packable)
    {
      for (i = 0; i < NameSize; i++)
        {
          ((PCHAR)NewKeyCell->Name)[i] = (CHAR)Key->Name[i];
        }
      NewKeyCell->Flags |= REG_KEY_NAME_PACKED;

    }
  else
    {
      memcpy (NewKeyCell->Name,
	      Key->Name,
	      NameSize);
    }

  /* Add key cell to the parent key's hash table */
  if (!CmiAddKeyToParentHashTable (Hive,
				   Parent,
				   NewKeyCell,
				   NKBOffset))
    {
      DbgPrint((DPRINT_REGISTRY, "CmiAddKeyToParentHashTable() failed\n"));
      return FALSE;
    }

  ValueCount = RegGetValueCount (Key);
  DbgPrint((DPRINT_REGISTRY, "ValueCount: %u\n", ValueCount));
  if (ValueCount > 0)
    {
      /* Allocate value list cell */
      if (!CmiAllocateValueListCell (Hive,
				     &NewKeyCell->ValueList.List,
				     ValueCount))
	{
	  DbgPrint((DPRINT_REGISTRY, "CmiAllocateValueListCell() failed\n"));
	  return FALSE;
	}

      if (Key->DataSize != 0)
	{
	  if (!CmiExportValue (Hive, NKBOffset, Key, NULL))
	    return FALSE;
	}

      /* Enumerate values */
      Entry = Key->ValueList.Flink;
      while (Entry != &Key->ValueList)
	{
	  Value = CONTAINING_RECORD(Entry,
				    VALUE,
				    ValueList);

	  if (!CmiExportValue (Hive, NKBOffset, Key, Value))
	    return FALSE;

	  Entry = Entry->Flink;
	}
    }

  SubKeyCount = RegGetSubKeyCount (Key);
  DbgPrint((DPRINT_REGISTRY, "SubKeyCount: %u\n", SubKeyCount));
  if (SubKeyCount > 0)
    {
      /* Allocate hash table cell */
      if (!CmiAllocateHashTableCell (Hive,
				     &NewKeyCell->SubKeyLists[HvStable],
				     SubKeyCount))
	{
	  DbgPrint((DPRINT_REGISTRY, "CmiAllocateHashTableCell() failed\n"));
	  return FALSE;
	}

      /* Enumerate subkeys */
      Entry = Key->SubKeyList.Flink;
      while (Entry != &Key->SubKeyList)
	{
	  SubKey = CONTAINING_RECORD(Entry,
				     KEY,
				     KeyList);

	  if (!CmiExportSubKey (Hive, NKBOffset, Key, SubKey))
	    return FALSE;

	  Entry = Entry->Flink;
	}
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -