mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
- most of the churn here is from code and headers imported from trunk.
- there are several improvements to freeldr for which ion and fireball are responsible. - also here is filip's cmlib. - my changes to freeldr mostly centered around managing the kernel slab and transitioning to the kernel memory map. the new map is built in a new area and installed once we have every page set up. this is a bit safer than the old method. - the video planes are handed off to ntoskrnl, and some trace macros using the frame buffer are available. - some hacks are removed. - current status: LdrInitModuleManagement tries to get the header from hal.dll but fails for some reason. i need to look into it. - this is a checkpoint, since there's been some interest in seeing how things are progressing. - you can put any pe-coff powerpc exe (based at 0x80000000) in place of ntoskrnl to test various aspects of the boot handoff. this will be useful for testing our trap handlers and such. - the toolchain didn't produce correct executables in all cases before, and didn't differentiate rva32 and rel32, causing some things to be linked wrong. so far, the current toolchain (20061231) links correctly, using R_PPC_UADDR32 as a surrogate for rva32, since it's never produced by gcc. - some earlyboot video tracing is in ntoskrnl so i can peek around a bit. svn path=/branches/powerpc/; revision=25259
This commit is contained in:
@@ -25,8 +25,10 @@
|
||||
<define name="__cdecl__" empty="true" />
|
||||
<define name="dllimport" empty="true" />
|
||||
<define name="WORDS_BIGENDIAN" empty="true" />
|
||||
<define name="MB_CUR_MAX">1</define>
|
||||
<compilerflag>-fshort-wchar</compilerflag>
|
||||
<compilerflag>-fsigned-char</compilerflag>
|
||||
<compilerflag>-map</compilerflag>
|
||||
<if property="MP" value="1">
|
||||
<define name="CONFIG_SMP" value="1" />
|
||||
</if>
|
||||
|
||||
@@ -86,7 +86,6 @@ zero_registers:
|
||||
|
||||
blr
|
||||
|
||||
.org 0x1000
|
||||
freeldr_banner:
|
||||
.ascii "ReactOS OpenFirmware Boot Program\r\n\0"
|
||||
|
||||
@@ -99,7 +98,7 @@ ofw_memory_size:
|
||||
.long 0
|
||||
.long 0
|
||||
|
||||
.org 0x2000
|
||||
.org 0x1000
|
||||
stack:
|
||||
.space 0x4000
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern ULONG CacheSizeLimit;
|
||||
of_proxy ofproxy;
|
||||
void *PageDirectoryStart, *PageDirectoryEnd;
|
||||
static int chosen_package, stdin_handle, part_handle = -1, kernel_mem = 0;
|
||||
int mmu_handle = 0;
|
||||
int mmu_handle = 0, FixedMemory = 0;
|
||||
BOOLEAN AcpiPresent = FALSE;
|
||||
char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
|
||||
jmp_buf jmp;
|
||||
@@ -344,9 +344,12 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
|
||||
/* Hack for pearpc */
|
||||
if( kernel_mem ) {
|
||||
BiosMemoryMap[slots].Length = kernel_mem * 1024;
|
||||
ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
|
||||
(int)BiosMemoryMap[slots].Length,
|
||||
0x1000);
|
||||
if( !FixedMemory ) {
|
||||
ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
|
||||
(int)BiosMemoryMap[slots].Length,
|
||||
0x1000);
|
||||
FixedMemory = BiosMemoryMap[slots].BaseAddress;
|
||||
}
|
||||
total += BiosMemoryMap[slots].Length;
|
||||
slots++;
|
||||
break;
|
||||
@@ -520,6 +523,10 @@ void PpcInit( of_proxy the_ofproxy ) {
|
||||
ofw_getprop( chosen_package, "mmu",
|
||||
(char *)&mmu_handle_chosen, sizeof(mmu_handle_chosen) );
|
||||
|
||||
ofw_print_string("Found stdin ");
|
||||
ofw_print_number(stdin_handle_chosen);
|
||||
ofw_print_string("\r\n");
|
||||
|
||||
stdin_handle = REV(stdin_handle_chosen);
|
||||
mmu_handle = REV(mmu_handle_chosen);
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ ULONG RaToPa(ULONG p) {
|
||||
#define BAT_GRANULARITY (64 * 1024)
|
||||
#define KernelMemorySize (16 * 1024 * 1024)
|
||||
#define KernelEntryPoint (KernelEntry - KERNEL_BASE_PHYS) + KernelBase
|
||||
#define XROUNDUP(x,n) ((((ULONG)x) + ((n) - 1)) & (~((n) - 1)))
|
||||
|
||||
/* Load Address of Next Module */
|
||||
ULONG_PTR NextModuleBase = 0;
|
||||
@@ -165,6 +166,7 @@ AddPageMapping( DIRECTORY_HEADER *TranslationMap,
|
||||
ULONG OldVirt) {
|
||||
ULONG Phys;
|
||||
DIRECTORY_ENTRY *Entry;
|
||||
|
||||
if( !TranslationMap->DirectoryPage ||
|
||||
TranslationMap->UsedSpace >= ((1<<PFN_SHIFT)/sizeof(DIRECTORY_ENTRY)) )
|
||||
{
|
||||
@@ -190,9 +192,9 @@ FrLdrStartup(ULONG Magic)
|
||||
{
|
||||
KernelEntryFn KernelEntryAddress =
|
||||
(KernelEntryFn)(KernelEntry + KernelBase);
|
||||
register ULONG_PTR i asm("r4"), j asm("r5") = 0;
|
||||
register DIRECTORY_HEADER *TranslationMap asm("r6") =
|
||||
MmAllocateMemory(1<<PFN_SHIFT);
|
||||
ULONG_PTR i, j;
|
||||
DIRECTORY_HEADER *TranslationMap = MmAllocateMemory(4<<PFN_SHIFT);
|
||||
ULONG_PTR stack = ((ULONG_PTR)TranslationMap)+(4<<PFN_SHIFT);
|
||||
boot_infos_t *LocalBootInfo = (boot_infos_t *)TranslationMap;
|
||||
TranslationMap = (DIRECTORY_HEADER *)
|
||||
(((PCHAR)&LocalBootInfo[1]) + sizeof(BootDigits));
|
||||
@@ -202,17 +204,22 @@ FrLdrStartup(ULONG Magic)
|
||||
ULONG_PTR KernelVirtAddr, NewMapSdr =
|
||||
(ULONG_PTR)MmAllocateMemory(128*1024);
|
||||
DIRECTORY_ENTRY *Entry;
|
||||
LoaderBlock.ArchExtra = (ULONG)LocalBootInfo;
|
||||
|
||||
NewMapSdr = ROUND_UP(NewMapSdr,64*1024);
|
||||
printf("Translation map: %x\n", TranslationMap);
|
||||
NewMapSdr = XROUNDUP(NewMapSdr,64*1024);
|
||||
printf("New SDR1 value will be %x\n", NewMapSdr);
|
||||
|
||||
memset(TranslationMap,0,sizeof(*TranslationMap));
|
||||
|
||||
printf("Translation map zeroed\n");
|
||||
/* Add the page containing the page directory */
|
||||
AddPageMapping( TranslationMap, (ULONG)TranslationMap, 0 );
|
||||
for( i = (ULONG_PTR)TranslationMap; i < stack; i += (1<<PFN_SHIFT) ) {
|
||||
AddPageMapping( TranslationMap, i, 0 );
|
||||
}
|
||||
|
||||
/* Map freeldr space 0xe00000 ... 0xe50000 */
|
||||
for( i = 0xe00000; i < 0xe50000; i += (1<<PFN_SHIFT),j++ ) {
|
||||
/* Map freeldr space 0xe00000 ... 0xe60000 */
|
||||
for( i = 0xe00000; i < 0xe80000; i += (1<<PFN_SHIFT) ) {
|
||||
AddPageMapping( TranslationMap, i, 0 );
|
||||
}
|
||||
|
||||
@@ -225,6 +232,7 @@ FrLdrStartup(ULONG Magic)
|
||||
}
|
||||
|
||||
printf("Built map of %d pages\n", TranslationMap->NumberOfPages);
|
||||
printf("Local boot info at %x\n", LocalBootInfo);
|
||||
|
||||
/*
|
||||
* Stuff page table entries for the page containing this code,
|
||||
@@ -243,11 +251,12 @@ FrLdrStartup(ULONG Magic)
|
||||
}
|
||||
|
||||
/* Tell them we're booting */
|
||||
DrawNumber(LocalBootInfo,0x1cabba9e,10,100);
|
||||
DrawNumber(LocalBootInfo,(ULONG)&LoaderBlock,10,100);
|
||||
DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,100);
|
||||
|
||||
SetSDR1( NewMapSdr );
|
||||
KernelEntryAddress( (void*)LocalBootInfo );
|
||||
KernelEntryAddress( (void*)&LoaderBlock );
|
||||
/* Nothing more */
|
||||
while(1);
|
||||
}
|
||||
|
||||
@@ -364,6 +373,12 @@ FrLdrSetupPageDirectory(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
ULONG SignExtend24(ULONG Base, ULONG Delta)
|
||||
{
|
||||
Delta = (Base & 0xfffffc) + Delta;
|
||||
return (Base & 0xff000003) | (Delta & 0xfffffc);
|
||||
}
|
||||
|
||||
/*++
|
||||
* FrLdrMapKernel
|
||||
* INTERNAL
|
||||
@@ -402,6 +417,7 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||
ULONG_PTR Delta;
|
||||
PUSHORT ShortPtr;
|
||||
PULONG LongPtr;
|
||||
PLOADER_MODULE ModuleData;
|
||||
|
||||
/* Allocate 1024 bytes for PE Header */
|
||||
ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
|
||||
@@ -519,6 +535,11 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||
*ShortPtr += HIWORD(Delta);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
*ShortPtr +=
|
||||
HIWORD(Delta) + ((LOWORD(Delta) & 0x8000) ? 1 : 0);
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
*ShortPtr += LOWORD(Delta);
|
||||
break;
|
||||
@@ -528,8 +549,13 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||
*LongPtr += Delta;
|
||||
break;
|
||||
|
||||
case IMAGE_REL_BASED_MIPS_JMPADDR:
|
||||
LongPtr = (PULONG)ShortPtr;
|
||||
*LongPtr = SignExtend24(*LongPtr,Delta);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown relocation %d\n", *TypeOffset >> 12);
|
||||
//printf("Unknown relocation %d\n", *TypeOffset >> 12);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -540,8 +566,13 @@ FrLdrMapKernel(FILE *KernelImage)
|
||||
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
|
||||
}
|
||||
|
||||
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
|
||||
ModuleData->ModStart = (ULONG)KernelMemory;
|
||||
/* Increase the next Load Base */
|
||||
NextModuleBase = ROUND_UP((ULONG)KernelMemory + ImageSize, PAGE_SIZE);
|
||||
ModuleData->ModEnd = NextModuleBase;
|
||||
ModuleData->String = (ULONG)"ntoskrnl.exe";
|
||||
LoaderBlock.ModsCount++;
|
||||
|
||||
/* Return Success */
|
||||
return TRUE;
|
||||
@@ -580,6 +611,11 @@ FrLdrLoadModule(FILE *ModuleImage,
|
||||
ModuleData->ModStart = NextModuleBase;
|
||||
ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
|
||||
|
||||
printf("Module size %x len %x name %s\n",
|
||||
ModuleData->ModStart,
|
||||
ModuleData->ModEnd - ModuleData->ModStart,
|
||||
ModuleName);
|
||||
|
||||
/* Save name */
|
||||
strcpy(NameBuffer, ModuleName);
|
||||
ModuleData->String = (ULONG_PTR)NameBuffer;
|
||||
|
||||
@@ -230,7 +230,23 @@ inline int GetSDR1() {
|
||||
}
|
||||
|
||||
inline void SetSDR1( int sdr ) {
|
||||
#if 0
|
||||
int i,j;
|
||||
#endif
|
||||
__asm__("mtsdr1 3");
|
||||
#if 0
|
||||
__asm__("sync");
|
||||
__asm__("isync");
|
||||
__asm__("ptesync");
|
||||
|
||||
for( i = 0; i < 256; i++ ) {
|
||||
j = i << 12;
|
||||
__asm__("tlbie %0,0" : : "r" (j));
|
||||
}
|
||||
__asm__("eieio");
|
||||
__asm__("tlbsync");
|
||||
__asm__("ptesync");
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int BatHit( int bath, int batl, int virt ) {
|
||||
@@ -319,12 +335,6 @@ BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) {
|
||||
SetPhys( ptegaddr + (i * 8), ptehi );
|
||||
SetPhys( ptegaddr + (i * 8) + 4, ptelo );
|
||||
|
||||
__asm__("ptesync");
|
||||
__asm__("tlbie %0,0" : : "r" (virt));
|
||||
__asm__("eieio");
|
||||
__asm__("tlbsync");
|
||||
__asm__("ptesync");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
</directory>
|
||||
<directory name="rtl">
|
||||
<file>list.c</file>
|
||||
<file>libsupp.c</file>
|
||||
</directory>
|
||||
<directory name="ui">
|
||||
<file>gui.c</file>
|
||||
|
||||
@@ -92,8 +92,10 @@ PVOID MmAllocateMemory(ULONG MemorySize)
|
||||
if (FreePagesInLookupTable < PagesNeeded)
|
||||
{
|
||||
#ifdef _M_PPC
|
||||
ULONG ptr;
|
||||
printf("Allocating %d bytes directly ...\n", MemorySize);
|
||||
MemPointer = (PVOID)ofw_claim(0,MemorySize,MM_PAGE_SIZE);
|
||||
ptr = ofw_claim(0,MemorySize,MM_PAGE_SIZE);
|
||||
MemPointer = (PVOID)(REV(ptr));
|
||||
#endif
|
||||
if( !MemPointer )
|
||||
{
|
||||
|
||||
@@ -30,8 +30,13 @@ LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded f
|
||||
char reactos_module_strings[64][256]; // Array to hold module names
|
||||
unsigned long reactos_memory_map_descriptor_size;
|
||||
memory_map_t reactos_memory_map[32]; // Memory map
|
||||
|
||||
ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information
|
||||
char reactos_arc_strings[32][256];
|
||||
unsigned long reactos_disk_count = 0;
|
||||
CHAR szHalName[255];
|
||||
CHAR szBootPath[255];
|
||||
static CHAR szLoadingMsg[] = "Loading ReactOS...";
|
||||
BOOLEAN FrLdrBootType;
|
||||
|
||||
static BOOLEAN
|
||||
NTAPI
|
||||
@@ -123,6 +128,7 @@ LoadKernelSymbols(PCHAR szKernelName, int nPos)
|
||||
PROSSYM_INFO RosSymInfo;
|
||||
ULONG Size;
|
||||
ULONG_PTR Base;
|
||||
//return TRUE;
|
||||
|
||||
RosSymInit(&FreeldrCallbacks);
|
||||
|
||||
@@ -562,14 +568,12 @@ VOID
|
||||
LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
{
|
||||
PFILE FilePointer;
|
||||
CHAR name[1024];
|
||||
CHAR value[1024];
|
||||
CHAR SystemPath[1024];
|
||||
CHAR szKernelName[1024];
|
||||
CHAR szHalName[1024];
|
||||
CHAR szFileName[1024];
|
||||
CHAR szBootPath[256];
|
||||
UINT i;
|
||||
CHAR name[255];
|
||||
CHAR value[255];
|
||||
CHAR SystemPath[255];
|
||||
CHAR szKernelName[255];
|
||||
CHAR szFileName[255];
|
||||
UINT i;
|
||||
CHAR MsgBuffer[256];
|
||||
ULONG SectionId;
|
||||
|
||||
@@ -595,6 +599,8 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
UiDrawStatusText("Detecting Hardware...");
|
||||
UiDrawProgressBarCenter(1, 100, szLoadingMsg);
|
||||
|
||||
printf("LoadAndBootReactOS\n");
|
||||
|
||||
/*
|
||||
* Setup multiboot information structure
|
||||
*/
|
||||
@@ -602,17 +608,21 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
|
||||
LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
|
||||
LoaderBlock.BootDevice = 0xffffffff;
|
||||
LoaderBlock.CommandLine = (unsigned long)reactos_kernel_cmdline;
|
||||
LoaderBlock.CommandLine = (ULONG)reactos_kernel_cmdline;
|
||||
LoaderBlock.ModsCount = 0;
|
||||
LoaderBlock.ModsAddr = (unsigned long)reactos_modules;
|
||||
LoaderBlock.ModsAddr = (ULONG)reactos_modules;
|
||||
LoaderBlock.DrivesAddr = (ULONG)reactos_arc_disk_info;
|
||||
LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t);
|
||||
printf("Got memory map length: %d\n", LoaderBlock.MmapLength);
|
||||
if (LoaderBlock.MmapLength)
|
||||
{
|
||||
LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
|
||||
LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
|
||||
reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
|
||||
*((PULONG)(LoaderBlock.MmapAddr - sizeof(ULONG))) =
|
||||
reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
|
||||
DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", LoaderBlock.MmapLength));
|
||||
DbgPrint((DPRINT_REACTOS, "dumping memory map:\n"));
|
||||
printf("memory map length: %d\n", LoaderBlock.MmapLength);
|
||||
for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
|
||||
{
|
||||
if (BiosMemoryUsable == reactos_memory_map[i].type &&
|
||||
@@ -634,6 +644,10 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
reactos_memory_map[i].base_addr_low,
|
||||
reactos_memory_map[i].length_low,
|
||||
reactos_memory_map[i].type));
|
||||
printf("start: %x size: %x type %d\n",
|
||||
reactos_memory_map[i].base_addr_low,
|
||||
reactos_memory_map[i].length_low,
|
||||
reactos_memory_map[i].type);
|
||||
}
|
||||
}
|
||||
DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", LoaderBlock.MemLower));
|
||||
@@ -679,7 +693,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
/*
|
||||
* Read the optional kernel parameters (if any)
|
||||
*/
|
||||
if (IniReadSettingByName(SectionId, "Options", value, 1024))
|
||||
if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
|
||||
{
|
||||
strcat(reactos_kernel_cmdline, " ");
|
||||
strcat(reactos_kernel_cmdline, value);
|
||||
@@ -692,6 +706,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
UiDrawProgressBarCenter(5, 100, szLoadingMsg);
|
||||
|
||||
if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
|
||||
LoaderBlock.DrivesCount = reactos_disk_count;
|
||||
|
||||
UiDrawStatusText("Loading...");
|
||||
|
||||
@@ -715,7 +730,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
* Find the kernel image name
|
||||
* and try to load the kernel off the disk
|
||||
*/
|
||||
if(IniReadSettingByName(SectionId, "Kernel", value, 1024))
|
||||
if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value)))
|
||||
{
|
||||
/*
|
||||
* Set the name and
|
||||
@@ -739,13 +754,11 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
strcat(szKernelName, value);
|
||||
}
|
||||
|
||||
if (!FrLdrLoadKernel(szKernelName, 5)) return;
|
||||
|
||||
/*
|
||||
* Find the HAL image name
|
||||
* and try to load the kernel off the disk
|
||||
*/
|
||||
if(IniReadSettingByName(SectionId, "Hal", value, 1024))
|
||||
if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value)))
|
||||
{
|
||||
/*
|
||||
* Set the name and
|
||||
@@ -769,19 +782,10 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
strcat(szHalName, value);
|
||||
}
|
||||
|
||||
if (!FrLdrLoadDriver(szHalName, 10))
|
||||
return;
|
||||
/* Load the kernel */
|
||||
if (!FrLdrLoadKernel(szKernelName, 5)) return;
|
||||
if (!FrLdrLoadDriver(szHalName, 6)) return;
|
||||
|
||||
#if 0
|
||||
/* Load bootvid */
|
||||
strcpy(value, "INBV.DLL");
|
||||
strcpy(szHalName, szBootPath);
|
||||
strcat(szHalName, "SYSTEM32\\");
|
||||
strcat(szHalName, value);
|
||||
|
||||
if (!FrLdrLoadDriver(szHalName, 10))
|
||||
return;
|
||||
#endif
|
||||
/*
|
||||
* Load the System hive from disk
|
||||
*/
|
||||
@@ -820,11 +824,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
/*
|
||||
* Import the loaded system hive
|
||||
*/
|
||||
if( !RegImportBinaryHive((PCHAR)Base, Size) )
|
||||
{
|
||||
printf("Could not load system hive\n");
|
||||
return;
|
||||
}
|
||||
RegImportBinaryHive((PCHAR)Base, Size);
|
||||
|
||||
/*
|
||||
* Initialize the 'CurrentControlSet' link
|
||||
@@ -874,8 +874,7 @@ LoadAndBootReactOS(PCSTR OperatingSystemName)
|
||||
|
||||
#undef DbgPrint
|
||||
ULONG
|
||||
__cdecl
|
||||
DbgPrint(PCCH Format, ...)
|
||||
DbgPrint(const char *Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
CHAR Buffer[512];
|
||||
|
||||
@@ -21,6 +21,15 @@
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
|
||||
IN PCH DllName,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
WinLdrScanImportDescriptorTable(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
|
||||
IN PCCH DirectoryPath,
|
||||
|
||||
@@ -26,8 +26,25 @@
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
//FIXME: Do a better way to retrieve Arc disk information
|
||||
extern ULONG reactos_disk_count;
|
||||
extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
|
||||
extern char reactos_arc_strings[32][256];
|
||||
|
||||
ARC_DISK_SIGNATURE BldrDiskInfo[32];
|
||||
CHAR BldrArcNames[32][256];
|
||||
|
||||
BOOLEAN
|
||||
WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
|
||||
IN PCH DllName,
|
||||
OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
|
||||
|
||||
// debug stuff
|
||||
VOID DumpMemoryAllocMap(VOID);
|
||||
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
|
||||
|
||||
void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
@@ -85,6 +102,14 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
|
||||
InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||
InitializeListHead(&LoaderBlock->BootDriverListHead);
|
||||
|
||||
/* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
|
||||
LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
|
||||
if (LoaderBlock->NlsData == NULL)
|
||||
{
|
||||
UiMessageBox("Failed to allocate memory for NLS table data!");
|
||||
return;
|
||||
}
|
||||
RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
|
||||
|
||||
*OutLoaderBlock = LoaderBlock;
|
||||
}
|
||||
@@ -95,11 +120,12 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
//CHAR Options[] = "/CRASHDEBUG /DEBUGPORT=COM1 /BAUDRATE=115200";
|
||||
CHAR Options[] = "/NODEBUG";
|
||||
CHAR SystemRoot[] = "\\WINNT";
|
||||
CHAR SystemRoot[] = "\\WINNT\\";
|
||||
CHAR HalPath[] = "\\";
|
||||
CHAR ArcBoot[] = "multi(0)disk(0)rdisk(1)partition(1)";
|
||||
CHAR ArcHal[] = "multi(0)disk(0)rdisk(1)partition(1)";
|
||||
|
||||
ULONG i;
|
||||
PLOADER_PARAMETER_EXTENSION Extension;
|
||||
|
||||
LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support
|
||||
@@ -132,18 +158,32 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
/* Arc devices */
|
||||
LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmAllocateMemory(sizeof(ARC_DISK_INFORMATION));
|
||||
InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
|
||||
|
||||
/* Convert ARC disk information from freeldr to a correct format */
|
||||
for (i = 0; i < reactos_disk_count; i++)
|
||||
{
|
||||
PARC_DISK_SIGNATURE ArcDiskInfo;
|
||||
|
||||
/* Get the ARC structure */
|
||||
ArcDiskInfo = &BldrDiskInfo[i];
|
||||
|
||||
/* Copy the data over */
|
||||
ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
|
||||
ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
|
||||
|
||||
/* Copy the ARC Name */
|
||||
strcpy(BldrArcNames[i], reactos_arc_disk_info[i].ArcName);
|
||||
ArcDiskInfo->ArcName = BldrArcNames[i];
|
||||
|
||||
/* Insert into the list */
|
||||
InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
|
||||
&ArcDiskInfo->ListEntry);
|
||||
}
|
||||
|
||||
/* Convert the list to virtual address */
|
||||
List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
|
||||
LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
|
||||
|
||||
/* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
|
||||
LoaderBlock->NlsData = MmAllocateMemory(sizeof(NLS_DATA_BLOCK));
|
||||
if (LoaderBlock->NlsData == NULL)
|
||||
{
|
||||
UiMessageBox("Failed to allocate memory for NLS table data!");
|
||||
return;
|
||||
}
|
||||
RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
|
||||
|
||||
/* Create configuration entries */
|
||||
InitializeHWConfig(LoaderBlock);
|
||||
|
||||
@@ -224,6 +264,111 @@ void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
RtlZeroMemory(*GdtIdt, NumPages << MM_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
LPSTR BootPath,
|
||||
PUNICODE_STRING FilePath,
|
||||
ULONG Flags,
|
||||
PLDR_DATA_TABLE_ENTRY *DriverDTE)
|
||||
{
|
||||
CHAR FullPath[1024];
|
||||
CHAR DriverPath[1024];
|
||||
CHAR DllName[1024];
|
||||
PCHAR DriverNamePos;
|
||||
BOOLEAN Status;
|
||||
PVOID DriverBase;
|
||||
|
||||
// Separate the path to file name and directory path
|
||||
sprintf(DriverPath, "%wZ", FilePath);
|
||||
DriverNamePos = strrchr(DriverPath, '\\');
|
||||
if (DriverNamePos != NULL)
|
||||
{
|
||||
// Copy the name
|
||||
strcpy(DllName, DriverNamePos+1);
|
||||
|
||||
// Cut out the name from the path
|
||||
*(DriverNamePos+1) = 0;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock));
|
||||
|
||||
|
||||
// Check if driver is already loaded
|
||||
Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
|
||||
if (Status)
|
||||
{
|
||||
// We've got the pointer to its DTE, just return success
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// It's not loaded, we have to load it
|
||||
sprintf(FullPath,"%s%wZ", BootPath, FilePath);
|
||||
Status = WinLdrLoadImage(FullPath, &DriverBase);
|
||||
if (!Status)
|
||||
return FALSE;
|
||||
|
||||
// Allocate a DTE for it
|
||||
Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
|
||||
if (!Status)
|
||||
{
|
||||
DbgPrint((DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Modify any flags, if needed
|
||||
(*DriverDTE)->Flags |= Flags;
|
||||
|
||||
// Look for any dependencies it may have, and load them too
|
||||
sprintf(FullPath,"%s%s", BootPath, DriverPath);
|
||||
Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
|
||||
if (!Status)
|
||||
{
|
||||
DbgPrint((DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
|
||||
FullPath));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
LPSTR BootPath)
|
||||
{
|
||||
PLIST_ENTRY NextBd;
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriver;
|
||||
BOOLEAN Status;
|
||||
|
||||
// Walk through the boot drivers list
|
||||
NextBd = LoaderBlock->BootDriverListHead.Flink;
|
||||
|
||||
while (NextBd != &LoaderBlock->BootDriverListHead)
|
||||
{
|
||||
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
|
||||
|
||||
//DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
|
||||
// BootDriver->DataTableEntry, &BootDriver->RegistryPath));
|
||||
|
||||
// Paths are relative (FIXME: Are they always relative?)
|
||||
|
||||
// Load it
|
||||
Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
|
||||
0, &BootDriver->DataTableEntry);
|
||||
|
||||
// If loading failed - cry loudly
|
||||
//FIXME: Maybe remove it from the list and try to continue?
|
||||
if (!Status)
|
||||
{
|
||||
UiMessageBox("Can't load boot driver!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NextBd = BootDriver->ListEntry.Flink;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
{
|
||||
@@ -243,8 +388,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
ULONG PcrBasePage=0;
|
||||
ULONG TssBasePage=0;
|
||||
|
||||
|
||||
|
||||
//sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);
|
||||
//UiMessageBox(MsgBuffer);
|
||||
|
||||
@@ -257,6 +400,13 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
return;
|
||||
}
|
||||
|
||||
UiDrawBackdrop();
|
||||
UiDrawStatusText("Detecting Hardware...");
|
||||
UiDrawProgressBarCenter(1, 100, "Loading Windows...");
|
||||
|
||||
//FIXME: This is needed only for MachHwDetect() which performs registry operations!
|
||||
RegInitializeRegistry();
|
||||
|
||||
/* Make sure the system path is set in the .ini file */
|
||||
if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
|
||||
{
|
||||
@@ -271,6 +421,9 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Detect hardware */
|
||||
MachHwDetect();
|
||||
|
||||
UiDrawStatusText("Loading...");
|
||||
|
||||
/* Try to open system drive */
|
||||
@@ -331,17 +484,16 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
if (KdComDTE)
|
||||
WinLdrScanImportDescriptorTable(LoaderBlock, SearchPath, KdComDTE);
|
||||
|
||||
/* Initialize Phase 1 - before NLS */
|
||||
WinLdrInitializePhase1(LoaderBlock);
|
||||
|
||||
/* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
|
||||
Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
|
||||
DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status));
|
||||
|
||||
/* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */
|
||||
|
||||
/* Load boot drivers */
|
||||
//WinLdrLoadBootDrivers();
|
||||
Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
|
||||
DbgPrint((DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status));
|
||||
|
||||
/* Initialize Phase 1 - no drivers loading anymore */
|
||||
WinLdrInitializePhase1(LoaderBlock);
|
||||
|
||||
/* Alloc PCR, TSS, do magic things with the GDT/IDT */
|
||||
WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
|
||||
@@ -361,6 +513,8 @@ LoadAndBootWindows(PCSTR OperatingSystemName, WORD OperatingSystemVersion)
|
||||
KiSystemStartup, LoaderBlockVA));
|
||||
|
||||
WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
|
||||
WinLdrpDumpBootDriver(LoaderBlockVA);
|
||||
WinLdrpDumpArcDisks(LoaderBlockVA);
|
||||
|
||||
//FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
|
||||
//while (1) {};
|
||||
@@ -394,3 +548,41 @@ WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
NextMd = MemoryDescriptor->ListEntry.Flink;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
PLIST_ENTRY NextBd;
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriver;
|
||||
|
||||
NextBd = LoaderBlock->BootDriverListHead.Flink;
|
||||
|
||||
while (NextBd != &LoaderBlock->BootDriverListHead)
|
||||
{
|
||||
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
|
||||
|
||||
DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
|
||||
BootDriver->DataTableEntry, &BootDriver->RegistryPath));
|
||||
|
||||
NextBd = BootDriver->ListEntry.Flink;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
PLIST_ENTRY NextBd;
|
||||
PARC_DISK_SIGNATURE ArcDisk;
|
||||
|
||||
NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
|
||||
|
||||
while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
|
||||
{
|
||||
ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
|
||||
|
||||
DbgPrint((DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
|
||||
ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature));
|
||||
|
||||
NextBd = ArcDisk->ListEntry.Flink;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
extern ULONG TotalNLSSize;
|
||||
|
||||
// This is needed because headers define wrong one for ReactOS
|
||||
#undef KIP0PCRADDRESS
|
||||
#define KIP0PCRADDRESS 0xffdff000
|
||||
@@ -300,7 +302,7 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
// Check if it's more than the allowed for OS loader
|
||||
// if yes - don't map the pages, just add as FirmwareTemporary
|
||||
//
|
||||
if (BasePage + PageCount > LOADER_HIGH_ZONE)
|
||||
if (BasePage + PageCount > LOADER_HIGH_ZONE && (Type != LoaderNlsData))
|
||||
{
|
||||
Mad[MadCount].MemoryType = LoaderFirmwareTemporary;
|
||||
|
||||
@@ -353,24 +355,9 @@ MempAddMemoryBlock(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
else
|
||||
{
|
||||
//
|
||||
// Now choose memory type as usual. FIXME!!!
|
||||
// Set memory type
|
||||
//
|
||||
if (Type == 0)
|
||||
{
|
||||
Mad[MadCount].MemoryType = LoaderFree;
|
||||
}
|
||||
else if (Type != 0 && Type != 1)
|
||||
{
|
||||
Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
|
||||
}
|
||||
else if (Type == 1)
|
||||
{
|
||||
Mad[MadCount].MemoryType = LoaderSystemCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mad[MadCount].MemoryType = LoaderFirmwarePermanent;
|
||||
}
|
||||
Mad[MadCount].MemoryType = Type;
|
||||
|
||||
//
|
||||
// Add descriptor
|
||||
@@ -397,12 +384,15 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
ULONG TssBasePage,
|
||||
PVOID GdtIdt)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
ULONG i, PagesCount;
|
||||
ULONG LastPageIndex, LastPageType;
|
||||
ULONG LastPageIndex, LastPageType, NtType;
|
||||
PPAGE_LOOKUP_TABLE_ITEM MemoryMap;
|
||||
ULONG NoEntries;
|
||||
#if 0
|
||||
PKTSS Tss;
|
||||
#endif
|
||||
PVOID NlsBase = VaToPa(((PNLS_DATA_BLOCK)VaToPa(LoaderBlock->NlsData))->AnsiCodePageData);
|
||||
ULONG NlsBasePage = (ULONG_PTR)NlsBase >> PAGE_SHIFT;
|
||||
|
||||
//
|
||||
// Creating a suitable memory map for the Windows can be tricky, so let's
|
||||
@@ -439,7 +429,8 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries\n"));
|
||||
DbgPrint((DPRINT_WINDOWS, "Got memory map with %d entries, NlsBasePage 0x%X\n",
|
||||
NoEntries, NlsBasePage));
|
||||
|
||||
// Construct a good memory map from what we've got
|
||||
PagesCount = 1;
|
||||
@@ -447,14 +438,67 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
LastPageType = MemoryMap[0].PageAllocated;
|
||||
for(i=1;i<NoEntries;i++)
|
||||
{
|
||||
if (MemoryMap[i].PageAllocated == LastPageType)
|
||||
if (MemoryMap[i].PageAllocated == LastPageType &&
|
||||
(i < NlsBasePage || i > NlsBasePage+TotalNLSSize) && (i != NoEntries-1) )
|
||||
{
|
||||
PagesCount++;
|
||||
}
|
||||
else if (i == NlsBasePage)
|
||||
{
|
||||
// This is NLS data, map it accordingly
|
||||
// It's VERY important for NT kernel - it calculates size of NLS
|
||||
// tables based on NlsData memory type descriptors!
|
||||
|
||||
// Firstly map what we already have (if we have any)
|
||||
// Convert mem types
|
||||
if (LastPageType == 0)
|
||||
NtType = LoaderFree;
|
||||
else if (LastPageType != 0 && LastPageType != 1)
|
||||
NtType = LoaderFirmwarePermanent;
|
||||
else if (LastPageType == 1)
|
||||
NtType = LoaderSystemCode;
|
||||
else
|
||||
NtType = LoaderFirmwarePermanent;
|
||||
|
||||
if (PagesCount > 0)
|
||||
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
|
||||
|
||||
// Then map nls data
|
||||
MempAddMemoryBlock(LoaderBlock, NlsBasePage, TotalNLSSize, LoaderNlsData);
|
||||
|
||||
// skip them
|
||||
i += TotalNLSSize;
|
||||
|
||||
// Reset our counter vars
|
||||
LastPageIndex = i;
|
||||
LastPageType = MemoryMap[i].PageAllocated;
|
||||
PagesCount = 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the region
|
||||
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, LastPageType);
|
||||
// Add the resulting region
|
||||
|
||||
// Convert mem types
|
||||
if (LastPageType == 0)
|
||||
{
|
||||
NtType = LoaderFree;
|
||||
}
|
||||
else if (LastPageType != 0 && LastPageType != 1)
|
||||
{
|
||||
NtType = LoaderFirmwarePermanent;
|
||||
}
|
||||
else if (LastPageType == 1)
|
||||
{
|
||||
NtType = LoaderSystemCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
NtType = LoaderFirmwarePermanent;
|
||||
}
|
||||
|
||||
MempAddMemoryBlock(LoaderBlock, LastPageIndex, PagesCount, NtType);
|
||||
|
||||
// Reset our counter vars
|
||||
LastPageIndex = i;
|
||||
@@ -480,6 +524,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
|
||||
// Page Tables have been setup, make special handling for PCR and TSS
|
||||
// (which is done in BlSetupFotNt in usual ntldr)
|
||||
#ifdef _M_IX86
|
||||
HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].PageFrameNumber = PcrBasePage+1;
|
||||
HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Valid = 1;
|
||||
HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> MM_PAGE_SHIFT].Write = 1;
|
||||
@@ -493,6 +538,7 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
//DbgPrint((DPRINT_WINDOWS, "VideoMemoryBase: 0x%X\n", VideoMemoryBase));
|
||||
|
||||
Tss = (PKTSS)(KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
|
||||
#endif
|
||||
|
||||
// Fill the memory descriptor list and
|
||||
//PrepareMemoryDescriptorList();
|
||||
@@ -525,23 +571,29 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
//BS->ExitBootServices(ImageHandle,MapKey);
|
||||
|
||||
// Disable Interrupts
|
||||
Ke386DisableInterrupts();
|
||||
_disable();
|
||||
|
||||
// Re-initalize EFLAGS
|
||||
#ifdef _M_IX86
|
||||
Ke386EraseFlags();
|
||||
#endif
|
||||
|
||||
// Set the PDBR
|
||||
Ke386SetPageTableDirectory((ULONG_PTR)PDE);
|
||||
#ifdef _M_IX86
|
||||
__writecr3((ULONG_PTR)PDE);
|
||||
#endif
|
||||
|
||||
// Enable paging by modifying CR0
|
||||
Ke386SetCr0(Ke386GetCr0() | CR0_PG);
|
||||
#ifdef _M_IX86
|
||||
__writecr0(__readcr0() | CR0_PG);
|
||||
#endif
|
||||
|
||||
// Set processor context
|
||||
WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT));
|
||||
WinLdrSetProcessorContext(GdtIdt, KIP0PCRADDRESS, 0/*KSEG0_BASE | (TssBasePage << MM_PAGE_SHIFT)*/);
|
||||
|
||||
// Zero KI_USER_SHARED_DATA page
|
||||
memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,23 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
// The only global var here, used to mark mem pages as NLS in WinLdrTurnOnPaging()
|
||||
ULONG TotalNLSSize = 0;
|
||||
|
||||
BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName,
|
||||
LPSTR OemName,
|
||||
LPSTR LangName);
|
||||
|
||||
VOID
|
||||
WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN LPCSTR DirectoryPath);
|
||||
|
||||
BOOLEAN
|
||||
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
||||
LPWSTR RegistryPath,
|
||||
LPWSTR ImagePath,
|
||||
LPWSTR ServiceName);
|
||||
|
||||
BOOLEAN
|
||||
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN LPCSTR DirectoryPath,
|
||||
@@ -96,6 +113,9 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* PRIVATE FUNCTIONS ******************************************************/
|
||||
|
||||
// Queries registry for those three file names
|
||||
BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName,
|
||||
LPSTR OemName,
|
||||
@@ -315,6 +335,9 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
MM_SIZE_TO_PAGES(OemFileSize) +
|
||||
MM_SIZE_TO_PAGES(LanguageFileSize);
|
||||
|
||||
/* Store it for later marking the pages as NlsData type */
|
||||
TotalNLSSize = TotalSize;
|
||||
|
||||
NlsDataBase = (ULONG_PTR)MmAllocateMemory(TotalSize*MM_PAGE_SIZE);
|
||||
|
||||
if (NlsDataBase == 0)
|
||||
@@ -401,3 +424,317 @@ Failure:
|
||||
UiMessageBox("Error reading NLS file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN LPCSTR DirectoryPath)
|
||||
{
|
||||
LONG rc = 0;
|
||||
FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
|
||||
WCHAR GroupNameBuffer[512];
|
||||
WCHAR ServiceName[256];
|
||||
ULONG OrderList[128];
|
||||
ULONG BufferSize;
|
||||
ULONG Index;
|
||||
ULONG TagIndex;
|
||||
LPWSTR GroupName;
|
||||
|
||||
ULONG ValueSize;
|
||||
ULONG ValueType;
|
||||
ULONG StartValue;
|
||||
ULONG TagValue;
|
||||
WCHAR DriverGroup[256];
|
||||
ULONG DriverGroupSize;
|
||||
|
||||
CHAR ImagePath[256];
|
||||
WCHAR TempImagePath[256];
|
||||
|
||||
BOOLEAN Status;
|
||||
|
||||
/* get 'service group order' key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
|
||||
&hGroupKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc));
|
||||
return;
|
||||
}
|
||||
|
||||
/* get 'group order list' key */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
|
||||
&hOrderKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc));
|
||||
return;
|
||||
}
|
||||
|
||||
/* enumerate drivers */
|
||||
rc = RegOpenKey(NULL,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
|
||||
&hServiceKey);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
|
||||
DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the Name Group */
|
||||
BufferSize = sizeof(GroupNameBuffer);
|
||||
rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
|
||||
DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc));
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return;
|
||||
DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize));
|
||||
DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer));
|
||||
|
||||
/* Loop through each group */
|
||||
GroupName = GroupNameBuffer;
|
||||
while (*GroupName)
|
||||
{
|
||||
DbgPrint((DPRINT_WINDOWS, "Driver group: '%S'\n", GroupName));
|
||||
|
||||
/* Query the Order */
|
||||
BufferSize = sizeof(OrderList);
|
||||
rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) OrderList[0] = 0;
|
||||
|
||||
/* enumerate all drivers */
|
||||
for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
|
||||
{
|
||||
Index = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
|
||||
//DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
|
||||
|
||||
/* Makre sure it's valid, and check if we're done */
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return;
|
||||
//DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
|
||||
|
||||
/* open driver Key */
|
||||
rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
//DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
//DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
//DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
|
||||
|
||||
/* Make sure it should be started */
|
||||
if ((StartValue == 0) &&
|
||||
(TagValue == OrderList[TagIndex]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0)) {
|
||||
|
||||
/* Get the Driver's Location */
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
|
||||
/* Write the whole path if it suceeded, else prepare to fail */
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
|
||||
TempImagePath[0] = 0;
|
||||
sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName);
|
||||
} else if (TempImagePath[0] != L'\\') {
|
||||
sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
|
||||
} else {
|
||||
sprintf(ImagePath, "%S", TempImagePath);
|
||||
DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
|
||||
}
|
||||
|
||||
DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n", ImagePath));
|
||||
|
||||
Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
TempImagePath,
|
||||
ServiceName);
|
||||
|
||||
if (!Status)
|
||||
DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
|
||||
} else
|
||||
{
|
||||
//DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
|
||||
// ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
|
||||
}
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
Index = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
|
||||
|
||||
//DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return;
|
||||
//DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
|
||||
|
||||
/* open driver Key */
|
||||
rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
{
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
//DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
//DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
//DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
|
||||
|
||||
for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
|
||||
if (TagValue == OrderList[TagIndex]) break;
|
||||
}
|
||||
|
||||
if ((StartValue == 0) &&
|
||||
(TagIndex > OrderList[0]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0)) {
|
||||
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) {
|
||||
DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
|
||||
TempImagePath[0] = 0;
|
||||
sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName);
|
||||
} else if (TempImagePath[0] != L'\\') {
|
||||
sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
|
||||
} else {
|
||||
sprintf(ImagePath, "%S", TempImagePath);
|
||||
DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
|
||||
}
|
||||
DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n", ImagePath));
|
||||
|
||||
Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
TempImagePath,
|
||||
ServiceName);
|
||||
|
||||
if (!Status)
|
||||
DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
|
||||
} else
|
||||
{
|
||||
//DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
|
||||
// ServiceName, StartValue, TagValue, DriverGroup, GroupName));
|
||||
}
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
/* Move to the next group name */
|
||||
GroupName = GroupName + wcslen(GroupName) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
||||
LPWSTR RegistryPath,
|
||||
LPWSTR ImagePath,
|
||||
LPWSTR ServiceName)
|
||||
{
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
|
||||
NTSTATUS Status;
|
||||
ULONG PathLength;
|
||||
|
||||
BootDriverEntry = MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY));
|
||||
|
||||
if (!BootDriverEntry)
|
||||
return FALSE;
|
||||
|
||||
// DTE will be filled during actual load of the driver
|
||||
BootDriverEntry->DataTableEntry = NULL;
|
||||
|
||||
// Check - if we have a valid ImagePath, if not - we need to build it
|
||||
// like "System32\\Drivers\\blah.sys"
|
||||
if (ImagePath && (wcslen(ImagePath) > 0))
|
||||
{
|
||||
// Just copy ImagePath to the corresponding field in the structure
|
||||
PathLength = wcslen(ImagePath) * sizeof(WCHAR);
|
||||
|
||||
BootDriverEntry->FilePath.Length = 0;
|
||||
BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR);
|
||||
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
|
||||
|
||||
if (!BootDriverEntry->FilePath.Buffer)
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have to construct ImagePath ourselves
|
||||
PathLength = wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");;
|
||||
BootDriverEntry->FilePath.Length = 0;
|
||||
BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR);
|
||||
BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
|
||||
|
||||
if (!BootDriverEntry->FilePath.Buffer)
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add registry path
|
||||
PathLength = wcslen(RegistryPath)*sizeof(WCHAR);
|
||||
BootDriverEntry->RegistryPath.Length = 0;
|
||||
BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR);
|
||||
BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength);
|
||||
if (!BootDriverEntry->RegistryPath.Buffer)
|
||||
return FALSE;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
// Insert entry at top of the list
|
||||
InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+1108
-1133
File diff suppressed because it is too large
Load Diff
@@ -646,4 +646,6 @@ typedef struct _KEXCEPTION_FRAME
|
||||
DOUBLE Fpr31;
|
||||
} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||
|
||||
#define KeGetPreviousMode ExGetPreviousMode
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,7 +62,7 @@ extern "C" {
|
||||
#elif (_MSC_VER)
|
||||
#define FORCEINLINE __inline
|
||||
#else
|
||||
#define FORCEINLINE static __inline
|
||||
#define FORCEINLINE static __attribute__((unused))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -65,6 +65,27 @@ typedef struct _MEMORY_ALLOCATION_DESCRIPTOR
|
||||
ULONG PageCount;
|
||||
} MEMORY_ALLOCATION_DESCRIPTOR, *PMEMORY_ALLOCATION_DESCRIPTOR;
|
||||
|
||||
typedef struct _BOOT_DRIVER_LIST_ENTRY
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
UNICODE_STRING FilePath;
|
||||
UNICODE_STRING RegistryPath;
|
||||
struct _LDR_DATA_TABLE_ENTRY *DataTableEntry;
|
||||
} BOOT_DRIVER_LIST_ENTRY, *PBOOT_DRIVER_LIST_ENTRY;
|
||||
|
||||
typedef struct _ARC_DISK_SIGNATURE
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG Signature;
|
||||
PCHAR ArcName;
|
||||
ULONG CheckSum;
|
||||
BOOLEAN ValidPartitionTable;
|
||||
BOOLEAN xInt13;
|
||||
BOOLEAN IsGpt;
|
||||
BOOLEAN Reserved;
|
||||
CHAR GptSignature[16];
|
||||
} ARC_DISK_SIGNATURE, *PARC_DISK_SIGNATURE;
|
||||
|
||||
typedef struct _CONFIGURATION_COMPONENT
|
||||
{
|
||||
CONFIGURATION_CLASS Class;
|
||||
@@ -268,6 +289,11 @@ typedef struct _I386_LOADER_BLOCK
|
||||
ULONG Reserved;
|
||||
} I386_LOADER_BLOCK, *PI386_LOADER_BLOCK;
|
||||
|
||||
typedef struct _POWERPC_LOADER_BLOCK
|
||||
{
|
||||
PVOID BootInfo;
|
||||
} POWERPC_LOADER_BLOCK, *PPOWERPC_LOADER_BLOCK;
|
||||
|
||||
//
|
||||
// Loader Parameter Block
|
||||
//
|
||||
@@ -298,6 +324,7 @@ typedef struct _LOADER_PARAMETER_BLOCK
|
||||
I386_LOADER_BLOCK I386;
|
||||
ALPHA_LOADER_BLOCK Alpha;
|
||||
IA64_LOADER_BLOCK Ia64;
|
||||
POWERPC_LOADER_BLOCK PowerPC;
|
||||
} u;
|
||||
} LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _ARCH_POWERPC_FONT_H
|
||||
#define _ARCH_POWERPC_FONT_H
|
||||
|
||||
font_char BootDigits[16] = {
|
||||
font_char BootDigits[37] = {
|
||||
" XXXXX "
|
||||
"X X "
|
||||
"X x X "
|
||||
@@ -113,6 +113,146 @@ font_char BootDigits[16] = {
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" ",
|
||||
" XXXX "
|
||||
" X X "
|
||||
" X "
|
||||
" X XX "
|
||||
" X X "
|
||||
" XXXXX "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" ",
|
||||
" XXXX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XXXX "
|
||||
" ",
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" X X "
|
||||
" XXXX "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" ",
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" XXXXXX "
|
||||
" ",
|
||||
" X X "
|
||||
" X XX X "
|
||||
" X XX X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" ",
|
||||
" X X "
|
||||
" XX X "
|
||||
" X X X "
|
||||
" X X X "
|
||||
" X XX "
|
||||
" X X "
|
||||
" ",
|
||||
" XXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXX "
|
||||
" ",
|
||||
" XXXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXXX "
|
||||
" X "
|
||||
" X "
|
||||
" ",
|
||||
" XXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X X "
|
||||
" X XXX "
|
||||
" XXXXX "
|
||||
" ",
|
||||
" XXXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXXX "
|
||||
" X X "
|
||||
" X X "
|
||||
" ",
|
||||
" XXXXX "
|
||||
" X "
|
||||
" XXXX "
|
||||
" X "
|
||||
" X "
|
||||
" XXXXX "
|
||||
" ",
|
||||
" XXXXXX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXX "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XX "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X XX X "
|
||||
" X XX X "
|
||||
" X X "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" XX "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" ",
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XX "
|
||||
" XX "
|
||||
" XX "
|
||||
" ",
|
||||
" XXXXXX "
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" X "
|
||||
" XXXXXX "
|
||||
" "
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
typedef char font_char[57];
|
||||
typedef struct _boot_infos_t {
|
||||
void *loaderBlock;
|
||||
int dispDeviceRect[4];
|
||||
int dispDeviceRowBytes;
|
||||
int dispDeviceDepth;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _PPCDEBUG_H
|
||||
#define _PPCDEBUG_H
|
||||
|
||||
#include "ppcboot.h"
|
||||
|
||||
extern struct _boot_infos_t *BootInfo;
|
||||
extern void DrawNumber(struct _boot_infos_t *, unsigned long, int, int);
|
||||
extern void DrawString(struct _boot_infos_t *, const char *, int, int);
|
||||
#define TRACEXY(x,y) do { \
|
||||
unsigned long _x_ = (unsigned long)(x), _y_ = (unsigned long)(y); \
|
||||
__asm__("ori 0,0,0"); \
|
||||
DrawNumber(BootInfo, __LINE__, 10, 160); \
|
||||
DrawString(BootInfo, __FILE__, 100, 160); \
|
||||
DrawNumber(BootInfo, _x_, 400, 160); \
|
||||
DrawNumber(BootInfo, _y_, 490, 160); \
|
||||
} while(0)
|
||||
#define TRACEX(x) TRACEXY(x,0)
|
||||
#define TRACE TRACEX(0)
|
||||
|
||||
#endif//_PPCDEBUG_H
|
||||
@@ -42,6 +42,7 @@ typedef struct _ROS_LOADER_PARAMETER_BLOCK
|
||||
ULONG PageDirectoryStart;
|
||||
ULONG PageDirectoryEnd;
|
||||
ULONG KernelBase;
|
||||
ULONG ArchExtra;
|
||||
} ROS_LOADER_PARAMETER_BLOCK, *PROS_LOADER_PARAMETER_BLOCK;
|
||||
|
||||
extern ULONG MmFreeLdrMemHigher, MmFreeLdrMemLower;
|
||||
|
||||
+154
-154
@@ -1,154 +1,154 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef CMLIB_CMDATA_H
|
||||
#define CMLIB_CMDATA_H
|
||||
|
||||
#define REG_INIT_BLOCK_LIST_SIZE 32
|
||||
#define REG_INIT_HASH_TABLE_SIZE 3
|
||||
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
||||
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
||||
|
||||
#define REG_KEY_CELL_ID 0x6b6e
|
||||
#define REG_HASH_TABLE_CELL_ID 0x666c
|
||||
#define REG_VALUE_CELL_ID 0x6b76
|
||||
#define REG_SECURITY_CELL_ID 0x6b73
|
||||
|
||||
#ifndef _CM_
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef struct _CM_VIEW_OF_FILE
|
||||
{
|
||||
LIST_ENTRY LRUViewList;
|
||||
LIST_ENTRY PinViewList;
|
||||
ULONG FileOffset;
|
||||
ULONG Size;
|
||||
PULONG ViewAddress;
|
||||
PVOID Bcb;
|
||||
ULONG UseCount;
|
||||
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
||||
|
||||
typedef struct _CHILD_LIST
|
||||
{
|
||||
ULONG Count;
|
||||
HCELL_INDEX List;
|
||||
} CHILD_LIST, *PCHILD_LIST;
|
||||
|
||||
typedef struct _CM_KEY_NODE
|
||||
{
|
||||
/* Key cell identifier "kn" (0x6b6e) */
|
||||
USHORT Id;
|
||||
|
||||
/* Flags */
|
||||
USHORT Flags;
|
||||
|
||||
/* Time of last flush */
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
|
||||
ULONG Spare;
|
||||
|
||||
/* BlockAddress offset of parent key cell */
|
||||
HCELL_INDEX Parent;
|
||||
|
||||
/* Count of sub keys for the key in this key cell (stable & volatile) */
|
||||
ULONG SubKeyCounts[HvMaxStorageType];
|
||||
|
||||
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */
|
||||
HCELL_INDEX SubKeyLists[HvMaxStorageType];
|
||||
|
||||
CHILD_LIST ValueList;
|
||||
|
||||
/* BlockAddress offset of security cell */
|
||||
HCELL_INDEX SecurityKeyOffset;
|
||||
|
||||
/* BlockAddress offset of registry key class */
|
||||
HCELL_INDEX ClassNameOffset;
|
||||
|
||||
ULONG MaxNameLen;
|
||||
ULONG MaxClassLen;
|
||||
ULONG MaxValueNameLen;
|
||||
ULONG MaxValueDataLen;
|
||||
ULONG WorkVar;
|
||||
|
||||
/* Size in bytes of key name */
|
||||
USHORT NameSize;
|
||||
|
||||
/* Size of class name in bytes */
|
||||
USHORT ClassSize;
|
||||
|
||||
/* Name of key (not zero terminated) */
|
||||
UCHAR Name[0];
|
||||
} CM_KEY_NODE, *PCM_KEY_NODE;
|
||||
|
||||
/* CM_KEY_NODE.Flags constants */
|
||||
#define REG_KEY_VOLATILE_CELL 0x01
|
||||
#define REG_KEY_ROOT_CELL 0x0C
|
||||
#define REG_KEY_LINK_CELL 0x10
|
||||
#define REG_KEY_NAME_PACKED 0x20
|
||||
|
||||
/*
|
||||
* Hash record
|
||||
*
|
||||
* HashValue:
|
||||
* packed name: four letters of value's name
|
||||
* otherwise: Zero!
|
||||
*/
|
||||
typedef struct _HASH_RECORD
|
||||
{
|
||||
HCELL_INDEX KeyOffset;
|
||||
ULONG HashValue;
|
||||
} HASH_RECORD, *PHASH_RECORD;
|
||||
|
||||
typedef struct _HASH_TABLE_CELL
|
||||
{
|
||||
USHORT Id;
|
||||
USHORT HashTableSize;
|
||||
HASH_RECORD Table[0];
|
||||
} HASH_TABLE_CELL, *PHASH_TABLE_CELL;
|
||||
|
||||
typedef struct _VALUE_LIST_CELL
|
||||
{
|
||||
HCELL_INDEX ValueOffset[0];
|
||||
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
||||
|
||||
typedef struct _CM_KEY_VALUE
|
||||
{
|
||||
USHORT Id; // "kv"
|
||||
USHORT NameSize; // length of Name
|
||||
ULONG DataSize; // length of datas in the cell pointed by DataOffset
|
||||
HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set
|
||||
ULONG DataType;
|
||||
USHORT Flags;
|
||||
USHORT Unused1;
|
||||
UCHAR Name[0]; /* warning : not zero terminated */
|
||||
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
||||
|
||||
/* CM_KEY_VALUE.Flags constants */
|
||||
#define REG_VALUE_NAME_PACKED 0x0001
|
||||
|
||||
/* CM_KEY_VALUE.DataSize mask constants */
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
typedef struct _CM_KEY_SECURITY
|
||||
{
|
||||
USHORT Signature; // "sk"
|
||||
USHORT Reserved;
|
||||
HCELL_INDEX Flink;
|
||||
HCELL_INDEX Blink;
|
||||
ULONG ReferenceCount;
|
||||
ULONG DescriptorLength;
|
||||
//SECURITY_DESCRIPTOR_RELATIVE Descriptor;
|
||||
UCHAR Data[0];
|
||||
} CM_KEY_SECURITY, *PCM_KEY_SECURITY;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CMLIB_CMDATA_H */
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef CMLIB_CMDATA_H
|
||||
#define CMLIB_CMDATA_H
|
||||
|
||||
#define REG_INIT_BLOCK_LIST_SIZE 32
|
||||
#define REG_INIT_HASH_TABLE_SIZE 3
|
||||
#define REG_EXTEND_HASH_TABLE_SIZE 4
|
||||
#define REG_VALUE_LIST_CELL_MULTIPLE 4
|
||||
|
||||
#define REG_KEY_CELL_ID 0x6b6e
|
||||
#define REG_HASH_TABLE_CELL_ID 0x666c
|
||||
#define REG_VALUE_CELL_ID 0x6b76
|
||||
#define REG_SECURITY_CELL_ID 0x6b73
|
||||
|
||||
#ifndef _CM_
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
typedef struct _CM_VIEW_OF_FILE
|
||||
{
|
||||
LIST_ENTRY LRUViewList;
|
||||
LIST_ENTRY PinViewList;
|
||||
ULONG FileOffset;
|
||||
ULONG Size;
|
||||
PULONG ViewAddress;
|
||||
PVOID Bcb;
|
||||
ULONG UseCount;
|
||||
} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
|
||||
|
||||
typedef struct _CHILD_LIST
|
||||
{
|
||||
ULONG Count;
|
||||
HCELL_INDEX List;
|
||||
} CHILD_LIST, *PCHILD_LIST;
|
||||
|
||||
typedef struct _CM_KEY_NODE
|
||||
{
|
||||
/* Key cell identifier "kn" (0x6b6e) */
|
||||
USHORT Id;
|
||||
|
||||
/* Flags */
|
||||
USHORT Flags;
|
||||
|
||||
/* Time of last flush */
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
|
||||
ULONG Spare;
|
||||
|
||||
/* BlockAddress offset of parent key cell */
|
||||
HCELL_INDEX Parent;
|
||||
|
||||
/* Count of sub keys for the key in this key cell (stable & volatile) */
|
||||
ULONG SubKeyCounts[HvMaxStorageType];
|
||||
|
||||
/* BlockAddress offset of has table for FIXME: subkeys/values? (stable & volatile) */
|
||||
HCELL_INDEX SubKeyLists[HvMaxStorageType];
|
||||
|
||||
CHILD_LIST ValueList;
|
||||
|
||||
/* BlockAddress offset of security cell */
|
||||
HCELL_INDEX SecurityKeyOffset;
|
||||
|
||||
/* BlockAddress offset of registry key class */
|
||||
HCELL_INDEX ClassNameOffset;
|
||||
|
||||
ULONG MaxNameLen;
|
||||
ULONG MaxClassLen;
|
||||
ULONG MaxValueNameLen;
|
||||
ULONG MaxValueDataLen;
|
||||
ULONG WorkVar;
|
||||
|
||||
/* Size in bytes of key name */
|
||||
USHORT NameSize;
|
||||
|
||||
/* Size of class name in bytes */
|
||||
USHORT ClassSize;
|
||||
|
||||
/* Name of key (not zero terminated) */
|
||||
UCHAR Name[0];
|
||||
} CM_KEY_NODE, *PCM_KEY_NODE;
|
||||
|
||||
/* CM_KEY_NODE.Flags constants */
|
||||
#define REG_KEY_VOLATILE_CELL 0x01
|
||||
#define REG_KEY_ROOT_CELL 0x0C
|
||||
#define REG_KEY_LINK_CELL 0x10
|
||||
#define REG_KEY_NAME_PACKED 0x20
|
||||
|
||||
/*
|
||||
* Hash record
|
||||
*
|
||||
* HashValue:
|
||||
* packed name: four letters of value's name
|
||||
* otherwise: Zero!
|
||||
*/
|
||||
typedef struct _HASH_RECORD
|
||||
{
|
||||
HCELL_INDEX KeyOffset;
|
||||
ULONG HashValue;
|
||||
} HASH_RECORD, *PHASH_RECORD;
|
||||
|
||||
typedef struct _HASH_TABLE_CELL
|
||||
{
|
||||
USHORT Id;
|
||||
USHORT HashTableSize;
|
||||
HASH_RECORD Table[0];
|
||||
} HASH_TABLE_CELL, *PHASH_TABLE_CELL;
|
||||
|
||||
typedef struct _VALUE_LIST_CELL
|
||||
{
|
||||
HCELL_INDEX ValueOffset[0];
|
||||
} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
|
||||
|
||||
typedef struct _CM_KEY_VALUE
|
||||
{
|
||||
USHORT Id; // "kv"
|
||||
USHORT NameSize; // length of Name
|
||||
ULONG DataSize; // length of datas in the cell pointed by DataOffset
|
||||
HCELL_INDEX DataOffset;// datas are here if high bit of DataSize is set
|
||||
ULONG DataType;
|
||||
USHORT Flags;
|
||||
USHORT Unused1;
|
||||
UCHAR Name[0]; /* warning : not zero terminated */
|
||||
} CM_KEY_VALUE, *PCM_KEY_VALUE;
|
||||
|
||||
/* CM_KEY_VALUE.Flags constants */
|
||||
#define REG_VALUE_NAME_PACKED 0x0001
|
||||
|
||||
/* CM_KEY_VALUE.DataSize mask constants */
|
||||
#define REG_DATA_SIZE_MASK 0x7FFFFFFF
|
||||
#define REG_DATA_IN_OFFSET 0x80000000
|
||||
|
||||
typedef struct _CM_KEY_SECURITY
|
||||
{
|
||||
USHORT Signature; // "sk"
|
||||
USHORT Reserved;
|
||||
HCELL_INDEX Flink;
|
||||
HCELL_INDEX Blink;
|
||||
ULONG ReferenceCount;
|
||||
ULONG DescriptorLength;
|
||||
//SECURITY_DESCRIPTOR_RELATIVE Descriptor;
|
||||
UCHAR Data[0];
|
||||
} CM_KEY_SECURITY, *PCM_KEY_SECURITY;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CMLIB_CMDATA_H */
|
||||
|
||||
+82
-82
@@ -1,82 +1,82 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
|
||||
BOOLEAN CMAPI
|
||||
CmCreateRootNode(
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name)
|
||||
{
|
||||
PCM_KEY_NODE KeyCell;
|
||||
HCELL_INDEX RootCellIndex;
|
||||
SIZE_T NameSize;
|
||||
|
||||
NameSize = wcslen(Name) * sizeof(WCHAR);
|
||||
RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable);
|
||||
if (RootCellIndex == HCELL_NULL)
|
||||
return FALSE;
|
||||
|
||||
Hive->HiveHeader->RootCell = RootCellIndex;
|
||||
Hive->HiveHeader->Checksum = HvpHiveHeaderChecksum(Hive->HiveHeader);
|
||||
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||
KeyCell->Id = REG_KEY_CELL_ID;
|
||||
KeyCell->Flags = REG_KEY_ROOT_CELL;
|
||||
KeyCell->LastWriteTime.QuadPart = 0;
|
||||
KeyCell->Parent = HCELL_NULL;
|
||||
KeyCell->SubKeyCounts[0] = 0;
|
||||
KeyCell->SubKeyCounts[1] = 0;
|
||||
KeyCell->SubKeyLists[0] = HCELL_NULL;
|
||||
KeyCell->SubKeyLists[1] = HCELL_NULL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NULL;
|
||||
KeyCell->SecurityKeyOffset = HCELL_NULL;
|
||||
KeyCell->ClassNameOffset = HCELL_NULL;
|
||||
KeyCell->NameSize = (USHORT)NameSize;
|
||||
KeyCell->ClassSize = 0;
|
||||
memcpy(KeyCell->Name, Name, NameSize);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
CmpPrepareKey(
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
ULONG i;
|
||||
|
||||
ASSERT(KeyCell->Id == REG_KEY_CELL_ID);
|
||||
|
||||
KeyCell->SubKeyLists[HvVolatile] = HCELL_NULL;
|
||||
KeyCell->SubKeyCounts[HvVolatile] = 0;
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[HvStable] > 0)
|
||||
{
|
||||
HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[HvStable]);
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++)
|
||||
{
|
||||
SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset);
|
||||
CmpPrepareKey(RegistryHive, SubKeyCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
CmPrepareHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
PCM_KEY_NODE RootCell;
|
||||
|
||||
RootCell = HvGetCell(RegistryHive, RegistryHive->HiveHeader->RootCell);
|
||||
CmpPrepareKey(RegistryHive, RootCell);
|
||||
}
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
|
||||
BOOLEAN CMAPI
|
||||
CmCreateRootNode(
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name)
|
||||
{
|
||||
PCM_KEY_NODE KeyCell;
|
||||
HCELL_INDEX RootCellIndex;
|
||||
SIZE_T NameSize;
|
||||
|
||||
NameSize = wcslen(Name) * sizeof(WCHAR);
|
||||
RootCellIndex = HvAllocateCell(Hive, sizeof(CM_KEY_NODE) + NameSize, HvStable);
|
||||
if (RootCellIndex == HCELL_NULL)
|
||||
return FALSE;
|
||||
|
||||
Hive->HiveHeader->RootCell = RootCellIndex;
|
||||
Hive->HiveHeader->Checksum = HvpHiveHeaderChecksum(Hive->HiveHeader);
|
||||
|
||||
KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, RootCellIndex);
|
||||
KeyCell->Id = REG_KEY_CELL_ID;
|
||||
KeyCell->Flags = REG_KEY_ROOT_CELL;
|
||||
KeyCell->LastWriteTime.QuadPart = 0;
|
||||
KeyCell->Parent = HCELL_NULL;
|
||||
KeyCell->SubKeyCounts[0] = 0;
|
||||
KeyCell->SubKeyCounts[1] = 0;
|
||||
KeyCell->SubKeyLists[0] = HCELL_NULL;
|
||||
KeyCell->SubKeyLists[1] = HCELL_NULL;
|
||||
KeyCell->ValueList.Count = 0;
|
||||
KeyCell->ValueList.List = HCELL_NULL;
|
||||
KeyCell->SecurityKeyOffset = HCELL_NULL;
|
||||
KeyCell->ClassNameOffset = HCELL_NULL;
|
||||
KeyCell->NameSize = (USHORT)NameSize;
|
||||
KeyCell->ClassSize = 0;
|
||||
memcpy(KeyCell->Name, Name, NameSize);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
CmpPrepareKey(
|
||||
PHHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell)
|
||||
{
|
||||
PCM_KEY_NODE SubKeyCell;
|
||||
PHASH_TABLE_CELL HashCell;
|
||||
ULONG i;
|
||||
|
||||
ASSERT(KeyCell->Id == REG_KEY_CELL_ID);
|
||||
|
||||
KeyCell->SubKeyLists[HvVolatile] = HCELL_NULL;
|
||||
KeyCell->SubKeyCounts[HvVolatile] = 0;
|
||||
|
||||
/* Enumerate and add subkeys */
|
||||
if (KeyCell->SubKeyCounts[HvStable] > 0)
|
||||
{
|
||||
HashCell = HvGetCell(RegistryHive, KeyCell->SubKeyLists[HvStable]);
|
||||
|
||||
for (i = 0; i < KeyCell->SubKeyCounts[HvStable]; i++)
|
||||
{
|
||||
SubKeyCell = HvGetCell(RegistryHive, HashCell->Table[i].KeyOffset);
|
||||
CmpPrepareKey(RegistryHive, SubKeyCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
CmPrepareHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
PCM_KEY_NODE RootCell;
|
||||
|
||||
RootCell = HvGetCell(RegistryHive, RegistryHive->HiveHeader->RootCell);
|
||||
CmpPrepareKey(RegistryHive, RootCell);
|
||||
}
|
||||
|
||||
+237
-237
@@ -1,237 +1,237 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef CMLIB_H
|
||||
#define CMLIB_H
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <ntddk.h>
|
||||
#include "hivedata.h"
|
||||
#include "cmdata.h"
|
||||
|
||||
#ifndef ROUND_UP
|
||||
#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
|
||||
#define ROUND_DOWN(a,b) (((a)/(b))*(b))
|
||||
#endif
|
||||
|
||||
#define CMAPI NTAPI
|
||||
|
||||
struct _HHIVE;
|
||||
|
||||
typedef PVOID (CMAPI *PGET_CELL_ROUTINE)(
|
||||
struct _HHIVE *Hive,
|
||||
HCELL_INDEX Cell);
|
||||
|
||||
typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)(
|
||||
struct _HHIVE *Hive,
|
||||
HCELL_INDEX Cell);
|
||||
|
||||
typedef PVOID (CMAPI *PALLOCATE_ROUTINE)(
|
||||
SIZE_T Size,
|
||||
BOOLEAN Paged);
|
||||
|
||||
typedef VOID (CMAPI *PFREE_ROUTINE)(
|
||||
PVOID Ptr);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileOffset,
|
||||
PVOID Buffer,
|
||||
SIZE_T BufferLength);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileOffset,
|
||||
PVOID Buffer,
|
||||
SIZE_T BufferLength);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileSize);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType);
|
||||
|
||||
typedef struct _HMAP_ENTRY
|
||||
{
|
||||
ULONG_PTR Bin;
|
||||
ULONG_PTR Block;
|
||||
struct _CM_VIEW_OF_FILE *CmHive;
|
||||
ULONG MemAlloc;
|
||||
} HMAP_ENTRY, *PHMAP_ENTRY;
|
||||
|
||||
typedef struct _HMAP_TABLE
|
||||
{
|
||||
HMAP_ENTRY Table[512];
|
||||
} HMAP_TABLE, *PHMAP_TABLE;
|
||||
|
||||
typedef struct _HMAP_DIRECTORY
|
||||
{
|
||||
PHMAP_TABLE Directory[2048];
|
||||
} HMAP_DIRECTORY, *PHMAP_DIRECTORY;
|
||||
|
||||
typedef struct _DUAL
|
||||
{
|
||||
ULONG Length;
|
||||
PHMAP_DIRECTORY Map;
|
||||
PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir;
|
||||
ULONG Guard;
|
||||
HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24];
|
||||
ULONG FreeSummary;
|
||||
LIST_ENTRY FreeBins;
|
||||
} DUAL, *PDUAL;
|
||||
|
||||
typedef struct _HHIVE
|
||||
{
|
||||
ULONG Signature;
|
||||
PGET_CELL_ROUTINE GetCellRoutine;
|
||||
PRELEASE_CELL_ROUTINE ReleaseCellRoutine;
|
||||
PALLOCATE_ROUTINE Allocate;
|
||||
PFREE_ROUTINE Free;
|
||||
PFILE_READ_ROUTINE FileRead;
|
||||
PFILE_WRITE_ROUTINE FileWrite;
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize;
|
||||
PFILE_FLUSH_ROUTINE FileFlush;
|
||||
PHBASE_BLOCK HiveHeader;
|
||||
RTL_BITMAP DirtyVector;
|
||||
ULONG DirtyCount;
|
||||
ULONG DirtyAlloc;
|
||||
ULONG BaseBlockAlloc;
|
||||
ULONG Cluster;
|
||||
BOOLEAN Flat;
|
||||
BOOLEAN ReadOnly;
|
||||
BOOLEAN Log;
|
||||
BOOLEAN DirtyFlag;
|
||||
ULONG HvBinHeadersUse;
|
||||
ULONG HvFreeCellsUse;
|
||||
ULONG HvUsedcellsUse;
|
||||
ULONG CmUsedCellsUse;
|
||||
ULONG HiveFlags;
|
||||
ULONG LogSize;
|
||||
ULONG RefreshCount;
|
||||
ULONG StorageTypeCount;
|
||||
ULONG Version;
|
||||
DUAL Storage[HvMaxStorageType];
|
||||
} HHIVE, *PHHIVE;
|
||||
|
||||
#ifndef _CM_
|
||||
typedef struct _EREGISTRY_HIVE
|
||||
{
|
||||
HHIVE Hive;
|
||||
LIST_ENTRY HiveList;
|
||||
UNICODE_STRING HiveFileName;
|
||||
UNICODE_STRING LogFileName;
|
||||
PCM_KEY_SECURITY RootSecurityCell;
|
||||
ULONG Flags;
|
||||
HANDLE HiveHandle;
|
||||
HANDLE LogHandle;
|
||||
} EREGISTRY_HIVE, *PEREGISTRY_HIVE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Public functions.
|
||||
*/
|
||||
|
||||
#define HV_OPERATION_CREATE_HIVE 0
|
||||
#define HV_OPERATION_MEMORY 1
|
||||
#define HV_OPERATION_MEMORY_INPLACE 3
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvInitialize(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG_PTR HiveData OPTIONAL,
|
||||
ULONG Cluster OPTIONAL,
|
||||
ULONG Flags,
|
||||
ULONG FileType,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
IN PUNICODE_STRING FileName);
|
||||
|
||||
VOID CMAPI
|
||||
HvFree(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
PVOID CMAPI
|
||||
HvGetCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
#define HvReleaseCell(h, c) \
|
||||
if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c)
|
||||
|
||||
LONG CMAPI
|
||||
HvGetCellSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell);
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvAllocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
SIZE_T Size,
|
||||
HV_STORAGE_TYPE Storage);
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvReallocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset,
|
||||
ULONG Size);
|
||||
|
||||
VOID CMAPI
|
||||
HvFreeCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
VOID CMAPI
|
||||
HvMarkCellDirty(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvSyncHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvWriteHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
CmCreateRootNode(
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name);
|
||||
|
||||
VOID CMAPI
|
||||
CmPrepareHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
/*
|
||||
* Private functions.
|
||||
*/
|
||||
|
||||
PHBIN CMAPI
|
||||
HvpAddBin(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage);
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHiveFreeCellList(
|
||||
PHHIVE Hive);
|
||||
|
||||
ULONG CMAPI
|
||||
HvpHiveHeaderChecksum(
|
||||
PHBASE_BLOCK HiveHeader);
|
||||
|
||||
#endif /* CMLIB_H */
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#ifndef CMLIB_H
|
||||
#define CMLIB_H
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <ntddk.h>
|
||||
#include "hivedata.h"
|
||||
#include "cmdata.h"
|
||||
|
||||
#ifndef ROUND_UP
|
||||
#define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
|
||||
#define ROUND_DOWN(a,b) (((a)/(b))*(b))
|
||||
#endif
|
||||
|
||||
#define CMAPI NTAPI
|
||||
|
||||
struct _HHIVE;
|
||||
|
||||
typedef PVOID (CMAPI *PGET_CELL_ROUTINE)(
|
||||
struct _HHIVE *Hive,
|
||||
HCELL_INDEX Cell);
|
||||
|
||||
typedef VOID (CMAPI *PRELEASE_CELL_ROUTINE)(
|
||||
struct _HHIVE *Hive,
|
||||
HCELL_INDEX Cell);
|
||||
|
||||
typedef PVOID (CMAPI *PALLOCATE_ROUTINE)(
|
||||
SIZE_T Size,
|
||||
BOOLEAN Paged);
|
||||
|
||||
typedef VOID (CMAPI *PFREE_ROUTINE)(
|
||||
PVOID Ptr);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_READ_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileOffset,
|
||||
PVOID Buffer,
|
||||
SIZE_T BufferLength);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_WRITE_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileOffset,
|
||||
PVOID Buffer,
|
||||
SIZE_T BufferLength);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_SET_SIZE_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType,
|
||||
ULONGLONG FileSize);
|
||||
|
||||
typedef BOOLEAN (CMAPI *PFILE_FLUSH_ROUTINE)(
|
||||
struct _HHIVE *RegistryHive,
|
||||
ULONG FileType);
|
||||
|
||||
typedef struct _HMAP_ENTRY
|
||||
{
|
||||
ULONG_PTR Bin;
|
||||
ULONG_PTR Block;
|
||||
struct _CM_VIEW_OF_FILE *CmHive;
|
||||
ULONG MemAlloc;
|
||||
} HMAP_ENTRY, *PHMAP_ENTRY;
|
||||
|
||||
typedef struct _HMAP_TABLE
|
||||
{
|
||||
HMAP_ENTRY Table[512];
|
||||
} HMAP_TABLE, *PHMAP_TABLE;
|
||||
|
||||
typedef struct _HMAP_DIRECTORY
|
||||
{
|
||||
PHMAP_TABLE Directory[2048];
|
||||
} HMAP_DIRECTORY, *PHMAP_DIRECTORY;
|
||||
|
||||
typedef struct _DUAL
|
||||
{
|
||||
ULONG Length;
|
||||
PHMAP_DIRECTORY Map;
|
||||
PHMAP_ENTRY BlockList; // PHMAP_TABLE SmallDir;
|
||||
ULONG Guard;
|
||||
HCELL_INDEX FreeDisplay[24]; //FREE_DISPLAY FreeDisplay[24];
|
||||
ULONG FreeSummary;
|
||||
LIST_ENTRY FreeBins;
|
||||
} DUAL, *PDUAL;
|
||||
|
||||
typedef struct _HHIVE
|
||||
{
|
||||
ULONG Signature;
|
||||
PGET_CELL_ROUTINE GetCellRoutine;
|
||||
PRELEASE_CELL_ROUTINE ReleaseCellRoutine;
|
||||
PALLOCATE_ROUTINE Allocate;
|
||||
PFREE_ROUTINE Free;
|
||||
PFILE_READ_ROUTINE FileRead;
|
||||
PFILE_WRITE_ROUTINE FileWrite;
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize;
|
||||
PFILE_FLUSH_ROUTINE FileFlush;
|
||||
PHBASE_BLOCK HiveHeader;
|
||||
RTL_BITMAP DirtyVector;
|
||||
ULONG DirtyCount;
|
||||
ULONG DirtyAlloc;
|
||||
ULONG BaseBlockAlloc;
|
||||
ULONG Cluster;
|
||||
BOOLEAN Flat;
|
||||
BOOLEAN ReadOnly;
|
||||
BOOLEAN Log;
|
||||
BOOLEAN DirtyFlag;
|
||||
ULONG HvBinHeadersUse;
|
||||
ULONG HvFreeCellsUse;
|
||||
ULONG HvUsedcellsUse;
|
||||
ULONG CmUsedCellsUse;
|
||||
ULONG HiveFlags;
|
||||
ULONG LogSize;
|
||||
ULONG RefreshCount;
|
||||
ULONG StorageTypeCount;
|
||||
ULONG Version;
|
||||
DUAL Storage[HvMaxStorageType];
|
||||
} HHIVE, *PHHIVE;
|
||||
|
||||
#ifndef _CM_
|
||||
typedef struct _EREGISTRY_HIVE
|
||||
{
|
||||
HHIVE Hive;
|
||||
LIST_ENTRY HiveList;
|
||||
UNICODE_STRING HiveFileName;
|
||||
UNICODE_STRING LogFileName;
|
||||
PCM_KEY_SECURITY RootSecurityCell;
|
||||
ULONG Flags;
|
||||
HANDLE HiveHandle;
|
||||
HANDLE LogHandle;
|
||||
} EREGISTRY_HIVE, *PEREGISTRY_HIVE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Public functions.
|
||||
*/
|
||||
|
||||
#define HV_OPERATION_CREATE_HIVE 0
|
||||
#define HV_OPERATION_MEMORY 1
|
||||
#define HV_OPERATION_MEMORY_INPLACE 3
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvInitialize(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG_PTR HiveData OPTIONAL,
|
||||
ULONG Cluster OPTIONAL,
|
||||
ULONG Flags,
|
||||
ULONG FileType,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
IN PUNICODE_STRING FileName);
|
||||
|
||||
VOID CMAPI
|
||||
HvFree(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
PVOID CMAPI
|
||||
HvGetCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
#define HvReleaseCell(h, c) \
|
||||
if (h->ReleaseCellRoutine) h->ReleaseCellRoutine(h, c)
|
||||
|
||||
LONG CMAPI
|
||||
HvGetCellSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell);
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvAllocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
SIZE_T Size,
|
||||
HV_STORAGE_TYPE Storage);
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvReallocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset,
|
||||
ULONG Size);
|
||||
|
||||
VOID CMAPI
|
||||
HvFreeCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
VOID CMAPI
|
||||
HvMarkCellDirty(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellOffset);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvSyncHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvWriteHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
BOOLEAN CMAPI
|
||||
CmCreateRootNode(
|
||||
PHHIVE Hive,
|
||||
PCWSTR Name);
|
||||
|
||||
VOID CMAPI
|
||||
CmPrepareHive(
|
||||
PHHIVE RegistryHive);
|
||||
|
||||
/*
|
||||
* Private functions.
|
||||
*/
|
||||
|
||||
PHBIN CMAPI
|
||||
HvpAddBin(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage);
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHiveFreeCellList(
|
||||
PHHIVE Hive);
|
||||
|
||||
ULONG CMAPI
|
||||
HvpHiveHeaderChecksum(
|
||||
PHBASE_BLOCK HiveHeader);
|
||||
|
||||
#endif /* CMLIB_H */
|
||||
|
||||
+72
-72
@@ -1,72 +1,72 @@
|
||||
CMLIB_BASE = $(LIB_BASE_)cmlib
|
||||
CMLIB_BASE_ = $(CMLIB_BASE)$(SEP)
|
||||
CMLIB_INT = $(INTERMEDIATE_)$(CMLIB_BASE)_host
|
||||
CMLIB_INT_ = $(INTERMEDIATE_)$(CMLIB_BASE)_host$(SEP)
|
||||
CMLIB_OUT = $(OUTPUT_)$(CMLIB_BASE)_host
|
||||
CMLIB_OUT_ = $(OUTPUT_)$(CMLIB_BASE)_host$(SEP)
|
||||
|
||||
$(CMLIB_INT): | $(LIB_INT)
|
||||
$(ECHO_MKDIR)
|
||||
${mkdir} $@
|
||||
|
||||
ifneq ($(INTERMEDIATE),$(OUTPUT))
|
||||
$(CMLIB_OUT): | $(OUTPUT_)$(LIB_BASE)
|
||||
$(ECHO_MKDIR)
|
||||
${mkdir} $@
|
||||
endif
|
||||
|
||||
CMLIB_HOST_TARGET = \
|
||||
$(CMLIB_OUT)$(SEP)cmlib.a
|
||||
|
||||
CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \
|
||||
cminit.c \
|
||||
hivebin.c \
|
||||
hivecell.c \
|
||||
hiveinit.c \
|
||||
hivesum.c \
|
||||
hivewrt.c \
|
||||
)
|
||||
|
||||
CMLIB_HOST_OBJECTS = \
|
||||
$(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o))
|
||||
|
||||
CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith \
|
||||
-D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_\
|
||||
-DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \
|
||||
-D__NO_CTYPE_INLINES
|
||||
|
||||
$(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT)
|
||||
$(ECHO_AR)
|
||||
$(host_ar) -r $@ $(CMLIB_HOST_OBJECTS)
|
||||
|
||||
$(CMLIB_INT_)cminit.o: $(CMLIB_BASE_)cminit.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivebin.o: $(CMLIB_BASE_)hivebin.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivecell.o: $(CMLIB_BASE_)hivecell.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hiveinit.o: $(CMLIB_BASE_)hiveinit.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivesum.o: $(CMLIB_BASE_)hivesum.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivewrt.o: $(CMLIB_BASE_)hivewrt.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
.PHONY: cmlib_host
|
||||
cmlib_host: $(CMLIB_HOST_TARGET)
|
||||
|
||||
.PHONY: cmlib_host_clean
|
||||
cmlib_host_clean:
|
||||
-@$(rm) $(CMLIB_HOST_TARGET) $(CMLIB_HOST_OBJECTS) 2>$(NUL)
|
||||
clean: cmlib_host_clean
|
||||
CMLIB_BASE = $(LIB_BASE_)cmlib
|
||||
CMLIB_BASE_ = $(CMLIB_BASE)$(SEP)
|
||||
CMLIB_INT = $(INTERMEDIATE_)$(CMLIB_BASE)_host
|
||||
CMLIB_INT_ = $(INTERMEDIATE_)$(CMLIB_BASE)_host$(SEP)
|
||||
CMLIB_OUT = $(OUTPUT_)$(CMLIB_BASE)_host
|
||||
CMLIB_OUT_ = $(OUTPUT_)$(CMLIB_BASE)_host$(SEP)
|
||||
|
||||
$(CMLIB_INT): | $(LIB_INT)
|
||||
$(ECHO_MKDIR)
|
||||
${mkdir} $@
|
||||
|
||||
ifneq ($(INTERMEDIATE),$(OUTPUT))
|
||||
$(CMLIB_OUT): | $(OUTPUT_)$(LIB_BASE)
|
||||
$(ECHO_MKDIR)
|
||||
${mkdir} $@
|
||||
endif
|
||||
|
||||
CMLIB_HOST_TARGET = \
|
||||
$(CMLIB_OUT)$(SEP)cmlib.a
|
||||
|
||||
CMLIB_HOST_SOURCES = $(addprefix $(CMLIB_BASE_), \
|
||||
cminit.c \
|
||||
hivebin.c \
|
||||
hivecell.c \
|
||||
hiveinit.c \
|
||||
hivesum.c \
|
||||
hivewrt.c \
|
||||
)
|
||||
|
||||
CMLIB_HOST_OBJECTS = \
|
||||
$(subst $(CMLIB_BASE), $(CMLIB_INT), $(CMLIB_HOST_SOURCES:.c=.o))
|
||||
|
||||
CMLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith \
|
||||
-D_X86_ -D__i386__ -D_REACTOS_ -D_NTOSKRNL_ -D_NTSYSTEM_ \
|
||||
-DCMLIB_HOST -D_M_IX86 -I$(CMLIB_BASE) -Iinclude/reactos -Iinclude/psdk -Iinclude/ddk -Iinclude/crt \
|
||||
-D__NO_CTYPE_INLINES
|
||||
|
||||
$(CMLIB_HOST_TARGET): $(CMLIB_HOST_OBJECTS) | $(CMLIB_OUT)
|
||||
$(ECHO_AR)
|
||||
$(host_ar) -r $@ $(CMLIB_HOST_OBJECTS)
|
||||
|
||||
$(CMLIB_INT_)cminit.o: $(CMLIB_BASE_)cminit.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivebin.o: $(CMLIB_BASE_)hivebin.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivecell.o: $(CMLIB_BASE_)hivecell.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hiveinit.o: $(CMLIB_BASE_)hiveinit.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivesum.o: $(CMLIB_BASE_)hivesum.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
$(CMLIB_INT_)hivewrt.o: $(CMLIB_BASE_)hivewrt.c | $(CMLIB_INT)
|
||||
$(ECHO_CC)
|
||||
${host_gcc} $(CMLIB_HOST_CFLAGS) -c $< -o $@
|
||||
|
||||
.PHONY: cmlib_host
|
||||
cmlib_host: $(CMLIB_HOST_TARGET)
|
||||
|
||||
.PHONY: cmlib_host_clean
|
||||
cmlib_host_clean:
|
||||
-@$(rm) $(CMLIB_HOST_TARGET) $(CMLIB_HOST_OBJECTS) 2>$(NUL)
|
||||
clean: cmlib_host_clean
|
||||
|
||||
+98
-98
@@ -1,98 +1,98 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2005 Hartmut Birr
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
|
||||
PHBIN CMAPI
|
||||
HvpAddBin(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHMAP_ENTRY BlockList;
|
||||
PHBIN Bin;
|
||||
SIZE_T BinSize;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
ULONG BlockCount;
|
||||
ULONG OldBlockListSize;
|
||||
PHCELL Block;
|
||||
|
||||
BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE);
|
||||
BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE);
|
||||
|
||||
Bin = RegistryHive->Allocate(BinSize, TRUE);
|
||||
if (Bin == NULL)
|
||||
return NULL;
|
||||
RtlZeroMemory(Bin, BinSize);
|
||||
|
||||
Bin->Signature = HV_BIN_SIGNATURE;
|
||||
Bin->FileOffset = RegistryHive->Storage[Storage].Length *
|
||||
HV_BLOCK_SIZE;
|
||||
Bin->Size = (ULONG)BinSize;
|
||||
|
||||
/* Allocate new block list */
|
||||
OldBlockListSize = RegistryHive->Storage[Storage].Length;
|
||||
BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
|
||||
(OldBlockListSize + BlockCount), TRUE);
|
||||
if (BlockList == NULL)
|
||||
{
|
||||
RegistryHive->Free(Bin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (OldBlockListSize > 0)
|
||||
{
|
||||
RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
|
||||
OldBlockListSize * sizeof(HMAP_ENTRY));
|
||||
RegistryHive->Free(RegistryHive->Storage[Storage].BlockList);
|
||||
}
|
||||
|
||||
RegistryHive->Storage[Storage].BlockList = BlockList;
|
||||
RegistryHive->Storage[Storage].Length += BlockCount;
|
||||
|
||||
for (i = 0; i < BlockCount; i++)
|
||||
{
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block =
|
||||
((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE));
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin;
|
||||
}
|
||||
|
||||
/* Initialize a free block in this heap. */
|
||||
Block = (PHCELL)(Bin + 1);
|
||||
Block->Size = (LONG)(BinSize - sizeof(HBIN));
|
||||
|
||||
if (Storage == HvStable)
|
||||
{
|
||||
/* Calculate bitmap size in bytes (always a multiple of 32 bits). */
|
||||
BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
|
||||
/* Grow bitmap if necessary. */
|
||||
if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
|
||||
{
|
||||
PULONG BitmapBuffer;
|
||||
|
||||
BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE);
|
||||
RtlZeroMemory(BitmapBuffer, BitmapSize);
|
||||
RtlCopyMemory(BitmapBuffer,
|
||||
RegistryHive->DirtyVector.Buffer,
|
||||
RegistryHive->DirtyVector.SizeOfBitMap / 8);
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer);
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
|
||||
BitmapSize * 8);
|
||||
}
|
||||
|
||||
/* Mark new bin dirty. */
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
Bin->FileOffset / HV_BLOCK_SIZE,
|
||||
BlockCount);
|
||||
}
|
||||
|
||||
return Bin;
|
||||
}
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2005 Hartmut Birr
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
|
||||
PHBIN CMAPI
|
||||
HvpAddBin(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHMAP_ENTRY BlockList;
|
||||
PHBIN Bin;
|
||||
SIZE_T BinSize;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
ULONG BlockCount;
|
||||
ULONG OldBlockListSize;
|
||||
PHCELL Block;
|
||||
|
||||
BinSize = ROUND_UP(Size + sizeof(HBIN), HV_BLOCK_SIZE);
|
||||
BlockCount = (ULONG)(BinSize / HV_BLOCK_SIZE);
|
||||
|
||||
Bin = RegistryHive->Allocate(BinSize, TRUE);
|
||||
if (Bin == NULL)
|
||||
return NULL;
|
||||
RtlZeroMemory(Bin, BinSize);
|
||||
|
||||
Bin->Signature = HV_BIN_SIGNATURE;
|
||||
Bin->FileOffset = RegistryHive->Storage[Storage].Length *
|
||||
HV_BLOCK_SIZE;
|
||||
Bin->Size = (ULONG)BinSize;
|
||||
|
||||
/* Allocate new block list */
|
||||
OldBlockListSize = RegistryHive->Storage[Storage].Length;
|
||||
BlockList = RegistryHive->Allocate(sizeof(HMAP_ENTRY) *
|
||||
(OldBlockListSize + BlockCount), TRUE);
|
||||
if (BlockList == NULL)
|
||||
{
|
||||
RegistryHive->Free(Bin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (OldBlockListSize > 0)
|
||||
{
|
||||
RtlCopyMemory(BlockList, RegistryHive->Storage[Storage].BlockList,
|
||||
OldBlockListSize * sizeof(HMAP_ENTRY));
|
||||
RegistryHive->Free(RegistryHive->Storage[Storage].BlockList);
|
||||
}
|
||||
|
||||
RegistryHive->Storage[Storage].BlockList = BlockList;
|
||||
RegistryHive->Storage[Storage].Length += BlockCount;
|
||||
|
||||
for (i = 0; i < BlockCount; i++)
|
||||
{
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Block =
|
||||
((ULONG_PTR)Bin + (i * HV_BLOCK_SIZE));
|
||||
RegistryHive->Storage[Storage].BlockList[OldBlockListSize + i].Bin = (ULONG_PTR)Bin;
|
||||
}
|
||||
|
||||
/* Initialize a free block in this heap. */
|
||||
Block = (PHCELL)(Bin + 1);
|
||||
Block->Size = (LONG)(BinSize - sizeof(HBIN));
|
||||
|
||||
if (Storage == HvStable)
|
||||
{
|
||||
/* Calculate bitmap size in bytes (always a multiple of 32 bits). */
|
||||
BitmapSize = ROUND_UP(RegistryHive->Storage[HvStable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
|
||||
/* Grow bitmap if necessary. */
|
||||
if (BitmapSize > RegistryHive->DirtyVector.SizeOfBitMap / 8)
|
||||
{
|
||||
PULONG BitmapBuffer;
|
||||
|
||||
BitmapBuffer = RegistryHive->Allocate(BitmapSize, TRUE);
|
||||
RtlZeroMemory(BitmapBuffer, BitmapSize);
|
||||
RtlCopyMemory(BitmapBuffer,
|
||||
RegistryHive->DirtyVector.Buffer,
|
||||
RegistryHive->DirtyVector.SizeOfBitMap / 8);
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer);
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, BitmapBuffer,
|
||||
BitmapSize * 8);
|
||||
}
|
||||
|
||||
/* Mark new bin dirty. */
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
Bin->FileOffset / HV_BLOCK_SIZE,
|
||||
BlockCount);
|
||||
}
|
||||
|
||||
return Bin;
|
||||
}
|
||||
|
||||
+429
-429
@@ -1,429 +1,429 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static PHCELL __inline CMAPI
|
||||
HvpGetCellHeader(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
ASSERT(CellIndex != HCELL_NULL);
|
||||
if (!RegistryHive->Flat)
|
||||
{
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
ULONG CellOffset;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
|
||||
ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
|
||||
Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].Block;
|
||||
ASSERT(Block != NULL);
|
||||
return (PVOID)((ULONG_PTR)Block + CellOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT((CellIndex & HCELL_TYPE_MASK) == HvStable);
|
||||
return (PVOID)((ULONG_PTR)RegistryHive->HiveHeader + HV_BLOCK_SIZE +
|
||||
CellIndex);
|
||||
}
|
||||
}
|
||||
|
||||
PVOID CMAPI
|
||||
HvGetCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1);
|
||||
}
|
||||
|
||||
static LONG __inline CMAPI
|
||||
HvpGetCellFullSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
{
|
||||
return ((PHCELL)Cell - 1)->Size;
|
||||
}
|
||||
|
||||
LONG CMAPI
|
||||
HvGetCellSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
{
|
||||
PHCELL CellHeader;
|
||||
|
||||
CellHeader = (PHCELL)Cell - 1;
|
||||
if (CellHeader->Size < 0)
|
||||
return CellHeader->Size + sizeof(HCELL);
|
||||
else
|
||||
return CellHeader->Size - sizeof(HCELL);
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
HvMarkCellDirty(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
LONG CellSize;
|
||||
ULONG CellBlock;
|
||||
ULONG CellLastBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != HvStable)
|
||||
return;
|
||||
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
CellSize = HvpGetCellFullSize(RegistryHive, HvGetCell(RegistryHive, CellIndex));
|
||||
if (CellSize < 0)
|
||||
CellSize = -CellSize;
|
||||
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
CellBlock, CellLastBlock - CellBlock);
|
||||
}
|
||||
|
||||
static ULONG __inline CMAPI
|
||||
HvpComputeFreeListIndex(
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG Index;
|
||||
static CCHAR FindFirstSet[256] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
|
||||
|
||||
Index = (Size >> 3) - 1;
|
||||
if (Index >= 16)
|
||||
{
|
||||
if (Index > 255)
|
||||
Index = 23;
|
||||
else
|
||||
Index = FindFirstSet[Index] + 7;
|
||||
}
|
||||
|
||||
return Index;
|
||||
}
|
||||
|
||||
static NTSTATUS CMAPI
|
||||
HvpAddFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL FreeBlock,
|
||||
HCELL_INDEX FreeIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeBlockData;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
|
||||
ASSERT(RegistryHive != NULL);
|
||||
ASSERT(FreeBlock != NULL);
|
||||
|
||||
Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
|
||||
|
||||
FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
|
||||
*FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
|
||||
|
||||
/* FIXME: Eventually get rid of free bins. */
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
HvpRemoveFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL CellBlock,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
|
||||
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NULL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if (*pFreeCellOffset == CellIndex)
|
||||
{
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
static HCELL_INDEX CMAPI
|
||||
HvpFindFree(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
ULONG Index;
|
||||
|
||||
for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
|
||||
{
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NULL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
|
||||
{
|
||||
FreeCellOffset = *pFreeCellOffset;
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return FreeCellOffset;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
}
|
||||
|
||||
return HCELL_NULL;
|
||||
}
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHiveFreeCellList(
|
||||
PHHIVE Hive)
|
||||
{
|
||||
HCELL_INDEX BlockOffset;
|
||||
PHCELL FreeBlock;
|
||||
ULONG BlockIndex;
|
||||
ULONG FreeOffset;
|
||||
PHBIN Bin;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
/* Initialize the free cell list */
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
Hive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL;
|
||||
Hive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL;
|
||||
}
|
||||
|
||||
BlockOffset = 0;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < Hive->Storage[HvStable].Length)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[HvStable].BlockList[BlockIndex].Bin;
|
||||
|
||||
/* Search free blocks and add to list */
|
||||
FreeOffset = sizeof(HBIN);
|
||||
while (FreeOffset < Bin->Size)
|
||||
{
|
||||
FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
|
||||
if (FreeBlock->Size > 0)
|
||||
{
|
||||
Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
FreeOffset += FreeBlock->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeOffset -= FreeBlock->Size;
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HV_BLOCK_SIZE;
|
||||
BlockOffset += Bin->Size;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvAllocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHCELL FreeCell;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL NewCell;
|
||||
PHBIN Bin;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
/* Round to 16 bytes multiple. */
|
||||
Size = ROUND_UP(Size + sizeof(HCELL), 16);
|
||||
|
||||
/* First search in free blocks. */
|
||||
FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
|
||||
|
||||
/* If no free cell was found we need to extend the hive file. */
|
||||
if (FreeCellOffset == HCELL_NULL)
|
||||
{
|
||||
Bin = HvpAddBin(RegistryHive, Size, Storage);
|
||||
if (Bin == NULL)
|
||||
return HCELL_NULL;
|
||||
FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
|
||||
FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
|
||||
|
||||
/* Split the block in two parts */
|
||||
/* FIXME: There is some minimal cell size that we must respect. */
|
||||
if ((ULONG)FreeCell->Size > Size + sizeof(HCELL_INDEX))
|
||||
{
|
||||
NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
|
||||
NewCell->Size = FreeCell->Size - Size;
|
||||
FreeCell->Size = Size;
|
||||
HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
|
||||
if (Storage == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset + Size);
|
||||
}
|
||||
|
||||
if (Storage == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset);
|
||||
FreeCell->Size = -FreeCell->Size;
|
||||
RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
|
||||
|
||||
return FreeCellOffset;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvReallocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
ULONG Size)
|
||||
{
|
||||
PVOID OldCell;
|
||||
PVOID NewCell;
|
||||
LONG OldCellSize;
|
||||
HCELL_INDEX NewCellIndex;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
|
||||
ASSERT(CellIndex != HCELL_NULL);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
|
||||
OldCell = HvGetCell(RegistryHive, CellIndex);
|
||||
OldCellSize = HvGetCellSize(RegistryHive, OldCell);
|
||||
ASSERT(OldCellSize < 0);
|
||||
|
||||
/*
|
||||
* If new data size is larger than the current, destroy current
|
||||
* data block and allocate a new one.
|
||||
*
|
||||
* FIXME: Merge with adjacent free cell if possible.
|
||||
* FIXME: Implement shrinking.
|
||||
*/
|
||||
if (Size > (ULONG)-OldCellSize)
|
||||
{
|
||||
NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage);
|
||||
if (NewCellIndex == HCELL_NULL)
|
||||
return HCELL_NULL;
|
||||
|
||||
NewCell = HvGetCell(RegistryHive, NewCellIndex);
|
||||
RtlCopyMemory(NewCell, OldCell, (SIZE_T)-OldCellSize);
|
||||
|
||||
HvFreeCell(RegistryHive, CellIndex);
|
||||
|
||||
return NewCellIndex;
|
||||
}
|
||||
|
||||
return CellIndex;
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
HvFreeCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL Free;
|
||||
PHCELL Neighbor;
|
||||
PHBIN Bin;
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
Free = HvpGetCellHeader(RegistryHive, CellIndex);
|
||||
|
||||
ASSERT(Free->Size < 0);
|
||||
|
||||
Free->Size = -Free->Size;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
/* FIXME: Merge free blocks */
|
||||
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].Bin;
|
||||
|
||||
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
|
||||
Bin->FileOffset + Bin->Size)
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor,
|
||||
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
|
||||
Free->Size += Neighbor->Size;
|
||||
}
|
||||
}
|
||||
|
||||
Neighbor = (PHCELL)(Bin + 1);
|
||||
while (Neighbor < Free)
|
||||
{
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
|
||||
{
|
||||
Neighbor->Size += Free->Size;
|
||||
if (CellType == HvStable)
|
||||
HvMarkCellDirty(RegistryHive,
|
||||
(HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset));
|
||||
return;
|
||||
}
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add block to the list of free blocks */
|
||||
HvpAddFree(RegistryHive, Free, CellIndex);
|
||||
|
||||
if (CellType == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, CellIndex);
|
||||
}
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static PHCELL __inline CMAPI
|
||||
HvpGetCellHeader(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
ASSERT(CellIndex != HCELL_NULL);
|
||||
if (!RegistryHive->Flat)
|
||||
{
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
ULONG CellOffset;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellOffset = (CellIndex & HCELL_OFFSET_MASK) >> HCELL_OFFSET_SHIFT;
|
||||
ASSERT(CellBlock < RegistryHive->Storage[CellType].Length);
|
||||
Block = (PVOID)RegistryHive->Storage[CellType].BlockList[CellBlock].Block;
|
||||
ASSERT(Block != NULL);
|
||||
return (PVOID)((ULONG_PTR)Block + CellOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT((CellIndex & HCELL_TYPE_MASK) == HvStable);
|
||||
return (PVOID)((ULONG_PTR)RegistryHive->HiveHeader + HV_BLOCK_SIZE +
|
||||
CellIndex);
|
||||
}
|
||||
}
|
||||
|
||||
PVOID CMAPI
|
||||
HvGetCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
return (PVOID)(HvpGetCellHeader(RegistryHive, CellIndex) + 1);
|
||||
}
|
||||
|
||||
static LONG __inline CMAPI
|
||||
HvpGetCellFullSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
{
|
||||
return ((PHCELL)Cell - 1)->Size;
|
||||
}
|
||||
|
||||
LONG CMAPI
|
||||
HvGetCellSize(
|
||||
PHHIVE RegistryHive,
|
||||
PVOID Cell)
|
||||
{
|
||||
PHCELL CellHeader;
|
||||
|
||||
CellHeader = (PHCELL)Cell - 1;
|
||||
if (CellHeader->Size < 0)
|
||||
return CellHeader->Size + sizeof(HCELL);
|
||||
else
|
||||
return CellHeader->Size - sizeof(HCELL);
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
HvMarkCellDirty(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
LONG CellSize;
|
||||
ULONG CellBlock;
|
||||
ULONG CellLastBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != HvStable)
|
||||
return;
|
||||
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
CellSize = HvpGetCellFullSize(RegistryHive, HvGetCell(RegistryHive, CellIndex));
|
||||
if (CellSize < 0)
|
||||
CellSize = -CellSize;
|
||||
|
||||
RtlSetBits(&RegistryHive->DirtyVector,
|
||||
CellBlock, CellLastBlock - CellBlock);
|
||||
}
|
||||
|
||||
static ULONG __inline CMAPI
|
||||
HvpComputeFreeListIndex(
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG Index;
|
||||
static CCHAR FindFirstSet[256] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
|
||||
|
||||
Index = (Size >> 3) - 1;
|
||||
if (Index >= 16)
|
||||
{
|
||||
if (Index > 255)
|
||||
Index = 23;
|
||||
else
|
||||
Index = FindFirstSet[Index] + 7;
|
||||
}
|
||||
|
||||
return Index;
|
||||
}
|
||||
|
||||
static NTSTATUS CMAPI
|
||||
HvpAddFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL FreeBlock,
|
||||
HCELL_INDEX FreeIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeBlockData;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
|
||||
ASSERT(RegistryHive != NULL);
|
||||
ASSERT(FreeBlock != NULL);
|
||||
|
||||
Storage = (FreeIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)FreeBlock->Size);
|
||||
|
||||
FreeBlockData = (PHCELL_INDEX)(FreeBlock + 1);
|
||||
*FreeBlockData = RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
RegistryHive->Storage[Storage].FreeDisplay[Index] = FreeIndex;
|
||||
|
||||
/* FIXME: Eventually get rid of free bins. */
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID CMAPI
|
||||
HvpRemoveFree(
|
||||
PHHIVE RegistryHive,
|
||||
PHCELL CellBlock,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
ULONG Index;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
Index = HvpComputeFreeListIndex((ULONG)CellBlock->Size);
|
||||
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NULL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if (*pFreeCellOffset == CellIndex)
|
||||
{
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
static HCELL_INDEX CMAPI
|
||||
HvpFindFree(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHCELL_INDEX FreeCellData;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL_INDEX pFreeCellOffset;
|
||||
ULONG Index;
|
||||
|
||||
for (Index = HvpComputeFreeListIndex(Size); Index < 24; Index++)
|
||||
{
|
||||
pFreeCellOffset = &RegistryHive->Storage[Storage].FreeDisplay[Index];
|
||||
while (*pFreeCellOffset != HCELL_NULL)
|
||||
{
|
||||
FreeCellData = (PHCELL_INDEX)HvGetCell(RegistryHive, *pFreeCellOffset);
|
||||
if ((ULONG)HvpGetCellFullSize(RegistryHive, FreeCellData) >= Size)
|
||||
{
|
||||
FreeCellOffset = *pFreeCellOffset;
|
||||
*pFreeCellOffset = *FreeCellData;
|
||||
return FreeCellOffset;
|
||||
}
|
||||
pFreeCellOffset = FreeCellData;
|
||||
}
|
||||
}
|
||||
|
||||
return HCELL_NULL;
|
||||
}
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHiveFreeCellList(
|
||||
PHHIVE Hive)
|
||||
{
|
||||
HCELL_INDEX BlockOffset;
|
||||
PHCELL FreeBlock;
|
||||
ULONG BlockIndex;
|
||||
ULONG FreeOffset;
|
||||
PHBIN Bin;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
/* Initialize the free cell list */
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
Hive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL;
|
||||
Hive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL;
|
||||
}
|
||||
|
||||
BlockOffset = 0;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < Hive->Storage[HvStable].Length)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[HvStable].BlockList[BlockIndex].Bin;
|
||||
|
||||
/* Search free blocks and add to list */
|
||||
FreeOffset = sizeof(HBIN);
|
||||
while (FreeOffset < Bin->Size)
|
||||
{
|
||||
FreeBlock = (PHCELL)((ULONG_PTR)Bin + FreeOffset);
|
||||
if (FreeBlock->Size > 0)
|
||||
{
|
||||
Status = HvpAddFree(Hive, FreeBlock, Bin->FileOffset + FreeOffset);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
FreeOffset += FreeBlock->Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeOffset -= FreeBlock->Size;
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HV_BLOCK_SIZE;
|
||||
BlockOffset += Bin->Size;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvAllocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Size,
|
||||
HV_STORAGE_TYPE Storage)
|
||||
{
|
||||
PHCELL FreeCell;
|
||||
HCELL_INDEX FreeCellOffset;
|
||||
PHCELL NewCell;
|
||||
PHBIN Bin;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
/* Round to 16 bytes multiple. */
|
||||
Size = ROUND_UP(Size + sizeof(HCELL), 16);
|
||||
|
||||
/* First search in free blocks. */
|
||||
FreeCellOffset = HvpFindFree(RegistryHive, Size, Storage);
|
||||
|
||||
/* If no free cell was found we need to extend the hive file. */
|
||||
if (FreeCellOffset == HCELL_NULL)
|
||||
{
|
||||
Bin = HvpAddBin(RegistryHive, Size, Storage);
|
||||
if (Bin == NULL)
|
||||
return HCELL_NULL;
|
||||
FreeCellOffset = Bin->FileOffset + sizeof(HBIN);
|
||||
FreeCellOffset |= Storage << HCELL_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
FreeCell = HvpGetCellHeader(RegistryHive, FreeCellOffset);
|
||||
|
||||
/* Split the block in two parts */
|
||||
/* FIXME: There is some minimal cell size that we must respect. */
|
||||
if ((ULONG)FreeCell->Size > Size + sizeof(HCELL_INDEX))
|
||||
{
|
||||
NewCell = (PHCELL)((ULONG_PTR)FreeCell + Size);
|
||||
NewCell->Size = FreeCell->Size - Size;
|
||||
FreeCell->Size = Size;
|
||||
HvpAddFree(RegistryHive, NewCell, FreeCellOffset + Size);
|
||||
if (Storage == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset + Size);
|
||||
}
|
||||
|
||||
if (Storage == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, FreeCellOffset);
|
||||
FreeCell->Size = -FreeCell->Size;
|
||||
RtlZeroMemory(FreeCell + 1, Size - sizeof(HCELL));
|
||||
|
||||
return FreeCellOffset;
|
||||
}
|
||||
|
||||
HCELL_INDEX CMAPI
|
||||
HvReallocateCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex,
|
||||
ULONG Size)
|
||||
{
|
||||
PVOID OldCell;
|
||||
PVOID NewCell;
|
||||
LONG OldCellSize;
|
||||
HCELL_INDEX NewCellIndex;
|
||||
HV_STORAGE_TYPE Storage;
|
||||
|
||||
ASSERT(CellIndex != HCELL_NULL);
|
||||
|
||||
Storage = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
|
||||
OldCell = HvGetCell(RegistryHive, CellIndex);
|
||||
OldCellSize = HvGetCellSize(RegistryHive, OldCell);
|
||||
ASSERT(OldCellSize < 0);
|
||||
|
||||
/*
|
||||
* If new data size is larger than the current, destroy current
|
||||
* data block and allocate a new one.
|
||||
*
|
||||
* FIXME: Merge with adjacent free cell if possible.
|
||||
* FIXME: Implement shrinking.
|
||||
*/
|
||||
if (Size > (ULONG)-OldCellSize)
|
||||
{
|
||||
NewCellIndex = HvAllocateCell(RegistryHive, Size, Storage);
|
||||
if (NewCellIndex == HCELL_NULL)
|
||||
return HCELL_NULL;
|
||||
|
||||
NewCell = HvGetCell(RegistryHive, NewCellIndex);
|
||||
RtlCopyMemory(NewCell, OldCell, (SIZE_T)-OldCellSize);
|
||||
|
||||
HvFreeCell(RegistryHive, CellIndex);
|
||||
|
||||
return NewCellIndex;
|
||||
}
|
||||
|
||||
return CellIndex;
|
||||
}
|
||||
|
||||
VOID CMAPI
|
||||
HvFreeCell(
|
||||
PHHIVE RegistryHive,
|
||||
HCELL_INDEX CellIndex)
|
||||
{
|
||||
PHCELL Free;
|
||||
PHCELL Neighbor;
|
||||
PHBIN Bin;
|
||||
ULONG CellType;
|
||||
ULONG CellBlock;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
Free = HvpGetCellHeader(RegistryHive, CellIndex);
|
||||
|
||||
ASSERT(Free->Size < 0);
|
||||
|
||||
Free->Size = -Free->Size;
|
||||
|
||||
CellType = (CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT;
|
||||
CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT;
|
||||
|
||||
/* FIXME: Merge free blocks */
|
||||
Bin = (PHBIN)RegistryHive->Storage[CellType].BlockList[CellBlock].Bin;
|
||||
|
||||
if ((CellIndex & ~HCELL_TYPE_MASK) + Free->Size <
|
||||
Bin->FileOffset + Bin->Size)
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Free + Free->Size);
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
HvpRemoveFree(RegistryHive, Neighbor,
|
||||
((HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset)) | (CellIndex & HCELL_TYPE_MASK));
|
||||
Free->Size += Neighbor->Size;
|
||||
}
|
||||
}
|
||||
|
||||
Neighbor = (PHCELL)(Bin + 1);
|
||||
while (Neighbor < Free)
|
||||
{
|
||||
if (Neighbor->Size > 0)
|
||||
{
|
||||
if ((ULONG_PTR)Neighbor + Neighbor->Size == (ULONG_PTR)Free)
|
||||
{
|
||||
Neighbor->Size += Free->Size;
|
||||
if (CellType == HvStable)
|
||||
HvMarkCellDirty(RegistryHive,
|
||||
(HCELL_INDEX)((ULONG_PTR)Neighbor - (ULONG_PTR)Bin +
|
||||
Bin->FileOffset));
|
||||
return;
|
||||
}
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor + Neighbor->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
Neighbor = (PHCELL)((ULONG_PTR)Neighbor - Neighbor->Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add block to the list of free blocks */
|
||||
HvpAddFree(RegistryHive, Free, CellIndex);
|
||||
|
||||
if (CellType == HvStable)
|
||||
HvMarkCellDirty(RegistryHive, CellIndex);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
* the other bits specify index into the hive file. The value HCELL_NULL
|
||||
* (-1) is reserved for marking invalid cells.
|
||||
*/
|
||||
|
||||
typedef ULONG HCELL_INDEX, *PHCELL_INDEX;
|
||||
|
||||
#define HCELL_NULL ((HCELL_INDEX)-1)
|
||||
|
||||
+391
-390
@@ -1,390 +1,391 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/**
|
||||
* @name HvpVerifyHiveHeader
|
||||
*
|
||||
* Internal function to verify that a hive header has valid format.
|
||||
*/
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvpVerifyHiveHeader(
|
||||
PHBASE_BLOCK HiveHeader)
|
||||
{
|
||||
if (HiveHeader->Signature != HV_SIGNATURE ||
|
||||
HiveHeader->Major != HV_MAJOR_VER ||
|
||||
HiveHeader->Minor < HV_MINOR_VER ||
|
||||
HiveHeader->Type != HV_TYPE_PRIMARY ||
|
||||
HiveHeader->Format != HV_FORMAT_MEMORY ||
|
||||
HiveHeader->Cluster != 1 ||
|
||||
HiveHeader->Sequence1 != HiveHeader->Sequence2 ||
|
||||
HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum)
|
||||
{
|
||||
DPRINT1("Verify Hive Header failed: \n");
|
||||
DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER);
|
||||
DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY);
|
||||
DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n",
|
||||
HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster);
|
||||
DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Sequence1, HiveHeader->Sequence2,
|
||||
HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpFreeHiveBins
|
||||
*
|
||||
* Internal function to free all bin storage associated with hive
|
||||
* descriptor.
|
||||
*/
|
||||
|
||||
VOID CMAPI
|
||||
HvpFreeHiveBins(
|
||||
PHHIVE Hive)
|
||||
{
|
||||
ULONG i;
|
||||
PHBIN Bin;
|
||||
ULONG Storage;
|
||||
|
||||
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
|
||||
{
|
||||
Bin = NULL;
|
||||
for (i = 0; i < Hive->Storage[Storage].Length; i++)
|
||||
{
|
||||
if (Hive->Storage[Storage].BlockList[i].Bin == (ULONG_PTR)NULL)
|
||||
continue;
|
||||
if (Hive->Storage[Storage].BlockList[i].Bin != (ULONG_PTR)Bin)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].Bin;
|
||||
Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].Bin);
|
||||
}
|
||||
Hive->Storage[Storage].BlockList[i].Bin = (ULONG_PTR)NULL;
|
||||
Hive->Storage[Storage].BlockList[i].Block = (ULONG_PTR)NULL;
|
||||
}
|
||||
|
||||
if (Hive->Storage[Storage].Length)
|
||||
Hive->Free(Hive->Storage[Storage].BlockList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpCreateHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* newly created hive.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
PHBASE_BLOCK HiveHeader;
|
||||
ULONG Index;
|
||||
|
||||
HiveHeader = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE);
|
||||
if (HiveHeader == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK));
|
||||
HiveHeader->Signature = HV_SIGNATURE;
|
||||
HiveHeader->Major = HV_MAJOR_VER;
|
||||
HiveHeader->Minor = HV_MINOR_VER;
|
||||
HiveHeader->Type = HV_TYPE_PRIMARY;
|
||||
HiveHeader->Format = HV_FORMAT_MEMORY;
|
||||
HiveHeader->Cluster = 1;
|
||||
HiveHeader->RootCell = HCELL_NULL;
|
||||
HiveHeader->Length = HV_BLOCK_SIZE;
|
||||
HiveHeader->Sequence1 = 1;
|
||||
HiveHeader->Sequence2 = 1;
|
||||
/* FIXME: Fill in the file name */
|
||||
HiveHeader->Checksum = HvpHiveHeaderChecksum(HiveHeader);
|
||||
|
||||
RegistryHive->HiveHeader = HiveHeader;
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
RegistryHive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL;
|
||||
RegistryHive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL;
|
||||
}
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpInitializeMemoryHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* a hive stored in memory. The data of the hive are copied and it is
|
||||
* prepared for read/write access.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryHive(
|
||||
PHHIVE Hive,
|
||||
ULONG_PTR ChunkBase)
|
||||
{
|
||||
SIZE_T BlockIndex;
|
||||
PHBIN Bin, NewBin;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
PULONG BitmapBuffer;
|
||||
SIZE_T ChunkSize;
|
||||
|
||||
//
|
||||
// This hack is similar in magnitude to the US's National Debt
|
||||
//
|
||||
ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length;
|
||||
((PHBASE_BLOCK)ChunkBase)->Length = HV_BLOCK_SIZE;
|
||||
DPRINT("ChunkSize: %lx\n", ChunkSize);
|
||||
|
||||
if (ChunkSize < sizeof(HBASE_BLOCK) ||
|
||||
!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
DPRINT1("Registry is corrupt: ChunkSize %d < sizeof(HBASE_BLOCK) %d, "
|
||||
"or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HBASE_BLOCK));
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE);
|
||||
if (Hive->HiveHeader == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
RtlCopyMemory(Hive->HiveHeader, (PVOID)ChunkBase, sizeof(HBASE_BLOCK));
|
||||
|
||||
/*
|
||||
* Build a block list from the in-memory chunk and copy the data as
|
||||
* we go.
|
||||
*/
|
||||
|
||||
Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1;
|
||||
Hive->Storage[HvStable].BlockList =
|
||||
Hive->Allocate(Hive->Storage[HvStable].Length *
|
||||
sizeof(HMAP_ENTRY), FALSE);
|
||||
if (Hive->Storage[HvStable].BlockList == NULL)
|
||||
{
|
||||
DPRINT1("Allocating block list failed\n");
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (BlockIndex = 0; BlockIndex < Hive->Storage[HvStable].Length; )
|
||||
{
|
||||
Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE);
|
||||
if (Bin->Signature != HV_BIN_SIGNATURE ||
|
||||
(Bin->Size % HV_BLOCK_SIZE) != 0)
|
||||
{
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
Hive->Free(Hive->Storage[HvStable].BlockList);
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
NewBin = Hive->Allocate(Bin->Size, TRUE);
|
||||
if (NewBin == NULL)
|
||||
{
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
Hive->Free(Hive->Storage[HvStable].BlockList);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex].Bin = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex].Block = (ULONG_PTR)NewBin;
|
||||
|
||||
RtlCopyMemory(NewBin, Bin, Bin->Size);
|
||||
|
||||
if (Bin->Size > HV_BLOCK_SIZE)
|
||||
{
|
||||
for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++)
|
||||
{
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex + i].Bin = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex + i].Block =
|
||||
((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HV_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (HvpCreateHiveFreeCellList(Hive))
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
BitmapSize = ROUND_UP(Hive->Storage[HvStable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE);
|
||||
if (BitmapBuffer == NULL)
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
|
||||
RtlClearAllBits(&Hive->DirtyVector);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpInitializeMemoryInplaceHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* a hive stored in memory. The in-memory data of the hive are directly
|
||||
* used and it is read-only accessible.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryInplaceHive(
|
||||
PHHIVE Hive,
|
||||
ULONG_PTR ChunkBase)
|
||||
{
|
||||
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->HiveHeader = (PHBASE_BLOCK)ChunkBase;
|
||||
Hive->ReadOnly = TRUE;
|
||||
Hive->Flat = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvInitialize
|
||||
*
|
||||
* Allocate a new hive descriptor structure and intialize it.
|
||||
*
|
||||
* @param RegistryHive
|
||||
* Output variable to store pointer to the hive descriptor.
|
||||
* @param Operation
|
||||
* - HV_OPERATION_CREATE_HIVE
|
||||
* Create a new hive for read/write access.
|
||||
* - HV_OPERATION_MEMORY
|
||||
* Load and copy in-memory hive for read/write access. The
|
||||
* pointer to data passed to this routine can be freed after
|
||||
* the function is executed.
|
||||
* - HV_OPERATION_MEMORY_INPLACE
|
||||
* Load an in-memory hive for read-only access. The pointer
|
||||
* to data passed to this routine MUSTN'T be freed until
|
||||
* HvFree is called.
|
||||
* @param ChunkBase
|
||||
* Pointer to hive data.
|
||||
* @param ChunkSize
|
||||
* Size of passed hive data.
|
||||
*
|
||||
* @return
|
||||
* STATUS_NO_MEMORY - A memory allocation failed.
|
||||
* STATUS_REGISTRY_CORRUPT - Registry corruption was detected.
|
||||
* STATUS_SUCCESS
|
||||
*
|
||||
* @see HvFree
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvInitialize(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG HiveType,
|
||||
ULONG HiveFlags,
|
||||
ULONG_PTR HiveData OPTIONAL,
|
||||
ULONG Cluster OPTIONAL,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
IN PUNICODE_STRING FileName)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHHIVE Hive = RegistryHive;
|
||||
|
||||
/*
|
||||
* Create a new hive structure that will hold all the maintenance data.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(Hive, sizeof(HHIVE));
|
||||
|
||||
Hive->Allocate = Allocate;
|
||||
Hive->Free = Free;
|
||||
Hive->FileRead = FileRead;
|
||||
Hive->FileWrite = FileWrite;
|
||||
Hive->FileSetSize = FileSetSize;
|
||||
Hive->FileFlush = FileFlush;
|
||||
|
||||
switch (Operation)
|
||||
{
|
||||
case HV_OPERATION_CREATE_HIVE:
|
||||
Status = HvpCreateHive(Hive);
|
||||
break;
|
||||
|
||||
case HV_OPERATION_MEMORY:
|
||||
Status = HvpInitializeMemoryHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
case HV_OPERATION_MEMORY_INPLACE:
|
||||
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: A better return status value is needed */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Hive->Free(Hive);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvFree
|
||||
*
|
||||
* Free all stroage and handles associated with hive descriptor.
|
||||
*/
|
||||
|
||||
VOID CMAPI
|
||||
HvFree(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
if (!RegistryHive->ReadOnly)
|
||||
{
|
||||
/* Release hive bitmap */
|
||||
if (RegistryHive->DirtyVector.Buffer)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer);
|
||||
}
|
||||
|
||||
HvpFreeHiveBins(RegistryHive);
|
||||
}
|
||||
|
||||
RegistryHive->Free(RegistryHive);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/**
|
||||
* @name HvpVerifyHiveHeader
|
||||
*
|
||||
* Internal function to verify that a hive header has valid format.
|
||||
*/
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvpVerifyHiveHeader(
|
||||
PHBASE_BLOCK HiveHeader)
|
||||
{
|
||||
if (HiveHeader->Signature != HV_SIGNATURE ||
|
||||
HiveHeader->Major != HV_MAJOR_VER ||
|
||||
HiveHeader->Minor < HV_MINOR_VER ||
|
||||
HiveHeader->Type != HV_TYPE_PRIMARY ||
|
||||
HiveHeader->Format != HV_FORMAT_MEMORY ||
|
||||
HiveHeader->Cluster != 1 ||
|
||||
HiveHeader->Sequence1 != HiveHeader->Sequence2 ||
|
||||
HvpHiveHeaderChecksum(HiveHeader) != HiveHeader->Checksum)
|
||||
{
|
||||
DPRINT1("Verify Hive Header failed: \n");
|
||||
DPRINT1(" Signature: 0x%x and not 0x%x, Major: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Signature, HV_SIGNATURE, HiveHeader->Major, HV_MAJOR_VER);
|
||||
DPRINT1(" Minor: 0x%x is not >= 0x%x, Type: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Minor, HV_MINOR_VER, HiveHeader->Type, HV_TYPE_PRIMARY);
|
||||
DPRINT1(" Format: 0x%x and not 0x%x, Cluster: 0x%x and not 1\n",
|
||||
HiveHeader->Format, HV_FORMAT_MEMORY, HiveHeader->Cluster);
|
||||
DPRINT1(" Sequence: 0x%x and not 0x%x, Checksum: 0x%x and not 0x%x\n",
|
||||
HiveHeader->Sequence1, HiveHeader->Sequence2,
|
||||
HvpHiveHeaderChecksum(HiveHeader), HiveHeader->Checksum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpFreeHiveBins
|
||||
*
|
||||
* Internal function to free all bin storage associated with hive
|
||||
* descriptor.
|
||||
*/
|
||||
|
||||
VOID CMAPI
|
||||
HvpFreeHiveBins(
|
||||
PHHIVE Hive)
|
||||
{
|
||||
ULONG i;
|
||||
PHBIN Bin;
|
||||
ULONG Storage;
|
||||
|
||||
for (Storage = HvStable; Storage < HvMaxStorageType; Storage++)
|
||||
{
|
||||
Bin = NULL;
|
||||
for (i = 0; i < Hive->Storage[Storage].Length; i++)
|
||||
{
|
||||
if (Hive->Storage[Storage].BlockList[i].Bin == (ULONG_PTR)NULL)
|
||||
continue;
|
||||
if (Hive->Storage[Storage].BlockList[i].Bin != (ULONG_PTR)Bin)
|
||||
{
|
||||
Bin = (PHBIN)Hive->Storage[Storage].BlockList[i].Bin;
|
||||
Hive->Free((PHBIN)Hive->Storage[Storage].BlockList[i].Bin);
|
||||
}
|
||||
Hive->Storage[Storage].BlockList[i].Bin = (ULONG_PTR)NULL;
|
||||
Hive->Storage[Storage].BlockList[i].Block = (ULONG_PTR)NULL;
|
||||
}
|
||||
|
||||
if (Hive->Storage[Storage].Length)
|
||||
Hive->Free(Hive->Storage[Storage].BlockList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpCreateHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* newly created hive.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpCreateHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
PHBASE_BLOCK HiveHeader;
|
||||
ULONG Index;
|
||||
|
||||
HiveHeader = RegistryHive->Allocate(sizeof(HBASE_BLOCK), FALSE);
|
||||
if (HiveHeader == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
RtlZeroMemory(HiveHeader, sizeof(HBASE_BLOCK));
|
||||
HiveHeader->Signature = HV_SIGNATURE;
|
||||
HiveHeader->Major = HV_MAJOR_VER;
|
||||
HiveHeader->Minor = HV_MINOR_VER;
|
||||
HiveHeader->Type = HV_TYPE_PRIMARY;
|
||||
HiveHeader->Format = HV_FORMAT_MEMORY;
|
||||
HiveHeader->Cluster = 1;
|
||||
HiveHeader->RootCell = HCELL_NULL;
|
||||
HiveHeader->Length = HV_BLOCK_SIZE;
|
||||
HiveHeader->Sequence1 = 1;
|
||||
HiveHeader->Sequence2 = 1;
|
||||
/* FIXME: Fill in the file name */
|
||||
HiveHeader->Checksum = HvpHiveHeaderChecksum(HiveHeader);
|
||||
|
||||
RegistryHive->HiveHeader = HiveHeader;
|
||||
for (Index = 0; Index < 24; Index++)
|
||||
{
|
||||
RegistryHive->Storage[HvStable].FreeDisplay[Index] = HCELL_NULL;
|
||||
RegistryHive->Storage[HvVolatile].FreeDisplay[Index] = HCELL_NULL;
|
||||
}
|
||||
RtlInitializeBitMap(&RegistryHive->DirtyVector, NULL, 0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpInitializeMemoryHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* a hive stored in memory. The data of the hive are copied and it is
|
||||
* prepared for read/write access.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryHive(
|
||||
PHHIVE Hive,
|
||||
ULONG_PTR ChunkBase)
|
||||
{
|
||||
SIZE_T BlockIndex;
|
||||
PHBIN Bin, NewBin;
|
||||
ULONG i;
|
||||
ULONG BitmapSize;
|
||||
PULONG BitmapBuffer;
|
||||
SIZE_T ChunkSize;
|
||||
|
||||
//
|
||||
// This hack is similar in magnitude to the US's National Debt
|
||||
//
|
||||
ChunkSize = ((PHBASE_BLOCK)ChunkBase)->Length;
|
||||
((PHBASE_BLOCK)ChunkBase)->Length = HV_BLOCK_SIZE;
|
||||
DPRINT("ChunkSize: %lx\n", ChunkSize);
|
||||
|
||||
if (ChunkSize < sizeof(HBASE_BLOCK) ||
|
||||
!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
DPRINT1("Registry is corrupt: ChunkSize %d < sizeof(HBASE_BLOCK) %d, "
|
||||
"or HvpVerifyHiveHeader() failed\n", ChunkSize, sizeof(HBASE_BLOCK));
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->HiveHeader = Hive->Allocate(sizeof(HBASE_BLOCK), FALSE);
|
||||
if (Hive->HiveHeader == NULL)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
RtlCopyMemory(Hive->HiveHeader, (PVOID)ChunkBase, sizeof(HBASE_BLOCK));
|
||||
|
||||
/*
|
||||
* Build a block list from the in-memory chunk and copy the data as
|
||||
* we go.
|
||||
*/
|
||||
|
||||
Hive->Storage[HvStable].Length = (ULONG)(ChunkSize / HV_BLOCK_SIZE) - 1;
|
||||
Hive->Storage[HvStable].BlockList =
|
||||
Hive->Allocate(Hive->Storage[HvStable].Length *
|
||||
sizeof(HMAP_ENTRY), FALSE);
|
||||
if (Hive->Storage[HvStable].BlockList == NULL)
|
||||
{
|
||||
DPRINT1("Allocating block list failed\n");
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (BlockIndex = 0; BlockIndex < Hive->Storage[HvStable].Length; )
|
||||
{
|
||||
Bin = (PHBIN)((ULONG_PTR)ChunkBase + (BlockIndex + 1) * HV_BLOCK_SIZE);
|
||||
if (Bin->Signature != HV_BIN_SIGNATURE ||
|
||||
(Bin->Size % HV_BLOCK_SIZE) != 0)
|
||||
{
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
Hive->Free(Hive->Storage[HvStable].BlockList);
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
NewBin = Hive->Allocate(Bin->Size, TRUE);
|
||||
if (NewBin == NULL)
|
||||
{
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
Hive->Free(Hive->Storage[HvStable].BlockList);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex].Bin = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex].Block = (ULONG_PTR)NewBin;
|
||||
|
||||
RtlCopyMemory(NewBin, Bin, Bin->Size);
|
||||
|
||||
if (Bin->Size > HV_BLOCK_SIZE)
|
||||
{
|
||||
for (i = 1; i < Bin->Size / HV_BLOCK_SIZE; i++)
|
||||
{
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex + i].Bin = (ULONG_PTR)NewBin;
|
||||
Hive->Storage[HvStable].BlockList[BlockIndex + i].Block =
|
||||
((ULONG_PTR)NewBin + (i * HV_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
BlockIndex += Bin->Size / HV_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
if (HvpCreateHiveFreeCellList(Hive))
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
BitmapSize = ROUND_UP(Hive->Storage[HvStable].Length,
|
||||
sizeof(ULONG) * 8) / 8;
|
||||
BitmapBuffer = (PULONG)Hive->Allocate(BitmapSize, TRUE);
|
||||
if (BitmapBuffer == NULL)
|
||||
{
|
||||
HvpFreeHiveBins(Hive);
|
||||
Hive->Free(Hive->HiveHeader);
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
RtlInitializeBitMap(&Hive->DirtyVector, BitmapBuffer, BitmapSize * 8);
|
||||
RtlClearAllBits(&Hive->DirtyVector);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvpInitializeMemoryInplaceHive
|
||||
*
|
||||
* Internal helper function to initalize hive descriptor structure for
|
||||
* a hive stored in memory. The in-memory data of the hive are directly
|
||||
* used and it is read-only accessible.
|
||||
*
|
||||
* @see HvInitialize
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvpInitializeMemoryInplaceHive(
|
||||
PHHIVE Hive,
|
||||
ULONG_PTR ChunkBase)
|
||||
{
|
||||
if (!HvpVerifyHiveHeader((PHBASE_BLOCK)ChunkBase))
|
||||
{
|
||||
return STATUS_REGISTRY_CORRUPT;
|
||||
}
|
||||
|
||||
Hive->HiveHeader = (PHBASE_BLOCK)ChunkBase;
|
||||
Hive->ReadOnly = TRUE;
|
||||
Hive->Flat = TRUE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvInitialize
|
||||
*
|
||||
* Allocate a new hive descriptor structure and intialize it.
|
||||
*
|
||||
* @param RegistryHive
|
||||
* Output variable to store pointer to the hive descriptor.
|
||||
* @param Operation
|
||||
* - HV_OPERATION_CREATE_HIVE
|
||||
* Create a new hive for read/write access.
|
||||
* - HV_OPERATION_MEMORY
|
||||
* Load and copy in-memory hive for read/write access. The
|
||||
* pointer to data passed to this routine can be freed after
|
||||
* the function is executed.
|
||||
* - HV_OPERATION_MEMORY_INPLACE
|
||||
* Load an in-memory hive for read-only access. The pointer
|
||||
* to data passed to this routine MUSTN'T be freed until
|
||||
* HvFree is called.
|
||||
* @param ChunkBase
|
||||
* Pointer to hive data.
|
||||
* @param ChunkSize
|
||||
* Size of passed hive data.
|
||||
*
|
||||
* @return
|
||||
* STATUS_NO_MEMORY - A memory allocation failed.
|
||||
* STATUS_REGISTRY_CORRUPT - Registry corruption was detected.
|
||||
* STATUS_SUCCESS
|
||||
*
|
||||
* @see HvFree
|
||||
*/
|
||||
|
||||
NTSTATUS CMAPI
|
||||
HvInitialize(
|
||||
PHHIVE RegistryHive,
|
||||
ULONG Operation,
|
||||
ULONG HiveType,
|
||||
ULONG HiveFlags,
|
||||
ULONG_PTR HiveData OPTIONAL,
|
||||
ULONG Cluster OPTIONAL,
|
||||
PALLOCATE_ROUTINE Allocate,
|
||||
PFREE_ROUTINE Free,
|
||||
PFILE_READ_ROUTINE FileRead,
|
||||
PFILE_WRITE_ROUTINE FileWrite,
|
||||
PFILE_SET_SIZE_ROUTINE FileSetSize,
|
||||
PFILE_FLUSH_ROUTINE FileFlush,
|
||||
IN PUNICODE_STRING FileName)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHHIVE Hive = RegistryHive;
|
||||
|
||||
/*
|
||||
* Create a new hive structure that will hold all the maintenance data.
|
||||
*/
|
||||
|
||||
RtlZeroMemory(Hive, sizeof(HHIVE));
|
||||
|
||||
Hive->Allocate = Allocate;
|
||||
Hive->Free = Free;
|
||||
Hive->FileRead = FileRead;
|
||||
Hive->FileWrite = FileWrite;
|
||||
Hive->FileSetSize = FileSetSize;
|
||||
Hive->FileFlush = FileFlush;
|
||||
Hive->StorageTypeCount = 2;
|
||||
|
||||
switch (Operation)
|
||||
{
|
||||
case HV_OPERATION_CREATE_HIVE:
|
||||
Status = HvpCreateHive(Hive);
|
||||
break;
|
||||
|
||||
case HV_OPERATION_MEMORY:
|
||||
Status = HvpInitializeMemoryHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
case HV_OPERATION_MEMORY_INPLACE:
|
||||
Status = HvpInitializeMemoryInplaceHive(Hive, HiveData);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: A better return status value is needed */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Hive->Free(Hive);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name HvFree
|
||||
*
|
||||
* Free all stroage and handles associated with hive descriptor.
|
||||
*/
|
||||
|
||||
VOID CMAPI
|
||||
HvFree(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
if (!RegistryHive->ReadOnly)
|
||||
{
|
||||
/* Release hive bitmap */
|
||||
if (RegistryHive->DirtyVector.Buffer)
|
||||
{
|
||||
RegistryHive->Free(RegistryHive->DirtyVector.Buffer);
|
||||
}
|
||||
|
||||
HvpFreeHiveBins(RegistryHive);
|
||||
}
|
||||
|
||||
RegistryHive->Free(RegistryHive);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+277
-277
@@ -1,277 +1,277 @@
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteLog(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ULONGLONG FileOffset;
|
||||
SIZE_T BufferSize;
|
||||
SIZE_T BitmapSize;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR Ptr;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
DPRINT("HvpWriteLog called\n");
|
||||
|
||||
if (RegistryHive->HiveHeader->Sequence1 !=
|
||||
RegistryHive->HiveHeader->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);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and checksum */
|
||||
RegistryHive->HiveHeader->Type = HV_TYPE_LOG;
|
||||
RegistryHive->HiveHeader->Sequence1++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Copy hive header */
|
||||
RtlCopyMemory(Buffer, RegistryHive->HiveHeader, 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 */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
0, Buffer, BufferSize);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegistryHive->Free(Buffer);
|
||||
|
||||
/* Write dirty blocks */
|
||||
FileOffset = BufferSize;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[HvStable].Length)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0 || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
FileOffset, BlockPtr,
|
||||
HV_BLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
FileOffset += HV_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileSetSize(RegistryHive, HV_TYPE_LOG, FileOffset);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileSetSize failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update first and second update counter and checksum. */
|
||||
RegistryHive->HiveHeader->Sequence2++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive header again with updated sequence counter. */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
0, RegistryHive->HiveHeader,
|
||||
HV_LOG_HEADER_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteHive(
|
||||
PHHIVE RegistryHive,
|
||||
BOOLEAN OnlyDirty)
|
||||
{
|
||||
ULONGLONG FileOffset;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
DPRINT("HvpWriteHive called\n");
|
||||
|
||||
if (RegistryHive->HiveHeader->Sequence1 !=
|
||||
RegistryHive->HiveHeader->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and checksum */
|
||||
RegistryHive->HiveHeader->Type = HV_TYPE_PRIMARY;
|
||||
RegistryHive->HiveHeader->Sequence1++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
0, RegistryHive->HiveHeader,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[HvStable].Length)
|
||||
{
|
||||
if (OnlyDirty)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0 || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block;
|
||||
FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
FileOffset, BlockPtr,
|
||||
HV_BLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update second update counter and checksum */
|
||||
RegistryHive->HiveHeader->Sequence2++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
0, RegistryHive->HiveHeader,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvSyncHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp);
|
||||
|
||||
/* Update log file */
|
||||
if (!HvpWriteLog(RegistryHive))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Clear dirty bitmap. */
|
||||
RtlClearAllBits(&RegistryHive->DirtyVector);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvWriteHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp);
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, FALSE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* PROJECT: registry manipulation library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
|
||||
* Copyright 2001 - 2005 Eric Kohl
|
||||
*/
|
||||
|
||||
#include "cmlib.h"
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteLog(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ULONGLONG FileOffset;
|
||||
SIZE_T BufferSize;
|
||||
SIZE_T BitmapSize;
|
||||
PUCHAR Buffer;
|
||||
PUCHAR Ptr;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
DPRINT("HvpWriteLog called\n");
|
||||
|
||||
if (RegistryHive->HiveHeader->Sequence1 !=
|
||||
RegistryHive->HiveHeader->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);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and checksum */
|
||||
RegistryHive->HiveHeader->Type = HV_TYPE_LOG;
|
||||
RegistryHive->HiveHeader->Sequence1++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Copy hive header */
|
||||
RtlCopyMemory(Buffer, RegistryHive->HiveHeader, 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 */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
0, Buffer, BufferSize);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegistryHive->Free(Buffer);
|
||||
|
||||
/* Write dirty blocks */
|
||||
FileOffset = BufferSize;
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[HvStable].Length)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0 || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
FileOffset, BlockPtr,
|
||||
HV_BLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
FileOffset += HV_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileSetSize(RegistryHive, HV_TYPE_LOG, FileOffset);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileSetSize failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update first and second update counter and checksum. */
|
||||
RegistryHive->HiveHeader->Sequence2++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive header again with updated sequence counter. */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_LOG,
|
||||
0, RegistryHive->HiveHeader,
|
||||
HV_LOG_HEADER_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Flush the log file */
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_LOG);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN CMAPI
|
||||
HvpWriteHive(
|
||||
PHHIVE RegistryHive,
|
||||
BOOLEAN OnlyDirty)
|
||||
{
|
||||
ULONGLONG FileOffset;
|
||||
ULONG BlockIndex;
|
||||
ULONG LastIndex;
|
||||
PVOID BlockPtr;
|
||||
BOOLEAN Success;
|
||||
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
DPRINT("HvpWriteHive called\n");
|
||||
|
||||
if (RegistryHive->HiveHeader->Sequence1 !=
|
||||
RegistryHive->HiveHeader->Sequence2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update first update counter and checksum */
|
||||
RegistryHive->HiveHeader->Type = HV_TYPE_PRIMARY;
|
||||
RegistryHive->HiveHeader->Sequence1++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
0, RegistryHive->HiveHeader,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex = 0;
|
||||
while (BlockIndex < RegistryHive->Storage[HvStable].Length)
|
||||
{
|
||||
if (OnlyDirty)
|
||||
{
|
||||
LastIndex = BlockIndex;
|
||||
BlockIndex = RtlFindSetBits(&RegistryHive->DirtyVector, 1, BlockIndex);
|
||||
if (BlockIndex == ~0 || BlockIndex < LastIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlockPtr = (PVOID)RegistryHive->Storage[HvStable].BlockList[BlockIndex].Block;
|
||||
FileOffset = (ULONGLONG)(BlockIndex + 1) * (ULONGLONG)HV_BLOCK_SIZE;
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
FileOffset, BlockPtr,
|
||||
HV_BLOCK_SIZE);
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BlockIndex++;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
/* Update second update counter and checksum */
|
||||
RegistryHive->HiveHeader->Sequence2++;
|
||||
RegistryHive->HiveHeader->Checksum =
|
||||
HvpHiveHeaderChecksum(RegistryHive->HiveHeader);
|
||||
|
||||
/* Write hive block */
|
||||
Success = RegistryHive->FileWrite(RegistryHive, HV_TYPE_PRIMARY,
|
||||
0, RegistryHive->HiveHeader,
|
||||
sizeof(HBASE_BLOCK));
|
||||
if (!Success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = RegistryHive->FileFlush(RegistryHive, HV_TYPE_PRIMARY);
|
||||
if (!Success)
|
||||
{
|
||||
DPRINT("FileFlush failed\n");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvSyncHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
if (RtlFindSetBits(&RegistryHive->DirtyVector, 1, 0) == ~0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp);
|
||||
|
||||
/* Update log file */
|
||||
if (!HvpWriteLog(RegistryHive))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Clear dirty bitmap. */
|
||||
RtlClearAllBits(&RegistryHive->DirtyVector);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN CMAPI
|
||||
HvWriteHive(
|
||||
PHHIVE RegistryHive)
|
||||
{
|
||||
ASSERT(RegistryHive->ReadOnly == FALSE);
|
||||
|
||||
/* Update hive header modification time */
|
||||
KeQuerySystemTime(&RegistryHive->HiveHeader->TimeStamp);
|
||||
|
||||
/* Update hive file */
|
||||
if (!HvpWriteHive(RegistryHive, FALSE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)
|
||||
#define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a)
|
||||
#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*++
|
||||
|
||||
@@ -194,9 +194,6 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#undef FORCEINLINE
|
||||
#define FORCEINLINE
|
||||
|
||||
//
|
||||
// Recalculates the due time
|
||||
//
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
#include "i386/fpu.h"
|
||||
#include "i386/v86m.h"
|
||||
#elif defined(_M_PPC)
|
||||
#ifndef InterlockedExchangeAddSizeT
|
||||
#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)
|
||||
#define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a)
|
||||
#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)
|
||||
#endif
|
||||
#include "powerpc/mm.h"
|
||||
#else
|
||||
#error "Unknown CPU"
|
||||
@@ -332,4 +337,9 @@ C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_P
|
||||
C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
|
||||
#endif
|
||||
|
||||
#ifdef _M_PPC
|
||||
#include <reactos/ppcboot.h>
|
||||
#include <reactos/ppcdebug.h>
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_INTERNAL_NTOSKRNL_H */
|
||||
|
||||
@@ -131,19 +131,19 @@ __asm__ __volatile__("mfmsr 0\n\t" \
|
||||
#define KeArchEraseFlags()
|
||||
#define KeArchDisableInterrupts() KePPCDisableInterrupts()
|
||||
|
||||
static __inline struct _KPRCB * KeGetCurrentPrcb(
|
||||
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(
|
||||
VOID)
|
||||
{
|
||||
return (struct _KPRCB *)__readfsdword(0x20);
|
||||
}
|
||||
|
||||
__inline struct _KPCR * NTHALAPI KeGetCurrentKPCR(
|
||||
FORCEINLINE struct _KPCR * NTHALAPI KeGetCurrentKPCR(
|
||||
VOID)
|
||||
{
|
||||
return (struct _KPCR *)__readfsdword(0x1c);
|
||||
}
|
||||
|
||||
__inline KIRQL NTHALAPI KeGetCurrentIrql(
|
||||
FORCEINLINE KIRQL NTHALAPI KeGetCurrentIrql(
|
||||
VOID)
|
||||
{
|
||||
return ((KIPCR *)KeGetCurrentKPCR())->CurrentIrql;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
@@ -48,6 +49,14 @@ MEMORY_ALLOCATION_DESCRIPTOR BldrMemoryDescriptors[64];
|
||||
WCHAR BldrModuleStrings[64][260];
|
||||
NLS_DATA_BLOCK BldrNlsDataBlock;
|
||||
SETUP_LOADER_BLOCK BldrSetupBlock;
|
||||
struct _boot_infos_t *BootInfo;
|
||||
|
||||
#ifdef _M_PPC
|
||||
#include "font.h"
|
||||
boot_infos_t PpcEarlybootInfo;
|
||||
#endif
|
||||
|
||||
#define KSEG0_BASE 0x80000000
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
@@ -294,6 +303,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
{
|
||||
ULONG i;
|
||||
ULONG size;
|
||||
ULONG StartKernelBase;
|
||||
ULONG HalBase;
|
||||
ULONG DriverBase;
|
||||
ULONG DriverSize;
|
||||
@@ -303,6 +313,20 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
PKTSS Tss;
|
||||
PKGDTENTRY TssEntry;
|
||||
#endif
|
||||
#ifdef _M_PPC
|
||||
{
|
||||
__asm__("ori 0,0,0");
|
||||
char *nk = "ntoskrnl is here";
|
||||
boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra;
|
||||
memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(PpcEarlybootInfo));
|
||||
PpcEarlybootInfo.dispFont = BootDigits;
|
||||
BootInfo = (struct _boot_infos_t *)&PpcEarlybootInfo;
|
||||
DrawNumber(BootInfo, 0x1234abcd, 10, 100);
|
||||
DrawNumber(BootInfo, (ULONG)nk, 10 , 150);
|
||||
DrawString(BootInfo, nk, 100, 150);
|
||||
__asm__("ori 0,0,0");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _M_IX86
|
||||
/* Load the GDT and IDT */
|
||||
@@ -320,12 +344,19 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
|
||||
#endif
|
||||
|
||||
DrawNumber(BootInfo, 0xb0071f03, 190, 90);
|
||||
DrawNumber(BootInfo, (ULONG)BootInfo, 190, 100);
|
||||
|
||||
/* Copy the Loader Block Data locally since Low-Memory will be wiped */
|
||||
TRACE;
|
||||
memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK));
|
||||
TRACE;
|
||||
memcpy(&KeLoaderModules[0],
|
||||
(PVOID)KeRosLoaderBlock.ModsAddr,
|
||||
sizeof(LOADER_MODULE) * KeRosLoaderBlock.ModsCount);
|
||||
TRACE;
|
||||
KeRosLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
|
||||
TRACE;
|
||||
|
||||
/* Check for BIOS memory map */
|
||||
KeMemoryMapRangeCount = 0;
|
||||
@@ -335,6 +366,8 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
size = *((PULONG)(KeRosLoaderBlock.MmapAddr - sizeof(ULONG)));
|
||||
i = 0;
|
||||
|
||||
TRACEXY(size, KeRosLoaderBlock.MmapLength);
|
||||
|
||||
/* Map it until we run out of size */
|
||||
while (i < KeRosLoaderBlock.MmapLength)
|
||||
{
|
||||
@@ -361,16 +394,23 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
KeRosLoaderBlock.MmapLength = 0;
|
||||
KeRosLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
|
||||
}
|
||||
TRACE;
|
||||
|
||||
/* Save the Base Address */
|
||||
MmSystemRangeStart = (PVOID)KeRosLoaderBlock.KernelBase;
|
||||
TRACEXY((ULONG)KeLoaderCommandLine, (ULONG)LoaderBlock->CommandLine);
|
||||
|
||||
/* Set the Command Line */
|
||||
strcpy(KeLoaderCommandLine, (PCHAR)LoaderBlock->CommandLine);
|
||||
KeRosLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
|
||||
TRACE;
|
||||
|
||||
/* Get the address of ntoskrnl in openfirmware memory */
|
||||
StartKernelBase = KeLoaderModules[0].ModStart;
|
||||
TRACE;
|
||||
|
||||
/* Create a block for each module */
|
||||
for (i = 1; i < KeRosLoaderBlock.ModsCount; i++)
|
||||
for (i = 0; i < KeRosLoaderBlock.ModsCount; i++)
|
||||
{
|
||||
/* Check if we have to copy the path or not */
|
||||
if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0)
|
||||
@@ -382,7 +422,18 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
|
||||
}
|
||||
|
||||
#ifdef _M_IX86
|
||||
#ifdef _M_PPC
|
||||
if(i == 0) {
|
||||
DrawNumber(BootInfo, KeLoaderModules[i].ModStart, 10, 200);
|
||||
DrawNumber(BootInfo, KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart, 100, 200);
|
||||
DrawNumber(BootInfo, KeLoaderModules[i].ModEnd, 190, 200);
|
||||
DrawNumber(BootInfo, KeLoaderModules[i+1].ModStart, 10, 210);
|
||||
DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd - KeLoaderModules[i+1].ModStart, 100, 210);
|
||||
DrawNumber(BootInfo, KeLoaderModules[i+1].ModEnd, 190, 210);
|
||||
}
|
||||
KeLoaderModules[i].ModStart += KSEG0_BASE - StartKernelBase;
|
||||
KeLoaderModules[i].ModEnd += KSEG0_BASE - StartKernelBase;
|
||||
#else
|
||||
/* Substract the base Address in Physical Memory */
|
||||
KeLoaderModules[i].ModStart -= 0x200000;
|
||||
|
||||
@@ -399,10 +450,12 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
/* Select the proper String */
|
||||
KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
|
||||
}
|
||||
TRACE;
|
||||
|
||||
/* Choose last module address as the final kernel address */
|
||||
MmFreeLdrLastKernelAddress =
|
||||
PAGE_ROUND_UP(KeLoaderModules[KeRosLoaderBlock.ModsCount - 1].ModEnd);
|
||||
TRACE;
|
||||
|
||||
/* Select the HAL Base */
|
||||
HalBase = KeLoaderModules[1].ModStart;
|
||||
@@ -410,11 +463,13 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
/* Choose Driver Base */
|
||||
DriverBase = MmFreeLdrLastKernelAddress;
|
||||
LdrHalBase = (ULONG_PTR)DriverBase;
|
||||
TRACE;
|
||||
|
||||
/* Initialize Module Management */
|
||||
LdrInitModuleManagement((PVOID)KeLoaderModules[0].ModStart);
|
||||
|
||||
/* Load HAL.DLL with the PE Loader */
|
||||
TRACE;
|
||||
LdrSafePEProcessModule((PVOID)HalBase,
|
||||
(PVOID)DriverBase,
|
||||
(PVOID)KeLoaderModules[0].ModStart,
|
||||
@@ -429,15 +484,18 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
//
|
||||
// This dirty hack fixes it, and should make symbol lookup work too.
|
||||
//
|
||||
TRACE;
|
||||
HalModuleObject.SizeOfImage = RtlImageNtHeader((PVOID)HalModuleObject.
|
||||
DllBase)->
|
||||
OptionalHeader.SizeOfImage;
|
||||
|
||||
/* Increase the last kernel address with the size of HAL */
|
||||
TRACE;
|
||||
MmFreeLdrLastKernelAddress += PAGE_ROUND_UP(DriverSize);
|
||||
|
||||
#ifdef _M_IX86
|
||||
/* Now select the final beginning and ending Kernel Addresses */
|
||||
TRACE;
|
||||
MmFreeLdrFirstKrnlPhysAddr = KeLoaderModules[0].ModStart -
|
||||
KSEG0_BASE + 0x200000;
|
||||
MmFreeLdrLastKrnlPhysAddr = MmFreeLdrLastKernelAddress -
|
||||
@@ -445,22 +503,28 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy,
|
||||
#endif
|
||||
|
||||
/* Setup the IDT */
|
||||
TRACE;
|
||||
KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP!
|
||||
TRACE;
|
||||
KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL
|
||||
|
||||
/* Load the Kernel with the PE Loader */
|
||||
TRACE;
|
||||
LdrSafePEProcessModule((PVOID)KeLoaderModules[0].ModStart,
|
||||
(PVOID)KeLoaderModules[0].ModStart,
|
||||
(PVOID)DriverBase,
|
||||
&DriverSize);
|
||||
|
||||
/* Sets up the VDM Data */
|
||||
TRACE;
|
||||
NtEarlyInitVdm();
|
||||
|
||||
/* Convert the loader block */
|
||||
TRACE;
|
||||
KiRosFrldrLpbToNtLpb(&KeRosLoaderBlock, &NtLoaderBlock);
|
||||
|
||||
/* Do general System Startup */
|
||||
TRACE;
|
||||
KiSystemStartup(NtLoaderBlock);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,30 +30,37 @@ _kernel_trap_stack_top:
|
||||
.globl NtProcessStartup
|
||||
.globl KiSystemStartup
|
||||
.globl KiRosPrepareForSystemStartup
|
||||
.globl DrawNumber
|
||||
|
||||
NtProcessStartup:
|
||||
lis 0,AP_MAGIC@ha
|
||||
ori 0,0,AP_MAGIC@l
|
||||
cmpw 0,0,3
|
||||
lis 30,AP_MAGIC@ha
|
||||
ori 30,30,AP_MAGIC@l
|
||||
cmpw 0,30,3
|
||||
bne .m1
|
||||
|
||||
|
||||
/*
|
||||
* Set a normal MSR value
|
||||
*/
|
||||
xor 0,0,0
|
||||
ori 30,0,0x3031
|
||||
mtmsr 30
|
||||
|
||||
/*
|
||||
* Reserve space for the floating point save area.
|
||||
*/
|
||||
addi 1,1,-SIZEOF_FX_SAVE_AREA
|
||||
|
||||
/*
|
||||
* Call the application processor initialization code
|
||||
*/
|
||||
bl KiSystemStartup
|
||||
|
||||
.m1:
|
||||
/* Bye bye asm land! */
|
||||
mr 4,3
|
||||
bl KiRosPrepareForSystemStartup
|
||||
|
||||
.m1:
|
||||
/* Load the initial kernel stack */
|
||||
lis 1,_kernel_stack_top@ha
|
||||
ori 1,1,_kernel_stack_top@l
|
||||
addi 1,1,-SIZEOF_FX_SAVE_AREA
|
||||
|
||||
/* Call the main kernel initialization */
|
||||
mr 3,5
|
||||
mr 4,6
|
||||
mr 4,3
|
||||
bl KiRosPrepareForSystemStartup
|
||||
|
||||
|
||||
@@ -825,17 +825,6 @@ KeGetCurrentThread(VOID)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
KPROCESSOR_MODE
|
||||
NTAPI
|
||||
KeGetPreviousMode(VOID)
|
||||
{
|
||||
/* Return the previous mode of this thread */
|
||||
return KeGetCurrentThread()->PreviousMode;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -112,8 +112,11 @@ LdrInitModuleManagement ( PVOID KernelBase )
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
|
||||
/* Initialize the module list and spinlock */
|
||||
TRACEX(&ModuleListHead);
|
||||
InitializeListHead(&ModuleListHead);
|
||||
TRACE;
|
||||
KeInitializeSpinLock(&ModuleListLock);
|
||||
TRACE;
|
||||
|
||||
/* Initialize ModuleObject for NTOSKRNL */
|
||||
RtlZeroMemory(&NtoskrnlModuleObject, sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
@@ -121,25 +124,37 @@ LdrInitModuleManagement ( PVOID KernelBase )
|
||||
RtlInitUnicodeString(&NtoskrnlModuleObject.FullDllName, KERNEL_MODULE_NAME);
|
||||
LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseDllName, &NtoskrnlModuleObject.FullDllName);
|
||||
|
||||
TRACEXY(&RtlImageNtHeader,KernelBase);
|
||||
NtHeader = RtlImageNtHeader((PVOID)KernelBase);
|
||||
TRACE;
|
||||
NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint);
|
||||
TRACE;
|
||||
DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint);
|
||||
NtoskrnlModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
|
||||
TRACE;
|
||||
|
||||
InsertTailList(&ModuleListHead, &NtoskrnlModuleObject.InLoadOrderLinks);
|
||||
|
||||
/* Initialize ModuleObject for HAL */
|
||||
TRACE;
|
||||
RtlZeroMemory(&HalModuleObject, sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
HalModuleObject.DllBase = (PVOID) LdrHalBase;
|
||||
|
||||
TRACE;
|
||||
RtlInitUnicodeString(&HalModuleObject.FullDllName, HAL_MODULE_NAME);
|
||||
LdrpBuildModuleBaseName(&HalModuleObject.BaseDllName, &HalModuleObject.FullDllName);
|
||||
|
||||
TRACEX(LdrHalBase);
|
||||
NtHeader = RtlImageNtHeader((PVOID)LdrHalBase);
|
||||
if(!NtHeader)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint);
|
||||
DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint);
|
||||
HalModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
|
||||
|
||||
TRACE;
|
||||
InsertTailList(&ModuleListHead, &HalModuleObject.InLoadOrderLinks);
|
||||
}
|
||||
|
||||
@@ -362,15 +377,19 @@ LdrProcessModule(
|
||||
{
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
|
||||
TRACE;
|
||||
|
||||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L)
|
||||
{
|
||||
TRACE;
|
||||
return LdrPEProcessModule(ModuleLoadBase,
|
||||
ModuleName,
|
||||
ModuleObject);
|
||||
}
|
||||
|
||||
TRACE;
|
||||
CPRINT("Module wasn't PE\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,72 @@
|
||||
#!/bin/sh -v
|
||||
|
||||
export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin
|
||||
powerpc-unknown-linux-gnu-ld -EL -g -nostartfiles -nostdlib -N -Ttext=0xe17000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/windows/conversion.o obj-ppc/boot/freeldr/freeldr/windows/peloader.o obj-ppc/boot/freeldr/freeldr/windows/winldr.o obj-ppc/boot/freeldr/freeldr/windows/wlmemory.o obj-ppc/boot/freeldr/freeldr/windows/wlregistry.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/cmlib/cmlib.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a
|
||||
powerpc-unknown-linux-gnu-ld \
|
||||
-EL -g -nostartfiles -nostdlib -N -Ttext=0xe17000 \
|
||||
-o freeldr.elf \
|
||||
obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o \
|
||||
obj-ppc/boot/freeldr/freeldr/cache/blocklist.o \
|
||||
obj-ppc/boot/freeldr/freeldr/cache/cache.o \
|
||||
obj-ppc/boot/freeldr/freeldr/comm/rs232.o \
|
||||
obj-ppc/boot/freeldr/freeldr/disk/disk.o \
|
||||
obj-ppc/boot/freeldr/freeldr/disk/partition.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/ext2.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/fat.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/fs.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/fsrec.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/iso.o \
|
||||
obj-ppc/boot/freeldr/freeldr/fs/ntfs.o \
|
||||
obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o \
|
||||
obj-ppc/boot/freeldr/freeldr/inifile/inifile.o \
|
||||
obj-ppc/boot/freeldr/freeldr/inifile/parse.o \
|
||||
obj-ppc/boot/freeldr/freeldr/math/libgcc2.o \
|
||||
obj-ppc/boot/freeldr/freeldr/mm/meminit.o \
|
||||
obj-ppc/boot/freeldr/freeldr/mm/mm.o \
|
||||
obj-ppc/boot/freeldr/freeldr/reactos/registry.o \
|
||||
obj-ppc/boot/freeldr/freeldr/reactos/binhive.o \
|
||||
obj-ppc/boot/freeldr/freeldr/reactos/arcname.o \
|
||||
obj-ppc/boot/freeldr/freeldr/reactos/reactos.o \
|
||||
obj-ppc/boot/freeldr/freeldr/rtl/list.o \
|
||||
obj-ppc/boot/freeldr/freeldr/rtl/libsupp.o \
|
||||
obj-ppc/boot/freeldr/freeldr/ui/gui.o \
|
||||
obj-ppc/boot/freeldr/freeldr/ui/tui.o \
|
||||
obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o \
|
||||
obj-ppc/boot/freeldr/freeldr/ui/ui.o \
|
||||
obj-ppc/boot/freeldr/freeldr/video/bank.o \
|
||||
obj-ppc/boot/freeldr/freeldr/video/fade.o \
|
||||
obj-ppc/boot/freeldr/freeldr/video/palette.o \
|
||||
obj-ppc/boot/freeldr/freeldr/video/pixel.o \
|
||||
obj-ppc/boot/freeldr/freeldr/video/video.o \
|
||||
obj-ppc/boot/freeldr/freeldr/freeldr.o \
|
||||
obj-ppc/boot/freeldr/freeldr/debug.o \
|
||||
obj-ppc/boot/freeldr/freeldr/version.o \
|
||||
obj-ppc/boot/freeldr/freeldr/cmdline.o \
|
||||
obj-ppc/boot/freeldr/freeldr/machine.o \
|
||||
obj-ppc/boot/freeldr/freeldr/windows/conversion.o \
|
||||
obj-ppc/boot/freeldr/freeldr/windows/peloader.o \
|
||||
obj-ppc/boot/freeldr/freeldr/windows/winldr.o \
|
||||
obj-ppc/boot/freeldr/freeldr/windows/wlmemory.o \
|
||||
obj-ppc/boot/freeldr/freeldr/windows/wlregistry.o \
|
||||
obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o \
|
||||
obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o \
|
||||
obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o \
|
||||
obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o \
|
||||
obj-ppc/boot/freeldr/freeldr/bootmgr.o \
|
||||
obj-ppc/boot/freeldr/freeldr/drivemap.o \
|
||||
obj-ppc/boot/freeldr/freeldr/miscboot.o \
|
||||
obj-ppc/boot/freeldr/freeldr/options.o \
|
||||
obj-ppc/boot/freeldr/freeldr/linuxboot.o \
|
||||
obj-ppc/boot/freeldr/freeldr/oslist.o \
|
||||
obj-ppc/boot/freeldr/freeldr/custom.o \
|
||||
obj-ppc/lib/rossym/rossym.a \
|
||||
obj-ppc/lib/cmlib/cmlib.a \
|
||||
obj-ppc/lib/string/string.a \
|
||||
obj-ppc/lib/rtl/rtl.a \
|
||||
/usr/local/pkg/reactos-powerpc/lib/libgcc.a
|
||||
powerpc-unknown-linux-gnu-objcopy -O binary freeldr.elf freeldr.tmp.le
|
||||
output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp
|
||||
(dd if=/dev/zero bs=4k count=16 ; echo 'byebye') >> freeldr.tmp
|
||||
powerpc-unknown-linux-gnu-objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload
|
||||
reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s
|
||||
powerpc-unknown-linux-gnu-ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr.x ofwboot.o ofwldr.payload
|
||||
powerpc-unknown-linux-gnu-objcopy --only-section=.text --only-section=.data ofwldr.x ofwldr
|
||||
powerpc-unknown-linux-gnu-objcopy --only-section=.text --only-section=.data --only-section=.bss ofwldr.x ofwldr
|
||||
|
||||
Reference in New Issue
Block a user