First hack at KMDLLs

svn path=/trunk/; revision=523
This commit is contained in:
Rex Jolliff 1999-05-28 18:24:27 +00:00
parent 9377d51b1a
commit d415ba8508
15 changed files with 610 additions and 118 deletions

View file

@ -3,12 +3,12 @@
: :
: copy files to HD... : copy files to HD...
: :
COPY /Y BLUE.SYS C:\reactos\system\drivers\blue.SYS COPY /Y BLUE.SYS C:\reactos\system\drivers\blue.SYS > NUL:
COPY /Y KEYBOARD.SYS C:\reactos\system\drivers\KEYBOARD.SYS COPY /Y KEYBOARD.SYS C:\reactos\system\drivers\KEYBOARD.SYS > NUL:
COPY /Y NTDLL.DLL C:\reactos\system\NTDLL.DLL COPY /Y NTDLL.DLL C:\reactos\system\NTDLL.DLL > NUL:
COPY /Y KERNEL32.DLL C:\reactos\system\KERNEL32.DLL COPY /Y KERNEL32.DLL C:\reactos\system\KERNEL32.DLL > NUL:
: COPY /Y CRTDLL.DLL C:\reactos\system\CRTDLL.DLL : COPY /Y CRTDLL.DLL C:\reactos\system\CRTDLL.DLL > NUL:
COPY /Y SHELL.EXE C:\reactos\system\SHELL.EXE COPY /Y SHELL.EXE C:\reactos\system\SHELL.EXE > NUL:
: :
: present a menu to the booter... : present a menu to the booter...

View file

@ -0,0 +1,25 @@
/*
* MINIPORT.H - miniport driver interface header
*/
#define EMULATOR_READ_ACCESS 0x00000001
#define EMULATOR_WRITE_ACCESS 0x00000002
typedef enum _EMULATOR_PORT_ACCESS_TYPE
{
Uchar,
Ushort,
Ulong
} EMULATOR_PORT_ACCESS_TYPE, *PEMULATOR_PORT_ACCESS_TYPE;
typedef struct _EMULATOR_ACCESS_ENTRY
{
ULONG BasePort;
ULONG NumConsecutivePorts;
EMULATOR_PORT_ACCESS_TYPE AccessType;
UCHAR AccessMode;
UCHAR StringSupport;
PVOID Routine;
} EMULATOR_ACCESS_ENTRY, *PEMULATOR_ACCESS_ENTRY;

View file

@ -2,6 +2,7 @@
#ifndef __MODULE_H #ifndef __MODULE_H
#define __MODULE_H #define __MODULE_H
#include <ddk/ntddk.h>
#include <coff.h> #include <coff.h>
#include <pe.h> #include <pe.h>
@ -30,11 +31,13 @@ typedef struct _module
typedef SCNHDR COFF_SECTION_HEADER, *PCOFF_SECTION_HEADER; typedef SCNHDR COFF_SECTION_HEADER, *PCOFF_SECTION_HEADER;
typedef struct _MODULE typedef struct _MODULE_OBJECT
{ {
PVOID Base; CSHORT ObjectType;
unsigned int Size; CSHORT ObjectSize;
unsigned int Flags; PVOID Base;
unsigned int Flags;
PVOID EntryPoint;
union union
{ {
struct struct
@ -51,10 +54,12 @@ typedef struct _MODULE
{ {
PIMAGE_FILE_HEADER FileHeader; PIMAGE_FILE_HEADER FileHeader;
PIMAGE_OPTIONAL_HEADER OptionalHeader; PIMAGE_OPTIONAL_HEADER OptionalHeader;
PCOFF_SECTION_HEADER SectionList; PIMAGE_SECTION_HEADER SectionList;
} PE; } PE;
} Image; } Image;
} MODULE, *PMODULE; } MODULE_OBJECT, *PMODULE_OBJECT;
typedef MODULE_OBJECT MODULE, *PMODULE;
#define MODULE_FLAG_BIN 0x0001 #define MODULE_FLAG_BIN 0x0001
#define MODULE_FLAG_MZ 0x0002 #define MODULE_FLAG_MZ 0x0002
@ -64,7 +69,7 @@ typedef struct _MODULE
typedef struct _INSTANCE typedef struct _INSTANCE
{ {
HANDLE ModuleHandle; HANDLE ModuleHandle;
} INSTANCE, *PINSTANCE; } INSTANCE, *PINSTANCE;
BOOLEAN process_boot_module(unsigned int start); BOOLEAN process_boot_module(unsigned int start);

View file

