diff --git a/reactos/include/funcs.h b/reactos/include/funcs.h index 1726b57cdba..6c3efb2bfa2 100644 --- a/reactos/include/funcs.h +++ b/reactos/include/funcs.h @@ -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 diff --git a/reactos/include/ntdll/ldr.h b/reactos/include/ntdll/ldr.h index 086317928a3..85c0752acc1 100644 --- a/reactos/include/ntdll/ldr.h +++ b/reactos/include/ntdll/ldr.h @@ -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, diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index 50e6fd2be25..5f546042741 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -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 */ diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index fb7e1aec9c6..983555e0117 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -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. diff --git a/reactos/lib/user32/user32.def b/reactos/lib/user32/user32.def index 847d291259a..b69cf5090d5 100644 --- a/reactos/lib/user32/user32.def +++ b/reactos/lib/user32/user32.def @@ -171,7 +171,7 @@ DrawCaption@16 DrawEdge@16 DrawFocusRect@8 ;DrawFrame -;DrawFrameControl +DrawFrameControl DrawIcon@16 DrawIconEx@36 DrawMenuBar@4 diff --git a/reactos/lib/user32/user32.edf b/reactos/lib/user32/user32.edf index 1ff2fc37627..9292e34eb55 100644 --- a/reactos/lib/user32/user32.edf +++ b/reactos/lib/user32/user32.edf @@ -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 diff --git a/reactos/lib/user32/windows/nonclient.c b/reactos/lib/user32/windows/nonclient.c index 09c79d9ed27..aa5fb48687e 100644 --- a/reactos/lib/user32/windows/nonclient.c +++ b/reactos/lib/user32/windows/nonclient.c @@ -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()). diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index f1e3effbf78..3fe840bdc53 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -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);