- FreeLdr Part II (ntoskrnl is now relocated, removes 3GB compiler flag). Note that there is a bug in LD which Filip and I are examining, so do not try this yet. 
    - Fix Registry ObRef/ObDeref bug -- Hartmut
    - Fix SID Capture Bug -- Thomas
    - Use KPRCB pointer properly (results in more portable and much faster code)
Modified: branches/alex_devel_branch/reactos/boot/freeldr/freeldr/multiboot.c
Modified: branches/alex_devel_branch/reactos/config
Modified: branches/alex_devel_branch/reactos/include/ntos/security.h
Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h
Modified: branches/alex_devel_branch/reactos/lib/ntdll/def/ntdll.def
Modified: branches/alex_devel_branch/reactos/lib/ntdll/rtl/misc.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/Makefile
Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/regobj.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/sysinfo.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/i386/ps.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ps.h
Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/create.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/device.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/dir.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/kd/kdebug.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/catch.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/clock.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/device.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/dpc.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/fpu.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/gdt.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/irq.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/i386/kernel.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/ipi.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/wait.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ob/object.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/i386/continue.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/idle.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/kill.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/process.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/thread.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/ps/w32call.c
Modified: branches/alex_devel_branch/reactos/ntoskrnl/se/sd.c
Modified: branches/alex_devel_branch/reactos/w32api/include/ddk/winddk.h

Modified: branches/alex_devel_branch/reactos/boot/freeldr/freeldr/multiboot.c
--- branches/alex_devel_branch/reactos/boot/freeldr/freeldr/multiboot.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/boot/freeldr/freeldr/multiboot.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -164,9 +164,7 @@
     /* Re-initalize EFLAGS */
     Ke386EraseFlags();
     
-    /* Get Kernel Base and Set MmSystemRangeStart */  
-    FrLdrGetKernelBase();
-
+    /* Get the PAE Mode */
     FrLdrGetPaeMode();
        
     /* Initialize the page directory */
@@ -531,6 +529,14 @@
     ULONG_PTR TargetSection;
     ULONG SectionSize;
     LONG i;
+    PIMAGE_DATA_DIRECTORY RelocationDDir;
+    PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+    ULONG Count;
+    ULONG_PTR Address, MaxAddress;
+    PUSHORT TypeOffset;
+    ULONG_PTR Delta;
+    PUSHORT ShortPtr;
+    PULONG LongPtr;
 
     /* Allocate 1024 bytes for PE Header */
     ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
@@ -552,8 +558,9 @@
     /* Now read the MZ header to get the offset to the PE Header */
     NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
      
-    /* Save the Image Base */
-    KernelBase = NtHeader->OptionalHeader.ImageBase;
+    /* Get Kernel Base */
+    KernelBase = NtHeader->OptionalHeader.ImageBase;  
+    FrLdrGetKernelBase();
     
     /* Save Entrypoint */
     KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
@@ -603,10 +610,65 @@
                    Section->Misc.VirtualSize - Section->SizeOfRawData);
         }
     }
+       
+    /* Get the Relocation Data Directory */
+    RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
     
-    /* Now relocate the file */
-    /* FIXME: ADD RELOC CODE */
+    /* Get the Relocation Section Start and End*/
+    RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
+    RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
+   
+    /* Calculate Difference between Real Base and Compiled Base*/
+    Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
     
+    /* Determine how far we shoudl relocate */
+    MaxAddress = KERNEL_BASE_PHYS + ImageSize;
+    
+    /* Relocate until we've processed all the blocks */
+    while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
+        
+        /* See how many Relocation Blocks we have */
+        Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
+        
+        /* Calculate the Address of this Directory */
+        Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
+        
+        /* Calculate the Offset of the Type */
+        TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+        for (i = 0; i < Count; i++) {
+            
+            ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
+
+            /* Don't relocate after the end of the loaded driver */
+            if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
+
+            switch (*TypeOffset >> 12) {
+                
+                case IMAGE_REL_BASED_ABSOLUTE:
+                    break;
+
+                case IMAGE_REL_BASED_HIGH:
+                    *ShortPtr += HIWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_LOW:
+                    *ShortPtr += LOWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_HIGHLOW:
+                    LongPtr = (PULONG)ShortPtr;
+                    *LongPtr += Delta;
+                    break;
+            }
+            
+            TypeOffset++;
+        }
+        
+        /* Move to the next Relocation Table */
+        RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
+    }
+    
     /* Increase the next Load Base */
     NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
 

