1 /* 2 * PROJECT: ReactOS API Tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Small library with probing utilities for thread/process classes information 5 * COPYRIGHT: Copyright 2020 George Bișoc <george.bisoc@reactos.org> 6 */ 7 8 #include "precomp.h" 9 #include <internal/ps_i.h> 10 11 VOID 12 QuerySetProcessValidator( 13 _In_ ALIGNMENT_PROBE_MODE ValidationMode, 14 _In_ ULONG InfoClassIndex, 15 _In_ PVOID InfoPointer, 16 _In_ ULONG InfoLength, 17 _In_ NTSTATUS ExpectedStatus) 18 { 19 NTSTATUS Status, SpecialStatus = STATUS_SUCCESS; 20 21 /* Before doing anything, check if we want query or set validation */ 22 switch (ValidationMode) 23 { 24 case QUERY: 25 { 26 switch (InfoClassIndex) 27 { 28 case ProcessWorkingSetWatch: 29 { 30 SpecialStatus = STATUS_UNSUCCESSFUL; 31 break; 32 } 33 34 case ProcessHandleTracing: 35 { 36 SpecialStatus = STATUS_INVALID_PARAMETER; 37 break; 38 } 39 40 /* 41 * This class returns an arbitrary size pointed by InformationLength 42 * which equates to the image filename of the process. Such status 43 * is returned in an invalid address query (STATUS_ACCESS_VIOLATION) 44 * where the function expects STATUS_INFO_LENGTH_MISMATCH instead. 45 */ 46 case ProcessImageFileName: 47 { 48 SpecialStatus = STATUS_INFO_LENGTH_MISMATCH; 49 break; 50 } 51 52 /* These classes don't belong in the query group */ 53 case ProcessBasePriority: 54 case ProcessRaisePriority: 55 case ProcessExceptionPort: 56 case ProcessAccessToken: 57 case ProcessLdtSize: 58 case ProcessIoPortHandlers: 59 case ProcessUserModeIOPL: 60 case ProcessEnableAlignmentFaultFixup: 61 case ProcessAffinityMask: 62 case ProcessForegroundInformation: 63 { 64 SpecialStatus = STATUS_INVALID_INFO_CLASS; 65 break; 66 } 67 68 /* These classes don't exist in Server 2003 */ 69 case ProcessIoPriority: 70 case ProcessTlsInformation: 71 case ProcessCycleTime: 72 case ProcessPagePriority: 73 case ProcessInstrumentationCallback: 74 case ProcessThreadStackAllocation: 75 case ProcessWorkingSetWatchEx: 76 case ProcessImageFileNameWin32: 77 case ProcessImageFileMapping: 78 case ProcessAffinityUpdateMode: 79 case ProcessMemoryAllocationMode: 80 { 81 SpecialStatus = STATUS_INVALID_INFO_CLASS; 82 break; 83 } 84 } 85 86 /* Query the information */ 87 Status = NtQueryInformationProcess(NtCurrentProcess(), 88 InfoClassIndex, 89 InfoPointer, 90 InfoLength, 91 NULL); 92 93 /* And probe the results we've got */ 94 ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT, 95 "0x%lx or special status (0x%lx) expected but got 0x%lx for class information %lu in query information process operation!\n", ExpectedStatus, SpecialStatus, Status, InfoClassIndex); 96 break; 97 } 98 99 case SET: 100 { 101 switch (InfoClassIndex) 102 { 103 case ProcessIoPortHandlers: 104 { 105 SpecialStatus = STATUS_INVALID_PARAMETER; 106 break; 107 } 108 109 /* 110 * This class returns STATUS_SUCCESS when testing 111 * for STATUS_ACCESS_VIOLATION (setting an invalid address). 112 */ 113 case ProcessWorkingSetWatch: 114 { 115 SpecialStatus = STATUS_PORT_ALREADY_SET; 116 break; 117 } 118 119 case ProcessUserModeIOPL: 120 { 121 SpecialStatus = STATUS_PRIVILEGE_NOT_HELD; 122 break; 123 } 124 125 /* These classes don't belong in the set group */ 126 case ProcessBasicInformation: 127 case ProcessIoCounters: 128 case ProcessVmCounters: 129 case ProcessTimes: 130 case ProcessDebugPort: 131 case ProcessPooledUsageAndLimits: 132 case ProcessHandleCount: 133 case ProcessWow64Information: 134 case ProcessImageFileName: 135 case ProcessLUIDDeviceMapsEnabled: 136 case ProcessDebugObjectHandle: 137 case ProcessCookie: 138 case ProcessImageInformation: 139 { 140 SpecialStatus = STATUS_INVALID_INFO_CLASS; 141 break; 142 } 143 144 /* These classes don't exist in Server 2003 */ 145 case ProcessIoPriority: 146 case ProcessTlsInformation: 147 case ProcessCycleTime: 148 case ProcessPagePriority: 149 case ProcessInstrumentationCallback: 150 case ProcessThreadStackAllocation: 151 case ProcessWorkingSetWatchEx: 152 case ProcessImageFileNameWin32: 153 case ProcessImageFileMapping: 154 case ProcessAffinityUpdateMode: 155 case ProcessMemoryAllocationMode: 156 { 157 SpecialStatus = STATUS_INVALID_INFO_CLASS; 158 break; 159 } 160 161 /* Alignment probing is not performed for these classes */ 162 case ProcessEnableAlignmentFaultFixup: 163 case ProcessPriorityClass: 164 case ProcessForegroundInformation: 165 { 166 SpecialStatus = STATUS_ACCESS_VIOLATION; 167 break; 168 } 169 } 170 171 /* Set the information */ 172 Status = NtSetInformationProcess(NtCurrentProcess(), 173 InfoClassIndex, 174 InfoPointer, 175 InfoLength); 176 177 /* And probe the results we've got */ 178 ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT || Status == STATUS_SUCCESS, 179 "0x%lx or special status (0x%lx) expected but got 0x%lx for class information %lu in set information process operation!\n", ExpectedStatus, SpecialStatus, Status, InfoClassIndex); 180 break; 181 } 182 183 default: 184 break; 185 } 186 } 187 188 VOID 189 QuerySetThreadValidator( 190 _In_ ALIGNMENT_PROBE_MODE ValidationMode, 191 _In_ ULONG InfoClassIndex, 192 _In_ PVOID InfoPointer, 193 _In_ ULONG InfoLength, 194 _In_ NTSTATUS ExpectedStatus) 195 { 196 NTSTATUS Status, SpecialStatus = STATUS_SUCCESS; 197 198 /* Before doing anything, check if we want query or set validation */ 199 switch (ValidationMode) 200 { 201 case QUERY: 202 { 203 switch (InfoClassIndex) 204 { 205 /* These classes don't belong in the query group */ 206 case ThreadPriority: 207 case ThreadBasePriority: 208 case ThreadAffinityMask: 209 case ThreadImpersonationToken: 210 case ThreadEnableAlignmentFaultFixup: 211 case ThreadZeroTlsCell: 212 case ThreadIdealProcessor: 213 case ThreadSetTlsArrayAddress: 214 case ThreadHideFromDebugger: 215 case ThreadSwitchLegacyState: 216 { 217 SpecialStatus = STATUS_INVALID_INFO_CLASS; 218 break; 219 } 220 221 /* These classes don't exist in Server 2003 SP2 */ 222 case ThreadEventPair_Reusable: 223 case ThreadLastSystemCall: 224 case ThreadIoPriority: 225 case ThreadCycleTime: 226 case ThreadPagePriority: 227 case ThreadActualBasePriority: 228 case ThreadTebInformation: 229 case ThreadCSwitchMon: 230 { 231 SpecialStatus = STATUS_INVALID_INFO_CLASS; 232 break; 233 } 234 } 235 236 /* Query the information */ 237 Status = NtQueryInformationThread(NtCurrentThread(), 238 InfoClassIndex, 239 InfoPointer, 240 InfoLength, 241 NULL); 242 243 /* And probe the results we've got */ 244 ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT, 245 "0x%lx or special status (0x%lx) expected but got 0x%lx for class information %lu in query information thread operation!\n", ExpectedStatus, SpecialStatus, Status, InfoClassIndex); 246 break; 247 } 248 249 case SET: 250 { 251 switch (InfoClassIndex) 252 { 253 /* This class is not implemented in Windows Server 2003 SP2 */ 254 case ThreadSwitchLegacyState: 255 { 256 SpecialStatus = STATUS_NOT_IMPLEMENTED; 257 break; 258 } 259 260 /* 261 * This class doesn't take a strict type for size length. 262 * The function happily succeds on an information length 263 * mismatch scenario with STATUS_SUCCESS. 264 */ 265 case ThreadHideFromDebugger: 266 { 267 SpecialStatus = STATUS_INFO_LENGTH_MISMATCH; 268 break; 269 } 270 271 /* These classes don't belong in the set group */ 272 case ThreadBasicInformation: 273 case ThreadTimes: 274 case ThreadDescriptorTableEntry: 275 case ThreadPerformanceCount: 276 case ThreadAmILastThread: 277 case ThreadIsIoPending: 278 case ThreadIsTerminated: 279 { 280 SpecialStatus = STATUS_INVALID_INFO_CLASS; 281 break; 282 } 283 284 /* These classes don't exist in Server 2003 SP2 */ 285 case ThreadEventPair_Reusable: 286 case ThreadLastSystemCall: 287 case ThreadIoPriority: 288 case ThreadCycleTime: 289 case ThreadPagePriority: 290 case ThreadActualBasePriority: 291 case ThreadTebInformation: 292 case ThreadCSwitchMon: 293 { 294 SpecialStatus = STATUS_INVALID_INFO_CLASS; 295 break; 296 } 297 298 /* Alignment probing is not performed for this class */ 299 case ThreadEnableAlignmentFaultFixup: 300 { 301 SpecialStatus = STATUS_ACCESS_VIOLATION; 302 break; 303 } 304 } 305 306 /* Set the information */ 307 Status = NtSetInformationThread(NtCurrentThread(), 308 InfoClassIndex, 309 InfoPointer, 310 InfoLength); 311 312 /* And probe the results we've got */ 313 ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT || Status == STATUS_SUCCESS, 314 "0x%lx or special status (0x%lx) expected but got 0x%lx for class information %lu in set information thread operation!\n", ExpectedStatus, SpecialStatus, Status, InfoClassIndex); 315 } 316 317 default: 318 break; 319 } 320 } 321