PE driver loader is complete.

svn path=/trunk/; revision=158
This commit is contained in:
Rex Jolliff 1999-01-13 03:00:06 +00:00
parent dc7be08202
commit b0cbc91ce1
14 changed files with 1489 additions and 1207 deletions

View file

@ -20,14 +20,14 @@ typedef struct _KEY_OBJECT
ULONG NumSubKeys;
ULONG MaxSubNameLength;
ULONG MaxSubClassLength;
PKEY_OBJECT *SubKeys;
struct _KEY_OBJECT *SubKeys;
ULONG NumValues;
ULONG MaxValueNameLength;
ULONG MaxValueDataLength;
PKEY_VALUE *Values;
WCHAR *Name;
WCHAR *Class;
PKEY_OBJECT *NextKey;
struct _KEY_OBJECT *NextKey;
} KEY_OBJECT, *PKEY_OBJECT;
/* key query information class */

View file

@ -26,7 +26,7 @@ extern "C"
#include <ddk/ntdef.h>
#include <ddk/defines.h>
#include <ddk/types.h>
#include <ddk/cfgtypes.h>
// #include <ddk/cfgtypes.h>
#include <ddk/cmtypes.h>
#include <ddk/ketypes.h>
#include <ddk/obtypes.h>

View file

@ -100,8 +100,6 @@ typedef enum _FILE_INFORMATION_CLASS
FileMaximumInformation,
} FILE_INFORMATION_CLASS;
typedef ULONG KEY_INFORMATION_CLASS;
typedef ULONG KEY_VALUE_INFORMATION_CLASS;
typedef LARGE_INTEGER PHYSICAL_ADDRESS;
typedef PHYSICAL_ADDRESS* PPHYSICAL_ADDRESS;
typedef ULONG WAIT_TYPE;

View file

@ -24,7 +24,7 @@ extern POBJECT_TYPE IoSymbolicLinkType;
* entry = pointer to the driver initialization routine
* RETURNS: Success or failure
*/
NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry);
NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry);

View file

@ -19,7 +19,7 @@
* entry = pointer to the driver initialization routine
* RETURNS: Success or failure
*/
NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry);
NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry);
VOID IoInitCancelHandling(VOID);
VOID IoInitSymbolicLinkImplementation(VOID);

View file

@ -77,7 +77,7 @@ typedef struct
/*
* Initalization functions (called once by main())
*/
void MmInitalize(boot_param* bp);
void MmInitialize(boot_param* bp);
void HalInit(boot_param* bp);
void IoInit(void);
void ObInit(void);

View file

@ -24,6 +24,7 @@ PKEY_OBJECT RootKey = NULL;
VOID
CmInitializeRegistry(VOID)
{
#if 0
ANSI_STRING AnsiString;
CmKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
@ -79,6 +80,7 @@ CmInitializeRegistry(VOID)
/* FIXME: Create initial predefined symbolic links */
/* HKEY_LOCAL_MACHINE */
/* HKEY_USERS */
#endif
}
NTSTATUS
@ -108,6 +110,7 @@ ZwCreateKey(PHANDLE KeyHandle,
ULONG CreateOptions,
PULONG Disposition)
{
#if 0
/* FIXME: Should CurLevel be alloced to handle arbitrary size components? */
WCHAR *S, *T, CurLevel[255];
PKEY_OBJECT ParentKey, CurSubKey, NewKey;
@ -253,7 +256,7 @@ ZwCreateKey(PHANDLE KeyHandle,
{
return STATUS_UNSUCCESSFUL;
}
#endif
UNIMPLEMENTED;
}

View file

@ -113,7 +113,7 @@ VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
}
NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry)
NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry)
/*
* FUNCTION: Called to initalize a loaded driver
* ARGUMENTS:
@ -131,21 +131,25 @@ NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry)
if (DriverObject==NULL)
{
DbgPrint("%s:%d\n",__FILE__,__LINE__);
return(STATUS_INSUFFICIENT_RESOURCES);
return STATUS_INSUFFICIENT_RESOURCES;
}
memset(DriverObject,sizeof(DRIVER_OBJECT),0);
memset(DriverObject, '\0', sizeof(DRIVER_OBJECT));
CHECKPOINT;
/*
* Initalize the driver
* FIXME: Registry in general please
*/
DPRINT("Calling driver entrypoint at %08lx\n", entry);
if ((ret=entry(DriverObject,NULL)) != STATUS_SUCCESS)
{
DPRINT("Failed to load driver (status %x)\n",ret);
ExFreePool(DriverObject);
return(ret);
return ret;
}
return(STATUS_SUCCESS);
CHECKPOINT;
return STATUS_SUCCESS;
}
NTSTATUS IoAttachDevice(PDEVICE_OBJECT SourceDevice,

View file

@ -310,3 +310,4 @@ VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
IoSecondStageCompletion(Irp,PriorityBoost);
}
}

View file

@ -1,178 +1,356 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
* PURPOSE: Initalizes the kernel
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* 28/05/98: Created
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#include <internal/ntoskrnl.h>
#include <internal/version.h>
#include <internal/mm.h>
#include <internal/string.h>
#include <internal/symbol.h>
#include <internal/module.h>
#include <internal/mmhal.h>
#include <internal/i386/segment.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,
unsigned int len)
/*
* FUNCTION: Sets a hardware breakpoint
* ARGUMENTS:
* i = breakpoint to set (0 to 3)
* addr = linear address to break on
* type = Type of access to break on
* len = length of the variable to watch
* NOTES:
* The variable to watch must be aligned to its length (i.e. a dword
* breakpoint must be aligned to a dword boundary)
*
* A fatal exception will be generated on the access to the variable.
* It is (at the moment) only really useful for catching undefined
* pointers if you know the variable effected but not the buggy
* routine.
*
* FIXME: Extend to call out to kernel debugger on breakpoint
* Add support for I/O breakpoints
* REFERENCES: See the i386 programmer manual for more details
*/
{
unsigned int mask;
if (i>3)
{
printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__);
return;
}
/*
* Load the linear address
*/
switch (i)
{
case 0:
__asm("movl %0,%%db0\n\t"
: /* no outputs */
: "d" (addr));
break;
case 1:
__asm__("movl %0,%%db1\n\t"
: /* no outputs */
: "d" (addr));
break;
case 2:
__asm__("movl %0,%%db2\n\t"
: /* no outputs */
: "d" (addr));
break;
case 3:
__asm__("movl %0,%%db3\n\t"
: /* no outputs */
: "d" (addr));
break;
}
/*
* Setup mask for dr7
*/
mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2));
__asm__("movl %%db7,%%eax\n\t"
"orl %0,%%eax\n\t"
"movl %%eax,%%db7\n\t"
: /* no outputs */
: "d" (mask)
: "ax");
}
extern int edata;
extern int end;
asmlinkage void _main(boot_param* _bp)
/*
* FUNCTION: Called by the boot loader to start the kernel
* ARGUMENTS:
* _bp = Pointer to boot parameters initialized by the boot loader
* NOTE: The boot parameters are stored in low memory which will become
* invalid after the memory managment is initialized so we make a local copy.
*/
{
unsigned int i;
unsigned int start;
unsigned int start1;
boot_param bp;
memset((void *)&edata,0,((int)&end)-((int)&edata));
/*
* Copy the parameters to a local buffer because lowmem will go away
*/
memcpy(&bp,_bp,sizeof(boot_param));
/*
* Initalize the console (before printing anything)
* Copy the parameters to a local buffer because lowmem will go away
*/
memcpy(&bp,_bp,sizeof(boot_param));
/*
* Initalize the console (before printing anything)
*/
HalInitConsole(&bp);
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
if (start < ((int)&end))
{
DbgPrint("start %x end %x\n",start,(int)&end);
DbgPrint("Kernel booted incorrectly, aborting\n");
DbgPrint("Reduce the amount of uninitialized data\n");
for(;;);
}
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
/*
* Initalize various critical subsystems
*/
HalInit(&bp);
MmInitalize(&bp);
MmInitialize(&bp);
KeInit();
ObInit();
PsInit();
IoInit();
/*
* Initalize services loaded at boot time
*/
DPRINT("%d files loaded\n",bp.nr_files);
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
for (i=1;i<bp.nr_files;i++)
{
process_boot_module(start);
start=start+PAGE_ROUND_UP(bp.module_length[i]);
}
/*
* Test various features of the kernel
*/
TstBegin();
/*
* Enter idle loop
*/
printk("Finished main()\n");
PsTerminateSystemThread(STATUS_SUCCESS);
}

View file

@ -396,5 +396,5 @@ BOOLEAN process_boot_module(unsigned int start)
* Call the module initalization routine
*/
func = (PDRIVER_INITIALIZE)(mod->base + entry);
return(InitalizeLoadedDriver(func));
return(InitializeLoadedDriver(func));
}

View file

