Fixed when changing the attributes of an area larger than the mapped area.

Unprotect pages before applying relocations
Create a module entry before fixing up imports to support recursive
dependencies
Added missing symbol to user32

svn path=/trunk/; revision=3438
This commit is contained in:
David Welch 2002-08-29 22:12:16 +00:00
parent 27e2be0d83
commit 3ede8f0814
8 changed files with 214 additions and 155 deletions

View file

@ -5502,8 +5502,7 @@ WINBOOL
STDCALL
DrawEdge(HDC hdc, LPRECT qrc, UINT edge, UINT grfFlags);
WINBOOL
STDCALL
WINBOOL STDCALL
DrawFrameControl(HDC, LPRECT, UINT, UINT);
WINBOOL

View file

@ -73,7 +73,10 @@ LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule);
#endif
PEPFUNC LdrPEStartup(PVOID ImageBase, HANDLE SectionHandle);
PEPFUNC LdrPEStartup (PVOID ImageBase,
HANDLE SectionHandle,
PLDR_MODULE* Module,
PWSTR FullDosName);
NTSTATUS LdrMapSections(HANDLE ProcessHandle,
PVOID ImageBase,
HANDLE SectionHandle,

View file

@ -1,4 +1,4 @@
/* $Id: startup.c,v 1.41 2002/08/17 15:17:59 hbirr Exp $
/* $Id: startup.c,v 1.42 2002/08/29 22:12:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -263,7 +263,7 @@ LdrInitializeThunk (ULONG Unknown1,
#endif /* DBG */
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL);
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
ExeModule->EntryPoint = (ULONG)EntryPoint;
/* all required dlls are loaded now */

View file

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.53 2002/08/10 16:41:17 dwelch Exp $
/* $Id: utils.c,v 1.54 2002/08/29 22:12:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -140,6 +140,53 @@ LdrAdjustDllName (PUNICODE_STRING FullDllName,
Buffer);
}
PLDR_MODULE
LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders,
PWSTR FullDosName)
{
PLDR_MODULE Module;
Module = RtlAllocateHeap(RtlGetProcessHeap(),
0,
sizeof (LDR_MODULE));
assert(Module);
Module->BaseAddress = (PVOID)ImageBase;
Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint;
if (Module->EntryPoint != 0)
Module->EntryPoint += (ULONG)Module->BaseAddress;
Module->SizeOfImage = NTHeaders->OptionalHeader.SizeOfImage;
if (NtCurrentPeb()->Ldr->Initialized == TRUE)
{
/* loading while app is running */
Module->LoadCount = 1;
}
else
{
/*
* loading while app is initializing
* dll must not be unloaded
*/
Module->LoadCount = -1;
}
Module->TlsIndex = 0;
Module->CheckSum = NTHeaders->OptionalHeader.CheckSum;
Module->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
RtlCreateUnicodeString (&Module->FullDllName,
FullDosName);
RtlCreateUnicodeString (&Module->BaseDllName,
wcsrchr(FullDosName, L'\\') + 1);
DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
/* FIXME: aquire loader lock */
InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
&Module->InLoadOrderModuleList);
InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
&Module->InInitializationOrderModuleList);
/* FIXME: release loader lock */
return(Module);
}
/***************************************************************************
* NAME EXPORTED
@ -349,54 +396,14 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
IMAGE_FILE_DLL)
{
Entrypoint =
(PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle);
(PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module,
FullDosName);
if (Entrypoint == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
}
/* build module entry */
Module = RtlAllocateHeap(RtlGetProcessHeap(),
0,
sizeof (LDR_MODULE));
assert(Module);
Module->BaseAddress = (PVOID)ImageBase;
Module->EntryPoint = NTHeaders->OptionalHeader.AddressOfEntryPoint;
if (Module->EntryPoint != 0)
Module->EntryPoint += (ULONG)Module->BaseAddress;
Module->SizeOfImage = ImageSize;
if (NtCurrentPeb()->Ldr->Initialized == TRUE)
{
/* loading while app is running */
Module->LoadCount = 1;
}
else
{
/*
* loading while app is initializing
* dll must not be unloaded
*/
Module->LoadCount = -1;
}
Module->TlsIndex = 0;
Module->CheckSum = NTHeaders->OptionalHeader.CheckSum;
Module->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
RtlCreateUnicodeString (&Module->FullDllName,
FullDosName);
RtlCreateUnicodeString (&Module->BaseDllName,
wcsrchr(FullDosName, L'\\') + 1);
DPRINT ("BaseDllName %wZ\n", &Module->BaseDllName);
/* FIXME: aquire loader lock */
InsertTailList(&NtCurrentPeb()->Ldr->InLoadOrderModuleList,
&Module->InLoadOrderModuleList);
InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
&Module->InInitializationOrderModuleList);
/* FIXME: release loader lock */
#ifdef DBG
LdrpLoadUserModuleSymbols(Module);
@ -826,96 +833,133 @@ LdrGetExportByName(PVOID BaseAddress,
static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
PVOID ImageBase)
{
USHORT NumberOfEntries;
PUSHORT pValue16;
ULONG RelocationRVA;
ULONG Delta32;
ULONG Offset;
PULONG pValue32;
PRELOCATION_DIRECTORY RelocationDir;
PRELOCATION_ENTRY RelocationBlock;
int i;
USHORT NumberOfEntries;
PUSHORT pValue16;
ULONG RelocationRVA;
ULONG Delta32;
ULONG Offset;
PULONG pValue32;
PRELOCATION_DIRECTORY RelocationDir;
PRELOCATION_ENTRY RelocationBlock;
int i;
PIMAGE_DATA_DIRECTORY RelocationDDir;
ULONG OldProtect;
NTSTATUS Status;
PIMAGE_SECTION_HEADER Sections;
ULONG MaxExtend;
ULONG LastOffset;
RelocationRVA = NTHeaders->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]
.VirtualAddress;
if (RelocationRVA)
Sections =
(PIMAGE_SECTION_HEADER)((PVOID)NTHeaders + sizeof(IMAGE_NT_HEADERS));
MaxExtend = 0;
for (i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
{
if (!(Sections[i].Characteristics & IMAGE_SECTION_NOLOAD))
{
RelocationDir = (PRELOCATION_DIRECTORY)
((PCHAR)ImageBase + RelocationRVA);
while (RelocationDir->SizeOfBlock)
{
Delta32 = (ULONG)(ImageBase -
NTHeaders->OptionalHeader.ImageBase);
RelocationBlock = (PRELOCATION_ENTRY) (
RelocationRVA
+ ImageBase
+ sizeof (RELOCATION_DIRECTORY)
);
NumberOfEntries = (
RelocationDir->SizeOfBlock
- sizeof (RELOCATION_DIRECTORY)
)
/ sizeof (RELOCATION_ENTRY);
for ( i = 0;
(i < NumberOfEntries);
i++
)
{
Offset = (
RelocationBlock[i].TypeOffset
& 0xfff
)
+ RelocationDir->VirtualAddress;
/*
* What kind of relocations should we perform
* for the current entry?
*/
switch (RelocationBlock[i].TypeOffset >> 12)
{
case TYPE_RELOC_ABSOLUTE:
break;
case TYPE_RELOC_HIGH:
pValue16 = (PUSHORT) (ImageBase + Offset);
*pValue16 += Delta32 >> 16;
break;
case TYPE_RELOC_LOW:
pValue16 = (PUSHORT)(ImageBase + Offset);
*pValue16 += Delta32 & 0xffff;
break;
case TYPE_RELOC_HIGHLOW:
pValue32 = (PULONG) (ImageBase + Offset);
*pValue32 += Delta32;
break;
case TYPE_RELOC_HIGHADJ:
/* FIXME: do the highadjust fixup */
DPRINT(
"TYPE_RELOC_HIGHADJ fixup not implemented"
", sorry\n"
);
return(STATUS_UNSUCCESSFUL);
default:
DPRINT("unexpected fixup type\n");
return STATUS_UNSUCCESSFUL;
}
}
RelocationRVA += RelocationDir->SizeOfBlock;
RelocationDir = (PRELOCATION_DIRECTORY) (
ImageBase
+ RelocationRVA
);
}
ULONG Extend;
Extend =
(ULONG)(Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize);
MaxExtend = max(MaxExtend, Extend);
}
return STATUS_SUCCESS;
}
RelocationDDir =
&NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
RelocationRVA = RelocationDDir->VirtualAddress;
if (RelocationRVA)
{
RelocationDir =
(PRELOCATION_DIRECTORY)((PCHAR)ImageBase + RelocationRVA);
while (RelocationDir->SizeOfBlock)
{
if (RelocationDir->VirtualAddress > MaxExtend)
{
RelocationRVA += RelocationDir->SizeOfBlock;
RelocationDir =
(PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
continue;
}
Delta32 = (ULONG)(ImageBase - NTHeaders->OptionalHeader.ImageBase);
RelocationBlock =
(PRELOCATION_ENTRY) (RelocationRVA + ImageBase +
sizeof (RELOCATION_DIRECTORY));
NumberOfEntries =
RelocationDir->SizeOfBlock - sizeof (RELOCATION_DIRECTORY);
NumberOfEntries = NumberOfEntries / sizeof (RELOCATION_ENTRY);
Status = NtProtectVirtualMemory(NtCurrentProcess(),
ImageBase +
RelocationDir->VirtualAddress,
PAGESIZE,
PAGE_READWRITE,
&OldProtect);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to unprotect relocation target.\n");
return(Status);
}
for (i = 0; i < NumberOfEntries; i++)
{
Offset = (RelocationBlock[i].TypeOffset & 0xfff);
Offset += (ULONG)(RelocationDir->VirtualAddress + ImageBase);
/*
* What kind of relocations should we perform
* for the current entry?
*/
switch (RelocationBlock[i].TypeOffset >> 12)
{
case TYPE_RELOC_ABSOLUTE:
break;
case TYPE_RELOC_HIGH:
pValue16 = (PUSHORT)Offset;
*pValue16 += Delta32 >> 16;
break;
case TYPE_RELOC_LOW:
pValue16 = (PUSHORT)Offset;
*pValue16 += Delta32 & 0xffff;
break;
case TYPE_RELOC_HIGHLOW:
pValue32 = (PULONG)Offset;
*pValue32 += Delta32;
break;
case TYPE_RELOC_HIGHADJ:
/* FIXME: do the highadjust fixup */
DPRINT("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
return(STATUS_UNSUCCESSFUL);
default:
DPRINT("unexpected fixup type\n");
return STATUS_UNSUCCESSFUL;
}
}
Status = NtProtectVirtualMemory(NtCurrentProcess(),
ImageBase +
RelocationDir->VirtualAddress,
PAGESIZE,
OldProtect,
&OldProtect);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to protect relocation target.\n");
return(Status);
}
RelocationRVA += RelocationDir->SizeOfBlock;
RelocationDir =
(PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA);
}
}
return STATUS_SUCCESS;
}
@ -1116,7 +1160,9 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
*
*/
PEPFUNC LdrPEStartup (PVOID ImageBase,
HANDLE SectionHandle)
HANDLE SectionHandle,
PLDR_MODULE* Module,
PWSTR FullDosName)
{
NTSTATUS Status;
PEPFUNC EntryPoint = NULL;
@ -1149,6 +1195,11 @@ PEPFUNC LdrPEStartup (PVOID ImageBase,
}
}
if (Module != NULL)
{
*Module = LdrAddModuleEntry(ImageBase, NTHeaders, FullDosName);
}
/*
* If the DLL's imports symbols from other
* modules, fixup the imported calls entry points.

View file

@ -171,7 +171,7 @@ DrawCaption@16
DrawEdge@16
DrawFocusRect@8
;DrawFrame
;DrawFrameControl
DrawFrameControl
DrawIcon@16
DrawIconEx@36
DrawMenuBar@4

View file

@ -171,7 +171,7 @@ DrawCaption=DrawCaption@16
DrawEdge=DrawEdge@16
DrawFocusRect=DrawFocusRect@8
;DrawFrame
;DrawFrameControl
DrawFrameControl=DrawFrameControl@16
DrawIcon=DrawIcon@16
DrawIconEx=DrawIconEx@36
DrawMenuBar=DrawMenuBar@4

View file

@ -42,6 +42,11 @@
/* FUNCTIONS *****************************************************************/
WINBOOL STDCALL
DrawFrameControl(HDC hDc, LPRECT Rect, UINT Type, UINT State)
{
}
/* Get the 'inside' rectangle of a window, i.e. the whole window rectangle
* but without the borders (if any).
* The rectangle is in window coordinates (for drawing with GetWindowDC()).

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: section.c,v 1.94 2002/08/28 07:13:04 hbirr Exp $
/* $Id: section.c,v 1.95 2002/08/29 22:12:16 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
@ -462,6 +462,20 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Address, NULL);
MmLockSection(Section);
MmLockSectionSegment(Segment);
/*
* Check if this page needs to be mapped COW
*/
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
(Region->Protect == PAGE_READWRITE ||
Region->Protect == PAGE_EXECUTE_READWRITE))
{
Attributes = PAGE_READONLY;
}
else
{
Attributes = Region->Protect;
}
/*
* Get or create a page operation descriptor
@ -544,7 +558,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address,
MemoryArea->Attributes,
Attributes,
Page,
FALSE);
if (!NT_SUCCESS(Status))
@ -715,20 +729,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
return(STATUS_SUCCESS);
}
/*
* Check if this page needs to be mapped COW
*/
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
(Region->Protect == PAGE_READWRITE ||
Region->Protect == PAGE_EXECUTE_READWRITE))
{
Attributes = PAGE_READONLY;
}
else
{
Attributes = Region->Protect;
}
/*
* Get the entry corresponding to the offset within the section
*/
@ -1731,7 +1731,8 @@ MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
PMM_REGION Region;
NTSTATUS Status;
Length = min(Length, MemoryArea->Length);
Length =
min(Length, MemoryArea->BaseAddress + MemoryArea->Length - BaseAddress);
Region = MmFindRegion(MemoryArea->BaseAddress,
&MemoryArea->Data.SectionData.RegionListHead,
BaseAddress, NULL);