- 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.)

svn path=/trunk/; revision=22287
This commit is contained in:
Alex Ionescu 2006-06-08 20:58:21 +00:00
parent 1c378756d0
commit d7c17c883d
4 changed files with 175 additions and 0 deletions

View file

@ -98,6 +98,10 @@ Author:
((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 & \
OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(h) - \
@ -409,6 +413,14 @@ typedef struct _OBJECT_HEADER_CREATOR_INFO
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
//

View file

@ -26,6 +26,86 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
/* 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
* IopCreateFile

View file

@ -51,7 +51,31 @@ VOID INIT_FUNCTION IopInitLookasideLists(VOID);
#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 @@ IoInit (VOID)
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 @@ IoInit (VOID)
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
ObjectTypeInitializer.ParseProcedure = IopParseFile;
ObjectTypeInitializer.UseDefaultObject = FALSE;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoFileObjectType);

View file

@ -27,6 +27,50 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL;
/* 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 @@ ObpIncrementHandleCount(IN PVOID Object,
POBJECT_HEADER ObjectHeader;
POBJECT_TYPE ObjectType;
ULONG ProcessHandleCount;
NTSTATUS Status;
/* Get the object header and type */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
@ -258,6 +303,10 @@ ObpIncrementHandleCount(IN PVOID Object,
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 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
{
/* 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
{