mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
- 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:
parent
1c378756d0
commit
d7c17c883d
4 changed files with 175 additions and 0 deletions
|
@ -98,6 +98,10 @@ Author:
|
||||||
((POBJECT_HEADER_HANDLE_INFO)(!(h)->HandleInfoOffset ? \
|
((POBJECT_HEADER_HANDLE_INFO)(!(h)->HandleInfoOffset ? \
|
||||||
NULL: ((PCHAR)(h) - (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) \
|
#define OBJECT_HEADER_TO_CREATOR_INFO(h) \
|
||||||
((POBJECT_HEADER_CREATOR_INFO)(!((h)->Flags & \
|
((POBJECT_HEADER_CREATOR_INFO)(!((h)->Flags & \
|
||||||
OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(h) - \
|
OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(h) - \
|
||||||
|
@ -409,6 +413,14 @@ typedef struct _OBJECT_HEADER_CREATOR_INFO
|
||||||
USHORT Reserved;
|
USHORT Reserved;
|
||||||
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
|
} 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
|
// Object Header
|
||||||
//
|
//
|
||||||
|
|
|
@ -26,6 +26,86 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
||||||
|
|
||||||
/* INTERNAL FUNCTIONS ********************************************************/
|
/* 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
|
* NAME INTERNAL
|
||||||
* IopCreateFile
|
* IopCreateFile
|
||||||
|
|
|
@ -51,7 +51,31 @@ VOID INIT_FUNCTION IopInitLookasideLists(VOID);
|
||||||
#pragma alloc_text(INIT, IoInit3)
|
#pragma alloc_text(INIT, IoInit3)
|
||||||
#endif
|
#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 ************************************************************/
|
/* INIT FUNCTIONS ************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -210,6 +234,7 @@ IoInit (VOID)
|
||||||
ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
|
ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
|
||||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
||||||
ObjectTypeInitializer.GenericMapping = IopFileMapping;
|
ObjectTypeInitializer.GenericMapping = IopFileMapping;
|
||||||
|
ObjectTypeInitializer.ParseProcedure = IopParseDevice;
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoDeviceObjectType);
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoDeviceObjectType);
|
||||||
|
|
||||||
/* Do the Adapter Type */
|
/* Do the Adapter Type */
|
||||||
|
@ -229,6 +254,7 @@ IoInit (VOID)
|
||||||
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
|
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
|
||||||
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
|
ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
|
||||||
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
|
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
|
||||||
|
ObjectTypeInitializer.ParseProcedure = IopParseFile;
|
||||||
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
||||||
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoFileObjectType);
|
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoFileObjectType);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,50 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* 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
|
* @name ObpDecrementHandleCount
|
||||||
*
|
*
|
||||||
|
@ -247,6 +291,7 @@ ObpIncrementHandleCount(IN PVOID Object,
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
POBJECT_TYPE ObjectType;
|
POBJECT_TYPE ObjectType;
|
||||||
ULONG ProcessHandleCount;
|
ULONG ProcessHandleCount;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Get the object header and type */
|
/* Get the object header and type */
|
||||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
||||||
|
@ -258,6 +303,10 @@ ObpIncrementHandleCount(IN PVOID Object,
|
||||||
ObjectHeader->HandleCount,
|
ObjectHeader->HandleCount,
|
||||||
ObjectHeader->PointerCount);
|
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 */
|
/* Check if we're opening an existing handle */
|
||||||
if (OpenReason == ObOpenHandle)
|
if (OpenReason == ObOpenHandle)
|
||||||
{
|
{
|
||||||
|
@ -1151,6 +1200,14 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
{
|
{
|
||||||
/* Then we are creating a new handle */
|
/* Then we are creating a new handle */
|
||||||
OpenReason = ObCreateHandle;
|
OpenReason = ObCreateHandle;
|
||||||
|
|
||||||
|
/* Check if we still have create info */
|
||||||
|
if (ObjectHeader->ObjectCreateInfo)
|
||||||
|
{
|
||||||
|
/* Free it */
|
||||||
|
//ObpFreeAndReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
|
//ObjectHeader->ObjectCreateInfo = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue