svn propset svn:eol-style native foo.py

svn path=/trunk/; revision=22025
This commit is contained in:
James Tabor 2006-05-24 22:07:11 +00:00
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

View file

@ -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

View file

@ -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,
&current, &current,
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 */

View file

@ -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 */