@ -554,6 +554,8 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
sizeof (IMAGE_FILE_HEADER) + \ sizeof (IMAGE_FILE_HEADER) + \
sizeof (IMAGE_OPTIONAL_HEADER))) sizeof (IMAGE_OPTIONAL_HEADER)))
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
typedef struct _IMAGE_IMPORT_MODULE_DIRECTORY typedef struct _IMAGE_IMPORT_MODULE_DIRECTORY
{ {
DWORD dwRVAFunctionNameList; DWORD dwRVAFunctionNameList;

View file

@ -0,0 +1,2 @@
crtdll.coff
crtdll.dll

View file

@ -0,0 +1,2 @@
fmifs.coff
fmifs.dll

View file

@ -1,7 +1,8 @@
base.tmp
junk.tmp
napi.asm napi.asm
napi.c napi.c
ntdll.lib ntdll.lib
base.tmp ntdll.coff
junk.tmp
ntdll.dll ntdll.dll
temp.exp temp.exp

View file

@ -0,0 +1,2 @@
user32.coff
user32.dll

View file

@ -1,13 +1,27 @@
@echo off @echo off
echo copying latest files to a:... echo copying latest files to a:...
copy /Y bootflop.bat a:\autoexec.bat copy /Y bootflop.bat a:\autoexec.bat > NUL:
copy /Y loaders\dos\loadros.com a: echo bootflop.bat to a:\autoexec.bat
copy /Y apps\shell\shell.exe a: copy /Y loaders\dos\loadros.com a: > NUL:
copy /Y ntoskrnl\ntoskrnl.exe a: echo loadros.com
copy /Y services\dd\blue\blue.sys a: copy /Y ntoskrnl\ntoskrnl.exe a: > NUL:
copy /Y services\dd\keyboard\keyboard.sys a: echo ntoskrnl.exe
copy /Y services\dd\ide\ide.sys a: copy /Y services\dd\ide\ide.sys a: > NUL:
copy /Y services\fs\vfat\vfatfsd.sys a: echo ide.sys
copy /Y lib\ntdll\ntdll.dll a: copy /Y services\fs\vfat\vfatfsd.sys a: > NUL:
copy /Y lib\kernel32\kernel32.dll a: echo vfatfsd.sys
: copy /Y lib\crtdll\crtdll.dll a: copy /Y services\dd\blue\blue.sys a: > NUL:
echo blue.sys
copy /Y services\dd\keyboard\keyboard.sys a: > NUL:
echo keyboard.sys
copy /Y lib\ntdll\ntdll.dll a: > NUL:
echo ntdll.dll
copy /Y lib\kernel32\kernel32.dll a: > NUL:
echo kernel32.dll
copy /Y apps\shell\shell.exe a: > NUL:
echo shell.exe
: copy /Y lib\crtdll\crtdll.dll a: > NUL:
: echo lib\crtdll\crtdll.dll a:

View file

@ -17,6 +17,7 @@ include rules.mak
COMPONENTS = iface_native ntoskrnl COMPONENTS = iface_native ntoskrnl
DLLS = ntdll kernel32 crtdll user32 fmifs gdi32 DLLS = ntdll kernel32 crtdll user32 fmifs gdi32
#DLLS = crtdll mingw32 #DLLS = crtdll mingw32
SUBSYS = win32k
# #
# Select the server(s) you want to build # Select the server(s) you want to build
@ -41,7 +42,7 @@ KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
APPS = args hello shell test cat bench APPS = args hello shell test cat bench
# APPS = cmd # APPS = cmd
all: $(COMPONENTS) $(DLLS) $(LOADERS) $(KERNEL_SERVICES) $(APPS) all: $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
.PHONY: all .PHONY: all
clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \ clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
@ -125,4 +126,15 @@ $(DLLS:%=%_clean): %_clean:
.PHONY: $(DLLS) $(DLLS:%=%_clean) .PHONY: $(DLLS) $(DLLS:%=%_clean)
#
# Kernel Subsystems
#
$(SUBSYS): %:
make -C subsys/$*
$(SUBSYS:%=%_clean): %_clean:
make -C lib/$* clean
.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean)

View file

@ -17,6 +17,7 @@ include rules.mak
COMPONENTS = iface_native ntoskrnl COMPONENTS = iface_native ntoskrnl
DLLS = ntdll kernel32 crtdll user32 fmifs DLLS = ntdll kernel32 crtdll user32 fmifs
#DLLS = crtdll mingw32 #DLLS = crtdll mingw32
SUBSYS = win32k
# #
# Select the server(s) you want to build # Select the server(s) you want to build
@ -41,7 +42,7 @@ KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
APPS = args hello shell test cat bench APPS = args hello shell test cat bench
# APPS = cmd # APPS = cmd
all: $(COMPONENTS) $(DLLS) $(LOADERS) $(KERNEL_SERVICES) $(APPS) all: $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
.PHONY: all .PHONY: all
clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \ clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
@ -125,4 +126,15 @@ $(DLLS:%=%_clean): %_clean:
.PHONY: $(DLLS) $(DLLS:%=%_clean) .PHONY: $(DLLS) $(DLLS:%=%_clean)
#
# Kernel Subsystems
#
$(SUBSYS): %:
make -C subsys/$*
$(SUBSYS:%=%_clean): %_clean:
make -C lib/$* clean
.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean)

View file

