mirror of
https://github.com/reactos/reactos.git
synced 2024-07-27 14:49:22 +00:00
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:
parent
27e2be0d83
commit
3ede8f0814
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -171,7 +171,7 @@ DrawCaption@16
|
|||
DrawEdge@16
|
||||
DrawFocusRect@8
|
||||
;DrawFrame
|
||||
;DrawFrameControl
|
||||
DrawFrameControl
|
||||
DrawIcon@16
|
||||
DrawIconEx@36
|
||||
DrawMenuBar@4
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()).
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue