Reactos
1/*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Test for NtQuerySection
5 * COPYRIGHT: Copyright 2025 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#include "precomp.h"
9
10static
11HANDLE
12CreateSection(ULONG Size, ULONG Protection, ULONG Attributes, HANDLE hFile)
13{
14 NTSTATUS Status;
15 HANDLE hSection = NULL;
16 LARGE_INTEGER MaximumSize;
17
18 MaximumSize.QuadPart = Size;
19 Status = NtCreateSection(&hSection,
20 SECTION_ALL_ACCESS,
21 NULL, // ObjectAttributes
22 &MaximumSize,
23 Protection,
24 Attributes,
25 hFile);
26 ok_ntstatus(Status, STATUS_SUCCESS);
27 return hSection;
28}
29
30static
31VOID
32QuerySbi(SECTION_BASIC_INFORMATION *SectionInfo, HANDLE hSection)
33{
34 NTSTATUS Status;
35 SIZE_T ReturnLength;
36
37 Status = NtQuerySection(hSection,
38 SectionBasicInformation,
39 SectionInfo,
40 sizeof(*SectionInfo),
41 &ReturnLength);
42 ok_ntstatus(Status, STATUS_SUCCESS);
43 ok_eq_hex(ReturnLength, sizeof(*SectionInfo));
44}
45
46void Test_SectionBasicInformation(void)
47{
48 NTSTATUS Status;
49 HANDLE hSection, hFile;
50 SECTION_BASIC_INFORMATION SectionInfo;
51 SIZE_T ReturnLength;
52
53 // Create a section with SEC_COMMIT
54 hSection = CreateSection(0x123, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
55 ok(hSection != NULL, "hSection is NULL\n");
56
57 // Call NtQuerySection with SectionBasicInformation and a NULL handle
58 Status = NtQuerySection(NULL,
59 SectionBasicInformation,
60 &SectionInfo,
61 sizeof(SectionInfo),
62 &ReturnLength);
63 ok_ntstatus(Status, STATUS_INVALID_HANDLE);
64
65 // Call NtQuerySection with SectionBasicInformation and a NULL buffer
66 Status = NtQuerySection(hSection,
67 SectionBasicInformation,
68 NULL,
69 sizeof(SectionInfo),
70 &ReturnLength);
71 ok_ntstatus(Status, STATUS_ACCESS_VIOLATION);
72
73 // Call NtQuerySection with SectionBasicInformation and a too small buffer
74 Status = NtQuerySection(hSection,
75 SectionBasicInformation,
76 &SectionInfo,
77 sizeof(SectionInfo) - 1,
78 &ReturnLength);
79 ok_ntstatus(Status, STATUS_INFO_LENGTH_MISMATCH);
80
81 // Call NtQuerySection with SectionBasicInformation and proper parameters
82 Status = NtQuerySection(hSection,
83 SectionBasicInformation,
84 &SectionInfo,
85 sizeof(SectionInfo),
86 &ReturnLength);
87 ok_ntstatus(Status, STATUS_SUCCESS);
88 ok_eq_hex(ReturnLength, sizeof(SectionInfo));
89 ok_eq_pointer(SectionInfo.BaseAddress, NULL);
90 ok_eq_hex(SectionInfo.Attributes, SEC_COMMIT);
91 ok_eq_hex64(SectionInfo.Size.QuadPart, PAGE_SIZE);
92 NtClose(hSection);
93
94 // Section with SEC_RESERVE
95 hSection = CreateSection(PAGE_SIZE + 1, PAGE_EXECUTE_READWRITE, SEC_RESERVE, NULL);
96 ok(hSection != NULL, "hSection is NULL\n");
97 QuerySbi(&SectionInfo, hSection);
98 ok_eq_pointer(SectionInfo.BaseAddress, NULL);
99 ok_eq_hex(SectionInfo.Attributes, SEC_RESERVE);
100 ok_eq_hex64(SectionInfo.Size.QuadPart, 2 * PAGE_SIZE);
101 NtClose(hSection);
102
103 // Section with SEC_BASED
104 hSection = CreateSection(0x20000, PAGE_EXECUTE_READWRITE, SEC_BASED | SEC_COMMIT, NULL);
105 ok(hSection != NULL, "hSection is NULL\n");
106 QuerySbi(&SectionInfo, hSection);
107 ok(SectionInfo.BaseAddress != NULL, "BaseAddress is NULL\n");
108 ok_eq_hex(SectionInfo.Attributes, SEC_BASED | SEC_COMMIT);
109 ok_eq_hex64(SectionInfo.Size.QuadPart, 0x20000);
110 NtClose(hSection);
111
112 // Open this executable file
113 CHAR TestExecutableName[MAX_PATH];
114 GetModuleFileNameA(NULL, TestExecutableName, sizeof(TestExecutableName));
115 hFile = CreateFileA(TestExecutableName,
116 GENERIC_READ | GENERIC_EXECUTE,
117 FILE_SHARE_READ,
118 NULL,
119 OPEN_EXISTING,
120 FILE_ATTRIBUTE_NORMAL,
121 NULL);
122 ok(hFile != INVALID_HANDLE_VALUE, "Failed to open file %s\n", TestExecutableName);
123
124 // Section with SEC_IMAGE and 0 size
125 hSection = CreateSection(0, PAGE_READONLY, SEC_IMAGE, hFile);
126 ok(hSection != NULL, "hSection is NULL\n");
127 QuerySbi(&SectionInfo, hSection);
128 ok_eq_pointer(SectionInfo.BaseAddress, NULL);
129 ok_eq_hex(SectionInfo.Attributes, SEC_FILE | SEC_IMAGE);
130 ok(SectionInfo.Size.QuadPart >= 3 * PAGE_SIZE, "Unexpected size:%I64x\n", SectionInfo.Size.QuadPart);
131 NtClose(hSection);
132
133 // Section with SEC_IMAGE and specific size
134 hSection = CreateSection(42, PAGE_EXECUTE_READ, SEC_IMAGE, hFile);
135 ok(hSection != NULL, "hSection is NULL\n");
136 QuerySbi(&SectionInfo, hSection);
137 ok_eq_pointer(SectionInfo.BaseAddress, NULL);
138 ok_eq_hex(SectionInfo.Attributes, SEC_FILE | SEC_IMAGE);
139 ok_eq_hex64(SectionInfo.Size.QuadPart, 42);
140 NtClose(hSection);
141
142 // File backed section with SEC_RESERVE (ignored)
143 hSection = CreateSection(1, PAGE_EXECUTE_READ, SEC_RESERVE, hFile);
144 ok(hSection != NULL, "hSection is NULL\n");
145 QuerySbi(&SectionInfo, hSection);
146 ok_eq_pointer(SectionInfo.BaseAddress, NULL);
147 ok_eq_hex(SectionInfo.Attributes, SEC_FILE);
148 ok_eq_hex64(SectionInfo.Size.QuadPart, 1);
149 NtClose(hSection);
150
151 // Close the file handle
152 NtClose(hFile);
153}
154
155START_TEST(NtQuerySection)
156{
157 Test_SectionBasicInformation();
158}