Author: hbelusca Date: Fri Feb 5 00:17:33 2016 New Revision: 70692
URL: http://svn.reactos.org/svn/reactos?rev=70692&view=rev Log: [FREELDR] Start splitting FreeLdr in the same spirit as our new UEFI boot manager/loader: split into a boot library, the boot manager code, and the NT loader. - The boot library provides the basic support (read INI/INF files, memory management, debugging, ARC compatibility/emulation, ...). - The boot manager code is FreeLdr proper. - The NT loader is used for loading Windows or ReactOS. Because of that fact I rename its directory "windows" into "NTLDR" to underline the fact it can load NT-type OSes (more exactly version 5.x), to which both Windows 2k/XP/2k3 and ReactOS belong. The APIs will certainly be renamed "NtLdrXXX" instead of "WinLdrXXX". - The general PE loader is put into the boot library since it is needed also by FreeLdr proper to be able to load SCSI drivers (on x86/64/... architectures; on ARC systems SCSI support is automatically provided).
Added: trunk/reactos/boot/freeldr/freeldr/arch/i386/halstub.c - copied, changed from r70690, trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/halstub.c trunk/reactos/boot/freeldr/freeldr/arch/i386/ntoskrnl.c - copied, changed from r70690, trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/ntoskrnl.c trunk/reactos/boot/freeldr/freeldr/include/conversion.h (with props) trunk/reactos/boot/freeldr/freeldr/include/ntoskrnl.h - copied unchanged from r70690, trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/ntoskrnl.h trunk/reactos/boot/freeldr/freeldr/lib/comm/ - copied from r70691, trunk/reactos/boot/freeldr/freeldr/comm/ trunk/reactos/boot/freeldr/freeldr/lib/debug.c - copied unchanged from r70691, trunk/reactos/boot/freeldr/freeldr/debug.c trunk/reactos/boot/freeldr/freeldr/lib/fs/ - copied from r70691, trunk/reactos/boot/freeldr/freeldr/fs/ trunk/reactos/boot/freeldr/freeldr/lib/mm/ - copied from r70691, trunk/reactos/boot/freeldr/freeldr/mm/ trunk/reactos/boot/freeldr/freeldr/lib/peloader.c - copied, changed from r70690, trunk/reactos/boot/freeldr/freeldr/windows/peloader.c trunk/reactos/boot/freeldr/freeldr/ntldr/ - copied from r70691, trunk/reactos/boot/freeldr/freeldr/windows/ Removed: trunk/reactos/boot/freeldr/freeldr/comm/ trunk/reactos/boot/freeldr/freeldr/debug.c trunk/reactos/boot/freeldr/freeldr/fs/ trunk/reactos/boot/freeldr/freeldr/mm/ trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/halstub.c trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.c trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.h trunk/reactos/boot/freeldr/freeldr/ntldr/peloader.c trunk/reactos/boot/freeldr/freeldr/windows/ Modified: trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt trunk/reactos/boot/freeldr/freeldr/include/freeldr.h trunk/reactos/boot/freeldr/freeldr/ntldr/conversion.c
Modified: trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/CMakeL... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -32,37 +32,55 @@
add_definitions(-D_NTHAL_ -D_BLDR_ -D_NTSYSTEM_)
-list(APPEND FREELDR_COMMON_SOURCE - include/freeldr.h + +list(APPEND FREELDR_BOOTLIB_COMMON_SOURCE + lib/debug.c + lib/peloader.c + + lib/comm/rs232.c + ## add KD support + lib/fs/ext2.c + lib/fs/fat.c + lib/fs/fs.c + lib/fs/iso.c + lib/fs/ntfs.c + lib/inifile/ini_init.c + lib/inifile/inifile.c + lib/inifile/parse.c + lib/mm/meminit.c + lib/mm/mm.c + lib/mm/heap.c + ) + +list(APPEND FREELDR_NTLDR_COMMON_SOURCE + ntldr/conversion.c + ntldr/registry.c + ntldr/winldr.c + ntldr/wlmemory.c + ntldr/wlregistry.c + ) + +list(APPEND FREELDR_ARC_COMMON_SOURCE arcname.c - cmdline.c - custom.c - debug.c - linuxboot.c - miscboot.c machine.c - options.c - oslist.c - version.c arch/archwsup.c cache/blocklist.c cache/cache.c - comm/rs232.c disk/disk.c disk/partition.c disk/ramdisk.c #disk/scsiport.c - fs/ext2.c - fs/fat.c - fs/fs.c - fs/iso.c - fs/ntfs.c - lib/inifile/ini_init.c - lib/inifile/inifile.c - lib/inifile/parse.c - mm/meminit.c - mm/mm.c - mm/heap.c + ) + +list(APPEND FREELDR_COMMON_SOURCE + include/freeldr.h + cmdline.c + custom.c + linuxboot.c + miscboot.c + options.c + oslist.c + version.c ui/directui.c ui/gui.c ui/minitui.c @@ -73,12 +91,7 @@ video/fade.c video/palette.c video/video.c - windows/conversion.c - windows/peloader.c - windows/registry.c - windows/winldr.c - windows/wlmemory.c - windows/wlregistry.c) + )
if(ARCH STREQUAL "i386") list(APPEND FREELDR_COMMON_ASM_SOURCE @@ -86,9 +99,21 @@ arch/i386/i386pnp.S arch/i386/i386trap.S arch/i386/linux.S - arch/i386/mb.S) - list(APPEND FREELDR_COMMON_SOURCE - fs/pxe.c + arch/i386/mb.S + ) + + list(APPEND FREELDR_NTLDR_COMMON_SOURCE + ntldr/arch/i386/winldr.c + ntldr/headless.c + ) + + ## list(APPEND FREELDR_COMMON_SOURCE + list(APPEND FREELDR_ARC_COMMON_SOURCE + lib/fs/pxe.c + + arch/i386/halstub.c + arch/i386/ntoskrnl.c + arch/i386/archmach.c arch/i386/drivemap.c arch/i386/hardware.c @@ -116,10 +141,6 @@ arch/i386/xboxmem.c arch/i386/xboxrtc.c arch/i386/xboxvideo.c - windows/arch/i386/halstub.c - windows/arch/i386/ntoskrnl.c - windows/arch/i386/winldr.c - windows/headless.c disk/scsiport.c) if(NOT MSVC) list(APPEND FREELDR_COMMON_ASM_SOURCE arch/i386/drvmap.S) @@ -129,8 +150,17 @@ arch/amd64/entry.S arch/amd64/int386.S arch/amd64/pnpbios.S) - list(APPEND FREELDR_COMMON_SOURCE - fs/pxe.c + + list(APPEND FREELDR_NTLDR_COMMON_SOURCE + ntldr/arch/amd64/winldr.c + ) + + ## list(APPEND FREELDR_COMMON_SOURCE + list(APPEND FREELDR_ARC_COMMON_SOURCE + lib/fs/pxe.c + + arch/i386/ntoskrnl.c + arch/i386/drivemap.c arch/i386/hardware.c arch/i386/hwacpi.c @@ -146,22 +176,27 @@ arch/i386/pcdisk.c arch/i386/pcmem.c arch/i386/pcrtc.c - arch/i386/pcvideo.c - windows/arch/i386/ntoskrnl.c - windows/arch/amd64/winldr.c) + arch/i386/pcvideo.c) elseif(ARCH STREQUAL "arm") list(APPEND FREELDR_COMMON_ASM_SOURCE arch/arm/boot.S) - list(APPEND FREELDR_COMMON_SOURCE + + list(APPEND FREELDR_NTLDR_COMMON_SOURCE + ntldr/arch/arm/winldr.c + ) + + ## list(APPEND FREELDR_COMMON_SOURCE + list(APPEND FREELDR_ARC_COMMON_SOURCE arch/arm/entry.c - arch/arm/macharm.c - windows/arch/arm/winldr.c) + arch/arm/macharm.c) else() #TBD endif()
add_asm_files(freeldr_common_asm ${FREELDR_COMMON_ASM_SOURCE}) -add_library(freeldr_common ${FREELDR_COMMON_SOURCE} ${freeldr_common_asm}) +add_library(freeldr_common ${FREELDR_BOOTLIB_COMMON_SOURCE} ${FREELDR_ARC_COMMON_SOURCE} + ${FREELDR_NTLDR_COMMON_SOURCE} + ${FREELDR_COMMON_SOURCE} ${freeldr_common_asm}) add_pch(freeldr_common include/freeldr.h FREELDR_COMMON_SOURCE) add_dependencies(freeldr_common bugcodes asm xdk)
@@ -173,7 +208,10 @@ list(APPEND FREELDR_BASE_SOURCE bootmgr.c # This file is compiled with custom definitions freeldr.c - windows/setupldr.c + ntldr/setupldr.c ## Strangely enough this file is needed in GCC builds + ## even if ${FREELDR_NTLDR_COMMON_SOURCE} is not added, + ## otherwise we get linking errors with Rtl**Bitmap** APIs. + ## Do not happen on MSVC builds however... lib/inffile/inffile.c lib/rtl/libsupp.c)
Copied: trunk/reactos/boot/freeldr/freeldr/arch/i386/halstub.c (from r70690, trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/halstub.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/halstub.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/halstub.c [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -8,7 +8,7 @@
/* INCLUDES ******************************************************************/
-#include "ntoskrnl.h" +#include <ntoskrnl.h> #define NDEBUG #include <debug.h>
Copied: trunk/reactos/boot/freeldr/freeldr/arch/i386/ntoskrnl.c (from r70690, trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/ntoskrnl.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/arch/i386/ntoskrnl.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/arch/i386/ntoskrnl.c [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -8,7 +8,7 @@
/* INCLUDES ******************************************************************/
-#include "ntoskrnl.h" +#include <ntoskrnl.h>
/* For KeStallExecutionProcessor */ #if defined(_M_IX86) || defined(_M_AMD64)
Removed: trunk/reactos/boot/freeldr/freeldr/debug.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/debug.... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/debug.c (removed) @@ -1,540 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer brianp@sginet.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <freeldr.h> -#include <debug.h> - -#if DBG && !defined(_M_ARM) - -// #define DEBUG_ALL -// #define DEBUG_WARN -// #define DEBUG_ERR -// #define DEBUG_INIFILE -// #define DEBUG_REACTOS -// #define DEBUG_CUSTOM -#define DEBUG_NONE - -#define DBG_DEFAULT_LEVELS (ERR_LEVEL|FIXME_LEVEL) - -static UCHAR DbgChannels[DBG_CHANNELS_COUNT]; - -#define SCREEN 1 -#define RS232 2 -#define BOCHS 4 - -#define BOCHS_OUTPUT_PORT 0xE9 - -ULONG DebugPort = RS232; - -/* Serial debug connection */ -ULONG ComPort = 0; // The COM port initializer chooses the first available port starting from COM4 down to COM1. -ULONG BaudRate = 115200; -ULONG PortIrq = 0; // Not used at the moment. - -BOOLEAN DebugStartOfLine = TRUE; - -VOID DebugInit(BOOLEAN MainInit) -{ - PCHAR CommandLine, PortString, BaudString, IrqString; - ULONG Value; - CHAR DebugString[256]; - - /* Always reset the debugging channels */ - -#if defined (DEBUG_ALL) - memset(DbgChannels, MAX_LEVEL, DBG_CHANNELS_COUNT); -#elif defined (DEBUG_WARN) - memset(DbgChannels, WARN_LEVEL|FIXME_LEVEL|ERR_LEVEL, DBG_CHANNELS_COUNT); -#elif defined (DEBUG_ERR) - memset(DbgChannels, ERR_LEVEL, DBG_CHANNELS_COUNT); -#else - memset(DbgChannels, 0, DBG_CHANNELS_COUNT); -#endif - -#if defined (DEBUG_INIFILE) - DbgChannels[DPRINT_INIFILE] = MAX_LEVEL; -#elif defined (DEBUG_REACTOS) - DbgChannels[DPRINT_REACTOS] = MAX_LEVEL; - DbgChannels[DPRINT_REGISTRY] = MAX_LEVEL; -#elif defined (DEBUG_CUSTOM) - DbgChannels[DPRINT_WARNING] = MAX_LEVEL; - DbgChannels[DPRINT_WINDOWS] = MAX_LEVEL; -#endif - - /* Check for pre- or main initialization phase */ - if (!MainInit) - { - /* Pre-initialization phase: use the FreeLdr command-line debugging string */ - CommandLine = (PCHAR)CmdLineGetDebugString(); - - /* If no command-line is provided, initialize the debug port with default settings */ - if (CommandLine == NULL) - goto Done; - - strcpy(DebugString, CommandLine); - } - else - { - /* Main initialization phase: use the FreeLdr INI debugging string */ - - ULONG_PTR SectionId; - - if (!IniOpenSection("FreeLoader", &SectionId)) - return; - - if (!IniReadSettingByName(SectionId, "Debug", DebugString, sizeof(DebugString))) - return; - } - - /* Get the Command Line */ - CommandLine = DebugString; - - /* Upcase it */ - _strupr(CommandLine); - - /* Get the port and baud rate */ - PortString = strstr(CommandLine, "DEBUGPORT"); - BaudString = strstr(CommandLine, "BAUDRATE"); - IrqString = strstr(CommandLine, "IRQ"); - - /* - * Check if we got /DEBUGPORT parameters. - * NOTE: Inspired by reactos/ntoskrnl/kd/kdinit.c, KdInitSystem(...) - */ - while (PortString) - { - /* Move past the actual string, to reach the port*/ - PortString += strlen("DEBUGPORT"); - - /* Now get past any spaces and skip the equal sign */ - while (*PortString == ' ') PortString++; - PortString++; - - /* Check for possible ports and set the port to use */ - if (strncmp(PortString, "SCREEN", 6) == 0) - { - PortString += 6; - DebugPort |= SCREEN; - } - else if (strncmp(PortString, "BOCHS", 5) == 0) - { - PortString += 5; - DebugPort |= BOCHS; - } - else if (strncmp(PortString, "COM", 3) == 0) - { - PortString += 3; - DebugPort |= RS232; - - /* Set the port to use */ - Value = atol(PortString); - if (Value) ComPort = Value; - } - - PortString = strstr(PortString, "DEBUGPORT"); - } - - /* Check if we got a baud rate */ - if (BaudString) - { - /* Move past the actual string, to reach the rate */ - BaudString += strlen("BAUDRATE"); - - /* Now get past any spaces */ - while (*BaudString == ' ') BaudString++; - - /* And make sure we have a rate */ - if (*BaudString) - { - /* Read and set it */ - Value = atol(BaudString + 1); - if (Value) BaudRate = Value; - } - } - - /* Check Serial Port Settings [IRQ] */ - if (IrqString) - { - /* Move past the actual string, to reach the rate */ - IrqString += strlen("IRQ"); - - /* Now get past any spaces */ - while (*IrqString == ' ') IrqString++; - - /* And make sure we have an IRQ */ - if (*IrqString) - { - /* Read and set it */ - Value = atol(IrqString + 1); - if (Value) PortIrq = Value; - } - } - -Done: - /* Try to initialize the port; if it fails, remove the corresponding flag */ - if (DebugPort & RS232) - { - if (!Rs232PortInitialize(ComPort, BaudRate)) - DebugPort &= ~RS232; - } -} - -VOID DebugPrintChar(UCHAR Character) -{ - if (Character == '\n') - DebugStartOfLine = TRUE; - - if (DebugPort & RS232) - { - if (Character == '\n') - Rs232PortPutByte('\r'); - - Rs232PortPutByte(Character); - } - if (DebugPort & BOCHS) - { - WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character); - } - if (DebugPort & SCREEN) - { - MachConsPutChar(Character); - } -} - -ULONG -DbgPrint(const char *Format, ...) -{ - va_list ap; - int Length; - char* ptr; - CHAR Buffer[512]; - - va_start(ap, Format); - Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap); - va_end(ap); - - /* Check if we went past the buffer */ - if (Length == -1) - { - /* Terminate it if we went over-board */ - Buffer[sizeof(Buffer) - 1] = '\n'; - - /* Put maximum */ - Length = sizeof(Buffer); - } - - ptr = Buffer; - while (Length--) - DebugPrintChar(*ptr++); - - return 0; -} - -VOID -DbgPrint2(ULONG Mask, ULONG Level, const char *File, ULONG Line, char *Format, ...) -{ - va_list ap; - char Buffer[2096]; - char *ptr = Buffer; - - /* Mask out unwanted debug messages */ - if (!(DbgChannels[Mask] & Level) && !(Level & DBG_DEFAULT_LEVELS)) - { - return; - } - - /* Print the header if we have started a new line */ - if (DebugStartOfLine) - { - DbgPrint("(%s:%lu) ", File, Line); - - switch (Level) - { - case ERR_LEVEL: - DbgPrint("err: "); - break; - case FIXME_LEVEL: - DbgPrint("fixme: "); - break; - case WARN_LEVEL: - DbgPrint("warn: "); - break; - case TRACE_LEVEL: - DbgPrint("trace: "); - break; - } - - DebugStartOfLine = FALSE; - } - - va_start(ap, Format); - vsprintf(Buffer, Format, ap); - va_end(ap); - - while (*ptr) - { - DebugPrintChar(*ptr++); - } -} - -VOID -DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length) -{ - PUCHAR BufPtr = (PUCHAR)Buffer; - ULONG Idx, Idx2; - - /* Mask out unwanted debug messages */ - if (!(DbgChannels[Mask] & TRACE_LEVEL)) - return; - - DebugStartOfLine = FALSE; // We don't want line headers - DbgPrint("Dumping buffer at %p with length of %lu bytes:\n", Buffer, Length); - - for (Idx = 0; Idx < Length; ) - { - DebugStartOfLine = FALSE; // We don't want line headers - - if (Idx < 0x0010) - DbgPrint("000%x:\t", Idx); - else if (Idx < 0x0100) - DbgPrint("00%x:\t", Idx); - else if (Idx < 0x1000) - DbgPrint("0%x:\t", Idx); - else - DbgPrint("%x:\t", Idx); - - for (Idx2 = 0; Idx2 < 16; Idx2++, Idx++) - { - if (BufPtr[Idx] < 0x10) - { - DbgPrint("0"); - } - DbgPrint("%x", BufPtr[Idx]); - - if (Idx2 == 7) - { - DbgPrint("-"); - } - else - { - DbgPrint(" "); - } - } - - Idx -= 16; - DbgPrint(" "); - - for (Idx2 = 0; Idx2 < 16; Idx2++, Idx++) - { - if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80)) - { - DbgPrint("%c", BufPtr[Idx]); - } - else - { - DbgPrint("."); - } - } - - DbgPrint("\n"); - } -} - -static BOOLEAN -DbgAddDebugChannel(CHAR* channel, CHAR* level, CHAR op) -{ - int iLevel, iChannel; - - if (channel == NULL || *channel == '\0' || strlen(channel) == 0) - return FALSE; - - if (level == NULL || *level == '\0' || strlen(level) == 0) - iLevel = MAX_LEVEL; - else if (strcmp(level, "err") == 0) - iLevel = ERR_LEVEL; - else if (strcmp(level, "fixme") == 0) - iLevel = FIXME_LEVEL; - else if (strcmp(level, "warn") == 0) - iLevel = WARN_LEVEL; - else if (strcmp(level, "trace") == 0) - iLevel = TRACE_LEVEL; - else - return FALSE; - - if (strcmp(channel, "memory" ) == 0) iChannel = DPRINT_MEMORY; - else if (strcmp(channel, "filesystem") == 0) iChannel = DPRINT_FILESYSTEM; - else if (strcmp(channel, "inifile" ) == 0) iChannel = DPRINT_INIFILE; - else if (strcmp(channel, "ui" ) == 0) iChannel = DPRINT_UI; - else if (strcmp(channel, "disk" ) == 0) iChannel = DPRINT_DISK; - else if (strcmp(channel, "cache" ) == 0) iChannel = DPRINT_CACHE; - else if (strcmp(channel, "registry" ) == 0) iChannel = DPRINT_REGISTRY; - else if (strcmp(channel, "linux" ) == 0) iChannel = DPRINT_LINUX; - else if (strcmp(channel, "hwdetect" ) == 0) iChannel = DPRINT_HWDETECT; - else if (strcmp(channel, "windows" ) == 0) iChannel = DPRINT_WINDOWS; - else if (strcmp(channel, "peloader" ) == 0) iChannel = DPRINT_PELOADER; - else if (strcmp(channel, "scsiport" ) == 0) iChannel = DPRINT_SCSIPORT; - else if (strcmp(channel, "heap" ) == 0) iChannel = DPRINT_HEAP; - else if (strcmp(channel, "all" ) == 0) - { - int i; - - for (i = 0; i < DBG_CHANNELS_COUNT; i++) - { - if (op == '+') - DbgChannels[i] |= iLevel; - else - DbgChannels[i] &= ~iLevel; - } - - return TRUE; - } - else return FALSE; - - if (op == '+') - DbgChannels[iChannel] |= iLevel; - else - DbgChannels[iChannel] &= ~iLevel; - - return TRUE; -} - -VOID -DbgParseDebugChannels(PCHAR Value) -{ - CHAR *str, *separator, *c, op; - - str = Value; - - do - { - separator = strchr(str, ','); - if (separator != NULL) - *separator = '\0'; - - c = strchr(str, '+'); - if (c == NULL) - c = strchr(str, '-'); - - if (c != NULL) - { - op = *c; - *c = '\0'; - c++; - - DbgAddDebugChannel(c, str, op); - } - - str = separator + 1; - } while (separator != NULL); -} - -#else - -ULONG -DbgPrint(PCCH Format, ...) -{ - return 0; -} - -#endif // DBG - -ULONG -MsgBoxPrint(const char *Format, ...) -{ - va_list ap; - CHAR Buffer[512]; - ULONG Length; - - va_start(ap, Format); - - /* Construct a string */ - Length = _vsnprintf(Buffer, 512, Format, ap); - - /* Check if we went past the buffer */ - if (Length == MAXULONG) - { - /* Terminate it if we went over-board */ - Buffer[sizeof(Buffer) - 1] = '\n'; - - /* Put maximum */ - Length = sizeof(Buffer); - } - - /* Show it as a message box */ - UiMessageBox(Buffer); - - /* Cleanup and exit */ - va_end(ap); - return 0; -} - -// DECLSPEC_NORETURN -VOID -NTAPI -KeBugCheckEx( - IN ULONG BugCheckCode, - IN ULONG_PTR BugCheckParameter1, - IN ULONG_PTR BugCheckParameter2, - IN ULONG_PTR BugCheckParameter3, - IN ULONG_PTR BugCheckParameter4) -{ - char Buffer[70]; - sprintf(Buffer, "*** STOP: 0x%08lX (0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX)", - BugCheckCode, BugCheckParameter1, BugCheckParameter2, - BugCheckParameter3, BugCheckParameter4); - UiMessageBoxCritical(Buffer); - ASSERT(FALSE); - for (;;); -} - -VOID -NTAPI -RtlAssert(IN PVOID FailedAssertion, - IN PVOID FileName, - IN ULONG LineNumber, - IN PCHAR Message OPTIONAL) -{ - if (Message) - { - DbgPrint("Assertion '%s' failed at %s line %u: %s\n", - (PCHAR)FailedAssertion, - (PCHAR)FileName, - LineNumber, - Message); - } - else - { - DbgPrint("Assertion '%s' failed at %s line %u\n", - (PCHAR)FailedAssertion, - (PCHAR)FileName, - LineNumber); - } - - DbgBreakPoint(); -} - -char *BugCodeStrings[] = -{ - "TEST_BUGCHECK", - "MISSING_HARDWARE_REQUIREMENTS", - "FREELDR_IMAGE_CORRUPTION", - "MEMORY_INIT_FAILURE", -}; - -ULONG_PTR BugCheckInfo[5];
Added: trunk/reactos/boot/freeldr/freeldr/include/conversion.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/conversion.h (added) +++ trunk/reactos/boot/freeldr/freeldr/include/conversion.h [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -0,0 +1,40 @@ +/* + * PROJECT: EFI Windows Loader + * LICENSE: GPL - See COPYING in the top level directory + * FILE: boot/freeldr/freeldr/windows/conversion.c + * PURPOSE: Physical <-> Virtual addressing mode conversions (arch-specific) + * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + */ + +#pragma once + +#ifndef _ZOOM2_ +/* Arch-specific addresses translation implementation */ +FORCEINLINE +PVOID +VaToPa(PVOID Va) +{ + return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE); +} + +FORCEINLINE +PVOID +PaToVa(PVOID Pa) +{ + return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE); +} +#else +FORCEINLINE +PVOID +VaToPa(PVOID Va) +{ + return Va; +} + +FORCEINLINE +PVOID +PaToVa(PVOID Pa) +{ + return Pa; +} +#endif
Propchange: trunk/reactos/boot/freeldr/freeldr/include/conversion.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/boot/freeldr/freeldr/include/freeldr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/freeldr.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/freeldr.h [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -81,6 +81,7 @@
/* NTOS loader */ #include <winldr.h> +#include <conversion.h> // More-or-less related to MM also...
/* File system headers */ #include <fs/ext2.h>
Copied: trunk/reactos/boot/freeldr/freeldr/lib/peloader.c (from r70690, trunk/reactos/boot/freeldr/freeldr/windows/peloader.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/lib/pe... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/peloader.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/lib/peloader.c [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -2,15 +2,18 @@ * PROJECT: FreeLoader * LICENSE: GPL - See COPYING in the top level directory * FILE: boot/freeldr/freeldr/windows/peloader.c - * PURPOSE: Provides routines for loading PE files. To be merged with - * arch/i386/loader.c in future - * This article was very handy during development: - * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ + * PURPOSE: Provides routines for loading PE files. + * (Deprecated remark) To be merged with arch/i386/loader.c in future. + * * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) + * * The source code in this file is based on the work of respective * authors of PE loading code in ReactOS and Brian Palmer and * Alex Ionescu's arch/i386/loader.c, and my research project - * (creating a native EFI loader for Windows) + * (creating a native EFI loader for Windows). + * + * NOTE: This article was very handy during development: + * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ */
/* INCLUDES ***************************************************************/
Removed: trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/halstub.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/halstub.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/halstub.c (removed) @@ -1,99 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: boot/freeldr/freeldr/arch/i386/halstub.c - * PURPOSE: I/O Stub HAL Routines - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) - */ - -/* INCLUDES ******************************************************************/ - -#include "ntoskrnl.h" -#define NDEBUG -#include <debug.h> - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -FASTCALL -xHalIoReadPartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN BOOLEAN ReturnRecognizedPartitions, - OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer) -{ - return IoReadPartitionTable(DeviceObject, - SectorSize, - ReturnRecognizedPartitions, - PartitionBuffer); -} - -UCHAR -NTAPI -xHalVectorToIDTEntry(IN ULONG Vector) -{ - /* Return the vector */ - return (UCHAR)Vector; -} - -VOID -NTAPI -xHalHaltSystem(VOID) -{ - /* Halt execution */ - while (TRUE); -} - -/* GLOBALS *******************************************************************/ - -HAL_DISPATCH HalDispatchTable = -{ - HAL_DISPATCH_VERSION, - (pHalQuerySystemInformation)NULL, - (pHalSetSystemInformation)NULL, - (pHalQueryBusSlots)NULL, - 0, - (pHalExamineMBR)NULL, - (pHalIoAssignDriveLetters)NULL, - (pHalIoReadPartitionTable)xHalIoReadPartitionTable, - (pHalIoSetPartitionInformation)NULL, - (pHalIoWritePartitionTable)NULL, - (pHalHandlerForBus)NULL, - (pHalReferenceBusHandler)NULL, - (pHalReferenceBusHandler)NULL, - (pHalInitPnpDriver)NULL, - (pHalInitPowerManagement)NULL, - (pHalGetDmaAdapter)NULL, - (pHalGetInterruptTranslator)NULL, - (pHalStartMirroring)NULL, - (pHalEndMirroring)NULL, - (pHalMirrorPhysicalMemory)NULL, - (pHalEndOfBoot)NULL, - (pHalMirrorVerify)NULL, - (pHalGetAcpiTable)NULL, - (pHalSetPciErrorHandlerCallback)NULL -}; - -HAL_PRIVATE_DISPATCH HalPrivateDispatchTable = -{ - HAL_PRIVATE_DISPATCH_VERSION, - (pHalHandlerForBus)NULL, - (pHalHandlerForConfigSpace)NULL, - (pHalLocateHiberRanges)NULL, - (pHalRegisterBusHandler)NULL, - (pHalSetWakeEnable)NULL, - (pHalSetWakeAlarm)NULL, - (pHalTranslateBusAddress)NULL, - (pHalAssignSlotResources)NULL, - (pHalHaltSystem)xHalHaltSystem, - (pHalFindBusAddressTranslation)NULL, - (pHalResetDisplay)NULL, - (pHalAllocateMapRegisters)NULL, - (pKdSetupPciDeviceForDebugging)NULL, - (pKdReleasePciDeviceForDebugging)NULL, - (pKdGetAcpiTablePhase0)NULL, - (pKdCheckPowerButton)NULL, - (pHalVectorToIDTEntry)xHalVectorToIDTEntry, - (pKdMapPhysicalMemory64)NULL, - (pKdUnmapVirtualAddress)NULL -};
Removed: trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.c (removed) @@ -1,142 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: boot/freeldr/freeldr/arch/i386/ntoskrnl.c - * PURPOSE: NTOS glue routines for the MINIHAL library - * PROGRAMMERS: Hervé Poussineau hpoussin@reactos.org - */ - -/* INCLUDES ******************************************************************/ - -#include "ntoskrnl.h" - -/* For KeStallExecutionProcessor */ -#if defined(_M_IX86) || defined(_M_AMD64) -#include <arch/pc/pcbios.h> -#endif - -/* FUNCTIONS *****************************************************************/ - -VOID -NTAPI -KeInitializeEvent( - IN PRKEVENT Event, - IN EVENT_TYPE Type, - IN BOOLEAN State) -{ - memset(Event, 0, sizeof(*Event)); -} - -VOID -FASTCALL -KiAcquireSpinLock( - IN PKSPIN_LOCK SpinLock) -{ -} - -VOID -FASTCALL -KiReleaseSpinLock( - IN PKSPIN_LOCK SpinLock) -{ -} - -VOID -NTAPI -KeSetTimeIncrement( - IN ULONG MaxIncrement, - IN ULONG MinIncrement) -{ -} - -VOID -FASTCALL -IoAssignDriveLetters( - IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock, - IN PSTRING NtDeviceName, - OUT PUCHAR NtSystemPath, - OUT PSTRING NtSystemPathString) -{ -} - -NTSTATUS -FASTCALL -IoSetPartitionInformation( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG PartitionNumber, - IN ULONG PartitionType) -{ - return STATUS_NOT_IMPLEMENTED; -} - -/* - * NTSTATUS - * FASTCALL - * IoReadPartitionTable( - * IN PDEVICE_OBJECT DeviceObject, - * IN ULONG SectorSize, - * IN BOOLEAN ReturnRecognizedPartitions, - * OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer); - * - * See boot/freeldr/freeldr/disk/partition.c - */ - -NTSTATUS -FASTCALL -IoWritePartitionTable( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG SectorsPerTrack, - IN ULONG NumberOfHeads, - IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer) -{ - return STATUS_NOT_IMPLEMENTED; -} - -VOID -NTAPI -KeStallExecutionProcessor( - IN ULONG MicroSeconds) -{ -#if defined(_M_IX86) || defined(_M_AMD64) - REGS Regs; - ULONG usec_this; - - // Int 15h AH=86h - // BIOS - WAIT (AT,PS) - // - // AH = 86h - // CX:DX = interval in microseconds - // Return: - // CF clear if successful (wait interval elapsed) - // CF set on error or AH=83h wait already in progress - // AH = status (see #00496) - - // Note: The resolution of the wait period is 977 microseconds on - // many systems because many BIOSes use the 1/1024 second fast - // interrupt from the AT real-time clock chip which is available on INT 70; - // because newer BIOSes may have much more precise timers available, it is - // not possible to use this function accurately for very short delays unless - // the precise behavior of the BIOS is known (or found through testing) - - while (MicroSeconds) - { - usec_this = MicroSeconds; - - if (usec_this > 4000000) - { - usec_this = 4000000; - } - - Regs.b.ah = 0x86; - Regs.w.cx = usec_this >> 16; - Regs.w.dx = usec_this & 0xffff; - Int386(0x15, &Regs, &Regs); - - MicroSeconds -= usec_this; - } -#else - #error unimplemented -#endif -}
Removed: trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/ntldr/arch/i386/ntoskrnl.h (removed) @@ -1,25 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: boot/freeldr/freeldr/include/ntoskrnl.h - * PURPOSE: NTOS glue routines for the MINIHAL library - * PROGRAMMERS: Hervé Poussineau hpoussin@reactos.org - */ - -#include <ntdef.h> -#undef _NTHAL_ -//#undef DECLSPEC_IMPORT -//#define DECLSPEC_IMPORT -#undef NTSYSAPI -#define NTSYSAPI - -/* Windows Device Driver Kit */ -#include <ntddk.h> -#include <ndk/haltypes.h> - -//typedef GUID UUID; - -/* Disk stuff */ -#include <arc/arc.h> -#include <ntdddisk.h> -#include <internal/hal.h>
Modified: trunk/reactos/boot/freeldr/freeldr/ntldr/conversion.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/ntldr/... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ntldr/conversion.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/ntldr/conversion.c [iso-8859-1] Fri Feb 5 00:17:33 2016 @@ -16,33 +16,6 @@ DBG_DEFAULT_CHANNEL(WINDOWS);
/* FUNCTIONS **************************************************************/ - -#ifndef _ZOOM2_ -/* Arch-specific addresses translation implementation */ -PVOID -VaToPa(PVOID Va) -{ - return (PVOID)((ULONG_PTR)Va & ~KSEG0_BASE); -} - -PVOID -PaToVa(PVOID Pa) -{ - return (PVOID)((ULONG_PTR)Pa | KSEG0_BASE); -} -#else -PVOID -VaToPa(PVOID Va) -{ - return Va; -} - -PVOID -PaToVa(PVOID Pa) -{ - return Pa; -} -#endif
VOID List_PaToVa(_In_ PLIST_ENTRY ListHeadPa)
Removed: trunk/reactos/boot/freeldr/freeldr/ntldr/peloader.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/ntldr/peloader.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/ntldr/peloader.c (removed) @@ -1,858 +0,0 @@ -/* - * PROJECT: FreeLoader - * LICENSE: GPL - See COPYING in the top level directory - * FILE: boot/freeldr/freeldr/windows/peloader.c - * PURPOSE: Provides routines for loading PE files. To be merged with - * arch/i386/loader.c in future - * This article was very handy during development: - * http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ - * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) - * The source code in this file is based on the work of respective - * authors of PE loading code in ReactOS and Brian Palmer and - * Alex Ionescu's arch/i386/loader.c, and my research project - * (creating a native EFI loader for Windows) - */ - -/* INCLUDES ***************************************************************/ -#include <freeldr.h> -#include <debug.h> - -DBG_DEFAULT_CHANNEL(PELOADER); - -static BOOLEAN -WinLdrpCompareDllName(IN PCH DllName, - IN PUNICODE_STRING UnicodeName); - -static BOOLEAN -WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead, - IN PVOID DllBase, - IN PVOID ImageBase, - IN PIMAGE_THUNK_DATA ThunkData, - IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, - IN ULONG ExportSize, - IN BOOLEAN ProcessForwards, - IN PCSTR DirectoryPath); - -static BOOLEAN -WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead, - PCCH DirectoryPath, - PCH ImportName, - PLDR_DATA_TABLE_ENTRY *DataTableEntry); - -static BOOLEAN -WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead, - IN PVOID DllBase, - IN PVOID ImageBase, - IN PIMAGE_THUNK_DATA ThunkData, - IN PCSTR DirectoryPath); - - - -/* FUNCTIONS **************************************************************/ - -/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */ -BOOLEAN -WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead, - IN PCH DllName, - OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry) -{ - PLDR_DATA_TABLE_ENTRY DataTableEntry; - LIST_ENTRY *ModuleEntry; - - TRACE("WinLdrCheckForLoadedDll: DllName %s\n", DllName); - - /* Just go through each entry in the LoadOrderList and compare loaded module's - name with a given name */ - ModuleEntry = ModuleListHead->Flink; - while (ModuleEntry != ModuleListHead) - { - /* Get pointer to the current DTE */ - DataTableEntry = CONTAINING_RECORD(ModuleEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - - TRACE("WinLdrCheckForLoadedDll: DTE %p, EP %p, base %p name '%.*ws'\n", - DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase, - DataTableEntry->BaseDllName.Length / 2, VaToPa(DataTableEntry->BaseDllName.Buffer)); - - /* Compare names */ - if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName)) - { - /* Yes, found it, report pointer to the loaded module's DTE - to the caller and increase load count for it */ - *LoadedEntry = DataTableEntry; - DataTableEntry->LoadCount++; - TRACE("WinLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry); - return TRUE; - } - - /* Go to the next entry */ - ModuleEntry = ModuleEntry->Flink; - } - - /* Nothing found */ - return FALSE; -} - -BOOLEAN -WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead, - IN PCCH DirectoryPath, - IN PLDR_DATA_TABLE_ENTRY ScanDTE) -{ - PLDR_DATA_TABLE_ENTRY DataTableEntry; - PIMAGE_IMPORT_DESCRIPTOR ImportTable; - ULONG ImportTableSize; - PCH ImportName; - BOOLEAN Success; - - /* Get a pointer to the import table of this image */ - ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase), - TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize); - - { - UNICODE_STRING BaseName; - BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer); - BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength; - BaseName.Length = ScanDTE->BaseDllName.Length; - TRACE("WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n", - &BaseName, ImportTable); - } - - /* If image doesn't have any import directory - just return success */ - if (ImportTable == NULL) - return TRUE; - - /* Loop through all entries */ - for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk != 0);ImportTable++) - { - /* Get pointer to the name */ - ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name)); - TRACE("WinLdrScanImportDescriptorTable(): Looking at %s\n", ImportName); - - /* In case we get a reference to ourselves - just skip it */ - if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName)) - continue; - - /* Load the DLL if it is not already loaded */ - if (!WinLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry)) - { - Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead, - DirectoryPath, - ImportName, - &DataTableEntry); - if (!Success) - { - ERR("WinLdrpLoadAndScanReferencedDll() failed\n"); - return Success; - } - } - - /* Scan its import address table */ - Success = WinLdrpScanImportAddressTable(ModuleListHead, - DataTableEntry->DllBase, - ScanDTE->DllBase, - (PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk), - DirectoryPath); - - if (!Success) - { - ERR("WinLdrpScanImportAddressTable() failed: ImportName = '%s', DirectoryPath = '%s'\n", - ImportName, DirectoryPath); - return Success; - } - } - - return TRUE; -} - -BOOLEAN -WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead, - IN PCCH BaseDllName, - IN PCCH FullDllName, - IN PVOID BasePA, - OUT PLDR_DATA_TABLE_ENTRY *NewEntry) -{ - PVOID BaseVA = PaToVa(BasePA); - PWSTR Buffer; - PLDR_DATA_TABLE_ENTRY DataTableEntry; - PIMAGE_NT_HEADERS NtHeaders; - USHORT Length; - TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n", - BaseDllName, FullDllName, BasePA); - - /* Allocate memory for a data table entry, zero-initialize it */ - DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY), - TAG_WLDR_DTE); - if (DataTableEntry == NULL) - return FALSE; - RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY)); - - /* Get NT headers from the image */ - NtHeaders = RtlImageNtHeader(BasePA); - - /* Initialize corresponding fields of DTE based on NT headers value */ - DataTableEntry->DllBase = BaseVA; - DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; - DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint); - DataTableEntry->SectionPointer = 0; - DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum; - - /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName - by simple conversion - copying each character */ - Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR)); - Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME); - if (Buffer == NULL) - { - FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE); - return FALSE; - } - RtlZeroMemory(Buffer, Length); - - DataTableEntry->BaseDllName.Length = Length; - DataTableEntry->BaseDllName.MaximumLength = Length; - DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer); - while (*BaseDllName != 0) - { - *Buffer++ = *BaseDllName++; - } - - /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName - using the same method */ - Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR)); - Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME); - if (Buffer == NULL) - { - FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE); - return FALSE; - } - RtlZeroMemory(Buffer, Length); - - DataTableEntry->FullDllName.Length = Length; - DataTableEntry->FullDllName.MaximumLength = Length; - DataTableEntry->FullDllName.Buffer = PaToVa(Buffer); - while (*FullDllName != 0) - { - *Buffer++ = *FullDllName++; - } - - /* Initialize what's left - LoadCount which is 1, and set Flags so that - we know this entry is processed */ - DataTableEntry->Flags = LDRP_ENTRY_PROCESSED; - DataTableEntry->LoadCount = 1; - - /* Insert this DTE to a list in the LPB */ - InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks); - TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry, - DataTableEntry->BaseDllName.Length / 2, - VaToPa(DataTableEntry->BaseDllName.Buffer), - DataTableEntry->DllBase); - - /* Save pointer to a newly allocated and initialized entry */ - *NewEntry = DataTableEntry; - - /* Return success */ - return TRUE; -} - -/* - * WinLdrLoadImage loads the specified image from the file (it doesn't - * perform any additional operations on the filename, just directly - * calls the file I/O routines), and relocates it so that it's ready - * to be used when paging is enabled. - * Addressing mode: physical - */ -BOOLEAN -WinLdrLoadImage(IN PCHAR FileName, - TYPE_OF_MEMORY MemoryType, - OUT PVOID *ImageBasePA) -{ - ULONG FileId; - PVOID PhysicalBase; - PVOID VirtualBase = NULL; - UCHAR HeadersBuffer[SECTOR_SIZE * 2]; - PIMAGE_NT_HEADERS NtHeaders; - PIMAGE_SECTION_HEADER SectionHeader; - ULONG VirtualSize, SizeOfRawData, NumberOfSections; - ARC_STATUS Status; - LARGE_INTEGER Position; - ULONG i, BytesRead; - TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType); - - /* Open the image file */ - Status = ArcOpen(FileName, OpenReadOnly, &FileId); - if (Status != ESUCCESS) - { - // UiMessageBox("Can not open the file."); - return FALSE; - } - - /* Load the first 2 sectors of the image so we can read the PE header */ - Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead); - if (Status != ESUCCESS) - { - UiMessageBox("Error reading from file."); - ArcClose(FileId); - return FALSE; - } - - /* Now read the MZ header to get the offset to the PE Header */ - NtHeaders = RtlImageNtHeader(HeadersBuffer); - if (!NtHeaders) - { - // Print(L"Error - no NT header found in %s\n", FileName); - UiMessageBox("Error - no NT header found."); - ArcClose(FileId); - return FALSE; - } - - /* Ensure this is executable image */ - if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) - { - // Print(L"Not an executable image %s\n", FileName); - UiMessageBox("Not an executable image."); - ArcClose(FileId); - return FALSE; - } - - /* Store number of sections to read and a pointer to the first section */ - NumberOfSections = NtHeaders->FileHeader.NumberOfSections; - SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); - - /* Try to allocate this memory, if fails - allocate somewhere else */ - PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, - (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)), - MemoryType); - - if (PhysicalBase == NULL) - { - /* It's ok, we don't panic - let's allocate again at any other "low" place */ - PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType); - - if (PhysicalBase == NULL) - { - // Print(L"Failed to alloc pages for image %s\n", FileName); - UiMessageBox("Failed to alloc pages for image."); - ArcClose(FileId); - return FALSE; - } - } - - /* This is the real image base - in form of a virtual address */ - VirtualBase = PaToVa(PhysicalBase); - - TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase); - - /* Set to 0 position and fully load the file image */ - Position.HighPart = Position.LowPart = 0; - Status = ArcSeek(FileId, &Position, SeekAbsolute); - if (Status != ESUCCESS) - { - UiMessageBox("Error seeking to start of file."); - ArcClose(FileId); - return FALSE; - } - - Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead); - if (Status != ESUCCESS) - { - // Print(L"Error reading headers %s\n", FileName); - UiMessageBox("Error reading headers."); - ArcClose(FileId); - return FALSE; - } - - /* Reload the NT Header */ - NtHeaders = RtlImageNtHeader(PhysicalBase); - - /* Load the first section */ - SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); - - /* Fill output parameters */ - *ImageBasePA = PhysicalBase; - - /* Walk through each section and read it (check/fix any possible - bad situations, if they arise) */ - for (i = 0; i < NumberOfSections; i++) - { - VirtualSize = SectionHeader->Misc.VirtualSize; - SizeOfRawData = SectionHeader->SizeOfRawData; - - /* Handle a case when VirtualSize equals 0 */ - if (VirtualSize == 0) - VirtualSize = SizeOfRawData; - - /* If PointerToRawData is 0, then force its size to be also 0 */ - if (SectionHeader->PointerToRawData == 0) - { - SizeOfRawData = 0; - } - else - { - /* Cut the loaded size to the VirtualSize extents */ - if (SizeOfRawData > VirtualSize) - SizeOfRawData = VirtualSize; - } - - /* Actually read the section (if its size is not 0) */ - if (SizeOfRawData != 0) - { - /* Seek to the correct position */ - Position.LowPart = SectionHeader->PointerToRawData; - Status = ArcSeek(FileId, &Position, SeekAbsolute); - - TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress); - - /* Read this section from the file, size = SizeOfRawData */ - Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead); - if (Status != ESUCCESS) - { - ERR("WinLdrLoadImage(): Error reading section from file!\n"); - break; - } - } - - /* Size of data is less than the virtual size - fill up the remainder with zeroes */ - if (SizeOfRawData < VirtualSize) - { - TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize); - RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); - } - - SectionHeader++; - } - - /* We are done with the file - close it */ - ArcClose(FileId); - - /* If loading failed - return right now */ - if (Status != ESUCCESS) - return FALSE; - - /* Relocate the image, if it needs it */ - if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase) - { - WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, - VirtualBase); - return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, - (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase, - "FreeLdr", - TRUE, - TRUE, /* in case of conflict still return success */ - FALSE); - } - - TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA); - return TRUE; -} - -/* PRIVATE FUNCTIONS *******************************************************/ - -/* DllName - physical, UnicodeString->Buffer - virtual */ -static BOOLEAN -WinLdrpCompareDllName(IN PCH DllName, - IN PUNICODE_STRING UnicodeName) -{ - PWSTR Buffer; - UNICODE_STRING UnicodeNamePA; - SIZE_T i, Length; - - /* First obvious check: for length of two names */ - Length = strlen(DllName); - - UnicodeNamePA.Length = UnicodeName->Length; - UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength; - UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer); - TRACE("WinLdrpCompareDllName: %s and %wZ, Length = %d " - "UN->Length %d\n", DllName, &UnicodeNamePA, Length, UnicodeName->Length); - - if ((Length * sizeof(WCHAR)) > UnicodeName->Length) - return FALSE; - - /* Store pointer to unicode string's buffer */ - Buffer = VaToPa(UnicodeName->Buffer); - - /* Loop character by character */ - for (i = 0; i < Length; i++) - { - /* Compare two characters, uppercasing them */ - if (toupper(*DllName) != toupper((CHAR)*Buffer)) - return FALSE; - - /* Move to the next character */ - DllName++; - Buffer++; - } - - /* Check, if strings either fully match, or match till the "." (w/o extension) */ - if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.')) - { - /* Yes they do */ - return TRUE; - } - - /* Strings don't match, return FALSE */ - return FALSE; -} - -static BOOLEAN -WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead, - IN PVOID DllBase, - IN PVOID ImageBase, - IN PIMAGE_THUNK_DATA ThunkData, - IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, - IN ULONG ExportSize, - IN BOOLEAN ProcessForwards, - IN PCSTR DirectoryPath) -{ - ULONG Ordinal; - PULONG NameTable, FunctionTable; - PUSHORT OrdinalTable; - LONG High, Low, Middle, Result; - ULONG Hint; - PIMAGE_IMPORT_BY_NAME ImportData; - PCHAR ExportName, ForwarderName; - BOOLEAN Success; - - //TRACE("WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X, ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n", - // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize, ProcessForwards); - - /* Check passed DllBase param */ - if(DllBase == NULL) - { - WARN("DllBase == NULL!\n"); - return FALSE; - } - - /* Convert all non-critical pointers to PA from VA */ - ThunkData = VaToPa(ThunkData); - - /* Is the reference by ordinal? */ - if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards) - { - /* Yes, calculate the ordinal */ - Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) - (UINT32)ExportDirectory->Base); - //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal); - } - else - { - /* It's reference by name, we have to look it up in the export directory */ - if (!ProcessForwards) - { - /* AddressOfData in thunk entry will become a virtual address (from relative) */ - //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n", ThunkData->u1.AddressOfData); - ThunkData->u1.AddressOfData = - (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData); - //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD became %p\n", ThunkData->u1.AddressOfData); - } - - /* Get the import name */ - ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData); - - /* Get pointers to Name and Ordinal tables (RVA -> VA) */ - NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames)); - OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals)); - - //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X, ED->AOFO 0x%X\n", - // NameTable, OrdinalTable, ExportDirectory->AddressOfNames, ExportDirectory->AddressOfNameOrdinals); - - /* Get the hint, convert it to a physical pointer */ - Hint = ((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint; - //TRACE("HintIndex %d\n", Hint); - - /* Get the export name from the hint */ - ExportName = VaToPa(RVA(DllBase, NameTable[Hint])); - - /* If Hint is less than total number of entries in the export directory, - and import name == export name, then we can just get it from the OrdinalTable */ - if ((Hint < ExportDirectory->NumberOfNames) && - (strcmp(ExportName, (PCHAR)ImportData->Name) == 0)) - { - Ordinal = OrdinalTable[Hint]; - //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal); - } - else - { - /* It's not the easy way, we have to lookup import name in the name table. - Let's use a binary search for this task. */ - - //TRACE("WinLdrpBindImportName() looking up the import name using binary search...\n"); - - /* Low boundary is set to 0, and high boundary to the maximum index */ - Low = 0; - High = ExportDirectory->NumberOfNames - 1; - - /* Perform a binary-search loop */ - while (High >= Low) - { - /* Divide by 2 by shifting to the right once */ - Middle = (Low + High) / 2; - - /* Get the name from the name table */ - ExportName = VaToPa(RVA(DllBase, NameTable[Middle])); - - /* Compare the names */ - Result = strcmp(ExportName, (PCHAR)ImportData->Name); - - /*TRACE("Binary search: comparing Import '__', Export '%s'\n",*/ - /*VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),*/ - /*(PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));*/ - - /*TRACE("TE->u1.AOD %p, fulladdr %p\n", - ThunkData->u1.AddressOfData, - ((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );*/ - - - /* Depending on result of strcmp, perform different actions */ - if (Result > 0) - { - /* Adjust top boundary */ - High = Middle - 1; - } - else if (Result < 0) - { - /* Adjust bottom boundary */ - Low = Middle + 1; - } - else - { - /* Yay, found it! */ - break; - } - } - - /* If high boundary is less than low boundary, then no result found */ - if (High < Low) - { - //Print(L"Error in binary search\n"); - ERR("Did not find export '%s'!\n", (PCHAR)ImportData->Name); - return FALSE; - } - - /* Everything allright, get the ordinal */ - Ordinal = OrdinalTable[Middle]; - - //TRACE("WinLdrpBindImportName() found Ordinal %d\n", Ordinal); - } - } - - /* Check ordinal number for validity! */ - if (Ordinal >= ExportDirectory->NumberOfFunctions) - { - ERR("Ordinal number is invalid!\n"); - return FALSE; - } - - /* Get a pointer to the function table */ - FunctionTable = (PULONG)VaToPa(RVA(DllBase, ExportDirectory->AddressOfFunctions)); - - /* Save a pointer to the function */ - ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]); - - /* Is it a forwarder? (function pointer is within the export directory) */ - ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function); - if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) && - ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize))) - { - PLDR_DATA_TABLE_ENTRY DataTableEntry; - CHAR ForwardDllName[255]; - PIMAGE_EXPORT_DIRECTORY RefExportDirectory; - ULONG RefExportSize; - TRACE("WinLdrpBindImportName(): ForwarderName %s\n", ForwarderName); - - /* Save the name of the forward dll */ - RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName)); - - /* Strip out the symbol name */ - *strrchr(ForwardDllName,'.') = '\0'; - - /* Check if the target image is already loaded */ - if (!WinLdrCheckForLoadedDll(ModuleListHead, ForwardDllName, &DataTableEntry)) - { - /* Check if the forward dll name has an extension */ - if (strchr(ForwardDllName, '.') == NULL) - { - /* Name does not have an extension, append '.dll' */ - strcat(ForwardDllName, ".dll"); - } - - /* Now let's try to load it! */ - Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead, - DirectoryPath, - ForwardDllName, - &DataTableEntry); - if (!Success) - { - ERR("WinLdrpLoadAndScanReferencedDll() failed to load forwarder dll.\n"); - return Success; - } - } - - /* Get pointer to the export directory of loaded DLL */ - RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY) - RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase), - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - &RefExportSize); - - /* Fail if it's NULL */ - if (RefExportDirectory) - { - UCHAR Buffer[128]; - IMAGE_THUNK_DATA RefThunkData; - PIMAGE_IMPORT_BY_NAME ImportByName; - PCHAR ImportName; - - /* Get pointer to the import name */ - ImportName = strrchr(ForwarderName, '.') + 1; - - /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */ - ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer; - - /* Fill the name with the import name */ - RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1); - - /* Set Hint to 0 */ - ImportByName->Hint = 0; - - /* And finally point ThunkData's AddressOfData to that structure */ - RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName; - - /* And recursively call ourselves */ - Success = WinLdrpBindImportName(ModuleListHead, - DataTableEntry->DllBase, - ImageBase, - &RefThunkData, - RefExportDirectory, - RefExportSize, - TRUE, - DirectoryPath); - - /* Fill out the ThunkData with data from RefThunkData */ - ThunkData->u1 = RefThunkData.u1; - - /* Return what we got from the recursive call */ - return Success; - } - else - { - /* Fail if ExportDirectory is NULL */ - return FALSE; - } - } - - /* Success! */ - return TRUE; -} - -static BOOLEAN -WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead, - PCCH DirectoryPath, - PCH ImportName, - PLDR_DATA_TABLE_ENTRY *DataTableEntry) -{ - CHAR FullDllName[256]; - BOOLEAN Success; - PVOID BasePA = NULL; - - /* Prepare the full path to the file to be loaded */ - strcpy(FullDllName, DirectoryPath); - strcat(FullDllName, ImportName); - - TRACE("Loading referenced DLL: %s\n", FullDllName); - //Print(L"Loading referenced DLL: %s\n", FullDllName); - - /* Load the image */ - Success = WinLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA); - if (!Success) - { - ERR("WinLdrLoadImage() failed\n"); - return Success; - } - - /* Allocate DTE for newly loaded DLL */ - Success = WinLdrAllocateDataTableEntry(ModuleListHead, - ImportName, - FullDllName, - BasePA, - DataTableEntry); - if (!Success) - { - ERR("WinLdrAllocateDataTableEntry() failed\n"); - return Success; - } - - /* Scan its dependencies too */ - TRACE("WinLdrScanImportDescriptorTable() calling ourselves for %S\n", - VaToPa((*DataTableEntry)->BaseDllName.Buffer)); - Success = WinLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath, *DataTableEntry); - if (!Success) - { - ERR("WinLdrScanImportDescriptorTable() failed\n"); - return Success; - } - - return TRUE; -} - -static BOOLEAN -WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead, - IN PVOID DllBase, - IN PVOID ImageBase, - IN PIMAGE_THUNK_DATA ThunkData, - IN PCSTR DirectoryPath) -{ - PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; - BOOLEAN Success; - ULONG ExportSize; - - TRACE("WinLdrpScanImportAddressTable(): DllBase 0x%X, " - "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData); - - /* Obtain the export table from the DLL's base */ - if (DllBase == NULL) - { - ERR("Error, DllBase == NULL!\n"); - return FALSE; - } - else - { - ExportDirectory = - (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase), - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - &ExportSize); - } - - TRACE("WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n", ExportDirectory); - - /* If pointer to Export Directory is */ - if (ExportDirectory == NULL) - { - ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase)); - return FALSE; - } - - /* Go through each entry in the thunk table and bind it */ - while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0) - { - /* Bind it */ - Success = WinLdrpBindImportName(ModuleListHead, - DllBase, - ImageBase, - ThunkData, - ExportDirectory, - ExportSize, - FALSE, - DirectoryPath); - - /* Move to the next entry */ - ThunkData++; - - /* Return error if binding was unsuccessful */ - if (!Success) - return Success; - } - - /* Return success */ - return TRUE; -}