Modified: branches/alex_devel_branch/reactos/config
--- branches/alex_devel_branch/reactos/config	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/config	2005-03-05 20:44:57 UTC (rev 13832)
@@ -5,7 +5,6 @@
 # Possible values in the future: alpha,i386,m68k,mips,powerpc
 ARCH := i386
 
-
 #
 # Which cpu should reactos optimize for
 # example : i486, i586, pentium, pentium2, pentium3, pentium4
@@ -14,7 +13,6 @@
 # see gcc manual for more cpu names and which cpus it can 
 # be optimized for. 
 #
-
 OARCH := pentium2
 
 #
@@ -43,11 +41,6 @@
 ACPI := 0
 
 #
-# whether to use a 3GB User, 1GB Kernel memory map
-#
-3GB := 0
-
-#
 # Which version of NDIS do we support up to?
 #
 #NDISVERSION=NDIS50

Modified: branches/alex_devel_branch/reactos/include/ntos/security.h
--- branches/alex_devel_branch/reactos/include/ntos/security.h	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/include/ntos/security.h	2005-03-05 20:44:57 UTC (rev 13832)
@@ -160,7 +160,7 @@
 #define TOKEN_WRITE			(0x200e0L)
 #define TOKEN_EXECUTE			(0x20000L)
 
-typedef BOOL SECURITY_CONTEXT_TRACKING_MODE;
+typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
 
 #define SECURITY_STATIC_TRACKING	(0)
 #define SECURITY_DYNAMIC_TRACKING	(1)
@@ -193,13 +193,14 @@
   TokenOrigin
 } TOKEN_INFORMATION_CLASS;
 
-typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
+typedef enum _SECURITY_IMPERSONATION_LEVEL
+{
+  SecurityAnonymous,
+  SecurityIdentification,
+  SecurityImpersonation,
+  SecurityDelegation
+} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
 
-#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0)
-#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1)
-#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2)
-#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3)
-
 typedef ULONG ACCESS_MASK, *PACCESS_MASK;
 typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
 

Modified: branches/alex_devel_branch/reactos/include/ntos/zwtypes.h
--- branches/alex_devel_branch/reactos/include/ntos/zwtypes.h	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/include/ntos/zwtypes.h	2005-03-05 20:44:57 UTC (rev 13832)
@@ -1220,9 +1220,17 @@
 #define ProcessSessionInformation		24
 #define ProcessForegroundInformation		25
 #define ProcessWow64Information			26
-/* ReactOS private. */
 #define ProcessImageFileName			27
-#define MaxProcessInfoClass			28
+#define ProcessLUIDDeviceMapsEnabled            28
+#define ProcessBreakOnTermination               29
+#define ProcessDebugObjectHandle                30
+#define ProcessDebugFlags                       31
+#define ProcessHandleTracing                    32
+#define ProcessUnknown33                        33
+#define ProcessUnknown34                        34
+#define ProcessUnknown35                        35
+#define ProcessCookie                           36
+#define MaxProcessInfoClass                     36
 
 /*
  * thread query / set information class

Modified: branches/alex_devel_branch/reactos/lib/ntdll/def/ntdll.def
--- branches/alex_devel_branch/reactos/lib/ntdll/def/ntdll.def	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/lib/ntdll/def/ntdll.def	2005-03-05 20:44:57 UTC (rev 13832)
@@ -362,6 +362,7 @@
 RtlCustomCPToUnicodeN@24
 RtlCutoverTimeToSystemTime@16
 RtlDeNormalizeProcessParams@4
+RtlDecodePointer@4=RtlEncodePointer@4
 RtlDecompressBuffer@24
 RtlDecompressFragment@32
 RtlDelete@4
@@ -394,6 +395,7 @@
 RtlDumpResource@4
 RtlDuplicateUnicodeString@12
 RtlEmptyAtomTable@8
+RtlEncodePointer@4
 RtlEnlargedIntegerMultiply@8
 RtlEnlargedUnsignedDivide@16
 RtlEnlargedUnsignedMultiply@8

Modified: branches/alex_devel_branch/reactos/lib/ntdll/rtl/misc.c
--- branches/alex_devel_branch/reactos/lib/ntdll/rtl/misc.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/lib/ntdll/rtl/misc.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -15,6 +15,9 @@
 #include <ddk/ntddk.h>
 #include <ntdll/rtl.h>
 
+#define NDEBUG
+#include <ntdll/ntdll.h>
+
 /**********************************************************************
  * NAME							EXPORTED
  * 	RtlGetNtProductType
@@ -107,3 +110,30 @@
 	PPEB pPeb = NtCurrentPeb();
 	return pPeb->NtGlobalFlag;
 }
+
+
+/*
+ * @implemented
+ */
+PVOID
+STDCALL
+RtlEncodePointer(IN PVOID Pointer)
+{
+  ULONG Cookie;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(NtCurrentProcess(),
+                                     ProcessCookie,
+                                     &Cookie,
+                                     sizeof(Cookie),
+                                     NULL);
+
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to receive the process cookie! Status: 0x%x\n", Status);
+    return NULL;
+  }
+
+  return (PVOID)((ULONG_PTR)Pointer ^ Cookie);
+}
+

Modified: branches/alex_devel_branch/reactos/ntoskrnl/Makefile
--- branches/alex_devel_branch/reactos/ntoskrnl/Makefile	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/Makefile	2005-03-05 20:44:57 UTC (rev 13832)
@@ -47,12 +47,7 @@
 TARGET_CFLAGS += -D_DISABLE_TIDENTS
 
 # 3GB User Mode Memory Space support
-ifeq ($(3GB), 1)
-TARGET_CFLAGS += -D__3GB__
-TARGET_BASE = 0xC0000000
-else
 TARGET_BASE = 0x80000000
-endif
 
 ifneq ($(DBG), 0)
 TARGET_CFLAGS += -DDBG

Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c
--- branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/cm/registry.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -20,7 +20,6 @@
 
 POBJECT_TYPE  CmiKeyType = NULL;
 PREGISTRY_HIVE  CmiVolatileHive = NULL;
-KSPIN_LOCK  CmiKeyListLock;
 
 LIST_ENTRY CmiHiveListHead;
 
@@ -361,7 +360,6 @@
   CmiVolatileHive->RootSecurityCell = RootSecurityCell;
 #endif
 
-  KeInitializeSpinLock(&CmiKeyListLock);
 
   /* Create '\Registry\Machine' key. */
   RtlInitUnicodeString(&KeyName,

Modified: branches/alex_devel_branch/reactos/ntoskrnl/cm/regobj.c
--- branches/alex_devel_branch/reactos/ntoskrnl/cm/regobj.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/cm/regobj.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -76,6 +76,9 @@
 		KeyName.Length);
   KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
 
+  /* Acquire hive lock */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
   FoundObject = CmiScanKeyList(ParsedKey,
 			       &KeyName,
@@ -91,6 +94,8 @@
 				Attributes);
       if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
 	{
+          ExReleaseResourceLite(&CmiRegistryLock);
+          KeLeaveCriticalRegion();
 	  RtlFreeUnicodeString(&KeyName);
 	  return(STATUS_UNSUCCESSFUL);
 	}
@@ -104,6 +109,9 @@
 				    &LinkPath);
 	  if (NT_SUCCESS(Status))
 	    {
+              ExReleaseResourceLite(&CmiRegistryLock);
+              KeLeaveCriticalRegion();
+
 	      DPRINT("LinkPath '%wZ'\n", &LinkPath);
 
 	      /* build new FullPath for reparsing */
@@ -152,6 +160,8 @@
 			      (PVOID*)&FoundObject);
       if (!NT_SUCCESS(Status))
 	{
+          ExReleaseResourceLite(&CmiRegistryLock);
+          KeLeaveCriticalRegion();
 	  RtlFreeUnicodeString(&KeyName);
 	  return(Status);
 	}
@@ -179,7 +189,12 @@
 	  if (NT_SUCCESS(Status))
 	    {
 	      DPRINT("LinkPath '%wZ'\n", &LinkPath);
+	
+              ExReleaseResourceLite(&CmiRegistryLock);
+              KeLeaveCriticalRegion();
 
+	      ObDereferenceObject(FoundObject);
+
 	      /* build new FullPath for reparsing */
 	      TargetPath.MaximumLength = LinkPath.MaximumLength;
 	      if (EndPtr != NULL)
@@ -213,6 +228,8 @@
 	    }
 	}
     }
+  ExReleaseResourceLite(&CmiRegistryLock);
+  KeLeaveCriticalRegion();
 
   DPRINT("CmiObjectParse: %s\n", FoundObject->Name);
 
@@ -269,6 +286,10 @@
 
   ObReferenceObject (ParentKeyObject);
 
+  /* Acquire hive lock */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
   if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
     {
       DPRINT1("Key not found in parent list ???\n");
@@ -297,6 +318,9 @@
 
   ObDereferenceObject (ParentKeyObject);
 
+  ExReleaseResourceLite(&CmiRegistryLock);
+  KeLeaveCriticalRegion();
+
   if (KeyObject->NumberOfSubKeys)
     {
       KEBUGCHECK(REGISTRY_ERROR);
@@ -527,11 +551,9 @@
 CmiAddKeyToList(PKEY_OBJECT ParentKey,
 		PKEY_OBJECT NewKey)
 {
-  KIRQL OldIrql;
 
   DPRINT("ParentKey %.08x\n", ParentKey);
 
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
 
   if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
     {
@@ -563,7 +585,6 @@
 		NULL,
 		UserMode);
   NewKey->ParentKey = ParentKey;
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 }
 
 
@@ -571,11 +592,9 @@
 CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
 {
   PKEY_OBJECT ParentKey;
-  KIRQL OldIrql;
   DWORD Index;
 
   ParentKey = KeyToRemove->ParentKey;
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
   /* FIXME: If list maintained in alphabetic order, use dichotomic search */
   for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++)
     {
@@ -586,7 +605,6 @@
 			  &ParentKey->SubKeys[Index + 1],
 			  (ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
 	  ParentKey->NumberOfSubKeys--;
-	  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 
 	  DPRINT("Dereference parent key: 0x%x\n", ParentKey);
 	
@@ -594,7 +612,6 @@
 	  return STATUS_SUCCESS;
 	}
     }
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 
   return STATUS_UNSUCCESSFUL;
 }
@@ -606,13 +623,12 @@
 	       ULONG Attributes)
 {
   PKEY_OBJECT CurKey;
-  KIRQL OldIrql;
   ULONG Index;
-
+  NTSTATUS Status;
+  
   DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
 	 KeyName, &Parent->Name);
 
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
   /* FIXME: if list maintained in alphabetic order, use dichotomic search */
   for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
     {
@@ -622,8 +638,7 @@
 	  if ((KeyName->Length == CurKey->Name.Length)
 	      && (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
 	    {
-	      KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-	      return CurKey;
+	      break;
 	    }
 	}
       else
@@ -631,13 +646,23 @@
 	  if ((KeyName->Length == CurKey->Name.Length)
 	      && (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
 	    {
-	      KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-	      return CurKey;
+	      break;
 	    }
 	}
     }
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 
+  if (Index < Parent->NumberOfSubKeys)
+    {
+      Status = ObReferenceObjectByPointer(CurKey,
+	                                  STANDARD_RIGHTS_REQUIRED,
+				          NULL,
+				          UserMode);
+      if (NT_SUCCESS(Status))
+	{
+          return CurKey;
+        }
+    }
+  
   return NULL;
 }
 

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ex/sysinfo.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ex/sysinfo.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ex/sysinfo.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -46,17 +46,18 @@
 	PULONG	CpuUsage
 	)
 {
-	PKPCR Pcr;
+	PKPRCB Prcb;
 	ULONG TotalTime;
-	ULONG PercentTime = 0;
 	ULONGLONG ScaledIdle;
 
-	Pcr = KeGetCurrentKPCR();
+	Prcb = KeGetCurrentPrcb();
 
-	ScaledIdle = Pcr->PrcbData.IdleThread->KernelTime * 100;
-	TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-	if (TotalTime) PercentTime = 100 - (ScaledIdle / TotalTime);
-	CpuUsage = &PercentTime;
+	ScaledIdle = Prcb->IdleThread->KernelTime * 100;
+	TotalTime = Prcb->KernelTime + Prcb->UserTime;
+	if (TotalTime != 0)
+          *CpuUsage = 100 - (ScaledIdle / TotalTime);
+        else
+          *CpuUsage = 0;
 }
 
 /*
@@ -70,20 +71,13 @@
 	PULONG	ProcessorNumber
 	)
 {
-	PKPCR Pcr;
-	ULONG TotalTime;
-	ULONG ThreadTime;
-	ULONG ProcNumber;
+	PKPRCB Prcb;
 
-	Pcr = KeGetCurrentKPCR();
+	Prcb = KeGetCurrentPrcb();
 
-	TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-	ThreadTime = Pcr->PrcbData.CurrentThread->KernelTime;
-	ProcNumber = Pcr->ProcessorNumber;
-
-	ThreadKernelTime = &ThreadTime;
-	TotalCpuTime = &TotalTime;
-	ProcessorNumber = &ProcNumber;
+	*ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime;
+	*TotalCpuTime = Prcb->CurrentThread->KernelTime;
+	*ProcessorNumber = KeGetCurrentKPCR()->ProcessorNumber;
 }
 
 /*
@@ -377,7 +371,7 @@
 {
 	PSYSTEM_PROCESSOR_INFORMATION Spi 
 		= (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
-	PKPCR Pcr;
+	PKPRCB Prcb;
 	*ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
 	/*
 	 * Check user buffer's size 
@@ -386,12 +380,12 @@
 	{
 		return (STATUS_INFO_LENGTH_MISMATCH);
 	}
-	Pcr = KeGetCurrentKPCR();
+	Prcb = KeGetCurrentPrcb();
 	Spi->ProcessorArchitecture = 0; /* Intel Processor */
