mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
749 lines
24 KiB
749 lines
24 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
obquery.c
|
|
|
|
Abstract:
|
|
|
|
Query Object system service
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 12-May-1989
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "obp.h"
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
#pragma alloc_text(PAGE,NtQueryObject)
|
|
#pragma alloc_text(PAGE,ObQueryNameString)
|
|
#pragma alloc_text(PAGE,ObQueryTypeName)
|
|
#pragma alloc_text(PAGE,ObQueryTypeInfo)
|
|
#pragma alloc_text(PAGE,ObQueryObjectAuditingByHandle)
|
|
#pragma alloc_text(PAGE,NtSetInformationObject)
|
|
#endif
|
|
|
|
NTSTATUS
|
|
NtQueryObject(
|
|
IN HANDLE Handle,
|
|
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
|
OUT PVOID ObjectInformation,
|
|
IN ULONG ObjectInformationLength,
|
|
OUT PULONG ReturnLength OPTIONAL
|
|
)
|
|
{
|
|
KPROCESSOR_MODE PreviousMode;
|
|
NTSTATUS Status;
|
|
PVOID Object;
|
|
POBJECT_HEADER ObjectHeader;
|
|
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
|
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
|
POBJECT_TYPE ObjectType;
|
|
POBJECT_HEADER ObjectDirectoryHeader;
|
|
POBJECT_DIRECTORY ObjectDirectory;
|
|
ACCESS_MASK GrantedAccess;
|
|
POBJECT_HANDLE_FLAG_INFORMATION HandleFlags;
|
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
|
ULONG NameInfoSize;
|
|
ULONG SecurityDescriptorSize;
|
|
ULONG TempReturnLength;
|
|
OBJECT_BASIC_INFORMATION ObjectBasicInfo;
|
|
POBJECT_TYPES_INFORMATION TypesInformation;
|
|
POBJECT_TYPE_INFORMATION TypeInfo;
|
|
ULONG i, TypesInfoSize;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Get previous processor mode and probe output argument if necessary.
|
|
//
|
|
|
|
PreviousMode = KeGetPreviousMode();
|
|
if (PreviousMode != KernelMode) {
|
|
try {
|
|
if ( ObjectInformationClass != ObjectHandleFlagInformation ) {
|
|
ProbeForWrite( ObjectInformation,
|
|
ObjectInformationLength,
|
|
sizeof( ULONG )
|
|
);
|
|
}
|
|
else {
|
|
ProbeForWrite( ObjectInformation,
|
|
ObjectInformationLength,
|
|
1
|
|
);
|
|
}
|
|
|
|
if (ARGUMENT_PRESENT( ReturnLength )) {
|
|
ProbeForWriteUlong( ReturnLength );
|
|
*ReturnLength = 0;
|
|
}
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
return( GetExceptionCode() );
|
|
}
|
|
}
|
|
|
|
if (ObjectInformationClass != ObjectTypesInformation) {
|
|
Status = ObReferenceObjectByHandle( Handle,
|
|
0,
|
|
NULL,
|
|
PreviousMode,
|
|
&Object,
|
|
&HandleInformation
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return( Status );
|
|
}
|
|
|
|
GrantedAccess = HandleInformation.GrantedAccess;
|
|
|
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
|
|
ObjectType = ObjectHeader->Type;
|
|
}
|
|
else {
|
|
GrantedAccess = 0;
|
|
Object = NULL;
|
|
ObjectHeader = NULL;
|
|
ObjectType = NULL;
|
|
}
|
|
|
|
switch( ObjectInformationClass ) {
|
|
case ObjectBasicInformation:
|
|
if (ObjectInformationLength != sizeof( OBJECT_BASIC_INFORMATION )) {
|
|
ObDereferenceObject( Object );
|
|
return( STATUS_INFO_LENGTH_MISMATCH );
|
|
}
|
|
|
|
ObjectBasicInfo.Attributes = HandleInformation.HandleAttributes;
|
|
if (ObjectHeader->Flags & OB_FLAG_PERMANENT_OBJECT) {
|
|
ObjectBasicInfo.Attributes |= OBJ_PERMANENT;
|
|
}
|
|
if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE_OBJECT) {
|
|
ObjectBasicInfo.Attributes |= OBJ_EXCLUSIVE;
|
|
}
|
|
|
|
ObjectBasicInfo.GrantedAccess = GrantedAccess;
|
|
ObjectBasicInfo.HandleCount = ObjectHeader->HandleCount;
|
|
ObjectBasicInfo.PointerCount = ObjectHeader->PointerCount;
|
|
QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader );
|
|
if (QuotaInfo != NULL) {
|
|
ObjectBasicInfo.PagedPoolCharge = QuotaInfo->PagedPoolCharge;
|
|
ObjectBasicInfo.NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;
|
|
}
|
|
else {
|
|
ObjectBasicInfo.PagedPoolCharge = 0;
|
|
ObjectBasicInfo.NonPagedPoolCharge = 0;
|
|
}
|
|
|
|
if (ObjectType == ObpSymbolicLinkObjectType) {
|
|
ObjectBasicInfo.CreationTime = ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime;
|
|
}
|
|
else {
|
|
RtlZeroMemory( &ObjectBasicInfo.CreationTime,
|
|
sizeof( ObjectBasicInfo.CreationTime )
|
|
);
|
|
}
|
|
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
|
|
if (NameInfo != NULL && NameInfo->Directory != NULL) {
|
|
ObjectDirectory = NameInfo->Directory;
|
|
if (ObjectDirectory) {
|
|
NameInfoSize = sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;
|
|
while (ObjectDirectory) {
|
|
ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory );
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader );
|
|
if (NameInfo != NULL && NameInfo->Directory != NULL) {
|
|
NameInfoSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;
|
|
ObjectDirectory = NameInfo->Directory;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
NameInfoSize += sizeof( OBJECT_NAME_INFORMATION ) + sizeof( UNICODE_NULL );
|
|
}
|
|
}
|
|
else {
|
|
NameInfoSize = 0;
|
|
}
|
|
ObjectBasicInfo.NameInfoSize = NameInfoSize;
|
|
ObjectBasicInfo.TypeInfoSize = ObjectType->Name.Length + sizeof( UNICODE_NULL ) +
|
|
sizeof( OBJECT_TYPE_INFORMATION );
|
|
if ((GrantedAccess & READ_CONTROL) &&
|
|
ARGUMENT_PRESENT( ObjectHeader->SecurityDescriptor ) ) {
|
|
|
|
SecurityDescriptorSize = RtlLengthSecurityDescriptor(
|
|
ObjectHeader->SecurityDescriptor);
|
|
}
|
|
else {
|
|
SecurityDescriptorSize = 0;
|
|
}
|
|
ObjectBasicInfo.SecurityDescriptorSize = SecurityDescriptorSize;
|
|
|
|
try {
|
|
*(POBJECT_BASIC_INFORMATION) ObjectInformation = ObjectBasicInfo;
|
|
|
|
if (ARGUMENT_PRESENT( ReturnLength ) ) {
|
|
*ReturnLength = ObjectInformationLength;
|
|
}
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
//
|
|
// Fall through, since we cannot undo what we have done.
|
|
//
|
|
}
|
|
|
|
break;
|
|
|
|
case ObjectNameInformation:
|
|
if (!ARGUMENT_PRESENT( ReturnLength ) ) {
|
|
TempReturnLength = 0;
|
|
ReturnLength = &TempReturnLength;
|
|
}
|
|
|
|
Status = ObQueryNameString( Object,
|
|
(POBJECT_NAME_INFORMATION)ObjectInformation,
|
|
ObjectInformationLength,
|
|
ReturnLength
|
|
);
|
|
break;
|
|
|
|
case ObjectTypeInformation:
|
|
if (!ARGUMENT_PRESENT( ReturnLength ) ) {
|
|
TempReturnLength = 0;
|
|
ReturnLength = &TempReturnLength;
|
|
}
|
|
|
|
Status = ObQueryTypeInfo( ObjectType,
|
|
(POBJECT_TYPE_INFORMATION)ObjectInformation,
|
|
ObjectInformationLength,
|
|
ReturnLength
|
|
);
|
|
break;
|
|
|
|
case ObjectTypesInformation:
|
|
if (!ARGUMENT_PRESENT( ReturnLength ) ) {
|
|
TempReturnLength = 0;
|
|
ReturnLength = &TempReturnLength;
|
|
}
|
|
|
|
TypesInfoSize = sizeof( ULONG );
|
|
for (i=0; i<OBP_MAX_DEFINED_OBJECT_TYPES; i++) {
|
|
ObjectType = ObpObjectTypes[ i ];
|
|
if (ObjectType == NULL) {
|
|
break;
|
|
}
|
|
|
|
ObjectType = ObjectType;
|
|
TypesInfoSize += (sizeof( OBJECT_TYPES_INFORMATION ) - sizeof( ULONG ));
|
|
TypesInfoSize += ObjectType->Name.Length + sizeof( UNICODE_NULL );
|
|
}
|
|
|
|
try {
|
|
if (ARGUMENT_PRESENT( ReturnLength ) ) {
|
|
*ReturnLength = sizeof( OBJECT_TYPES_INFORMATION );
|
|
}
|
|
TypesInformation = (POBJECT_TYPES_INFORMATION)ObjectInformation;
|
|
if (ObjectInformationLength < sizeof( OBJECT_TYPES_INFORMATION ) ) {
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
}
|
|
else {
|
|
TypesInformation->NumberOfTypes = 0;
|
|
for (i=0; i<OBP_MAX_DEFINED_OBJECT_TYPES; i++) {
|
|
ObjectType = ObpObjectTypes[ i ];
|
|
if (ObjectType == NULL) {
|
|
break;
|
|
}
|
|
|
|
TypesInformation->NumberOfTypes += 1;
|
|
}
|
|
}
|
|
|
|
TypeInfo = (POBJECT_TYPE_INFORMATION)(TypesInformation + 1);
|
|
for (i=0; i<OBP_MAX_DEFINED_OBJECT_TYPES; i++) {
|
|
ObjectType = ObpObjectTypes[ i ];
|
|
if (ObjectType == NULL) {
|
|
break;
|
|
}
|
|
|
|
Status = ObQueryTypeInfo( ObjectType,
|
|
TypeInfo,
|
|
ObjectInformationLength,
|
|
ReturnLength
|
|
);
|
|
if (NT_SUCCESS( Status )) {
|
|
TypeInfo = (POBJECT_TYPE_INFORMATION)
|
|
((PCHAR)(TypeInfo+1) + ALIGN_UP( TypeInfo->TypeName.MaximumLength, ULONG ));
|
|
}
|
|
}
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Status = GetExceptionCode();
|
|
}
|
|
|
|
break;
|
|
|
|
case ObjectHandleFlagInformation:
|
|
try {
|
|
if (ARGUMENT_PRESENT(ReturnLength)) {
|
|
*ReturnLength = sizeof(OBJECT_HANDLE_FLAG_INFORMATION);
|
|
}
|
|
|
|
HandleFlags = (POBJECT_HANDLE_FLAG_INFORMATION)ObjectInformation;
|
|
if (ObjectInformationLength < sizeof( OBJECT_HANDLE_FLAG_INFORMATION)) {
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
} else {
|
|
HandleFlags->Inherit = FALSE;
|
|
if (HandleInformation.HandleAttributes & OBJ_INHERIT) {
|
|
HandleFlags->Inherit = TRUE;
|
|
}
|
|
|
|
HandleFlags->ProtectFromClose = FALSE;
|
|
if (HandleInformation.HandleAttributes & OBJ_PROTECT_CLOSE) {
|
|
HandleFlags->ProtectFromClose = TRUE;
|
|
}
|
|
}
|
|
|
|
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Status = GetExceptionCode();
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
ObDereferenceObject( Object );
|
|
return( STATUS_INVALID_INFO_CLASS );
|
|
}
|
|
|
|
if (Object != NULL) {
|
|
ObDereferenceObject( Object );
|
|
}
|
|
|
|
return( Status );
|
|
}
|
|
|
|
|
|
#if DBG
|
|
PUNICODE_STRING
|
|
ObGetObjectName(
|
|
IN PVOID Object
|
|
)
|
|
{
|
|
POBJECT_HEADER ObjectHeader;
|
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
|
|
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
|
|
|
|
if (NameInfo != NULL && NameInfo->Name.Length != 0) {
|
|
return &NameInfo->Name;
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
#endif // DBG
|
|
|
|
#define OBP_MISSING_NAME_LITERAL L"..."
|
|
#define OBP_MISSING_NAME_LITERAL_SIZE (sizeof( OBP_MISSING_NAME_LITERAL ) - sizeof( UNICODE_NULL ))
|
|
|
|
NTSTATUS
|
|
ObQueryNameString(
|
|
IN PVOID Object,
|
|
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
|
|
IN ULONG Length,
|
|
OUT PULONG ReturnLength
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
POBJECT_HEADER ObjectHeader;
|
|
POBJECT_HEADER_NAME_INFO NameInfo;
|
|
POBJECT_HEADER ObjectDirectoryHeader;
|
|
POBJECT_DIRECTORY ObjectDirectory;
|
|
ULONG NameInfoSize;
|
|
PUNICODE_STRING String;
|
|
PWCH StringBuffer;
|
|
ULONG NameSize;
|
|
|
|
PAGED_CODE();
|
|
|
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
|
|
|
|
if (ObjectHeader->Type->TypeInfo.QueryNameProcedure != NULL) {
|
|
try {
|
|
KIRQL SaveIrql;
|
|
|
|
ObpBeginTypeSpecificCallOut( SaveIrql );
|
|
ObpEndTypeSpecificCallOut( SaveIrql, "Query", ObjectHeader->Type, Object );
|
|
Status = (*ObjectHeader->Type->TypeInfo.QueryNameProcedure)(
|
|
Object,
|
|
(BOOLEAN)(NameInfo != NULL && NameInfo->Name.Length != 0),
|
|
ObjectNameInfo,
|
|
Length,
|
|
ReturnLength
|
|
);
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Status = GetExceptionCode();
|
|
}
|
|
|
|
return( Status );
|
|
}
|
|
|
|
if (NameInfo == NULL || NameInfo->Name.Buffer == NULL) {
|
|
NameInfoSize = sizeof( OBJECT_NAME_INFORMATION );
|
|
try {
|
|
*ReturnLength = NameInfoSize;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
return( GetExceptionCode() );
|
|
}
|
|
|
|
if (Length < NameInfoSize) {
|
|
return( STATUS_INFO_LENGTH_MISMATCH );
|
|
}
|
|
|
|
try {
|
|
ObjectNameInfo->Name.Length = 0;
|
|
ObjectNameInfo->Name.MaximumLength = 0;
|
|
ObjectNameInfo->Name.Buffer = NULL;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
//
|
|
// Fall through, since we cannot undo what we have done.
|
|
//
|
|
}
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
if (Object == ObpRootDirectoryObject) {
|
|
NameSize = sizeof( OBJ_NAME_PATH_SEPARATOR );
|
|
}
|
|
else {
|
|
ObjectDirectory = NameInfo->Directory;
|
|
NameSize = sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;
|
|
while (ObjectDirectory != ObpRootDirectoryObject && (ObjectDirectory)) {
|
|
ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory );
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader );
|
|
if (NameInfo != NULL && NameInfo->Directory != NULL) {
|
|
NameSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;
|
|
ObjectDirectory = NameInfo->Directory;
|
|
}
|
|
else {
|
|
NameSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + OBP_MISSING_NAME_LITERAL_SIZE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
NameInfoSize = NameSize + sizeof( OBJECT_NAME_INFORMATION ) + sizeof( UNICODE_NULL );
|
|
|
|
try {
|
|
*ReturnLength = NameInfoSize;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
return( GetExceptionCode() );
|
|
}
|
|
|
|
if (Length < NameInfoSize) {
|
|
return( STATUS_INFO_LENGTH_MISMATCH );
|
|
}
|
|
|
|
if (NameInfoSize != 0) {
|
|
StringBuffer = (PWCH)ObjectNameInfo;
|
|
StringBuffer = (PWCH)((PCH)StringBuffer + NameInfoSize);
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
|
|
|
|
try {
|
|
*--StringBuffer = UNICODE_NULL;
|
|
if (Object != ObpRootDirectoryObject) {
|
|
String = &NameInfo->Name;
|
|
StringBuffer = (PWCH)((PCH)StringBuffer - String->Length);
|
|
RtlMoveMemory( StringBuffer, String->Buffer, String->Length );
|
|
|
|
ObjectDirectory = NameInfo->Directory;
|
|
while ((ObjectDirectory != ObpRootDirectoryObject) && (ObjectDirectory)) {
|
|
ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory );
|
|
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader );
|
|
*--StringBuffer = OBJ_NAME_PATH_SEPARATOR;
|
|
if (NameInfo != NULL && NameInfo->Directory != NULL) {
|
|
String = &NameInfo->Name;
|
|
StringBuffer = (PWCH)((PCH)StringBuffer - String->Length);
|
|
RtlMoveMemory( StringBuffer, String->Buffer, String->Length );
|
|
ObjectDirectory = NameInfo->Directory;
|
|
}
|
|
else {
|
|
StringBuffer = (PWCH)((PCH)StringBuffer - OBP_MISSING_NAME_LITERAL_SIZE);
|
|
RtlMoveMemory( StringBuffer,
|
|
OBP_MISSING_NAME_LITERAL,
|
|
OBP_MISSING_NAME_LITERAL_SIZE
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*--StringBuffer = OBJ_NAME_PATH_SEPARATOR;
|
|
|
|
ObjectNameInfo->Name.Length = (USHORT)NameSize;
|
|
ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize+sizeof( UNICODE_NULL ));
|
|
ObjectNameInfo->Name.Buffer = StringBuffer;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
//
|
|
// Fall through, since we cannot undo what we have done.
|
|
//
|
|
}
|
|
}
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ObQueryTypeName(
|
|
IN PVOID Object,
|
|
PUNICODE_STRING ObjectTypeName,
|
|
IN ULONG Length,
|
|
OUT PULONG ReturnLength
|
|
)
|
|
{
|
|
POBJECT_TYPE ObjectType;
|
|
POBJECT_HEADER ObjectHeader;
|
|
ULONG TypeNameSize;
|
|
PUNICODE_STRING String;
|
|
PWCH StringBuffer;
|
|
ULONG NameSize;
|
|
|
|
PAGED_CODE();
|
|
|
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
|
|
ObjectType = ObjectHeader->Type;
|
|
|
|
NameSize = ObjectType->Name.Length;
|
|
TypeNameSize = NameSize + sizeof( UNICODE_NULL ) + sizeof( UNICODE_STRING );
|
|
|
|
try {
|
|
*ReturnLength = TypeNameSize;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
return( GetExceptionCode() );
|
|
}
|
|
|
|
if (Length < TypeNameSize) {
|
|
return( STATUS_INFO_LENGTH_MISMATCH );
|
|
}
|
|
|
|
if (TypeNameSize != 0) {
|
|
StringBuffer = (PWCH)ObjectTypeName;
|
|
StringBuffer = (PWCH)((PCH)StringBuffer + TypeNameSize);
|
|
String = &ObjectType->Name;
|
|
try {
|
|
*--StringBuffer = UNICODE_NULL;
|
|
StringBuffer = (PWCH)((PCH)StringBuffer - String->Length);
|
|
RtlMoveMemory( StringBuffer, String->Buffer, String->Length );
|
|
ObjectTypeName->Length = (USHORT)NameSize;
|
|
ObjectTypeName->MaximumLength = (USHORT)(NameSize+sizeof( UNICODE_NULL ));
|
|
ObjectTypeName->Buffer = StringBuffer;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
//
|
|
// Fall through, since we cannot undo what we have done.
|
|
//
|
|
}
|
|
}
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ObQueryTypeInfo(
|
|
IN POBJECT_TYPE ObjectType,
|
|
OUT POBJECT_TYPE_INFORMATION ObjectTypeInfo,
|
|
IN ULONG Length,
|
|
OUT PULONG ReturnLength
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
try {
|
|
*ReturnLength += sizeof( *ObjectTypeInfo ) + ALIGN_UP( ObjectType->Name.MaximumLength, ULONG );
|
|
if (Length < *ReturnLength) {
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
}
|
|
else {
|
|
ObjectTypeInfo->TotalNumberOfObjects = ObjectType->TotalNumberOfObjects;
|
|
ObjectTypeInfo->TotalNumberOfHandles = ObjectType->TotalNumberOfHandles;
|
|
ObjectTypeInfo->HighWaterNumberOfObjects = ObjectType->HighWaterNumberOfObjects;
|
|
ObjectTypeInfo->HighWaterNumberOfHandles = ObjectType->HighWaterNumberOfHandles;
|
|
ObjectTypeInfo->InvalidAttributes = ObjectType->TypeInfo.InvalidAttributes;
|
|
ObjectTypeInfo->GenericMapping = ObjectType->TypeInfo.GenericMapping;
|
|
ObjectTypeInfo->ValidAccessMask = ObjectType->TypeInfo.ValidAccessMask;
|
|
ObjectTypeInfo->SecurityRequired = ObjectType->TypeInfo.SecurityRequired;
|
|
ObjectTypeInfo->MaintainHandleCount = ObjectType->TypeInfo.MaintainHandleCount;
|
|
ObjectTypeInfo->PoolType = ObjectType->TypeInfo.PoolType;
|
|
ObjectTypeInfo->DefaultPagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
|
|
ObjectTypeInfo->DefaultNonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
|
|
ObjectTypeInfo->TypeName.Buffer = (PWSTR)(ObjectTypeInfo+1);
|
|
ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength;
|
|
RtlCopyUnicodeString( &ObjectTypeInfo->TypeName, &ObjectType->Name );
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER ) {
|
|
Status = GetExceptionCode();
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
ObQueryObjectAuditingByHandle(
|
|
IN HANDLE Handle,
|
|
OUT PBOOLEAN GenerateOnClose
|
|
)
|
|
{
|
|
PHANDLE_TABLE ObjectTable;
|
|
POBJECT_TABLE_ENTRY ObjectTableEntry;
|
|
PVOID Object;
|
|
ULONG CapturedGrantedAccess;
|
|
ULONG CapturedAttributes;
|
|
POBJECT_HEADER ObjectHeader;
|
|
NTSTATUS Status;
|
|
|
|
PAGED_CODE();
|
|
ObpValidateIrql( "ObQueryObjectAuditingByHandle" );
|
|
|
|
ObjectTable = ObpGetObjectTable();
|
|
ObjectTableEntry = (POBJECT_TABLE_ENTRY)ExMapHandleToPointer(
|
|
ObjectTable,
|
|
(HANDLE)OBJ_HANDLE_TO_HANDLE_INDEX( Handle ),
|
|
TRUE // shared access
|
|
);
|
|
|
|
if (ObjectTableEntry != NULL) {
|
|
ObjectHeader = (POBJECT_HEADER)(ObjectTableEntry->Attributes & ~OBJ_HANDLE_ATTRIBUTES);
|
|
CapturedAttributes = (ULONG)(ObjectTableEntry->Attributes);
|
|
if (CapturedAttributes & OBJ_AUDIT_OBJECT_CLOSE) {
|
|
*GenerateOnClose = TRUE;
|
|
} else {
|
|
*GenerateOnClose = FALSE;
|
|
}
|
|
ExUnlockHandleTableShared(ObjectTable);
|
|
return(STATUS_SUCCESS);
|
|
} else {
|
|
return(STATUS_INVALID_HANDLE);
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
ObpSetHandleAttributes(
|
|
IN OUT PVOID TableEntry,
|
|
IN ULONG Parameter
|
|
)
|
|
|
|
{
|
|
|
|
POBJECT_HANDLE_FLAG_INFORMATION ObjectInformation;
|
|
POBJECT_TABLE_ENTRY ObjectTableEntry = (POBJECT_TABLE_ENTRY)TableEntry;
|
|
|
|
ObjectInformation = (POBJECT_HANDLE_FLAG_INFORMATION)Parameter;
|
|
if (ObjectInformation->Inherit) {
|
|
ObjectTableEntry->Attributes |= OBJ_INHERIT;
|
|
|
|
} else {
|
|
ObjectTableEntry->Attributes &= ~OBJ_INHERIT;
|
|
}
|
|
|
|
if (ObjectInformation->ProtectFromClose) {
|
|
ObjectTableEntry->Attributes |= OBJ_PROTECT_CLOSE;
|
|
|
|
} else {
|
|
ObjectTableEntry->Attributes &= ~OBJ_PROTECT_CLOSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
NtSetInformationObject(
|
|
IN HANDLE Handle,
|
|
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
|
IN PVOID ObjectInformation,
|
|
IN ULONG ObjectInformationLength
|
|
)
|
|
|
|
{
|
|
|
|
OBJECT_HANDLE_FLAG_INFORMATION CapturedInformation;
|
|
HANDLE ObjectHandle;
|
|
PVOID ObjectTable;
|
|
KPROCESSOR_MODE PreviousMode;
|
|
NTSTATUS Status;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Check if the information class and information lenght are correct.
|
|
//
|
|
|
|
if (ObjectInformationClass != ObjectHandleFlagInformation) {
|
|
return STATUS_INVALID_INFO_CLASS;
|
|
}
|
|
|
|
if (ObjectInformationLength != sizeof(OBJECT_HANDLE_FLAG_INFORMATION)) {
|
|
return STATUS_INFO_LENGTH_MISMATCH;
|
|
}
|
|
|
|
//
|
|
// Get previous processor mode and probe output argument if necessary.
|
|
//
|
|
|
|
PreviousMode = KeGetPreviousMode();
|
|
try {
|
|
if (PreviousMode != KernelMode) {
|
|
ProbeForRead(ObjectInformation, ObjectInformationLength, 1);
|
|
}
|
|
|
|
CapturedInformation = *(POBJECT_HANDLE_FLAG_INFORMATION)ObjectInformation;
|
|
|
|
} except(ExSystemExceptionFilter()) {
|
|
return GetExceptionCode();
|
|
}
|
|
|
|
//
|
|
// Get the address of the object table for the current process.
|
|
//
|
|
|
|
ObjectTable = ObpGetObjectTable();
|
|
ObjectHandle = (HANDLE)OBJ_HANDLE_TO_HANDLE_INDEX(Handle);
|
|
|
|
//
|
|
// Make the change to the handle table entry
|
|
//
|
|
|
|
if (ExChangeHandle(ObjectTable,
|
|
ObjectHandle,
|
|
ObpSetHandleAttributes,
|
|
(ULONG)&CapturedInformation)) {
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
} else {
|
|
Status = STATUS_ACCESS_DENIED;
|
|
}
|
|
|
|
return Status;
|
|
}
|