added more irql checks and secured access to buffers in symbolic link code
Modified: trunk/reactos/ntoskrnl/cm/cm.h
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c
Modified: trunk/reactos/ntoskrnl/ob/ntobj.c
Modified: trunk/reactos/ntoskrnl/ob/object.c
Modified: trunk/reactos/ntoskrnl/ob/security.c
Modified: trunk/reactos/ntoskrnl/ob/symlink.c
Modified: trunk/reactos/ntoskrnl/po/power.c

Modified: trunk/reactos/ntoskrnl/cm/cm.h
--- trunk/reactos/ntoskrnl/cm/cm.h	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/cm/cm.h	2005-02-22 21:09:54 UTC (rev 13718)
@@ -431,6 +431,7 @@
     PEX_CALLBACK_FUNCTION Function;
     PVOID Context;
     LARGE_INTEGER Cookie;
+    BOOLEAN PendingDelete;
 } REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
--- trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -50,6 +50,7 @@
     ExInitializeRundownProtection(&Callback->RundownRef);
     Callback->Function = Function;
     Callback->Context = Context;
+    Callback->PendingDelete = FALSE;
     
     /* add it to the callback list and receive a cookie for the callback */
     ExAcquireFastMutex(&CmiCallbackLock);
@@ -87,22 +88,32 @@
     CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
     if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart)
     {
-      /* found the callback, don't unlink it from the list yet so we don't screw
-         the calling loop */
-      ExReleaseFastMutex(&CmiCallbackLock);
+      if(!CurrentCallback->PendingDelete)
+      {
+        /* found the callback, don't unlink it from the list yet so we don't screw
+           the calling loop */
+        CurrentCallback->PendingDelete = TRUE;
+        ExReleaseFastMutex(&CmiCallbackLock);
 
-      /* if the callback is currently executing, wait until it finished */
-      ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
+        /* if the callback is currently executing, wait until it finished */
+        ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef);
 
-      /* time to unlink it. It's now safe because every attempt to acquire a
-         runtime protection on this callback will fail */
-      ExAcquireFastMutex(&CmiCallbackLock);
-      RemoveEntryList(&CurrentCallback->ListEntry);
-      ExReleaseFastMutex(&CmiCallbackLock);
+        /* time to unlink it. It's now safe because every attempt to acquire a
+           runtime protection on this callback will fail */
+        ExAcquireFastMutex(&CmiCallbackLock);
+        RemoveEntryList(&CurrentCallback->ListEntry);
+        ExReleaseFastMutex(&CmiCallbackLock);
 
-      /* free the callback */
-      ExFreePool(CurrentCallback);
-      return STATUS_SUCCESS;
+        /* free the callback */
+        ExFreePool(CurrentCallback);
+        return STATUS_SUCCESS;
+      }
+      else
+      {
+        /* pending delete, pretend like it already is deleted */
+        ExReleaseFastMutex(&CmiCallbackLock);
+        return STATUS_UNSUCCESSFUL;
+      }
     }
   }
   
@@ -127,7 +138,8 @@
     PREGISTRY_CALLBACK CurrentCallback;
 
     CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
