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
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/init.c
* PURPOSE: Handles Object Manager Initialization and Shutdown
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, ObInit)
#endif
GENERIC_MAPPING ObpTypeMapping =
{
STANDARD_RIGHTS_READ,
STANDARD_RIGHTS_WRITE,
STANDARD_RIGHTS_EXECUTE,
0x000F0001
};
GENERIC_MAPPING ObpDirectoryMapping =
{
STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
DIRECTORY_TRAVERSE,
STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
DIRECTORY_CREATE_OBJECT,
STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
DIRECTORY_TRAVERSE,
DIRECTORY_ALL_ACCESS
};
PDEVICE_MAP ObSystemDeviceMap = NULL;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
INIT_FUNCTION
ObInit(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
OBP_LOOKUP_CONTEXT Context;
/* Initialize the security descriptor cache */
ObpInitSdCache();
/* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
/* Create the Type Type */
DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Type");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.MaintainTypeList = TRUE;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
/* Create the Directory Type */
DPRINT("Creating Directory Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Directory");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = FALSE;
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
ObjectTypeInitializer.MaintainTypeList = FALSE;
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
/* Create security descriptor */
RtlCreateSecurityDescriptor(&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION1);
RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
SeAliasAdminsSid,
FALSE);
RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
SeLocalSystemSid,
FALSE);
RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
TRUE,
SePublicDefaultDacl,
FALSE);
/* Create root directory */
DPRINT("Creating Root Directory\n");
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_PERMANENT,
NULL,
&SecurityDescriptor);
ObCreateObject(KernelMode,
ObDirectoryType,
&ObjectAttributes,
KernelMode,
NULL,
sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&NameSpaceRoot);
ObInsertObject((PVOID)NameSpaceRoot,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Create '\ObjectTypes' directory */
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_PERMANENT,
NULL,
&SecurityDescriptor);
ObCreateObject(KernelMode,
ObDirectoryType,
&ObjectAttributes,
KernelMode,
NULL,
sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&ObpTypeDirectoryObject);
ObInsertObject((PVOID)ObpTypeDirectoryObject,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Insert the two objects we already created but couldn't add */
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
Context.Directory = ObpTypeDirectoryObject;
Context.DirectoryLocked = TRUE;
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
OBJ_CASE_INSENSITIVE,
FALSE,
&Context))
{
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObTypeObjectType));
}
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
OBJ_CASE_INSENSITIVE,
FALSE,
&Context))
{
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObDirectoryType));
}
/* Create 'symbolic link' object type */
ObInitSymbolicLinkImplementation();
/* FIXME: Hack Hack! */
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
}
/* EOF */
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/init.c
* PURPOSE: Handles Object Manager Initialization and Shutdown
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, ObInit)
#endif
GENERIC_MAPPING ObpTypeMapping =
{
STANDARD_RIGHTS_READ,
STANDARD_RIGHTS_WRITE,
STANDARD_RIGHTS_EXECUTE,
0x000F0001
};
GENERIC_MAPPING ObpDirectoryMapping =
{
STANDARD_RIGHTS_READ | DIRECTORY_QUERY |
DIRECTORY_TRAVERSE,
STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY |
DIRECTORY_CREATE_OBJECT,
STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY |
DIRECTORY_TRAVERSE,
DIRECTORY_ALL_ACCESS
};
PDEVICE_MAP ObSystemDeviceMap = NULL;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
INIT_FUNCTION
ObInit(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
OBP_LOOKUP_CONTEXT Context;
/* Initialize the security descriptor cache */
ObpInitSdCache();
/* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
/* Create the Type Type */
DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Type");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.MaintainTypeList = TRUE;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObTypeObjectType);
/* Create the Directory Type */
DPRINT("Creating Directory Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Directory");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = FALSE;
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ObpParseDirectory;
ObjectTypeInitializer.MaintainTypeList = FALSE;
ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
/* Create security descriptor */
RtlCreateSecurityDescriptor(&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION1);
RtlSetOwnerSecurityDescriptor(&SecurityDescriptor,
SeAliasAdminsSid,
FALSE);
RtlSetGroupSecurityDescriptor(&SecurityDescriptor,
SeLocalSystemSid,
FALSE);
RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
TRUE,
SePublicDefaultDacl,
FALSE);
/* Create root directory */
DPRINT("Creating Root Directory\n");
InitializeObjectAttributes(&ObjectAttributes,
NULL,
OBJ_PERMANENT,
NULL,
&SecurityDescriptor);
ObCreateObject(KernelMode,
ObDirectoryType,
&ObjectAttributes,
KernelMode,
NULL,
sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&NameSpaceRoot);
ObInsertObject((PVOID)NameSpaceRoot,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Create '\ObjectTypes' directory */
RtlInitUnicodeString(&Name, L"\\ObjectTypes");
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_PERMANENT,
NULL,
&SecurityDescriptor);
ObCreateObject(KernelMode,
ObDirectoryType,
&ObjectAttributes,
KernelMode,
NULL,
sizeof(OBJECT_DIRECTORY),
0,
0,
(PVOID*)&ObpTypeDirectoryObject);
ObInsertObject((PVOID)ObpTypeDirectoryObject,
NULL,
DIRECTORY_ALL_ACCESS,
0,
NULL,
NULL);
/* Insert the two objects we already created but couldn't add */
/* NOTE: Uses TypeList & Creator Info in OB 2.0 */
Context.Directory = ObpTypeDirectoryObject;
Context.DirectoryLocked = TRUE;
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
OBJ_CASE_INSENSITIVE,
FALSE,
&Context))
{
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObTypeObjectType));
}
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
OBJ_CASE_INSENSITIVE,
FALSE,
&Context))
{
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, BODY_TO_HEADER(ObDirectoryType));
}
/* Create 'symbolic link' object type */
ObInitSymbolicLinkImplementation();
/* FIXME: Hack Hack! */
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
}
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@ -1,365 +1,365 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/namespce.c
* PURPOSE: Manages all functions related to the Object Manager name-
* space, such as finding objects or querying their names.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
POBJECT_DIRECTORY NameSpaceRoot = NULL;
POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
/* PRIVATE FUNCTIONS *********************************************************/
NTSTATUS
NTAPI
ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType,
POBP_LOOKUP_CONTEXT Context)
{
PVOID NextObject;
PVOID CurrentObject;
PVOID RootObject;
POBJECT_HEADER CurrentHeader;
NTSTATUS Status;
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
PAGED_CODE();
DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
RtlInitUnicodeString (RemainingPath, NULL);
if (ObjectCreateInfo->RootDirectory == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
CurrentObject = NameSpaceRoot;
}
else
{
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
0,
NULL,
ObjectCreateInfo->ProbeMode,
&CurrentObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
if (ObjectName->Length == 0 ||
ObjectName->Buffer[0] == UNICODE_NULL)
{
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
}
if (ObjectCreateInfo->RootDirectory == NULL &&
ObjectName->Buffer[0] != L'\\')
{
ObDereferenceObject (CurrentObject);
DPRINT1("failed\n");
return STATUS_UNSUCCESSFUL;
}
/* Create a zero-terminated copy of the object name */
PathString.Length = ObjectName->Length;
PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
PathString.Buffer = ExAllocatePool (NonPagedPool,
PathString.MaximumLength);
if (PathString.Buffer == NULL)
{
ObDereferenceObject (CurrentObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory (PathString.Buffer,
ObjectName->Buffer,
ObjectName->Length);
PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
current = PathString.Buffer;
RootObject = CurrentObject;
Attributes = ObjectCreateInfo->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
while (TRUE)
{
DPRINT("current %S\n",current);
CurrentHeader = BODY_TO_HEADER(CurrentObject);
DPRINT("Current ObjectType %wZ\n",
&CurrentHeader->Type->Name);
if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
{
DPRINT("Current object can't parse\n");
break;
}
Status = ((OB_ROS_PARSE_METHOD)CurrentHeader->Type->TypeInfo.ParseProcedure)(CurrentObject,
&NextObject,
&PathString,
&current,
Attributes,
Context);
if (Status == STATUS_REPARSE)
{
/* reparse the object path */
NextObject = NameSpaceRoot;
current = PathString.Buffer;
ObReferenceObjectByPointer(NextObject,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
}
if (NextObject == NULL)
{
break;
}
ObDereferenceObject(CurrentObject);
CurrentObject = NextObject;
}
if (current)
{
RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
}
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
}
/* PUBLIC FUNCTIONS *********************************************************/
NTSTATUS
STDCALL
ObQueryNameString(IN PVOID Object,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength)
{
POBJECT_HEADER_NAME_INFO LocalInfo;
POBJECT_HEADER ObjectHeader;
POBJECT_DIRECTORY ParentDirectory;
ULONG NameSize;
PWCH ObjectName;
NTSTATUS Status;
DPRINT("ObQueryNameString: %x, %x\n", Object, ObjectNameInfo);
/* Get the Kernel Meta-Structures */
ObjectHeader = BODY_TO_HEADER(Object);
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
/* Check if a Query Name Procedure is available */
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
{
/* Call the procedure */
DPRINT("Calling Object's Procedure\n");
Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
TRUE, //fixme
ObjectNameInfo,
Length,
ReturnLength);
/* Return the status */
return Status;
}
/* Check if the object doesn't even have a name */
if (!LocalInfo || !LocalInfo->Name.Buffer)
{
/* We're returning the name structure */
DPRINT("Nameless Object\n");
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
/* Check if we were given enough space */
if (*ReturnLength > Length)
{
DPRINT1("Not enough buffer space\n");
return STATUS_INFO_LENGTH_MISMATCH;
}
/* Return an empty buffer */
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.MaximumLength = 0;
ObjectNameInfo->Name.Buffer = NULL;
return STATUS_SUCCESS;
}
/*
* Find the size needed for the name. We won't do
* this during the Name Creation loop because we want
* to let the caller know that the buffer isn't big
* enough right at the beginning, not work our way through
* and find out at the end
*/
if (Object == NameSpaceRoot)
{
/* Size of the '\' string */
DPRINT("Object is Root\n");
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
}
else
{
/* Get the Object Directory and add name of Object */
ParentDirectory = LocalInfo->Directory;
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
/* Loop inside the directory to get the top-most one (meaning root) */
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
{
/* Get the Name Information */
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
/* Add the size of the Directory Name */
if (LocalInfo && LocalInfo->Directory)
{
/* Size of the '\' string + Directory Name */
NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
/* Move to next parent Directory */
ParentDirectory = LocalInfo->Directory;
}
else
{
/* Directory with no name. We append "...\" */
DPRINT("Nameless Directory\n");
NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
break;
}
}
}
/* Finally, add the name of the structure and the null char */
*ReturnLength = NameSize + sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
DPRINT("Final Length: %x\n", *ReturnLength);
/* Check if we were given enough space */
if (*ReturnLength > Length)
{
DPRINT1("Not enough buffer space\n");
return STATUS_INFO_LENGTH_MISMATCH;
}
/*
* 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
* parent directories. We use the same logic as Name Length calculation.
*/
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
*--ObjectName = UNICODE_NULL;
if (Object == NameSpaceRoot)
{
/* This is already the Root Directory, return "\\" */
DPRINT("Returning Root Dir\n");
*--ObjectName = OBJ_NAME_PATH_SEPARATOR;
ObjectNameInfo->Name.Length = (USHORT)NameSize;
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
ObjectNameInfo->Name.Buffer = ObjectName;
return STATUS_SUCCESS;
}
else
{
/* Start by adding the Object's Name */
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
/* Now parse the Parent directories until we reach the top */
ParentDirectory = LocalInfo->Directory;
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
{
/* Get the name information */
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
/* Add the "\" */
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
/* Add the Parent Directory's Name */
if (LocalInfo && LocalInfo->Name.Buffer)
{
/* Add the name */
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
/* Move to next parent */
ParentDirectory = LocalInfo->Directory;
}
else
{
/* Directory without a name, we add "..." */
DPRINT("Nameless Directory\n");
ObjectName -= sizeof(L"...");
ObjectName = L"...";
break;
}
}
/* Add Root Directory Name */
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
DPRINT("Current Buffer: %S\n", ObjectName);
ObjectNameInfo->Name.Length = (USHORT)NameSize;
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
ObjectNameInfo->Name.Buffer = ObjectName;
DPRINT("Complete: %wZ\n", ObjectNameInfo);
}
return STATUS_SUCCESS;
}
VOID
NTAPI
ObQueryDeviceMapInformation(IN PEPROCESS Process,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
{
//KIRQL OldIrql ;
/*
* 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
*/
/* FIXME: Acquire the DeviceMap Spinlock */
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
/* Make a copy */
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
RtlMoveMemory(DeviceMapInfo->Query.DriveType,
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
}
/* EOF */
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/namespce.c
* PURPOSE: Manages all functions related to the Object Manager name-
* space, such as finding objects or querying their names.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
POBJECT_DIRECTORY NameSpaceRoot = NULL;
POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
/* PRIVATE FUNCTIONS *********************************************************/
NTSTATUS
NTAPI
ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
PUNICODE_STRING ObjectName,
PVOID* ReturnedObject,
PUNICODE_STRING RemainingPath,
POBJECT_TYPE ObjectType,
POBP_LOOKUP_CONTEXT Context)
{
PVOID NextObject;
PVOID CurrentObject;
PVOID RootObject;
POBJECT_HEADER CurrentHeader;
NTSTATUS Status;
PWSTR current;
UNICODE_STRING PathString;
ULONG Attributes;
PAGED_CODE();
DPRINT("ObFindObject(ObjectCreateInfo %x, ReturnedObject %x, "
"RemainingPath %x)\n",ObjectCreateInfo,ReturnedObject,RemainingPath);
RtlInitUnicodeString (RemainingPath, NULL);
if (ObjectCreateInfo->RootDirectory == NULL)
{
ObReferenceObjectByPointer(NameSpaceRoot,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
CurrentObject = NameSpaceRoot;
}
else
{
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
0,
NULL,
ObjectCreateInfo->ProbeMode,
&CurrentObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
if (ObjectName->Length == 0 ||
ObjectName->Buffer[0] == UNICODE_NULL)
{
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
}
if (ObjectCreateInfo->RootDirectory == NULL &&
ObjectName->Buffer[0] != L'\\')
{
ObDereferenceObject (CurrentObject);
DPRINT1("failed\n");
return STATUS_UNSUCCESSFUL;
}
/* Create a zero-terminated copy of the object name */
PathString.Length = ObjectName->Length;
PathString.MaximumLength = ObjectName->Length + sizeof(WCHAR);
PathString.Buffer = ExAllocatePool (NonPagedPool,
PathString.MaximumLength);
if (PathString.Buffer == NULL)
{
ObDereferenceObject (CurrentObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory (PathString.Buffer,
ObjectName->Buffer,
ObjectName->Length);
PathString.Buffer[PathString.Length / sizeof(WCHAR)] = UNICODE_NULL;
current = PathString.Buffer;
RootObject = CurrentObject;
Attributes = ObjectCreateInfo->Attributes;
if (ObjectType == ObSymbolicLinkType)
Attributes |= OBJ_OPENLINK;
while (TRUE)
{
DPRINT("current %S\n",current);
CurrentHeader = BODY_TO_HEADER(CurrentObject);
DPRINT("Current ObjectType %wZ\n",
&CurrentHeader->Type->Name);
if (CurrentHeader->Type->TypeInfo.ParseProcedure == NULL)
{
DPRINT("Current object can't parse\n");
break;
}
Status = ((OB_ROS_PARSE_METHOD)CurrentHeader->Type->TypeInfo.ParseProcedure)(CurrentObject,
&NextObject,
&PathString,
&current,
Attributes,
Context);
if (Status == STATUS_REPARSE)
{
/* reparse the object path */
NextObject = NameSpaceRoot;
current = PathString.Buffer;
ObReferenceObjectByPointer(NextObject,
DIRECTORY_TRAVERSE,
NULL,
ObjectCreateInfo->ProbeMode);
}
if (NextObject == NULL)
{
break;
}
ObDereferenceObject(CurrentObject);
CurrentObject = NextObject;
}
if (current)
{
RtlpCreateUnicodeString (RemainingPath, current, NonPagedPool);
}
RtlFreeUnicodeString (&PathString);
*ReturnedObject = CurrentObject;
return STATUS_SUCCESS;
}
/* PUBLIC FUNCTIONS *********************************************************/
NTSTATUS
STDCALL
ObQueryNameString(IN PVOID Object,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength)
{
POBJECT_HEADER_NAME_INFO LocalInfo;
POBJECT_HEADER ObjectHeader;
POBJECT_DIRECTORY ParentDirectory;
ULONG NameSize;
PWCH ObjectName;
NTSTATUS Status;
DPRINT("ObQueryNameString: %x, %x\n", Object, ObjectNameInfo);
/* Get the Kernel Meta-Structures */
ObjectHeader = BODY_TO_HEADER(Object);
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
/* Check if a Query Name Procedure is available */
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure)
{
/* Call the procedure */
DPRINT("Calling Object's Procedure\n");
Status = ObjectHeader->Type->TypeInfo.QueryNameProcedure(Object,
TRUE, //fixme
ObjectNameInfo,
Length,
ReturnLength);
/* Return the status */
return Status;
}
/* Check if the object doesn't even have a name */
if (!LocalInfo || !LocalInfo->Name.Buffer)
{
/* We're returning the name structure */
DPRINT("Nameless Object\n");
*ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
/* Check if we were given enough space */
if (*ReturnLength > Length)
{
DPRINT1("Not enough buffer space\n");
return STATUS_INFO_LENGTH_MISMATCH;
}
/* Return an empty buffer */
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.MaximumLength = 0;
ObjectNameInfo->Name.Buffer = NULL;
return STATUS_SUCCESS;
}
/*
* Find the size needed for the name. We won't do
* this during the Name Creation loop because we want
* to let the caller know that the buffer isn't big
* enough right at the beginning, not work our way through
* and find out at the end
*/
if (Object == NameSpaceRoot)
{
/* Size of the '\' string */
DPRINT("Object is Root\n");
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR);
}
else
{
/* Get the Object Directory and add name of Object */
ParentDirectory = LocalInfo->Directory;
NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
/* Loop inside the directory to get the top-most one (meaning root) */
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
{
/* Get the Name Information */
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
/* Add the size of the Directory Name */
if (LocalInfo && LocalInfo->Directory)
{
/* Size of the '\' string + Directory Name */
NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + LocalInfo->Name.Length;
/* Move to next parent Directory */
ParentDirectory = LocalInfo->Directory;
}
else
{
/* Directory with no name. We append "...\" */
DPRINT("Nameless Directory\n");
NameSize += sizeof(L"...") + sizeof(OBJ_NAME_PATH_SEPARATOR);
break;
}
}
}
/* Finally, add the name of the structure and the null char */
*ReturnLength = NameSize + sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
DPRINT("Final Length: %x\n", *ReturnLength);
/* Check if we were given enough space */
if (*ReturnLength > Length)
{
DPRINT1("Not enough buffer space\n");
return STATUS_INFO_LENGTH_MISMATCH;
}
/*
* 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
* parent directories. We use the same logic as Name Length calculation.
*/
LocalInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
ObjectName = (PWCH)((ULONG_PTR)ObjectNameInfo + *ReturnLength);
*--ObjectName = UNICODE_NULL;
if (Object == NameSpaceRoot)
{
/* This is already the Root Directory, return "\\" */
DPRINT("Returning Root Dir\n");
*--ObjectName = OBJ_NAME_PATH_SEPARATOR;
ObjectNameInfo->Name.Length = (USHORT)NameSize;
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
ObjectNameInfo->Name.Buffer = ObjectName;
return STATUS_SUCCESS;
}
else
{
/* Start by adding the Object's Name */
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
/* Now parse the Parent directories until we reach the top */
ParentDirectory = LocalInfo->Directory;
while ((ParentDirectory != NameSpaceRoot) && (ParentDirectory))
{
/* Get the name information */
LocalInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ParentDirectory));
/* Add the "\" */
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
/* Add the Parent Directory's Name */
if (LocalInfo && LocalInfo->Name.Buffer)
{
/* Add the name */
ObjectName = (PWCH)((ULONG_PTR)ObjectName - LocalInfo->Name.Length);
RtlMoveMemory(ObjectName, LocalInfo->Name.Buffer, LocalInfo->Name.Length);
/* Move to next parent */
ParentDirectory = LocalInfo->Directory;
}
else
{
/* Directory without a name, we add "..." */
DPRINT("Nameless Directory\n");
ObjectName -= sizeof(L"...");
ObjectName = L"...";
break;
}
}
/* Add Root Directory Name */
*(--ObjectName) = OBJ_NAME_PATH_SEPARATOR;
DPRINT("Current Buffer: %S\n", ObjectName);
ObjectNameInfo->Name.Length = (USHORT)NameSize;
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize + sizeof(UNICODE_NULL));
ObjectNameInfo->Name.Buffer = ObjectName;
DPRINT("Complete: %wZ\n", ObjectNameInfo);
}
return STATUS_SUCCESS;
}
VOID
NTAPI
ObQueryDeviceMapInformation(IN PEPROCESS Process,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
{
//KIRQL OldIrql ;
/*
* 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
*/
/* FIXME: Acquire the DeviceMap Spinlock */
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
/* Make a copy */
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
RtlMoveMemory(DeviceMapInfo->Query.DriveType,
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
}
/* EOF */

View File

@ -1,455 +1,455 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/refderef.c
* PURPOSE: Manages the referencing and de-referencing of all Objects,
* as well as the Object Fast Reference implementation.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
VOID
FASTCALL
ObInitializeFastReference(IN PEX_FAST_REF FastRef,
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
FastRef->Object = Object;
}
PVOID
FASTCALL
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
{
/* FIXME: Fast Referencing is Unimplemented */
/* Do a normal Reference */
ObReferenceObject(FastRef->Object);
/* Return the Object */
return FastRef->Object;
}
VOID
FASTCALL
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
/* Do a normal Dereference */
ObDereferenceObject(FastRef->Object);
}
PVOID
FASTCALL
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
PVOID Object)
{
PVOID OldObject = FastRef->Object;
/* FIXME: Fast Referencing is Unimplemented */
FastRef->Object = Object;
/* Do a normal Dereference */
ObDereferenceObject(OldObject);
/* Return old Object*/
return OldObject;
}
/* PUBLIC FUNCTIONS *********************************************************/
ULONG STDCALL
ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
return Header->PointerCount;
}
VOID FASTCALL
ObfReferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
/* No one should be referencing an object once we are deleting it. */
if (InterlockedIncrement(&Header->PointerCount) == 1 && !(Header->Flags & OB_FLAG_PERMANENT))
{
KEBUGCHECK(0);
}
}
VOID
FASTCALL
ObfDereferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
LONG NewPointerCount;
BOOL Permanent;
ASSERT(Object);
/* Extract the object header. */
Header = BODY_TO_HEADER(Object);
Permanent = Header->Flags & OB_FLAG_PERMANENT;
/*
Drop our reference and get the new count so we can tell if this was the
last reference.
*/
NewPointerCount = InterlockedDecrement(&Header->PointerCount);
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
ASSERT(NewPointerCount >= 0);
/* Check whether the object can now be deleted. */
if (NewPointerCount == 0 &&
!Permanent)
{
ObpDeleteObjectDpcLevel(Header, NewPointerCount);
}
}
NTSTATUS STDCALL
ObReferenceObjectByPointer(IN PVOID Object,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
/* NOTE: should be possible to reference an object above APC_LEVEL! */
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
Object,ObjectType);
Header = BODY_TO_HEADER(Object);
if (ObjectType != NULL && Header->Type != ObjectType)
{
DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n",
Header,
Header->Type,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Header->Type))->Name,
ObjectType,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObjectType))->Name);
return(STATUS_UNSUCCESSFUL);
}
if (Header->Type == PsProcessType)
{
DPRINT("Ref p 0x%x PointerCount %d type %x ",
Object, Header->PointerCount, PsProcessType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
}
if (Header->Type == PsThreadType)
{
DPRINT("Deref t 0x%x with PointerCount %d type %x ",
Object, Header->PointerCount, PsThreadType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
}
if (Header->PointerCount == 0 && !(Header->Flags & OB_FLAG_PERMANENT))
{
if (Header->Type == PsProcessType)
{
return STATUS_PROCESS_IS_TERMINATING;
}
if (Header->Type == PsThreadType)
{
return STATUS_THREAD_IS_TERMINATING;
}
return(STATUS_UNSUCCESSFUL);
}
if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
{
KEBUGCHECK(0);
}
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
ULONG Attributes,
PACCESS_STATE PassedAccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID* ObjectPtr)
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
/* Capture the name */
DPRINT("Capturing Name\n");
Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
if (!NT_SUCCESS(Status))
{
DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
return Status;
}
/*
* Create a fake ObjectCreateInfo structure. Note that my upcoming
* ObFindObject refactoring will remove the need for this hack.
*/
ObjectCreateInfo.RootDirectory = NULL;
ObjectCreateInfo.Attributes = Attributes;
Status = ObFindObject(&ObjectCreateInfo,
&ObjectName,
&Object,
&RemainingPath,
ObjectType,
&Context);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
if (RemainingPath.Buffer != NULL || Object == NULL)
{
DPRINT("Object %p\n", Object);
*ObjectPtr = NULL;
RtlFreeUnicodeString (&RemainingPath);
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
*ObjectPtr = Object;
RtlFreeUnicodeString (&RemainingPath);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
ObReferenceObjectByHandle(HANDLE Handle,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID* Object,
POBJECT_HANDLE_INFORMATION HandleInformation)
{
PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader;
PVOID ObjectBody;
ACCESS_MASK GrantedAccess;
ULONG Attributes;
PEPROCESS CurrentProcess, Process;
BOOLEAN AttachedToProcess = FALSE;
KAPC_STATE ApcState;
PAGED_CODE();
DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
"ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
ObjectType,AccessMode,Object);
if (Handle == NULL)
{
return STATUS_INVALID_HANDLE;
}
CurrentProcess = PsGetCurrentProcess();
/*
* Handle special handle names
*/
if (Handle == NtCurrentProcess() &&
(ObjectType == PsProcessType || ObjectType == NULL))
{
ObReferenceObject(CurrentProcess);
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
}
*Object = CurrentProcess;
DPRINT("Referencing current process %p\n", CurrentProcess);
return STATUS_SUCCESS;
}
else if (Handle == NtCurrentProcess())
{
CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
if (Handle == NtCurrentThread() &&
(ObjectType == PsThreadType || ObjectType == NULL))
{
PETHREAD CurrentThread = PsGetCurrentThread();
ObReferenceObject(CurrentThread);
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
}
*Object = CurrentThread;
CHECKPOINT;
return STATUS_SUCCESS;
}
else if (Handle == NtCurrentThread())
{
CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
/* desire as much access rights as possible */
if (DesiredAccess & MAXIMUM_ALLOWED)
{
DesiredAccess &= ~MAXIMUM_ALLOWED;
DesiredAccess |= GENERIC_ALL;
}
if(ObIsKernelHandle(Handle, AccessMode))
{
Process = PsInitialSystemProcess;
Handle = ObKernelHandleToHandle(Handle);
}
else
{
Process = CurrentProcess;
}
KeEnterCriticalRegion();
if (Process != CurrentProcess)
{
KeStackAttachProcess(&Process->Pcb,
&ApcState);
AttachedToProcess = TRUE;
}
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
Handle);
if (HandleEntry == NULL)
{
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
return(STATUS_INVALID_HANDLE);
}
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
ObjectBody = &ObjectHeader->Body;
DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
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);
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
return(STATUS_OBJECT_TYPE_MISMATCH);
}
/* map the generic access masks if the caller asks for generic access */
if (DesiredAccess & GENERIC_ACCESS)
{
RtlMapGenericMask(&DesiredAccess,
&BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
}
GrantedAccess = HandleEntry->GrantedAccess;
/* Unless running as KernelMode, deny access if caller desires more access
rights than the handle can grant */
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
{
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
return(STATUS_ACCESS_DENIED);
}
ObReferenceObject(ObjectBody);
Attributes = HandleEntry->ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
EX_HANDLE_ENTRY_INHERITABLE |
EX_HANDLE_ENTRY_AUDITONCLOSE);
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = Attributes;
HandleInformation->GrantedAccess = GrantedAccess;
}
*Object = ObjectBody;
return(STATUS_SUCCESS);
}
#ifdef ObDereferenceObject
#undef ObDereferenceObject
#endif
VOID STDCALL
ObDereferenceObject(IN PVOID Object)
{
ObfDereferenceObject(Object);
}
/* EOF */
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/refderef.c
* PURPOSE: Manages the referencing and de-referencing of all Objects,
* as well as the Object Fast Reference implementation.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
VOID
FASTCALL
ObInitializeFastReference(IN PEX_FAST_REF FastRef,
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
FastRef->Object = Object;
}
PVOID
FASTCALL
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
{
/* FIXME: Fast Referencing is Unimplemented */
/* Do a normal Reference */
ObReferenceObject(FastRef->Object);
/* Return the Object */
return FastRef->Object;
}
VOID
FASTCALL
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
/* Do a normal Dereference */
ObDereferenceObject(FastRef->Object);
}
PVOID
FASTCALL
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
PVOID Object)
{
PVOID OldObject = FastRef->Object;
/* FIXME: Fast Referencing is Unimplemented */
FastRef->Object = Object;
/* Do a normal Dereference */
ObDereferenceObject(OldObject);
/* Return old Object*/
return OldObject;
}
/* PUBLIC FUNCTIONS *********************************************************/
ULONG STDCALL
ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
PAGED_CODE();
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
return Header->PointerCount;
}
VOID FASTCALL
ObfReferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
ASSERT(Object);
Header = BODY_TO_HEADER(Object);
/* No one should be referencing an object once we are deleting it. */
if (InterlockedIncrement(&Header->PointerCount) == 1 && !(Header->Flags & OB_FLAG_PERMANENT))
{
KEBUGCHECK(0);
}
}
VOID
FASTCALL
ObfDereferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
LONG NewPointerCount;
BOOL Permanent;
ASSERT(Object);
/* Extract the object header. */
Header = BODY_TO_HEADER(Object);
Permanent = Header->Flags & OB_FLAG_PERMANENT;
/*
Drop our reference and get the new count so we can tell if this was the
last reference.
*/
NewPointerCount = InterlockedDecrement(&Header->PointerCount);
DPRINT("ObfDereferenceObject(0x%x)==%d\n", Object, NewPointerCount);
ASSERT(NewPointerCount >= 0);
/* Check whether the object can now be deleted. */
if (NewPointerCount == 0 &&
!Permanent)
{
ObpDeleteObjectDpcLevel(Header, NewPointerCount);
}
}
NTSTATUS STDCALL
ObReferenceObjectByPointer(IN PVOID Object,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
/* NOTE: should be possible to reference an object above APC_LEVEL! */
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
Object,ObjectType);
Header = BODY_TO_HEADER(Object);
if (ObjectType != NULL && Header->Type != ObjectType)
{
DPRINT("Failed %p (type was %x %wZ) should be %x %wZ\n",
Header,
Header->Type,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Header->Type))->Name,
ObjectType,
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObjectType))->Name);
return(STATUS_UNSUCCESSFUL);
}
if (Header->Type == PsProcessType)
{
DPRINT("Ref p 0x%x PointerCount %d type %x ",
Object, Header->PointerCount, PsProcessType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
}
if (Header->Type == PsThreadType)
{
DPRINT("Deref t 0x%x with PointerCount %d type %x ",
Object, Header->PointerCount, PsThreadType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
}
if (Header->PointerCount == 0 && !(Header->Flags & OB_FLAG_PERMANENT))
{
if (Header->Type == PsProcessType)
{
return STATUS_PROCESS_IS_TERMINATING;
}
if (Header->Type == PsThreadType)
{
return STATUS_THREAD_IS_TERMINATING;
}
return(STATUS_UNSUCCESSFUL);
}
if (1 == InterlockedIncrement(&Header->PointerCount) && !(Header->Flags & OB_FLAG_PERMANENT))
{
KEBUGCHECK(0);
}
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
ULONG Attributes,
PACCESS_STATE PassedAccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID* ObjectPtr)
{
PVOID Object = NULL;
UNICODE_STRING RemainingPath;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
NTSTATUS Status;
OBP_LOOKUP_CONTEXT Context;
PAGED_CODE();
/* Capture the name */
DPRINT("Capturing Name\n");
Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
if (!NT_SUCCESS(Status))
{
DPRINT("ObpCaptureObjectName() failed (Status %lx)\n", Status);
return Status;
}
/*
* Create a fake ObjectCreateInfo structure. Note that my upcoming
* ObFindObject refactoring will remove the need for this hack.
*/
ObjectCreateInfo.RootDirectory = NULL;
ObjectCreateInfo.Attributes = Attributes;
Status = ObFindObject(&ObjectCreateInfo,
&ObjectName,
&Object,
&RemainingPath,
ObjectType,
&Context);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("RemainingPath.Buffer '%S' Object %p\n", RemainingPath.Buffer, Object);
if (RemainingPath.Buffer != NULL || Object == NULL)
{
DPRINT("Object %p\n", Object);
*ObjectPtr = NULL;
RtlFreeUnicodeString (&RemainingPath);
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
*ObjectPtr = Object;
RtlFreeUnicodeString (&RemainingPath);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
ObReferenceObjectByHandle(HANDLE Handle,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID* Object,
POBJECT_HANDLE_INFORMATION HandleInformation)
{
PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader;
PVOID ObjectBody;
ACCESS_MASK GrantedAccess;
ULONG Attributes;
PEPROCESS CurrentProcess, Process;
BOOLEAN AttachedToProcess = FALSE;
KAPC_STATE ApcState;
PAGED_CODE();
DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
"ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
ObjectType,AccessMode,Object);
if (Handle == NULL)
{
return STATUS_INVALID_HANDLE;
}
CurrentProcess = PsGetCurrentProcess();
/*
* Handle special handle names
*/
if (Handle == NtCurrentProcess() &&
(ObjectType == PsProcessType || ObjectType == NULL))
{
ObReferenceObject(CurrentProcess);
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
}
*Object = CurrentProcess;
DPRINT("Referencing current process %p\n", CurrentProcess);
return STATUS_SUCCESS;
}
else if (Handle == NtCurrentProcess())
{
CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
if (Handle == NtCurrentThread() &&
(ObjectType == PsThreadType || ObjectType == NULL))
{
PETHREAD CurrentThread = PsGetCurrentThread();
ObReferenceObject(CurrentThread);
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
}
*Object = CurrentThread;
CHECKPOINT;
return STATUS_SUCCESS;
}
else if (Handle == NtCurrentThread())
{
CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
/* desire as much access rights as possible */
if (DesiredAccess & MAXIMUM_ALLOWED)
{
DesiredAccess &= ~MAXIMUM_ALLOWED;
DesiredAccess |= GENERIC_ALL;
}
if(ObIsKernelHandle(Handle, AccessMode))
{
Process = PsInitialSystemProcess;
Handle = ObKernelHandleToHandle(Handle);
}
else
{
Process = CurrentProcess;
}
KeEnterCriticalRegion();
if (Process != CurrentProcess)
{
KeStackAttachProcess(&Process->Pcb,
&ApcState);
AttachedToProcess = TRUE;
}
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
Handle);
if (HandleEntry == NULL)
{
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
return(STATUS_INVALID_HANDLE);
}
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
ObjectBody = &ObjectHeader->Body;
DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
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);
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
return(STATUS_OBJECT_TYPE_MISMATCH);
}
/* map the generic access masks if the caller asks for generic access */
if (DesiredAccess & GENERIC_ACCESS)
{
RtlMapGenericMask(&DesiredAccess,
&BODY_TO_HEADER(ObjectBody)->Type->TypeInfo.GenericMapping);
}
GrantedAccess = HandleEntry->GrantedAccess;
/* Unless running as KernelMode, deny access if caller desires more access
rights than the handle can grant */
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
{
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
return(STATUS_ACCESS_DENIED);
}
ObReferenceObject(ObjectBody);
Attributes = HandleEntry->ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
EX_HANDLE_ENTRY_INHERITABLE |
EX_HANDLE_ENTRY_AUDITONCLOSE);
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
if (AttachedToProcess)
{
KeUnstackDetachProcess(&ApcState);
}
KeLeaveCriticalRegion();
if (HandleInformation != NULL)
{
HandleInformation->HandleAttributes = Attributes;
HandleInformation->GrantedAccess = GrantedAccess;
}
*Object = ObjectBody;
return(STATUS_SUCCESS);
}
#ifdef ObDereferenceObject
#undef ObDereferenceObject
#endif
VOID STDCALL
ObDereferenceObject(IN PVOID Object)
{
ObfDereferenceObject(Object);
}
/* EOF */