-	Spi->ProcessorLevel	   = Pcr->PrcbData.CpuType;
-	Spi->ProcessorRevision	   = Pcr->PrcbData.CpuStep;
+	Spi->ProcessorLevel	   = Prcb->CpuType;
+	Spi->ProcessorRevision	   = Prcb->CpuStep;
 	Spi->Unknown 		   = 0;
-	Spi->FeatureBits	   = Pcr->PrcbData.FeatureBits;
+	Spi->FeatureBits	   = Prcb->FeatureBits;
 
 	DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
 		Spi->ProcessorLevel, Spi->ProcessorRevision);
@@ -727,7 +721,7 @@
 
         ULONG i;
 	LARGE_INTEGER CurrentTime;
-	PKPCR Pcr;
+	PKPRCB Prcb;
 
 	*ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSORTIME_INFO);
 	/*
@@ -739,19 +733,17 @@
 	}
 
 	CurrentTime.QuadPart = KeQueryInterruptTime();
-	Pcr = (PKPCR)KPCR_BASE;   
+	Prcb = ((PKPCR)KPCR_BASE)->Prcb;
 	for (i = 0; i < KeNumberProcessors; i++)
 	{
-
-	   Spi->TotalProcessorRunTime.QuadPart = (Pcr->PrcbData.IdleThread->KernelTime + Pcr->PrcbData.IdleThread->UserTime) * 100000LL; // IdleTime
-           Spi->TotalProcessorTime.QuadPart =  Pcr->PrcbData.KernelTime * 100000LL; // KernelTime
-           Spi->TotalProcessorUserTime.QuadPart = Pcr->PrcbData.UserTime * 100000LL;
-           Spi->TotalDPCTime.QuadPart = Pcr->PrcbData.DpcTime * 100000LL;
-           Spi->TotalInterruptTime.QuadPart = Pcr->PrcbData.InterruptTime * 100000LL;
-           Spi->TotalInterrupts = Pcr->PrcbData.InterruptCount; // Interrupt Count
+	   Spi->TotalProcessorRunTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL; // IdleTime
+           Spi->TotalProcessorTime.QuadPart =  Prcb->KernelTime * 100000LL; // KernelTime
+           Spi->TotalProcessorUserTime.QuadPart = Prcb->UserTime * 100000LL;
+           Spi->TotalDPCTime.QuadPart = Prcb->DpcTime * 100000LL;
+           Spi->TotalInterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
+           Spi->TotalInterrupts = Prcb->InterruptCount; // Interrupt Count
 	   Spi++;
-//	   Pcr++;
-	   Pcr = (PKPCR)((ULONG_PTR)Pcr + PAGE_SIZE);
+	   Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
 	}
      
 	return (STATUS_SUCCESS);

Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/i386/ps.h
--- branches/alex_devel_branch/reactos/ntoskrnl/include/internal/i386/ps.h	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/include/internal/i386/ps.h	2005-03-05 20:44:57 UTC (rev 13832)
@@ -217,7 +217,7 @@
 typedef struct _KPCR {
   KPCR_TIB  Tib;                /* 00 */
   struct _KPCR  *Self;          /* 1C */
