*** empty log message ***

svn path=/trunk/; revision=966
This commit is contained in:
Jason Filby 2000-01-26 21:10:16 +00:00
parent d24a48cd94
commit 980d94c760

View file

@ -1,4 +1,4 @@
/* $Id: loader.c,v 1.42 2000/01/12 19:03:27 ekohl Exp $ /* $Id: loader.c,v 1.43 2000/01/26 21:10:16 jfilby Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -6,13 +6,15 @@
* PURPOSE: Loaders for PE executables * PURPOSE: Loaders for PE executables
* PROGRAMMERS: Jean Michault * PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com) * Rex Jolliff (rex@lvcablemodem.com)
* Jason Filby (jasonfilby@yahoo.com)
* UPDATE HISTORY: * UPDATE HISTORY:
* DW 22/05/98 Created * DW 22/05/98 Created
* RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE * RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE
* RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF * RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF
* RJJ 10/12/98 Rolled in David's code to load COFF drivers * RJJ 10/12/98 Rolled in David's code to load COFF drivers
* JM 14/12/98 Built initial PE user module loader * JM 14/12/98 Built initial PE user module loader
* RJJ 06/03/99 Moved user PE loader into NTDLL * RJJ 06/03/99 Moved user PE loader into NTDLL
* JF 26/01/2000 Recoded some parts to retrieve export details correctly
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -174,7 +176,7 @@ static VOID LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName)
NTSTATUS Status; NTSTATUS Status;
UNICODE_STRING DriverName; UNICODE_STRING DriverName;
DbgPrint("Loading %S\n",RelativeDriverName); DbgPrint("Loading %w\n",RelativeDriverName);
LdrGetSystemDirectory(TmpFileName, (MAX_PATH * sizeof(WCHAR))); LdrGetSystemDirectory(TmpFileName, (MAX_PATH * sizeof(WCHAR)));
wcscat(TmpFileName, L"\\drivers\\"); wcscat(TmpFileName, L"\\drivers\\");
@ -209,11 +211,11 @@ LdrLoadAutoConfigDrivers (VOID)
/* /*
* VideoPort driver * VideoPort driver
*/ */
// LdrLoadAutoConfigDriver( L"vidport.sys" ); LdrLoadAutoConfigDriver( L"vidport.sys" );
/* /*
* VGA Miniport driver * VGA Miniport driver
*/ */
// LdrLoadAutoConfigDriver( L"vgamp.sys" ); LdrLoadAutoConfigDriver( L"vgamp.sys" );
} }
@ -318,6 +320,7 @@ LdrLoadModule(PUNICODE_STRING Filename)
/* Allocate nonpageable memory for driver */ /* Allocate nonpageable memory for driver */
ModuleLoadBase = ExAllocatePool(NonPagedPool, ModuleLoadBase = ExAllocatePool(NonPagedPool,
FileStdInfo.EndOfFile.u.LowPart); FileStdInfo.EndOfFile.u.LowPart);
if (ModuleLoadBase == NULL) if (ModuleLoadBase == NULL)
{ {
DbgPrint("could not allocate memory for module"); DbgPrint("could not allocate memory for module");
@ -462,6 +465,8 @@ LdrGetExportAddress(PMODULE_OBJECT ModuleObject,
/* ---------------------------------------------- PE Module support */ /* ---------------------------------------------- PE Module support */
typedef char *PSTR;
PMODULE_OBJECT PMODULE_OBJECT
LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName) LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
{ {
@ -553,32 +558,38 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
DPRINT1("Module is at base %x\n",DriverBase); DPRINT1("Module is at base %x\n",DriverBase);
/* Copy image sections into virtual section */ /* Copy image sections into virtual section */
// memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData); memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData);
// CurrentBase = (PVOID) ((DWORD)DriverBase + PESectionHeaders[0].PointerToRawData); // CurrentBase = (PVOID) ((DWORD)DriverBase + PESectionHeaders[0].PointerToRawData);
CurrentSize = 0; CurrentSize = 0;
memcpy(DriverBase, ModuleLoadBase, DriverSize);
for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++) for (Idx = 0; Idx < PEFileHeader->NumberOfSections; Idx++)
{ {
/* Copy current section into current offset of virtual section */ // Copy current section into current offset of virtual section
if (PESectionHeaders[Idx].Characteristics & if (PESectionHeaders[Idx].Characteristics &
(IMAGE_SECTION_CHAR_CODE | IMAGE_SECTION_CHAR_DATA)) (IMAGE_SECTION_CHAR_CODE | IMAGE_SECTION_CHAR_DATA))
{ {
DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n", DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
PESectionHeaders[Idx].VirtualAddress + DriverBase); PESectionHeaders[Idx].VirtualAddress + DriverBase);
memcpy(PESectionHeaders[Idx].VirtualAddress + DriverBase, memcpy(PESectionHeaders[Idx].VirtualAddress + DriverBase,
(PVOID)(ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData), (PVOID)(ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData),
PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/); PESectionHeaders[Idx].Misc.VirtualSize);
} }
else else
{ {
DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n", DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
PESectionHeaders[Idx].VirtualAddress + DriverBase); PESectionHeaders[Idx].VirtualAddress + DriverBase);
memset(PESectionHeaders[Idx].VirtualAddress + DriverBase, memset(PESectionHeaders[Idx].VirtualAddress + DriverBase,
'\0', PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/); '\0', PESectionHeaders[Idx].Misc.VirtualSize);
} }
CurrentSize += ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/, CurrentSize += ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize,
PEOptionalHeader->SectionAlignment); PEOptionalHeader->SectionAlignment);
// CurrentBase = (PVOID)((DWORD)CurrentBase + // CurrentBase = (PVOID)((DWORD)CurrentBase +
// ROUND_UP(PESectionHeaders[Idx].Misc.VirtualSize /*SizeOfRawData*/, // ROUND_UP(PESectionHeaders[Idx].SizeOfRawData.Misc.VirtualSize,
// PEOptionalHeader->SectionAlignment)); // PEOptionalHeader->SectionAlignment));
} }
@ -652,8 +663,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress); .VirtualAddress);
/* Perform import fixups */ /* Perform import fixups */
if (PEOptionalHeader->DataDirectory[ if (PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
{ {
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
@ -680,6 +690,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer); ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
ModuleName.Buffer = NameBuffer; ModuleName.Buffer = NameBuffer;
DPRINT("Import module: %wZ\n", &ModuleName); DPRINT("Import module: %wZ\n", &ModuleName);
LibraryModuleObject = LdrLoadModule(&ModuleName); LibraryModuleObject = LdrLoadModule(&ModuleName);
if (LibraryModuleObject == 0) if (LibraryModuleObject == 0)
{ {
@ -706,6 +717,8 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
if ((*FunctionNameList) & 0x80000000) // hint if ((*FunctionNameList) & 0x80000000) // hint
{ {
pName = NULL; pName = NULL;
Hint = (*FunctionNameList) & 0xffff; Hint = (*FunctionNameList) & 0xffff;
} }
else // hint-name else // hint-name
@ -791,18 +804,18 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
PEOptionalHeader->AddressOfEntryPoint); PEOptionalHeader->AddressOfEntryPoint);
ModuleObject->Length = DriverSize; ModuleObject->Length = DriverSize;
DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint); DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint);
ModuleObject->Image.PE.FileHeader = ModuleObject->Image.PE.FileHeader =
(PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + (PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG));
PEDosHeader->e_lfanew + sizeof(ULONG));
DPRINT("FileHeader at %x\n", ModuleObject->Image.PE.FileHeader); DPRINT("FileHeader at %x\n", ModuleObject->Image.PE.FileHeader);
ModuleObject->Image.PE.OptionalHeader = ModuleObject->Image.PE.OptionalHeader =
(PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + (PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER)); sizeof(IMAGE_FILE_HEADER));
DPRINT("OptionalHeader at %x\n", ModuleObject->Image.PE.OptionalHeader); DPRINT("OptionalHeader at %x\n", ModuleObject->Image.PE.OptionalHeader);
ModuleObject->Image.PE.SectionList = ModuleObject->Image.PE.SectionList =
(PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + (PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER));
sizeof(IMAGE_OPTIONAL_HEADER));
DPRINT("SectionList at %x\n", ModuleObject->Image.PE.SectionList); DPRINT("SectionList at %x\n", ModuleObject->Image.PE.SectionList);
return ModuleObject; return ModuleObject;
@ -814,7 +827,7 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
unsigned short Hint) unsigned short Hint)
{ {
WORD Idx; WORD Idx;
DWORD ExportsStartRVA, ExportsEndRVA, Delta; DWORD ExportsStartRVA, ExportsEndRVA;
PVOID ExportAddress; PVOID ExportAddress;
PWORD OrdinalList; PWORD OrdinalList;
PDWORD FunctionList, NameList; PDWORD FunctionList, NameList;
@ -826,35 +839,26 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
ExportsEndRVA = ExportsStartRVA + ExportsEndRVA = ExportsStartRVA +
ModuleObject->Image.PE.OptionalHeader->DataDirectory ModuleObject->Image.PE.OptionalHeader->DataDirectory
[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; [IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
/* Get the IMAGE_SECTION_HEADER that contains the exports. This is /* Get the IMAGE_SECTION_HEADER that contains the exports. This is
usually the .edata section, but doesn't have to be. */ usually the .edata section, but doesn't have to be. */
SectionHeader = LdrPEGetEnclosingSectionHeader(ExportsStartRVA, ModuleObject); SectionHeader = LdrPEGetEnclosingSectionHeader(ExportsStartRVA, ModuleObject);
DPRINT("Base:%08lx ExportsStartRVA:%08lx End:%08lx SectionHeader:%08lx\n",
ModuleObject->Base, ExportsStartRVA, ExportsEndRVA, SectionHeader);
if (!SectionHeader) if (!SectionHeader)
{ {
return 0; return 0;
} }
Delta = (DWORD)(SectionHeader->VirtualAddress -
SectionHeader->PointerToRawData);
ExportDirectory = MakePtr(PIMAGE_EXPORT_DIRECTORY, ExportDirectory = MakePtr(PIMAGE_EXPORT_DIRECTORY,
ModuleObject->Base, ModuleObject->Base,
ExportsStartRVA - Delta); SectionHeader->VirtualAddress);
DPRINT("Export Dir:%08lx\n", ExportDirectory);
FunctionList = (PDWORD)((DWORD)ExportDirectory->AddressOfFunctions - FunctionList = (PDWORD)((DWORD)ExportDirectory->AddressOfFunctions + ModuleObject->Base);
Delta + ModuleObject->Base); NameList = (PDWORD)((DWORD)ExportDirectory->AddressOfNames + ModuleObject->Base);
NameList = (PDWORD)((DWORD)ExportDirectory->AddressOfNames - OrdinalList = (PWORD)((DWORD)ExportDirectory->AddressOfNameOrdinals + ModuleObject->Base);
Delta + ModuleObject->Base);
OrdinalList = (PWORD)((DWORD)ExportDirectory->AddressOfNameOrdinals -
Delta + ModuleObject->Base);
DPRINT("Delta:%08x\n", Delta);
DPRINT("Func:%08x RVA:%08x Name:%08x RVA:%08x\nOrd:%08x RVA:%08x ",
FunctionList, ExportDirectory->AddressOfFunctions,
NameList, ExportDirectory->AddressOfNames,
OrdinalList, ExportDirectory->AddressOfNameOrdinals);
DPRINT("NumNames:%d NumFuncs:%d\n", ExportDirectory->NumberOfNames,
ExportDirectory->NumberOfFunctions);
ExportAddress = 0; ExportAddress = 0;
if (Name != NULL) if (Name != NULL)
{ {
for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++) for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++)
@ -864,6 +868,7 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
Name, Name,
Idx, Idx,
(DWORD) ModuleObject->Base + NameList[Idx]); (DWORD) ModuleObject->Base + NameList[Idx]);
#endif #endif
if (!strcmp(Name, (PCHAR) ((DWORD)ModuleObject->Base + NameList[Idx]))) if (!strcmp(Name, (PCHAR) ((DWORD)ModuleObject->Base + NameList[Idx])))
{ {
@ -881,8 +886,10 @@ LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject,
if (ExportAddress == 0) if (ExportAddress == 0)
{ {
DbgPrint("Export not found for %d:%s\n", Hint, Name != NULL ? Name : "(Ordinal)"); DbgPrint("Export not found for %d:%s\n", Hint, Name != NULL ? Name : "(Ordinal)");
for(;;) ;
} }
return ExportAddress; return ExportAddress;
} }
@ -906,5 +913,3 @@ LdrPEGetEnclosingSectionHeader(DWORD RVA,
return 0; return 0;
} }