mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[NTDLL_APITEST] Implement alignment probing library code
The probing library code only probes data types for threads/processes information classes in Process Structure subsystem for now.
This commit is contained in:
parent
66007dee2b
commit
ae8ebe45d2
2 changed files with 343 additions and 0 deletions
|
@ -12,4 +12,27 @@
|
|||
#include <ndk/ntndk.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
/* probelib.c */
|
||||
typedef enum _ALIGNMENT_PROBE_MODE
|
||||
{
|
||||
QUERY,
|
||||
SET
|
||||
} ALIGNMENT_PROBE_MODE;
|
||||
|
||||
VOID
|
||||
QuerySetProcessValidator(
|
||||
_In_ ALIGNMENT_PROBE_MODE ValidationMode,
|
||||
_In_ ULONG InfoClassIndex,
|
||||
_In_ PVOID InfoPointer,
|
||||
_In_ ULONG InfoLength,
|
||||
_In_ NTSTATUS ExpectedStatus);
|
||||
|
||||
VOID
|
||||
QuerySetThreadValidator(
|
||||
_In_ ALIGNMENT_PROBE_MODE ValidationMode,
|
||||
_In_ ULONG InfoClassIndex,
|
||||
_In_ PVOID InfoPointer,
|
||||
_In_ ULONG InfoLength,
|
||||
_In_ NTSTATUS ExpectedStatus);
|
||||
|
||||
#endif /* _NTDLL_APITEST_PRECOMP_H_ */
|
||||
|
|
320
modules/rostests/apitests/ntdll/probelib.c
Normal file
320
modules/rostests/apitests/ntdll/probelib.c
Normal file
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Small library with probing utilities for thread/process classes information
|
||||
* COPYRIGHT: Copyright 2020 George Bișoc <george.bisoc@reactos.org>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <internal/ps_i.h>
|
||||
|
||||
VOID
|
||||
QuerySetProcessValidator(
|
||||
_In_ ALIGNMENT_PROBE_MODE ValidationMode,
|
||||
_In_ ULONG InfoClassIndex,
|
||||
_In_ PVOID InfoPointer,
|
||||
_In_ ULONG InfoLength,
|
||||
_In_ NTSTATUS ExpectedStatus)
|
||||
{
|
||||
NTSTATUS Status, SpecialStatus = STATUS_SUCCESS;
|
||||
|
||||
/* Before doing anything, check if we want query or set validation */
|
||||
switch (ValidationMode)
|
||||
{
|
||||
case QUERY:
|
||||
{
|
||||
switch (InfoClassIndex)
|
||||
{
|
||||
case ProcessWorkingSetWatch:
|
||||
{
|
||||
SpecialStatus = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
|
||||
case ProcessHandleTracing:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This class returns an arbitrary size pointed by InformationLength
|
||||
* which equates to the image filename of the process. Such status
|
||||
* is returned in an invalid address query (STATUS_ACCESS_VIOLATION)
|
||||
* where the function expects STATUS_INFO_LENGTH_MISMATCH instead.
|
||||
*/
|
||||
case ProcessImageFileName:
|
||||
{
|
||||
SpecialStatus = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't belong in the query group */
|
||||
case ProcessBasePriority:
|
||||
case ProcessRaisePriority:
|
||||
case ProcessExceptionPort:
|
||||
case ProcessAccessToken:
|
||||
case ProcessLdtSize:
|
||||
case ProcessIoPortHandlers:
|
||||
case ProcessUserModeIOPL:
|
||||
case ProcessEnableAlignmentFaultFixup:
|
||||
case ProcessAffinityMask:
|
||||
case ProcessForegroundInformation:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't exist in Server 2003 */
|
||||
case ProcessIoPriority:
|
||||
case ProcessTlsInformation:
|
||||
case ProcessCycleTime:
|
||||
case ProcessPagePriority:
|
||||
case ProcessInstrumentationCallback:
|
||||
case ProcessThreadStackAllocation:
|
||||
case ProcessWorkingSetWatchEx:
|
||||
case ProcessImageFileNameWin32:
|
||||
case ProcessImageFileMapping:
|
||||
case ProcessAffinityUpdateMode:
|
||||
case ProcessMemoryAllocationMode:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Query the information */
|
||||
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||
InfoClassIndex,
|
||||
InfoPointer,
|
||||
InfoLength,
|
||||
NULL);
|
||||
|
||||
/* And probe the results we've got */
|
||||
ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT,
|
||||
"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);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET:
|
||||
{
|
||||
switch (InfoClassIndex)
|
||||
{
|
||||
case ProcessIoPortHandlers:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This class returns STATUS_SUCCESS when testing
|
||||
* for STATUS_ACCESS_VIOLATION (setting an invalid address).
|
||||
*/
|
||||
case ProcessWorkingSetWatch:
|
||||
{
|
||||
SpecialStatus = STATUS_PORT_ALREADY_SET;
|
||||
break;
|
||||
}
|
||||
|
||||
case ProcessUserModeIOPL:
|
||||
{
|
||||
SpecialStatus = STATUS_PRIVILEGE_NOT_HELD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't belong in the set group */
|
||||
case ProcessBasicInformation:
|
||||
case ProcessIoCounters:
|
||||
case ProcessVmCounters:
|
||||
case ProcessTimes:
|
||||
case ProcessDebugPort:
|
||||
case ProcessPooledUsageAndLimits:
|
||||
case ProcessHandleCount:
|
||||
case ProcessWow64Information:
|
||||
case ProcessImageFileName:
|
||||
case ProcessLUIDDeviceMapsEnabled:
|
||||
case ProcessDebugObjectHandle:
|
||||
case ProcessCookie:
|
||||
case ProcessImageInformation:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't exist in Server 2003 */
|
||||
case ProcessIoPriority:
|
||||
case ProcessTlsInformation:
|
||||
case ProcessCycleTime:
|
||||
case ProcessPagePriority:
|
||||
case ProcessInstrumentationCallback:
|
||||
case ProcessThreadStackAllocation:
|
||||
case ProcessWorkingSetWatchEx:
|
||||
case ProcessImageFileNameWin32:
|
||||
case ProcessImageFileMapping:
|
||||
case ProcessAffinityUpdateMode:
|
||||
case ProcessMemoryAllocationMode:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Alignment probing is not performed for these classes */
|
||||
case ProcessEnableAlignmentFaultFixup:
|
||||
case ProcessPriorityClass:
|
||||
case ProcessForegroundInformation:
|
||||
{
|
||||
SpecialStatus = STATUS_ACCESS_VIOLATION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the information */
|
||||
Status = NtSetInformationProcess(NtCurrentProcess(),
|
||||
InfoClassIndex,
|
||||
InfoPointer,
|
||||
InfoLength);
|
||||
|
||||
/* And probe the results we've got */
|
||||
ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT || Status == STATUS_SUCCESS,
|
||||
"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);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
QuerySetThreadValidator(
|
||||
_In_ ALIGNMENT_PROBE_MODE ValidationMode,
|
||||
_In_ ULONG InfoClassIndex,
|
||||
_In_ PVOID InfoPointer,
|
||||
_In_ ULONG InfoLength,
|
||||
_In_ NTSTATUS ExpectedStatus)
|
||||
{
|
||||
NTSTATUS Status, SpecialStatus = STATUS_SUCCESS;
|
||||
|
||||
/* Before doing anything, check if we want query or set validation */
|
||||
switch (ValidationMode)
|
||||
{
|
||||
case QUERY:
|
||||
{
|
||||
switch (InfoClassIndex)
|
||||
{
|
||||
/* These classes don't belong in the query group */
|
||||
case ThreadPriority:
|
||||
case ThreadBasePriority:
|
||||
case ThreadAffinityMask:
|
||||
case ThreadImpersonationToken:
|
||||
case ThreadEnableAlignmentFaultFixup:
|
||||
case ThreadZeroTlsCell:
|
||||
case ThreadIdealProcessor:
|
||||
case ThreadSetTlsArrayAddress:
|
||||
case ThreadHideFromDebugger:
|
||||
case ThreadSwitchLegacyState:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't exist in Server 2003 SP2 */
|
||||
case ThreadEventPair_Reusable:
|
||||
case ThreadLastSystemCall:
|
||||
case ThreadIoPriority:
|
||||
case ThreadCycleTime:
|
||||
case ThreadPagePriority:
|
||||
case ThreadActualBasePriority:
|
||||
case ThreadTebInformation:
|
||||
case ThreadCSwitchMon:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Query the information */
|
||||
Status = NtQueryInformationThread(NtCurrentThread(),
|
||||
InfoClassIndex,
|
||||
InfoPointer,
|
||||
InfoLength,
|
||||
NULL);
|
||||
|
||||
/* And probe the results we've got */
|
||||
ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT,
|
||||
"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);
|
||||
break;
|
||||
}
|
||||
|
||||
case SET:
|
||||
{
|
||||
switch (InfoClassIndex)
|
||||
{
|
||||
/* This class is not implemented in Windows Server 2003 SP2 */
|
||||
case ThreadSwitchLegacyState:
|
||||
{
|
||||
SpecialStatus = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This class doesn't take a strict type for size length.
|
||||
* The function happily succeds on an information length
|
||||
* mismatch scenario with STATUS_SUCCESS.
|
||||
*/
|
||||
case ThreadHideFromDebugger:
|
||||
{
|
||||
SpecialStatus = STATUS_INFO_LENGTH_MISMATCH;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't belong in the set group */
|
||||
case ThreadBasicInformation:
|
||||
case ThreadTimes:
|
||||
case ThreadDescriptorTableEntry:
|
||||
case ThreadPerformanceCount:
|
||||
case ThreadAmILastThread:
|
||||
case ThreadIsIoPending:
|
||||
case ThreadIsTerminated:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These classes don't exist in Server 2003 SP2 */
|
||||
case ThreadEventPair_Reusable:
|
||||
case ThreadLastSystemCall:
|
||||
case ThreadIoPriority:
|
||||
case ThreadCycleTime:
|
||||
case ThreadPagePriority:
|
||||
case ThreadActualBasePriority:
|
||||
case ThreadTebInformation:
|
||||
case ThreadCSwitchMon:
|
||||
{
|
||||
SpecialStatus = STATUS_INVALID_INFO_CLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Alignment probing is not performed for this class */
|
||||
case ThreadEnableAlignmentFaultFixup:
|
||||
{
|
||||
SpecialStatus = STATUS_ACCESS_VIOLATION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the information */
|
||||
Status = NtSetInformationThread(NtCurrentThread(),
|
||||
InfoClassIndex,
|
||||
InfoPointer,
|
||||
InfoLength);
|
||||
|
||||
/* And probe the results we've got */
|
||||
ok(Status == ExpectedStatus || Status == SpecialStatus || Status == STATUS_DATATYPE_MISALIGNMENT || Status == STATUS_SUCCESS,
|
||||
"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);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue