Author: ion
Date: Mon May 29 07:32:43 2006
New Revision: 22100
URL:
http://svn.reactos.ru/svn/reactos?rev=22100&view=rev
Log:
- Object Manager Improvements (3 of 3):
* Implement Per-Processor Lookaside List based allocation and de-allocation of the
Object Create Information (object attributes capture) and of the object name. I counted
over 4000 allocations for only 30 seconds of runtime, so this change greatly reduces pool
fragmentation and increases speed. (Implementation is similar to the IRP lookaside list
implementation, but inlined for speed).
* Fix some cases where we weren't freeing captured information properly. This patch
should also decrease memory leaks/usage.
* Comment/formatting fixes.
Modified:
trunk/reactos/include/ddk/winddk.h
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/registry.c
trunk/reactos/ntoskrnl/ex/init.c
trunk/reactos/ntoskrnl/include/internal/ob.h
trunk/reactos/ntoskrnl/io/file.c
trunk/reactos/ntoskrnl/ob/obhandle.c
trunk/reactos/ntoskrnl/ob/obinit.c
trunk/reactos/ntoskrnl/ob/oblife.c
trunk/reactos/ntoskrnl/ob/obref.c
Modified: trunk/reactos/include/ddk/winddk.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=22…
==============================================================================
--- trunk/reactos/include/ddk/winddk.h (original)
+++ trunk/reactos/include/ddk/winddk.h Mon May 29 07:32:43 2006
@@ -6168,6 +6168,17 @@
((STRING)->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR) \
)
+FORCEINLINE
+VOID
+RtlInitEmptyUnicodeString(OUT PUNICODE_STRING UnicodeString,
+ IN PWSTR Buffer,
+ IN USHORT BufferSize)
+{
+ UnicodeString->Length = 0;
+ UnicodeString->MaximumLength = BufferSize;
+ UnicodeString->Buffer = Buffer;
+}
+
NTOSAPI
NTSTATUS
DDKAPI
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon May 29 07:32:43 2006
@@ -241,7 +241,7 @@
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes,
PreviousMode,
- CmiKeyType,
+ FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
@@ -471,7 +471,7 @@
ReleaseCapturedUnicodeString(&CapturedClass,
PreviousMode);
}
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath);
if (Object != NULL) ObDereferenceObject(Object);
@@ -1305,7 +1305,7 @@
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes,
PreviousMode,
- CmiKeyType,
+ FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
@@ -1320,7 +1320,7 @@
if (!NT_SUCCESS(Status))
{
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
return Status;
}
@@ -1372,7 +1372,7 @@
PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL;
PostOpenKeyInfo.Status = Status;
CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
if (Object)
{
Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Mon May 29 07:32:43 2006
@@ -712,7 +712,7 @@
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(KeyObjectAttributes,
KernelMode,
- CmiKeyType,
+ FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
@@ -729,7 +729,7 @@
NULL,
NULL);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
if (!NT_SUCCESS(Status))
{
return Status;
Modified: trunk/reactos/ntoskrnl/ex/init.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=2210…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/init.c (original)
+++ trunk/reactos/ntoskrnl/ex/init.c Mon May 29 07:32:43 2006
@@ -514,6 +514,9 @@
/* Check if the structures match the ASM offset constants */
ExecuteRuntimeAsserts();
+ /* Set 1 CPU for now, we'll increment this later */
+ KeNumberProcessors = 1;
+
/* Sets up the Text Sections of the Kernel and HAL for debugging */
LdrInit1();
@@ -554,21 +557,18 @@
/* Load basic Security for other Managers */
if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+ /* Initialize Lookaside Lists */
+ ExpInitLookasideLists();
+
/* Create the Basic Object Manager Types to allow new Object Types */
ObInit();
- /* Initialize Lookaside Lists */
- ExpInitLookasideLists();
-
/* Set up Region Maps, Sections and the Paging File */
MmInit2();
/* Initialize Tokens now that the Object Manager is ready */
if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
- /* Set 1 CPU for now, we'll increment this later */
- KeNumberProcessors = 1;
-
/* Initalize the Process Manager */
PiInitProcessManager();
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ob.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon May 29 07:32:43 2006
@@ -32,6 +32,7 @@
extern PHANDLE_TABLE ObpKernelHandleTable;
extern WORK_QUEUE_ITEM ObpReaperWorkItem;
extern volatile PVOID ObpReaperList;
+extern NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
BOOLEAN
NTAPI
@@ -221,14 +222,15 @@
PVOID Object
);
-/* Secure object information functions */
+/* Object Create and Object Name Capture Functions */
NTSTATUS
STDCALL
ObpCaptureObjectName(
IN PUNICODE_STRING CapturedName,
IN PUNICODE_STRING ObjectName,
- IN KPROCESSOR_MODE AccessMode
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN AllocateFromLookaside
);
NTSTATUS
@@ -236,17 +238,124 @@
ObpCaptureObjectAttributes(
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN KPROCESSOR_MODE AccessMode,
- IN POBJECT_TYPE ObjectType,
+ IN BOOLEAN AllocateFromLookaside,
IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
OUT PUNICODE_STRING ObjectName
);
VOID
-STDCALL
-ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo);
-
-/* object information classes */
-
-
+static __inline
+ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
+{
+ /* Check if we have a security descriptor */
+ if (ObjectCreateInfo->SecurityDescriptor)
+ {
+ /* Release it */
+ SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
+ ObjectCreateInfo->ProbeMode,
+ TRUE);
+ ObjectCreateInfo->SecurityDescriptor = NULL;
+ }
+}
+
+PVOID
+static __inline
+ObpAllocateCapturedAttributes(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PVOID Buffer;
+ PNPAGED_LOOKASIDE_LIST List;
+
+ /* Get the P list first */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
+
+ /* Attempt allocation */
+ List->L.TotalAllocates++;
+ Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+ if (!Buffer)
+ {
+ /* Let the balancer know that the P list failed */
+ List->L.AllocateMisses++;
+
+ /* Try the L List */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
+ List->L.TotalAllocates++;
+ Buffer = (PVOID)InterlockedPopEntrySList(&List->L.ListHead);
+ if (!Buffer)
+ {
+ /* Let the balancer know the L list failed too */
+ List->L.AllocateMisses++;
+
+ /* Allocate it */
+ Buffer = List->L.Allocate(List->L.Type, List->L.Size,
List->L.Tag);
+ }
+ }
+
+ /* Return buffer */
+ return Buffer;
+}
+
+VOID
+static __inline
+ObpFreeCapturedAttributes(IN PVOID Buffer,
+ IN PP_NPAGED_LOOKASIDE_NUMBER Type)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PNPAGED_LOOKASIDE_LIST List;
+
+ /* Use the P List */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].P;
+ List->L.TotalFrees++;
+
+ /* Check if the Free was within the Depth or not */
+ if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
+ {
+ /* Let the balancer know */
+ List->L.FreeMisses++;
+
+ /* Use the L List */
+ List = (PNPAGED_LOOKASIDE_LIST)Prcb->PPLookasideList[Type].L;
+ List->L.TotalFrees++;
+
+ /* Check if the Free was within the Depth or not */
+ if (ExQueryDepthSList(&List->L.ListHead) >= List->L.Depth)
+ {
+ /* All lists failed, use the pool */
+ List->L.FreeMisses++;
+ List->L.Free(Buffer);
+ }
+ }
+ else
+ {
+ /* The free was within the Depth */
+ InterlockedPushEntrySList(&List->L.ListHead,
+ (PSINGLE_LIST_ENTRY)Buffer);
+ }
+}
+
+VOID
+static __inline
+ObpReleaseCapturedName(IN PUNICODE_STRING Name)
+{
+ /* We know this is a pool-allocation if the size doesn't match */
+ if (Name->MaximumLength != 248)
+ {
+ ExFreePool(Name->Buffer);
+ }
+ else
+ {
+ /* Otherwise, free from the lookaside */
+ ObpFreeCapturedAttributes(Name, LookasideNameBufferList);
+ }
+}
+
+VOID
+static __inline
+ObpFreeAndReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
+{
+ /* First release the attributes, then free them from the lookaside list */
+ ObpReleaseCapturedAttributes(ObjectCreateInfo);
+ ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList);
+}
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
Modified: trunk/reactos/ntoskrnl/io/file.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/io/file.c?rev=2210…
==============================================================================
--- trunk/reactos/ntoskrnl/io/file.c (original)
+++ trunk/reactos/ntoskrnl/io/file.c Mon May 29 07:32:43 2006
@@ -962,7 +962,7 @@
Status = ObpCaptureObjectAttributes(ObjectAttributes,
AccessMode,
- NULL,
+ FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
@@ -977,7 +977,7 @@
0,
NULL);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
/* FIXME: wt... */
@@ -2415,7 +2415,7 @@
{
Status = ObpCaptureObjectAttributes(ObjectAttributes,
AccessMode,
- NULL,
+ FALSE,
&ObjectCreateInfo,
&ObjectName);
}
@@ -2440,7 +2440,7 @@
if (AccessMode != KernelMode)
{
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
}
if (!NT_SUCCESS (Status))
{
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obhandle.c (original)
+++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon May 29 07:32:43 2006
@@ -767,7 +767,7 @@
/* Capture all the info */
Status = ObpCaptureObjectAttributes(ObjectAttributes,
AccessMode,
- ObjectType,
+ TRUE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status)) return Status;
@@ -828,7 +828,7 @@
/* Release the object attributes and return status */
Quickie:
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
return Status;
}
@@ -1054,8 +1054,7 @@
/* We can delete the Create Info now */
Header->ObjectCreateInfo = NULL;
- ObpReleaseCapturedAttributes(ObjectCreateInfo);
- ExFreePool(ObjectCreateInfo);
+ ObpFreeAndReleaseCapturedAttributes(ObjectCreateInfo);
DPRINT("Status %x\n", Status);
return Status;
Modified: trunk/reactos/ntoskrnl/ob/obinit.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obinit.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obinit.c (original)
+++ trunk/reactos/ntoskrnl/ob/obinit.c Mon May 29 07:32:43 2006
@@ -43,6 +43,90 @@
VOID
INIT_FUNCTION
+ObInit2(VOID)
+{
+ ULONG i;
+ PKPRCB Prcb;
+ PNPAGED_LOOKASIDE_LIST CurrentList = NULL;
+
+ /* Initialize the OBJECT_CREATE_INFORMATION List */
+ ExInitializeNPagedLookasideList(&ObpCiLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(OBJECT_CREATE_INFORMATION),
+ TAG('O', 'b', 'C',
'I'),
+ 32);
+
+ /* Set the captured UNICODE_STRING Object Name List */
+ ExInitializeNPagedLookasideList(&ObpNmLookasideList,
+ NULL,
+ NULL,
+ 0,
+ 248,
+ TAG('O', 'b', 'N',
'M'),
+ 16);
+
+ /* Now allocate the per-processor lists */
+ for (i = 0; i < KeNumberProcessors; i++)
+ {
+ /* Get the PRCB for this CPU */
+ Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
+
+ /* Set the OBJECT_CREATE_INFORMATION List */
+ Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCiLookasideList.L;
+ CurrentList = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(NPAGED_LOOKASIDE_LIST),
+ TAG('O', 'b', 'C',
'I'));
+ if (CurrentList)
+ {
+ /* Initialize it */
+ ExInitializeNPagedLookasideList(CurrentList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(OBJECT_CREATE_INFORMATION),
+ TAG('O', 'b', 'C',
'I'),
+ 32);
+ }
+ else
+ {
+ /* No list, use the static buffer */
+ CurrentList = &ObpCiLookasideList;
+ }
+
+ /* Link it */
+ Prcb->PPLookasideList[LookasideCreateInfoList].P = &CurrentList->L;
+
+ /* Set the captured UNICODE_STRING Object Name List */
+ Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNmLookasideList.L;
+ CurrentList = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(NPAGED_LOOKASIDE_LIST),
+ TAG('O', 'b', 'N',
'M'));
+ if (CurrentList)
+ {
+ /* Initialize it */
+ ExInitializeNPagedLookasideList(CurrentList,
+ NULL,
+ NULL,
+ 0,
+ 248,
+ TAG('O', 'b', 'N',
'M'),
+ 16);
+ }
+ else
+ {
+ /* No list, use the static buffer */
+ CurrentList = &ObpNmLookasideList;
+ }
+
+ /* Link it */
+ Prcb->PPLookasideList[LookasideNameBufferList].P = &CurrentList->L;
+ }
+}
+
+VOID
+INIT_FUNCTION
ObInit(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -59,6 +143,9 @@
/* Setup the Object Reaper */
ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
+
+ /* Initialize lookaside lists */
+ ObInit2();
/* Create the Type Type */
DPRINT("Creating Type Type\n");
@@ -72,7 +159,7 @@
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));
Modified: trunk/reactos/ntoskrnl/ob/oblife.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=22…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/oblife.c (original)
+++ trunk/reactos/ntoskrnl/ob/oblife.c Mon May 29 07:32:43 2006
@@ -21,6 +21,9 @@
POBJECT_TYPE ObTypeObjectType = NULL;
KEVENT ObpDefaultObject;
+
+NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
+
WORK_QUEUE_ITEM ObpReaperWorkItem;
volatile PVOID ObpReaperList;
@@ -64,7 +67,7 @@
if (Header->ObjectCreateInfo)
{
/* Free it */
- ObpReleaseCapturedAttributes(Header->ObjectCreateInfo);
+ ObpFreeAndReleaseCapturedAttributes(Header->ObjectCreateInfo);
Header->ObjectCreateInfo = NULL;
}
}
@@ -178,31 +181,30 @@
}
NTSTATUS
-STDCALL
+NTAPI
ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
IN PUNICODE_STRING ObjectName,
- IN KPROCESSOR_MODE AccessMode)
+ IN KPROCESSOR_MODE AccessMode,
+ IN BOOLEAN AllocateFromLookaside)
{
NTSTATUS Status = STATUS_SUCCESS;
- ULONG StringLength;
+ ULONG StringLength, MaximumLength;
PWCHAR StringBuffer = NULL;
UNICODE_STRING LocalName = {}; /* <= GCC 4.0 + Optimizer */
-
+ PAGED_CODE();
+
/* Initialize the Input String */
- RtlInitUnicodeString(CapturedName, NULL);
+ RtlInitEmptyUnicodeString(CapturedName, NULL, 0);
/* Protect everything */
_SEH_TRY
{
- /* First Probe the String */
- DPRINT("ObpCaptureObjectName: %wZ\n", ObjectName);
+ /* Check if we came from user mode */
if (AccessMode != KernelMode)
{
- ProbeForRead(ObjectName,
- sizeof(UNICODE_STRING),
- sizeof(USHORT));
+ /* First Probe the String */
+ ProbeForReadUnicodeString(ObjectName);
LocalName = *ObjectName;
-
ProbeForRead(LocalName.Buffer,
LocalName.Length,
sizeof(WCHAR));
@@ -214,13 +216,12 @@
}
/* Make sure there really is a string */
- DPRINT("Probing OK\n");
if ((StringLength = LocalName.Length))
{
/* Check that the size is a valid WCHAR multiple */
if ((StringLength & (sizeof(WCHAR) - 1)) ||
/* Check that the NULL-termination below will work */
- (StringLength == (MAXUSHORT - sizeof(WCHAR) + 1)))
+ (StringLength == (MAXUSHORT - sizeof(UNICODE_NULL) + 1)))
{
/* PS: Please keep the checks above expanded for clarity */
DPRINT1("Invalid String Length\n");
@@ -228,19 +229,36 @@
}
else
{
- /* Allocate a non-paged buffer for this string */
- DPRINT("Capturing String\n");
+ /* Set the maximum length to the length plus the terminator */
+ MaximumLength = StringLength + sizeof(UNICODE_NULL);
+
+ /* Check if we should use the lookaside buffer */
+ //if (!(AllocateFromLookaside) || (MaximumLength > 248))
+ {
+ /* Nope, allocate directly from pool */
+ StringBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ MaximumLength,
+ OB_NAME_TAG);
+ }
+ //else
+ {
+ /* Allocate from the lookaside */
+ // MaximumLength = 248;
+ // StringBuffer =
+ // ObpAllocateCapturedAttributes(LookasideNameBufferList);
+ }
+
+ /* Setup the string */
CapturedName->Length = StringLength;
- CapturedName->MaximumLength = StringLength + sizeof(WCHAR);
- if ((StringBuffer = ExAllocatePoolWithTag(NonPagedPool,
- StringLength + sizeof(WCHAR),
- OB_NAME_TAG)))
- {
+ CapturedName->MaximumLength = MaximumLength;
+ CapturedName->Buffer = StringBuffer;
+
+ /* Make sure we have a buffer */
+ if (StringBuffer)
+ {
/* Copy the string and null-terminate it */
RtlMoveMemory(StringBuffer, LocalName.Buffer, StringLength);
StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
- CapturedName->Buffer = StringBuffer;
- DPRINT("String Captured: %wZ\n", CapturedName);
}
else
{
@@ -254,23 +272,19 @@
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
Status = _SEH_GetExceptionCode();
-
- /* Remember to free the buffer in case of failure */
- DPRINT1("Failed\n");
if (StringBuffer) ExFreePool(StringBuffer);
}
_SEH_END;
-
+
/* Return */
- DPRINT("Returning: %lx\n", Status);
return Status;
}
NTSTATUS
-STDCALL
+NTAPI
ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN KPROCESSOR_MODE AccessMode,
- IN POBJECT_TYPE ObjectType,
+ IN BOOLEAN AllocateFromLookaside,
IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
OUT PUNICODE_STRING ObjectName)
{
@@ -278,90 +292,92 @@
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
PUNICODE_STRING LocalObjectName = NULL;
+ PAGED_CODE();
/* Zero out the Capture Data */
- DPRINT("ObpCaptureObjectAttributes\n");
RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
-
+
/* SEH everything here for protection */
_SEH_TRY
{
- /* Check if we got Oba */
+ /* Check if we got attributes */
if (ObjectAttributes)
{
+ /* Check if we're in user mode */
if (AccessMode != KernelMode)
{
- DPRINT("Probing OBA\n");
+ /* Probe the attributes */
ProbeForRead(ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
}
-
+
/* Validate the Size and Attributes */
- DPRINT("Validating OBA\n");
if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
(ObjectAttributes->Attributes & ~OBJ_VALID_ATTRIBUTES))
{
+ /* Invalid combination, fail */
Status = STATUS_INVALID_PARAMETER;
- DPRINT1("Invalid Size: %lx or Attributes: %lx\n",
- ObjectAttributes->Length, ObjectAttributes->Attributes);
_SEH_LEAVE;
}
-
+
/* Set some Create Info */
- DPRINT("Creating OBCI\n");
ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
ObjectCreateInfo->Attributes = ObjectAttributes->Attributes;
LocalObjectName = ObjectAttributes->ObjectName;
SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
SecurityQos = ObjectAttributes->SecurityQualityOfService;
-
- /* Validate the SD */
+
+ /* Check if we have a security descriptor */
if (SecurityDescriptor)
{
- DPRINT("Probing SD: %x\n", SecurityDescriptor);
+ /* Capture it */
Status = SeCaptureSecurityDescriptor(SecurityDescriptor,
AccessMode,
NonPagedPool,
TRUE,
-
&ObjectCreateInfo->SecurityDescriptor);
+ &ObjectCreateInfo->
+ SecurityDescriptor);
if(!NT_SUCCESS(Status))
{
- DPRINT1("Unable to capture the security descriptor!!!\n");
+ /* Capture failed, quit */
ObjectCreateInfo->SecurityDescriptor = NULL;
_SEH_LEAVE;
}
-
- DPRINT("Probe done\n");
+
+ /* Save the probe mode and security descriptor size */
ObjectCreateInfo->SecurityDescriptorCharge = 2048; /* FIXME */
ObjectCreateInfo->ProbeMode = AccessMode;
}
-
- /* Validate the QoS */
+
+ /* Check if we have QoS */
if (SecurityQos)
{
+ /* Check if we came from user mode */
if (AccessMode != KernelMode)
{
- DPRINT("Probing QoS\n");
+ /* Validate the QoS */
ProbeForRead(SecurityQos,
sizeof(SECURITY_QUALITY_OF_SERVICE),
sizeof(ULONG));
}
-
+
/* Save Info */
ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
- ObjectCreateInfo->SecurityQos =
&ObjectCreateInfo->SecurityQualityOfService;
+ ObjectCreateInfo->SecurityQos =
+ &ObjectCreateInfo->SecurityQualityOfService;
}
}
else
{
+ /* We don't have a name */
LocalObjectName = NULL;
}
}
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
{
+ /* Get the exception */
Status = _SEH_GetExceptionCode();
- DPRINT1("Failed\n");
}
_SEH_END;
@@ -370,46 +386,29 @@
/* Now check if the Object Attributes had an Object Name */
if (LocalObjectName)
{
- DPRINT("Name Buffer: %wZ\n", LocalObjectName);
Status = ObpCaptureObjectName(ObjectName,
LocalObjectName,
- AccessMode);
+ AccessMode,
+ AllocateFromLookaside);
}
else
{
/* Clear the string */
- RtlInitUnicodeString(ObjectName, NULL);
+ RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
/* He can't have specified a Root Directory */
if (ObjectCreateInfo->RootDirectory)
{
- DPRINT1("Invalid name\n");
Status = STATUS_OBJECT_NAME_INVALID;
}
}
}
- else
- {
- DPRINT1("Failed to capture, cleaning up\n");
- ObpReleaseCapturedAttributes(ObjectCreateInfo);
- }
-
- DPRINT("Return to caller %x\n", Status);
+
+ /* Cleanup if we failed */
+ if (!NT_SUCCESS(Status)) ObpReleaseCapturedAttributes(ObjectCreateInfo);
+
+ /* Return status to caller */
return Status;
-}
-
-VOID
-STDCALL
-ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
-{
- /* Release the SD, it's the only thing we allocated */
- if (ObjectCreateInfo->SecurityDescriptor)
- {
- SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
- ObjectCreateInfo->ProbeMode,
- TRUE);
- ObjectCreateInfo->SecurityDescriptor = NULL;
- }
}
NTSTATUS
@@ -688,20 +687,17 @@
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
UNICODE_STRING ObjectName;
POBJECT_HEADER Header;
-
DPRINT("ObCreateObject(Type %p ObjectAttributes %p, Object %p)\n",
Type, ObjectAttributes, Object);
- /* Allocate a Buffer for the Object Create Info */
- ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(*ObjectCreateInfo),
- TAG('O','b','C',
'I'));
+ /* Allocate a capture buffer */
+ ObjectCreateInfo = ObpAllocateCapturedAttributes(LookasideCreateInfoList);
if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
/* Capture all the info */
Status = ObpCaptureObjectAttributes(ObjectAttributes,
ObjectAttributesAccessMode,
- Type,
+ FALSE,
ObjectCreateInfo,
&ObjectName);
if (NT_SUCCESS(Status))
@@ -730,32 +726,32 @@
{
/* Return the Object */
*Object = &Header->Body;
-
- /* Check if this is a permanent object */
- if (Header->Flags & OB_FLAG_PERMANENT)
+
+ /* Check if this is a permanent object */
+ if (Header->Flags & OB_FLAG_PERMANENT)
+ {
+ /* Do the privilege check */
+ if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
+ ObjectAttributesAccessMode))
{
- /* Do the privilege check */
- if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
- ObjectAttributesAccessMode))
- {
- /* Fail */
- ObpDeallocateObject(*Object);
- Status = STATUS_PRIVILEGE_NOT_HELD;
- }
+ /* Fail */
+ ObpDeallocateObject(*Object);
+ Status = STATUS_PRIVILEGE_NOT_HELD;
}
-
- /* Return status */
+ }
+
+ /* Return status */
return Status;
}
}
/* Release the Capture Info, we don't need it */
ObpReleaseCapturedAttributes(ObjectCreateInfo);
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
}
/* We failed, so release the Buffer */
- ExFreePool(ObjectCreateInfo);
+ ObpFreeCapturedAttributes(ObjectCreateInfo, LookasideCreateInfoList);
return Status;
}
Modified: trunk/reactos/ntoskrnl/ob/obref.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/ob/obref.c?rev=221…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obref.c (original)
+++ trunk/reactos/ntoskrnl/ob/obref.c Mon May 29 07:32:43 2006
@@ -216,7 +216,7 @@
ACCESS_STATE AccessState;
/* Capture the name */
- Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode);
+ Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* Check if we didn't get an access state */
@@ -264,7 +264,7 @@
Quickie:
/* Free the captured name if we had one, and return status */
- if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
+ if (ObjectName.Buffer) ObpReleaseCapturedName(&ObjectName);
return Status;
}