mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
secured access to buffers in NtWaitForSingleObject(), NtWaitForMultipleObjects() and NtSignalAndWaitForSingleObject()
svn path=/trunk/; revision=13579
This commit is contained in:
parent
eafae64526
commit
f4c9f96205
3 changed files with 152 additions and 87 deletions
|
@ -4423,28 +4423,28 @@ ZwShutdownSystem(
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Signals an object and wait for an other one.
|
* FUNCTION: Signals an object and wait for an other one.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* SignalObject = Handle to the object that should be signaled
|
* ObjectHandleToSignal = Handle to the object that should be signaled
|
||||||
* WaitObject = Handle to the object that should be waited for
|
* WaitableObjectHandle = Handle to the object that should be waited for
|
||||||
* Alertable = True if the wait is alertable
|
* Alertable = True if the wait is alertable
|
||||||
* Time = The time to wait
|
* TimeOut = The time to wait
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtSignalAndWaitForSingleObject(
|
NtSignalAndWaitForSingleObject(
|
||||||
IN HANDLE SignalObject,
|
IN HANDLE ObjectHandleToSignal,
|
||||||
IN HANDLE WaitObject,
|
IN HANDLE WaitableObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtSignalAndWaitForSingleObject(
|
NtSignalAndWaitForSingleObject(
|
||||||
IN HANDLE SignalObject,
|
IN HANDLE ObjectHandleToSignal,
|
||||||
IN HANDLE WaitObject,
|
IN HANDLE WaitableObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4651,9 +4651,9 @@ ZwWriteVirtualMemory(
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Waits for an object to become signalled.
|
* FUNCTION: Waits for an object to become signalled.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Object = The object handle
|
* ObjectHandle = The object handle
|
||||||
* Alertable = If true the wait is alertable.
|
* Alertable = If true the wait is alertable.
|
||||||
* Time = The maximum wait time.
|
* TimeOut = The maximum wait time.
|
||||||
* REMARKS:
|
* REMARKS:
|
||||||
* This function maps to the win32 WaitForSingleObjectEx.
|
* This function maps to the win32 WaitForSingleObjectEx.
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
|
@ -4661,17 +4661,17 @@ ZwWriteVirtualMemory(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtWaitForSingleObject (
|
NtWaitForSingleObject (
|
||||||
IN HANDLE Object,
|
IN HANDLE ObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ZwWaitForSingleObject (
|
ZwWaitForSingleObject (
|
||||||
IN HANDLE Object,
|
IN HANDLE ObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/* --- EVENT PAIR OBJECT --- */
|
/* --- EVENT PAIR OBJECT --- */
|
||||||
|
@ -5583,11 +5583,11 @@ NtUnlockVirtualMemory(
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Waits for multiple objects to become signalled.
|
* FUNCTION: Waits for multiple objects to become signalled.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Count = The number of objects
|
* ObjectCount = The number of objects
|
||||||
* Object = The array of object handles
|
* ObjectsArray = The array of object handles
|
||||||
* WaitType = Can be one of the values UserMode or KernelMode
|
* WaitType = Can be one of the values UserMode or KernelMode
|
||||||
* Alertable = If true the wait is alertable.
|
* Alertable = If true the wait is alertable.
|
||||||
* Time = The maximum wait time.
|
* TimeOut = The maximum wait time.
|
||||||
* REMARKS:
|
* REMARKS:
|
||||||
* This function maps to the win32 WaitForMultipleObjectEx.
|
* This function maps to the win32 WaitForMultipleObjectEx.
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
|
@ -5595,11 +5595,11 @@ NtUnlockVirtualMemory(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtWaitForMultipleObjects (
|
NtWaitForMultipleObjects (
|
||||||
IN ULONG Count,
|
IN ULONG ObjectCount,
|
||||||
IN HANDLE Object[],
|
IN PHANDLE ObjectsArray,
|
||||||
IN WAIT_TYPE WaitType,
|
IN WAIT_TYPE WaitType,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -6357,11 +6357,11 @@ ZwUnlockVirtualMemory(
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Waits for multiple objects to become signalled.
|
* FUNCTION: Waits for multiple objects to become signalled.
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Count = The number of objects
|
* ObjectCount = The number of objects
|
||||||
* Object = The array of object handles
|
* ObjectsArray = The array of object handles
|
||||||
* WaitType = Can be one of the values UserMode or KernelMode
|
* WaitType = Can be one of the values UserMode or KernelMode
|
||||||
* Alertable = If true the wait is alertable.
|
* Alertable = If true the wait is alertable.
|
||||||
* Time = The maximum wait time.
|
* TimeOut = The maximum wait time.
|
||||||
* REMARKS:
|
* REMARKS:
|
||||||
* This function maps to the win32 WaitForMultipleObjectEx.
|
* This function maps to the win32 WaitForMultipleObjectEx.
|
||||||
* RETURNS: Status
|
* RETURNS: Status
|
||||||
|
@ -6369,11 +6369,11 @@ ZwUnlockVirtualMemory(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ZwWaitForMultipleObjects (
|
ZwWaitForMultipleObjects (
|
||||||
IN ULONG Count,
|
IN ULONG ObjectCount,
|
||||||
IN HANDLE Object[],
|
IN PHANDLE ObjectsArray,
|
||||||
IN WAIT_TYPE WaitType,
|
IN WAIT_TYPE WaitType,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time
|
IN PLARGE_INTEGER TimeOut OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -785,45 +785,71 @@ VOID KeInitializeDispatcher(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtWaitForMultipleObjects(IN ULONG Count,
|
NtWaitForMultipleObjects(IN ULONG ObjectCount,
|
||||||
IN HANDLE Object [],
|
IN PHANDLE ObjectsArray,
|
||||||
IN WAIT_TYPE WaitType,
|
IN WAIT_TYPE WaitType,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER UnsafeTime)
|
IN PLARGE_INTEGER TimeOut OPTIONAL)
|
||||||
{
|
{
|
||||||
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
|
HANDLE SafeObjectsArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
|
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
KPROCESSOR_MODE WaitMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER SafeTimeOut;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, "
|
DPRINT("NtWaitForMultipleObjects(ObjectCount %lu ObjectsArray[] %x, Alertable %d, "
|
||||||
"Time %x)\n", Count,Object,Alertable,Time);
|
"TimeOut %x)\n", ObjectCount,ObjectsArray,Alertable,TimeOut);
|
||||||
|
|
||||||
if (Count > MAXIMUM_WAIT_OBJECTS)
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (ObjectCount > MAXIMUM_WAIT_OBJECTS)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
if (0 == Count)
|
if (0 == ObjectCount)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (UnsafeTime)
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
|
ProbeForRead(ObjectsArray,
|
||||||
if (!NT_SUCCESS(Status))
|
ObjectCount * sizeof(ObjectsArray[0]),
|
||||||
{
|
sizeof(ULONG));
|
||||||
return(Status);
|
/* make a copy so we don't have to guard with SEH later and keep track of
|
||||||
}
|
what objects we referenced in case dereferencing pointers suddenly fails */
|
||||||
|
RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount * sizeof(ObjectsArray[0]));
|
||||||
|
ObjectsArray = SafeObjectsArray;
|
||||||
|
|
||||||
|
if(TimeOut != NULL)
|
||||||
|
{
|
||||||
|
ProbeForRead(TimeOut,
|
||||||
|
sizeof(LARGE_INTEGER),
|
||||||
|
sizeof(ULONG));
|
||||||
|
/* make a local copy of the timeout on the stack */
|
||||||
|
SafeTimeOut = *TimeOut;
|
||||||
|
TimeOut = &SafeTimeOut;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
WaitMode = ExGetPreviousMode();
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* reference all objects */
|
/* reference all objects */
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < ObjectCount; i++)
|
||||||
{
|
{
|
||||||
Status = ObReferenceObjectByHandle(Object[i],
|
Status = ObReferenceObjectByHandle(ObjectsArray[i],
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
NULL,
|
NULL,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
&ObjectPtrArray[i],
|
&ObjectPtrArray[i],
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status) || !KiIsObjectWaitable(ObjectPtrArray[i]))
|
if (!NT_SUCCESS(Status) || !KiIsObjectWaitable(ObjectPtrArray[i]))
|
||||||
|
@ -845,17 +871,17 @@ NtWaitForMultipleObjects(IN ULONG Count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = KeWaitForMultipleObjects(Count,
|
Status = KeWaitForMultipleObjects(ObjectCount,
|
||||||
ObjectPtrArray,
|
ObjectPtrArray,
|
||||||
WaitType,
|
WaitType,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
UnsafeTime ? &Time : NULL,
|
TimeOut,
|
||||||
WaitBlockArray);
|
WaitBlockArray);
|
||||||
|
|
||||||
/* dereference all objects */
|
/* dereference all objects */
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < ObjectCount; i++)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(ObjectPtrArray[i]);
|
ObDereferenceObject(ObjectPtrArray[i]);
|
||||||
}
|
}
|
||||||
|
@ -868,33 +894,47 @@ NtWaitForMultipleObjects(IN ULONG Count,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtWaitForSingleObject(IN HANDLE Object,
|
NtWaitForSingleObject(IN HANDLE ObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER UnsafeTime)
|
IN PLARGE_INTEGER TimeOut OPTIONAL)
|
||||||
{
|
{
|
||||||
PVOID ObjectPtr;
|
PVOID ObjectPtr;
|
||||||
NTSTATUS Status;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
KPROCESSOR_MODE WaitMode;
|
LARGE_INTEGER SafeTimeOut;
|
||||||
LARGE_INTEGER Time;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n",
|
DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n",
|
||||||
Object,Alertable,Time);
|
ObjectHandle,Alertable,TimeOut);
|
||||||
|
|
||||||
if (UnsafeTime)
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if(TimeOut != NULL && PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = MmCopyFromCaller(&Time, UnsafeTime, sizeof(LARGE_INTEGER));
|
ProbeForRead(TimeOut,
|
||||||
if (!NT_SUCCESS(Status))
|
sizeof(LARGE_INTEGER),
|
||||||
{
|
sizeof(ULONG));
|
||||||
return(Status);
|
/* make a copy on the stack */
|
||||||
}
|
SafeTimeOut = *TimeOut;
|
||||||
|
TimeOut = &SafeTimeOut;
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WaitMode = ExGetPreviousMode();
|
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(Object,
|
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
NULL,
|
NULL,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
&ObjectPtr,
|
&ObjectPtr,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -911,9 +951,9 @@ NtWaitForSingleObject(IN HANDLE Object,
|
||||||
{
|
{
|
||||||
Status = KeWaitForSingleObject(ObjectPtr,
|
Status = KeWaitForSingleObject(ObjectPtr,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
UnsafeTime ? &Time : NULL);
|
TimeOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(ObjectPtr);
|
ObDereferenceObject(ObjectPtr);
|
||||||
|
@ -923,22 +963,47 @@ NtWaitForSingleObject(IN HANDLE Object,
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
|
NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
|
||||||
IN HANDLE WaitObject,
|
IN HANDLE WaitableObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time)
|
IN PLARGE_INTEGER TimeOut OPTIONAL)
|
||||||
{
|
{
|
||||||
KPROCESSOR_MODE WaitMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
DISPATCHER_HEADER* hdr;
|
DISPATCHER_HEADER* hdr;
|
||||||
PVOID SignalObj;
|
PVOID SignalObj;
|
||||||
PVOID WaitObj;
|
PVOID WaitObj;
|
||||||
NTSTATUS Status;
|
LARGE_INTEGER SafeTimeOut;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
WaitMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
Status = ObReferenceObjectByHandle(SignalObject,
|
|
||||||
|
if(TimeOut != NULL && PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(TimeOut,
|
||||||
|
sizeof(LARGE_INTEGER),
|
||||||
|
sizeof(ULONG));
|
||||||
|
/* make a copy on the stack */
|
||||||
|
SafeTimeOut = *TimeOut;
|
||||||
|
TimeOut = &SafeTimeOut;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
&SignalObj,
|
&SignalObj,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -946,10 +1011,10 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(WaitObject,
|
Status = ObReferenceObjectByHandle(WaitableObjectHandle,
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
NULL,
|
NULL,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
&WaitObj,
|
&WaitObj,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -988,9 +1053,9 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
|
||||||
|
|
||||||
Status = KeWaitForSingleObject(WaitObj,
|
Status = KeWaitForSingleObject(WaitObj,
|
||||||
UserRequest,
|
UserRequest,
|
||||||
WaitMode,
|
PreviousMode,
|
||||||
Alertable,
|
Alertable,
|
||||||
Time);
|
TimeOut);
|
||||||
|
|
||||||
ObDereferenceObject(SignalObj);
|
ObDereferenceObject(SignalObj);
|
||||||
ObDereferenceObject(WaitObj);
|
ObDereferenceObject(WaitObj);
|
||||||
|
|
|
@ -9131,17 +9131,17 @@ NTOSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
DDKAPI
|
DDKAPI
|
||||||
NtWaitForSingleObject(
|
NtWaitForSingleObject(
|
||||||
IN HANDLE Object,
|
IN HANDLE ObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time);
|
IN PLARGE_INTEGER TimeOut OPTIONAL);
|
||||||
|
|
||||||
NTOSAPI
|
NTOSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
DDKAPI
|
DDKAPI
|
||||||
ZwWaitForSingleObject(
|
ZwWaitForSingleObject(
|
||||||
IN HANDLE Object,
|
IN HANDLE ObjectHandle,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
IN PLARGE_INTEGER Time);
|
IN PLARGE_INTEGER TimeOut OPTIONAL);
|
||||||
|
|
||||||
NTOSAPI
|
NTOSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue