Windows NT 4.0 source code leak
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

/*++
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;
}