-  struct _KPRCB  *PCRCB;        /* 20 */
+  struct _KPRCB  *Prcb;         /* 20 */
   KIRQL  Irql;                  /* 24 */
   ULONG  IRR;                   /* 28 */
   ULONG  IrrActive;             /* 2C */
@@ -269,9 +269,28 @@
   return((PKPCR)value);
 }
 
+static inline PKPRCB KeGetCurrentPrcb(VOID)
+{
+  ULONG value;
+
+#if defined(__GNUC__)
+  __asm__ __volatile__ ("movl %%fs:0x20, %0\n\t"
+	  : "=r" (value)
+    : /* no inputs */
+    );
+#elif defined(_MSC_VER)
+  __asm mov eax, fs:0x20;
+  __asm mov value, eax;
 #else
+#error Unknown compiler for inline assembler
+#endif
+  return((PKPRCB)value);
+}
 
+#else
+
 #define KeGetCurrentKPCR(X) ((PKPCR)KPCR_BASE)
+#define KeGetCurrentPrcb() (((PKPCR)KPCR_BASE)->Prcb)
 
 #endif
 

Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h
--- branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ke.h	2005-03-05 20:44:57 UTC (rev 13832)
@@ -41,6 +41,7 @@
 struct _KTHREAD;
 struct _KIRQ_TRAPFRAME;
 struct _KPCR;
+struct _KPRCB;
 struct _KEXCEPTION_FRAME;
 
 #define IPI_REQUEST_FUNCTIONCALL    0
@@ -207,7 +208,7 @@
 VOID KeInitExceptions(VOID);
 VOID KeInitInterrupts(VOID);
 VOID KeInitTimer(VOID);
-VOID KeInitDpc(struct _KPCR* Pcr);
+VOID KeInitDpc(struct _KPRCB* Prcb);
 VOID KeInitDispatcher(VOID);
 VOID inline FASTCALL KeInitializeDispatcher(VOID);
 VOID KiInitializeSystemClock(VOID);

Modified: branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ps.h
--- branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ps.h	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/include/internal/ps.h	2005-03-05 20:44:57 UTC (rev 13832)
@@ -416,6 +416,7 @@
   PRTL_BITMAP           VadPhysicalPagesBitMap;
   ULONG                 VadPhysicalPages;
   KSPIN_LOCK            AweLock;
