diff --git a/reactos/drivers/fs/ext2/makefile b/reactos/drivers/fs/ext2/makefile index a6019785da6..e4ca51b50a2 100644 --- a/reactos/drivers/fs/ext2/makefile +++ b/reactos/drivers/fs/ext2/makefile @@ -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 + diff --git a/reactos/include/pe.h b/reactos/include/pe.h index 18067ab89d5..e312581e1ed 100644 --- a/reactos/include/pe.h +++ b/reactos/include/pe.h @@ -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 // diff --git a/reactos/loaders/boot/boot.map b/reactos/loaders/boot/boot.map deleted file mode 100644 index 743747fb55c..00000000000 --- a/reactos/loaders/boot/boot.map +++ /dev/null @@ -1,8 +0,0 @@ - - Start Stop Length Name Class - - 00000H 001FFH 00200H TEXT TEXT - -Program entry point at 0000:0000 -Warning: No stack - diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 6437d7bda36..24c0753b00a 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -25,23 +25,24 @@ #include -#define NDEBUG +//#define NDEBUG #include /* 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; } diff --git a/reactos/ntoskrnl/tst/test.c b/reactos/ntoskrnl/tst/test.c index 481daac4e9d..50bfdd4cbbe 100644 --- a/reactos/ntoskrnl/tst/test.c +++ b/reactos/ntoskrnl/tst/test.c @@ -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()