mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 08:25:53 +00:00
- Rewrote the Object Directory implementation to follow the NT Structures in the NDK. This got rid of the last remaining OBJECT_HEADER difference and switched over to OBJECT_DIRECTORY.
- The low-level implementation is based on information from "Undocumented Windows 2000 Internals: A Programmer's Cookbook", with some modifications done by myself to match the updated 2003 structures. This implementation was hackishly stuck into our messed up high-level object lookup implementation, which now has 4 more band-aids. Still needs a lot of work done to the upper echelons of object lookup, but at least this gets rid of ROS-internal stuff. svn path=/trunk/; revision=22015
This commit is contained in:
parent
238be0b59c
commit
3ccc97c6c4
|
@ -318,12 +318,44 @@ typedef struct _OBJECT_TYPE
|
||||||
ERESOURCE ObjectLocks[4];
|
ERESOURCE ObjectLocks[4];
|
||||||
} OBJECT_TYPE;
|
} OBJECT_TYPE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Object Directory Structures
|
||||||
|
//
|
||||||
|
typedef struct _OBJECT_DIRECTORY_ENTRY
|
||||||
|
{
|
||||||
|
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
|
||||||
|
PVOID Object;
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||||
|
ULONG HashValue;
|
||||||
|
#endif
|
||||||
|
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _OBJECT_DIRECTORY
|
||||||
|
{
|
||||||
|
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
|
||||||
|
#if (NTDDI_VERSION < NTDDI_WINXP)
|
||||||
|
ERESOURCE Lock;
|
||||||
|
#elif (NTDDI_VERSION >= NTDDI_WINXP)
|
||||||
|
ERESOURCE Lock; // FIXME: HACKHACK, SHOULD BE EX_PUSH_LOCK
|
||||||
|
#endif
|
||||||
|
#if (NTDDI_VERSION < NTDDI_WINXP)
|
||||||
|
BOOLEAN CurrentEntryValid;
|
||||||
|
#else
|
||||||
|
struct _DEVICE_MAP *DeviceMap;
|
||||||
|
#endif
|
||||||
|
ULONG SessionId;
|
||||||
|
#if (NTDDI_VERSION == NTDDI_WINXP)
|
||||||
|
USHORT Reserved;
|
||||||
|
USHORT SymbolicLinkUsageCount;
|
||||||
|
#endif
|
||||||
|
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Object Header Addon Information
|
// Object Header Addon Information
|
||||||
//
|
//
|
||||||
typedef struct _OBJECT_HEADER_NAME_INFO
|
typedef struct _OBJECT_HEADER_NAME_INFO
|
||||||
{
|
{
|
||||||
struct _DIRECTORY_OBJECT *Directory;
|
POBJECT_DIRECTORY Directory;
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
ULONG QueryReferences;
|
ULONG QueryReferences;
|
||||||
ULONG Reserved2;
|
ULONG Reserved2;
|
||||||
|
@ -384,48 +416,16 @@ typedef struct _OBJECT_HEADER
|
||||||
QUAD Body;
|
QUAD Body;
|
||||||
} OBJECT_HEADER, *POBJECT_HEADER;
|
} OBJECT_HEADER, *POBJECT_HEADER;
|
||||||
|
|
||||||
//
|
|
||||||
// Object Directory Structures
|
|
||||||
//
|
|
||||||
typedef struct _OBJECT_DIRECTORY_ENTRY
|
|
||||||
{
|
|
||||||
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
|
|
||||||
PVOID Object;
|
|
||||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
|
||||||
ULONG HashValue;
|
|
||||||
#endif
|
|
||||||
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
|
|
||||||
|
|
||||||
typedef struct _OBJECT_DIRECTORY
|
|
||||||
{
|
|
||||||
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
|
|
||||||
#if (NTDDI_VERSION < NTDDI_WINXP)
|
|
||||||
PERESOURCE Lock;
|
|
||||||
#elif (NTDDI_VERSION >= NTDDI_WINXP)
|
|
||||||
EX_PUSH_LOCK Lock;
|
|
||||||
#endif
|
|
||||||
#if (NTDDI_VERSION < NTDDI_WINXP)
|
|
||||||
BOOLEAN CurrentEntryValid;
|
|
||||||
#else
|
|
||||||
struct _DEVICE_MAP *DeviceMap;
|
|
||||||
#endif
|
|
||||||
ULONG SessionId;
|
|
||||||
#if (NTDDI_VERSION == NTDDI_WINXP)
|
|
||||||
USHORT Reserved;
|
|
||||||
USHORT SymbolicLinkUsageCount;
|
|
||||||
#endif
|
|
||||||
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Device Map
|
// Device Map
|
||||||
//
|
//
|
||||||
typedef struct _DEVICE_MAP
|
typedef struct _DEVICE_MAP
|
||||||
{
|
{
|
||||||
POBJECT_DIRECTORY DosDevicesDirectory;
|
POBJECT_DIRECTORY DosDevicesDirectory;
|
||||||
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
|
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
|
||||||
ULONG ReferenceCount;
|
ULONG ReferenceCount;
|
||||||
ULONG DriveMap;
|
ULONG DriveMap;
|
||||||
UCHAR DriveType[32];
|
UCHAR DriveType[32];
|
||||||
} DEVICE_MAP, *PDEVICE_MAP;
|
} DEVICE_MAP, *PDEVICE_MAP;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -199,6 +199,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
UNICODE_STRING CapturedClass = {0};
|
UNICODE_STRING CapturedClass = {0};
|
||||||
HANDLE hKey;
|
HANDLE hKey;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -262,7 +263,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType,
|
||||||
|
&Context);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
|
@ -1262,6 +1264,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo;
|
REG_PRE_OPEN_KEY_INFORMATION PreOpenKeyInfo;
|
||||||
REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo;
|
REG_POST_OPEN_KEY_INFORMATION PostOpenKeyInfo;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -1329,7 +1332,8 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType,
|
||||||
|
&Context);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
||||||
|
|
|
@ -704,6 +704,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
PWSTR SubName;
|
PWSTR SubName;
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
DPRINT("CmiConnectHive(%p, %p) called.\n",
|
DPRINT("CmiConnectHive(%p, %p) called.\n",
|
||||||
KeyObjectAttributes, RegistryHive);
|
KeyObjectAttributes, RegistryHive);
|
||||||
|
@ -725,7 +726,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
(PVOID*)&ParentKey,
|
(PVOID*)&ParentKey,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType,
|
||||||
|
&Context);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
|
@ -86,14 +86,16 @@ ExpWinStaObjectParse(PVOID Object,
|
||||||
PVOID *NextObject,
|
PVOID *NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR *Path,
|
PWSTR *Path,
|
||||||
ULONG Attributes)
|
ULONG Attributes,
|
||||||
|
POBP_LOOKUP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
/* Call the Registered Callback */
|
/* Call the Registered Callback */
|
||||||
return ExpWindowStationObjectParse(Object,
|
return ExpWindowStationObjectParse(Object,
|
||||||
NextObject,
|
NextObject,
|
||||||
FullPath,
|
FullPath,
|
||||||
Path,
|
Path,
|
||||||
Attributes);
|
Attributes,
|
||||||
|
Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -11,21 +11,8 @@
|
||||||
|
|
||||||
struct _EPROCESS;
|
struct _EPROCESS;
|
||||||
|
|
||||||
typedef struct _DIRECTORY_OBJECT
|
|
||||||
{
|
|
||||||
CSHORT Type;
|
|
||||||
CSHORT Size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PURPOSE: Head of the list of our subdirectories
|
|
||||||
*/
|
|
||||||
LIST_ENTRY head;
|
|
||||||
KSPIN_LOCK Lock;
|
|
||||||
} DIRECTORY_OBJECT, *PDIRECTORY_OBJECT;
|
|
||||||
|
|
||||||
typedef struct _ROS_OBJECT_HEADER
|
typedef struct _ROS_OBJECT_HEADER
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
|
||||||
LONG PointerCount;
|
LONG PointerCount;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -46,6 +33,16 @@ typedef struct _ROS_OBJECT_HEADER
|
||||||
QUAD Body;
|
QUAD Body;
|
||||||
} ROS_OBJECT_HEADER, *PROS_OBJECT_HEADER;
|
} ROS_OBJECT_HEADER, *PROS_OBJECT_HEADER;
|
||||||
|
|
||||||
|
typedef struct _OBP_LOOKUP_CONTEXT
|
||||||
|
{
|
||||||
|
POBJECT_DIRECTORY Directory;
|
||||||
|
PVOID Object;
|
||||||
|
ULONG HashValue;
|
||||||
|
USHORT HashIndex;
|
||||||
|
BOOLEAN DirectoryLocked;
|
||||||
|
ULONG LockStateSignature;
|
||||||
|
} OBP_LOOKUP_CONTEXT, *POBP_LOOKUP_CONTEXT;
|
||||||
|
|
||||||
#define BODY_TO_HEADER(objbdy) \
|
#define BODY_TO_HEADER(objbdy) \
|
||||||
CONTAINING_RECORD((objbdy), ROS_OBJECT_HEADER, Body)
|
CONTAINING_RECORD((objbdy), ROS_OBJECT_HEADER, Body)
|
||||||
|
|
||||||
|
@ -69,7 +66,7 @@ typedef struct _ROS_OBJECT_HEADER
|
||||||
#define ObMarkHandleAsKernelHandle(Handle) \
|
#define ObMarkHandleAsKernelHandle(Handle) \
|
||||||
(HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
|
(HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
|
||||||
|
|
||||||
extern PDIRECTORY_OBJECT NameSpaceRoot;
|
extern POBJECT_DIRECTORY NameSpaceRoot;
|
||||||
extern POBJECT_TYPE ObSymbolicLinkType;
|
extern POBJECT_TYPE ObSymbolicLinkType;
|
||||||
extern PHANDLE_TABLE ObpKernelHandleTable;
|
extern PHANDLE_TABLE ObpKernelHandleTable;
|
||||||
|
|
||||||
|
@ -94,30 +91,27 @@ typedef NTSTATUS
|
||||||
PVOID *NextObject,
|
PVOID *NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR *Path,
|
PWSTR *Path,
|
||||||
ULONG Attributes
|
ULONG Attributes,
|
||||||
|
POBP_LOOKUP_CONTEXT Context
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpAddEntryDirectory(
|
ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context);
|
||||||
PDIRECTORY_OBJECT Parent,
|
|
||||||
PROS_OBJECT_HEADER Header,
|
|
||||||
PWSTR Name
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpCreateDirectory(
|
ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
||||||
OB_OPEN_REASON Reason,
|
IN POBP_LOOKUP_CONTEXT Context,
|
||||||
PEPROCESS Process,
|
IN POBJECT_HEADER ObjectHeader);
|
||||||
PVOID ObjectBody,
|
|
||||||
ACCESS_MASK GrantedAccess,
|
|
||||||
ULONG HandleCount
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpRemoveEntryDirectory(PROS_OBJECT_HEADER Header);
|
ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
||||||
|
IN PUNICODE_STRING Name,
|
||||||
|
IN ULONG Attributes,
|
||||||
|
IN UCHAR SearchShadow,
|
||||||
|
IN POBP_LOOKUP_CONTEXT Context);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -139,7 +133,8 @@ ObpParseDirectory(
|
||||||
PVOID * NextObject,
|
PVOID * NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR * Path,
|
PWSTR * Path,
|
||||||
ULONG Attributes
|
ULONG Attributes,
|
||||||
|
POBP_LOOKUP_CONTEXT Context
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -157,7 +152,8 @@ ObFindObject(
|
||||||
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
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
|
|
||||||
/* INCLUDES ***************************************************************/
|
/* INCLUDES ***************************************************************/
|
||||||
|
|
||||||
|
#define NTDDI_VERSION NTDDI_WS03
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#define OBP_PROFILE
|
||||||
#ifdef OBP_PROFILE
|
#ifdef OBP_PROFILE
|
||||||
|
|
||||||
LARGE_INTEGER ObpProfileTime;
|
LARGE_INTEGER ObpProfileTime;
|
||||||
|
@ -48,119 +50,228 @@ BOOLEAN ObpProfileComplete;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS ******************************************************/
|
/* PRIVATE FUNCTIONS ******************************************************/
|
||||||
|
|
||||||
VOID
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
|
ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent,
|
||||||
PROS_OBJECT_HEADER Header,
|
IN POBP_LOOKUP_CONTEXT Context,
|
||||||
PWSTR Name)
|
IN POBJECT_HEADER ObjectHeader)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl;
|
POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
|
||||||
|
POBJECT_DIRECTORY_ENTRY NewEntry;
|
||||||
|
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
||||||
|
|
||||||
ObpStartProfile();
|
/* Make sure we have a name */
|
||||||
ASSERT(HEADER_TO_OBJECT_NAME(Header));
|
ASSERT(ObjectHeader->NameInfoOffset != 0);
|
||||||
HEADER_TO_OBJECT_NAME(Header)->Directory = Parent;
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&Parent->Lock, &oldlvl);
|
/* Validate the context */
|
||||||
InsertTailList(&Parent->head, &Header->Entry);
|
if ((Context->Object) || !(Context->DirectoryLocked) || !Parent)
|
||||||
KeReleaseSpinLock(&Parent->Lock, oldlvl);
|
|
||||||
ObpEndProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
ObpRemoveEntryDirectory(PROS_OBJECT_HEADER Header)
|
|
||||||
{
|
|
||||||
KIRQL oldlvl;
|
|
||||||
|
|
||||||
ObpStartProfile();
|
|
||||||
DPRINT("ObpRemoveEntryDirectory(Header %x)\n",Header);
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),&oldlvl);
|
|
||||||
if (Header->Entry.Flink && Header->Entry.Blink)
|
|
||||||
{
|
{
|
||||||
RemoveEntryList(&(Header->Entry));
|
DbgPrint("OB: ObpInsertEntryDirectory - invalid context %p %ld\n",
|
||||||
Header->Entry.Flink = Header->Entry.Blink = NULL;
|
Context, Context->DirectoryLocked);
|
||||||
|
DbgBreakPoint();
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&(HEADER_TO_OBJECT_NAME(Header)->Directory->Lock),oldlvl);
|
|
||||||
ObpEndProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
/* Allocate a new Directory Entry */
|
||||||
NTAPI
|
NewEntry = ExAllocatePoolWithTag(PagedPool,
|
||||||
ObpCreateDirectory(OB_OPEN_REASON Reason,
|
sizeof(OBJECT_DIRECTORY_ENTRY),
|
||||||
PEPROCESS Process,
|
TAG('O', 'b', 'D', 'i'));
|
||||||
PVOID ObjectBody,
|
if (!NewEntry) return FALSE;
|
||||||
ACCESS_MASK GrantedAccess,
|
|
||||||
ULONG HandleCount)
|
|
||||||
{
|
|
||||||
PDIRECTORY_OBJECT Directory = ObjectBody;
|
|
||||||
|
|
||||||
ObpStartProfile();
|
/* Save the hash */
|
||||||
if (Reason == ObCreateHandle)
|
NewEntry->HashValue = Context->HashValue;
|
||||||
{
|
|
||||||
InitializeListHead(&Directory->head);
|
|
||||||
KeInitializeSpinLock(&Directory->Lock);
|
|
||||||
}
|
|
||||||
ObpEndProfile();
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
/* Get the Object Name Information */
|
||||||
|
HeaderNameInfo = HEADER_TO_OBJECT_NAME(ObjectHeader);
|
||||||
|
|
||||||
|
/* Get the Allocated entry */
|
||||||
|
AllocatedEntry = &Parent->HashBuckets[Context->HashIndex];
|
||||||
|
DPRINT("ADD: Allocated Entry: %p. NewEntry: %p\n", AllocatedEntry, NewEntry);
|
||||||
|
DPRINT("ADD: Name: %wZ, Hash: %lx\n", &HeaderNameInfo->Name, Context->HashIndex);
|
||||||
|
DPRINT("ADD: Parent: %p. Name: %wZ\n",
|
||||||
|
Parent,
|
||||||
|
HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent)) ?
|
||||||
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(Parent))->Name : NULL);
|
||||||
|
|
||||||
|
/* Set it */
|
||||||
|
NewEntry->ChainLink = *AllocatedEntry;
|
||||||
|
*AllocatedEntry = NewEntry;
|
||||||
|
|
||||||
|
/* Associate the Object */
|
||||||
|
NewEntry->Object = &ObjectHeader->Body;
|
||||||
|
|
||||||
|
/* Associate the Directory */
|
||||||
|
HeaderNameInfo->Directory = Parent;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject,
|
ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
||||||
PWSTR Name,
|
IN PUNICODE_STRING Name,
|
||||||
ULONG Attributes)
|
IN ULONG Attributes,
|
||||||
|
IN UCHAR SearchShadow,
|
||||||
|
IN POBP_LOOKUP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current = DirectoryObject->head.Flink;
|
BOOLEAN CaseInsensitive = FALSE;
|
||||||
PROS_OBJECT_HEADER current_obj;
|
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
||||||
|
ULONG HashValue;
|
||||||
|
ULONG HashIndex;
|
||||||
|
LONG TotalChars;
|
||||||
|
WCHAR CurrentChar;
|
||||||
|
POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
|
||||||
|
POBJECT_DIRECTORY_ENTRY *LookupBucket;
|
||||||
|
POBJECT_DIRECTORY_ENTRY CurrentEntry;
|
||||||
|
PVOID FoundObject = NULL;
|
||||||
|
PWSTR Buffer;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
ObpStartProfile();
|
/* Always disable this until we have LUID Device Maps */
|
||||||
DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
|
SearchShadow = FALSE;
|
||||||
ObpCompleteProfile();
|
|
||||||
|
|
||||||
if (Name[0]==0)
|
/* Fail the following cases */
|
||||||
|
TotalChars = Name->Length / sizeof(WCHAR);
|
||||||
|
if (!(Directory) || !(Name) || !(Name->Buffer) || !(TotalChars))
|
||||||
{
|
{
|
||||||
ObpEndProfile();
|
goto Quickie;
|
||||||
return(DirectoryObject);
|
|
||||||
}
|
}
|
||||||
if (Name[0]=='.' && Name[1]==0)
|
|
||||||
|
/* Set up case-sensitivity */
|
||||||
|
if (Attributes & OBJ_CASE_INSENSITIVE) CaseInsensitive = TRUE;
|
||||||
|
|
||||||
|
/* Create the Hash */
|
||||||
|
Buffer = Name->Buffer;
|
||||||
|
for (HashValue = 0; TotalChars; TotalChars--)
|
||||||
{
|
{
|
||||||
ObpEndProfile();
|
/* Go to the next Character */
|
||||||
return(DirectoryObject);
|
CurrentChar = *Buffer++;
|
||||||
|
|
||||||
|
/* Prepare the Hash */
|
||||||
|
HashValue += (HashValue << 1) + (HashValue >> 1);
|
||||||
|
|
||||||
|
/* Create the rest based on the name */
|
||||||
|
if (CurrentChar < 'a') HashValue += CurrentChar;
|
||||||
|
else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
|
||||||
|
else HashValue += (CurrentChar - ('a'-'A'));
|
||||||
}
|
}
|
||||||
if (Name[0]=='.' && Name[1]=='.' && Name[2]==0)
|
|
||||||
|
/* Merge it with our number of hash buckets */
|
||||||
|
HashIndex = HashValue % 37;
|
||||||
|
DPRINT("LOOKUP: ObjectName: %wZ\n", Name);
|
||||||
|
DPRINT("LOOKUP: Generated Hash: 0x%x. Generated Id: 0x%x\n", HashValue, HashIndex);
|
||||||
|
|
||||||
|
/* Save the result */
|
||||||
|
Context->HashValue = HashValue;
|
||||||
|
Context->HashIndex = HashIndex;
|
||||||
|
|
||||||
|
/* Get the root entry and set it as our lookup bucket */
|
||||||
|
AllocatedEntry = &Directory->HashBuckets[HashIndex];
|
||||||
|
LookupBucket = AllocatedEntry;
|
||||||
|
DPRINT("LOOKUP: Allocated Entry: %p. LookupBucket: %p\n", AllocatedEntry, LookupBucket);
|
||||||
|
|
||||||
|
/* Check if the directory is already locked */
|
||||||
|
if (!Context->DirectoryLocked)
|
||||||
{
|
{
|
||||||
ObpEndProfile();
|
/* Lock it */
|
||||||
return(HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(DirectoryObject))->Directory);
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceSharedLite(&Directory->Lock, TRUE);
|
||||||
|
Context->LockStateSignature = 0xDDDD1234;
|
||||||
}
|
}
|
||||||
while (current!=(&(DirectoryObject->head)))
|
|
||||||
|
/* Start looping */
|
||||||
|
while ((CurrentEntry = *AllocatedEntry))
|
||||||
{
|
{
|
||||||
current_obj = CONTAINING_RECORD(current,ROS_OBJECT_HEADER,Entry);
|
/* Do the hashes match? */
|
||||||
DPRINT(" Scanning: %S for: %S\n",HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name);
|
DPRINT("CurrentEntry: %p. CurrentHash: %lx\n", CurrentEntry, CurrentEntry->HashValue);
|
||||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
if (CurrentEntry->HashValue == HashValue)
|
||||||
{
|
{
|
||||||
if (_wcsicmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
|
/* Make sure that it has a name */
|
||||||
|
ASSERT(BODY_TO_HEADER(CurrentEntry->Object)->NameInfoOffset != 0);
|
||||||
|
|
||||||
|
/* Get the name information */
|
||||||
|
HeaderNameInfo = HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(CurrentEntry->Object));
|
||||||
|
|
||||||
|
/* Do the names match? */
|
||||||
|
DPRINT("NameCheck: %wZ, %wZ\n", Name, &HeaderNameInfo->Name);
|
||||||
|
if ((Name->Length == HeaderNameInfo->Name.Length) &&
|
||||||
|
(RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
|
||||||
{
|
{
|
||||||
DPRINT("Found it %x\n",¤t_obj->Body);
|
DPRINT("Found Name Match\n");
|
||||||
ObpEndProfile();
|
break;
|
||||||
return(¤t_obj->Body);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Move to the next entry */
|
||||||
if ( wcscmp(HEADER_TO_OBJECT_NAME(current_obj)->Name.Buffer, Name)==0)
|
AllocatedEntry = &CurrentEntry->ChainLink;
|
||||||
{
|
|
||||||
DPRINT("Found it %x\n",¤t_obj->Body);
|
|
||||||
ObpEndProfile();
|
|
||||||
return(¤t_obj->Body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current = current->Flink;
|
|
||||||
}
|
}
|
||||||
DPRINT(" Not Found: %s() = NULL\n",__FUNCTION__);
|
|
||||||
ObpEndProfile();
|
/* Check if we still have an entry */
|
||||||
return(NULL);
|
if (CurrentEntry)
|
||||||
|
{
|
||||||
|
/* Set this entry as the first, to speed up incoming insertion */
|
||||||
|
if (AllocatedEntry != LookupBucket)
|
||||||
|
{
|
||||||
|
/* Set the Current Entry */
|
||||||
|
*AllocatedEntry = CurrentEntry->ChainLink;
|
||||||
|
|
||||||
|
/* Link to the old Hash Entry */
|
||||||
|
CurrentEntry->ChainLink = *LookupBucket;
|
||||||
|
|
||||||
|
/* Set the new Hash Entry */
|
||||||
|
*LookupBucket = CurrentEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the found object */
|
||||||
|
FoundObject = CurrentEntry->Object;
|
||||||
|
if (!FoundObject) goto Quickie;
|
||||||
|
|
||||||
|
/* Add a reference to the object */
|
||||||
|
ObReferenceObject(FoundObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the directory was unlocked (which means we locked it) */
|
||||||
|
if (!Context->DirectoryLocked)
|
||||||
|
{
|
||||||
|
/* Lock it */
|
||||||
|
ExReleaseResourceLite(&Directory->Lock);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
Context->LockStateSignature = 0xEEEE1234;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
/* Return the object we found */
|
||||||
|
DPRINT("Object Found: %p Context: %p\n", FoundObject, Context);
|
||||||
|
Context->Object = FoundObject;
|
||||||
|
return FoundObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context)
|
||||||
|
{
|
||||||
|
POBJECT_DIRECTORY Directory;
|
||||||
|
POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
|
||||||
|
POBJECT_DIRECTORY_ENTRY CurrentEntry;
|
||||||
|
|
||||||
|
/* Get the Directory */
|
||||||
|
Directory = Context->Directory;
|
||||||
|
if (!Directory) return FALSE;
|
||||||
|
|
||||||
|
/* Get the Entry */
|
||||||
|
AllocatedEntry = &Directory->HashBuckets[Context->HashIndex];
|
||||||
|
CurrentEntry = *AllocatedEntry;
|
||||||
|
DPRINT("DEL: Parent: %p, Hash: %lx, AllocatedEntry: %p, CurrentEntry: %p\n",
|
||||||
|
Directory, Context->HashIndex, AllocatedEntry, CurrentEntry);
|
||||||
|
|
||||||
|
/* Unlink the Entry */
|
||||||
|
*AllocatedEntry = CurrentEntry->ChainLink;
|
||||||
|
CurrentEntry->ChainLink = NULL;
|
||||||
|
|
||||||
|
/* Free it */
|
||||||
|
ExFreePool(CurrentEntry);
|
||||||
|
|
||||||
|
/* Return */
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -169,22 +280,19 @@ ObpParseDirectory(PVOID Object,
|
||||||
PVOID * NextObject,
|
PVOID * NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR * Path,
|
PWSTR * Path,
|
||||||
ULONG Attributes)
|
ULONG Attributes,
|
||||||
|
POBP_LOOKUP_CONTEXT Context)
|
||||||
{
|
{
|
||||||
PWSTR Start;
|
PWSTR Start;
|
||||||
PWSTR End;
|
PWSTR End;
|
||||||
PVOID FoundObject;
|
PVOID FoundObject;
|
||||||
KIRQL oldlvl;
|
//KIRQL oldlvl;
|
||||||
|
UNICODE_STRING StartUs;
|
||||||
ObpStartProfile();
|
|
||||||
DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n",
|
|
||||||
Object,Path,*Path);
|
|
||||||
|
|
||||||
*NextObject = NULL;
|
*NextObject = NULL;
|
||||||
|
|
||||||
if ((*Path) == NULL)
|
if ((*Path) == NULL)
|
||||||
{
|
{
|
||||||
ObpEndProfile();
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,16 +306,18 @@ ObpParseDirectory(PVOID Object,
|
||||||
*End = 0;
|
*End = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
|
//KeAcquireSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), &oldlvl);
|
||||||
FoundObject = ObpFindEntryDirectory(Object, Start, Attributes);
|
RtlInitUnicodeString(&StartUs, Start);
|
||||||
|
Context->DirectoryLocked = TRUE;
|
||||||
|
Context->Directory = Object;
|
||||||
|
FoundObject = ObpLookupEntryDirectory(Object, &StartUs, Attributes, FALSE, Context);
|
||||||
if (FoundObject == NULL)
|
if (FoundObject == NULL)
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
//KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
||||||
if (End != NULL)
|
if (End != NULL)
|
||||||
{
|
{
|
||||||
*End = L'\\';
|
*End = L'\\';
|
||||||
}
|
}
|
||||||
ObpEndProfile();
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +325,7 @@ ObpParseDirectory(PVOID Object,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode);
|
UserMode);
|
||||||
KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
//KeReleaseSpinLock(&(((PDIRECTORY_OBJECT)Object)->Lock), oldlvl);
|
||||||
if (End != NULL)
|
if (End != NULL)
|
||||||
{
|
{
|
||||||
*End = L'\\';
|
*End = L'\\';
|
||||||
|
@ -228,7 +338,6 @@ ObpParseDirectory(PVOID Object,
|
||||||
|
|
||||||
*NextObject = FoundObject;
|
*NextObject = FoundObject;
|
||||||
|
|
||||||
ObpEndProfile();
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +469,7 @@ NtQueryDirectoryObject(IN HANDLE DirectoryHandle,
|
||||||
IN OUT PULONG Context,
|
IN OUT PULONG Context,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PDIRECTORY_OBJECT Directory;
|
POBJECT_DIRECTORY Directory;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
ULONG SkipEntries = 0;
|
ULONG SkipEntries = 0;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
@ -441,7 +550,7 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
{
|
{
|
||||||
PDIRECTORY_OBJECT Directory;
|
POBJECT_DIRECTORY Directory;
|
||||||
HANDLE hDirectory;
|
HANDLE hDirectory;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
@ -475,7 +584,7 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(DIRECTORY_OBJECT),
|
sizeof(OBJECT_DIRECTORY),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&Directory);
|
(PVOID*)&Directory);
|
||||||
|
@ -488,12 +597,6 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&hDirectory);
|
&hDirectory);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ObMakeTemporaryObject(Directory);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Directory);
|
|
||||||
|
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
|
@ -506,6 +609,8 @@ NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle,
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(Directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -54,6 +54,7 @@ ObpDecrementHandleCount(PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
PROS_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
PROS_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
||||||
LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
|
LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
DPRINT("Header: %x\n", ObjectHeader);
|
DPRINT("Header: %x\n", ObjectHeader);
|
||||||
DPRINT("NewHandleCount: %x\n", NewHandleCount);
|
DPRINT("NewHandleCount: %x\n", NewHandleCount);
|
||||||
DPRINT("HEADER_TO_OBJECT_NAME: %x\n", HEADER_TO_OBJECT_NAME(ObjectHeader));
|
DPRINT("HEADER_TO_OBJECT_NAME: %x\n", HEADER_TO_OBJECT_NAME(ObjectHeader));
|
||||||
|
@ -75,7 +76,18 @@ ObpDecrementHandleCount(PVOID ObjectBody)
|
||||||
/* delete the object from the namespace when the last handle got closed.
|
/* delete the object from the namespace when the last handle got closed.
|
||||||
Only do this if it's actually been inserted into the namespace and
|
Only do this if it's actually been inserted into the namespace and
|
||||||
if it's not a permanent object. */
|
if it's not a permanent object. */
|
||||||
ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader);
|
|
||||||
|
/* Make sure it's still inserted */
|
||||||
|
Context.Directory = HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory;
|
||||||
|
Context.DirectoryLocked = TRUE;
|
||||||
|
if (ObpLookupEntryDirectory(HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
|
||||||
|
&HEADER_TO_OBJECT_NAME(ObjectHeader)->Name,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
ObpDeleteEntryDirectory(&Context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the keep-alive reference */
|
/* remove the keep-alive reference */
|
||||||
|
@ -1150,6 +1162,7 @@ ObInsertObject(IN PVOID Object,
|
||||||
BOOLEAN ObjectAttached = FALSE;
|
BOOLEAN ObjectAttached = FALSE;
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
|
||||||
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -1167,7 +1180,8 @@ ObInsertObject(IN PVOID Object,
|
||||||
&ObjectNameInfo->Name,
|
&ObjectNameInfo->Name,
|
||||||
&FoundObject,
|
&FoundObject,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
NULL);
|
NULL,
|
||||||
|
&Context);
|
||||||
DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath);
|
DPRINT("FoundObject: %x, Path: %wZ\n", FoundObject, &RemainingPath);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -1202,10 +1216,7 @@ ObInsertObject(IN PVOID Object,
|
||||||
PVOID NewName;
|
PVOID NewName;
|
||||||
PWSTR BufferPos = RemainingPath.Buffer;
|
PWSTR BufferPos = RemainingPath.Buffer;
|
||||||
ULONG Delta = 0;
|
ULONG Delta = 0;
|
||||||
|
|
||||||
ObpAddEntryDirectory(FoundObject, (PROS_OBJECT_HEADER)Header, NULL);
|
|
||||||
ObjectAttached = TRUE;
|
|
||||||
|
|
||||||
ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
|
ObjectNameInfo = HEADER_TO_OBJECT_NAME(Header);
|
||||||
|
|
||||||
if (BufferPos[0] == L'\\')
|
if (BufferPos[0] == L'\\')
|
||||||
|
@ -1219,7 +1230,8 @@ ObInsertObject(IN PVOID Object,
|
||||||
ObjectNameInfo->Name.Buffer = NewName;
|
ObjectNameInfo->Name.Buffer = NewName;
|
||||||
ObjectNameInfo->Name.Length = RemainingPath.Length - Delta;
|
ObjectNameInfo->Name.Length = RemainingPath.Length - Delta;
|
||||||
ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength - Delta;
|
ObjectNameInfo->Name.MaximumLength = RemainingPath.MaximumLength - Delta;
|
||||||
DPRINT("Name: %S\n", ObjectNameInfo->Name.Buffer);
|
ObpInsertEntryDirectory(FoundObject, &Context, (POBJECT_HEADER)Header);
|
||||||
|
ObjectAttached = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Header->Type == IoFileObjectType) ||
|
if ((Header->Type == IoFileObjectType) ||
|
||||||
|
@ -1262,7 +1274,7 @@ ObInsertObject(IN PVOID Object,
|
||||||
DPRINT("Create Failed\n");
|
DPRINT("Create Failed\n");
|
||||||
if (ObjectAttached == TRUE)
|
if (ObjectAttached == TRUE)
|
||||||
{
|
{
|
||||||
ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)Header);
|
ObpDeleteEntryDirectory(&Context);
|
||||||
}
|
}
|
||||||
if (FoundObject)
|
if (FoundObject)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,8 +26,8 @@ extern ULONG NtGlobalFlag;
|
||||||
POBJECT_TYPE ObDirectoryType = NULL;
|
POBJECT_TYPE ObDirectoryType = NULL;
|
||||||
POBJECT_TYPE ObTypeObjectType = NULL;
|
POBJECT_TYPE ObTypeObjectType = NULL;
|
||||||
|
|
||||||
PDIRECTORY_OBJECT NameSpaceRoot = NULL;
|
POBJECT_DIRECTORY NameSpaceRoot = NULL;
|
||||||
PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
|
POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
||||||
/* FIXME: Move this somewhere else once devicemap support is in */
|
/* FIXME: Move this somewhere else once devicemap support is in */
|
||||||
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
PDEVICE_MAP ObSystemDeviceMap = NULL;
|
||||||
KEVENT ObpDefaultObject;
|
KEVENT ObpDefaultObject;
|
||||||
|
@ -72,6 +72,7 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -95,7 +96,8 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
&Object,
|
&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType);
|
ObjectType,
|
||||||
|
&Context);
|
||||||
|
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
|
|
||||||
|
@ -160,6 +162,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -182,7 +185,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
&Object,
|
&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType);
|
ObjectType,
|
||||||
|
&Context);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -252,6 +256,7 @@ ObInit(VOID)
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
SECURITY_DESCRIPTOR SecurityDescriptor;
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
/* Initialize the security descriptor cache */
|
/* Initialize the security descriptor cache */
|
||||||
ObpInitSdCache();
|
ObpInitSdCache();
|
||||||
|
@ -279,11 +284,10 @@ ObInit(VOID)
|
||||||
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.OpenProcedure = ObpCreateDirectory;
|
|
||||||
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(DIRECTORY_OBJECT);
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
|
||||||
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
|
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ObDirectoryType);
|
||||||
|
|
||||||
/* Create security descriptor */
|
/* Create security descriptor */
|
||||||
|
@ -312,7 +316,7 @@ ObInit(VOID)
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(DIRECTORY_OBJECT),
|
sizeof(OBJECT_DIRECTORY),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&NameSpaceRoot);
|
(PVOID*)&NameSpaceRoot);
|
||||||
|
@ -335,7 +339,7 @@ ObInit(VOID)
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(DIRECTORY_OBJECT),
|
sizeof(OBJECT_DIRECTORY),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&ObpTypeDirectoryObject);
|
(PVOID*)&ObpTypeDirectoryObject);
|
||||||
|
@ -348,8 +352,24 @@ ObInit(VOID)
|
||||||
|
|
||||||
/* 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 */
|
||||||
ObpAddEntryDirectory(ObpTypeDirectoryObject, (PROS_OBJECT_HEADER)BODY_TO_HEADER(ObTypeObjectType), NULL);
|
Context.Directory = ObpTypeDirectoryObject;
|
||||||
ObpAddEntryDirectory(ObpTypeDirectoryObject, (PROS_OBJECT_HEADER)BODY_TO_HEADER(ObDirectoryType), NULL);
|
Context.DirectoryLocked = TRUE;
|
||||||
|
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObTypeObjectType))->Name,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
FALSE,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, (POBJECT_HEADER)BODY_TO_HEADER(ObTypeObjectType));
|
||||||
|
}
|
||||||
|
if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
&HEADER_TO_OBJECT_NAME(BODY_TO_HEADER(ObDirectoryType))->Name,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
FALSE,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, (POBJECT_HEADER)BODY_TO_HEADER(ObDirectoryType));
|
||||||
|
}
|
||||||
|
|
||||||
/* Create 'symbolic link' object type */
|
/* Create 'symbolic link' object type */
|
||||||
ObInitSymbolicLinkImplementation();
|
ObInitSymbolicLinkImplementation();
|
||||||
|
@ -471,7 +491,15 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
|
||||||
/* Insert it into the Object Directory */
|
/* Insert it into the Object Directory */
|
||||||
if (ObpTypeDirectoryObject)
|
if (ObpTypeDirectoryObject)
|
||||||
{
|
{
|
||||||
ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
Context.Directory = ObpTypeDirectoryObject;
|
||||||
|
Context.DirectoryLocked = TRUE;
|
||||||
|
ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||||
|
TypeName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
FALSE,
|
||||||
|
&Context);
|
||||||
|
ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, (POBJECT_HEADER)Header);
|
||||||
ObReferenceObject(ObpTypeDirectoryObject);
|
ObReferenceObject(ObpTypeDirectoryObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
|
||||||
IN BOOLEAN Permanent)
|
IN BOOLEAN Permanent)
|
||||||
{
|
{
|
||||||
PROS_OBJECT_HEADER ObjectHeader;
|
PROS_OBJECT_HEADER ObjectHeader;
|
||||||
|
OBP_LOOKUP_CONTEXT Context;
|
||||||
|
|
||||||
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
||||||
ASSERT (ObjectHeader->PointerCount > 0);
|
ASSERT (ObjectHeader->PointerCount > 0);
|
||||||
|
@ -49,8 +50,17 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
|
||||||
if (ObjectHeader->HandleCount == 0 &&
|
if (ObjectHeader->HandleCount == 0 &&
|
||||||
HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory)
|
HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory)
|
||||||
{
|
{
|
||||||
/* Remove the object from the namespace */
|
/* Make sure it's still inserted */
|
||||||
ObpRemoveEntryDirectory((PROS_OBJECT_HEADER)ObjectHeader);
|
Context.Directory = HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory;
|
||||||
|
Context.DirectoryLocked = TRUE;
|
||||||
|
if (ObpLookupEntryDirectory(HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory,
|
||||||
|
&HEADER_TO_OBJECT_NAME(ObjectHeader)->Name,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&Context))
|
||||||
|
{
|
||||||
|
ObpDeleteEntryDirectory(&Context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,8 @@ 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)
|
||||||
{
|
{
|
||||||
PVOID NextObject;
|
PVOID NextObject;
|
||||||
PVOID CurrentObject;
|
PVOID CurrentObject;
|
||||||
|
@ -388,7 +389,8 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
&NextObject,
|
&NextObject,
|
||||||
&PathString,
|
&PathString,
|
||||||
¤t,
|
¤t,
|
||||||
Attributes);
|
Attributes,
|
||||||
|
Context);
|
||||||
if (Status == STATUS_REPARSE)
|
if (Status == STATUS_REPARSE)
|
||||||
{
|
{
|
||||||
/* reparse the object path */
|
/* reparse the object path */
|
||||||
|
@ -442,7 +444,7 @@ ObQueryNameString(IN PVOID Object,
|
||||||
{
|
{
|
||||||
POBJECT_HEADER_NAME_INFO LocalInfo;
|
POBJECT_HEADER_NAME_INFO LocalInfo;
|
||||||
PROS_OBJECT_HEADER ObjectHeader;
|
PROS_OBJECT_HEADER ObjectHeader;
|
||||||
PDIRECTORY_OBJECT ParentDirectory;
|
POBJECT_DIRECTORY ParentDirectory;
|
||||||
ULONG NameSize;
|
ULONG NameSize;
|
||||||
PWCH ObjectName;
|
PWCH ObjectName;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
|
@ -74,7 +74,8 @@ IntWinStaObjectParse(PVOID Object,
|
||||||
PVOID *NextObject,
|
PVOID *NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR *Path,
|
PWSTR *Path,
|
||||||
ULONG Attributes);
|
ULONG Attributes,
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
IntValidateWindowStationHandle(
|
IntValidateWindowStationHandle(
|
||||||
|
|
|
@ -382,7 +382,7 @@ DriverEntry (
|
||||||
* Register Object Manager Callbacks
|
* Register Object Manager Callbacks
|
||||||
*/
|
*/
|
||||||
CalloutData.WinStaOpen = IntWinStaObjectOpen;
|
CalloutData.WinStaOpen = IntWinStaObjectOpen;
|
||||||
CalloutData.WinStaParse = IntWinStaObjectParse;
|
CalloutData.WinStaParse = (OB_ROS_PARSE_METHOD)IntWinStaObjectParse;
|
||||||
CalloutData.WinStaDelete = IntWinStaObjectDelete;
|
CalloutData.WinStaDelete = IntWinStaObjectDelete;
|
||||||
CalloutData.WinStaFind = IntWinStaObjectFind;
|
CalloutData.WinStaFind = IntWinStaObjectFind;
|
||||||
CalloutData.DesktopCreate = IntDesktopObjectCreate;
|
CalloutData.DesktopCreate = IntDesktopObjectCreate;
|
||||||
|
|
|
@ -190,7 +190,8 @@ IntWinStaObjectParse(PVOID Object,
|
||||||
PVOID *NextObject,
|
PVOID *NextObject,
|
||||||
PUNICODE_STRING FullPath,
|
PUNICODE_STRING FullPath,
|
||||||
PWSTR *Path,
|
PWSTR *Path,
|
||||||
ULONG Attributes)
|
ULONG Attributes,
|
||||||
|
PVOID Context)
|
||||||
{
|
{
|
||||||
PVOID FoundObject;
|
PVOID FoundObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
Loading…
Reference in a new issue