Author: ion
Date: Mon Jun 5 04:04:36 2006
New Revision: 22228
URL:
http://svn.reactos.ru/svn/reactos?rev=22228&view=rev
Log:
- Fix ExChangeHandle not to send NULL but the actual context to the callback function (fix
by Thomas Weidenmueller <w3seek(a)reactos.org>)
- Re-implement NtSetInformationObject based on ExChangeHandle and using
ObpSetHandleAttributes as a callback.
- Re-implement NtQueryObject's ObjectHandleInformation case to simply return the
information that's already in HandleAttributes; there is no point in querying for it
all over again.
- Fix NtSetInformationObject not to allow a user-mode call to modify kernel-mdoe handle
attributes. Add FIXME for Inheritance permissions check.
- Fix NtQueryObject to properly return OBJ_PERMANENT and OBJ_EXCLUSIVE; these flags are
not stored in Handle Attributes.
- Fix NtQueryObject not to attempt referencing the handle if the caller specified
AllTypesInformation, because then a handle is not needed.
Modified:
trunk/reactos/ntoskrnl/ex/handle.c
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/ob/obhandle.c
trunk/reactos/ntoskrnl/ob/oblife.c
Modified: trunk/reactos/ntoskrnl/ex/handle.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/handle.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/handle.c (original)
+++ trunk/reactos/ntoskrnl/ex/handle.c Mon Jun 5 04:04:36 2006
@@ -916,7 +916,7 @@
{
Ret = ChangeHandleCallback(HandleTable,
HandleTableEntry,
- NULL);
+ Context);
ExUnlockHandleTableEntry(HandleTable,
HandleTableEntry);
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon Jun 5 04:04:36 2006
@@ -8,6 +8,12 @@
#ifndef __INCLUDE_INTERNAL_OBJMGR_H
#define __INCLUDE_INTERNAL_OBJMGR_H
+
+typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
+{
+ KPROCESSOR_MODE PreviousMode;
+ OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information;
+} OBP_SET_HANDLE_ATTRIBUTES_CONTEXT, *POBP_SET_HANDLE_ATTRIBUTES_CONTEXT;
#define GENERIC_ACCESS (GENERIC_READ | \
GENERIC_WRITE | \
@@ -100,18 +106,12 @@
IN PVOID Insert
);
-NTSTATUS
-NTAPI
-ObpQueryHandleAttributes(
- HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
-);
-
-NTSTATUS
+BOOLEAN
NTAPI
ObpSetHandleAttributes(
- HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo
+ IN PHANDLE_TABLE HandleTable,
+ IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry,
+ IN PVOID Context
);
NTSTATUS
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jun 5 04:04:36 2006
@@ -154,129 +154,51 @@
}
}
-NTSTATUS
+BOOLEAN
NTAPI
-ObpQueryHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
-{
- PHANDLE_TABLE_ENTRY HandleTableEntry;
- PEPROCESS Process, CurrentProcess;
- KAPC_STATE ApcState;
- BOOLEAN AttachedToProcess = FALSE;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- DPRINT("ObpQueryHandleAttributes(Handle %p)\n", Handle);
- CurrentProcess = PsGetCurrentProcess();
-
- KeEnterCriticalRegion();
-
- if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
- {
- Process = PsInitialSystemProcess;
- Handle = ObKernelHandleToHandle(Handle);
-
- if (Process != CurrentProcess)
- {
- KeStackAttachProcess(&Process->Pcb,
- &ApcState);
- AttachedToProcess = TRUE;
- }
- }
- else
- {
- Process = CurrentProcess;
- }
-
- HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
- Handle);
- if (HandleTableEntry != NULL)
- {
- HandleInfo->Inherit = (HandleTableEntry->ObAttributes &
EX_HANDLE_ENTRY_INHERITABLE) != 0;
- HandleInfo->ProtectFromClose = (HandleTableEntry->ObAttributes &
EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
-
- ExUnlockHandleTableEntry(Process->ObjectTable,
- HandleTableEntry);
- }
- else
- Status = STATUS_INVALID_HANDLE;
-
- if (AttachedToProcess)
- {
- KeUnstackDetachProcess(&ApcState);
- }
-
- KeLeaveCriticalRegion();
-
- return Status;
-}
-
-NTSTATUS
-NTAPI
-ObpSetHandleAttributes(HANDLE Handle,
- POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
-{
- PHANDLE_TABLE_ENTRY HandleTableEntry;
- PEPROCESS Process, CurrentProcess;
- KAPC_STATE ApcState;
- BOOLEAN AttachedToProcess = FALSE;
- NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
-
- DPRINT("ObpSetHandleAttributes(Handle %p)\n", Handle);
- CurrentProcess = PsGetCurrentProcess();
-
- KeEnterCriticalRegion();
-
- if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
- {
- Process = PsInitialSystemProcess;
- Handle = ObKernelHandleToHandle(Handle);
-
- if (Process != CurrentProcess)
- {
- KeStackAttachProcess(&Process->Pcb,
- &ApcState);
- AttachedToProcess = TRUE;
- }
- }
- else
- {
- Process = CurrentProcess;
- }
-
- HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
- Handle);
- if (HandleTableEntry != NULL)
- {
- if (HandleInfo->Inherit)
- HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
- else
- HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
-
- if (HandleInfo->ProtectFromClose)
- HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
- else
- HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
-
- /* FIXME: Do we need to set anything in the object header??? */
-
- ExUnlockHandleTableEntry(Process->ObjectTable,
- HandleTableEntry);
- }
- else
- Status = STATUS_INVALID_HANDLE;
-
- if (AttachedToProcess)
- {
- KeUnstackDetachProcess(&ApcState);
- }
-
- KeLeaveCriticalRegion();
-
- return Status;
+ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
+ IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry,
+ IN PVOID Context)
+{
+ POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo =
+ (POBP_SET_HANDLE_ATTRIBUTES_CONTEXT)Context;
+ POBJECT_HEADER ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
+ PAGED_CODE();
+
+ /* Don't allow operations on kernel objects */
+ if ((ObjectHeader->Flags & OB_FLAG_KERNEL_MODE) &&
+ (SetHandleInfo->PreviousMode != KernelMode))
+ {
+ /* Fail */
+ return FALSE;
+ }
+
+ /* Check if making the handle inheritable */
+ if (SetHandleInfo->Information.Inherit)
+ {
+ /* Set the flag. FIXME: Need to check if this is allowed */
+ HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
+ }
+ else
+ {
+ /* Otherwise this implies we're removing the flag */
+ HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
+ }
+
+ /* Check if making the handle protected */
+ if (SetHandleInfo->Information.ProtectFromClose)
+ {
+ /* Set the flag */
+ HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
+ }
+ else
+ {
+ /* Otherwise, remove it */
+ HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
+ }
+
+ /* Return success */
+ return TRUE;
}
static NTSTATUS
Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c Mon Jun 5 04:04:36 2006
@@ -790,95 +790,157 @@
OUT PULONG ResultLength OPTIONAL)
{
OBJECT_HANDLE_INFORMATION HandleInfo;
- POBJECT_HEADER ObjectHeader;
+ POBJECT_HEADER ObjectHeader = NULL;
+ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags;
+ POBJECT_BASIC_INFORMATION BasicInfo;
ULONG InfoLength;
- PVOID Object;
+ PVOID Object = NULL;
NTSTATUS Status;
PAGED_CODE();
- Status = ObReferenceObjectByHandle(ObjectHandle,
- 0,
- NULL,
- KeGetPreviousMode(),
- &Object,
- &HandleInfo);
- if (!NT_SUCCESS (Status)) return Status;
-
- ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
-
+ /* FIXME: Needs SEH */
+
+ /*
+ * Make sure this isn't a generic type query, since the caller doesn't
+ * have to give a handle for it
+ */
+ if (ObjectInformationClass != ObjectAllTypesInformation)
+ {
+ /* Reference the object */
+ Status = ObReferenceObjectByHandle(ObjectHandle,
+ 0,
+ NULL,
+ KeGetPreviousMode(),
+ &Object,
+ &HandleInfo);
+ if (!NT_SUCCESS (Status)) return Status;
+
+ /* Get the object header */
+ ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
+ }
+
+ /* Check the information class */
switch (ObjectInformationClass)
{
- case ObjectBasicInformation:
- InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
- if (Length != sizeof(OBJECT_BASIC_INFORMATION))
- {
- Status = STATUS_INFO_LENGTH_MISMATCH;
- }
- else
- {
- POBJECT_BASIC_INFORMATION BasicInfo;
-
+ /* Basic info */
+ case ObjectBasicInformation:
+
+ /* Validate length */
+ InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
+ if (Length != sizeof(OBJECT_BASIC_INFORMATION))
+ {
+ /* Fail */
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Fill out the basic information */
BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation;
BasicInfo->Attributes = HandleInfo.HandleAttributes;
BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
BasicInfo->HandleCount = ObjectHeader->HandleCount;
BasicInfo->PointerCount = ObjectHeader->PointerCount;
+
+ /* Permanent/Exclusive Flags are NOT in Handle attributes! */
+ if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
+ {
+ /* Set the flag */
+ BasicInfo->Attributes |= OBJ_EXCLUSIVE;
+ }
+ if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
+ {
+ /* Set the flag */
+ BasicInfo->Attributes |= OBJ_PERMANENT;
+ }
+
+ /* Copy quota information */
BasicInfo->PagedPoolUsage = 0; /* FIXME*/
BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
+
+ /* Copy name information */
BasicInfo->NameInformationLength = 0; /* FIXME*/
BasicInfo->TypeInformationLength = 0; /* FIXME*/
+
+ /* Copy security information */
BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
+
+ /* Check if this is a symlink */
if (ObjectHeader->Type == ObSymbolicLinkType)
{
+ /* Return the creation time */
BasicInfo->CreateTime.QuadPart =
((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
}
else
{
+ /* Otherwise return 0 */
BasicInfo->CreateTime.QuadPart = (ULONGLONG)0;
}
+
+ /* Break out with success */
Status = STATUS_SUCCESS;
- }
- break;
-
- case ObjectNameInformation:
- Status = ObQueryNameString(Object,
- (POBJECT_NAME_INFORMATION)ObjectInformation,
- Length,
- &InfoLength);
- break;
-
- case ObjectTypeInformation:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- case ObjectAllTypesInformation:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
- case ObjectHandleInformation:
- InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
- if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
- {
- Status = STATUS_INFO_LENGTH_MISMATCH;
- }
- else
- {
- Status = ObpQueryHandleAttributes(
- ObjectHandle,
- (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation);
- }
- break;
-
- default:
- Status = STATUS_INVALID_INFO_CLASS;
- break;
- }
-
- ObDereferenceObject (Object);
-
- if (ResultLength != NULL) *ResultLength = InfoLength;
-
+ break;
+
+ /* Name information */
+ case ObjectNameInformation:
+
+ /* Call the helper and break out */
+ Status = ObQueryNameString(Object,
+ (POBJECT_NAME_INFORMATION)
+ ObjectInformation,
+ Length,
+ &InfoLength);
+ break;
+
+ /* Information about this type */
+ case ObjectTypeInformation:
+ DPRINT1("NOT IMPLEMENTED!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ /* Information about all types */
+ case ObjectAllTypesInformation:
+ DPRINT1("NOT IMPLEMENTED!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ /* Information about the handle flags */
+ case ObjectHandleInformation:
+
+ /* Validate length */
+ InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
+ if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Get the structure */
+ HandleFlags = (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+ ObjectInformation;
+
+ /* Set the flags */
+ HandleFlags->Inherit = (HandleInfo.HandleAttributes &
+ EX_HANDLE_ENTRY_INHERITABLE) != 0;
+ HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
+ EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
+
+ /* Break out with success */
+ Status = STATUS_SUCCESS;
+ break;
+
+ /* Anything else */
+ default:
+ /* Fail it */
+ Status = STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+
+ /* Derefernece the object if we had referenced it */
+ if (Object) ObDereferenceObject (Object);
+
+ /* Return the length and status */
+ if (ResultLength) *ResultLength = InfoLength;
return Status;
}
@@ -912,29 +974,66 @@
IN PVOID ObjectInformation,
IN ULONG Length)
{
- PVOID Object;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
+ OBP_SET_HANDLE_ATTRIBUTES_CONTEXT Context;
+ PVOID ObjectTable;
+ KAPC_STATE ApcState;
+ BOOLEAN AttachedToProcess = FALSE;
PAGED_CODE();
+ /* Validate the information class */
if (ObjectInformationClass != ObjectHandleInformation)
+ {
+ /* Invalid class */
return STATUS_INVALID_INFO_CLASS;
-
+ }
+
+ /* Validate the length */
if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
+ {
+ /* Invalid length */
return STATUS_INFO_LENGTH_MISMATCH;
-
- Status = ObReferenceObjectByHandle(ObjectHandle,
- 0,
- NULL,
- KeGetPreviousMode(),
- &Object,
- NULL);
- if (!NT_SUCCESS (Status)) return Status;
-
- Status = ObpSetHandleAttributes(ObjectHandle,
- (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
- ObjectInformation);
-
- ObDereferenceObject (Object);
+ }
+
+ /* Save the previous mode and actual information */
+ Context.PreviousMode = ExGetPreviousMode();
+ Context.Information = *(POBJECT_HANDLE_ATTRIBUTE_INFORMATION)
+ ObjectInformation;
+
+ /* Check if this is a kernel handle */
+ if (ObIsKernelHandle(ObjectHandle, Context.PreviousMode))
+ {
+ /* Get the actual handle */
+ ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
+ ObjectTable = ObpKernelHandleTable;
+
+ /* Check if we're not in the system process */
+ if (PsGetCurrentProcess() != PsInitialSystemProcess)
+ {
+ /* Attach to it */
+ KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
+ AttachedToProcess = TRUE;
+ }
+ }
+ else
+ {
+ /* Use the current table */
+ ObjectTable = PsGetCurrentProcess()->ObjectTable;
+ }
+
+ /* Change the handle attributes */
+ if (!ExChangeHandle(ObjectTable,
+ ObjectHandle,
+ ObpSetHandleAttributes,
+ &Context))
+ {
+ /* Some failure */
+ Status = STATUS_ACCESS_DENIED;
+ }
+
+ /* De-attach if we were attached, and return status */
+ if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
return Status;
}
+
/* EOF */