1. fixed prototypes of NtQueryPerformanceCounter() and NtDelayExecution() and made them safely access buffers

2. moved the implementation of Sleep(Ex)() into more a appropriate file

svn path=/trunk/; revision=13337
This commit is contained in:
Thomas Bluemel
2005-01-27 14:11:19 +00:00
parent 6a5c36c54a
commit 466fa48bd1
5 changed files with 136 additions and 98 deletions
-2
View File
@@ -19,8 +19,6 @@
#ifdef DBG
extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size );
/* See debug.h for debug/trace constants */
//DWORD DebugTraceLevel = DEBUG_ULTRA;
DWORD DebugTraceLevel = 0;
+9 -9
View File
@@ -3014,8 +3014,8 @@ ZwQueryMutant(
/*
* FUNCTION: Queries the system ( high-resolution ) performance counter.
* ARGUMENTS:
* Counter = Performance counter
* Frequency = Performance frequency
* PerformanceCounter = Performance counter
* PerformanceFrequency = Performance frequency
* REMARKS:
This procedure queries a tick count faster than 10ms ( The resolution for Intel®-based CPUs is about 0.8 microseconds.)
This procedure maps to the win32 QueryPerformanceCounter, QueryPerformanceFrequency
@@ -3025,15 +3025,15 @@ ZwQueryMutant(
NTSTATUS
STDCALL
NtQueryPerformanceCounter(
IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency
OUT PLARGE_INTEGER PerformanceCounter,
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
);
NTSTATUS
STDCALL
ZwQueryPerformanceCounter(
IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency
OUT PLARGE_INTEGER PerformanceCounter,
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
);
/*
@@ -5240,8 +5240,8 @@ NtCreateThread(
NTSTATUS
STDCALL
NtDelayExecution(
IN ULONG Alertable,
IN LARGE_INTEGER *Interval
IN BOOLEAN Alertable,
IN PLARGE_INTEGER DelayInterval
);
/*
@@ -6439,7 +6439,7 @@ NTSTATUS
STDCALL
ZwDelayExecution(
IN BOOLEAN Alertable,
IN TIME *Interval
IN PLARGE_INTEGER DelayInterval
);
/*
-45
View File
@@ -438,51 +438,6 @@ WaitForInputIdle (
}
/*
* @implemented
*/
VOID STDCALL
Sleep(DWORD dwMilliseconds)
{
SleepEx(dwMilliseconds, FALSE);
return;
}
/*
* @implemented
*/
DWORD STDCALL
SleepEx(DWORD dwMilliseconds,
BOOL bAlertable)
{
LARGE_INTEGER Interval;
NTSTATUS errCode;
if (dwMilliseconds != INFINITE)
{
/*
* System time units are 100 nanoseconds (a nanosecond is a billionth of
* a second).
*/
Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000);
}
else
{
/* Approximately 292000 years hence */
Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
}
errCode = NtDelayExecution (bAlertable, &Interval);
if (!NT_SUCCESS(errCode))
{
SetLastErrorByStatus (errCode);
return -1;
}
return 0;
}
/*
* @implemented
*/
+45
View File
@@ -852,4 +852,49 @@ GetThreadIOPendingFlag(HANDLE hThread,
return FALSE;
}
/*
* @implemented
*/
VOID STDCALL
Sleep(DWORD dwMilliseconds)
{
SleepEx(dwMilliseconds, FALSE);
return;
}
/*
* @implemented
*/
DWORD STDCALL
SleepEx(DWORD dwMilliseconds,
BOOL bAlertable)
{
LARGE_INTEGER Interval;
NTSTATUS errCode;
if (dwMilliseconds != INFINITE)
{
/*
* System time units are 100 nanoseconds (a nanosecond is a billionth of
* a second).
*/
Interval.QuadPart = -((ULONGLONG)dwMilliseconds * 10000);
}
else
{
/* Approximately 292000 years hence */
Interval.QuadPart = -0x7FFFFFFFFFFFFFFFLL;
}
errCode = NtDelayExecution ((bAlertable ? TRUE : FALSE), &Interval);
if (!NT_SUCCESS(errCode))
{
SetLastErrorByStatus (errCode);
return -1;
}
return 0;
}
/* EOF */
+82 -42
View File
@@ -71,8 +71,6 @@ static KDPC ExpireTimerDpc;
/* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */
extern HANDLE PsIdleThreadHandle;
#define MICROSECONDS_PER_TICK (10000)
#define TICKS_TO_CALIBRATE (1)
#define CALIBRATE_PERIOD (MICROSECONDS_PER_TICK * TICKS_TO_CALIBRATE)
@@ -104,58 +102,100 @@ NtSetTimerResolution(IN ULONG DesiredResolution,
NTSTATUS STDCALL
NtQueryPerformanceCounter(IN PLARGE_INTEGER Counter,
IN PLARGE_INTEGER Frequency)
NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
{
LARGE_INTEGER PerfCounter;
LARGE_INTEGER PerfFrequency;
NTSTATUS Status;
PerfCounter = KeQueryPerformanceCounter(&PerfFrequency);
if (Counter != NULL)
{
Status = MmCopyToCaller(&Counter->QuadPart, &PerfCounter.QuadPart, sizeof(PerfCounter.QuadPart));
if (!NT_SUCCESS(Status))
{
return(Status);
}
}
if (Frequency != NULL)
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
Status = MmCopyToCaller(&Frequency->QuadPart, &PerfFrequency.QuadPart, sizeof(PerfFrequency.QuadPart));
if (!NT_SUCCESS(Status))
{
return(Status);
}
_SEH_TRY
{
ProbeForWrite(PerformanceCounter,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
if(PerformanceFrequency != NULL)
{
ProbeForWrite(PerformanceFrequency,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
return(STATUS_SUCCESS);
PerfCounter = KeQueryPerformanceCounter(&PerfFrequency);
_SEH_TRY
{
*PerformanceCounter = PerfCounter;
if(PerformanceFrequency != NULL)
{
*PerformanceFrequency = PerfFrequency;
}
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
return Status;
}
NTSTATUS STDCALL
NtDelayExecution(IN ULONG Alertable,
IN LARGE_INTEGER* Interval)
NtDelayExecution(IN BOOLEAN Alertable,
IN PLARGE_INTEGER DelayInterval)
{
NTSTATUS Status;
LARGE_INTEGER Timeout;
Status = MmCopyFromCaller(&Timeout, Interval, sizeof(Timeout));
if (!NT_SUCCESS(Status))
{
return(Status);
}
Timeout = *((PLARGE_INTEGER)Interval);
DPRINT("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n",
Alertable, Internal, Timeout);
KPROCESSOR_MODE PreviousMode;
LARGE_INTEGER SafeInterval;
DPRINT("Execution delay is %d/%d\n",
Timeout.u.HighPart, Timeout.u.LowPart);
Status = KeDelayExecutionThread(UserMode, (BOOLEAN)Alertable, &Timeout);
return(Status);
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
NTSTATUS Status = STATUS_SUCCESS;
_SEH_TRY
{
ProbeForRead(DelayInterval,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
/* make a copy on the kernel stack and let DelayInterval point to it so
we don't need to wrap KeDelayExecutionThread in SEH! */
SafeInterval = *DelayInterval;
DelayInterval = &SafeInterval;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(!NT_SUCCESS(Status))
{
return Status;
}
}
return KeDelayExecutionThread(PreviousMode,
Alertable,
DelayInterval);
}