ntdll: Implement the SectionBasicInformation class of NtQuerySection.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-07-26 14:43:02 +09:00
parent 1ddc636051
commit 2602df14d8
6 changed files with 182 additions and 25 deletions

View File

@ -52,6 +52,7 @@ static DWORD page_size;
static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
const LARGE_INTEGER *, ULONG, ULONG, HANDLE );
static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, ULONG, ULONG *);
static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG);
static NTSTATUS (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
@ -241,8 +242,21 @@ static NTSTATUS map_image_section( const IMAGE_NT_HEADERS *nt_header )
file = CreateFileA(dll_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
status = pNtCreateSection(&map, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ, NULL, &size,
PAGE_READONLY, SEC_IMAGE, file );
status = pNtCreateSection(&map, STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ | SECTION_QUERY,
NULL, &size, PAGE_READONLY, SEC_IMAGE, file );
if (!status)
{
SECTION_BASIC_INFORMATION info;
ULONG info_size = 0xdeadbeef;
NTSTATUS ret = pNtQuerySection( map, SectionBasicInformation, &info, sizeof(info), &info_size );
ok( !ret, "NtQuerySection failed err %x\n", ret );
ok( info_size == sizeof(info), "NtQuerySection wrong size %u\n", info_size );
ok( info.Attributes == (SEC_IMAGE | SEC_FILE), "NtQuerySection wrong attr %x\n", info.Attributes );
ok( info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", info.BaseAddress );
todo_wine
ok( info.Size.QuadPart == size.QuadPart, "NtQuerySection wrong size %x%08x / %x%08x\n",
info.Size.u.HighPart, info.Size.u.LowPart, size.u.HighPart, size.u.LowPart );
}
if (map) CloseHandle( map );
CloseHandle( file );
DeleteFileA( dll_name );
@ -2777,6 +2791,7 @@ START_TEST(loader)
ntdll = GetModuleHandleA("ntdll.dll");
pNtCreateSection = (void *)GetProcAddress(ntdll, "NtCreateSection");
pNtQuerySection = (void *)GetProcAddress(ntdll, "NtQuerySection");
pNtMapViewOfSection = (void *)GetProcAddress(ntdll, "NtMapViewOfSection");
pNtUnmapViewOfSection = (void *)GetProcAddress(ntdll, "NtUnmapViewOfSection");
pNtTerminateProcess = (void *)GetProcAddress(ntdll, "NtTerminateProcess");

View File

@ -41,8 +41,11 @@ static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD);
static UINT (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
static UINT (WINAPI *pResetWriteWatch)(LPVOID,SIZE_T);
static NTSTATUS (WINAPI *pNtAreMappedFilesTheSame)(PVOID,PVOID);
static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
const LARGE_INTEGER *, ULONG, ULONG, HANDLE );
static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG);
static DWORD (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, ULONG, ULONG *);
static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, PVECTORED_EXCEPTION_HANDLER);
static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
static BOOL (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL);
@ -406,9 +409,13 @@ static void test_MapViewOfFile(void)
const char *name;
HANDLE file, mapping, map2;
void *ptr, *ptr2, *addr;
SECTION_BASIC_INFORMATION section_info;
MEMORY_BASIC_INFORMATION info;
BOOL ret;
SIZE_T size;
NTSTATUS status;
ULONG info_size;
LARGE_INTEGER map_size;
SetLastError(0xdeadbeef);
file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
@ -591,12 +598,12 @@ static void test_MapViewOfFile(void)
SetLastError(0xdeadbeef);
name = "Local\\Foo";
file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4090, name );
/* nt4 doesn't have Local\\ */
if (!file && GetLastError() == ERROR_PATH_NOT_FOUND)
{
name = "Foo";
file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
file = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4090, name );
}
ok( file != 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
@ -621,6 +628,21 @@ static void test_MapViewOfFile(void)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
UnmapViewOfFile( ptr );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( status == STATUS_ACCESS_DENIED, "NtQuerySection failed err %x\n", status );
CloseHandle( mapping );
mapping = OpenFileMappingA( FILE_MAP_READ | SECTION_QUERY, FALSE, name );
ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info_size == sizeof(section_info), "NtQuerySection wrong size %u\n", info_size );
ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
ok( section_info.Size.QuadPart == info.RegionSize, "NtQuerySection wrong size %x%08x / %08lx\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart, info.RegionSize );
CloseHandle( mapping );
SetLastError(0xdeadbeef);
@ -644,6 +666,22 @@ static void test_MapViewOfFile(void)
ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
UnmapViewOfFile( ptr );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( status == STATUS_ACCESS_DENIED, "NtQuerySection failed err %x\n", status );
CloseHandle( mapping );
mapping = OpenFileMappingA( FILE_MAP_WRITE | SECTION_QUERY, FALSE, name );
ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info_size == sizeof(section_info), "NtQuerySection wrong size %u\n", info_size );
ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
ok( section_info.Size.QuadPart == info.RegionSize, "NtQuerySection wrong size %x%08x / %08lx\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart, info.RegionSize );
CloseHandle( mapping );
CloseHandle( file );
@ -651,6 +689,14 @@ static void test_MapViewOfFile(void)
/* read/write mapping with SEC_RESERVE */
mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0, MAPPING_SIZE, NULL);
ok(mapping != INVALID_HANDLE_VALUE, "CreateFileMappingA failed with error %d\n", GetLastError());
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( section_info.Attributes == SEC_RESERVE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %x%08x / %08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart, MAPPING_SIZE );
ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
@ -842,6 +888,15 @@ static void test_MapViewOfFile(void)
SetLastError(0xdeadbeef);
ret = CloseHandle(map2);
ok(ret, "CloseHandle error %d\n", GetLastError());
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info_size == sizeof(section_info), "NtQuerySection wrong size %u\n", info_size );
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
SetLastError(0xdeadbeef);
ret = CloseHandle(mapping);
ok(ret, "CloseHandle error %d\n", GetLastError());
@ -926,6 +981,69 @@ static void test_MapViewOfFile(void)
ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() );
CloseHandle(mapping);
mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 36, NULL );
ok( mapping != NULL, "CreateFileMappingA failed with error %u\n", GetLastError() );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info_size == sizeof(section_info), "NtQuerySection wrong size %u\n", info_size );
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 36, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
SetFilePointer(file, 0x3456, NULL, FILE_BEGIN);
SetEndOfFile(file);
mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 0, NULL );
ok( mapping != NULL, "CreateFileMappingA failed with error %u\n", GetLastError() );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
sizeof(section_info), &info_size );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( info_size == sizeof(section_info), "NtQuerySection wrong size %u\n", info_size );
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 0x3456, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
map_size.QuadPart = 0x3457;
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
&map_size, PAGE_READONLY, SEC_COMMIT, file );
todo_wine
ok( status == STATUS_SECTION_TOO_BIG, "NtCreateSection failed %x\n", status );
if (!status) CloseHandle( mapping );
map_size.QuadPart = 0x3452;
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
&map_size, PAGE_READONLY, SEC_COMMIT, file );
ok( !status, "NtCreateSection failed %x\n", status );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
todo_wine
ok( section_info.Size.QuadPart == 0x3452, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
&map_size, PAGE_READONLY, SEC_COMMIT, 0 );
ok( !status, "NtCreateSection failed %x\n", status );
status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info), NULL );
ok( !status, "NtQuerySection failed err %x\n", status );
ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08x\n",
section_info.Attributes );
ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
ok( section_info.Size.QuadPart == 0x4000, "NtQuerySection wrong size %x%08x\n",
section_info.Size.u.HighPart, section_info.Size.u.LowPart );
CloseHandle(mapping);
CloseHandle(file);
DeleteFileA(testfile);
}
@ -3747,8 +3865,10 @@ START_TEST(virtual)
pGetProcessDEPPolicy = (void *)GetProcAddress( hkernel32, "GetProcessDEPPolicy" );
pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" );
pNtAreMappedFilesTheSame = (void *)GetProcAddress( hntdll, "NtAreMappedFilesTheSame" );
pNtCreateSection = (void *)GetProcAddress( hntdll, "NtCreateSection" );
pNtMapViewOfSection = (void *)GetProcAddress( hntdll, "NtMapViewOfSection" );
pNtUnmapViewOfSection = (void *)GetProcAddress( hntdll, "NtUnmapViewOfSection" );
pNtQuerySection = (void *)GetProcAddress( hntdll, "NtQuerySection" );
pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" );
pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" );
pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" );

