Fix bug with registry loading on bootcd (Thanks Steven). Properly implement Profile Objects with Ex/Ke architecture (structures are a guess, and code is based on dwelch and some simple testing/common sense, but not ready for primetime (NT doesnt even use theirs). Optimize Device Queues a bit and use the inserted field properly.
Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/profile.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/timer.c

Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h
--- branches/alex_devel_branch/reactos/include/ntos/zwtypes.h	2005-03-03 02:46:43 UTC (rev 13804)
+++ branches/alex_devel_branch/reactos/include/ntos/zwtypes.h	2005-03-03 03:57:59 UTC (rev 13805)
@@ -58,6 +58,7 @@
   ProfileTime
 } KPROFILE_SOURCE;
 
+
 // file disposition values
 
 #define FILE_SUPERSEDE                  0x0000

Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c
--- branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c	2005-03-03 02:46:43 UTC (rev 13804)
+++ branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c	2005-03-03 03:57:59 UTC (rev 13805)
@@ -248,10 +248,12 @@
 {
     PCHAR BaseAddress;
     
-    /* Load Registry Hives */
-    BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
-    CmImportSystemHive(BaseAddress,
-                       CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    /* Load Registry Hives. This one can be missing. */
+    if (CachedModules[SystemRegistry]) {
+        BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
+        CmImportSystemHive(BaseAddress,
+                           CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    }
     
     BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
     CmImportHardwareHive(BaseAddress,

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c	2005-03-03 02:46:43 UTC (rev 13804)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ex/profile.c	2005-03-03 03:57:59 UTC (rev 13805)
@@ -1,11 +1,10 @@
-/* $Id:$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/nt/profile.c
- * PURPOSE:         Support for profiling
+ * FILE:            ntoskrnl/ex/profile.c
+ * PURPOSE:         Support for Executive Profile Objects
  * 
- * PROGRAMMERS:     No programmer listed.
+ * PROGRAMMERS:     Alex Ionescu
  */
 
 /* INCLUDES *****************************************************************/
@@ -13,369 +12,448 @@
 #include <ntoskrnl.h>
 #include <internal/debug.h>
 
-/* TYPES ********************************************************************/
+/* This structure is a *GUESS* -- Alex */
+typedef struct _EPROFILE {
+    PEPROCESS Process;
+    PVOID ImageBase;
+    ULONG ImageSize;
+    ULONG BucketSize;
+    PVOID Buffer;
+    ULONG BufferSize;
+    PKPROFILE KeProfile;
+    KPROFILE_SOURCE ProfileSource;
+    KAFFINITY Affinity;
+    PMDL Mdl;
+    PVOID LockedBuffer;
+} EPROFILE, *PEPROFILE;
 
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE EXPORTED ExProfileObjectType = NULL;
 
-static GENERIC_MAPPING ExpProfileMapping = {
-	STANDARD_RIGHTS_READ,
-	STANDARD_RIGHTS_WRITE,
-	STANDARD_RIGHTS_EXECUTE,
-	STANDARD_RIGHTS_ALL};
+static KMUTEX ExpProfileMutex;
 
-/*
- * Size of the profile hash table.
- */
-#define PROFILE_HASH_TABLE_SIZE      (32)
+#define PROFILE_CONTROL 1
 
-/*
- * Table of lists of per-process profiling data structures hashed by PID.
- */
-LIST_ENTRY ProcessProfileListHashTable[PROFILE_HASH_TABLE_SIZE];
+static GENERIC_MAPPING ExpProfileMapping = {
+    STANDARD_RIGHTS_READ    | PROFILE_CONTROL,
+    STANDARD_RIGHTS_WRITE   | PROFILE_CONTROL,
+    STANDARD_RIGHTS_EXECUTE | PROFILE_CONTROL,
+    STANDARD_RIGHTS_ALL};
 
-/*
- * Head of the list of profile data structures for the kernel.
- */
-LIST_ENTRY SystemProfileList;
-
-/*
- * Lock that protects the profiling data structures.
- */
-KSPIN_LOCK ProfileListLock;
-
-/*
- * Timer interrupts happen before we have initialized the profiling
- * data structures so just ignore them before that.
- */
-BOOLEAN ProfileInitDone = FALSE;
-
-VOID INIT_FUNCTION
-ExpInitializeProfileImplementation(VOID)
+VOID 
+STDCALL
+ExpDeleteProfile(PVOID ObjectBody)
 {
-  ULONG i;
+    PEPROFILE Profile;
 
-  InitializeListHead(&SystemProfileList);
+    /* Typecast the Object */
+    Profile = (PEPROFILE)ObjectBody;
+    
+    /* Check if there if the Profile was started */
+    if (Profile->LockedBuffer) {
+        
+        /* Stop the Profile */
+        KeStopProfile(Profile->KeProfile);
+    
+        /* Unmap the Locked Buffer */
+        MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
+        MmUnlockPages(Profile->Mdl);
+        ExFreePool(Profile->Mdl);
+    }
   
-  for (i = 0; i < PROFILE_HASH_TABLE_SIZE; i++)
-    {
-      InitializeListHead(&ProcessProfileListHashTable[i]);
+    /* Check if a Process is associated */
+    if (Profile->Process != NULL) {
+        
+        /* Dereference it */
+        ObDereferenceObject(Profile->Process);
+        Profile->Process = NULL;
     }
+}
 
-  KeInitializeSpinLock(&ProfileListLock);
-  ProfileInitDone = TRUE;
-
-  ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-  
-  RtlpCreateUnicodeString(&ExProfileObjectType->TypeName, L"Profile", NonPagedPool);
-  
-  ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F');
-  ExProfileObjectType->PeakObjects = 0;
-  ExProfileObjectType->PeakHandles = 0;
-  ExProfileObjectType->TotalObjects = 0;
-  ExProfileObjectType->TotalHandles = 0;
-  ExProfileObjectType->PagedPoolCharge = 0;
-  ExProfileObjectType->NonpagedPoolCharge = sizeof(KPROFILE);
-  ExProfileObjectType->Mapping = &ExpProfileMapping;
-  ExProfileObjectType->Dump = NULL;
-  ExProfileObjectType->Open = NULL;
-  ExProfileObjectType->Close = NULL;
-  ExProfileObjectType->Delete = KiDeleteProfile;
-  ExProfileObjectType->Parse = NULL;
-  ExProfileObjectType->Security = NULL;
-  ExProfileObjectType->QueryName = NULL;
-  ExProfileObjectType->OkayToClose = NULL;
-  ExProfileObjectType->Create = NULL;
-
-  ObpCreateTypeObject(ExProfileObjectType);
+VOID 
+INIT_FUNCTION
+ExpInitializeProfileImplementation(VOID)
+{
+    /* Initialize the Mutex to lock the States */
+    KeInitializeMutex(&ExpProfileMutex, 0x40);
+    
+    /* Create the Object Type */
+    ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlpCreateUnicodeString(&ExProfileObjectType->TypeName, L"Profile", NonPagedPool);  
+    ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F');
+    ExProfileObjectType->PeakObjects = 0;
+    ExProfileObjectType->PeakHandles = 0;
+    ExProfileObjectType->TotalObjects = 0;
+    ExProfileObjectType->TotalHandles = 0;
+    ExProfileObjectType->PagedPoolCharge = 0;
+    ExProfileObjectType->NonpagedPoolCharge = sizeof(EPROFILE);
+    ExProfileObjectType->Mapping = &ExpProfileMapping;
+    ExProfileObjectType->Dump = NULL;
+    ExProfileObjectType->Open = NULL;
+    ExProfileObjectType->Close = NULL;
+    ExProfileObjectType->Delete = ExpDeleteProfile;
+    ExProfileObjectType->Parse = NULL;
+    ExProfileObjectType->Security = NULL;
+    ExProfileObjectType->QueryName = NULL;
+    ExProfileObjectType->OkayToClose = NULL;
+    ExProfileObjectType->Create = NULL;
+    ObpCreateTypeObject(ExProfileObjectType);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS 
+STDCALL 
 NtCreateProfile(OUT PHANDLE ProfileHandle,
-		IN HANDLE Process  OPTIONAL,
-		IN PVOID ImageBase, 
-		IN ULONG ImageSize, 
-		IN ULONG BucketSize,
-		IN PVOID Buffer,
-		IN ULONG BufferSize,
-		IN KPROFILE_SOURCE ProfileSource,
-		IN KAFFINITY Affinity)
+                IN HANDLE Process OPTIONAL,
+                IN PVOID ImageBase, 
+                IN ULONG ImageSize, 
+                IN ULONG BucketSize,
+                IN PVOID Buffer,
+                IN ULONG BufferSize,
+                IN KPROFILE_SOURCE ProfileSource,
+                IN KAFFINITY Affinity)
 {
-  HANDLE hProfile;
-  PKPROFILE Profile;
-  PEPROCESS pProcess;
-  KPROCESSOR_MODE PreviousMode;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hProfile;
+    PEPROFILE Profile;
+    PEPROCESS pProcess;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
+    PAGED_CODE();
   
-  PreviousMode = ExGetPreviousMode();
-  
-  if(BufferSize == 0)
-  {
-    return STATUS_INVALID_PARAMETER_7;
-  }
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(ProfileHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-      ProbeForWrite(Buffer,
-                    BufferSize,
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    /* Easy way out */
+    if(BufferSize == 0) return STATUS_INVALID_PARAMETER_7;
+
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(ProfileHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+            
+            ProbeForWrite(Buffer,
+                          BufferSize,
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
+        if(!NT_SUCCESS(Status)) return Status;
     }
-  }
 
-  /*
-   * Reference the associated process
-   */
-  if (Process != NULL)
-    {
-      Status = ObReferenceObjectByHandle(Process,
-					 PROCESS_QUERY_INFORMATION,
-					 PsProcessType,
-					 PreviousMode,
-					 (PVOID*)&pProcess,
-					 NULL);
-      if (!NT_SUCCESS(Status))
-	{
-	  return(Status);
-	}
+    /* Check if a process was specified */
+    if (Process) {
+        
+        /* Reference it */
+        Status = ObReferenceObjectByHandle(Process,
+                                           PROCESS_QUERY_INFORMATION,
+                                           PsProcessType,
+                                           PreviousMode,
+                                           (PVOID*)&pProcess,
+                                           NULL);
+        if (!NT_SUCCESS(Status)) return(Status);
+        
+    } else {
+        
+        /* No process was specified, which means a System-Wide Profile */
+        pProcess = NULL;
+        
+        /* For this, we need to check the Privilege */
+        if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege, PreviousMode)) {
+            
+            DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
+            return STATUS_PRIVILEGE_NOT_HELD;
+        }
     }
-  else
-    {
-      pProcess = NULL;
-      if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege,
-                                 PreviousMode))
-      {
-        DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
-        return STATUS_PRIVILEGE_NOT_HELD;
-      }
-    }
 
-  /*
-   * Check the parameters
-   */
-  if ((pProcess == NULL && ImageBase < (PVOID)KERNEL_BASE) ||
-      (pProcess != NULL && ImageBase >= (PVOID)KERNEL_BASE))
-    {
-      return(STATUS_INVALID_PARAMETER_3);
-    }
-  if (((ImageSize >> BucketSize) * 4) >= BufferSize)
-    {
-      return(STATUS_BUFFER_TOO_SMALL);
-    }
-  if (ProfileSource != ProfileTime)
-    {
-      return(STATUS_INVALID_PARAMETER_9);
-    }
-  if (Affinity != 0)
-    {
-      return(STATUS_INVALID_PARAMETER_10);
-    }
+    /* Create the object */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               0,
+                               NULL,
+                               NULL);
+    Status = ObCreateObject(KernelMode,
+                            ExProfileObjectType,
+                            &ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(EPROFILE),
+                            0,
+                            0,
+                            (PVOID*)&Profile);
+    if (!NT_SUCCESS(Status)) return(Status);
 
-  /*
-   * Create the object
-   */
-  InitializeObjectAttributes(&ObjectAttributes,
+    /* Initialize it */
+    Profile->ImageBase = ImageBase;
+    Profile->ImageSize = ImageSize;
+    Profile->Buffer = Buffer;
+    Profile->BufferSize = BufferSize;
+    Profile->BucketSize = BucketSize;
+    Profile->LockedBuffer = NULL;
+    Profile->Affinity = Affinity;
+    Profile->Process = pProcess;
+    
+    /* Insert into the Object Tree */
+    Status = ObInsertObject ((PVOID)Profile,
                              NULL,
+                             PROFILE_CONTROL,
                              0,
                              NULL,
-                             NULL);
-
-  Status = ObCreateObject(KernelMode,
-			  ExProfileObjectType,
-			  &ObjectAttributes,
-			  PreviousMode,
-			  NULL,
-			  sizeof(KPROFILE),
-			  0,
-			  0,
-			  (PVOID*)&Profile);
-  if (!NT_SUCCESS(Status))
-     {
-	return(Status);
-     }
-
-  /*
-   * Initialize it
-   */
-  Profile->Base = ImageBase;
-  Profile->Size = ImageSize;
-  Profile->BucketShift = BucketSize;
-  Profile->BufferMdl = MmCreateMdl(NULL, Buffer, BufferSize);
-  if(Profile->BufferMdl == NULL) {
-	DPRINT("MmCreateMdl: Out of memory!");
-	ObDereferenceObject (Profile);
-	return(STATUS_NO_MEMORY);
-  }  
-  MmProbeAndLockPages(Profile->BufferMdl, UserMode, IoWriteAccess);
-  Profile->Buffer = MmGetSystemAddressForMdl(Profile->BufferMdl);
-  Profile->BufferSize = BufferSize;
-  Profile->ProcessorMask = Affinity;
-  Profile->Started = FALSE;
-  Profile->Process = pProcess;
-
-  /*
-   * Insert the profile into the profile list data structures
-   */
-  KiInsertProfile(Profile);
-
-  Status = ObInsertObject ((PVOID)Profile,
-			   NULL,
-			   STANDARD_RIGHTS_ALL,
-			   0,
-			   NULL,
-			   &hProfile);
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject (Profile);
-      return Status;
+                             &hProfile);
+    ObDereferenceObject(Profile);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Dereference Process on failure */
+        if (pProcess) ObDereferenceObject(pProcess);
+        return Status;
     }
+    
+    /* Copy the created handle back to the caller*/
+    _SEH_TRY {
+        
+        *ProfileHandle = hProfile;
+        
+    } _SEH_HANDLE {
+        
+        Status = _SEH_GetExceptionCode();
+    } _SEH_END;
 
-  /*
-   * Copy the created handle back to the caller
-   */
-  _SEH_TRY
-  {
-    *ProfileHandle = hProfile;
-  }
-  _SEH_HANDLE
-  {
-    Status = _SEH_GetExceptionCode();
-  }
-  _SEH_END;
-
-  ObDereferenceObject(Profile);
-
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
-NTSTATUS STDCALL 
-NtQueryIntervalProfile(IN  KPROFILE_SOURCE ProfileSource,
-		       OUT PULONG Interval)
+NTSTATUS 
+STDCALL
+NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
+                          OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
 {
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    LARGE_INTEGER PerfFrequency;
   
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(Interval,
-                    sizeof(ULONG),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PerformanceCounter,
+                          sizeof(LARGE_INTEGER),
+                          sizeof(ULONG));
+            
+            ProbeForWrite(PerformanceFrequency,
+                          sizeof(LARGE_INTEGER),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
+        if(!NT_SUCCESS(Status)) return Status;
     }
-  }
 
-  if (ProfileSource == ProfileTime)
-    {
-      ULONG ReturnInterval;
-
-      /* FIXME: What units does this use, for now nanoseconds */
-      ReturnInterval = 100;
-
-      _SEH_TRY
-      {
-        *Interval = ReturnInterval;
-      }
-      _SEH_HANDLE
-      {
+    _SEH_TRY {
+        
+        /* Query the Kernel */
+        *PerformanceCounter = KeQueryPerformanceCounter(&PerfFrequency);
+        
+        /* Return Frequency if requested */
+        if(PerformanceFrequency) {
+            
+            *PerformanceFrequency = PerfFrequency;
+        }
+    } _SEH_HANDLE {
+        
         Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
-      
-      return Status;
-    }
-  return STATUS_INVALID_PARAMETER_2;
-}
+    
+    } _SEH_END;
 
-NTSTATUS STDCALL 
-NtSetIntervalProfile(IN ULONG Interval,
-		     IN KPROFILE_SOURCE Source)
-{
-  return(STATUS_NOT_IMPLEMENTED);
+    return Status;
 }
 
-NTSTATUS STDCALL 
+NTSTATUS 
+STDCALL 
 NtStartProfile(IN HANDLE ProfileHandle)
 {
-  PKPROFILE Profile;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
+    PEPROFILE Profile;
+    PKPROFILE KeProfile;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PVOID TempLockedBuffer;
+    NTSTATUS Status;
   
-  PAGED_CODE();
+    PAGED_CODE();
   
-  PreviousMode = ExGetPreviousMode();
-
-  Status = ObReferenceObjectByHandle(ProfileHandle,
-				     STANDARD_RIGHTS_ALL,
-				     ExProfileObjectType,
-				     PreviousMode,
-				     (PVOID*)&Profile,
-				     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(ProfileHandle,
+                                       PROFILE_CONTROL,
+                                       ExProfileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Profile,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return(Status);
+    
+    /* To avoid a Race, wait on the Mutex */
+    KeWaitForSingleObject(&ExpProfileMutex, 
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          NULL);
+    
+    /* The Profile can still be enabled though, so handle that */
+    if (Profile->LockedBuffer) {
+    
+        /* Release our lock, dereference and return */
+        KeReleaseMutex(&ExpProfileMutex, FALSE);
+        ObDereferenceObject(Profile);
+        return STATUS_PROFILING_NOT_STOPPED;
     }
-  Profile->Started = TRUE;
-  ObDereferenceObject(Profile);
-  return(STATUS_SUCCESS);
+    
+    /* Allocate a Kernel Profile Object. */
+    KeProfile = ExAllocatePoolWithTag(NonPagedPool, 
+                                      sizeof(EPROFILE),
+                                      TAG('P', 'r', 'o', 'f'));
+   
+    /* Allocate the Mdl Structure */
+    Profile->Mdl = MmCreateMdl(NULL, Profile->Buffer, Profile->BufferSize);
+    
+    /* Probe and Lock for Write Access */
+    MmProbeAndLockPages(Profile->Mdl, PreviousMode, IoWriteAccess);
+    
+    /* Map the pages */
+    TempLockedBuffer = MmMapLockedPages(Profile->Mdl, KernelMode);
+    
+    /* Initialize the Kernel Profile Object */
+    Profile->KeProfile = KeProfile;
+    KeInitializeProfile(KeProfile,
+                        (PKPROCESS)Profile->Process,
+                        Profile->ImageBase,
+                        Profile->ImageSize,
+                        Profile->BucketSize,
+                        Profile->ProfileSource,
+                        Profile->Affinity);
+    
+    /* Start the Profiling */
+    KeStartProfile(KeProfile, TempLockedBuffer);
+    
+    /* Now it's safe to save this */
+    Profile->LockedBuffer = TempLockedBuffer;
+    
+    /* Release mutex, dereference and return */
+    KeReleaseMutex(&ExpProfileMutex, FALSE);
+    ObDereferenceObject(Profile);
+    return STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL 
+NTSTATUS
+STDCALL 
 NtStopProfile(IN HANDLE ProfileHandle)
 {
-  PKPROFILE Profile;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
+    PEPROFILE Profile;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
   
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
+    PAGED_CODE();
 
-  Status = ObReferenceObjectByHandle(ProfileHandle,
-				     STANDARD_RIGHTS_ALL,
-				     ExProfileObjectType,
-				     PreviousMode,
-				     (PVOID*)&Profile,
-				     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(ProfileHandle,
+                                       PROFILE_CONTROL,
+                                       ExProfileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Profile,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return(Status);
+    
+    /* Get the Mutex */
+    KeWaitForSingleObject(&ExpProfileMutex, 
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          NULL);
+    
+    /* Make sure the Profile Object is really Started */
+    if (!Profile->LockedBuffer) {
+    
+        Status = STATUS_PROFILING_NOT_STARTED;
+        goto Exit;
     }
-  Profile->Started = FALSE;
-  ObDereferenceObject(Profile);
-  return(STATUS_SUCCESS);
+    
+    /* Stop the Profile */
+    KeStopProfile(Profile->KeProfile);
+    
+    /* Unlock the Buffer */
+    MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
+    MmUnlockPages(Profile->Mdl);
+    ExFreePool(Profile->KeProfile);
+    
+    /* Clear the Locked Buffer pointer, meaning the Object is Stopped */
+    Profile->LockedBuffer = NULL;
+    
+Exit:
+    /* Release Mutex, Dereference and Return */
+    KeReleaseMutex(&ExpProfileMutex, FALSE);
+    ObDereferenceObject(Profile);
+    return Status;
 }
 
+NTSTATUS 
+STDCALL 
+NtQueryIntervalProfile(IN  KPROFILE_SOURCE ProfileSource,
+                       OUT PULONG Interval)
+{
+    KPROCESSOR_MODE PreviousMode= ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    ULONG ReturnInterval;
+  
+    PAGED_CODE();
+    
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(Interval,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+    
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+  
+    /* Query the Interval */
+    ReturnInterval = KeQueryIntervalProfile(ProfileSource);
 
+    /* Return the data */
+    _SEH_TRY  {
+        
+        *Interval = ReturnInterval;
+        
+    } _SEH_HANDLE {
+        
+        Status = _SEH_GetExceptionCode();
+        
+    } _SEH_END;
+    
+    /* Return Success */  
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS 
+STDCALL 
+NtSetIntervalProfile(IN ULONG Interval,
+                     IN KPROFILE_SOURCE Source)
+{
+    /* Let the Kernel do the job */
+    KeSetIntervalProfile(Interval, Source);
+    
+    /* Nothing can go wrong */
+    return STATUS_SUCCESS;
+}

Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h
--- branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h	2005-03-03 02:46:43 UTC (rev 13804)
+++ branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h	2005-03-03 03:57:59 UTC (rev 13805)
@@ -64,56 +64,26 @@
 
 /* next file ***************************************************************/
 
-typedef struct _KPROCESS_PROFILE
-/*
- * List of the profile data structures associated with a process.
- */
-{
-  LIST_ENTRY ProfileListHead;
-  LIST_ENTRY ListEntry;
-  HANDLE Pid;
-} KPROCESS_PROFILE, *PKPROCESS_PROFILE;
+typedef struct _KPROFILE_SOURCE_OBJECT {
+    KPROFILE_SOURCE Source;
+    LIST_ENTRY ListEntry;    
+} KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT;
 
-typedef struct _KPROFILE
 /*
  * Describes a contiguous region of process memory that is being profiled.
  */
-{
-  CSHORT Type;
-  CSHORT Name;
-
-  /* Entry in the list of profile data structures for this process. */
-  LIST_ENTRY ListEntry; 
-
-  /* Base of the region being profiled. */
-  PVOID Base;
-
-  /* Size of the region being profiled. */
-  ULONG Size;
-
-  /* Shift of offsets from the region to buckets in the profiling buffer. */
-  ULONG BucketShift;
-
-  /* MDL which described the buffer that receives profiling data. */
-  struct _MDL *BufferMdl;
-
-  /* System alias for the profiling buffer. */
-  PULONG Buffer;
-
-  /* Size of the buffer for profiling data. */
-  ULONG BufferSize;
-
-  /* 
-   * Mask of processors for which profiling data should be collected. 
-   * Currently unused.
-   */
-  ULONG ProcessorMask;
-
-  /* TRUE if profiling has been started for this region. */
-  BOOLEAN Started;
-
-  /* Pointer (and reference) to the process which is being profiled. */
-  struct _EPROCESS *Process;
+typedef struct _KPROFILE {
+    CSHORT Type;
+    CSHORT Size;
+    LIST_ENTRY ListEntry; 
+    PVOID RegionStart;
+    ULONG RegionEnd;
+    ULONG BucketShift;
+    PVOID Buffer;
+    CSHORT Source;
+    ULONG Affinity;
+    BOOLEAN Active;
+    struct _KPROCESS *Process;
 } KPROFILE, *PKPROFILE;
 
 /* Cached modules from the loader block */
@@ -130,8 +100,36 @@
 VOID STDCALL 
 DbgBreakPointNoBugCheck(VOID);
 
+STDCALL 
 VOID
+KeInitializeProfile(struct _KPROFILE* Profile,
+                    struct _KPROCESS* Process,
+                    PVOID ImageBase,
+                    ULONG ImageSize,
+                    ULONG BucketSize,
+                    KPROFILE_SOURCE ProfileSource,
+                    KAFFINITY Affinity);
+                    
 STDCALL
+VOID
+KeStartProfile(struct _KPROFILE* Profile,
+               PVOID Buffer);
+
+STDCALL               
+VOID
+KeStopProfile(struct _KPROFILE* Profile);
+    
+STDCALL    
+ULONG 
+KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource);
+
+STDCALL    
+VOID 
+KeSetIntervalProfile(KPROFILE_SOURCE ProfileSource,
+                     ULONG Interval);
+                
+VOID
+STDCALL
 KeProfileInterrupt(
     PKTRAP_FRAME TrapFrame
 );
@@ -143,14 +141,6 @@
 	IN KPROFILE_SOURCE		Source
 );
 
-VOID KiAddProfileEventToProcess(PLIST_ENTRY ListHead, PVOID Eip);
-VOID KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
-VOID KiInsertProfileIntoProcess(PLIST_ENTRY ListHead, PKPROFILE Profile);
-VOID KiInsertProfile(PKPROFILE Profile);
-VOID KiRemoveProfile(PKPROFILE Profile);
-VOID STDCALL KiDeleteProfile(PVOID ObjectBody);
-
-
 VOID STDCALL KeUpdateSystemTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c	2005-03-03 02:46:43 UTC (rev 13804)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ke/kqueue.c	2005-03-03 03:57:59 UTC (rev 13805)
@@ -1,11 +1,13 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PURPOSE:         ReactOS kernel
  * FILE:            ntoskrnl/ke/kqueue.c
  * PURPOSE:         Implement device queues
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Several optimizations and implement
+ *                                                    usage of Inserted flag + reformat and
+ *                                                    add debug output.
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES ****************************************************************/
@@ -16,216 +18,255 @@
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ *
+ * FUNCTION: Intializes a device queue
+ * ARGUMENTS:
+ *       DeviceQueue = Device queue to initialize
+ */
+VOID
+STDCALL
+KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
+{
 
+    /* Initialize the Header */
+    DeviceQueue->Type = DeviceQueueObject;
+    DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
+    
+    /* Initialize the Listhead and Spinlock */
+    InitializeListHead(&DeviceQueue->DeviceListHead);
+    KeInitializeSpinLock(&DeviceQueue->Lock);
+    
+    /* Set it as busy */
+    DeviceQueue->Busy=FALSE;
+}
+
 /*
  * @implemented
+ *
+ * FUNCTION: Inserts an entry in a device queue
+ * ARGUMENTS:
+ *        DeviceQueue = Queue to insert the entry in
+ *        DeviceQueueEntry = Entry to insert
+ * RETURNS: False is the device queue wasn't busy
+ *          True otherwise
  */
[truncated at 1000 lines; 947 more skipped]