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=22... ============================================================================== --- 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=22287... ============================================================================== --- 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=2228... ============================================================================== --- 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=2... ============================================================================== --- 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 {