@ -22,6 +22,7 @@
#include <internal/linkage.h> #include <internal/linkage.h>
#include <internal/module.h> #include <internal/module.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#include <internal/mmhal.h>
#include <internal/ob.h> #include <internal/ob.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <string.h> #include <string.h>
@ -38,6 +39,8 @@ NTSTATUS IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry);
/* MACROS ********************************************************************/ /* MACROS ********************************************************************/
#define MODULE_ROOT_NAME L"\\Modules\\"
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
POBJECT_TYPE ObModuleType = NULL; POBJECT_TYPE ObModuleType = NULL;
@ -47,12 +50,25 @@ POBJECT_TYPE ObModuleType = NULL;
NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename); NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename);
NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase); NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase);
PMODULE_OBJECT LdrLoadModule(PUNICODE_STRING Filename);
PMODULE_OBJECT LdrProcessModule(PVOID ModuleLoadBase);
PVOID LdrGetExportAddress(PMODULE_OBJECT ModuleObject, char *Name, unsigned short Hint);
static PIMAGE_SECTION_HEADER LdrPEGetEnclosingSectionHeader(DWORD RVA,
PMODULE_OBJECT ModuleObject);
static NTSTATUS LdrCreateModule(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes);
/* PE Driver load support */ /* PE Driver load support */
static NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase); static PMODULE_OBJECT LdrPEProcessModule(PVOID ModuleLoadBase);
static PVOID LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
char *Name,
unsigned short Hint);
static unsigned int LdrGetKernelSymbolAddr(char *Name); static unsigned int LdrGetKernelSymbolAddr(char *Name);
/* COFF Driver load support */ /* COFF Driver load support */
static NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase); static PMODULE_OBJECT LdrCOFFProcessModule(PVOID ModuleLoadBase);
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex); static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation); static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation); static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
@ -64,7 +80,14 @@ static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName
VOID LdrInitModuleManagement(VOID) VOID LdrInitModuleManagement(VOID)
{ {
HANDLE DirHandle, ModuleHandle;
NTSTATUS Status;
WCHAR NameBuffer[60];
ANSI_STRING AnsiString; ANSI_STRING AnsiString;
UNICODE_STRING ModuleName;
OBJECT_ATTRIBUTES ObjectAttributes;
PIMAGE_DOS_HEADER DosHeader;
PMODULE_OBJECT ModuleObject;
/* Register the process object type */ /* Register the process object type */
ObModuleType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); ObModuleType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
@ -82,8 +105,85 @@ VOID LdrInitModuleManagement(VOID)
ObModuleType->Security = NULL; ObModuleType->Security = NULL;
ObModuleType->QueryName = NULL; ObModuleType->QueryName = NULL;
ObModuleType->OkayToClose = NULL; ObModuleType->OkayToClose = NULL;
ObModuleType->Create = LdrCreateModule;
RtlInitAnsiString(&AnsiString, "Module"); RtlInitAnsiString(&AnsiString, "Module");
RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE); RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE);
/* Create Modules object directory */
wcscpy(NameBuffer, MODULE_ROOT_NAME);
*(wcsrchr(NameBuffer, L'\\')) = 0;
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
InitializeObjectAttributes(&ObjectAttributes,
&ModuleName,
0,
NULL,
NULL);
DPRINT("Create dir: %W\n", &ModuleName);
Status = ZwCreateDirectoryObject(&DirHandle, 0, &ObjectAttributes);
assert(NT_SUCCESS(Status));
/* Add module entry for NTOSKRNL */
wcscpy(NameBuffer, MODULE_ROOT_NAME);
wcscat(NameBuffer, L"ntoskrnl.exe");
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
DPRINT("Kernel's Module name is: %W\n", &ModuleName);
/* Initialize ObjectAttributes for ModuleObject */
InitializeObjectAttributes(&ObjectAttributes,
&ModuleName,
0,
NULL,
NULL);
/* Create module object */
ModuleHandle = 0;
ModuleObject = ObCreateObject(&ModuleHandle,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
ObModuleType);
assert(ModuleObject != NULL);
/* Initialize ModuleObject data */
ModuleObject->Base = (PVOID) KERNEL_BASE;
ModuleObject->Flags = MODULE_FLAG_PE;
DosHeader = (PIMAGE_DOS_HEADER) KERNEL_BASE;
ModuleObject->Image.PE.FileHeader =
(PIMAGE_FILE_HEADER) ((DWORD) ModuleObject->Base +
DosHeader->e_lfanew + sizeof(ULONG));
ModuleObject->Image.PE.OptionalHeader = (PIMAGE_OPTIONAL_HEADER)
((DWORD)ModuleObject->Image.PE.FileHeader + sizeof(IMAGE_FILE_HEADER));
ModuleObject->Image.PE.SectionList = (PIMAGE_SECTION_HEADER)
((DWORD)ModuleObject->Image.PE.OptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER));
ModuleObject->EntryPoint = (PVOID) ((DWORD) ModuleObject->Base +
ModuleObject->Image.PE.OptionalHeader->AddressOfEntryPoint);
DPRINT("ModuleObject:%08x entrypoint at %x\n", ModuleObject, ModuleObject->EntryPoint);
/* FIXME: Add fake module entry for HAL */
}
static NTSTATUS
LdrCreateModule(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes)
{
DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %w)\n",
ObjectBody,
Parent,
RemainingPath);
if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
{
return STATUS_UNSUCCESSFUL;
}
if (Parent != NULL && RemainingPath != NULL)
{
ObAddEntryDirectory(Parent, ObjectBody, RemainingPath + 1);
}
return STATUS_SUCCESS;
} }
/* /*
@ -125,17 +225,68 @@ VOID LdrLoadAutoConfigDrivers(VOID)
NTSTATUS NTSTATUS
LdrLoadDriver(PUNICODE_STRING Filename) LdrLoadDriver(PUNICODE_STRING Filename)
{
PMODULE_OBJECT ModuleObject;
ModuleObject = LdrLoadModule(Filename);
if (ModuleObject == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* FIXME: should we dereference the ModuleObject here? */
return IoInitializeDriver(ModuleObject->EntryPoint);
}
PMODULE_OBJECT
LdrLoadModule(PUNICODE_STRING Filename)
{ {
PVOID ModuleLoadBase; PVOID ModuleLoadBase;
NTSTATUS Status; NTSTATUS Status;
HANDLE FileHandle; HANDLE FileHandle;
OBJECT_ATTRIBUTES FileObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
PMODULE_OBJECT ModuleObject;
FILE_STANDARD_INFORMATION FileStdInfo; FILE_STANDARD_INFORMATION FileStdInfo;
WCHAR NameBuffer[60];
PWSTR RemainingPath;
UNICODE_STRING ModuleName;
DbgPrint("Loading Driver %W...\n", Filename); DPRINT("Loading Module %W...\n", Filename);
/* Open the Driver */ /* Check for module already loaded */
InitializeObjectAttributes(&FileObjectAttributes, wcscpy(NameBuffer, MODULE_ROOT_NAME);
if (wcsrchr(Filename->Buffer, '\\') != 0)
{
wcscat(NameBuffer, wcsrchr(Filename->Buffer, '\\') + 1);
}
else
{
wcscat(NameBuffer, Filename->Buffer);
}
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
InitializeObjectAttributes(&ObjectAttributes,
&ModuleName,
0,
NULL,
NULL);
Status = ObFindObject(&ObjectAttributes,
(PVOID *) &ModuleObject,
&RemainingPath);
CHECKPOINT;
if (NT_SUCCESS(Status) && *RemainingPath == 0)
{
return ModuleObject;
}
CHECKPOINT;
if (!wcsncmp(Filename->Buffer, MODULE_ROOT_NAME, wcslen(MODULE_ROOT_NAME)))
{
return 0;
}
/* Open the Module */
InitializeObjectAttributes(&ObjectAttributes,
Filename, Filename,
0, 0,
NULL, NULL,
@ -143,12 +294,13 @@ LdrLoadDriver(PUNICODE_STRING Filename)
CHECKPOINT; CHECKPOINT;
Status = ZwOpenFile(&FileHandle, Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS, FILE_ALL_ACCESS,
&FileObjectAttributes, &ObjectAttributes,
NULL, 0, 0); NULL, 0, 0);
CHECKPOINT; CHECKPOINT;
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; DbgPrint("Could not open module file: %W\n", Filename);
return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -160,7 +312,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
FileStandardInformation); FileStandardInformation);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; DbgPrint("Could not get file size\n");
return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -169,7 +322,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
FileStdInfo.EndOfFile.u.LowPart); FileStdInfo.EndOfFile.u.LowPart);
if (ModuleLoadBase == NULL) if (ModuleLoadBase == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; DbgPrint("could not allocate memory for module");
return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -181,23 +335,41 @@ LdrLoadDriver(PUNICODE_STRING Filename)
0, 0); 0, 0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("could not read module file into memory");
ExFreePool(ModuleLoadBase); ExFreePool(ModuleLoadBase);
return Status;
return 0;
} }
CHECKPOINT; CHECKPOINT;
ZwClose(FileHandle); ZwClose(FileHandle);
Status = LdrProcessDriver(ModuleLoadBase); ModuleObject = LdrProcessModule(ModuleLoadBase);
/* Cleanup */ /* Cleanup */
ExFreePool(ModuleLoadBase); ExFreePool(ModuleLoadBase);
return STATUS_SUCCESS; return ModuleObject;
} }
NTSTATUS NTSTATUS
LdrProcessDriver(PVOID ModuleLoadBase) LdrProcessDriver(PVOID ModuleLoadBase)
{
PMODULE_OBJECT ModuleObject;
ModuleObject = LdrProcessModule(ModuleLoadBase);
if (ModuleObject == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* FIXME: should we dereference the ModuleObject here? */
return IoInitializeDriver(ModuleObject->EntryPoint);
}
PMODULE_OBJECT
LdrProcessModule(PVOID ModuleLoadBase)
{ {
PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_DOS_HEADER PEDosHeader;
@ -205,42 +377,66 @@ LdrProcessDriver(PVOID ModuleLoadBase)
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase; PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC && PEDosHeader->e_lfanew != 0L) if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC && PEDosHeader->e_lfanew != 0L)
{ {
return LdrPEProcessDriver(ModuleLoadBase); return LdrPEProcessModule(ModuleLoadBase);
} }
#if 0
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC) if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC)
{ {
return STATUS_NOT_IMPLEMENTED; return 0;
} }
else /* Assume COFF format and load */ else /* Assume COFF format and load */
{ {
return LdrCOFFProcessDriver(ModuleLoadBase); return LdrCOFFProcessModule(ModuleLoadBase);
}
#endif
return 0;
}
PVOID
LdrGetExportAddress(PMODULE_OBJECT ModuleObject,
char *Name,
unsigned short Hint)
{
if (ModuleObject->Flags & MODULE_FLAG_PE)
{
return LdrPEGetExportAddress(ModuleObject, Name, Hint);
}
else
{
return 0;
} }
} }
NTSTATUS /* ---------------------------------------------- PE Module support */
LdrPEProcessDriver(PVOID ModuleLoadBase)
PMODULE_OBJECT
LdrPEProcessModule(PVOID ModuleLoadBase)
{ {
unsigned int DriverSize, Idx; unsigned int DriverSize, Idx, Idx2;
ULONG RelocDelta, NumRelocs; ULONG RelocDelta, NumRelocs;
DWORD CurrentSize, TotalRelocs; DWORD CurrentSize, TotalRelocs;
PVOID DriverBase, CurrentBase, EntryPoint; PVOID DriverBase, CurrentBase;
PULONG PEMagic; PULONG PEMagic;
PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_DOS_HEADER PEDosHeader;
PIMAGE_FILE_HEADER PEFileHeader; PIMAGE_FILE_HEADER PEFileHeader;
PIMAGE_OPTIONAL_HEADER PEOptionalHeader; PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
PIMAGE_SECTION_HEADER PESectionHeaders; PIMAGE_SECTION_HEADER PESectionHeaders;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
PRELOCATION_DIRECTORY RelocDir; PRELOCATION_DIRECTORY RelocDir;
PRELOCATION_ENTRY RelocEntry; PRELOCATION_ENTRY RelocEntry;
PMODULE Library; PMODULE_OBJECT LibraryModuleObject;
HANDLE ModuleHandle;
PMODULE_OBJECT ModuleObject;
PVOID *ImportAddressList; PVOID *ImportAddressList;
PULONG FunctionNameList; PULONG FunctionNameList;
PCHAR pName, SymbolNameBuf; PCHAR pName, SymbolNameBuf;
PWORD pHint; WORD Hint;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ModuleName;
WCHAR NameBuffer[60];
/* FIXME: this could be used to load kernel DLLs also, however */ DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
/* the image headers should be preserved in such a case */
DPRINT("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
/* Get header pointers */ /* Get header pointers */
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase; PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
@ -258,23 +454,23 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
/* Check file magic numbers */ /* Check file magic numbers */
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC) if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC)
{ {
DPRINT("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic); DbgPrint("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
return STATUS_UNSUCCESSFUL; return 0;
} }
if (PEDosHeader->e_lfanew == 0) if (PEDosHeader->e_lfanew == 0)
{ {
DPRINT("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew); DbgPrint("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
return STATUS_UNSUCCESSFUL; return 0;
} }
if (*PEMagic != IMAGE_PE_MAGIC) if (*PEMagic != IMAGE_PE_MAGIC)
{ {
DPRINT("Incorrect PE magic: %08x\n", *PEMagic); DbgPrint("Incorrect PE magic: %08x\n", *PEMagic);
return STATUS_UNSUCCESSFUL; return 0;
} }
if (PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386) if (PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
{ {
DPRINT("Incorrect Architechture: %04x\n", PEFileHeader->Machine); DbgPrint("Incorrect Architechture: %04x\n", PEFileHeader->Machine);
return STATUS_UNSUCCESSFUL; return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -299,10 +495,10 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
if (DriverBase == 0) if (DriverBase == 0)
{ {
DbgPrint("Failed to allocate a virtual section for driver\n"); DbgPrint("Failed to allocate a virtual section for driver\n");
return STATUS_INSUFFICIENT_RESOURCES; return 0;
} }
CHECKPOINT; CHECKPOINT;
DbgPrint("Module is at base %x\n",DriverBase); DPRINT("Module is at base %x\n",DriverBase);
/* Copy image sections into virtual section */ /* Copy image sections into virtual section */
memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData); memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData);
@ -390,8 +586,8 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
} }
else if (Type != 0) else if (Type != 0)
{ {
DPRINT("Unknown relocation type %x\n",Type); DbgPrint("Unknown relocation type %x\n",Type);
return STATUS_UNSUCCESSFUL; return 0;
} }
} }
TotalRelocs += RelocDir->SizeOfBlock; TotalRelocs += RelocDir->SizeOfBlock;
@ -415,21 +611,36 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY) ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
((DWORD)DriverBase + PEOptionalHeader-> ((DWORD)DriverBase + PEOptionalHeader->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
while (ImportModuleDirectory->dwRVAModuleName) while (ImportModuleDirectory->dwRVAModuleName)
{ {
/* FIXME: handle kernel mode DLLs */
/* Check to make sure that import lib is kernel */ /* Check to make sure that import lib is kernel */
Library = NULL;
pName = (PCHAR) DriverBase + pName = (PCHAR) DriverBase +
ImportModuleDirectory->dwRVAModuleName; ImportModuleDirectory->dwRVAModuleName;
// DPRINT("Import module: %s\n", pName); if (!strcmp(pName, "ntoskrnl.exe") || !strcmp(pName, "HAL.dll"))
if (strcmp(pName, "ntoskrnl.exe")!=0 &&
strcmp(pName, "HAL.dll")!=0)
{ {
DPRINT("Kernel mode DLLs are currently unsupported\n"); LibraryModuleObject = NULL;
DPRINT("Kernel imports\n");
}
else
{
wcscpy(NameBuffer, MODULE_ROOT_NAME);
for (Idx = 0; NameBuffer[Idx] != 0; Idx++)
;
for (Idx2 = 0; pName[Idx2] != '\0'; Idx2++)
{
NameBuffer[Idx + Idx2] = (WCHAR) pName[Idx2];
}
NameBuffer[Idx + Idx2] = 0;
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
DPRINT("Import module: %W\n", &ModuleName);
LibraryModuleObject = LdrLoadModule(&ModuleName);
if (LibraryModuleObject == 0)
{
DbgPrint("Unknown import module: %W\n", &ModuleName);
}
} }
/* Get the import address list */ /* Get the import address list */
ImportAddressList = (PVOID *) ((DWORD)DriverBase + ImportAddressList = (PVOID *) ((DWORD)DriverBase +
ImportModuleDirectory->dwRVAFunctionAddressList); ImportModuleDirectory->dwRVAFunctionAddressList);
@ -445,35 +656,38 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
FunctionNameList = (PULONG) ((DWORD)DriverBase + FunctionNameList = (PULONG) ((DWORD)DriverBase +
ImportModuleDirectory->dwRVAFunctionAddressList); ImportModuleDirectory->dwRVAFunctionAddressList);
} }
/* Walk through function list and fixup addresses */ /* Walk through function list and fixup addresses */
while(*FunctionNameList != 0L) while (*FunctionNameList != 0L)
{ {
if ((*FunctionNameList) & 0x80000000) // hint if ((*FunctionNameList) & 0x80000000) // hint
{ {
// DPRINT(" Hint: %08lx\n", *FunctionNameList); pName = NULL;
if (Library == NULL) Hint = (*FunctionNameList) & 0xffff;
{
DPRINT("Hints for kernel symbols are not handled.\n");
*ImportAddressList = 0;
}
} }
else // hint-name else // hint-name
{ {
pName = (PCHAR)((DWORD)DriverBase+ pName = (PCHAR)((DWORD)DriverBase +
*FunctionNameList + 2); *FunctionNameList + 2);
pHint = (PWORD)((DWORD)DriverBase + *FunctionNameList); Hint = *(PWORD)((DWORD)DriverBase + *FunctionNameList);
// DPRINT(" Hint:%04x Name:%s\n", pHint, pName); }
DPRINT(" Hint:%04x Name:%s\n", Hint, pName);
/* Fixup the current import symbol */
if (LibraryModuleObject != NULL)
{
*ImportAddressList = LdrGetExportAddress(LibraryModuleObject,
pName,
Hint);
}
else
{
/* Get address for symbol */ /* Get address for symbol */
if (Library == NULL) *SymbolNameBuf = '_';
strcpy(SymbolNameBuf + 1, pName);
*ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf);
if (*ImportAddressList == 0L)
{ {
*SymbolNameBuf = '_'; DbgPrint("Unresolved kernel symbol: %s\n", pName);
strcpy(SymbolNameBuf + 1, pName);
*ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf); if (*ImportAddressList == 0L)
{
DPRINT("Unresolved kernel symbol: %s\n", pName);
}
} }
} }
ImportAddressList++; ImportAddressList++;
@ -485,15 +699,165 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
ExFreePool(SymbolNameBuf); ExFreePool(SymbolNameBuf);
} }
/* Compute address of entry point */ /* Create ModuleName string */
EntryPoint = (PVOID) ((DWORD)DriverBase + PEOptionalHeader->AddressOfEntryPoint); wcscpy(NameBuffer, MODULE_ROOT_NAME);
DbgPrint("Calling entrypoint at %x\n",EntryPoint); if (PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
.VirtualAddress != 0)
{
ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) (DriverBase +
PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
.VirtualAddress);
wcscat(NameBuffer, DriverBase + ExportDirectory->Name);
}
else
{
char buf[12];
return IoInitializeDriver(EntryPoint); sprintf(buf, "%08X", (DWORD) DriverBase);
for (Idx = 0; NameBuffer[Idx] != 0; Idx++)
;
Idx2 = 0;
while ((NameBuffer[Idx + Idx2] = (WCHAR) buf[Idx2]) != 0)
Idx2++;
}
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
DPRINT("Module name is: %W\n", &ModuleName);
/* Initialize ObjectAttributes for ModuleObject */
InitializeObjectAttributes(&ObjectAttributes,
&ModuleName,
0,
NULL,
NULL);
/* Create module object */
ModuleHandle = 0;
ModuleObject = ObCreateObject(&ModuleHandle,
STANDARD_RIGHTS_REQUIRED,
&ObjectAttributes,
ObModuleType);
/* Initialize ModuleObject data */
ModuleObject->Base = DriverBase;
ModuleObject->Flags = MODULE_FLAG_PE;
ModuleObject->EntryPoint = (PVOID) ((DWORD)DriverBase +
PEOptionalHeader->AddressOfEntryPoint);
DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint);
ModuleObject->Image.PE.FileHeader =
(PIMAGE_FILE_HEADER) ((unsigned int) DriverBase +
PEDosHeader->e_lfanew + sizeof(ULONG));
DPRINT("FileHeader at %x\n", ModuleObject->Image.PE.FileHeader);
ModuleObject->Image.PE.OptionalHeader =
(PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase +
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
DPRINT("OptionalHeader at %x\n", ModuleObject->Image.PE.OptionalHeader);
ModuleObject->Image.PE.SectionList =
(PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase +
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) +
sizeof(IMAGE_OPTIONAL_HEADER));
DPRINT("SectionList at %x\n", ModuleObject->Image.PE.SectionList);
return ModuleObject;
} }
NTSTATUS static PVOID
LdrCOFFProcessDriver(PVOID ModuleLoadBase) LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
char *Name,
unsigned short Hint)
{
WORD Idx;
DWORD ExportsStartRVA, ExportsEndRVA, Delta;
PVOID ExportAddress;
PWORD OrdinalList;
PDWORD FunctionList, NameList;
PIMAGE_SECTION_HEADER SectionHeader;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
ExportsStartRVA = ModuleObject->Image.PE.OptionalHeader->DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
ExportsEndRVA = ExportsStartRVA +
ModuleObject->Image.PE.OptionalHeader->DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
/* Get the IMAGE_SECTION_HEADER that contains the exports. This is
usually the .edata section, but doesn't have to be. */
SectionHeader = LdrPEGetEnclosingSectionHeader(ExportsStartRVA, ModuleObject);
if (!SectionHeader)
{
return 0;
}
Delta = (DWORD)(SectionHeader->VirtualAddress -
SectionHeader->PointerToRawData);
ExportDirectory = MakePtr(PIMAGE_EXPORT_DIRECTORY,
ModuleObject->Base,
ExportsStartRVA - Delta);
FunctionList = (PDWORD)((DWORD)ExportDirectory->AddressOfFunctions -
Delta + ModuleObject->Base);
NameList = (PDWORD)((DWORD)ExportDirectory->AddressOfNames -
Delta + ModuleObject->Base);
OrdinalList = (PWORD)((DWORD)ExportDirectory->AddressOfNameOrdinals -
Delta + ModuleObject->Base);
DPRINT("Delta:%08x\n", Delta);
DPRINT("Func:%08x RVA:%08x Name:%08x RVA:%08x Ord:%08x RVA:%08x\n", FunctionList,
ExportDirectory->AddressOfFunctions, NameList,
ExportDirectory->AddressOfNames, OrdinalList,
ExportDirectory->AddressOfNameOrdinals);
DPRINT("NumNames:%d NumFuncs:%d\n", ExportDirectory->NumberOfNames,
ExportDirectory->NumberOfFunctions);
for(;;);
ExportAddress = 0;
if (Name != NULL)
{
for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++)
{
DPRINT(" Name:%s NameList[%d]:%s\n", Name, Idx, NameList[Idx]);
if (!strcmp(Name, (PCHAR) ((DWORD)ModuleObject->Base + NameList[Idx])))
{
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
FunctionList[OrdinalList[Idx]]);
break;
}
}
}
else /* use hint */
{
ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
FunctionList[Hint - ExportDirectory->Base]);
}
if (ExportAddress == 0)
{
DbgPrint("Export not found for %d:%s\n", Hint, Name != NULL ? Name : "(Ordinal)");
}
return ExportAddress;
}
static PIMAGE_SECTION_HEADER
LdrPEGetEnclosingSectionHeader(DWORD RVA,
PMODULE_OBJECT ModuleObject)
{
PIMAGE_SECTION_HEADER SectionHeader = SECHDROFFSET(ModuleObject->Base);
unsigned i;
for (i = 0; i < ModuleObject->Image.PE.FileHeader->NumberOfSections;
i++, SectionHeader++)
{
/* Is the RVA within this section? */
if ((RVA >= SectionHeader->VirtualAddress) &&
(RVA < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
{
return SectionHeader;
}
}
return 0;
}
/* ------------------------------------------- COFF Module support */
PMODULE_OBJECT
LdrCOFFProcessModule(PVOID ModuleLoadBase)
{ {
BOOLEAN FoundEntry; BOOLEAN FoundEntry;
char SymbolName[255]; char SymbolName[255];
@ -502,7 +866,12 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
FILHDR *FileHeader; FILHDR *FileHeader;
AOUTHDR *AOUTHeader; AOUTHDR *AOUTHeader;
module *Module; module *Module;
PDRIVER_INITIALIZE EntryRoutine; PVOID EntryRoutine;
HANDLE ModuleHandle;
PMODULE_OBJECT ModuleObject;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ModuleName;
WCHAR NameBuffer[60];
/* Get header pointers */ /* Get header pointers */
FileHeader = ModuleLoadBase; FileHeader = ModuleLoadBase;
@ -514,7 +883,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
{ {
DbgPrint("Module has bad magic value (%x)\n", DbgPrint("Module has bad magic value (%x)\n",
FileHeader->f_magic); FileHeader->f_magic);
return STATUS_UNSUCCESSFUL; return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -522,7 +891,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
Module = (module *) ExAllocatePool(NonPagedPool, sizeof(module)); Module = (module *) ExAllocatePool(NonPagedPool, sizeof(module));
if (Module == NULL) if (Module == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return 0;
} }
Module->sym_list = (SYMENT *)(ModuleLoadBase + FileHeader->f_symptr); Module->sym_list = (SYMENT *)(ModuleLoadBase + FileHeader->f_symptr);
Module->str_tab = (char *)(ModuleLoadBase + FileHeader->f_symptr + Module->str_tab = (char *)(ModuleLoadBase + FileHeader->f_symptr +
@ -569,7 +938,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
{ {
DbgPrint("Failed to alloc section for module\n"); DbgPrint("Failed to alloc section for module\n");
ExFreePool(Module); ExFreePool(Module);
return STATUS_INSUFFICIENT_RESOURCES; return 0;
} }
CHECKPOINT; CHECKPOINT;
@ -589,14 +958,14 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
Module->scn_list[i].s_size); Module->scn_list[i].s_size);
if (!LdrCOFFDoRelocations(Module, i)) if (!LdrCOFFDoRelocations(Module, i))
{ {
DPRINT("Relocation failed for section %s\n", DbgPrint("Relocation failed for section %s\n",
Module->scn_list[i].s_name); Module->scn_list[i].s_name);
/* FIXME: unallocate all sections here */ /* FIXME: unallocate all sections here */
ExFreePool(Module); ExFreePool(Module);
return STATUS_UNSUCCESSFUL; return 0;
} }
} }
if (Module->scn_list[i].s_flags & STYP_BSS) if (Module->scn_list[i].s_flags & STYP_BSS)
@ -607,7 +976,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
} }
} }
DbgPrint("Module base: %x\n", Module->base); DPRINT("Module base: %x\n", Module->base);
/* Find the entry point */ /* Find the entry point */
EntryOffset = 0L; EntryOffset = 0L;
@ -629,16 +998,46 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
/* FIXME: unallocate all sections here */ /* FIXME: unallocate all sections here */
return STATUS_UNSUCCESSFUL; return 0;
} }
/* Get the address of the module initalization routine */ /* Get the address of the module initalization routine */
EntryRoutine = (PDRIVER_INITIALIZE)(Module->base + EntryOffset); EntryRoutine = (PVOID)(Module->base + EntryOffset);
/* Create ModuleName string */
wcscpy(NameBuffer, MODULE_ROOT_NAME);
/* FIXME: someone who is interested needs to fix this. */
wcscat(NameBuffer, L"BOGUS.o");
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer;
DPRINT("Module name is: %w", NameBuffer);
/* Initialize ObjectAttributes for ModuleObject */
InitializeObjectAttributes(&ObjectAttributes,
&ModuleName,
0,
NULL,
NULL);
/* Create module object */
ModuleHandle = 0;
ModuleObject = ObCreateObject(&ModuleHandle,
OBJECT_TYPE_ALL_ACCESS,
&ObjectAttributes,
ObModuleType);
/* Initialize ModuleObject data */
ModuleObject->Base = (PVOID) Module->base;
ModuleObject->Flags = MODULE_FLAG_COFF;
ModuleObject->EntryPoint = (PVOID) (Module->base + EntryOffset);
DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint);
/* FIXME: the COFF headers need to be copied into the module
space, and the ModuleObject needs to be set to point to them */
/* Cleanup */ /* Cleanup */
ExFreePool(Module); ExFreePool(Module);
return IoInitializeDriver(EntryRoutine); return ModuleObject;
} }
/* LdrCOFFDoRelocations /* LdrCOFFDoRelocations
@ -684,7 +1083,7 @@ LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex)
break; break;
default: default:
DPRINT("%.8s: Unknown relocation type %x at %d in module\n", DbgPrint("%.8s: Unknown relocation type %x at %d in module\n",
Module->scn_list[SectionIndex].s_name, Module->scn_list[SectionIndex].s_name,
Relocation->r_type, Relocation->r_type,
j); j);
@ -846,7 +1245,7 @@ LdrGetKernelSymbolAddr(char *Name)
if ((s=strchr(Name,'@'))!=NULL) if ((s=strchr(Name,'@'))!=NULL)
{ {
*s=0; *s=0;
DbgPrint("Name %s ",Name); DPRINT("Name %s ",Name);
} }
while (symbol_table[i].name != NULL) while (symbol_table[i].name != NULL)
{ {
@ -855,7 +1254,7 @@ LdrGetKernelSymbolAddr(char *Name)
if (s!=NULL) if (s!=NULL)
{ {
*s=0; *s=0;
DbgPrint("Matched with %s\n",symbol_table[i].name); DPRINT("Matched with %s\n",symbol_table[i].name);
} }
return symbol_table[i].value; return symbol_table[i].value;
} }

View file

@ -133,17 +133,19 @@ else
endif endif
$(CC) $(CFLAGS) -c ke/exports.c -o ke/exports.o $(CC) $(CFLAGS) -c ke/exports.c -o ke/exports.o
ntoskrnl.exe: $(OBJECTS) ntoskrnl.def all: ntoskrnl.a ntoskrnl.exe ntoskrnl.sym
$(LD) -r $(OBJECTS) -o ntoskrnl.o
$(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \ .PHONY: all
--output-lib ntoskrnl.a
ntoskrnl.exe: ntoskrnl.o ntoskrnl.def
$(CC) -specs=../specs -mdll -o junk.tmp \ $(CC) -specs=../specs -mdll -o junk.tmp \
-Wl,--image-base,0xc0000000 \ -Wl,--image-base,0xc0000000 \
-Wl,--file-alignment,0x1000 \ -Wl,--file-alignment,0x1000 \
-Wl,--section-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \
-Wl,--defsym,_end=end \ -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \ -Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp ntoskrnl.o -Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp \
ntoskrnl.o
- $(RM) junk.tmp - $(RM) junk.tmp
$(DLLTOOL) --dllname ntoskrnl.exe --base-file base.tmp \ $(DLLTOOL) --dllname ntoskrnl.exe --base-file base.tmp \
--output-exp temp.exp --def ntoskrnl.def --output-exp temp.exp --def ntoskrnl.def
@ -158,6 +160,13 @@ ntoskrnl.exe: $(OBJECTS) ntoskrnl.def
- $(RM) temp.exp - $(RM) temp.exp
$(NM) --numeric-sort ntoskrnl.exe > ntoskrnl.sym $(NM) --numeric-sort ntoskrnl.exe > ntoskrnl.sym
ntoskrnl.o: $(OBJECTS)
$(LD) -r $(OBJECTS) -o ntoskrnl.o
ntoskrnl.a: ntoskrnl.def
$(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \
--output-lib ntoskrnl.a
clean: $(CLEAN_FILES:%=%_clean) clean: $(CLEAN_FILES:%=%_clean)
$(CLEAN_FILES:%=%_clean): %_clean: $(CLEAN_FILES:%=%_clean): %_clean:

View file

@ -137,7 +137,12 @@ wcsncat(wchar_t *dest, const wchar_t *src, size_t count)
int int
wcsncmp(const wchar_t *cs, const wchar_t *ct, size_t count) wcsncmp(const wchar_t *cs, const wchar_t *ct, size_t count)
{ {
UNIMPLEMENTED; while (*cs != '\0' && *ct != '\0' && *cs == *ct && --count)
{
cs++;
ct++;
}
return *cs - *ct;
} }

View file

@ -0,0 +1,2 @@
win32k.coff
win32k.sys