Author: ion
Date: Thu Feb 22 03:01:52 2007
New Revision: 25872
URL:
http://svn.reactos.org/svn/reactos?rev=25872&view=rev
Log:
- Rename ModuleListHead to PsLoadedModulesList.
- Start implementing some routines of the Mm SysLdr. Implemented MiSnapThunk and most of
MiResolveImageReferences. The SysLdr has a lot of restrictions that the typical Ldr in
user-mode doesn't, as well as manages imports and reference counts them, so the code
can't be shared with ntdll's Ldr (this is also why real NT doesn't have an Ldr
component, and this is in Mm).
- Fix some PE Header types that were wrong in our PSDK.
Added:
trunk/reactos/ntoskrnl/mm/sysldr.c
Modified:
trunk/reactos/include/ddk/ntifs.h
trunk/reactos/include/ddk/winddk.h
trunk/reactos/include/ndk/ldrtypes.h
trunk/reactos/include/psdk/winnt.h
trunk/reactos/ntoskrnl/ex/sysinfo.c
trunk/reactos/ntoskrnl/include/internal/ps.h
trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c
trunk/reactos/ntoskrnl/ke/bug.c
trunk/reactos/ntoskrnl/ldr/loader.c
trunk/reactos/ntoskrnl/mm/mm.c
trunk/reactos/ntoskrnl/mm/verifier.c
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: trunk/reactos/include/ddk/ntifs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntifs.h?rev=25…
==============================================================================
--- trunk/reactos/include/ddk/ntifs.h (original)
+++ trunk/reactos/include/ddk/ntifs.h Thu Feb 22 03:01:52 2007
@@ -3814,6 +3814,14 @@
);
NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAppendStringToString(
+ PSTRING Destination,
+ const STRING *Source
+);
+
+NTSYSAPI
USHORT
NTAPI
RtlCaptureStackBackTrace (
Modified: trunk/reactos/include/ddk/winddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=2…
==============================================================================
--- trunk/reactos/include/ddk/winddk.h (original)
+++ trunk/reactos/include/ddk/winddk.h Thu Feb 22 03:01:52 2007
@@ -247,6 +247,8 @@
#define MAXIMUM_PRIORITY 32
#define MAXIMUM_SUSPEND_COUNT MAXCHAR
+
+#define MAXIMUM_FILENAME_LENGTH 256
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
Modified: trunk/reactos/include/ndk/ldrtypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ldrtypes.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/ldrtypes.h (original)
+++ trunk/reactos/include/ndk/ldrtypes.h Thu Feb 22 03:01:52 2007
@@ -119,6 +119,15 @@
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
//
+// Loaded Imports Reference Counting in Kernel
+//
+typedef struct _LOAD_IMPORTS
+{
+ SIZE_T Count;
+ PLDR_DATA_TABLE_ENTRY Entry[1];
+} LOAD_IMPORTS, *PLOAD_IMPORTS;
+
+//
// Loader Resource Information
//
typedef struct _LDR_RESOURCE_INFO
Modified: trunk/reactos/include/psdk/winnt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winnt.h?rev=2…
==============================================================================
--- trunk/reactos/include/psdk/winnt.h (original)
+++ trunk/reactos/include/psdk/winnt.h Thu Feb 22 03:01:52 2007
@@ -3119,21 +3119,21 @@
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_THUNK_DATA {
union {
- PBYTE ForwarderString;
- PDWORD Function;
+ ULONG ForwarderString;
+ ULONG Function;
DWORD Ordinal;
- PIMAGE_IMPORT_BY_NAME AddressOfData;
+ ULONG AddressOfData;
} u1;
} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
_ANONYMOUS_UNION union {
DWORD Characteristics;
- PIMAGE_THUNK_DATA OriginalFirstThunk;
+ ULONG OriginalFirstThunk;
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
- PIMAGE_THUNK_DATA FirstThunk;
+ ULONG FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c Thu Feb 22 03:01:52 2007
@@ -952,8 +952,8 @@
/* Class 11 - Module Information */
QSI_DEF(SystemModuleInformation)
{
- extern LIST_ENTRY ModuleListHead;
- return ExpQueryModuleInformation(&ModuleListHead,
+ extern LIST_ENTRY PsLoadedModuleList;
+ return ExpQueryModuleInformation(&PsLoadedModuleList,
NULL,
(PRTL_PROCESS_MODULES)Buffer,
Size,
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ps.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h Thu Feb 22 03:01:52 2007
@@ -384,7 +384,7 @@
extern POBJECT_TYPE PsJobType;
extern LARGE_INTEGER ShortPsLockDelay;
extern UNICODE_STRING PsNtDllPathName;
-extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
+extern LIST_ENTRY PsLoadedModuleList;
//
// Inlined Functions
Modified: trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kdbg/kdb_symbols.…
==============================================================================
--- trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c (original)
+++ trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c Thu Feb 22 03:01:52 2007
@@ -107,13 +107,12 @@
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
- extern LIST_ENTRY ModuleListHead;
INT Count = 0;
INT Length;
- current_entry = ModuleListHead.Flink;
-
- while (current_entry != &ModuleListHead)
+ current_entry = PsLoadedModuleList.Flink;
+
+ while (current_entry != &PsLoadedModuleList)
{
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
Modified: trunk/reactos/ntoskrnl/ke/bug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=2587…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/bug.c (original)
+++ trunk/reactos/ntoskrnl/ke/bug.c Thu Feb 22 03:01:52 2007
@@ -37,15 +37,15 @@
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
- extern LIST_ENTRY ModuleListHead;
+ extern LIST_ENTRY PsLoadedModuleList;
ULONG_PTR RelativeAddress;
ULONG i = 0;
do
{
- current_entry = ModuleListHead.Flink;
-
- while (current_entry != &ModuleListHead)
+ current_entry = PsLoadedModuleList.Flink;
+
+ while (current_entry != &PsLoadedModuleList)
{
current = CONTAINING_RECORD(current_entry,
LDR_DATA_TABLE_ENTRY,
@@ -267,13 +267,13 @@
PVOID ImageBase, EipBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
- extern LIST_ENTRY ModuleListHead;
+ extern LIST_ENTRY PsLoadedModuleList;
/* Assume no */
*InKernel = FALSE;
/* Set list pointers and make sure it's valid */
- ListHead = &ModuleListHead;
+ ListHead = &PsLoadedModuleList;
NextEntry = ListHead->Flink;
if (NextEntry)
{
Modified: trunk/reactos/ntoskrnl/ldr/loader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ldr/loader.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ldr/loader.c (original)
+++ trunk/reactos/ntoskrnl/ldr/loader.c Thu Feb 22 03:01:52 2007
@@ -20,44 +20,21 @@
/* GLOBALS *******************************************************************/
-LIST_ENTRY ModuleListHead;
+LIST_ENTRY PsLoadedModuleList;
KSPIN_LOCK ModuleListLock;
LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject;
LDR_DATA_TABLE_ENTRY HalModuleObject;
/* FUNCTIONS *****************************************************************/
-static PVOID
-LdrPEGetExportByName (
- PVOID BaseAddress,
- PUCHAR SymbolName,
- USHORT Hint );
-
-static VOID
-LdrpBuildModuleBaseName (
- PUNICODE_STRING BaseName,
- PUNICODE_STRING FullName )
-{
- PWCHAR p;
-
- DPRINT("LdrpBuildModuleBaseName()\n");
- DPRINT("FullName %wZ\n", FullName);
-
- p = wcsrchr(FullName->Buffer, L'\\');
- if (p == NULL)
- {
- p = FullName->Buffer;
- }
- else
- {
- p++;
- }
-
- DPRINT("p %S\n", p);
-
- RtlInitUnicodeString(BaseName, p);
-}
-
+NTSTATUS
+NTAPI
+MiResolveImageReferences(IN PVOID ImageBase,
+ IN PUNICODE_STRING ImageFileDirectory,
+ IN PUNICODE_STRING NamePrefix OPTIONAL,
+ OUT PCHAR *MissingApi,
+ OUT PWCHAR *MissingDriver,
+ OUT PLOAD_IMPORTS *LoadImports);
static LONG
LdrpCompareModuleNames (
@@ -128,380 +105,128 @@
return(0);
}
-#ifndef PATH_MAX
-#define PATH_MAX 260
-#endif
-
-static NTSTATUS
-LdrPEGetOrLoadModule (
- PWCHAR ModuleName,
- PCHAR ImportedName,
- PLDR_DATA_TABLE_ENTRY* ImportedModule)
+VOID
+INIT_FUNCTION
+NTAPI
+LdrInit1(VOID)
{
- UNICODE_STRING DriverName;
- UNICODE_STRING NameString;
- WCHAR NameBuffer[PATH_MAX];
- NTSTATUS Status = STATUS_SUCCESS;
-
- RtlCreateUnicodeStringFromAsciiz (&DriverName, ImportedName);
- DPRINT("Import module: %wZ\n", &DriverName);
-
- *ImportedModule = LdrGetModuleObject(&DriverName);
- if (*ImportedModule == NULL)
- {
- PWCHAR PathEnd;
- ULONG PathLength;
-
- PathEnd = wcsrchr(ModuleName, L'\\');
- if (NULL != PathEnd)
+ PLDR_DATA_TABLE_ENTRY HalModuleObject, NtoskrnlModuleObject, LdrEntry;
+
+ /* Initialize the module list and spinlock */
+ InitializeListHead(&PsLoadedModuleList);
+ KeInitializeSpinLock(&ModuleListLock);
+
+ /* Get the NTOSKRNL Entry from the loader */
+ LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink,
LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+
+ /* Initialize ModuleObject for NTOSKRNL */
+ NtoskrnlModuleObject = ExAllocatePoolWithTag(PagedPool,
+ sizeof(LDR_DATA_TABLE_ENTRY),
+ TAG('M', 'm',
'L', 'd'));
+ NtoskrnlModuleObject->DllBase = LdrEntry->DllBase;
+ RtlInitUnicodeString(&NtoskrnlModuleObject->FullDllName, KERNEL_MODULE_NAME);
+ NtoskrnlModuleObject->BaseDllName = NtoskrnlModuleObject->FullDllName;
+ NtoskrnlModuleObject->EntryPoint = LdrEntry->EntryPoint;
+ NtoskrnlModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
+
+ /* Insert it into the list */
+ InsertTailList(&PsLoadedModuleList,
&NtoskrnlModuleObject->InLoadOrderLinks);
+
+ /* Get the HAL Entry from the loader */
+ LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink->Flink,
LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+
+ /* Initialize ModuleObject for HAL */
+ HalModuleObject = ExAllocatePoolWithTag(PagedPool,
+ sizeof(LDR_DATA_TABLE_ENTRY),
+ TAG('M', 'm',
'L', 'd'));
+ HalModuleObject->DllBase = LdrEntry->DllBase;
+ RtlInitUnicodeString(&HalModuleObject->FullDllName, HAL_MODULE_NAME);
+ HalModuleObject->BaseDllName = HalModuleObject->FullDllName;
+ HalModuleObject->EntryPoint = LdrEntry->EntryPoint;
+ HalModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
+
+ /* Insert it into the list */
+ InsertTailList(&PsLoadedModuleList, &HalModuleObject->InLoadOrderLinks);
+
+ /* Hook for KDB on initialization of the loader. */
+ KDB_LOADERINIT_HOOK(NtoskrnlModuleObject, HalModuleObject);
+}
+
+//
+// Used for checking if a module is already in the module list.
+// Used during loading/unloading drivers.
+//
+PLDR_DATA_TABLE_ENTRY
+NTAPI
+LdrGetModuleObject ( PUNICODE_STRING ModuleName )
+{
+ PLDR_DATA_TABLE_ENTRY Module;
+ PLIST_ENTRY Entry;
+ KIRQL Irql;
+
+ DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
+
+ KeAcquireSpinLock(&ModuleListLock,&Irql);
+
+ Entry = PsLoadedModuleList.Flink;
+ while (Entry != &PsLoadedModuleList)
+ {
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+
+ DPRINT("Comparing %wZ and %wZ\n",
+ &Module->BaseDllName,
+ ModuleName);
+
+ if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
{
- PathLength = (PathEnd - ModuleName + 1) * sizeof(WCHAR);
- RtlCopyMemory(NameBuffer, ModuleName, PathLength);
- RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer,
DriverName.Length);
- NameString.Buffer = NameBuffer;
- NameString.MaximumLength = NameString.Length = (USHORT)PathLength +
DriverName.Length;
-
- /* NULL-terminate */
- NameString.MaximumLength += sizeof(WCHAR);
- NameBuffer[NameString.Length / sizeof(WCHAR)] = 0;
-
- Status = LdrLoadModule(&NameString, ImportedModule);
+ DPRINT("Module %wZ\n", &Module->BaseDllName);
+ KeReleaseSpinLock(&ModuleListLock, Irql);
+ return(Module);
}
- else
- {
- DPRINT("Module '%wZ' not loaded yet\n", &DriverName);
- wcscpy(NameBuffer, L"\\SystemRoot\\system32\\drivers\\");
- wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
- RtlInitUnicodeString(&NameString, NameBuffer);
- Status = LdrLoadModule(&NameString, ImportedModule);
- }
- if (!NT_SUCCESS(Status))
- {
- wcscpy(NameBuffer, L"\\SystemRoot\\system32\\");
- wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
- RtlInitUnicodeString(&NameString, NameBuffer);
- Status = LdrLoadModule(&NameString, ImportedModule);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unknown import module: %wZ (Status %lx)\n",
&DriverName, Status);
- }
- }
- }
- RtlFreeUnicodeString(&DriverName);
- return Status;
+
+ Entry = Entry->Flink;
+ }
+
+ KeReleaseSpinLock(&ModuleListLock, Irql);
+
+ DPRINT("Could not find module '%wZ'\n", ModuleName);
+
+ return(NULL);
}
-static PVOID
-LdrPEFixupForward ( PCHAR ForwardName )
-{
- CHAR NameBuffer[128];
- UNICODE_STRING ModuleName;
- PCHAR p;
- PLDR_DATA_TABLE_ENTRY ModuleObject;
-
- DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
-
- strcpy(NameBuffer, ForwardName);
- p = strchr(NameBuffer, '.');
- if (p == NULL)
- {
- return NULL;
- }
-
- *p = 0;
-
- DPRINT("Driver: %s Function: %s\n", NameBuffer, p+1);
-
- RtlCreateUnicodeStringFromAsciiz(&ModuleName,
- NameBuffer);
- ModuleObject = LdrGetModuleObject(&ModuleName);
- RtlFreeUnicodeString(&ModuleName);
-
- DPRINT("ModuleObject: %p\n", ModuleObject);
-
- if (ModuleObject == NULL)
- {
- DPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
- return NULL;
- }
- return LdrPEGetExportByName(ModuleObject->DllBase, (PUCHAR)(p+1), 0xffff);
-}
-
-static PVOID
-LdrPEGetExportByOrdinal (
- PVOID BaseAddress,
- ULONG Ordinal )
-{
- PIMAGE_EXPORT_DIRECTORY ExportDir;
- ULONG ExportDirSize;
- PULONG * ExFunctions;
- PVOID Function;
-
- ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData (
- BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportDirSize);
-
- ExFunctions = (PULONG *)RVA(BaseAddress,
- ExportDir->AddressOfFunctions);
- DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n",
- Ordinal,
- RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base]));
-
- Function = 0 != ExFunctions[Ordinal - ExportDir->Base]
- ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
- : NULL;
-
- if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
- ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize))
- {
- DPRINT("Forward: %s\n", (PCHAR)Function);
- Function = LdrPEFixupForward((PCHAR)Function);
- }
-
- return Function;
-}
-
-static PVOID
-LdrPEGetExportByName (
- PVOID BaseAddress,
- PUCHAR SymbolName,
- USHORT Hint )
-{
- PIMAGE_EXPORT_DIRECTORY ExportDir;
- PULONG * ExFunctions;
- PULONG * ExNames;
- USHORT * ExOrdinals;
- PVOID ExName;
- ULONG Ordinal;
- PVOID Function;
- LONG minn, maxn, mid, res;
- ULONG ExportDirSize;
-
- DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
-
- ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportDirSize);
- if (ExportDir == NULL)
- {
- DPRINT1("LdrPEGetExportByName(): no export directory!\n");
- return NULL;
- }
-
-
- /* The symbol names may be missing entirely */
- if (ExportDir->AddressOfNames == 0)
- {
- DPRINT("LdrPEGetExportByName(): symbol names missing entirely\n");
- return NULL;
- }
-
- /*
- * Get header pointers
- */
- ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
- ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
- ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
-
- /*
- * Check the hint first
- */
- if (Hint < ExportDir->NumberOfNames)
- {
- ExName = RVA(BaseAddress, ExNames[Hint]);
- if (strcmp(ExName, (PCHAR)SymbolName) == 0)
- {
- Ordinal = ExOrdinals[Hint];
- Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
- (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
- {
- DPRINT("Forward: %s\n", (PCHAR)Function);
- Function = LdrPEFixupForward((PCHAR)Function);
- if (Function == NULL)
- {
- DPRINT1("LdrPEGetExportByName(): failed to find
%s\n",SymbolName);
- }
- return Function;
- }
- if (Function != NULL)
- {
- return Function;
- }
- }
- }
-
- /*
- * Binary search
- */
- minn = 0;
- maxn = ExportDir->NumberOfNames - 1;
- while (minn <= maxn)
- {
- mid = (minn + maxn) / 2;
-
- ExName = RVA(BaseAddress, ExNames[mid]);
- res = strcmp(ExName, (PCHAR)SymbolName);
- if (res == 0)
- {
- Ordinal = ExOrdinals[mid];
- Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
- (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
- {
- DPRINT("Forward: %s\n", (PCHAR)Function);
- Function = LdrPEFixupForward((PCHAR)Function);
- if (Function == NULL)
- {
- DPRINT1("LdrPEGetExportByName(): failed to find
%s\n",SymbolName);
- }
- return Function;
- }
- if (Function != NULL)
- {
- return Function;
- }
- }
- else if (res > 0)
- {
- maxn = mid - 1;
- }
- else
- {
- minn = mid + 1;
- }
- }
-
- ExName = RVA(BaseAddress, ExNames[mid]);
- DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
- return (PVOID)NULL;
-}
-
-static NTSTATUS
-LdrPEProcessImportDirectoryEntry(
- PVOID DriverBase,
- PLDR_DATA_TABLE_ENTRY ImportedModule,
- PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory )
-{
- PVOID* ImportAddressList;
- PULONG FunctionNameList;
- ULONG Ordinal;
-
- if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Get the import address list. */
- ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
-
- /* Get the list of functions to import. */
- if (ImportModuleDirectory->OriginalFirstThunk != 0)
- {
- FunctionNameList = (PULONG)RVA(DriverBase,
ImportModuleDirectory->OriginalFirstThunk);
- }
- else
- {
- FunctionNameList = (PULONG)RVA(DriverBase,
ImportModuleDirectory->FirstThunk);
- }
-
- /* Walk through function list and fixup addresses. */
- while (*FunctionNameList != 0L)
- {
- if ((*FunctionNameList) & 0x80000000)
- {
- Ordinal = (*FunctionNameList) & 0x7fffffff;
- *ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->DllBase,
Ordinal);
- if ((*ImportAddressList) == NULL)
- {
- DPRINT1("Failed to import #%ld from %wZ\n", Ordinal,
&ImportedModule->FullDllName);
- return STATUS_UNSUCCESSFUL;
- }
- }
- else
- {
- IMAGE_IMPORT_BY_NAME *pe_name;
- pe_name = RVA(DriverBase, *FunctionNameList);
- *ImportAddressList = LdrPEGetExportByName(ImportedModule->DllBase,
pe_name->Name, pe_name->Hint);
- if ((*ImportAddressList) == NULL)
- {
- DPRINT1("Failed to import %s from %wZ\n", pe_name->Name,
&ImportedModule->FullDllName);
- return STATUS_UNSUCCESSFUL;
- }
- }
- ImportAddressList++;
- FunctionNameList++;
- }
- return STATUS_SUCCESS;
-}
-
-typedef struct _LOAD_IMPORTS
-{
- SIZE_T Count;
- PLDR_DATA_TABLE_ENTRY Entry[1];
-} LOAD_IMPORTS, *PLOAD_IMPORTS;
-
+//
+// Used when unloading drivers
+//
NTSTATUS
NTAPI
-MiResolveImageReferences(IN PVOID ImageBase,
- IN PUNICODE_STRING ImageFileDirectory,
- IN PUNICODE_STRING NamePrefix OPTIONAL,
- OUT PCHAR *MissingApi,
- OUT PWCHAR *MissingDriver,
- OUT PLOAD_IMPORTS *LoadImports)
+LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
{
- /* We don't do anything for now */
- return STATUS_SUCCESS;
+ KIRQL Irql;
+
+ /* Remove the module from the module list */
+ KeAcquireSpinLock(&ModuleListLock,&Irql);
+ RemoveEntryList(&ModuleObject->InLoadOrderLinks);
+ KeReleaseSpinLock(&ModuleListLock, Irql);
+
+ /* Hook for KDB on unloading a driver. */
+ KDB_UNLOADDRIVER_HOOK(ModuleObject);
+
+ /* Free module section */
+ // MmFreeSection(ModuleObject->DllBase);
+
+ ExFreePool(ModuleObject->FullDllName.Buffer);
+ ExFreePool(ModuleObject);
+
+ return(STATUS_SUCCESS);
}
-static NTSTATUS
-LdrPEFixupImports (IN PVOID DllBase,
- IN PWCHAR DllName)
-{
- PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
- PCHAR ImportedName;
- PLDR_DATA_TABLE_ENTRY ImportedModule;
- NTSTATUS Status;
- ULONG Size;
-
- /* Process each import module */
- ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(DllBase,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- &Size);
- DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
- while (ImportModuleDirectory->Name)
- {
- /* Check to make sure that import lib is kernel */
- ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
-
- Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule,
ImportModuleDirectory);
- if (!NT_SUCCESS(Status))
- {
- while (TRUE);
- return Status;
- }
-
- ImportModuleDirectory++;
- }
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-LdrPEProcessModule(
- PVOID ModuleLoadBase,
- PUNICODE_STRING FileName,
- PLDR_DATA_TABLE_ENTRY *ModuleObject )
+//
+// Used for images already loaded (boot drivers)
+//
+NTSTATUS
+LdrProcessModule(PVOID ModuleLoadBase,
+ PUNICODE_STRING FileName,
+ PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
unsigned int DriverSize, Idx;
ULONG CurrentSize;
@@ -641,7 +366,7 @@
BaseLength *= sizeof(WCHAR);
/* Setup the string */
- BaseName.Length = BaseLength;
+ BaseName.Length = (USHORT)BaseLength;
BaseName.Buffer = p;
}
else
@@ -698,7 +423,7 @@
NtHeader->OptionalHeader.AddressOfEntryPoint);
LdrEntry->SizeOfImage = DriverSize;
LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
- LdrEntry->SectionPointer = NULL; // FIXME
+ LdrEntry->SectionPointer = LdrEntry;
/* Now write the DLL name */
LdrEntry->BaseDllName.Buffer = NameBuffer;
@@ -737,7 +462,7 @@
/* Insert the entry */
KeAcquireSpinLock(&ModuleListLock, &Irql);
- InsertTailList(&ModuleListHead, &LdrEntry->InLoadOrderLinks);
+ InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
/* Resolve imports */
@@ -748,10 +473,6 @@
&MissingApiName,
&MissingDriverName,
&LoadedImports);
-
- /* Resolve imports */
- Status = LdrPEFixupImports(LdrEntry->DllBase,
- LdrEntry->FullDllName.Buffer);
if (!NT_SUCCESS(Status))
{
/* Fail */
@@ -763,145 +484,6 @@
/* Return */
*ModuleObject = LdrEntry;
return STATUS_SUCCESS;
-}
-
-VOID
-INIT_FUNCTION
-NTAPI
-LdrInit1(VOID)
-{
- PLDR_DATA_TABLE_ENTRY HalModuleObject, NtoskrnlModuleObject, LdrEntry;
-
- /* Initialize the module list and spinlock */
- InitializeListHead(&ModuleListHead);
- KeInitializeSpinLock(&ModuleListLock);
-
- /* Get the NTOSKRNL Entry from the loader */
- LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink,
LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
- /* Initialize ModuleObject for NTOSKRNL */
- NtoskrnlModuleObject = ExAllocatePoolWithTag(PagedPool,
- sizeof(LDR_DATA_TABLE_ENTRY),
- TAG('M', 'm',
'L', 'd'));
- NtoskrnlModuleObject->DllBase = LdrEntry->DllBase;
- RtlInitUnicodeString(&NtoskrnlModuleObject->FullDllName, KERNEL_MODULE_NAME);
- LdrpBuildModuleBaseName(&NtoskrnlModuleObject->BaseDllName,
&NtoskrnlModuleObject->FullDllName);
- NtoskrnlModuleObject->EntryPoint = LdrEntry->EntryPoint;
- NtoskrnlModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
-
- /* Insert it into the list */
- InsertTailList(&ModuleListHead, &NtoskrnlModuleObject->InLoadOrderLinks);
-
- /* Get the HAL Entry from the loader */
- LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink->Flink,
LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
- /* Initialize ModuleObject for HAL */
- HalModuleObject = ExAllocatePoolWithTag(PagedPool,
- sizeof(LDR_DATA_TABLE_ENTRY),
- TAG('M', 'm',
'L', 'd'));
- HalModuleObject->DllBase = LdrEntry->DllBase;
- RtlInitUnicodeString(&HalModuleObject->FullDllName, HAL_MODULE_NAME);
- LdrpBuildModuleBaseName(&HalModuleObject->BaseDllName,
&HalModuleObject->FullDllName);
- HalModuleObject->EntryPoint = LdrEntry->EntryPoint;
- HalModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
-
- /* Insert it into the list */
- InsertTailList(&ModuleListHead, &HalModuleObject->InLoadOrderLinks);
-
- /* Hook for KDB on initialization of the loader. */
- KDB_LOADERINIT_HOOK(NtoskrnlModuleObject, HalModuleObject);
-}
-
-//
-// Used for checking if a module is already in the module list.
-// Used during loading/unloading drivers.
-//
-PLDR_DATA_TABLE_ENTRY
-NTAPI
-LdrGetModuleObject ( PUNICODE_STRING ModuleName )
-{
- PLDR_DATA_TABLE_ENTRY Module;
- PLIST_ENTRY Entry;
- KIRQL Irql;
-
- DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
-
- KeAcquireSpinLock(&ModuleListLock,&Irql);
-
- Entry = ModuleListHead.Flink;
- while (Entry != &ModuleListHead)
- {
- Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
-
- DPRINT("Comparing %wZ and %wZ\n",
- &Module->BaseDllName,
- ModuleName);
-
- if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
- {
- DPRINT("Module %wZ\n", &Module->BaseDllName);
- KeReleaseSpinLock(&ModuleListLock, Irql);
- return(Module);
- }
-
- Entry = Entry->Flink;
- }
-
- KeReleaseSpinLock(&ModuleListLock, Irql);
-
- DPRINT("Could not find module '%wZ'\n", ModuleName);
-
- return(NULL);
-}
-
-//
-// Used when unloading drivers
-//
-NTSTATUS
-NTAPI
-LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
-{
- KIRQL Irql;
-
- /* Remove the module from the module list */
- KeAcquireSpinLock(&ModuleListLock,&Irql);
- RemoveEntryList(&ModuleObject->InLoadOrderLinks);
- KeReleaseSpinLock(&ModuleListLock, Irql);
-
- /* Hook for KDB on unloading a driver. */
- KDB_UNLOADDRIVER_HOOK(ModuleObject);
-
- /* Free module section */
- // MmFreeSection(ModuleObject->DllBase);
-
- ExFreePool(ModuleObject->FullDllName.Buffer);
- ExFreePool(ModuleObject);
-
- return(STATUS_SUCCESS);
-}
-
-//
-// Used for images already loaded (boot drivers)
-//
-NTSTATUS
-LdrProcessModule(
- PVOID ModuleLoadBase,
- PUNICODE_STRING ModuleName,
- PLDR_DATA_TABLE_ENTRY *ModuleObject )
-{
- PIMAGE_DOS_HEADER PEDosHeader;
-
- /* If MZ header exists */
- PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
- if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE &&
PEDosHeader->e_lfanew != 0L)
- {
- return LdrPEProcessModule(ModuleLoadBase,
- ModuleName,
- ModuleObject);
- }
-
- DPRINT("Module wasn't PE\n");
- return STATUS_UNSUCCESSFUL;
}
//
Modified: trunk/reactos/ntoskrnl/mm/mm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mm.c?rev=25872…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mm.c (original)
+++ trunk/reactos/ntoskrnl/mm/mm.c Thu Feb 22 03:01:52 2007
@@ -409,7 +409,7 @@
ANSI_STRING AnsiRoutineName;
NTSTATUS Status;
PLIST_ENTRY NextEntry;
- extern LIST_ENTRY ModuleListHead;
+ extern LIST_ENTRY PsLoadedModuleList;
PLDR_DATA_TABLE_ENTRY LdrEntry;
BOOLEAN Found = FALSE;
UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
@@ -422,8 +422,8 @@
if (!NT_SUCCESS(Status)) return NULL;
/* Loop the loaded module list */
- NextEntry = ModuleListHead.Flink;
- while (NextEntry != &ModuleListHead)
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
{
/* Get the entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
Added: trunk/reactos/ntoskrnl/mm/sysldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/sysldr.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/sysldr.c (added)
+++ trunk/reactos/ntoskrnl/mm/sysldr.c Thu Feb 22 03:01:52 2007
@@ -1,0 +1,586 @@
+/*
+* PROJECT: ReactOS Kernel
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: ntoskrnl/mm/sysldr.c
+* PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files.
+* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+*/
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+MiSnapThunk(IN PVOID DllBase,
+ IN PVOID ImageBase,
+ IN PIMAGE_THUNK_DATA Name,
+ IN PIMAGE_THUNK_DATA Address,
+ IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
+ IN ULONG ExportSize,
+ IN BOOLEAN SnapForwarder,
+ OUT PCHAR *MissingApi)
+{
+ BOOLEAN IsOrdinal;
+ USHORT Ordinal;
+ PULONG NameTable;
+ PUSHORT OrdinalTable;
+ PIMAGE_IMPORT_BY_NAME NameImport;
+ USHORT Hint;
+ ULONG Low = 0, Mid = 0, High;
+ LONG Ret;
+ NTSTATUS Status;
+ PCHAR MissingForwarder;
+ CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
+ PULONG ExportTable;
+ ANSI_STRING DllName;
+ UNICODE_STRING ForwarderName;
+ PLIST_ENTRY NextEntry;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ ULONG ForwardExportSize;
+ PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
+ PIMAGE_IMPORT_BY_NAME ForwardName;
+ ULONG ForwardLength;
+ IMAGE_THUNK_DATA ForwardThunk;
+ PAGED_CODE();
+
+ /* Check if this is an ordinal */
+ IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
+ if ((IsOrdinal) && !(SnapForwarder))
+ {
+ /* Get the ordinal number and set it as missing */
+ Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
+ ExportDirectory->Base);
+ *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
+ }
+ else
+ {
+ /* Get the VA if we don't have to snap */
+ if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
+ NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
+
+ /* Copy the procedure name */
+ strncpy(*MissingApi,
+ (PCHAR)&NameImport->Name[0],
+ MAXIMUM_FILENAME_LENGTH - 1);
+
+ /* Setup name tables */
+ DPRINT("Import name: %s\n", NameImport->Name);
+ NameTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNames);
+ OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNameOrdinals);
+
+ /* Get the hint and check if it's valid */
+ Hint = NameImport->Hint;
+ if ((Hint < ExportDirectory->NumberOfNames) &&
+ !(strcmp(NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
+ {
+ /* We have a match, get the ordinal number from here */
+ Ordinal = OrdinalTable[Hint];
+ }
+ else
+ {
+ /* Do a binary search */
+ High = ExportDirectory->NumberOfNames - 1;
+ while (High >= Low)
+ {
+ /* Get new middle value */
+ Mid = (Low + High) >> 1;
+
+ /* Compare name */
+ Ret = strcmp(NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
+ if (Ret < 0)
+ {
+ /* Update high */
+ High = Mid - 1;
+ }
+ else if (Ret > 0)
+ {
+ /* Update low */
+ Low = Mid + 1;
+ }
+ else
+ {
+ /* We got it */
+ break;
+ }
+ }
+
+ /* Check if we couldn't find it */
+ if (High < Low) return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+
+ /* Otherwise, this is the ordinal */
+ Ordinal = OrdinalTable[Mid];
+ }
+ }
+
+ /* Check if the ordinal is invalid */
+ if (Ordinal >= ExportDirectory->NumberOfFunctions)
+ {
+ /* Fail */
+ Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
+ }
+ else
+ {
+ /* In case the forwarder is missing */
+ MissingForwarder = NameBuffer;
+
+ /* Resolve the address and write it */
+ ExportTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfFunctions);
+ Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
+
+ /* Assume success from now on */
+ Status = STATUS_SUCCESS;
+
+ /* Check if the function is actually a forwarder */
+ if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
+ (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
+ {
+ /* Now assume failure in case the forwarder doesn't exist */
+ Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+
+ /* Build the forwarder name */
+ DllName.Buffer = (PCHAR)Address->u1.Function;
+ DllName.Length = strchr(DllName.Buffer, '.') -
+ DllName.Buffer +
+ sizeof(ANSI_NULL);
+ DllName.MaximumLength = DllName.Length;
+
+ /* Convert it */
+ if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
+ &DllName,
+ TRUE)))
+ {
+ /* We failed, just return an error */
+ return Status;
+ }
+
+ /* Loop the module list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the loader entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Check if it matches */
+ if (RtlPrefixString((PSTRING)&ForwarderName,
+ (PSTRING)&LdrEntry->BaseDllName,
+ TRUE))
+ {
+ /* Get the forwarder export directory */
+ ForwardExportDirectory =
+ RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ForwardExportSize);
+ if (!ForwardExportDirectory) break;
+
+ /* Allocate a name entry */
+ ForwardLength = strlen(DllName.Buffer + DllName.Length) +
+ sizeof(ANSI_NULL);
+ ForwardName = ExAllocatePoolWithTag(PagedPool,
+ sizeof(*ForwardName) +
+ ForwardLength,
+ TAG_LDR_WSTR);
+ if (!ForwardName) break;
+
+ /* Copy the data */
+ RtlCopyMemory(&ForwardName->Name[0],
+ DllName.Buffer + DllName.Length,
+ ForwardLength);
+ ForwardName->Hint = 0;
+
+ /* Set the new address */
+ *(PULONG)&ForwardThunk.u1.AddressOfData = (ULONG)ForwardName;
+
+ /* Snap the forwarder */
+ Status = MiSnapThunk(LdrEntry->DllBase,
+ ImageBase,
+ &ForwardThunk,
+ &ForwardThunk,
+ ForwardExportDirectory,
+ ForwardExportSize,
+ TRUE,
+ &MissingForwarder);
+
+ /* Free the forwarder name and set the thunk */
+ ExFreePool(ForwardName);
+ Address->u1 = ForwardThunk.u1;
+ break;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Free the name */
+ RtlFreeUnicodeString(&ForwarderName);
+ }
+ }
+
+ /* Return status */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+MiResolveImageReferences(IN PVOID ImageBase,
+ IN PUNICODE_STRING ImageFileDirectory,
+ IN PUNICODE_STRING NamePrefix OPTIONAL,
+ OUT PCHAR *MissingApi,
+ OUT PWCHAR *MissingDriver,
+ OUT PLOAD_IMPORTS *LoadImports)
+{
+ PCHAR MissingApiBuffer = *MissingApi, ImportName;
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
+ ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
+ PLOAD_IMPORTS LoadedImports;
+ ULONG GdiLink, NormalLink, i;
+ BOOLEAN ReferenceNeeded, Loaded;
+ ANSI_STRING TempString;
+ UNICODE_STRING NameString, DllName;
+ PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
+ PVOID ImportBase, DllBase;
+ PLIST_ENTRY NextEntry;
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ NTSTATUS Status;
+ PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
+ PAGED_CODE();
+ DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
+ __FUNCTION__, ImageBase, ImageFileDirectory);
+
+ /* Assume no imports */
+ *LoadImports = (PVOID)-2;
+
+ /* Get the import descriptor */
+ ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ &ImportSize);
+ if (!ImportDescriptor) return STATUS_SUCCESS;
+
+ /* Loop all imports to count them */
+ for (CurrentImport = ImportDescriptor;
+ (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
+ CurrentImport++)
+ {
+ /* One more */
+ ImportCount++;
+ }
+
+ /* Make sure we have non-zero imports */
+ if (ImportCount)
+ {
+ /* Calculate and allocate the list we'll need */
+ LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
+ LoadedImports = ExAllocatePoolWithTag(PagedPool,
+ LoadedImportsSize,
+ TAG_LDR_WSTR);
+ if (LoadedImports)
+ {
+ /* Zero it and set the count */
+ RtlZeroMemory(LoadedImports, LoadedImportsSize);
+ LoadedImports->Count = ImportCount;
+ }
+ }
+ else
+ {
+ /* No table */
+ LoadedImports = NULL;
+ }
+
+ /* Reset the import count and loop descriptors again */
+ ImportCount = GdiLink = NormalLink = 0;
+ while ((ImportDescriptor->Name) &&
(ImportDescriptor->OriginalFirstThunk))
+ {
+ /* Get the name */
+ ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
+
+ /* Check if this is a GDI driver */
+ GdiLink = GdiLink |
+ !(_strnicmp(ImportName, "win32k", sizeof("win32k")
- 1));
+
+ /* We can also allow dxapi */
+ NormalLink = NormalLink |
+ ((_strnicmp(ImportName, "win32k",
sizeof("win32k") - 1)) &&
+ (_strnicmp(ImportName, "dxapi", sizeof("dxapi")
- 1)));
+
+ /* Check if this is a valid GDI driver */
+ if ((GdiLink) && (NormalLink))
+ {
+ /* It's not, it's importing stuff it shouldn't be! */
+ DPRINT1("Invalid driver!\n");
+ //MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return STATUS_PROCEDURE_NOT_FOUND;
+ }
+
+ /* Check if this is a "core" import, which doesn't get referenced
*/
+ if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") -
1)) ||
+ !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1))
||
+ !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
+ {
+ /* Don't reference this */
+ ReferenceNeeded = FALSE;
+ }
+ else
+ {
+ /* Reference these modules */
+ ReferenceNeeded = TRUE;
+ }
+
+ /* Now setup a unicode string for the import */
+ RtlInitAnsiString(&TempString, ImportName);
+ Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ //MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return Status;
+ }
+
+ /* We don't support name prefixes yet */
+ if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
+
+ /* Remember that we haven't loaded the import at this point */
+CheckDllState:
+ Loaded = FALSE;
+ ImportBase = NULL;
+
+ /* Loop the driver list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the loader entry and compare the name */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ if (RtlEqualUnicodeString(&NameString,
+ &LdrEntry->BaseDllName,
+ TRUE))
+ {
+ /* Get the base address */
+ ImportBase = LdrEntry->DllBase;
+
+ /* Check if we haven't loaded yet, and we need references */
+ if (!(Loaded) && (ReferenceNeeded))
+ {
+ /* Make sure we're not already loading */
+ if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
+ {
+ /* Increase the load count */
+ LdrEntry->LoadCount++;
+ }
+ }
+
+ /* Done, break out */
+ break;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Check if we haven't loaded the import yet */
+ if (!ImportBase)
+ {
+ /* Setup the import DLL name */
+ DllName.MaximumLength = NameString.Length +
+ ImageFileDirectory->Length +
+ sizeof(UNICODE_NULL);
+ DllName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ DllName.MaximumLength,
+ TAG_LDR_WSTR);
+ if (DllName.Buffer)
+ {
+ /* Setup the base length and copy it */
+ DllName.Length = ImageFileDirectory->Length;
+ RtlCopyMemory(DllName.Buffer,
+ ImageFileDirectory->Buffer,
+ ImageFileDirectory->Length);
+
+ /* Now add the import name and null-terminate it */
+ RtlAppendStringToString((PSTRING)&DllName,
+ (PSTRING)&NameString);
+ DllName.Buffer[(DllName.MaximumLength - 1) / 2] = UNICODE_NULL;
+
+ /* Load the image */
+ Status = LdrLoadModule(&DllName, &DllEntry);
+ if (NT_SUCCESS(Status))
+ {
+ /* We can free the DLL Name */
+ ExFreePool(DllName.Buffer);
+ }
+ else
+ {
+ /* Fill out the information for the error */
+ DPRINT1("Failed to import: %S\n", DllName.Buffer);
+ *MissingDriver = DllName.Buffer;
+ *(PULONG)MissingDriver |= 1;
+ *MissingApi = NULL;
+ }
+ }
+ else
+ {
+ /* We're out of resources */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Check if we're OK until now */
+ if (NT_SUCCESS(Status))
+ {
+ /* We're now loaded */
+ Loaded = TRUE;
+
+ /* Get the base address and other information */
+ DllBase = DllEntry->DllBase;
+ ASSERT(DllBase = DllEntry->DllBase);
+
+ /* Call the initialization routines */
+#if 0
+ Status = MmCallDllInitialize(DllEntry, &PsLoadedModuleList);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, unload the image */
+ MmUnloadSystemImage(DllEntry);
+ while (TRUE);
+ Loaded = FALSE;
+ }
+#endif
+ }
+
+ /* Check if we failed by here */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Cleanup and return */
+ DPRINT1("Failed loading import\n");
+ RtlFreeUnicodeString(&NameString);
+ //MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return Status;
+ }
+
+ /* Loop again to make sure that everything is OK */
+ goto CheckDllState;
+ }
+
+ /* Check if we're support to reference this import */
+ if ((ReferenceNeeded) && (LoadedImports))
+ {
+ /* Make sure we're not already loading */
+ if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
+ {
+ /* Add the entry */
+ LoadedImports->Entry[ImportCount] = LdrEntry;
+ ImportCount++;
+ }
+ }
+
+ /* Free the import name */
+ RtlFreeUnicodeString(&NameString);
+
+ /* Set the missing driver name and get the export directory */
+ *MissingDriver = LdrEntry->BaseDllName.Buffer;
+ ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!ExportDirectory)
+ {
+ /* Cleanup and return */
+ DPRINT1("Invalid driver: %wZ\n", &LdrEntry->BaseDllName);
+ //MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+ }
+
+ /* Make sure we have an IAT */
+ if (ImportDescriptor->OriginalFirstThunk)
+ {
+ /* Get the first thunks */
+ OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
+ ImportDescriptor->OriginalFirstThunk);
+ FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
+ ImportDescriptor->FirstThunk);
+
+ /* Loop the IAT */
+ while (OrigThunk->u1.AddressOfData)
+ {
+ /* Snap thunk */
+ Status = MiSnapThunk(ImportBase,
+ ImageBase,
+ OrigThunk++,
+ FirstThunk++,
+ ExportDirectory,
+ ExportSize,
+ FALSE,
+ MissingApi);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Cleanup and return */
+ //MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return Status;
+ }
+
+ /* Reset the buffer */
+ *MissingApi = MissingApiBuffer;
+ }
+ }
+
+ /* Go to the next import */
+ ImportDescriptor++;
+ }
+
+ /* Check if we have an import list */
+ if (LoadedImports)
+ {
+ /* Reset the count again, and loop entries*/
+ ImportCount = 0;
+ for (i = 0; i < LoadedImports->Count; i++)
+ {
+ if (LoadedImports->Entry[i])
+ {
+ /* Got an entry, OR it with 1 in case it's the single entry */
+ ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] | 1);
+ ImportCount++;
+ }
+ }
+
+ /* Check if we had no imports */
+ if (!ImportCount)
+ {
+ /* Free the list and set it to no imports */
+ ExFreePool(LoadedImports);
+ LoadedImports = (PVOID)-2;
+ }
+ else if (ImportCount == 1)
+ {
+ /* Just one entry, we can free the table and only use our entry */
+ ExFreePool(LoadedImports);
+ LoadedImports = (PLOAD_IMPORTS)ImportEntry;
+ }
+ else if (ImportCount != LoadedImports->Count)
+ {
+ /* FIXME: Can this happen? */
+ DPRINT1("Unhandled scenario\n");
+ while (TRUE);
+ }
+
+ /* Return the list */
+ *LoadImports = LoadedImports;
+ }
+
+ /* Return success */
+ return STATUS_SUCCESS;
+}
+
Modified: trunk/reactos/ntoskrnl/mm/verifier.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/verifier.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/verifier.c (original)
+++ trunk/reactos/ntoskrnl/mm/verifier.c Thu Feb 22 03:01:52 2007
@@ -19,7 +19,7 @@
KMUTANT MmSystemLoadLock;
ULONG MiActiveVerifierThunks;
-extern LIST_ENTRY ModuleListHead;
+extern LIST_ENTRY PsLoadedModuleList;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -32,7 +32,7 @@
PAGED_CODE();
/* Loop entries */
- NextEntry = ModuleListHead.Flink;
+ NextEntry = PsLoadedModuleList.Flink;
do
{
/* Get the loader entry */
@@ -51,7 +51,7 @@
/* Move on */
NextEntry = NextEntry->Flink;
- } while(NextEntry != &ModuleListHead);
+ } while(NextEntry != &PsLoadedModuleList);
/* Return the entry */
return FoundEntry;
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Thu Feb 22 03:01:52 2007
@@ -275,6 +275,7 @@
<file>region.c</file>
<file>rmap.c</file>
<file>section.c</file>
+ <file>sysldr.c</file>
<file>verifier.c</file>
<file>virtual.c</file>
<file>wset.c</file>