-    if(ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
+    if(!CurrentCallback->PendingDelete &&
+       ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
     {
       NTSTATUS Status;
       

Modified: trunk/reactos/ntoskrnl/ob/dirobj.c
--- trunk/reactos/ntoskrnl/ob/dirobj.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/dirobj.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -50,6 +50,8 @@
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status = STATUS_SUCCESS;
    
+   PAGED_CODE();
+   
    PreviousMode = ExGetPreviousMode();
    
    if(PreviousMode != KernelMode)
@@ -169,6 +171,8 @@
   ULONG NextEntry = 0;
   NTSTATUS Status = STATUS_SUCCESS;
   
+  PAGED_CODE();
+  
   PreviousMode = ExGetPreviousMode();
 
   if(PreviousMode != KernelMode)
@@ -427,6 +431,8 @@
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
   
+  PAGED_CODE();
+  
   DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
 	 "DesiredAccess %x, ObjectAttributes %x\n",
 	 DirectoryHandle, DesiredAccess, ObjectAttributes);

Modified: trunk/reactos/ntoskrnl/ob/handle.c
--- trunk/reactos/ntoskrnl/ob/handle.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/handle.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -287,7 +287,7 @@
    HANDLE TargetHandle;
    NTSTATUS Status;
    
-   ASSERT_IRQL(PASSIVE_LEVEL);
+   PAGED_CODE();
    
    Status = ObReferenceObjectByHandle(SourceProcessHandle,
 				      PROCESS_DUP_HANDLE,
@@ -552,6 +552,8 @@
    PHANDLE_TABLE HandleTable;
    POBJECT_HEADER Header;
    HANDLE_BLOCK *Block;
+   
+   PAGED_CODE();
 
    DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
 
@@ -630,6 +632,8 @@
    HANDLE_BLOCK* new_blk = NULL;
    PHANDLE_TABLE HandleTable;
    KIRQL oldlvl;
+   
+   PAGED_CODE();
 
    DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
 
@@ -723,6 +727,8 @@
   PEPROCESS Process;
   KIRQL oldIrql;
   PHANDLE_ENTRY HandleEntry;
+  
+  PAGED_CODE();
 
   DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
 
@@ -777,7 +783,7 @@
    ULONG Attributes;
    NTSTATUS Status;
    
-   ASSERT_IRQL(PASSIVE_LEVEL);
+   PAGED_CODE();
    
    DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
 	   "ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
@@ -930,7 +936,7 @@
    POBJECT_HEADER	Header;
    NTSTATUS Status;
    
-   ASSERT_IRQL(PASSIVE_LEVEL);
+   PAGED_CODE();
    
    DPRINT("NtClose(Handle %x)\n",Handle);
    
@@ -966,6 +972,8 @@
 {
   POBJECT_HEADER ObjectHeader;
   ACCESS_MASK Access;
+  
+  PAGED_CODE();
 
   Access = DesiredAccess;
   ObjectHeader = BODY_TO_HEADER(Object);

Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/namespc.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -55,6 +55,8 @@
    UNICODE_STRING RemainingPath;
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
+   
+   PAGED_CODE();
 
    InitializeObjectAttributes(&ObjectAttributes,
 			      ObjectPath,
@@ -126,6 +128,8 @@
    UNICODE_STRING RemainingPath;
    PVOID Object = NULL;
    NTSTATUS Status;
+   
+   PAGED_CODE();
 
    DPRINT("ObOpenObjectByName(...)\n");
 

Modified: trunk/reactos/ntoskrnl/ob/ntobj.c
--- trunk/reactos/ntoskrnl/ob/ntobj.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/ntobj.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -37,6 +37,8 @@
 {
   PVOID Object;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   if (ObjectInformationClass != ObjectHandleInformation)
     return STATUS_INVALID_INFO_CLASS;
@@ -88,6 +90,8 @@
   ULONG InfoLength;
   PVOID Object;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   Status = ObReferenceObjectByHandle (ObjectHandle,
 				      0,
@@ -260,6 +264,8 @@
 {
   PVOID ObjectBody;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   Status = ObReferenceObjectByHandle(ObjectHandle,
 				     0,
@@ -299,6 +305,8 @@
 {
   PVOID ObjectBody;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   Status = ObReferenceObjectByHandle(ObjectHandle,
 				     0,

Modified: trunk/reactos/ntoskrnl/ob/object.c
--- trunk/reactos/ntoskrnl/ob/object.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/object.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -346,6 +346,8 @@
   UNICODE_STRING PathString;
   ULONG Attributes;
   PUNICODE_STRING ObjectName;
+  
+  PAGED_CODE();
 
   DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
 	 "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath);
@@ -483,6 +485,8 @@
   POBJECT_HEADER ObjectHeader;
   ULONG LocalReturnLength;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   *ReturnLength = 0;
 
@@ -611,7 +615,7 @@
   PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
   SECURITY_SUBJECT_CONTEXT SubjectContext;
 
-  ASSERT_IRQL(APC_LEVEL);
+  PAGED_CODE();
   
   if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
   {
@@ -814,6 +818,8 @@
 			   IN KPROCESSOR_MODE AccessMode)
 {
    POBJECT_HEADER Header;
+   
+   /* NOTE: should be possible to reference an object above APC_LEVEL! */
 
    DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
 	  Object,ObjectType);
@@ -876,6 +882,8 @@
 {
    NTSTATUS Status;
    
+   PAGED_CODE();
+   
    DPRINT("ObOpenObjectByPointer()\n");
    
    Status = ObReferenceObjectByPointer(Object,
@@ -1117,6 +1125,8 @@
 ObGetObjectPointerCount(PVOID Object)
 {
   POBJECT_HEADER Header;
+  
+  PAGED_CODE();
 
   ASSERT(Object);
   Header = BODY_TO_HEADER(Object);
@@ -1142,6 +1152,8 @@
 ObGetObjectHandleCount(PVOID Object)
 {
   POBJECT_HEADER Header;
+  
+  PAGED_CODE();
 
   ASSERT(Object);
   Header = BODY_TO_HEADER(Object);

Modified: trunk/reactos/ntoskrnl/ob/security.c
--- trunk/reactos/ntoskrnl/ob/security.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/security.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -1,4 +1,4 @@
-/* $Id:$
+/* $Id$
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -27,6 +27,8 @@
 {
   PSECURITY_DESCRIPTOR NewDescriptor;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   /* Build the new security descriptor */
   Status = SeAssignSecurity(SecurityDescriptor,
@@ -73,6 +75,8 @@
   POBJECT_HEADER Header;
   ULONG Length;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   Header = BODY_TO_HEADER(Object);
   if (Header->ObjectType == NULL)
@@ -129,6 +133,8 @@
 ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
 			IN BOOLEAN MemoryAllocated)
 {
+  PAGED_CODE();
+  
   if (SecurityDescriptor == NULL)
     return;
 
@@ -156,6 +162,8 @@
   POBJECT_HEADER Header;
   PVOID Object;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   DPRINT("NtQuerySecurityObject() called\n");
 
@@ -226,6 +234,8 @@
   ULONG Control = 0;
   ULONG_PTR Current;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   DPRINT("NtSetSecurityObject() called\n");
 

Modified: trunk/reactos/ntoskrnl/ob/symlink.c
--- trunk/reactos/ntoskrnl/ob/symlink.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/ob/symlink.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -206,61 +206,104 @@
 			   IN POBJECT_ATTRIBUTES ObjectAttributes,
 			   IN PUNICODE_STRING LinkTarget)
 {
+  HANDLE hLink;
   PSYMLINK_OBJECT SymbolicLink;
-  NTSTATUS Status;
+  UNICODE_STRING CapturedLinkTarget;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
 
-  ASSERT_IRQL(PASSIVE_LEVEL);
+  PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
 
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForWrite(LinkHandle,
+                    sizeof(HANDLE),
+                    sizeof(ULONG));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  
+  Status = RtlCaptureUnicodeString(&CapturedLinkTarget,
+                                   PreviousMode,
+                                   PagedPool,
+                                   FALSE,
+                                   LinkTarget);
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT1("NtCreateSymbolicLinkObject: Capturing the target link failed!\n");
+    return Status;
+  }
+
   DPRINT("NtCreateSymbolicLinkObject(LinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, LinkTarget %wZ)\n",
 	 LinkHandle,
 	 DesiredAccess,
 	 ObjectAttributes,
-	 LinkTarget);
+	 &CapturedLinkTarget);
 
   Status = ObCreateObject(ExGetPreviousMode(),
 			  ObSymbolicLinkType,
 			  ObjectAttributes,
-			  ExGetPreviousMode(),
+			  PreviousMode,
 			  NULL,
 			  sizeof(SYMLINK_OBJECT),
 			  0,
 			  0,
 			  (PVOID*)&SymbolicLink);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
+  if (NT_SUCCESS(Status))
+  {
+    SymbolicLink->TargetName.Length = 0;
+    SymbolicLink->TargetName.MaximumLength =
+      ((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR));
+    SymbolicLink->TargetName.Buffer =
+      ExAllocatePoolWithTag(NonPagedPool,
+			    SymbolicLink->TargetName.MaximumLength,
+			    TAG_SYMLINK_TARGET);
+    RtlCopyUnicodeString(&SymbolicLink->TargetName,
+		         &CapturedLinkTarget);
 
-  Status = ObInsertObject ((PVOID)SymbolicLink,
-			   NULL,
-			   DesiredAccess,
-			   0,
-			   NULL,
-			   LinkHandle);
-  if (!NT_SUCCESS(Status))
+    DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
+
+    ZwQuerySystemTime (&SymbolicLink->CreateTime);
+
+    Status = ObInsertObject ((PVOID)SymbolicLink,
+			     NULL,
+			     DesiredAccess,
+			     0,
+			     NULL,
+			     &hLink);
+    if (NT_SUCCESS(Status))
     {
-      ObDereferenceObject (SymbolicLink);
-      return Status;
+      _SEH_TRY
+      {
+        *LinkHandle = hLink;
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
     }
+    ObDereferenceObject(SymbolicLink);
+  }
+  
+  RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
+                                  PreviousMode,
+                                  FALSE);
 
-  SymbolicLink->TargetName.Length = 0;
-  SymbolicLink->TargetName.MaximumLength = 
-    ((wcslen(LinkTarget->Buffer) + 1) * sizeof(WCHAR));
-  SymbolicLink->TargetName.Buffer = 
-    ExAllocatePoolWithTag(NonPagedPool,
-			  SymbolicLink->TargetName.MaximumLength,
-			  TAG_SYMLINK_TARGET);
-  RtlCopyUnicodeString(&SymbolicLink->TargetName,
-		       LinkTarget);
-
-  DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
-
-  ZwQuerySystemTime (&SymbolicLink->CreateTime);
-
-  DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
-  ObDereferenceObject(SymbolicLink);
-
-  return(STATUS_SUCCESS);
+  return Status;
 }
 
 
@@ -282,16 +325,58 @@
 			 IN ACCESS_MASK DesiredAccess,
 			 IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
+  HANDLE hLink;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForWrite(LinkHandle,
+                    sizeof(HANDLE),
+                    sizeof(ULONG));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+
   DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n",
 	 ObjectAttributes->ObjectName);
 
-  return(ObOpenObjectByName(ObjectAttributes,
-			    ObSymbolicLinkType,
-			    NULL,
-			    (KPROCESSOR_MODE)KeGetPreviousMode(),
-			    DesiredAccess,
-			    NULL,
-			    LinkHandle));
+  Status = ObOpenObjectByName(ObjectAttributes,
+			      ObSymbolicLinkType,
+			      NULL,
+			      PreviousMode,
+			      DesiredAccess,
+			      NULL,
+			      &hLink);
+  if(NT_SUCCESS(Status))
+  {
+    _SEH_TRY
+    {
+      *LinkHandle = hLink;
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+  }
+  
+  return Status;
 }
 
 
@@ -313,38 +398,93 @@
 			  OUT PUNICODE_STRING LinkTarget,
 			  OUT PULONG ResultLength  OPTIONAL)
 {
+  UNICODE_STRING SafeLinkTarget;
   PSYMLINK_OBJECT SymlinkObject;
-  NTSTATUS Status;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      /* probe the unicode string and buffers supplied */
+      ProbeForWrite(LinkTarget,
+                    sizeof(UNICODE_STRING),
+                    sizeof(ULONG));
+      SafeLinkTarget = *LinkTarget;
+      ProbeForWrite(SafeLinkTarget.Buffer,
+                    SafeLinkTarget.MaximumLength,
+                    sizeof(WCHAR));
 
+      if(ResultLength != NULL)
+      {
+        ProbeForWrite(ResultLength,
+                      sizeof(ULONG),
+                      sizeof(ULONG));
+      }
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+  else
+  {
+    SafeLinkTarget = *LinkTarget;
+  }
+
   Status = ObReferenceObjectByHandle(LinkHandle,
 				     SYMBOLIC_LINK_QUERY,
 				     ObSymbolicLinkType,
-				     (KPROCESSOR_MODE)KeGetPreviousMode(),
+				     PreviousMode,
 				     (PVOID *)&SymlinkObject,
 				     NULL);
-  if (!NT_SUCCESS(Status))
+  if (NT_SUCCESS(Status))
+  {
+    ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR);
+    
+    _SEH_TRY
     {
-      return Status;
+      if(SafeLinkTarget.MaximumLength >= LengthRequired)
+      {
+        /* don't pass TargetLink to RtlCopyUnicodeString here because the caller
+           might have modified the structure which could lead to a copy into
+           kernel memory! */
+        RtlCopyUnicodeString(&SafeLinkTarget,
+                             &SymlinkObject->TargetName);
+        SafeLinkTarget.Buffer[SafeLinkTarget.Length / sizeof(WCHAR)] = L'\0';
+        /* copy back the new UNICODE_STRING structure */
+        *LinkTarget = SafeLinkTarget;
+      }
+      else
+      {
+        Status = STATUS_BUFFER_TOO_SMALL;
+      }
+      
+      if(ResultLength != NULL)
+      {
+        *ResultLength = LengthRequired;
+      }
     }
-
-  if (ResultLength != NULL)
+    _SEH_HANDLE
     {
-      *ResultLength = (ULONG)SymlinkObject->TargetName.Length + sizeof(WCHAR);
+      Status = _SEH_GetExceptionCode();
     }
+    _SEH_END;
 
-  if (LinkTarget->MaximumLength >= SymlinkObject->TargetName.Length + sizeof(WCHAR))
-    {
-      RtlCopyUnicodeString(LinkTarget,
-			   &SymlinkObject->TargetName);
-      Status = STATUS_SUCCESS;
-    }
-  else
-    {
-      Status = STATUS_BUFFER_TOO_SMALL;
-    }
+    ObDereferenceObject(SymlinkObject);
+  }
 
-  ObDereferenceObject(SymlinkObject);
-
   return Status;
 }
 

Modified: trunk/reactos/ntoskrnl/po/power.c
--- trunk/reactos/ntoskrnl/po/power.c	2005-02-22 20:08:06 UTC (rev 13717)
+++ trunk/reactos/ntoskrnl/po/power.c	2005-02-22 21:09:54 UTC (rev 13718)
@@ -91,6 +91,8 @@
   IN POWER_STATE State)
 {
   POWER_STATE ps;
+  
+  ASSERT_IRQL(DISPATCH_LEVEL);
 
   ps.SystemState = PowerSystemWorking;  // Fully on
   ps.DeviceState = PowerDeviceD0;       // Fully on
@@ -228,6 +230,8 @@
 	)
 {
    NTSTATUS Status;
+   
+   PAGED_CODE();
 
    DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
           "InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",