+  ULONG                 Cookie;
 
   /*
    * FIXME - ReactOS specified - remove the following fields ASAP!!!

Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/create.c
--- branches/alex_devel_branch/reactos/ntoskrnl/io/create.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/io/create.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -213,7 +213,7 @@
   DPRINT("IoCreateStreamFileObject(FileObject %x, DeviceObject %x)\n",
 	 FileObject, DeviceObject);
 
-  ASSERT_IRQL(PASSIVE_LEVEL);
+  PAGED_CODE();
 
   Status = ObCreateObject(KernelMode,
 			  IoFileObjectType,
@@ -406,6 +406,10 @@
      }
      _SEH_HANDLE
      {
+       if(SystemEaBuffer != NULL)
+       {
+         ExFreePool(SystemEaBuffer);
+       }
        Status = _SEH_GetExceptionCode();
      }
      _SEH_END;
@@ -596,7 +600,7 @@
      ExFreePool(SystemEaBuffer);
    }
 
-   ASSERT_IRQL(PASSIVE_LEVEL);
+   PAGED_CODE();
 
    DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));
 

Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/device.c
--- branches/alex_devel_branch/reactos/ntoskrnl/io/device.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/io/device.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -541,7 +541,7 @@
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    
-   ASSERT_IRQL(PASSIVE_LEVEL);
+   PAGED_CODE();
    
    if (DeviceName != NULL)
    {

Modified: branches/alex_devel_branch/reactos/ntoskrnl/io/dir.c
--- branches/alex_devel_branch/reactos/ntoskrnl/io/dir.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/io/dir.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -38,13 +38,41 @@
    PIRP Irp;
    PDEVICE_OBJECT DeviceObject;
    PFILE_OBJECT FileObject;
-   NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
    
    DPRINT("NtNotifyChangeDirectoryFile()\n");
+   
+   PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(IoStatusBlock,
+                     sizeof(IO_STATUS_BLOCK),
+                     sizeof(ULONG));
+       if(BufferSize != 0)
+       {
+         ProbeForWrite(Buffer,
+                       BufferSize,
+                       sizeof(ULONG));
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
 
    Status = ObReferenceObjectByHandle(FileHandle,
 				      FILE_LIST_DIRECTORY,
@@ -155,14 +183,39 @@
    PIRP Irp;
    PDEVICE_OBJECT DeviceObject;
    PFILE_OBJECT FileObject;
-   NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
    
    DPRINT("NtQueryDirectoryFile()\n");
+   
+   PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(IoStatusBlock,
+                     sizeof(IO_STATUS_BLOCK),
+                     sizeof(ULONG));
+       ProbeForWrite(FileInformation,
+                     Length,
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
 
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
    Status = ObReferenceObjectByHandle(FileHandle,
 				      FILE_LIST_DIRECTORY,
 				      IoFileObjectType,

Modified: branches/alex_devel_branch/reactos/ntoskrnl/kd/kdebug.c
--- branches/alex_devel_branch/reactos/ntoskrnl/kd/kdebug.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/kd/kdebug.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -444,7 +444,7 @@
       /* FIXME: This is needed to allow Int10 to attach to csrss until
        * bugchecks are done properly with Inbv, which i'll implement soon -- Alex
        */
-      KeGetCurrentKPCR()->PrcbData.DpcRoutineActive = FALSE;
+      KeGetCurrentPrcb()->DpcRoutineActive = FALSE;
       KEBUGCHECK(MANUALLY_INITIATED_CRASH);
     }
   /* 

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/catch.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ke/catch.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ke/catch.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -54,7 +54,7 @@
     DPRINT("KiDispatchException() called\n");
 
     /* Increase number of Exception Dispatches */
