mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
more work on loader
svn path=/trunk/; revision=157
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(LD) -r $(OBJECTS) -o ext2fs.sys
|
||||
OBJECTS = super.o blockdev.o inode.o file.o dir.o rw.o
|
||||
|
||||
all: ext2.o
|
||||
|
||||
ext2.o: $(OBJECTS)
|
||||
$(LD) -r $(OBJECTS) -o ext2fs.sys
|
||||
|
||||
include ../../../rules.mak
|
||||
|
||||
|
||||
+19
-10
@@ -1,4 +1,6 @@
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
|
||||
#ifndef PWORD
|
||||
typedef WORD *PWORD;
|
||||
#endif
|
||||
@@ -7,7 +9,7 @@ typedef WORD *PWORD;
|
||||
typedef DWORD *PDWORD;
|
||||
#endif
|
||||
|
||||
#define IMAGE_DOS_MAGIC 0x54ad
|
||||
#define IMAGE_DOS_MAGIC 0x5a4d
|
||||
#define IMAGE_PE_MAGIC 0x00004550
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||
@@ -66,7 +68,6 @@ typedef struct _IMAGE_FILE_HEADER {
|
||||
#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
|
||||
|
||||
|
||||
//
|
||||
// Directory format.
|
||||
//
|
||||
@@ -125,14 +126,6 @@ typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
|
||||
|
||||
|
||||
typedef struct _IMAGE_NT_HEADERS {
|
||||
DWORD Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
|
||||
|
||||
|
||||
// Directory Entries
|
||||
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
|
||||
@@ -149,6 +142,12 @@ typedef struct _IMAGE_NT_HEADERS {
|
||||
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
|
||||
#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
|
||||
|
||||
typedef struct _IMAGE_NT_HEADERS {
|
||||
DWORD Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
|
||||
|
||||
//
|
||||
// Section header format.
|
||||
//
|
||||
@@ -174,6 +173,16 @@ typedef struct _IMAGE_SECTION_HEADER {
|
||||
#define IMAGE_SIZEOF_SECTION_HEADER 40
|
||||
|
||||
|
||||
#define IMAGE_SECTION_CHAR_CODE 0x00000020
|
||||
#define IMAGE_SECTION_CHAR_DATA 0x00000040
|
||||
#define IMAGE_SECTION_CHAR_BSS 0x00000080
|
||||
#define IMAGE_SECTION_CHAR_NON_CACHABLE 0x04000000
|
||||
#define IMAGE_SECTION_CHAR_NON_PAGEABLE 0x08000000
|
||||
#define IMAGE_SECTION_CHAR_SHARED 0x10000000
|
||||
#define IMAGE_SECTION_CHAR_EXECUTABLE 0x20000000
|
||||
#define IMAGE_SECTION_CHAR_READABLE 0x40000000
|
||||
#define IMAGE_SECTION_CHAR_WRITABLE 0x80000000
|
||||
|
||||
//
|
||||
// Export Format
|
||||
//
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
Start Stop Length Name Class
|
||||
|
||||
00000H 001FFH 00200H TEXT TEXT
|
||||
|
||||
Program entry point at 0000:0000
|
||||
Warning: No stack
|
||||
|
||||
+136
-70
@@ -25,23 +25,24 @@
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* MACROS ********************************************************************/
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
POBJECT_TYPE ObModuleType = NULL;
|
||||
|
||||
/* FORWARD DECLARATIONS ******************************************************/
|
||||
|
||||
NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
|
||||
NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
|
||||
NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase);
|
||||
|
||||
/* PE Driver load support */
|
||||
static NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
|
||||
|
||||
/* COFF Driver load support */
|
||||
static NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
|
||||
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
|
||||
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
||||
static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
||||
@@ -95,7 +96,6 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
|
||||
DbgPrint("Loading Driver %W...\n", Filename);
|
||||
@@ -132,7 +132,7 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||
|
||||
/* Allocate nonpageable memory for driver */
|
||||
ModuleLoadBase = ExAllocatePool(NonPagedPool,
|
||||
GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize));
|
||||
GET_LARGE_INTEGER_LOW_PART(FileStdInfo.EndOfFile));
|
||||
if (ModuleLoadBase == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
@@ -143,7 +143,7 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||
Status = ZwReadFile(FileHandle,
|
||||
0, 0, 0, 0,
|
||||
ModuleLoadBase,
|
||||
GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize),
|
||||
GET_LARGE_INTEGER_LOW_PART(FileStdInfo.EndOfFile),
|
||||
0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
@@ -154,31 +154,7 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||
|
||||
ZwClose(FileHandle);
|
||||
|
||||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC && PEDosHeader->e_lfanew != 0L)
|
||||
{
|
||||
Status = LdrPEProcessDriver(ModuleLoadBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ModuleLoadBase);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC)
|
||||
{
|
||||
ExFreePool(ModuleLoadBase);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else /* Assume COFF format and load */
|
||||
{
|
||||
Status = LdrCOFFProcessDriver(ModuleLoadBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ModuleLoadBase);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
Status = LdrProcessDriver(ModuleLoadBase);
|
||||
|
||||
/* Cleanup */
|
||||
ExFreePool(ModuleLoadBase);
|
||||
@@ -186,15 +162,40 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
LdrProcessDriver(PVOID ModuleLoadBase)
|
||||
{
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
|
||||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC && PEDosHeader->e_lfanew != 0L)
|
||||
{
|
||||
return LdrPEProcessDriver(ModuleLoadBase);
|
||||
}
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
else /* Assume COFF format and load */
|
||||
{
|
||||
return LdrCOFFProcessDriver(ModuleLoadBase);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||
{
|
||||
unsigned int DriverSize;
|
||||
PVOID DriverBase, CodeBase, InitializedDataBase, UninitializedDataBase;
|
||||
unsigned int DriverSize, Idx;
|
||||
long int RelocDelta, NumRelocs;
|
||||
PVOID DriverBase, RelocBase;
|
||||
PULONG PEMagic;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
PIMAGE_FILE_HEADER PEFileHeader;
|
||||
PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
|
||||
PIMAGE_SECTION_HEADER PESectionHeaders;
|
||||
PRELOCATION_DIRECTORY RelocDir;
|
||||
PRELOCATION_ENTRY RelocEntry;
|
||||
|
||||
DPRINT("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
|
||||
|
||||
@@ -206,19 +207,34 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||
PEDosHeader->e_lfanew + sizeof(ULONG));
|
||||
PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) ModuleLoadBase +
|
||||
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
|
||||
PESectionHeaders = (PIMAGE_SECTION_HEADER) ((unsigned int) ModuleLoadBase +
|
||||
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) +
|
||||
sizeof(IMAGE_OPTIONAL_HEADER));
|
||||
CHECKPOINT;
|
||||
|
||||
/* Check file magic numbers */
|
||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
||||
PEDosHeader->e_lfanew == 0 ||
|
||||
*PEMagic != IMAGE_PE_MAGIC ||
|
||||
PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
|
||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC)
|
||||
{
|
||||
DPRINT("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (PEDosHeader->e_lfanew == 0)
|
||||
{
|
||||
DPRINT("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (*PEMagic != IMAGE_PE_MAGIC)
|
||||
{
|
||||
DPRINT("Incorrect PE magic: %08x\n", *PEMagic);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
if (PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
|
||||
{
|
||||
DPRINT("Incorrect Architechture: %04x\n", PEFileHeader->Machine);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
#if 0
|
||||
/* FIXME: if image is fixed-address load, then fail */
|
||||
|
||||
/* FIXME: check/verify OS version number */
|
||||
@@ -227,25 +243,30 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||
PEOptionalHeader->Magic,
|
||||
PEOptionalHeader->MajorLinkerVersion,
|
||||
PEOptionalHeader->MinorLinkerVersion);
|
||||
DPRINT("Size: CODE:%08lx(%d) DATA:%08lx(%d) BSS:%08lx(%d)\n",
|
||||
PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SizeOfUninitializedData,
|
||||
PEOptionalHeader->SizeOfUninitializedData);
|
||||
DPRINT("Entry Point:%08lx\n", PEOptionalHeader->AddressOfEntryPoint);
|
||||
CHECKPOINT;
|
||||
|
||||
/* Determine the size of the module */
|
||||
DriverSize = ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SectionAlignment) +
|
||||
ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SectionAlignment) +
|
||||
ROUND_UP(PEOptionalHeader->SizeOfUninitializedData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
CHECKPOINT;
|
||||
|
||||
DPRINT("Sections: (section align:%08lx)\n",
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
DriverSize = 0;
|
||||
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
|
||||
{
|
||||
DPRINT("Name: %-8.8s VA:%08lx RawSize:%6d Offset:%08lx CHAR:%08lx OfsAdr: %08lx\n",
|
||||
PESectionHeaders[Idx].Name,
|
||||
PESectionHeaders[Idx].VirtualAddress,
|
||||
PESectionHeaders[Idx].SizeOfRawData,
|
||||
PESectionHeaders[Idx].PointerToRawData,
|
||||
PESectionHeaders[Idx].Characteristics,
|
||||
DriverSize);
|
||||
DriverSize += ROUND_UP(PESectionHeaders[Idx].SizeOfRawData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
}
|
||||
DPRINT("DriverSize computed by using section headers: %d(%08lx)\n",
|
||||
DriverSize,
|
||||
DriverSize);
|
||||
|
||||
#if 0
|
||||
/* Allocate a virtual section for the module */
|
||||
DriverBase = MmAllocateSection(DriverSize);
|
||||
if (DriverBase == 0)
|
||||
@@ -255,26 +276,71 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/* Compute addresses for driver sections */
|
||||
CodeBase = DriverBase;
|
||||
InitializedDataBase = (PUCHAR) DriverBase +
|
||||
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
UninitializedDataBase = (PUCHAR) InitializedDataBase +
|
||||
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
CurrentBase = ModuleLoadBase;
|
||||
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
|
||||
{
|
||||
/* Copy current section into current offset of virtual section */
|
||||
if (PESectionHeaders[Idx].Characteristics &
|
||||
(IMAGE_SECTION_CHAR_CODE | IMAGE_SECTION_CHAR_DATA))
|
||||
{
|
||||
memcpy(CurrentBase,
|
||||
(PVOID)(ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData),
|
||||
PESectionHeaders[Idx].SizeOfRawData);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(CurrentBase, '\0', PESectionHeaders[Idx].SizeOfRawData);
|
||||
}
|
||||
CurrentSize += ROUND_UP(PESectionHeaders[Idx].SizeOfRawData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
}
|
||||
|
||||
/* FIXME: Copy code section into virtual section */
|
||||
memcpy(CodeBase,
|
||||
(PVOID)(ModuleLoadBase + ???),
|
||||
ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->FileAlignment));
|
||||
#else
|
||||
DriverBase = ModuleLoadBase;
|
||||
#endif
|
||||
|
||||
/* FIXME: Copy initialized data section into virtual section */
|
||||
/* FIXME: Perform relocations fixups */
|
||||
/* FIXME: 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,
|
||||
RelocDelta);
|
||||
while (RelocDir->SizeOfBlock != 0)
|
||||
{
|
||||
NumRelocs = (RelocDir->SizeOfBlock - sizeof(RELOCATION_DIRECTORY)) /
|
||||
sizeof(WORD);
|
||||
DPRINT("RelocDir at %08lx for VA %08lx with %08lx relocs\n",
|
||||
RelocDir,
|
||||
RelocDir->VirtualAddress,
|
||||
NumRelocs);
|
||||
RelocEntry = (PRELOCATION_ENTRY) ((DWORD)RelocDir +
|
||||
sizeof(RELOCATION_DIRECTORY));
|
||||
for (Idx = 0; Idx < NumRelocs; Idx++)
|
||||
{
|
||||
DPRINT(" reloc at %08lx %x %s old:%08lx new:%08lx\n",
|
||||
DriverBase + RelocDir->VirtualAddress +
|
||||
(RelocEntry[Idx].TypeOffset & 0x0fff),
|
||||
(RelocEntry[Idx].TypeOffset >> 12) & 0xf,
|
||||
(RelocEntry[Idx].TypeOffset >> 12) & 0xf ? "HIGHLOW" : "ABS",
|
||||
*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress +
|
||||
(RelocEntry[Idx].TypeOffset & 0x0fff)),
|
||||
(*(PDWORD)((DWORD) DriverBase + RelocDir->VirtualAddress +
|
||||
(RelocEntry[Idx].TypeOffset & 0x0fff))) + RelocDelta);
|
||||
}
|
||||
RelocDir = (PRELOCATION_DIRECTORY)((DWORD)RelocDir +
|
||||
RelocDir->SizeOfBlock);
|
||||
getchar();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* FIXME: perform import fixups */
|
||||
/* FIXME: compute address of entry point */
|
||||
|
||||
#endif
|
||||
|
||||
/* return InitializeLoadedDriver(EntryPoint); */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@@ -544,6 +544,15 @@ void TstDriverLoad(void)
|
||||
DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
|
||||
DbgPrintErrorMessage(Status);
|
||||
}
|
||||
RtlInitAnsiString(&AnsiDriverName,"\\??\\C:\\reactos\\system\\beep.sys");
|
||||
RtlAnsiStringToUnicodeString(&DriverName, &AnsiDriverName, TRUE);
|
||||
Status = LdrLoadDriver(&DriverName);
|
||||
RtlFreeUnicodeString(&DriverName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
|
||||
DbgPrintErrorMessage(Status);
|
||||
}
|
||||
}
|
||||
|
||||
void TstBegin()
|
||||
|
||||
Reference in New Issue
Block a user