Implement LOAD_LIBRARY_AS_DATAFILE flag
Modified: trunk/reactos/lib/ntdll/ldr/res.c
Modified: trunk/reactos/lib/ntdll/ldr/utils.c
_____
Modified: trunk/reactos/lib/ntdll/ldr/res.c
--- trunk/reactos/lib/ntdll/ldr/res.c 2005-01-16 09:24:00 UTC (rev
13072)
+++ trunk/reactos/lib/ntdll/ldr/res.c 2005-01-16 09:36:19 UTC (rev
13073)
@@ -110,12 +110,14 @@
int j, pos = 0;
LCID UserLCID, SystemLCID;
LANGID UserLangID, SystemLangID;
+ BOOL MappedAsDataFile;
+ MappedAsDataFile = LdrMappedAsDataFile(&BaseAddress);
DPRINT("LdrFindResource_U(%08x, %08x, %d, %08x)\n", BaseAddress,
ResourceInfo, Level, ResourceDataEntry);
/* Get the pointer to the resource directory */
ResDir =
(PIMAGE_RESOURCE_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
- TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &i);
+ ! MappedAsDataFile,
IMAGE_DIRECTORY_ENTRY_RESOURCE, &i);
if (ResDir == NULL) {
return STATUS_RESOURCE_DATA_NOT_FOUND;
}
@@ -278,18 +280,20 @@
ULONG DataSize;
ULONG Offset = 0;
ULONG Data;
+ BOOL MappedAsDataFile;
if(!ResourceDataEntry)
return STATUS_RESOURCE_DATA_NOT_FOUND;
+ MappedAsDataFile = LdrMappedAsDataFile(&BaseAddress);
Data = (ULONG)RtlImageDirectoryEntryToData(BaseAddress,
TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE,
&DataSize);
if (Data == 0) {
return STATUS_RESOURCE_DATA_NOT_FOUND;
}
- if ((ULONG)BaseAddress & 1) {
+ if (MappedAsDataFile) {
/* loaded as ordinary file */
- NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress &
~1UL));
+ NtHeader = RtlImageNtHeader(BaseAddress);
Offset = (ULONG)BaseAddress - Data +
NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].V
irtualAddress;
Section = RtlImageRvaToSection(NtHeader, BaseAddress,
NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].V
irtualAddress);
if (Section == NULL) {
_____
Modified: trunk/reactos/lib/ntdll/ldr/utils.c
--- trunk/reactos/lib/ntdll/ldr/utils.c 2005-01-16 09:24:00 UTC (rev
13072)
+++ trunk/reactos/lib/ntdll/ldr/utils.c 2005-01-16 09:36:19 UTC (rev
13073)
@@ -61,7 +61,8 @@
static NTSTATUS LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
IN ULONG LoadFlags,
IN PUNICODE_STRING Name,
- OUT PLDR_MODULE *Module);
+ OUT PLDR_MODULE *Module,
+ OUT PVOID *BaseAddress OPTIONAL);
static NTSTATUS LdrpAttachProcess(VOID);
static VOID LdrpDetachProcess(BOOL UnloadAll);
@@ -83,6 +84,18 @@
#endif /* DBG || KDBG */
+BOOL
+LdrMappedAsDataFile(PVOID *BaseAddress)
+{
+ if (0 != ((DWORD_PTR) *BaseAddress & (PAGE_SIZE - 1)))
+ {
+ *BaseAddress = (PVOID) ((DWORD_PTR) *BaseAddress & ~ ((DWORD_PTR)
PAGE_SIZE - 1));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static inline LONG LdrpDecrementLoadCount(PLDR_MODULE Module, BOOL
Locked)
{
LONG LoadCount;
@@ -548,6 +561,7 @@
LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
IN PUNICODE_STRING DllName,
OUT PUNICODE_STRING FullDosName,
+ IN BOOL MapAsDataFile,
OUT PHANDLE SectionHandle)
{
WCHAR SearchPathBuffer[MAX_PATH];
@@ -558,8 +572,6 @@
char BlockBuffer [1024];
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
- PVOID ImageBase;
- ULONG ImageSize;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
ULONG len;
@@ -663,11 +675,6 @@
return STATUS_UNSUCCESSFUL;
}
- ImageBase = (PVOID) NTHeaders->OptionalHeader.ImageBase;
- ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
-
- DPRINT("ImageBase 0x%08x\n", ImageBase);
-
/*
* Create a section for dll.
*/
@@ -676,7 +683,7 @@
NULL,
NULL,
PAGE_READWRITE,
- SEC_COMMIT | SEC_IMAGE,
+ SEC_COMMIT | (MapAsDataFile ? 0 :
SEC_IMAGE),
FileHandle);
NtClose(FileHandle);
@@ -732,8 +739,8 @@
*BaseAddress = NULL;
- Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module);
- if (NT_SUCCESS(Status))
+ Status = LdrpLoadModule(SearchPath, LoadFlags, Name, &Module,
BaseAddress);
+ if (NT_SUCCESS(Status) && 0 == (LoadFlags &
LOAD_LIBRARY_AS_DATAFILE))
{
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
Status = LdrpAttachProcess();
@@ -1346,7 +1353,8 @@
Status = LdrpLoadModule(SerachPath,
NtCurrentPeb()->Ldr->Initialized ? 0 :
LDRP_PROCESS_CREATION_TIME,
&DllName,
- Module);
+ Module,
+ NULL);
if (NT_SUCCESS(Status))
{
Status = LdrFindEntryForName (&DllName, Module, FALSE);
@@ -1978,7 +1986,8 @@
LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
IN ULONG LoadFlags,
IN PUNICODE_STRING Name,
- PLDR_MODULE *Module)
+ PLDR_MODULE *Module,
+ PVOID *BaseAddress OPTIONAL)
{
UNICODE_STRING AdjustedName;
UNICODE_STRING FullDosName;
@@ -1988,6 +1997,7 @@
ULONG ViewSize;
PVOID ImageBase;
PIMAGE_NT_HEADERS NtHeaders;
+ BOOL MappedAsDataFile;
if (Module == NULL)
{
@@ -1998,11 +2008,16 @@
DPRINT("%wZ\n", &AdjustedName);
+ MappedAsDataFile = FALSE;
/* Test if dll is already loaded */
Status = LdrFindEntryForName(&AdjustedName, Module, TRUE);
if (NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&AdjustedName);
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = (*Module)->BaseAddress;
+ }
}
else
{
@@ -2010,7 +2025,9 @@
Status = LdrpMapKnownDll(&AdjustedName, &FullDosName,
&SectionHandle);
if (!NT_SUCCESS(Status))
{
- Status = LdrpMapDllImageFile(SearchPath, &AdjustedName,
&FullDosName, &SectionHandle);
+ MappedAsDataFile = (0 != (LoadFlags &
LOAD_LIBRARY_AS_DATAFILE));
+ Status = LdrpMapDllImageFile(SearchPath, &AdjustedName,
&FullDosName,
+ MappedAsDataFile,
&SectionHandle);
}
if (!NT_SUCCESS(Status))
{
@@ -2039,6 +2056,10 @@
NtClose(SectionHandle);
return(Status);
}
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = ImageBase;
+ }
/* Get and check the NT headers */
NtHeaders = RtlImageNtHeader(ImageBase);
if (NtHeaders == NULL)
@@ -2049,6 +2070,19 @@
RtlFreeUnicodeString(&FullDosName);
return STATUS_UNSUCCESSFUL;
}
+ DPRINT("Mapped %wZ at %x\n", &FullDosName, ImageBase);
+ if (MappedAsDataFile)
+ {
+ assert(NULL != BaseAddress);
+ if (NULL != BaseAddress)
+ {
+ *BaseAddress = (PVOID) ((char *) *BaseAddress + 1);
+ }
+ *Module = NULL;
+ RtlFreeUnicodeString(&FullDosName);
+ NtClose(SectionHandle);
+ return STATUS_SUCCESS;
+ }
/* If the base address is different from the
* one the DLL is actually loaded, perform any
* relocation. */
@@ -2212,12 +2246,20 @@
if (BaseAddress == NULL)
return STATUS_SUCCESS;
- Status = LdrFindEntryForAddress(BaseAddress, &Module);
- if (NT_SUCCESS(Status))
+ if (LdrMappedAsDataFile(&BaseAddress))
{
- TRACE_LDR("LdrUnloadDll, , unloading %wZ\n",
&Module->BaseDllName);
- Status = LdrpUnloadModule(Module, TRUE);
+ Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
+ else
+ {
+ Status = LdrFindEntryForAddress(BaseAddress, &Module);
+ if (NT_SUCCESS(Status))
+ {
+ TRACE_LDR("LdrUnloadDll, , unloading %wZ\n",
&Module->BaseDllName);
+ Status = LdrpUnloadModule(Module, TRUE);
+ }
+ }
+
return Status;
}