mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 00:27:13 +00:00
svn propset svn:eol-style native foo.py
svn path=/trunk/; revision=22025
This commit is contained in:
parent
901bb3dc40
commit
945ca8d68e
6 changed files with 3948 additions and 3948 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,174 +1,174 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/ob/init.c
|
* FILE: ntoskrnl/ob/init.c
|
||||||
* PURPOSE: Handles Object Manager Initialization and Shutdown
|
* PURPOSE: Handles Object Manager Initialization and Shutdown
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Eric Kohl
|
* Eric Kohl
|
||||||
* Thomas Weidenmueller (w3seek@reactos.org)
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
#if defined (ALLOC_PRAGMA)
|
||||||
#pragma alloc_text(INIT, ObInit)
|
#pragma alloc_text(INIT, ObInit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GENERIC_MAPPING ObpTypeMapping =
|
GENERIC_MAPPING ObpTypeMapping =
|
||||||
{
|
{
|
||||||
STANDARD_RIGHTS_READ,
|
STANDARD_RIGHTS_READ,
|
||||||
STANDARD_RIGHTS_WRITE,
|
STANDARD_RIGHTS_WRITE,
|
||||||
STANDARD_RIGHTS_EXECUTE,
|
STANDARD_RIGHTS_EXECUTE,
|
||||||
0x000F0001
|
0x000F0001
|
||||||
};
|
};
|
||||||
|
|
||||||
GENERIC_MAPPING ObpDirectoryMapping =
|
GENERIC_MAPPING ObpDirectoryMapping =
|
||||||
{
|
{
|
||||||
STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
|
STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
|
STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
|
||||||
DIRECTORY_CREATE_OBJECT,
|
DIRECTORY_CREATE_OBJECT,
|
||||||
STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
|
STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
DIRECTORY_ALL_ACCESS
|
DIRECTORY_ALL_ACCESS
|
||||||
};
|
};
|
||||||
|
|
||||||
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
ObInit(VOID)
|
ObInit(VOID)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
SECURITY_DESCRIPTOR SecurityDescriptor;
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
OBP_LOOKUP_CONTEXT Context;
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
/* Initialize the security descriptor cache */
|
/* Initialize the security descriptor cache */
|
||||||
ObpInitSdCache();
|
ObpInitSdCache();
|
||||||
|
|
||||||
/* Initialize the Default Event */
|
/* Initialize the Default Event */
|
||||||
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
|
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
|
||||||
|
|
||||||
/* Create the Type Type */
|
/* Create the Type Type */
|
||||||
DPRINT("Creating Type Type\n");
|
DPRINT("Creating Type Type\n");
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
||||||
RtlInitUnicodeString(&Name, L"Type");
|
RtlInitUnicodeString(&Name, L"Type");
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||||
ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
|
ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
|
||||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
||||||
ObjectTypeInitializer.MaintainTypeList = TRUE;
|
ObjectTypeInitializer.MaintainTypeList = TRUE;
|
||||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
|
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
|
||||||
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
|
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
|
||||||
|
|
||||||
/* Create the Directory Type */
|
/* Create the Directory Type */
|
||||||
DPRINT("Creating Directory Type\n");
|
DPRINT("Creating Directory Type\n");
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
||||||
RtlInitUnicodeString(&Name, L"Directory");
|
RtlInitUnicodeString(&Name, L"Directory");
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||||
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
|
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
|
||||||
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
||||||
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
|
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
|
||||||
ObjectTypeInitializer.MaintainTypeList = FALSE;
|
ObjectTypeInitializer.MaintainTypeList = FALSE;
|
||||||
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
|
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
||||||
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
|
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
|
||||||
|
|
||||||
/* Create security descriptor */
|
/* Create security descriptor */
|
||||||
RtlCreateSecurityDescriptor(&SecurityDescriptor,
|
RtlCreateSecurityDescriptor(&SecurityDescriptor,
|
||||||
SECURITY_DESCRIPTOR_REVISION1);
|
SECURITY_DESCRIPTOR_REVISION1);
|
||||||
RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
|
RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
|
||||||
SeAliasAdminsSid,
|
SeAliasAdminsSid,
|
||||||
FALSE);
|
FALSE);
|
||||||
RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
|
RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
|
||||||
SeLocalSystemSid,
|
SeLocalSystemSid,
|
||||||
FALSE);
|
FALSE);
|
||||||
RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
|
RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
|
||||||
TRUE,
|
TRUE,
|
||||||
SePublicDefaultDacl,
|
SePublicDefaultDacl,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
/* Create root directory */
|
/* Create root directory */
|
||||||
DPRINT("Creating Root Directory\n");
|
DPRINT("Creating Root Directory\n");
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
NULL,
|
NULL,
|
||||||
OBJ_PERMANENT,
|
OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
&SecurityDescriptor);
|
&SecurityDescriptor);
|
||||||
ObCreateObject(KernelMode,
|
ObCreateObject(KernelMode,
|
||||||
ObDirectoryType,
|
ObDirectoryType,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(OBJECT_DIRECTORY),
|
sizeof(OBJECT_DIRECTORY),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&NameSpaceRoot);
|
(PVOID*)&NameSpaceRoot);
|
||||||
ObInsertObject((PVOID)NameSpaceRoot,
|
ObInsertObject((PVOID)NameSpaceRoot,
|
||||||
NULL,
|
NULL,
|
||||||
DIRECTORY_ALL_ACCESS,
|
DIRECTORY_ALL_ACCESS,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Create '\ObjectTypes' directory */
|
/* Create '\ObjectTypes' directory */
|
||||||
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
|
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&Name,
|
&Name,
|
||||||
OBJ_PERMANENT,
|
OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
&SecurityDescriptor);
|
&SecurityDescriptor);
|
||||||
ObCreateObject(KernelMode,
|
ObCreateObject(KernelMode,
|
||||||
ObDirectoryType,
|
ObDirectoryType,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(OBJECT_DIRECTORY),
|
sizeof(OBJECT_DIRECTORY),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&ObpTypeDirectoryObject);
|
(PVOID*)&ObpTypeDirectoryObject);
|
||||||
ObInsertObject((PVOID)ObpTypeDirectoryObject,
|
ObInsertObject((PVOID)ObpTypeDirectoryObject,
|
||||||
NULL,
|
NULL,
|
||||||
DIRECTORY_ALL_ACCESS,
|
DIRECTORY_ALL_ACCESS,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Insert the two objects we already created but couldn't add */
|
/* Insert the two objects we already created but couldn't add */
|
||||||
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
|
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
|
||||||
Context.Directory = ObpTypeDirectoryObject;
|
Context.Directory = ObpTypeDirectoryObject;
|
||||||
Context.DirectoryLocked = TRUE;
|
Context.DirectoryLocked = TRUE;
|
||||||
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Context))
|
&Context))
|
||||||
{
|
{
|
||||||
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObTypeObjectType));
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObTypeObjectType));
|
||||||
}
|
}
|
||||||
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Context))
|
&Context))
|
||||||
{
|
{
|
||||||
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObDirectoryType));
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObDirectoryType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create 'symbolic link' object type */
|
/* Create 'symbolic link' object type */
|
||||||
ObInitSymbolicLinkImplementation();
|
ObInitSymbolicLinkImplementation();
|
||||||
|
|
||||||
/* FIXME: Hack Hack! */
|
/* FIXME: Hack Hack! */
|
||||||
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
|
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
|
||||||
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
|
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
|
||||||
}
|
}
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,365 +1,365 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/ob/namespce.c
|
* FILE: ntoskrnl/ob/namespce.c
|
||||||
* PURPOSE: Manages all functions related to the Object Manager name-
|
* PURPOSE: Manages all functions related to the Object Manager name-
|
||||||
* space, such as finding objects or querying their names.
|
* space, such as finding objects or querying their names.
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Eric Kohl
|
* Eric Kohl
|
||||||
* Thomas Weidenmueller (w3seek@reactos.org)
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
POBJECT_DIRECTORY NameSpaceRoot = NULL;
|
POBJECT_DIRECTORY NameSpaceRoot = NULL;
|
||||||
POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
PUNICODE_STRING ObjectName,
|
PUNICODE_STRING ObjectName,
|
||||||
PVOID* ReturnedObject,
|
PVOID* ReturnedObject,
|
||||||
PUNICODE_STRING RemainingPath,
|
PUNICODE_STRING RemainingPath,
|
||||||
POBJECT_TYPE ObjectType,
|
POBJECT_TYPE ObjectType,
|
||||||
POBP_LOOKUP_CONTEXT Context)
|
POBP_LOOKUP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
PVOID NextObject;
|
PVOID NextObject;
|
||||||
PVOID CurrentObject;
|
PVOID CurrentObject;
|
||||||
PVOID RootObject;
|
PVOID RootObject;
|
||||||
POBJECT_HEADER CurrentHeader;
|
POBJECT_HEADER CurrentHeader;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PWSTR current;
|
PWSTR current;
|
||||||
UNICODE_STRING PathString;
|
UNICODE_STRING PathString;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
|
DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
|
||||||
"RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
|
"RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
|
||||||
|
|
||||||
RtlInitUnicodeString (RemainingPath, NULL);
|
RtlInitUnicodeString (RemainingPath, NULL);
|
||||||
|
|
||||||
if (ObjectCreateInfo->RootDirectory == NULL)
|
if (ObjectCreateInfo->RootDirectory == NULL)
|
||||||
{
|
{
|
||||||
ObReferenceObjectByPointer(NameSpaceRoot,
|
ObReferenceObjectByPointer(NameSpaceRoot,
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
NULL,
|
NULL,
|
||||||
ObjectCreateInfo->ProbeMode);
|
ObjectCreateInfo->ProbeMode);
|
||||||
CurrentObject = NameSpaceRoot;
|
CurrentObject = NameSpaceRoot;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
|
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
ObjectCreateInfo->ProbeMode,
|
ObjectCreateInfo->ProbeMode,
|
||||||
&CurrentObject,
|
&CurrentObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectName->Length == 0 ||
|
if (ObjectName->Length == 0 ||
|
||||||
ObjectName->Buffer[0] == UNICODE_NULL)
|
ObjectName->Buffer[0] == UNICODE_NULL)
|
||||||
{
|
{
|
||||||
*ReturnedObject = CurrentObject;
|
*ReturnedObject = CurrentObject;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectCreateInfo->RootDirectory == NULL &&
|
if (ObjectCreateInfo->RootDirectory == NULL &&
|
||||||
ObjectName->Buffer[0] != L'\\')
|
ObjectName->Buffer[0] != L'\\')
|
||||||
{
|
{
|
||||||
ObDereferenceObject (CurrentObject);
|
ObDereferenceObject (CurrentObject);
|
||||||
DPRINT1("failed\n");
|
DPRINT1("failed\n");
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a zero-terminated copy of the object name */
|
/* Create a zero-terminated copy of the object name */
|
||||||
PathString.Length = ObjectName->Length;
|
PathString.Length = ObjectName->Length;
|
||||||
PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
|
PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
|
||||||
PathString.Buffer = ExAllocatePool (NonPagedPool,
|
PathString.Buffer = ExAllocatePool (NonPagedPool,
|
||||||
PathString.MaximumLength);
|
PathString.MaximumLength);
|
||||||
if (PathString.Buffer == NULL)
|
if (PathString.Buffer == NULL)
|
||||||
{
|
{
|
||||||
ObDereferenceObject (CurrentObject);
|
ObDereferenceObject (CurrentObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlCopyMemory (PathString.Buffer,
|
RtlCopyMemory (PathString.Buffer,
|
||||||
ObjectName->Buffer,
|
ObjectName->Buffer,
|
||||||
ObjectName->Length);
|
ObjectName->Length);
|
||||||
PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||||
|
|
||||||
current = PathString.Buffer;
|
current = PathString.Buffer;
|
||||||
|
|
||||||
RootObject = CurrentObject;
|
RootObject = CurrentObject;
|
||||||
Attributes = ObjectCreateInfo->Attributes;
|
Attributes = ObjectCreateInfo->Attributes;
|
||||||
if (ObjectType == ObSymbolicLinkType)
|
if (ObjectType == ObSymbolicLinkType)
|
||||||
Attributes |= OBJ_OPENLINK;
|
Attributes |= OBJ_OPENLINK;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
DPRINT("current %S\n",current);
|
DPRINT("current %S\n",current);
|
||||||
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
CurrentHeader = BODY_TO_HEADER(CurrentObject);
|
||||||
|
|
||||||
DPRINT("Current ObjectType %wZ\n",
|
DPRINT("Current ObjectType %wZ\n",
|
||||||
&CurrentHeader->Type->Name);
|
&CurrentHeader->Type->Name);
|
||||||
|
|
||||||
if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
|
if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Current object can't parse\n");
|
DPRINT("Current object can't parse\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Status = ((OB_ROS_PARSE_METHOD)CurrentHeader->Type->TypeInfo.ParseProcedure)(CurrentObject,
|
Status = ((OB_ROS_PARSE_METHOD)CurrentHeader->Type->TypeInfo.ParseProcedure)(CurrentObject,
|
||||||
&NextObject,
|
&NextObject,
|
||||||
&PathString,
|
&PathString,
|
||||||
¤t,
|
¤t,
|
||||||
Attributes,
|
Attributes,
|
||||||
Context);
|
Context);
|
||||||
if (Status == STATUS_REPARSE)
|
if (Status == STATUS_REPARSE)
|
||||||
{
|
{
|
||||||
/* reparse the object path */
|
/* reparse the object path */
|
||||||
NextObject = NameSpaceRoot;
|
NextObject = NameSpaceRoot;
|
||||||
current = PathString.Buffer;
|
current = PathString.Buffer;
|
||||||
|
|
||||||
ObReferenceObjectByPointer(NextObject,
|
ObReferenceObjectByPointer(NextObject,
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
NULL,
|
NULL,
|
||||||
ObjectCreateInfo->ProbeMode);
|
ObjectCreateInfo->ProbeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NextObject == NULL)
|
if (NextObject == NULL)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ObDereferenceObject(CurrentObject);
|
ObDereferenceObject(CurrentObject);
|
||||||
CurrentObject = NextObject;
|
CurrentObject = NextObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
{
|
{
|
||||||
RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
|
RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString (&PathString);
|
RtlFreeUnicodeString (&PathString);
|
||||||
*ReturnedObject = CurrentObject;
|
*ReturnedObject = CurrentObject;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS *********************************************************/
|
/* PUBLIC FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ObQueryNameString(IN PVOID Object,
|
ObQueryNameString(IN PVOID Object,
|
||||||
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
|
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG ReturnLength)
|
OUT PULONG ReturnLength)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER_NAME_INFO LocalInfo;
|
POBJECT_HEADER_NAME_INFO LocalInfo;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
POBJECT_DIRECTORY ParentDirectory;
|
POBJECT_DIRECTORY ParentDirectory;
|
||||||
ULONG NameSize;
|
ULONG NameSize;
|
||||||
PWCH ObjectName;
|
PWCH ObjectName;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("ObQueryNameString: %x, %x\n", Object, ObjectNameInfo);
|
DPRINT("ObQueryNameString: %x, %x\n", Object, ObjectNameInfo);
|
||||||
|
|
||||||
/* Get the Kernel Meta-Structures */
|
/* Get the Kernel Meta-Structures */
|
||||||
ObjectHeader = BODY_TO_HEADER(Object);
|
ObjectHeader = BODY_TO_HEADER(Object);
|
||||||
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
|
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
|
||||||
|
|
||||||
/* Check if a Query Name Procedure is available */
|
/* Check if a Query Name Procedure is available */
|
||||||
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
|
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
|
||||||
{
|
{
|
||||||
/* Call the procedure */
|
/* Call the procedure */
|
||||||
DPRINT("Calling Object's Procedure\n");
|
DPRINT("Calling Object's Procedure\n");
|
||||||
Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
|
Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
|
||||||
TRUE, //fixme
|
TRUE, //fixme
|
||||||
ObjectNameInfo,
|
ObjectNameInfo,
|
||||||
Length,
|
Length,
|
||||||
ReturnLength);
|
ReturnLength);
|
||||||
|
|
||||||
/* Return the status */
|
/* Return the status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the object doesn't even have a name */
|
/* Check if the object doesn't even have a name */
|
||||||
if (!LocalInfo || !LocalInfo->Name.Buffer)
|
if (!LocalInfo || !LocalInfo->Name.Buffer)
|
||||||
{
|
{
|
||||||
/* We're returning the name structure */
|
/* We're returning the name structure */
|
||||||
DPRINT("Nameless Object\n");
|
DPRINT("Nameless Object\n");
|
||||||
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
|
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
|
||||||
|
|
||||||
/* Check if we were given enough space */
|
/* Check if we were given enough space */
|
||||||
if (*ReturnLength > Length)
|
if (*ReturnLength > Length)
|
||||||
{
|
{
|
||||||
DPRINT1("Not enough buffer space\n");
|
DPRINT1("Not enough buffer space\n");
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return an empty buffer */
|
/* Return an empty buffer */
|
||||||
ObjectNameInfo->Name.Length = 0;
|
ObjectNameInfo->Name.Length = 0;
|
||||||
ObjectNameInfo->Name.MaximumLength = 0;
|
ObjectNameInfo->Name.MaximumLength = 0;
|
||||||
ObjectNameInfo->Name.Buffer = NULL;
|
ObjectNameInfo->Name.Buffer = NULL;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the size needed for the name. We won't do
|
* Find the size needed for the name. We won't do
|
||||||
* this during the Name Creation loop because we want
|
* this during the Name Creation loop because we want
|
||||||
* to let the caller know that the buffer isn't big
|
* to let the caller know that the buffer isn't big
|
||||||
* enough right at the beginning, not work our way through
|
* enough right at the beginning, not work our way through
|
||||||
* and find out at the end
|
* and find out at the end
|
||||||
*/
|
*/
|
||||||
if (Object == NameSpaceRoot)
|
if (Object == NameSpaceRoot)
|
||||||
{
|
{
|
||||||
/* Size of the '\' string */
|
/* Size of the '\' string */
|
||||||
DPRINT("Object is Root\n");
|
DPRINT("Object is Root\n");
|
||||||
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
|
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Get the Object Directory and add name of Object */
|
/* Get the Object Directory and add name of Object */
|
||||||
ParentDirectory = LocalInfo->Directory;
|
ParentDirectory = LocalInfo->Directory;
|
||||||
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
|
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
|
||||||
|
|
||||||
/* Loop inside the directory to get the top-most one (meaning root) */
|
/* Loop inside the directory to get the top-most one (meaning root) */
|
||||||
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
|
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
|
||||||
{
|
{
|
||||||
/* Get the Name Information */
|
/* Get the Name Information */
|
||||||
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
|
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
|
||||||
|
|
||||||
/* Add the size of the Directory Name */
|
/* Add the size of the Directory Name */
|
||||||
if (LocalInfo && LocalInfo->Directory)
|
if (LocalInfo && LocalInfo->Directory)
|
||||||
{
|
{
|
||||||
/* Size of the '\' string + Directory Name */
|
/* Size of the '\' string + Directory Name */
|
||||||
NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
|
NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
|
||||||
|
|
||||||
/* Move to next parent Directory */
|
/* Move to next parent Directory */
|
||||||
ParentDirectory = LocalInfo->Directory;
|
ParentDirectory = LocalInfo->Directory;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Directory with no name. We append "...\" */
|
/* Directory with no name. We append "...\" */
|
||||||
DPRINT("Nameless Directory\n");
|
DPRINT("Nameless Directory\n");
|
||||||
NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, add the name of the structure and the null char */
|
/* Finally, add the name of the structure and the null char */
|
||||||
*ReturnLength = NameSize + sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
|
*ReturnLength = NameSize + sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
|
||||||
DPRINT("Final Length: %x\n", *ReturnLength);
|
DPRINT("Final Length: %x\n", *ReturnLength);
|
||||||
|
|
||||||
/* Check if we were given enough space */
|
/* Check if we were given enough space */
|
||||||
if (*ReturnLength > Length)
|
if (*ReturnLength > Length)
|
||||||
{
|
{
|
||||||
DPRINT1("Not enough buffer space\n");
|
DPRINT1("Not enough buffer space\n");
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we will actually create the name. We work backwards because
|
* Now we will actually create the name. We work backwards because
|
||||||
* it's easier to start off from the Name we have and walk up the
|
* it's easier to start off from the Name we have and walk up the
|
||||||
* parent directories. We use the same logic as Name Length calculation.
|
* parent directories. We use the same logic as Name Length calculation.
|
||||||
*/
|
*/
|
||||||
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
|
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
|
||||||
ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
|
ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
|
||||||
*--ObjectName = UNICODE_NULL;
|
*--ObjectName = UNICODE_NULL;
|
||||||
|
|
||||||
if (Object == NameSpaceRoot)
|
if (Object == NameSpaceRoot)
|
||||||
{
|
{
|
||||||
/* This is already the Root Directory, return "\\" */
|
/* This is already the Root Directory, return "\\" */
|
||||||
DPRINT("Returning Root Dir\n");
|
DPRINT("Returning Root Dir\n");
|
||||||
*--ObjectName = OBJ_NAME_PATH_SEPARATOR;
|
*--ObjectName = OBJ_NAME_PATH_SEPARATOR;
|
||||||
ObjectNameInfo->Name.Length = (USHORT)NameSize;
|
ObjectNameInfo->Name.Length = (USHORT)NameSize;
|
||||||
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
|
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
|
||||||
ObjectNameInfo->Name.Buffer = ObjectName;
|
ObjectNameInfo->Name.Buffer = ObjectName;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Start by adding the Object's Name */
|
/* Start by adding the Object's Name */
|
||||||
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
|
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
|
||||||
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
|
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
|
||||||
|
|
||||||
/* Now parse the Parent directories until we reach the top */
|
/* Now parse the Parent directories until we reach the top */
|
||||||
ParentDirectory = LocalInfo->Directory;
|
ParentDirectory = LocalInfo->Directory;
|
||||||
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
|
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
|
||||||
{
|
{
|
||||||
/* Get the name information */
|
/* Get the name information */
|
||||||
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
|
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
|
||||||
|
|
||||||
/* Add the "\" */
|
/* Add the "\" */
|
||||||
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
|
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
|
||||||
|
|
||||||
/* Add the Parent Directory's Name */
|
/* Add the Parent Directory's Name */
|
||||||
if (LocalInfo && LocalInfo->Name.Buffer)
|
if (LocalInfo && LocalInfo->Name.Buffer)
|
||||||
{
|
{
|
||||||
/* Add the name */
|
/* Add the name */
|
||||||
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
|
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
|
||||||
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
|
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
|
||||||
|
|
||||||
/* Move to next parent */
|
/* Move to next parent */
|
||||||
ParentDirectory = LocalInfo->Directory;
|
ParentDirectory = LocalInfo->Directory;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Directory without a name, we add "..." */
|
/* Directory without a name, we add "..." */
|
||||||
DPRINT("Nameless Directory\n");
|
DPRINT("Nameless Directory\n");
|
||||||
ObjectName -= sizeof(L"...");
|
ObjectName -= sizeof(L"...");
|
||||||
ObjectName = L"...";
|
ObjectName = L"...";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add Root Directory Name */
|
/* Add Root Directory Name */
|
||||||
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
|
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
|
||||||
DPRINT("Current Buffer: %S\n", ObjectName);
|
DPRINT("Current Buffer: %S\n", ObjectName);
|
||||||
ObjectNameInfo->Name.Length = (USHORT)NameSize;
|
ObjectNameInfo->Name.Length = (USHORT)NameSize;
|
||||||
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
|
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
|
||||||
ObjectNameInfo->Name.Buffer = ObjectName;
|
ObjectNameInfo->Name.Buffer = ObjectName;
|
||||||
DPRINT("Complete: %wZ\n", ObjectNameInfo);
|
DPRINT("Complete: %wZ\n", ObjectNameInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObQueryDeviceMapInformation(IN PEPROCESS Process,
|
ObQueryDeviceMapInformation(IN PEPROCESS Process,
|
||||||
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
|
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
|
||||||
{
|
{
|
||||||
//KIRQL OldIrql ;
|
//KIRQL OldIrql ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: This is an ugly hack for now, to always return the System Device Map
|
* FIXME: This is an ugly hack for now, to always return the System Device Map
|
||||||
* instead of returning the Process Device Map. Not important yet since we don't use it
|
* instead of returning the Process Device Map. Not important yet since we don't use it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME: Acquire the DeviceMap Spinlock */
|
/* FIXME: Acquire the DeviceMap Spinlock */
|
||||||
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
|
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
|
||||||
|
|
||||||
/* Make a copy */
|
/* Make a copy */
|
||||||
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
|
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
|
||||||
RtlMoveMemory(DeviceMapInfo->Query.DriveType,
|
RtlMoveMemory(DeviceMapInfo->Query.DriveType,
|
||||||
ObSystemDeviceMap->DriveType,
|
ObSystemDeviceMap->DriveType,
|
||||||
sizeof(ObSystemDeviceMap->DriveType));
|
sizeof(ObSystemDeviceMap->DriveType));
|
||||||
|
|
||||||
/* FIXME: Release the DeviceMap Spinlock */
|
/* FIXME: Release the DeviceMap Spinlock */
|
||||||
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
|
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,455 +1,455 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: ntoskrnl/ob/refderef.c
|
* FILE: ntoskrnl/ob/refderef.c
|
||||||
* PURPOSE: Manages the referencing and de-referencing of all Objects,
|
* PURPOSE: Manages the referencing and de-referencing of all Objects,
|
||||||
* as well as the Object Fast Reference implementation.
|
* as well as the Object Fast Reference implementation.
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Eric Kohl
|
* Eric Kohl
|
||||||
* Thomas Weidenmueller (w3seek@reactos.org)
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObInitializeFastReference(IN PEX_FAST_REF FastRef,
|
ObInitializeFastReference(IN PEX_FAST_REF FastRef,
|
||||||
PVOID Object)
|
PVOID Object)
|
||||||
{
|
{
|
||||||
/* FIXME: Fast Referencing is Unimplemented */
|
/* FIXME: Fast Referencing is Unimplemented */
|
||||||
FastRef->Object = Object;
|
FastRef->Object = Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
|
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
|
||||||
{
|
{
|
||||||
/* FIXME: Fast Referencing is Unimplemented */
|
/* FIXME: Fast Referencing is Unimplemented */
|
||||||
|
|
||||||
/* Do a normal Reference */
|
/* Do a normal Reference */
|
||||||
ObReferenceObject(FastRef->Object);
|
ObReferenceObject(FastRef->Object);
|
||||||
|
|
||||||
/* Return the Object */
|
/* Return the Object */
|
||||||
return FastRef->Object;
|
return FastRef->Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
|
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
|
||||||
PVOID Object)
|
PVOID Object)
|
||||||
{
|
{
|
||||||
/* FIXME: Fast Referencing is Unimplemented */
|
/* FIXME: Fast Referencing is Unimplemented */
|
||||||
|
|
||||||
/* Do a normal Dereference */
|
/* Do a normal Dereference */
|
||||||
ObDereferenceObject(FastRef->Object);
|
ObDereferenceObject(FastRef->Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
|
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
|
||||||
PVOID Object)
|
PVOID Object)
|
||||||
{
|
{
|
||||||
PVOID OldObject = FastRef->Object;
|
PVOID OldObject = FastRef->Object;
|
||||||
|
|
||||||
/* FIXME: Fast Referencing is Unimplemented */
|
/* FIXME: Fast Referencing is Unimplemented */
|
||||||
FastRef->Object = Object;
|
FastRef->Object = Object;
|
||||||
|
|
||||||
/* Do a normal Dereference */
|
/* Do a normal Dereference */
|
||||||
ObDereferenceObject(OldObject);
|
ObDereferenceObject(OldObject);
|
||||||
|
|
||||||
/* Return old Object*/
|
/* Return old Object*/
|
||||||
return OldObject;
|
return OldObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS *********************************************************/
|
/* PUBLIC FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
ULONG STDCALL
|
ULONG STDCALL
|
||||||
ObGetObjectPointerCount(PVOID Object)
|
ObGetObjectPointerCount(PVOID Object)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
ASSERT(Object);
|
ASSERT(Object);
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
return Header->PointerCount;
|
return Header->PointerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
ObfReferenceObject(IN PVOID Object)
|
ObfReferenceObject(IN PVOID Object)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
ASSERT(Object);
|
ASSERT(Object);
|
||||||
|
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
/* No one should be referencing an object once we are deleting it. */
|
/* No one should be referencing an object once we are deleting it. */
|
||||||
if (InterlockedIncrement(&Header->PointerCount) == 1 && !(Header->Flags & OB_FLAG_PERMANENT))
|
if (InterlockedIncrement(&Header->PointerCount) == 1 && !(Header->Flags & OB_FLAG_PERMANENT))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ObfDereferenceObject(IN PVOID Object)
|
ObfDereferenceObject(IN PVOID Object)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
LONG NewPointerCount;
|
LONG NewPointerCount;
|
||||||
BOOL Permanent;
|
BOOL Permanent;
|
||||||
|
|
||||||
ASSERT(Object);
|
ASSERT(Object);
|
||||||
|
|
||||||
/* Extract the object header. */
|
/* Extract the object header. */
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
Permanent = Header->Flags & OB_FLAG_PERMANENT;
|
Permanent = Header->Flags & OB_FLAG_PERMANENT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Drop our reference and get the new count so we can tell if this was the
|
Drop our reference and get the new count so we can tell if this was the
|
||||||
last reference.
|
last reference.
|
||||||
*/
|
*/
|
||||||
NewPointerCount = InterlockedDecrement(&Header->PointerCount);
|
NewPointerCount = InterlockedDecrement(&Header->PointerCount);
|
||||||
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
|
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
|
||||||
ASSERT(NewPointerCount >= 0);
|
ASSERT(NewPointerCount >= 0);
|
||||||
|
|
||||||
/* Check whether the object can now be deleted. */
|
/* Check whether the object can now be deleted. */
|
||||||
if (NewPointerCount == 0 &&
|
if (NewPointerCount == 0 &&
|
||||||
!Permanent)
|
!Permanent)
|
||||||
{
|
{
|
||||||
ObpDeleteObjectDpcLevel(Header, NewPointerCount);
|
ObpDeleteObjectDpcLevel(Header, NewPointerCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
ObReferenceObjectByPointer(IN PVOID Object,
|
ObReferenceObjectByPointer(IN PVOID Object,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_TYPE ObjectType,
|
IN POBJECT_TYPE ObjectType,
|
||||||
IN KPROCESSOR_MODE AccessMode)
|
IN KPROCESSOR_MODE AccessMode)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER Header;
|
POBJECT_HEADER Header;
|
||||||
|
|
||||||
/* NOTE: should be possible to reference an object above APC_LEVEL! */
|
/* NOTE: should be possible to reference an object above APC_LEVEL! */
|
||||||
|
|
||||||
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
|
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
|
||||||
Object,ObjectType);
|
Object,ObjectType);
|
||||||
|
|
||||||
Header = BODY_TO_HEADER(Object);
|
Header = BODY_TO_HEADER(Object);
|
||||||
|
|
||||||
if (ObjectType != NULL && Header->Type != ObjectType)
|
if (ObjectType != NULL && Header->Type != ObjectType)
|
||||||
{
|
{
|
||||||
DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n",
|
DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n",
|
||||||
Header,
|
Header,
|
||||||
Header->Type,
|
Header->Type,
|
||||||
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Header->Type))->Name,
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Header->Type))->Name,
|
||||||
ObjectType,
|
ObjectType,
|
||||||
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObjectType))->Name);
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObjectType))->Name);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
if (Header->Type == PsProcessType)
|
if (Header->Type == PsProcessType)
|
||||||
{
|
{
|
||||||
DPRINT("Ref p 0x%x PointerCount %d type %x ",
|
DPRINT("Ref p 0x%x PointerCount %d type %x ",
|
||||||
Object, Header->PointerCount, PsProcessType);
|
Object, Header->PointerCount, PsProcessType);
|
||||||
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
||||||
}
|
}
|
||||||
if (Header->Type == PsThreadType)
|
if (Header->Type == PsThreadType)
|
||||||
{
|
{
|
||||||
DPRINT("Deref t 0x%x with PointerCount %d type %x ",
|
DPRINT("Deref t 0x%x with PointerCount %d type %x ",
|
||||||
Object, Header->PointerCount, PsThreadType);
|
Object, Header->PointerCount, PsThreadType);
|
||||||
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Header->PointerCount == 0 && !(Header->Flags & OB_FLAG_PERMANENT))
|
if (Header->PointerCount == 0 && !(Header->Flags & OB_FLAG_PERMANENT))
|
||||||
{
|
{
|
||||||
if (Header->Type == PsProcessType)
|
if (Header->Type == PsProcessType)
|
||||||
{
|
{
|
||||||
return STATUS_PROCESS_IS_TERMINATING;
|
return STATUS_PROCESS_IS_TERMINATING;
|
||||||
}
|
}
|
||||||
if (Header->Type == PsThreadType)
|
if (Header->Type == PsThreadType)
|
||||||
{
|
{
|
||||||
return STATUS_THREAD_IS_TERMINATING;
|
return STATUS_THREAD_IS_TERMINATING;
|
||||||
}
|
}
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
|
if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
ULONG Attributes,
|
ULONG Attributes,
|
||||||
PACCESS_STATE PassedAccessState,
|
PACCESS_STATE PassedAccessState,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
POBJECT_TYPE ObjectType,
|
POBJECT_TYPE ObjectType,
|
||||||
KPROCESSOR_MODE AccessMode,
|
KPROCESSOR_MODE AccessMode,
|
||||||
PVOID ParseContext,
|
PVOID ParseContext,
|
||||||
PVOID* ObjectPtr)
|
PVOID* ObjectPtr)
|
||||||
{
|
{
|
||||||
PVOID Object = NULL;
|
PVOID Object = NULL;
|
||||||
UNICODE_STRING RemainingPath;
|
UNICODE_STRING RemainingPath;
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
OBP_LOOKUP_CONTEXT Context;
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Capture the name */
|
/* Capture the name */
|
||||||
DPRINT("Capturing Name\n");
|
DPRINT("Capturing Name\n");
|
||||||
Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
|
Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
|
DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a fake ObjectCreateInfo structure. Note that my upcoming
|
* Create a fake ObjectCreateInfo structure. Note that my upcoming
|
||||||
* ObFindObject refactoring will remove the need for this hack.
|
* ObFindObject refactoring will remove the need for this hack.
|
||||||
*/
|
*/
|
||||||
ObjectCreateInfo.RootDirectory = NULL;
|
ObjectCreateInfo.RootDirectory = NULL;
|
||||||
ObjectCreateInfo.Attributes = Attributes;
|
ObjectCreateInfo.Attributes = Attributes;
|
||||||
|
|
||||||
Status = ObFindObject(&ObjectCreateInfo,
|
Status = ObFindObject(&ObjectCreateInfo,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
&Object,
|
&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType,
|
ObjectType,
|
||||||
&Context);
|
&Context);
|
||||||
|
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
|
DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
|
||||||
|
|
||||||
if (RemainingPath.Buffer != NULL || Object == NULL)
|
if (RemainingPath.Buffer != NULL || Object == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Object %p\n", Object);
|
DPRINT("Object %p\n", Object);
|
||||||
*ObjectPtr = NULL;
|
*ObjectPtr = NULL;
|
||||||
RtlFreeUnicodeString (&RemainingPath);
|
RtlFreeUnicodeString (&RemainingPath);
|
||||||
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
||||||
}
|
}
|
||||||
*ObjectPtr = Object;
|
*ObjectPtr = Object;
|
||||||
RtlFreeUnicodeString (&RemainingPath);
|
RtlFreeUnicodeString (&RemainingPath);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
ObReferenceObjectByHandle(HANDLE Handle,
|
ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
POBJECT_TYPE ObjectType,
|
POBJECT_TYPE ObjectType,
|
||||||
KPROCESSOR_MODE AccessMode,
|
KPROCESSOR_MODE AccessMode,
|
||||||
PVOID* Object,
|
PVOID* Object,
|
||||||
POBJECT_HANDLE_INFORMATION HandleInformation)
|
POBJECT_HANDLE_INFORMATION HandleInformation)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
PVOID ObjectBody;
|
PVOID ObjectBody;
|
||||||
ACCESS_MASK GrantedAccess;
|
ACCESS_MASK GrantedAccess;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
PEPROCESS CurrentProcess, Process;
|
PEPROCESS CurrentProcess, Process;
|
||||||
BOOLEAN AttachedToProcess = FALSE;
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
KAPC_STATE ApcState;
|
KAPC_STATE ApcState;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
|
DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
|
||||||
"ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
|
"ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
|
||||||
ObjectType,AccessMode,Object);
|
ObjectType,AccessMode,Object);
|
||||||
|
|
||||||
if (Handle == NULL)
|
if (Handle == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle special handle names
|
* Handle special handle names
|
||||||
*/
|
*/
|
||||||
if (Handle == NtCurrentProcess() &&
|
if (Handle == NtCurrentProcess() &&
|
||||||
(ObjectType == PsProcessType || ObjectType == NULL))
|
(ObjectType == PsProcessType || ObjectType == NULL))
|
||||||
{
|
{
|
||||||
ObReferenceObject(CurrentProcess);
|
ObReferenceObject(CurrentProcess);
|
||||||
|
|
||||||
if (HandleInformation != NULL)
|
if (HandleInformation != NULL)
|
||||||
{
|
{
|
||||||
HandleInformation->HandleAttributes = 0;
|
HandleInformation->HandleAttributes = 0;
|
||||||
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
|
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
*Object = CurrentProcess;
|
*Object = CurrentProcess;
|
||||||
DPRINT("Referencing current process %p\n", CurrentProcess);
|
DPRINT("Referencing current process %p\n", CurrentProcess);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Handle == NtCurrentProcess())
|
else if (Handle == NtCurrentProcess())
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Handle == NtCurrentThread() &&
|
if (Handle == NtCurrentThread() &&
|
||||||
(ObjectType == PsThreadType || ObjectType == NULL))
|
(ObjectType == PsThreadType || ObjectType == NULL))
|
||||||
{
|
{
|
||||||
PETHREAD CurrentThread = PsGetCurrentThread();
|
PETHREAD CurrentThread = PsGetCurrentThread();
|
||||||
|
|
||||||
ObReferenceObject(CurrentThread);
|
ObReferenceObject(CurrentThread);
|
||||||
|
|
||||||
if (HandleInformation != NULL)
|
if (HandleInformation != NULL)
|
||||||
{
|
{
|
||||||
HandleInformation->HandleAttributes = 0;
|
HandleInformation->HandleAttributes = 0;
|
||||||
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
|
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
*Object = CurrentThread;
|
*Object = CurrentThread;
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Handle == NtCurrentThread())
|
else if (Handle == NtCurrentThread())
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* desire as much access rights as possible */
|
/* desire as much access rights as possible */
|
||||||
if (DesiredAccess & MAXIMUM_ALLOWED)
|
if (DesiredAccess & MAXIMUM_ALLOWED)
|
||||||
{
|
{
|
||||||
DesiredAccess &= ~MAXIMUM_ALLOWED;
|
DesiredAccess &= ~MAXIMUM_ALLOWED;
|
||||||
DesiredAccess |= GENERIC_ALL;
|
DesiredAccess |= GENERIC_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ObIsKernelHandle(Handle, AccessMode))
|
if(ObIsKernelHandle(Handle, AccessMode))
|
||||||
{
|
{
|
||||||
Process = PsInitialSystemProcess;
|
Process = PsInitialSystemProcess;
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Process = CurrentProcess;
|
Process = CurrentProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
if (Process != CurrentProcess)
|
if (Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeStackAttachProcess(&Process->Pcb,
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
&ApcState);
|
&ApcState);
|
||||||
AttachedToProcess = TRUE;
|
AttachedToProcess = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
|
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
|
||||||
Handle);
|
Handle);
|
||||||
if (HandleEntry == NULL)
|
if (HandleEntry == NULL)
|
||||||
{
|
{
|
||||||
if (AttachedToProcess)
|
if (AttachedToProcess)
|
||||||
{
|
{
|
||||||
KeUnstackDetachProcess(&ApcState);
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
|
DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
|
||||||
return(STATUS_INVALID_HANDLE);
|
return(STATUS_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||||
ObjectBody = &ObjectHeader->Body;
|
ObjectBody = &ObjectHeader->Body;
|
||||||
|
|
||||||
DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
|
DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
|
||||||
|
|
||||||
if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
|
if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
|
||||||
{
|
{
|
||||||
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%p)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
|
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%p)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
if (AttachedToProcess)
|
if (AttachedToProcess)
|
||||||
{
|
{
|
||||||
KeUnstackDetachProcess(&ApcState);
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map the generic access masks if the caller asks for generic access */
|
/* map the generic access masks if the caller asks for generic access */
|
||||||
if (DesiredAccess & GENERIC_ACCESS)
|
if (DesiredAccess & GENERIC_ACCESS)
|
||||||
{
|
{
|
||||||
RtlMapGenericMask(&DesiredAccess,
|
RtlMapGenericMask(&DesiredAccess,
|
||||||
&BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
|
&BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrantedAccess = HandleEntry->GrantedAccess;
|
GrantedAccess = HandleEntry->GrantedAccess;
|
||||||
|
|
||||||
/* Unless running as KernelMode, deny access if caller desires more access
|
/* Unless running as KernelMode, deny access if caller desires more access
|
||||||
rights than the handle can grant */
|
rights than the handle can grant */
|
||||||
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
|
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
|
||||||
{
|
{
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
if (AttachedToProcess)
|
if (AttachedToProcess)
|
||||||
{
|
{
|
||||||
KeUnstackDetachProcess(&ApcState);
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
|
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
|
||||||
|
|
||||||
return(STATUS_ACCESS_DENIED);
|
return(STATUS_ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObReferenceObject(ObjectBody);
|
ObReferenceObject(ObjectBody);
|
||||||
|
|
||||||
Attributes = HandleEntry->ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
|
Attributes = HandleEntry->ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
|
||||||
EX_HANDLE_ENTRY_INHERITABLE |
|
EX_HANDLE_ENTRY_INHERITABLE |
|
||||||
EX_HANDLE_ENTRY_AUDITONCLOSE);
|
EX_HANDLE_ENTRY_AUDITONCLOSE);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
if (AttachedToProcess)
|
if (AttachedToProcess)
|
||||||
{
|
{
|
||||||
KeUnstackDetachProcess(&ApcState);
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
if (HandleInformation != NULL)
|
if (HandleInformation != NULL)
|
||||||
{
|
{
|
||||||
HandleInformation->HandleAttributes = Attributes;
|
HandleInformation->HandleAttributes = Attributes;
|
||||||
HandleInformation->GrantedAccess = GrantedAccess;
|
HandleInformation->GrantedAccess = GrantedAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
*Object = ObjectBody;
|
*Object = ObjectBody;
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ObDereferenceObject
|
#ifdef ObDereferenceObject
|
||||||
#undef ObDereferenceObject
|
#undef ObDereferenceObject
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
ObDereferenceObject(IN PVOID Object)
|
ObDereferenceObject(IN PVOID Object)
|
||||||
{
|
{
|
||||||
ObfDereferenceObject(Object);
|
ObfDereferenceObject(Object);
|
||||||
}
|
}
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue