diff --git a/debian/changelog b/debian/changelog index 97e94505..f8401704 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,11 @@ wine-compholio (1.7.29) UNRELEASED; urgency=low * Updated DOS Attributes patch to better detect XATTR functions. + * Updated NtQuerySection patch. * Added patch to support IDF_CHECKFIRST in SetupPromptForDisk. * Added patch to fix issues when executing pages with guard page / write watch permissions. * Added patch to set return value of basic_string_wchar_dtor to return NULL. * Added patch for UTF7 encoding/decoding support. + * Added patch to implement ID3DXSkinInfoImpl_UpdateSkinnedMesh. * Removed patch to fix issues with drag image in ImageLists (accepted upstream). * Removed patch to set ldr.EntryPoint for main executable (accepted upstream). * Removed patch to implement stubs for [Get|Set]SystemFileCacheSize (accepted upstream). diff --git a/patches/Makefile b/patches/Makefile index 07eb95b1..7561fb91 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -731,19 +731,22 @@ ntdll-Junction_Points.ok: ntdll-Fix_Free.ok # Patchset ntdll-NtQuerySection # | # | Included patches: -# | * Implement NtQuerySection class SectionBasicInformation. [by Dmitry Timoshkov] +# | * Implement NtQuerySection class SectionBasicInformation. [rev 2, by Dmitry Timoshkov] # | # | This patchset fixes the following Wine bugs: # | * [#37338] Support for NtQuerySection # | # | Modified files: -# | * dlls/ntdll/nt.c, dlls/ntdll/virtual.c, include/winternl.h +# | * dlls/kernel32/tests/virtual.c, dlls/ntdll/nt.c, dlls/ntdll/ntdll.spec, dlls/ntdll/virtual.c, include/winternl.h, +# | server/mapping.c, server/protocol.def # | .INTERMEDIATE: ntdll-NtQuerySection.ok ntdll-NtQuerySection.ok: - $(call APPLY_FILE,ntdll-NtQuerySection/0001-ntdll-Implement-NtQuerySection-class-SectionBasicInf.patch) + $(call APPLY_FILE,ntdll-NtQuerySection/0001-include-Fix-definition-of-SECTION_BASIC_INFORMATION-.patch) + $(call APPLY_FILE,ntdll-NtQuerySection/0002-ntdll-Implement-NtQuerySection.patch) + $(call APPLY_FILE,ntdll-NtQuerySection/0003-kernel32-tests-Add-tests-for-NtQuerySection.patch) @( \ - echo '+ { "ntdll-NtQuerySection", "Dmitry Timoshkov", "Implement NtQuerySection class SectionBasicInformation." },'; \ + echo '+ { "ntdll-NtQuerySection", "Dmitry Timoshkov", "Implement NtQuerySection class SectionBasicInformation. [rev 2]" },'; \ ) > ntdll-NtQuerySection.ok # Patchset ntdll-Pipe_SpecialCharacters diff --git a/patches/ntdll-NtQuerySection/0001-include-Fix-definition-of-SECTION_BASIC_INFORMATION-.patch b/patches/ntdll-NtQuerySection/0001-include-Fix-definition-of-SECTION_BASIC_INFORMATION-.patch new file mode 100644 index 00000000..cccad522 --- /dev/null +++ b/patches/ntdll-NtQuerySection/0001-include-Fix-definition-of-SECTION_BASIC_INFORMATION-.patch @@ -0,0 +1,47 @@ +From aa9949cef21f63e2f5ba93515c4e1e17b66b1abf Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 16 Oct 2014 22:36:58 +0200 +Subject: include: Fix definition of SECTION_BASIC_INFORMATION and + SECTION_IMAGE_INFORMATION. + +--- + include/winternl.h | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/include/winternl.h b/include/winternl.h +index 5a27f94..bb27a21 100644 +--- a/include/winternl.h ++++ b/include/winternl.h +@@ -1792,7 +1792,7 @@ typedef enum _SECTION_INFORMATION_CLASS + } SECTION_INFORMATION_CLASS; + + typedef struct _SECTION_BASIC_INFORMATION { +- ULONG BaseAddress; ++ PVOID BaseAddress; + ULONG Attributes; + LARGE_INTEGER Size; + } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; +@@ -1800,14 +1800,16 @@ typedef struct _SECTION_BASIC_INFORMATION { + typedef struct _SECTION_IMAGE_INFORMATION { + PVOID EntryPoint; + ULONG StackZeroBits; +- ULONG StackReserved; +- ULONG StackCommit; ++ SIZE_T StackReserved; ++ SIZE_T StackCommit; + ULONG ImageSubsystem; + WORD SubsystemVersionLow; + WORD SubsystemVersionHigh; + ULONG Unknown1; +- ULONG ImageCharacteristics; +- ULONG ImageMachineType; ++ USHORT ImageCharacteristics; ++ USHORT DllCharacteristics; ++ USHORT ImageMachineType; ++ BOOLEAN ImageContainsCode; + ULONG Unknown2[3]; + } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; + +-- +2.1.2 + diff --git a/patches/ntdll-NtQuerySection/0001-ntdll-Implement-NtQuerySection-class-SectionBasicInf.patch b/patches/ntdll-NtQuerySection/0001-ntdll-Implement-NtQuerySection-class-SectionBasicInf.patch deleted file mode 100644 index a9afba87..00000000 --- a/patches/ntdll-NtQuerySection/0001-ntdll-Implement-NtQuerySection-class-SectionBasicInf.patch +++ /dev/null @@ -1,121 +0,0 @@ -From bf3f5ae559f93ec5c0598574aa1838464a2ad701 Mon Sep 17 00:00:00 2001 -From: Dmitry Timoshkov -Date: Fri, 3 Oct 2014 18:03:58 +0200 -Subject: ntdll: Implement NtQuerySection class SectionBasicInformation. - ---- - dlls/ntdll/nt.c | 19 ------------------- - dlls/ntdll/virtual.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - include/winternl.h | 2 +- - 3 files changed, 54 insertions(+), 20 deletions(-) - -diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c -index 73d9383..f0433db 100644 ---- a/dlls/ntdll/nt.c -+++ b/dlls/ntdll/nt.c -@@ -646,25 +646,6 @@ NTSTATUS WINAPI NtPrivilegeCheck( - } - - /* -- * Section -- */ -- --/****************************************************************************** -- * NtQuerySection [NTDLL.@] -- */ --NTSTATUS WINAPI NtQuerySection( -- IN HANDLE SectionHandle, -- IN SECTION_INFORMATION_CLASS SectionInformationClass, -- OUT PVOID SectionInformation, -- IN ULONG Length, -- OUT PULONG ResultLength) --{ -- FIXME("(%p,%d,%p,0x%08x,%p) stub!\n", -- SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength); -- return 0; --} -- --/* - * ports - */ - -diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c -index 4819d2d..94b4827 100644 ---- a/dlls/ntdll/virtual.c -+++ b/dlls/ntdll/virtual.c -@@ -2465,6 +2465,59 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ - - - /*********************************************************************** -+ * NtQuerySection (NTDLL.@) -+ */ -+NTSTATUS WINAPI NtQuerySection(HANDLE handle, SECTION_INFORMATION_CLASS info_class, -+ PVOID buffer, ULONG len, PULONG ret_len) -+{ -+ SECTION_BASIC_INFORMATION *info; -+ HANDLE dup_mapping, shared_file; -+ unsigned protect; -+ LARGE_INTEGER size; -+ void *base; -+ NTSTATUS res; -+ -+ if (info_class != SectionBasicInformation) -+ { -+ FIXME("%p,info_class=%d,%p,%d,%p) Unknown information class\n", -+ handle, info_class, buffer, len, ret_len); -+ return STATUS_INVALID_INFO_CLASS; -+ } -+ -+ if (len < sizeof(SECTION_BASIC_INFORMATION)) -+ return STATUS_INFO_LENGTH_MISMATCH; -+ -+ SERVER_START_REQ( get_mapping_info ) -+ { -+ req->handle = wine_server_obj_handle( handle ); -+ req->access = SECTION_QUERY; -+ res = wine_server_call( req ); -+ protect = reply->protect; -+ base = wine_server_get_ptr( reply->base ); -+ size.QuadPart = reply->size; -+ dup_mapping = wine_server_ptr_handle( reply->mapping ); -+ shared_file = wine_server_ptr_handle( reply->shared_file ); -+ if ((ULONG_PTR)base != reply->base) base = NULL; -+ } -+ SERVER_END_REQ; -+ if (res) return res; -+ -+ info = buffer; -+ info->BaseAddress = base; -+ info->Size = size; -+ info->Attributes = (protect & VPROT_COMMITTED) ? SEC_COMMIT : SEC_RESERVE; -+ if (protect & VPROT_NOCACHE) info->Attributes |= SEC_NOCACHE; -+ if (protect & VPROT_IMAGE) info->Attributes |= SEC_IMAGE; -+ /* FIXME: SEC_FILE */ -+ if (ret_len) *ret_len = sizeof(*info); -+ -+ if (dup_mapping) NtClose( dup_mapping ); -+ if (shared_file) NtClose( shared_file ); -+ return STATUS_SUCCESS; -+} -+ -+ -+/*********************************************************************** - * NtMapViewOfSection (NTDLL.@) - * ZwMapViewOfSection (NTDLL.@) - */ -diff --git a/include/winternl.h b/include/winternl.h -index 95951e2..ee08187 100644 ---- a/include/winternl.h -+++ b/include/winternl.h -@@ -1791,7 +1791,7 @@ typedef enum _SECTION_INFORMATION_CLASS - } SECTION_INFORMATION_CLASS; - - typedef struct _SECTION_BASIC_INFORMATION { -- ULONG BaseAddress; -+ PVOID BaseAddress; - ULONG Attributes; - LARGE_INTEGER Size; - } SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION; --- -2.1.1 - diff --git a/patches/ntdll-NtQuerySection/0002-ntdll-Implement-NtQuerySection.patch b/patches/ntdll-NtQuerySection/0002-ntdll-Implement-NtQuerySection.patch new file mode 100644 index 00000000..b54d0d7a --- /dev/null +++ b/patches/ntdll-NtQuerySection/0002-ntdll-Implement-NtQuerySection.patch @@ -0,0 +1,283 @@ +From 0cd17445c177428f06fa6dccd724e62fccd7619c Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 16 Oct 2014 23:24:37 +0200 +Subject: ntdll: Implement NtQuerySection. + +--- + dlls/ntdll/nt.c | 19 ---------- + dlls/ntdll/ntdll.spec | 4 +-- + dlls/ntdll/virtual.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ + server/mapping.c | 43 ++++++++++++++++++++++ + server/protocol.def | 7 ++++ + 5 files changed, 150 insertions(+), 21 deletions(-) + +diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c +index 73d9383..f0433db 100644 +--- a/dlls/ntdll/nt.c ++++ b/dlls/ntdll/nt.c +@@ -646,25 +646,6 @@ NTSTATUS WINAPI NtPrivilegeCheck( + } + + /* +- * Section +- */ +- +-/****************************************************************************** +- * NtQuerySection [NTDLL.@] +- */ +-NTSTATUS WINAPI NtQuerySection( +- IN HANDLE SectionHandle, +- IN SECTION_INFORMATION_CLASS SectionInformationClass, +- OUT PVOID SectionInformation, +- IN ULONG Length, +- OUT PULONG ResultLength) +-{ +- FIXME("(%p,%d,%p,0x%08x,%p) stub!\n", +- SectionHandle,SectionInformationClass,SectionInformation,Length,ResultLength); +- return 0; +-} +- +-/* + * ports + */ + +diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec +index 5bac269..32b023b 100644 +--- a/dlls/ntdll/ntdll.spec ++++ b/dlls/ntdll/ntdll.spec +@@ -262,7 +262,7 @@ + @ stdcall NtQueryPerformanceCounter(ptr ptr) + # @ stub NtQueryPortInformationProcess + # @ stub NtQueryQuotaInformationFile +-@ stdcall NtQuerySection (long long long long long) ++@ stdcall NtQuerySection(long long ptr long ptr) + @ stdcall NtQuerySecurityObject (long long long long long) + @ stdcall NtQuerySemaphore (long long ptr long ptr) + @ stdcall NtQuerySymbolicLinkObject(long ptr ptr) +@@ -1139,7 +1139,7 @@ + @ stdcall ZwQueryPerformanceCounter (long long) NtQueryPerformanceCounter + # @ stub ZwQueryPortInformationProcess + # @ stub ZwQueryQuotaInformationFile +-@ stdcall ZwQuerySection (long long long long long) NtQuerySection ++@ stdcall ZwQuerySection(long long ptr long ptr) NtQuerySection + @ stdcall ZwQuerySecurityObject (long long long long long) NtQuerySecurityObject + @ stdcall ZwQuerySemaphore (long long long long long) NtQuerySemaphore + @ stdcall ZwQuerySymbolicLinkObject(long ptr ptr) NtQuerySymbolicLinkObject +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index 4c4c05d..c3ed481 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -2553,6 +2553,104 @@ NTSTATUS WINAPI NtOpenSection( HANDLE *handle, ACCESS_MASK access, const OBJECT_ + + + /*********************************************************************** ++ * NtQuerySection (NTDLL.@) ++ */ ++NTSTATUS WINAPI NtQuerySection(HANDLE handle, SECTION_INFORMATION_CLASS info_class, ++ PVOID buffer, ULONG len, PULONG ret_len) ++{ ++ HANDLE dup_mapping, shared_file; ++ unsigned protect; ++ LARGE_INTEGER size; ++ void *base, *entry; ++ short machine, subsystem; ++ short major_subsystem, minor_subsystem; ++ short characteristics, dll_characteristics; ++ NTSTATUS res; ++ ++ if (info_class == SectionBasicInformation) ++ { ++ if (len < sizeof(SECTION_BASIC_INFORMATION)) ++ return STATUS_INFO_LENGTH_MISMATCH; ++ } ++ else if (info_class == SectionImageInformation) ++ { ++ if (len < sizeof(SECTION_IMAGE_INFORMATION)) ++ return STATUS_INFO_LENGTH_MISMATCH; ++ } ++ else ++ { ++ FIXME("%p,info_class=%d,%p,%u,%p) Unknown information class\n", ++ handle, info_class, buffer, len, ret_len); ++ return STATUS_INVALID_INFO_CLASS; ++ } ++ ++ if (!buffer) return STATUS_ACCESS_VIOLATION; ++ ++ SERVER_START_REQ( get_mapping_info ) ++ { ++ req->handle = wine_server_obj_handle( handle ); ++ req->access = SECTION_QUERY; ++ res = wine_server_call( req ); ++ protect = reply->protect; ++ base = wine_server_get_ptr( reply->base ); ++ size.QuadPart = reply->size; ++ dup_mapping = wine_server_ptr_handle( reply->mapping ); ++ shared_file = wine_server_ptr_handle( reply->shared_file ); ++ if ((ULONG_PTR)base != reply->base) base = NULL; ++ ++ entry = wine_server_get_ptr( reply->entry ); ++ subsystem = reply->subsystem; ++ major_subsystem = reply->major_subsystem; ++ minor_subsystem = reply->minor_subsystem; ++ characteristics = reply->characteristics; ++ dll_characteristics = reply->dll_characteristics; ++ machine = reply->machine; ++ } ++ SERVER_END_REQ; ++ if (res) return res; ++ ++ if (dup_mapping) NtClose( dup_mapping ); ++ if (shared_file) NtClose( shared_file ); ++ ++ if (info_class == SectionBasicInformation) ++ { ++ SECTION_BASIC_INFORMATION *info = buffer; ++ ++ info->BaseAddress = NULL; ++ info->Size = size; ++ info->Attributes = (protect & VPROT_COMMITTED) ? SEC_COMMIT : SEC_RESERVE; ++ if (protect & VPROT_NOCACHE) info->Attributes |= SEC_NOCACHE; ++ if (protect & VPROT_IMAGE) info->Attributes |= SEC_IMAGE; ++ /* FIXME: SEC_FILE */ ++ if (ret_len) *ret_len = sizeof(*info); ++ } ++ else ++ { ++ SECTION_IMAGE_INFORMATION *info = buffer; ++ ++ if (!(protect & VPROT_IMAGE)) ++ return STATUS_SECTION_NOT_IMAGE; ++ ++ memset( info, 0, sizeof(*info) ); ++ info->EntryPoint = entry; ++ info->StackZeroBits = 0; /* FIXME */ ++ info->StackReserved = 0; /* FIXME */ ++ info->StackCommit = 0; /* FIXME */ ++ info->ImageSubsystem = subsystem; ++ info->SubsystemVersionHigh = major_subsystem; ++ info->SubsystemVersionLow = minor_subsystem; ++ info->ImageCharacteristics = characteristics; ++ info->DllCharacteristics = dll_characteristics; ++ info->ImageMachineType = machine; ++ info->ImageContainsCode = TRUE; /* FIXME */ ++ if (ret_len) *ret_len = sizeof(*info); ++ } ++ ++ return STATUS_SUCCESS; ++} ++ ++ ++/*********************************************************************** + * NtMapViewOfSection (NTDLL.@) + * ZwMapViewOfSection (NTDLL.@) + */ +diff --git a/server/mapping.c b/server/mapping.c +index 64b3003..8a04183 100644 +--- a/server/mapping.c ++++ b/server/mapping.c +@@ -64,6 +64,15 @@ struct mapping + enum cpu_type cpu; /* client CPU (for PE image mapping) */ + int header_size; /* size of headers (for PE image mapping) */ + client_ptr_t base; /* default base addr (for PE image mapping) */ ++ client_ptr_t entry; /* entry point addr (for PE image mapping) */ ++ mem_size_t stack_reserve; /* stack reserve (for PE image mapping) */ ++ mem_size_t stack_commit; /* stack commit (for PE image mapping) */ ++ int subsystem; /* subsystem (for PE image mapping) */ ++ int major_subsystem; /* major subsystem version (for PE image mapping) */ ++ int minor_subsystem; /* minor subsystem version (for PE image mapping) */ ++ int characteristics; /* image characteristics (for PE image mapping) */ ++ int dll_characteristics; /* dll characteristics (for PE image mapping) */ ++ int machine; /* image machine type (for PE image mapping) */ + struct ranges *committed; /* list of committed ranges in this mapping */ + struct file *shared_file; /* temp file for shared PE mapping */ + struct list shared_entry; /* entry in global shared PE mappings list */ +@@ -430,17 +439,34 @@ static unsigned int get_image_params( struct mapping *mapping, int unix_fd, int + return STATUS_INVALID_IMAGE_FORMAT; + } + ++ mapping->characteristics = nt.FileHeader.Characteristics; ++ mapping->machine = nt.FileHeader.Machine; ++ + switch (nt.opt.hdr32.Magic) + { + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage ); + mapping->base = nt.opt.hdr32.ImageBase; + mapping->header_size = nt.opt.hdr32.SizeOfHeaders; ++ mapping->entry = mapping->base + nt.opt.hdr32.AddressOfEntryPoint; ++ mapping->stack_reserve = nt.opt.hdr32.SizeOfStackReserve; ++ mapping->stack_commit = nt.opt.hdr32.SizeOfStackCommit; ++ mapping->subsystem = nt.opt.hdr32.Subsystem; ++ mapping->major_subsystem = nt.opt.hdr32.MajorSubsystemVersion; ++ mapping->minor_subsystem = nt.opt.hdr32.MinorSubsystemVersion; ++ mapping->dll_characteristics = nt.opt.hdr32.DllCharacteristics; + break; + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage ); + mapping->base = nt.opt.hdr64.ImageBase; + mapping->header_size = nt.opt.hdr64.SizeOfHeaders; ++ mapping->entry = mapping->base + nt.opt.hdr64.AddressOfEntryPoint; ++ mapping->stack_reserve = nt.opt.hdr64.SizeOfStackReserve; ++ mapping->stack_commit = nt.opt.hdr64.SizeOfStackCommit; ++ mapping->subsystem = nt.opt.hdr64.Subsystem; ++ mapping->major_subsystem = nt.opt.hdr64.MajorSubsystemVersion; ++ mapping->minor_subsystem = nt.opt.hdr64.MinorSubsystemVersion; ++ mapping->dll_characteristics = nt.opt.hdr64.DllCharacteristics; + break; + } + +@@ -488,8 +514,18 @@ static struct object *create_mapping( struct directory *root, const struct unico + GROUP_SECURITY_INFORMATION| + DACL_SECURITY_INFORMATION| + SACL_SECURITY_INFORMATION ); ++ + mapping->header_size = 0; + mapping->base = 0; ++ mapping->entry = 0; ++ mapping->stack_reserve = 0; ++ mapping->stack_commit = 0; ++ mapping->subsystem = 0; ++ mapping->major_subsystem = 0; ++ mapping->minor_subsystem = 0; ++ mapping->characteristics = 0; ++ mapping->dll_characteristics = 0; ++ mapping->machine = 0; + mapping->fd = NULL; + mapping->shared_file = NULL; + mapping->committed = NULL; +@@ -727,6 +763,13 @@ DECL_HANDLER(get_mapping_info) + reply->protect = mapping->protect; + reply->header_size = mapping->header_size; + reply->base = mapping->base; ++ reply->entry = mapping->entry; ++ reply->subsystem = mapping->subsystem; ++ reply->major_subsystem = mapping->major_subsystem; ++ reply->minor_subsystem = mapping->minor_subsystem; ++ reply->characteristics = mapping->characteristics; ++ reply->dll_characteristics = mapping->dll_characteristics; ++ reply->machine = mapping->machine; + reply->shared_file = 0; + if ((fd = get_obj_fd( &mapping->obj ))) + { +diff --git a/server/protocol.def b/server/protocol.def +index c9270ea..9585fe2 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -1619,6 +1619,13 @@ enum char_info_mode + int protect; /* protection flags */ + int header_size; /* header size (for VPROT_IMAGE mapping) */ + client_ptr_t base; /* default base addr (for VPROT_IMAGE mapping) */ ++ client_ptr_t entry; /* entry point addr (for PE image mapping) */ ++ short int subsystem; /* subsystem (for PE image mapping) */ ++ short int major_subsystem; /* major subsystem version (for PE image mapping) */ ++ short int minor_subsystem; /* minor subsystem version (for PE image mapping) */ ++ short int characteristics; /* image characteristics (for PE image mapping) */ ++ short int dll_characteristics; /* dll characteristics (for PE image mapping) */ ++ short int machine; /* image machine type (for PE image mapping) */ + obj_handle_t mapping; /* duplicate mapping handle unless removable */ + obj_handle_t shared_file; /* shared mapping file handle */ + @END +-- +2.1.2 + diff --git a/patches/ntdll-NtQuerySection/0003-kernel32-tests-Add-tests-for-NtQuerySection.patch b/patches/ntdll-NtQuerySection/0003-kernel32-tests-Add-tests-for-NtQuerySection.patch new file mode 100644 index 00000000..383adea0 --- /dev/null +++ b/patches/ntdll-NtQuerySection/0003-kernel32-tests-Add-tests-for-NtQuerySection.patch @@ -0,0 +1,304 @@ +From 21625ff016038380562ff7461c0b8a8d1d781d3a Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 16 Oct 2014 23:26:35 +0200 +Subject: kernel32/tests: Add tests for NtQuerySection. + +--- + dlls/kernel32/tests/virtual.c | 258 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 258 insertions(+) + +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index 73b753e..302d175 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -46,9 +46,27 @@ static DWORD (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID); + static struct _TEB * (WINAPI *pNtCurrentTeb)(void); + static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, PVECTORED_EXCEPTION_HANDLER); + static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID); ++static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, int, PVOID, ULONG, PULONG); + + /* ############################### */ + ++static UINT_PTR page_mask = 0xfff; ++#define ROUND_SIZE(addr,size) \ ++ (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask) ++ ++static PIMAGE_NT_HEADERS image_nt_header(HMODULE module) ++{ ++ IMAGE_NT_HEADERS *ret = NULL; ++ IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)module; ++ ++ if (dos->e_magic == IMAGE_DOS_SIGNATURE) ++ { ++ ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew); ++ if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL; ++ } ++ return ret; ++} ++ + static HANDLE create_target_process(const char *arg) + { + char **argv; +@@ -3282,6 +3300,244 @@ static void test_shared_memory_ro(BOOL is_child, DWORD child_access) + CloseHandle(mapping); + } + ++static void test_NtQuerySection(void) ++{ ++ char path[MAX_PATH]; ++ HANDLE file, mapping; ++ void *p; ++ NTSTATUS status; ++ union ++ { ++ SECTION_BASIC_INFORMATION basic; ++ SECTION_IMAGE_INFORMATION image; ++ char buf[1024]; ++ } info; ++ IMAGE_NT_HEADERS *nt; ++ ULONG ret; ++ SIZE_T fsize, image_size; ++ SYSTEM_INFO si; ++ ++ if (!pNtQuerySection) ++ { ++ win_skip("NtQuerySection is not available\n"); ++ return; ++ } ++ ++ GetSystemInfo(&si); ++ page_mask = si.dwPageSize - 1; ++ ++ GetSystemDirectoryA(path, sizeof(path)); ++ strcat(path, "\\kernel32.dll"); ++ ++ SetLastError(0xdeadbef); ++ file = CreateFileA(path, GENERIC_READ|GENERIC_EXECUTE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); ++ ok(file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError()); ++ ++ fsize = GetFileSize(file, NULL); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(file, NULL, PAGE_EXECUTE_READ, 0, 0, NULL); ++ /* NT4 and win2k don't support EXEC on file mappings */ ++ if (!mapping) ++ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL); ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ ++ status = pNtQuerySection(mapping, SectionBasicInformation, NULL, sizeof(info), &ret); ++ ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, 0, NULL); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, 0, &ret); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++todo_wine ++ ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", info.basic.Attributes); ++todo_wine ++ ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", fsize, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, sizeof(info.basic), &ret); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SECTION_NOT_IMAGE, "expected STATUS_SECTION_NOT_IMAGE, got %#x\n", status); ++ ++ SetLastError(0xdeadbef); ++ p = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); ++ ok(p != NULL, "MapViewOfFile error %u\n", GetLastError()); ++ ++ nt = image_nt_header(p); ++ image_size = ROUND_SIZE(p, nt->OptionalHeader.SizeOfImage); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++todo_wine ++ ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", info.basic.Attributes); ++todo_wine ++ ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", fsize, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ UnmapViewOfFile(p); ++ CloseHandle(mapping); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(file, NULL, PAGE_EXECUTE_READ|SEC_IMAGE, 0, 0, NULL); ++ /* NT4 and win2k don't support EXEC on file mappings */ ++ if (!mapping) ++ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, NULL); ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++todo_wine ++ ok(info.basic.Attributes == (SEC_FILE|SEC_IMAGE), "expected SEC_FILE|SEC_IMAGE, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == image_size, "expected %#lx, got %#x/%08x\n", image_size, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, NULL, sizeof(info), &ret); ++ ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, 0, NULL); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, 0, &ret); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, sizeof(info.basic), &ret); ++ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %#x\n", status); ++ ++ SetLastError(0xdeadbef); ++ p = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); ++ ok(p != NULL, "MapViewOfFile error %u\n", GetLastError()); ++ ++ nt = image_nt_header(p); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionImageInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.image), "wrong returned size %u\n", ret); ++ ok((ULONG_PTR)info.image.EntryPoint == nt->OptionalHeader.ImageBase + nt->OptionalHeader.AddressOfEntryPoint, ++ "expected %#x, got %p\n", nt->OptionalHeader.ImageBase + nt->OptionalHeader.AddressOfEntryPoint, info.image.EntryPoint); ++ ok(info.image.StackZeroBits == 0, "expected 0, got %#x\n", info.image.StackZeroBits); ++todo_wine ++ ok(info.image.StackReserved == nt->OptionalHeader.SizeOfStackReserve, "expected %#x, got %#lx\n", nt->OptionalHeader.SizeOfStackReserve, info.image.StackReserved); ++todo_wine ++ ok(info.image.StackCommit == nt->OptionalHeader.SizeOfStackCommit, "expected %#x, got %#lx\n", nt->OptionalHeader.SizeOfStackCommit, info.image.StackCommit); ++ ok(info.image.ImageSubsystem == nt->OptionalHeader.Subsystem, "expected %#x, got %#x\n", nt->OptionalHeader.Subsystem, info.image.ImageSubsystem); ++ ok(info.image.SubsystemVersionLow == nt->OptionalHeader.MinorSubsystemVersion, "expected %#x, got %#x\n", nt->OptionalHeader.MinorSubsystemVersion, info.image.SubsystemVersionLow); ++ ok(info.image.SubsystemVersionHigh == nt->OptionalHeader.MajorSubsystemVersion, "expected %#x, got %#x\n", nt->OptionalHeader.MajorSubsystemVersion, info.image.SubsystemVersionHigh); ++ ok(info.image.ImageCharacteristics == nt->FileHeader.Characteristics, "expected %#x, got %#x\n", nt->FileHeader.Characteristics, info.image.ImageCharacteristics); ++ ok(info.image.DllCharacteristics == nt->OptionalHeader.DllCharacteristics, "expected %#x, got %#x\n", nt->OptionalHeader.DllCharacteristics, info.image.DllCharacteristics); ++ ok(info.image.ImageMachineType == nt->FileHeader.Machine, "expected %#x, got %#x\n", nt->FileHeader.Machine, info.image.ImageMachineType); ++ ok(info.image.ImageContainsCode == TRUE, "expected 1, got %#x\n", info.image.ImageContainsCode); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++todo_wine ++ ok(info.basic.Attributes == (SEC_FILE|SEC_IMAGE), "expected SEC_FILE|SEC_IMAGE, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == image_size, "expected %#lx, got %#x/%08x\n", image_size, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ UnmapViewOfFile(p); ++ CloseHandle(mapping); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY|SEC_COMMIT|SEC_NOCACHE, 0, 0, NULL); ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++todo_wine ++ ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", info.basic.Attributes); ++todo_wine ++ ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", fsize, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ CloseHandle(mapping); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY|SEC_RESERVE, 0, 0, NULL); ++todo_wine ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ if (!mapping) goto skip1; ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++ ok(info.basic.Attributes == SEC_FILE, "expected SEC_FILE, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == fsize, "expected %#lx, got %#x/%08x\n", fsize, info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ CloseHandle(mapping); ++skip1: ++ CloseHandle(file); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE|SEC_COMMIT, 0, 4096, NULL); ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++ ok(info.basic.Attributes == SEC_COMMIT, "expected SEC_COMMIT, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == 4096, "expected 4096, got %#x/%08x\n", info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ SetLastError(0xdeadbef); ++ p = MapViewOfFile(mapping, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0); ++ ok(p != NULL, "MapViewOfFile error %u\n", GetLastError()); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++ ok(info.basic.Attributes == SEC_COMMIT, "expected SEC_COMMIT, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == 4096, "expected 4096, got %#x/%08x\n", info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ UnmapViewOfFile(p); ++ CloseHandle(mapping); ++ ++ SetLastError(0xdeadbef); ++ mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READONLY|SEC_RESERVE, 0, 4096, NULL); ++ ok(mapping != 0, "CreateFileMapping error %u\n", GetLastError()); ++ ++ memset(&info, 0x55, sizeof(info)); ++ ret = 0xdeadbeef; ++ status = pNtQuerySection(mapping, SectionBasicInformation, &info, sizeof(info), &ret); ++ ok(status == STATUS_SUCCESS, "NtQuerySection error %#x\n", status); ++ ok(ret == sizeof(info.basic), "wrong returned size %u\n", ret); ++ ok(info.basic.BaseAddress == NULL, "expected NULL, got %p\n", info.basic.BaseAddress); ++ ok(info.basic.Attributes == SEC_RESERVE, "expected SEC_RESERVE, got %#x\n", info.basic.Attributes); ++ ok(info.basic.Size.QuadPart == 4096, "expected 4096, got %#x/%08x\n", info.basic.Size.HighPart, info.basic.Size.LowPart); ++ ++ CloseHandle(mapping); ++} ++ + START_TEST(virtual) + { + int argc; +@@ -3333,12 +3589,14 @@ START_TEST(virtual) + pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" ); + pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" ); + pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" ); ++ pNtQuerySection = (void *)GetProcAddress( hntdll, "NtQuerySection" ); + + test_shared_memory(FALSE); + test_shared_memory_ro(FALSE, FILE_MAP_READ|FILE_MAP_WRITE); + test_shared_memory_ro(FALSE, FILE_MAP_COPY); + test_shared_memory_ro(FALSE, FILE_MAP_COPY|FILE_MAP_WRITE); + test_mapping(); ++ test_NtQuerySection(); + test_CreateFileMapping_protection(); + test_VirtualAlloc_protection(); + test_VirtualProtect(); +-- +2.1.2 + diff --git a/patches/ntdll-NtQuerySection/definition b/patches/ntdll-NtQuerySection/definition index 85269603..a7a1c808 100644 --- a/patches/ntdll-NtQuerySection/definition +++ b/patches/ntdll-NtQuerySection/definition @@ -1,4 +1,4 @@ Author: Dmitry Timoshkov Subject: Implement NtQuerySection class SectionBasicInformation. -Revision: 1 +Revision: 2 Fixes: [37338] Support for NtQuerySection