CVS: winex/dlls/ntdll ntdll.spec, 1.51, 1.52 rtl.c, 1.7, 1.8
[email protected] 12 Sep 2007 12:17:00 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/ntdll ntdll.spec,1.51,1.52 rtl.c,1.7,1.8Update of /var/lib/cvsd/cvsroot/winex/dlls/ntdll
In directory agravaine:/tmp/cvs-serv7276/dlls/ntdll
Modified Files:
ntdll.spec rtl.c
Log Message:
- added implementations for the RtlImageRvaToSection(), RtlImageRvaToVa(), and RtlImageDirectoryEntryToData() functions. These are all used by winehq's dbghelp dll. These were all tested against native for identical behaviour.
Index: ntdll.spec
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/ntdll.spec,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- ntdll.spec 12 Sep 2007 12:14:45 -0000 1.51
+++ ntdll.spec 12 Sep 2007 12:16:58 -0000 1.52
@@ -424,8 +424,10 @@
@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)RtlGetSaclSecurityDescriptor
@ stub RtlGetUserInfoHeap
@ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid
-@ stub RtlImageDirectoryEntryToData
+@ stdcall RtlImageDirectoryEntryToData(long long long ptr) RtlImageDirectoryEntryToData
@ stdcall RtlImageNtHeader(long) RtlImageNtHeader
+@ stdcall RtlImageRvaToSection(ptr long long) RtlImageRvaToSection
+@ stdcall RtlImageRvaToVa(ptr long long ptr) RtlImageRvaToVa
@ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf
@ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString
@ stub RtlInitCodePageTable
Index: rtl.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/rtl.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- rtl.c 6 Nov 2006 16:22:25 -0000 1.7
+++ rtl.c 12 Sep 2007 12:16:58 -0000 1.8
@@ -354,6 +354,133 @@
return ret;
}
+/***********************************************************************
+ * RtlImageRvaToSection (NTDLL.@)
+ */
+PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection(const IMAGE_NT_HEADERS *ntHeaders, HMODULE base, DWORD rva){
+ int i;
+ int sectionCount;
+ IMAGE_SECTION_HEADER * nextSection = NULL;
+
+
+ /* make sure we got a valid header */
+ if (ntHeaders == NULL)
+ return NULL;
+
+ /* this parameter is reserved for future use */
+ /*if (base != 0)
+ return NULL;*/
+
+
+ /* MSDN says the section table starts immediately after the file and optional headers */
+ sectionCount = ntHeaders->FileHeader.NumberOfSections;
+ nextSection = (IMAGE_SECTION_HEADER *)(((BYTE *)&ntHeaders->OptionalHeader) + ntHeaders->FileHeader.SizeOfOptionalHeader);
+
+
+ for (i = 0; i < sectionCount; i++){
+
+ /* each section table entry conveniently contains its mapped virtual address and size on disk. Just test to
+ see if the address we're interested in is in the range of this section. All addresses seem to be relative
+ to the image's base address (which is ignored in this call) */
+ if (rva >= nextSection->VirtualAddress && rva < nextSection->VirtualAddress + nextSection->SizeOfRawData)
+ return nextSection;
+
+ nextSection++;
+ }
+
+ return NULL;
+}
+
+/***********************************************************************
+ * RtlImageRvaToVa (NTDLL.@)
+ */
+PVOID WINAPI RtlImageRvaToVa(const IMAGE_NT_HEADERS *ntHeaders, HMODULE base, DWORD rva, IMAGE_SECTION_HEADER **lastRvaSection){
+ IMAGE_SECTION_HEADER *section = NULL;
+
+
+ /* test the last used section for the address first. We could luck out and the new
+ RVA will also be in the same section. */
+ if (lastRvaSection)
+ section = *lastRvaSection;
+
+ /* a previous section was passed in => test that one first */
+ if (section){
+
+ /* test to see if the requested RVA is in the section that was last used */
+ if (rva >= section->VirtualAddress && rva < section->VirtualAddress + section->SizeOfRawData){
+
+ /* the address will be the memory mapped base of the section plus the RVA's
+ offset into the section. In this case <lastRvaSection> will keep the
+ same value. */
+ return (PVOID)(((ULONG_PTR)base + section->PointerToRawData) + (rva - section->VirtualAddress));
+ }
+ }
+
+
+ /* find the section that the requested RVA is in */
+ section = RtlImageRvaToSection(ntHeaders, base, rva);
+
+
+ /* section not found => fail */
+ if (section == NULL)
+ return NULL;
+
+ /* save the last used section for an optimized search next time */
+ if (lastRvaSection)
+ *lastRvaSection = section;
+
+
+ /* the address will be the memory mapped base of the section plus the RVA's
+ offset into the section. */
+ return (PVOID)(((ULONG_PTR)base + section->PointerToRawData) + (rva - section->VirtualAddress));
+}
+
+/***********************************************************************
+ * RtlImageDirectoryEntryToData (NTDLL.@)
+ */
+PVOID WINAPI RtlImageDirectoryEntryToData(HMODULE base, BOOL mappedAsImage, WORD directoryEntry, ULONG *size){
+ IMAGE_NT_HEADERS * ntHeader;
+ DWORD va;
+
+
+ /* invalid image base => fail */
+ if (!base)
+ return NULL;
+
+
+ /* attempt to retrieve the PE header */
+ ntHeader = RtlImageNtHeader(base);
+
+ /* could not retrieve header => fail */
+ if (ntHeader == NULL)
+ return NULL;
+
+
+ /* invalid directory entry name => fail */
+ if (directoryEntry >= ntHeader->OptionalHeader.NumberOfRvaAndSizes)
+ return NULL;
+
+
+ /* grab the virtual address and section size */
+ va = ntHeader->OptionalHeader.DataDirectory[directoryEntry].VirtualAddress;
+
+ if (size)
+ *size = (ULONG)ntHeader->OptionalHeader.DataDirectory[directoryEntry].Size;
+
+ /* the section does not exist in this module => fail */
+ if (va == 0)
+ return NULL;
+
+
+ /* the file is already mapped as a loaded executeable => the VA will already have been updated */
+ if (mappedAsImage)
+ return (PVOID)(((ULONG_PTR)base) + va);
+
+
+ /* the file is not mapped -> the listed VA is actually an RVA => convert it */
+ return RtlImageRvaToVa(ntHeader, base, va, NULL);
+}
+
/******************************************************************************
* RtlCreateEnvironment [NTDLL.@]