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
Modified: trunk/reactos/drivers/net/afd/afd/main.c
Modified: trunk/reactos/include/ntos/zw.h
Modified: trunk/reactos/lib/kernel32/process/proc.c
Modified: trunk/reactos/lib/kernel32/thread/thread.c
Modified: trunk/reactos/ntoskrnl/ke/timer.c

Modified: trunk/reactos/drivers/net/afd/afd/main.c
--- trunk/reactos/drivers/net/afd/afd/main.c	2005-01-27 08:16:42 UTC (rev 13336)
+++ trunk/reactos/drivers/net/afd/afd/main.c	2005-01-27 14:11:19 UTC (rev 13337)
@@ -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;

Modified: trunk/reactos/include/ntos/zw.h
--- trunk/reactos/include/ntos/zw.h	2005-01-27 08:16:42 UTC (rev 13336)
+++ trunk/reactos/include/ntos/zw.h	2005-01-27 14:11:19 UTC (rev 13337)
@@ -3014,8 +3014,8 @@
 /*
  * 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 @@
 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 @@
 NTSTATUS
 STDCALL
 NtDelayExecution(
-	IN ULONG Alertable,
-	IN LARGE_INTEGER *Interval
+	IN BOOLEAN Alertable,
+	IN PLARGE_INTEGER DelayInterval
 	);
 
 /*
@@ -6439,7 +6439,7 @@
 STDCALL
 ZwDelayExecution(
 	IN BOOLEAN Alertable,
-	IN TIME *Interval
+	IN PLARGE_INTEGER DelayInterval
 	);
 
 /*

Modified: trunk/reactos/lib/kernel32/process/proc.c
--- trunk/reactos/lib/kernel32/process/proc.c	2005-01-27 08:16:42 UTC (rev 13336)
+++ trunk/reactos/lib/kernel32/process/proc.c	2005-01-27 14:11:19 UTC (rev 13337)
@@ -442,51 +442,6 @@
  * @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
- */
-VOID STDCALL
 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
 {
   PRTL_USER_PROCESS_PARAMETERS Params;

Modified: trunk/reactos/lib/kernel32/thread/thread.c
--- trunk/reactos/lib/kernel32/thread/thread.c	2005-01-27 08:16:42 UTC (rev 13336)
+++ trunk/reactos/lib/kernel32/thread/thread.c	2005-01-27 14:11:19 UTC (rev 13337)
@@ -852,4 +852,49 @@
   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 */

Modified: trunk/reactos/ntoskrnl/ke/timer.c
--- trunk/reactos/ntoskrnl/ke/timer.c	2005-01-27 08:16:42 UTC (rev 13336)
+++ trunk/reactos/ntoskrnl/ke/timer.c	2005-01-27 14:11:19 UTC (rev 13337)
@@ -71,8 +71,6 @@
 
 /* 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 @@
 
 
 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;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _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;
+    }
+  }
 
   PerfCounter = KeQueryPerformanceCounter(&PerfFrequency);
-
-  if (Counter != NULL)
+  
+  _SEH_TRY
+  {
+    *PerformanceCounter = PerfCounter;
+    if(PerformanceFrequency != NULL)
     {
-      Status = MmCopyToCaller(&Counter->QuadPart, &PerfCounter.QuadPart, sizeof(PerfCounter.QuadPart));
-      if (!NT_SUCCESS(Status))
-        {
-	  return(Status);
-        }
+      *PerformanceFrequency = PerfFrequency;
     }
-
-  if (Frequency != NULL)
+  }
+  _SEH_HANDLE
   {
-      Status = MmCopyToCaller(&Frequency->QuadPart, &PerfFrequency.QuadPart, sizeof(PerfFrequency.QuadPart));
-      if (!NT_SUCCESS(Status))
-        {
-	  return(Status);
-        }
+    Status = _SEH_GetExceptionCode();
   }
+  _SEH_END;
 
-  return(STATUS_SUCCESS);
+  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))
+   KPROCESSOR_MODE PreviousMode;
+   LARGE_INTEGER SafeInterval;
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     NTSTATUS Status = STATUS_SUCCESS;
+     
+     _SEH_TRY
      {
-	return(Status);
+       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;
+     }
+   }
 
-   Timeout = *((PLARGE_INTEGER)Interval);
-   DPRINT("NtDelayExecution(Alertable %d, Internal %x) IntervalP %x\n",
-	  Alertable, Internal, Timeout);
-   
-   DPRINT("Execution delay is %d/%d\n", 
-	  Timeout.u.HighPart, Timeout.u.LowPart);
-   Status = KeDelayExecutionThread(UserMode, (BOOLEAN)Alertable, &Timeout);
-   return(Status);
+   return KeDelayExecutionThread(PreviousMode,
+                                 Alertable,
+                                 DelayInterval);
 }