Author: ion
Date: Fri Jun 9 00:58:21 2006
New Revision: 22287
URL:
http://svn.reactos.ru/svn/reactos?rev=22287&view=rev
Log:
- Add Object Header Quota structure/define
- Give Files/Devices a parse routine and currently stubplement it for debugging purposes
and trying to figure out a way to kill the IopCreateFile hack.
- Implement ObpChargeQuotaForObject. Using a memory breakpoint in WinDBG I've finally
found where the OB_FLAG_CREATE_INFO flag gets masked out. Also attempted a very naive
quota charging implementation, but it's a guess and probably wrong (but at least it
does...something.)
Modified:
trunk/reactos/include/ndk/obtypes.h
trunk/reactos/ntoskrnl/io/file.c
trunk/reactos/ntoskrnl/io/iomgr.c
trunk/reactos/ntoskrnl/ob/obhandle.c
Modified: trunk/reactos/include/ndk/obtypes.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ndk/obtypes.h?rev=2…
==============================================================================
--- trunk/reactos/include/ndk/obtypes.h (original)
+++ trunk/reactos/include/ndk/obtypes.h Fri Jun 9 00:58:21 2006
@@ -97,6 +97,10 @@
#define OBJECT_HEADER_TO_HANDLE_INFO(h) \
((POBJECT_HEADER_HANDLE_INFO)(!(h)->HandleInfoOffset ? \
NULL: ((PCHAR)(h) - (h)->HandleInfoOffset)))
+
+#define OBJECT_HEADER_TO_QUOTA_INFO(h) \
+ ((POBJECT_HEADER_QUOTA_INFO)(!(h)->QuotaInfoOffset ? \
+ NULL: ((PCHAR)(h) - (h)->QuotaInfoOffset)))
#define OBJECT_HEADER_TO_CREATOR_INFO(h) \
((POBJECT_HEADER_CREATOR_INFO)(!((h)->Flags & \
@@ -409,6 +413,14 @@
USHORT Reserved;
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
+typedef struct _OBJECT_HEADER_QUOTA_INFO
+{
+ ULONG PagedPoolCharge;
+ ULONG NonPagedPoolCharge;
+ ULONG SecurityDescriptorCharge;
+ PEPROCESS ExclusiveProcess;
+} OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;
+
//
// Object Header
//
Modified: trunk/reactos/ntoskrnl/io/file.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/io/file.c?rev=2228…
==============================================================================
--- trunk/reactos/ntoskrnl/io/file.c (original)
+++ trunk/reactos/ntoskrnl/io/file.c Fri Jun 9 00:58:21 2006
@@ -25,6 +25,86 @@
PULONG BufferLength);
/* INTERNAL FUNCTIONS ********************************************************/
+
+NTSTATUS
+NTAPI
+IopParseDevice(IN PVOID ParseObject,
+ IN POBJECT_TYPE ObjectType,
+ IN OUT PACCESS_STATE AccessState,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG Attributes,
+ IN OUT PUNICODE_STRING CompleteName,
+ IN OUT PUNICODE_STRING RemainingName,
+ IN OUT PVOID Context OPTIONAL,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
+ OUT PVOID *Object)
+{
+ DPRINT("IopParseDevice:\n"
+ "DeviceObject : %p, Type : %p, TypeName : %wZ\n"
+ "FileObject : %p, Type : %p, TypeName : %wZ\n"
+ "CompleteName : %wZ, RemainingName : %wZ\n",
+ ParseObject,
+ ObjectType,
+ &ObjectType->Name,
+ Context,
+ Context ? OBJECT_TO_OBJECT_HEADER(Context)->Type : NULL,
+ Context ? &OBJECT_TO_OBJECT_HEADER(Context)->Type->Name: NULL,
+ CompleteName,
+ RemainingName);
+
+ /*
+ * Just clear the object and return success, and ObFindObject will behave
+ * just as if we had no parse procedure, so we can debug in peace.
+ */
+ *Object = NULL;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IopParseFile(IN PVOID ParseObject,
+ IN POBJECT_TYPE ObjectType,
+ IN OUT PACCESS_STATE AccessState,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG Attributes,
+ IN OUT PUNICODE_STRING CompleteName,
+ IN OUT PUNICODE_STRING RemainingName,
+ IN OUT PVOID Context OPTIONAL,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
+ OUT PVOID *Object)
+{
+ PVOID DeviceObject;
+
+ /* Get the device object */
+ DeviceObject = IoGetRelatedDeviceObject(ParseObject);
+ Context = ParseObject;
+
+ DPRINT("IopParseFile:\n"
+ "DeviceObject : %p, Type : %p, TypeName : %wZ\n"
+ "FileObject : %p, Type : %p, TypeName : %wZ\n"
+ "CompleteName : %wZ, RemainingName : %wZ\n",
+ DeviceObject,
+ OBJECT_TO_OBJECT_HEADER(DeviceObject)->Type,
+ &OBJECT_TO_OBJECT_HEADER(DeviceObject)->Type->Name,
+ ParseObject,
+ ObjectType,
+ &ObjectType->Name,
+ CompleteName,
+ RemainingName);
+
+ /* Call the main routine */
+ return IopParseDevice(DeviceObject,
+ ObjectType,
+ AccessState,
+ AccessMode,
+ Attributes,
+ CompleteName,
+ RemainingName,
+ Context,
+ SecurityQos,
+ Object);
+
+}
/*
* NAME INTERNAL
Modified: trunk/reactos/ntoskrnl/io/iomgr.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr.c?rev=222…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr.c Fri Jun 9 00:58:21 2006
@@ -51,7 +51,31 @@
#pragma alloc_text(INIT, IoInit3)
#endif
-
+NTSTATUS
+NTAPI
+IopParseFile(IN PVOID ParseObject,
+ IN PVOID ObjectType,
+ IN OUT PACCESS_STATE AccessState,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG Attributes,
+ IN OUT PUNICODE_STRING CompleteName,
+ IN OUT PUNICODE_STRING RemainingName,
+ IN OUT PVOID Context OPTIONAL,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
+ OUT PVOID *Object);
+
+NTSTATUS
+NTAPI
+IopParseDevice(IN PVOID ParseObject,
+ IN PVOID ObjectType,
+ IN OUT PACCESS_STATE AccessState,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG Attributes,
+ IN OUT PUNICODE_STRING CompleteName,
+ IN OUT PUNICODE_STRING RemainingName,
+ IN OUT PVOID Context OPTIONAL,
+ IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
+ OUT PVOID *Object);
/* INIT FUNCTIONS ************************************************************/
VOID
@@ -210,6 +234,7 @@
ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.GenericMapping = IopFileMapping;
+ ObjectTypeInitializer.ParseProcedure = IopParseDevice;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL,
&IoDeviceObjectType);
/* Do the Adapter Type */
@@ -229,6 +254,7 @@
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
+ ObjectTypeInitializer.ParseProcedure = IopParseFile;
ObjectTypeInitializer.UseDefaultObject = FALSE;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL,
&IoFileObjectType);
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 Fri Jun 9 00:58:21 2006
@@ -27,6 +27,50 @@
/* PRIVATE FUNCTIONS *********************************************************/
+NTSTATUS
+NTAPI
+ObpChargeQuotaForObject(IN POBJECT_HEADER ObjectHeader,
+ IN POBJECT_TYPE ObjectType)
+{
+ POBJECT_HEADER_QUOTA_INFO ObjectQuota;
+ ULONG PagedPoolCharge, NonPagedPoolCharge;
+ PEPROCESS Process;
+
+ /* Get quota information */
+ ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
+
+ /* Check if this is a new object */
+ if (ObjectHeader->Flags & OB_FLAG_CREATE_INFO)
+ {
+ /* Remove the flag */
+ ObjectHeader->Flags &= ~ OB_FLAG_CREATE_INFO;
+ if (ObjectQuota)
+ {
+ /* We have a quota, get the charges */
+ PagedPoolCharge = ObjectQuota->PagedPoolCharge;
+ NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
+ }
+ else
+ {
+ /* Get it from the object type */
+ PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
+ NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
+ }
+
+ /*
+ * Charge the quota
+ * FIXME: This is a *COMPLETE* guess and probably defintely not the way to do
this.
+ */
+ Process = PsGetCurrentProcess();
+ Process->QuotaBlock->QuotaEntry[PagedPool].Usage += PagedPoolCharge;
+ Process->QuotaBlock->QuotaEntry[NonPagedPool].Usage += NonPagedPoolCharge;
+ ObjectHeader->QuotaBlockCharged = Process->QuotaBlock;
+ }
+
+ /* Return success */
+ return STATUS_SUCCESS;
+}
+
/*++
* @name ObpDecrementHandleCount
*
@@ -247,6 +291,7 @@
POBJECT_HEADER ObjectHeader;
POBJECT_TYPE ObjectType;
ULONG ProcessHandleCount;
+ NTSTATUS Status;
/* Get the object header and type */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
@@ -257,6 +302,10 @@
OpenReason,
ObjectHeader->HandleCount,
ObjectHeader->PointerCount);
+
+ /* Charge quota and remove the creator info flag */
+ Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType);
+ if (!NT_SUCCESS(Status)) return Status;
/* Check if we're opening an existing handle */
if (OpenReason == ObOpenHandle)
@@ -1151,6 +1200,14 @@
{
/* Then we are creating a new handle */
OpenReason = ObCreateHandle;
+
+ /* Check if we still have create info */
+ if (ObjectHeader->ObjectCreateInfo)
+ {
+ /* Free it */
+ //ObpFreeAndReleaseCapturedAttributes(&ObjectCreateInfo);
+ //ObjectHeader->ObjectCreateInfo = NULL;
+ }
}
else
{