Thomas Weidenmueller <w3seek@reactos.com>
[reactos.git] / reactos / ntoskrnl / se / luid.c
index 9edbf0d..a7c516e 100644 (file)
-/* $Id: luid.c,v 1.7 2003/05/31 11:10:30 ekohl Exp $
+/* $Id$
  *
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * PURPOSE:           Security manager
- * FILE:              ntoskrnl/se/luid.c
- * PROGRAMER:         ?
- * REVISION HISTORY:
- *                 26/07/98: Added stubs for security functions
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/se/luid.c
+ * PURPOSE:         Security manager
+ * 
+ * PROGRAMMERS:     No programmer listed.
  */
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-
+#include <ntoskrnl.h>
 #include <internal/debug.h>
 
 /* GLOBALS *******************************************************************/
 
-static KSPIN_LOCK LuidLock;
 static LARGE_INTEGER LuidIncrement;
 static LARGE_INTEGER LuidValue;
 
-#define SYSTEM_LUID   0x3E7;
-
 /* FUNCTIONS *****************************************************************/
 
-VOID
+VOID INIT_FUNCTION
 SepInitLuid(VOID)
 {
-  KeInitializeSpinLock(&LuidLock);
-  LuidValue.QuadPart = SYSTEM_LUID;
+  LUID DummyLuidValue = SYSTEM_LUID;
+  
+  LuidValue.u.HighPart = DummyLuidValue.HighPart;
+  LuidValue.u.LowPart = DummyLuidValue.LowPart;
   LuidIncrement.QuadPart = 1;
 }
 
 
-NTSTATUS STDCALL
-NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
-{
-  LARGE_INTEGER ReturnedLuid;
-  KIRQL Irql;
-
-  KeAcquireSpinLock(&LuidLock,
-                   &Irql);
-  ReturnedLuid = LuidValue;
-  LuidValue = RtlLargeIntegerAdd(LuidValue,
-                                LuidIncrement);
-  KeReleaseSpinLock(&LuidLock,
-                   Irql);
-
-  LocallyUniqueId->LowPart = ReturnedLuid.u.LowPart;
-  LocallyUniqueId->HighPart = ReturnedLuid.u.HighPart;
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID STDCALL
-RtlCopyLuid(IN PLUID LuidDest,
-           IN PLUID LuidSrc)
+NTSTATUS
+ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
 {
-  LuidDest->LowPart = LuidSrc->LowPart;
-  LuidDest->HighPart = LuidSrc->HighPart;
+  LARGE_INTEGER NewLuid, PrevLuid;
+  
+  /* atomically increment the luid */
+  do
+  {
+    PrevLuid = (volatile LARGE_INTEGER)LuidValue;
+    NewLuid = RtlLargeIntegerAdd(PrevLuid,
+                                 LuidIncrement);
+  } while(ExfInterlockedCompareExchange64(&LuidValue.QuadPart,
+                                          &NewLuid.QuadPart,
+                                          &PrevLuid.QuadPart) != PrevLuid.QuadPart);
+
+  LocallyUniqueId->LowPart = NewLuid.u.LowPart;
+  LocallyUniqueId->HighPart = NewLuid.u.HighPart;
+  
+  return STATUS_SUCCESS;
 }
 
 
-BOOLEAN STDCALL
-RtlEqualLuid(IN PLUID Luid1,
-            IN PLUID Luid2)
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
 {
-  return (Luid1->LowPart == Luid2->LowPart &&
-         Luid1->HighPart == Luid2->HighPart);
+  LUID NewLuid;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForWrite(LocallyUniqueId,
+                    sizeof(LUID),
+                    sizeof(ULONG));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+
+  Status = ExpAllocateLocallyUniqueId(&NewLuid);
+
+  _SEH_TRY
+  {
+    *LocallyUniqueId = NewLuid;
+  }
+  _SEH_HANDLE
+  {
+    Status = _SEH_GetExceptionCode();
+  }
+  _SEH_END;
+
+  return Status;
 }
 
 /* EOF */