From 21d673afd6f937a90c4bf4a578f6b3bcf4aa2940 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 16 Oct 2014 23:26:35 +0200
Subject: kernel32/tests: Add tests for NtQuerySection. (try 2)

---
 dlls/kernel32/tests/virtual.c | 245 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 245 insertions(+)

diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 46b019c5817..b0c3db0fb76 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -57,6 +57,23 @@ static NTSTATUS (WINAPI *pNtFreeVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG)
 
 /* ############################### */
 
+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;
@@ -4204,6 +4221,233 @@ 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;
+    SIZE_T 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);
+    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);
+
+    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);
+    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);
+
+    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);
+    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.TransferAddress == nt->OptionalHeader.ImageBase + nt->OptionalHeader.AddressOfEntryPoint,
+       "expected %#lx, got %p\n", (SIZE_T)(nt->OptionalHeader.ImageBase + nt->OptionalHeader.AddressOfEntryPoint), info.image.TransferAddress);
+    ok(info.image.ZeroBits == 0, "expected 0, got %#x\n", info.image.ZeroBits);
+    ok(info.image.MaximumStackSize == nt->OptionalHeader.SizeOfStackReserve, "expected %#lx, got %#lx\n", (SIZE_T)nt->OptionalHeader.SizeOfStackReserve, info.image.MaximumStackSize);
+    ok(info.image.CommittedStackSize == nt->OptionalHeader.SizeOfStackCommit, "expected %#lx, got %#lx\n", (SIZE_T)nt->OptionalHeader.SizeOfStackCommit, info.image.CommittedStackSize);
+    ok(info.image.SubSystemType == nt->OptionalHeader.Subsystem, "expected %#x, got %#x\n", nt->OptionalHeader.Subsystem, info.image.SubSystemType);
+    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.Machine == nt->FileHeader.Machine, "expected %#x, got %#x\n", nt->FileHeader.Machine, info.image.Machine);
+todo_wine
+    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);
+    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);
+    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);
+    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_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);
+    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;
@@ -4270,6 +4514,7 @@ START_TEST(virtual)
     test_shared_memory_ro(FALSE, FILE_MAP_COPY);
     test_shared_memory_ro(FALSE, FILE_MAP_COPY|FILE_MAP_WRITE);
     test_mappings();
+    test_NtQuerySection();
     test_CreateFileMapping_protection();
     test_VirtualAlloc_protection();
     test_VirtualProtect();
-- 
2.14.1