-    KeGetCurrentKPCR()->PrcbData.KeExceptionDispatchCount++;
+    KeGetCurrentPrcb()->KeExceptionDispatchCount++;
 
     if (!Context) {
         

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/clock.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ke/clock.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ke/clock.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -242,22 +242,22 @@
     IN KIRQL  Irql
     )
 {
-   PKPCR Pcr;
+   PKPRCB Prcb;
    PKTHREAD CurrentThread;
    PKPROCESS CurrentProcess;
 #if 0
    ULONG DpcLastCount;
 #endif
 
-   Pcr = KeGetCurrentKPCR();
+   Prcb = KeGetCurrentPrcb();
 
    /* Make sure we don't go further if we're in early boot phase. */
-   if (Pcr == NULL || Pcr->PrcbData.CurrentThread == NULL)
+   if (Prcb == NULL || Prcb->CurrentThread == NULL)
       return;
 
-   DPRINT("KernelTime  %u, UserTime %u \n", Pcr->PrcbData.KernelTime, Pcr->PrcbData.UserTime);
+   DPRINT("KernelTime  %u, UserTime %u \n", Prcb->KernelTime, Prcb->UserTime);
 
-   CurrentThread = Pcr->PrcbData.CurrentThread;
+   CurrentThread = Prcb->CurrentThread;
    CurrentProcess = CurrentThread->ApcState.Process;
 
    /* 
@@ -269,36 +269,36 @@
    {
       InterlockedIncrementUL(&CurrentThread->UserTime);
       InterlockedIncrementUL(&CurrentProcess->UserTime);
-      Pcr->PrcbData.UserTime++;
+      Prcb->UserTime++;
    }
    else
    {
       if (Irql > DISPATCH_LEVEL)
       {
-         Pcr->PrcbData.InterruptTime++;
+         Prcb->InterruptTime++;
       }
       else if (Irql == DISPATCH_LEVEL)
       {
-         Pcr->PrcbData.DpcTime++;
+         Prcb->DpcTime++;
       }
       else
       {
          InterlockedIncrementUL(&CurrentThread->KernelTime);
          InterlockedIncrementUL(&CurrentProcess->KernelTime);
-	 Pcr->PrcbData.KernelTime++;
+	 Prcb->KernelTime++;
       }
    }
 
 #if 0
-   DpcLastCount = Pcr->PrcbData.DpcLastCount;
-   Pcr->PrcbData.DpcLastCount = Pcr->PrcbData.DpcCount;
-   Pcr->PrcbData.DpcRequestRate = ((Pcr->PrcbData.DpcCount - DpcLastCount) +
-                                   Pcr->PrcbData.DpcRequestRate) / 2;
+   DpcLastCount = Prcb->DpcLastCount;
+   Prcb->DpcLastCount = Prcb->DpcCount;
+   Prcb->DpcRequestRate = ((Prcb->DpcCount - DpcLastCount) +
+                                   Prcb->DpcRequestRate) / 2;
 #endif
 
-   if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0 &&
-       Pcr->PrcbData.DpcRoutineActive == FALSE &&
-       Pcr->PrcbData.DpcInterruptRequested == FALSE)
+   if (Prcb->DpcData[0].DpcQueueDepth > 0 &&
+       Prcb->DpcRoutineActive == FALSE &&
+       Prcb->DpcInterruptRequested == FALSE)
    {
       HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
    }
@@ -311,7 +311,7 @@
     */
    if ((CurrentThread->Quantum -= 3) <= 0)
    {
-     Pcr->PrcbData.QuantumEnd = TRUE;
+     Prcb->QuantumEnd = TRUE;
      HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
    }
 }

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/device.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ke/device.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ke/device.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -57,17 +57,17 @@
 {
 	KIRQL OldIrql;
 	PKPROCESS Process = NULL;
-	PKPCR Pcr = NULL;
+	PKPRCB Prcb = NULL;
 	
 	/* Raise the IRQL for the TB Flush */
 	OldIrql = KeRaiseIrqlToSynchLevel();
 	
 	/* All CPUs need to have the TB flushed. */
 	if (CurrentCpuOnly == FALSE) {
-		Pcr = KeGetCurrentKPCR();
+		Prcb = KeGetCurrentPrcb();
 		
 		/* How many CPUs is our caller using? */
-		Process = Pcr->PrcbData.CurrentThread->ApcState.Process;
+		Process = Prcb->CurrentThread->ApcState.Process;
 		
 		/* More then one, so send an IPI */
 		if (Process->ActiveProcessors > 1) {
@@ -83,7 +83,7 @@
 		/* Did we send an IPI? If so, wait for completion */
 		if (Process->ActiveProcessors > 1) {
 			do {
-			} while (Pcr->PrcbData.TargetSet != 0);
+			} while (Prcb->TargetSet != 0);
 		} 
 	} 
 	

Modified: branches/alex_devel_branch/reactos/ntoskrnl/ke/dpc.c
--- branches/alex_devel_branch/reactos/ntoskrnl/ke/dpc.c	2005-03-05 20:44:41 UTC (rev 13831)
+++ branches/alex_devel_branch/reactos/ntoskrnl/ke/dpc.c	2005-03-05 20:44:57 UTC (rev 13832)
@@ -32,14 +32,14 @@
  */
 VOID
 INIT_FUNCTION
-KeInitDpc(PKPCR Pcr)
+KeInitDpc(PKPRCB Prcb)
 {
-   InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead);
-   KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0);
-   KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-   Pcr->PrcbData.MaximumDpcQueueDepth = 4;
-   Pcr->PrcbData.MinimumDpcRate = 3;
-   Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0;    
+   InitializeListHead(&Prcb->DpcData[0].DpcListHead);
+   KeInitializeEvent(Prcb->DpcEvent, 0, 0);
+   KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock);
+   Prcb->MaximumDpcQueueDepth = 4;
+   Prcb->MinimumDpcRate = 3;
+   Prcb->DpcData[0].DpcQueueDepth = 0;
 }
 
 /*
@@ -156,7 +156,7 @@
                  PVOID SystemArgument2)
 {
     KIRQL OldIrql;
-    PKPCR Pcr;
+    PKPRCB Prcb;
 
     DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
         Dpc, SystemArgument1, SystemArgument2);
[truncated at 1000 lines; 952 more skipped]