View File

@ -645,25 +645,6 @@ NTSTATUS WINAPI NtPrivilegeCheck(
return status;
}
/*
* 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
*/

View File

@ -269,7 +269,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)
@ -1194,7 +1194,7 @@
@ stdcall ZwQueryPerformanceCounter(ptr ptr) 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 ptr long ptr) NtQuerySemaphore
@ stdcall ZwQuerySymbolicLinkObject(long ptr ptr) NtQuerySymbolicLinkObject

View File

@ -2761,6 +2761,41 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
}
/******************************************************************************
* NtQuerySection (NTDLL.@)
* ZwQuerySection (NTDLL.@)
*/
NTSTATUS WINAPI NtQuerySection( HANDLE handle, SECTION_INFORMATION_CLASS class, void *ptr,
ULONG size, ULONG *ret_size )
{
NTSTATUS status;
SECTION_BASIC_INFORMATION *basic_info = ptr;
if (class != SectionBasicInformation)
{
FIXME( "class %u not implemented\n", class );
return STATUS_NOT_IMPLEMENTED;
}
if (size < sizeof(*basic_info)) return STATUS_INFO_LENGTH_MISMATCH;
SERVER_START_REQ( get_mapping_info )
{
req->handle = wine_server_obj_handle( handle );
req->access = SECTION_QUERY;
if (!(status = wine_server_call( req )))
{
basic_info->Attributes = reply->flags;
basic_info->BaseAddress = NULL;
basic_info->Size.QuadPart = reply->size;
if (ret_size) *ret_size = sizeof(*basic_info);
}
}
SERVER_END_REQ;
return status;
}
/***********************************************************************
* NtFlushVirtualMemory (NTDLL.@)
* ZwFlushVirtualMemory (NTDLL.@)

View File

@ -704,6 +704,12 @@ DECL_HANDLER(get_mapping_info)
reply->header_size = mapping->header_size;
reply->base = mapping->base;
if (!(req->access & (SECTION_MAP_READ | SECTION_MAP_WRITE))) /* query only */
{
release_object( mapping );
return;
}
if ((mapping->flags & SEC_IMAGE) && mapping->cpu != current->process->cpu)
{
set_error( STATUS_INVALID_IMAGE_FORMAT );