@ -40,6 +40,7 @@ NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase);
/* PE Driver load support */
static NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
static unsigned int LdrGetKernelSymbolAddr(char *Name);
/* COFF Driver load support */
static NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
@ -48,7 +49,6 @@ static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relo
static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
static void LdrCOFFGetSymbolName(module *Module, unsigned int Idx, char *Name);
static unsigned int LdrCOFFGetSymbolValue(module *Module, unsigned int Idx);
static unsigned int LdrCOFFGetKernelSymbolAddr(char *Name);
static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName, unsigned int Idx);
/* Image loader forward delcarations */
@ -188,7 +188,8 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
{
unsigned int DriverSize, Idx;
long int RelocDelta, NumRelocs;
PVOID DriverBase, RelocBase;
DWORD CurrentSize;
PVOID DriverBase, CurrentBase, EntryPoint;
PULONG PEMagic;
PIMAGE_DOS_HEADER PEDosHeader;
PIMAGE_FILE_HEADER PEFileHeader;
@ -196,6 +197,14 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
PIMAGE_SECTION_HEADER PESectionHeaders;
PRELOCATION_DIRECTORY RelocDir;
PRELOCATION_ENTRY RelocEntry;
PMODULE Library;
PVOID *ImportAddressList;
PULONG FunctionNameList;
PCHAR pName, SymbolNameBuf;
PWORD pHint;
/* FIXME: this could be used to load kernel DLLs also, however */
/* the image headers should be preserved in such a case */
DPRINT("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
@ -249,10 +258,10 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
/* Determine the size of the module */
DPRINT("Sections: (section align:%08lx)\n",
PEOptionalHeader->SectionAlignment);
DriverSize = 0;
DriverSize = PESectionHeaders[0].PointerToRawData;
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
{
DPRINT("Name: %-8.8s VA:%08lx RawSize:%6d Offset:%08lx CHAR:%08lx OfsAdr: %08lx\n",
DPRINT("Name:%-8.8s VA:%08lx RawSz:%6d Offs:%08lx CHAR:%08lx OfsA: %08lx\n",
PESectionHeaders[Idx].Name,
PESectionHeaders[Idx].VirtualAddress,
PESectionHeaders[Idx].SizeOfRawData,
@ -266,7 +275,6 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
DriverSize,
DriverSize);
#if 0
/* Allocate a virtual section for the module */
DriverBase = MmAllocateSection(DriverSize);
if (DriverBase == 0)
@ -276,7 +284,9 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
}
CHECKPOINT;
CurrentBase = ModuleLoadBase;
/* Copy image sections into virtual section */
memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData);
CurrentBase = (PVOID) ((DWORD)DriverBase + PESectionHeaders[0].PointerToRawData);
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
{
/* Copy current section into current offset of virtual section */
@ -293,19 +303,19 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
}
CurrentSize += ROUND_UP(PESectionHeaders[Idx].SizeOfRawData,
PEOptionalHeader->SectionAlignment);
CurrentBase = (PVOID)((DWORD)CurrentBase +
ROUND_UP(PESectionHeaders[Idx].SizeOfRawData,
PEOptionalHeader->SectionAlignment));
}
#else
DriverBase = ModuleLoadBase;
#endif
/* FIXME: Perform relocation fixups */
/* Perform relocation fixups */
RelocDelta = (DWORD) DriverBase - PEOptionalHeader->ImageBase;
RelocDir = (PRELOCATION_DIRECTORY) ((DWORD)ModuleLoadBase +
PEOptionalHeader->DataDirectory[
IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
DPRINT("Relocs: ModuleLoadBase: %08lx RelocDelta %08lx\n",
ModuleLoadBase,
DPRINT("DrvrBase:%08lx ImgBase:%08lx RelocDelta:%08lx\n",
DriverBase,
PEOptionalHeader->ImageBase,
RelocDelta);
while (RelocDir->SizeOfBlock != 0)
{
@ -328,21 +338,108 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
(RelocEntry[Idx].TypeOffset & 0x0fff)),
(*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress +
(RelocEntry[Idx].TypeOffset & 0x0fff))) + RelocDelta);
if (((RelocEntry[Idx].TypeOffset >> 12) & 0xf) == 3)
{
(*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress +
(RelocEntry[Idx].TypeOffset & 0x0fff))) += RelocDelta;
}
else if (((RelocEntry[Idx].TypeOffset >> 12) & 0xf) != 0)
{
DPRINT("Unknown relocation type %x\n",
(RelocEntry[Idx].TypeOffset >> 12) & 0xf);
return STATUS_UNSUCCESSFUL;
}
}
RelocDir = (PRELOCATION_DIRECTORY)((DWORD)RelocDir +
RelocDir->SizeOfBlock);
getchar();
}
#if 0
/* Perform import fixups */
if (PEOptionalHeader->DataDirectory[
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
{
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
/* FIXME: perform import fixups */
/* FIXME: compute address of entry point */
SymbolNameBuf = ExAllocatePool(NonPagedPool, 512);
#endif
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
((DWORD)ModuleLoadBase + PEOptionalHeader->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (ImportModuleDirectory->dwRVAModuleName)
{
/* FIXME: handle kernel mode DLLs */
/* return InitializeLoadedDriver(EntryPoint); */
return STATUS_NOT_IMPLEMENTED;
/* Check to make sure that import lib is kernel */
Library = NULL;
pName = (PCHAR) ModuleLoadBase +
ImportModuleDirectory->dwRVAModuleName;
DPRINT("Import module: %s\n", pName);
if (strcmp(pName, "ntoskrnl.exe") &&
strcmp(pName, "HAL.dll"))
{
DPRINT("Kernel mode DLLs are currently unsupported\n");
}
/* Get the import address list */
ImportAddressList = (PVOID *) ((DWORD)ModuleLoadBase +
ImportModuleDirectory->dwRVAFunctionAddressList);
/* Get the list of functions to import */
if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
{
FunctionNameList = (PULONG) ((DWORD)ModuleLoadBase +
ImportModuleDirectory->dwRVAFunctionNameList);
}
else
{
FunctionNameList = (PULONG) ((DWORD)ModuleLoadBase +
ImportModuleDirectory->dwRVAFunctionAddressList);
}
/* Walk through function list and fixup addresses */
while(*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000) // hint
{
DPRINT(" Hint: %08lx\n", *FunctionNameList);
if (Library == NULL)
{
DPRINT("Hints for kernel symbols are not handled.\n");
*ImportAddressList = 0;
}
}
else // hint-name
{
pName = (PCHAR)((DWORD)ModuleLoadBase +
*FunctionNameList + 2);
pHint = (PWORD)((DWORD)ModuleLoadBase + *FunctionNameList);
DPRINT(" Hint:%04x Name:%s\n", pHint, pName);
/* Get address for symbol */
if (Library == NULL)
{
*SymbolNameBuf = '_';
strcpy(SymbolNameBuf + 1, pName);
*ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf); if (*ImportAddressList == 0L)
{
DPRINT("Unresolved kernel symbol: %s\n", pName);
}
}
}
ImportAddressList++;
FunctionNameList++;
}
ImportModuleDirectory++;
}
ExFreePool(SymbolNameBuf);
}
/* Compute address of entry point */
EntryPoint = (PVOID) ((DWORD)DriverBase + PEOptionalHeader->AddressOfEntryPoint);
return InitializeLoadedDriver(EntryPoint);
}
NTSTATUS
@ -491,7 +588,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
/* Cleanup */
ExFreePool(Module);
return InitalizeLoadedDriver(EntryRoutine);
return InitializeLoadedDriver(EntryRoutine);
}
/* LdrCOFFDoRelocations
@ -594,7 +691,7 @@ LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation)
memset(Name, 0, 255);
LdrCOFFGetSymbolName(Module, Relocation->r_symndx, Name);
Value = (unsigned int) LdrCOFFGetKernelSymbolAddr(Name);
Value = (unsigned int) LdrGetKernelSymbolAddr(Name);
if (Value == 0L)
{
Value = LdrCOFFGetSymbolValueByName(Module, Name, Relocation->r_symndx);
@ -691,7 +788,7 @@ LdrCOFFGetSymbolValue(module *Module, unsigned int Idx)
*/
static unsigned int
LdrCOFFGetKernelSymbolAddr(char *Name)
LdrGetKernelSymbolAddr(char *Name)
{
int i = 0;

View file

@ -48,7 +48,7 @@ MM_SYSTEM_SIZE MmQuerySystemSize()
UNIMPLEMENTED;
}
void MmInitalize(boot_param* bp)
void MmInitialize(boot_param* bp)
/*
* FUNCTION: Initalize memory managment
*/

View file

@ -674,3 +674,4 @@ PVOID ExAllocateNonPagedPoolWithTag(ULONG type, ULONG size, ULONG Tag)
memset(block,0,size);
return(block);
}