mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
added more irql checks and secured access to buffers in symbolic link code
svn path=/trunk/; revision=13718
This commit is contained in:
parent
87428f5f55
commit
310c7ac816
10 changed files with 288 additions and 83 deletions
|
@ -431,6 +431,7 @@ typedef struct _REGISTRY_CALLBACK
|
|||
PEX_CALLBACK_FUNCTION Function;
|
||||
PVOID Context;
|
||||
LARGE_INTEGER Cookie;
|
||||
BOOLEAN PendingDelete;
|
||||
} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK;
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -50,6 +50,7 @@ CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function,
|
|||
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 @@ CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
|
|||
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 @@ CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1,
|
|||
PREGISTRY_CALLBACK CurrentCallback;
|
||||
|
||||
CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
|
||||
if(ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
|
||||
if(!CurrentCallback->PendingDelete &&
|
||||
ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ NtOpenDirectoryObject (OUT PHANDLE DirectoryHandle,
|
|||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
|
@ -169,6 +171,8 @@ NtQueryDirectoryObject (IN HANDLE DirectoryHandle,
|
|||
ULONG NextEntry = 0;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
|
@ -427,6 +431,8 @@ NtCreateDirectoryObject (OUT PHANDLE DirectoryHandle,
|
|||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
|
||||
"DesiredAccess %x, ObjectAttributes %x\n",
|
||||
DirectoryHandle, DesiredAccess, ObjectAttributes);
|
||||
|
|
|
@ -287,7 +287,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
|||
HANDLE TargetHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
PAGED_CODE();
|
||||
|
||||
Status = ObReferenceObjectByHandle(SourceProcessHandle,
|
||||
PROCESS_DUP_HANDLE,
|
||||
|
@ -552,6 +552,8 @@ ObDeleteHandle(PEPROCESS Process,
|
|||
PHANDLE_TABLE HandleTable;
|
||||
POBJECT_HEADER Header;
|
||||
HANDLE_BLOCK *Block;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
|
||||
|
||||
|
@ -630,6 +632,8 @@ ObCreateHandle(PEPROCESS Process,
|
|||
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 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
|
|||
PEPROCESS Process;
|
||||
KIRQL oldIrql;
|
||||
PHANDLE_ENTRY HandleEntry;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
|
||||
|
||||
|
@ -777,7 +783,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
|||
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 @@ NtClose(IN HANDLE Handle)
|
|||
POBJECT_HEADER Header;
|
||||
NTSTATUS Status;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtClose(Handle %x)\n",Handle);
|
||||
|
||||
|
@ -966,6 +972,8 @@ ObInsertObject(IN PVOID Object,
|
|||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
ACCESS_MASK Access;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Access = DesiredAccess;
|
||||
ObjectHeader = BODY_TO_HEADER(Object);
|
||||
|
|
|
@ -55,6 +55,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
|||
UNICODE_STRING RemainingPath;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
ObjectPath,
|
||||
|
@ -126,6 +128,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
UNICODE_STRING RemainingPath;
|
||||
PVOID Object = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("ObOpenObjectByName(...)\n");
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ NtSetInformationObject (IN HANDLE ObjectHandle,
|
|||
{
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if (ObjectInformationClass != ObjectHandleInformation)
|
||||
return STATUS_INVALID_INFO_CLASS;
|
||||
|
@ -88,6 +90,8 @@ NtQueryObject (IN HANDLE ObjectHandle,
|
|||
ULONG InfoLength;
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = ObReferenceObjectByHandle (ObjectHandle,
|
||||
0,
|
||||
|
@ -260,6 +264,8 @@ NtMakeTemporaryObject(IN HANDLE ObjectHandle)
|
|||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
0,
|
||||
|
@ -299,6 +305,8 @@ NtMakePermanentObject(IN HANDLE ObjectHandle)
|
|||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
0,
|
||||
|
|
|
@ -346,6 +346,8 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
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 @@ ObQueryNameString (IN PVOID Object,
|
|||
POBJECT_HEADER ObjectHeader;
|
||||
ULONG LocalReturnLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
*ReturnLength = 0;
|
||||
|
||||
|
@ -611,7 +615,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
|||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
|
||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||
|
||||
ASSERT_IRQL(APC_LEVEL);
|
||||
PAGED_CODE();
|
||||
|
||||
if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
|
||||
{
|
||||
|
@ -814,6 +818,8 @@ ObReferenceObjectByPointer(IN PVOID Object,
|
|||
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 @@ ObOpenObjectByPointer(IN POBJECT Object,
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("ObOpenObjectByPointer()\n");
|
||||
|
||||
Status = ObReferenceObjectByPointer(Object,
|
||||
|
@ -1117,6 +1125,8 @@ ULONG STDCALL
|
|||
ObGetObjectPointerCount(PVOID Object)
|
||||
{
|
||||
POBJECT_HEADER Header;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Object);
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
@ -1142,6 +1152,8 @@ ULONG
|
|||
ObGetObjectHandleCount(PVOID Object)
|
||||
{
|
||||
POBJECT_HEADER Header;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Object);
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id:$
|
||||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -27,6 +27,8 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
|
|||
{
|
||||
PSECURITY_DESCRIPTOR NewDescriptor;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
/* Build the new security descriptor */
|
||||
Status = SeAssignSecurity(SecurityDescriptor,
|
||||
|
@ -73,6 +75,8 @@ ObGetObjectSecurity(IN PVOID Object,
|
|||
POBJECT_HEADER Header;
|
||||
ULONG Length;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
if (Header->ObjectType == NULL)
|
||||
|
@ -129,6 +133,8 @@ VOID STDCALL
|
|||
ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
IN BOOLEAN MemoryAllocated)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (SecurityDescriptor == NULL)
|
||||
return;
|
||||
|
||||
|
@ -156,6 +162,8 @@ NtQuerySecurityObject(IN HANDLE Handle,
|
|||
POBJECT_HEADER Header;
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtQuerySecurityObject() called\n");
|
||||
|
||||
|
@ -226,6 +234,8 @@ NtSetSecurityObject(IN HANDLE Handle,
|
|||
ULONG Control = 0;
|
||||
ULONG_PTR Current;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtSetSecurityObject() called\n");
|
||||
|
||||
|
|
|
@ -206,61 +206,104 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
|
|||
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))
|
||||
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);
|
||||
|
||||
DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer);
|
||||
|
||||
ZwQuerySystemTime (&SymbolicLink->CreateTime);
|
||||
|
||||
Status = ObInsertObject ((PVOID)SymbolicLink,
|
||||
NULL,
|
||||
DesiredAccess,
|
||||
0,
|
||||
NULL,
|
||||
&hLink);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
_SEH_TRY
|
||||
{
|
||||
*LinkHandle = hLink;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
ObDereferenceObject(SymbolicLink);
|
||||
}
|
||||
|
||||
RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
|
||||
PreviousMode,
|
||||
FALSE);
|
||||
|
||||
Status = ObInsertObject ((PVOID)SymbolicLink,
|
||||
NULL,
|
||||
DesiredAccess,
|
||||
0,
|
||||
NULL,
|
||||
LinkHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject (SymbolicLink);
|
||||
return 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,
|
||||
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 @@ NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle,
|
|||
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,37 +398,92 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle,
|
|||
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;
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (ResultLength != NULL)
|
||||
{
|
||||
*ResultLength = (ULONG)SymlinkObject->TargetName.Length + sizeof(WCHAR);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,8 @@ PoSetPowerState(
|
|||
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 @@ NtPowerInformation(
|
|||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
|
||||
"InputBufferLength 0x%x, OutputBuffer 0x%x, OutputBufferLength 0x%x)\n",
|
||||
|
|
Loading…
Reference in a new issue