mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 01:51:24 +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 <ndk/ntndk.h>
|
||||||
#include <strsafe.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_ */
|
#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…
Add table
Add a link
Reference in a new issue