Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obquery.c File Reference

#include "obp.h"

Go to the source code of this file.

Classes

struct  __OBP_SET_HANDLE_ATTRIBUTES

Defines

#define OBP_MISSING_NAME_LITERAL   L"..."
#define OBP_MISSING_NAME_LITERAL_SIZE   (sizeof( OBP_MISSING_NAME_LITERAL ) - sizeof( UNICODE_NULL ))

Typedefs

typedef __OBP_SET_HANDLE_ATTRIBUTES OBP_SET_HANDLE_ATTRIBUTES
typedef __OBP_SET_HANDLE_ATTRIBUTESPOBP_SET_HANDLE_ATTRIBUTES

Functions

BOOLEAN ObpSetHandleAttributes (IN OUT PVOID TableEntry, IN ULONG_PTR Parameter)
NTSTATUS NtQueryObject (IN HANDLE Handle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength OPTIONAL)
NTSTATUS NTAPI NtSetInformationObject (IN HANDLE Handle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, IN PVOID ObjectInformation, IN ULONG ObjectInformationLength)
NTSTATUS ObQueryNameString (IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
NTSTATUS ObQueryTypeName (IN PVOID Object, PUNICODE_STRING ObjectTypeName, IN ULONG Length, OUT PULONG ReturnLength)
NTSTATUS ObQueryTypeInfo (IN POBJECT_TYPE ObjectType, OUT POBJECT_TYPE_INFORMATION ObjectTypeInfo, IN ULONG Length, OUT PULONG ReturnLength)
NTSTATUS ObQueryObjectAuditingByHandle (IN HANDLE Handle, OUT PBOOLEAN GenerateOnClose)
BOOLEAN ObpSetHandleAttributes (IN OUT PHANDLE_TABLE_ENTRY ObjectTableEntry, IN ULONG_PTR Parameter)


Define Documentation

#define OBP_MISSING_NAME_LITERAL   L"..."
 

Definition at line 709 of file obquery.c.

Referenced by ObQueryNameString().

#define OBP_MISSING_NAME_LITERAL_SIZE   (sizeof( OBP_MISSING_NAME_LITERAL ) - sizeof( UNICODE_NULL ))
 

Definition at line 710 of file obquery.c.

Referenced by ObQueryNameString().


Typedef Documentation

typedef struct __OBP_SET_HANDLE_ATTRIBUTES OBP_SET_HANDLE_ATTRIBUTES
 

typedef struct __OBP_SET_HANDLE_ATTRIBUTES * POBP_SET_HANDLE_ATTRIBUTES
 

Referenced by ObpSetHandleAttributes().


Function Documentation

NTSTATUS NtQueryObject IN HANDLE  Handle,
IN OBJECT_INFORMATION_CLASS  ObjectInformationClass,
OUT PVOID  ObjectInformation,
IN ULONG  ObjectInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 58 of file obquery.c.

References ALIGN_UP, _OBJECT_HEADER_NAME_INFO::Directory, EXCEPTION_EXECUTE_HANDLER, FALSE, _OBJECT_HEADER::Flags, _OBJECT_HANDLE_INFORMATION::GrantedAccess, Handle, _OBJECT_HANDLE_INFORMATION::HandleAttributes, _OBJECT_HEADER::HandleCount, KernelMode, KPROCESSOR_MODE, _OBJECT_TYPE::Name, _OBJECT_HEADER_NAME_INFO::Name, _OBJECT_HEADER_QUOTA_INFO::NonPagedPoolCharge, NT_SUCCESS, NTSTATUS(), NULL, OB_FLAG_EXCLUSIVE_OBJECT, OB_FLAG_PERMANENT_OBJECT, ObDereferenceObject, OBJ_PROTECT_CLOSE, OBJECT_HEADER_TO_NAME_INFO, OBJECT_HEADER_TO_QUOTA_INFO, OBJECT_TO_OBJECT_HEADER, OBP_MAX_DEFINED_OBJECT_TYPES, ObpAcquireDescriptorCacheReadLock(), ObpEnterRootDirectoryMutex, ObpLeaveRootDirectoryMutex, ObpObjectTypes, ObpReleaseDescriptorCacheLock(), ObpSymbolicLinkObjectType, ObQueryNameString(), ObQueryTypeInfo(), ObReferenceObjectByHandle(), PAGED_CODE, _OBJECT_HEADER_QUOTA_INFO::PagedPoolCharge, _OBJECT_HEADER::PointerCount, ProbeForWrite(), ProbeForWriteUlong, RtlLengthSecurityDescriptor(), _OBJECT_HEADER::SecurityDescriptor, Status, TRUE, and _OBJECT_HEADER::Type.

Referenced by InitializeRestrictedStuff(), IopLoadDriver(), IsInterestingPath(), TestParent(), and xProtectHandle().

00068 : 00069 00070 This routine is used to query information about a given object 00071 00072 Arguments: 00073 00074 Handle - Supplies a handle to the object being queried. This value 00075 is ignored if the requested information class is for type 00076 information. 00077 00078 ObjectInformationClass - Specifies the type of information to return 00079 00080 ObjectInformation - Supplies an output buffer for the information being 00081 returned 00082 00083 ObjectInformationLength - Specifies, in bytes, the length of the 00084 preceding object information buffer 00085 00086 ReturnLength - Optionally receives the length, in bytes, used to store 00087 the object information 00088 00089 Return Value: 00090 00091 An appropriate status value 00092 00093 --*/ 00094 00095 { 00096 KPROCESSOR_MODE PreviousMode; 00097 NTSTATUS Status; 00098 PVOID Object; 00099 POBJECT_HEADER ObjectHeader; 00100 POBJECT_HEADER_QUOTA_INFO QuotaInfo; 00101 POBJECT_HEADER_NAME_INFO NameInfo; 00102 POBJECT_TYPE ObjectType; 00103 POBJECT_HEADER ObjectDirectoryHeader; 00104 POBJECT_DIRECTORY ObjectDirectory; 00105 ACCESS_MASK GrantedAccess; 00106 POBJECT_HANDLE_FLAG_INFORMATION HandleFlags; 00107 OBJECT_HANDLE_INFORMATION HandleInformation; 00108 ULONG NameInfoSize; 00109 ULONG SecurityDescriptorSize; 00110 ULONG TempReturnLength; 00111 OBJECT_BASIC_INFORMATION ObjectBasicInfo; 00112 POBJECT_TYPES_INFORMATION TypesInformation; 00113 POBJECT_TYPE_INFORMATION TypeInfo; 00114 ULONG i; 00115 00116 PAGED_CODE(); 00117 00118 // 00119 // Initialize our local variables 00120 // 00121 00122 TempReturnLength = 0; 00123 00124 // 00125 // Get previous processor mode and probe output argument if necessary. 00126 // 00127 00128 PreviousMode = KeGetPreviousMode(); 00129 00130 if (PreviousMode != KernelMode) { 00131 00132 try { 00133 00134 if (ObjectInformationClass != ObjectHandleFlagInformation) { 00135 00136 ProbeForWrite( ObjectInformation, 00137 ObjectInformationLength, 00138 sizeof( ULONG )); 00139 00140 } else { 00141 00142 ProbeForWrite( ObjectInformation, 00143 ObjectInformationLength, 00144 1 ); 00145 } 00146 00147 // 00148 // We'll use a local temp return length variable to pass 00149 // through to the later ob query calls which will increment 00150 // its value. We can't pass the users return length directly 00151 // because the user might also be altering its value behind 00152 // our back. 00153 // 00154 00155 if (ARGUMENT_PRESENT( ReturnLength )) { 00156 00157 ProbeForWriteUlong( ReturnLength ); 00158 } 00159 00160 } except( EXCEPTION_EXECUTE_HANDLER ) { 00161 00162 return( GetExceptionCode() ); 00163 } 00164 } 00165 00166 // 00167 // If the query is not for types information then we 00168 // will have to get the object in question. Otherwise 00169 // for types information there really isn't an object 00170 // to grab. 00171 // 00172 00173 if (ObjectInformationClass != ObjectTypesInformation) { 00174 00175 Status = ObReferenceObjectByHandle( Handle, 00176 0, 00177 NULL, 00178 PreviousMode, 00179 &Object, 00180 &HandleInformation ); 00181 00182 if (!NT_SUCCESS( Status )) { 00183 00184 return( Status ); 00185 } 00186 00187 GrantedAccess = HandleInformation.GrantedAccess; 00188 00189 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00190 ObjectType = ObjectHeader->Type; 00191 00192 } else { 00193 00194 GrantedAccess = 0; 00195 Object = NULL; 00196 ObjectHeader = NULL; 00197 ObjectType = NULL; 00198 } 00199 00200 // 00201 // Now process the particular information class being 00202 // requested 00203 // 00204 00205 switch( ObjectInformationClass ) { 00206 00207 case ObjectBasicInformation: 00208 00209 // 00210 // Make sure the output buffer is long enough and then 00211 // fill in the appropriate fields into our local copy 00212 // of basic information. 00213 // 00214 00215 if (ObjectInformationLength != sizeof( OBJECT_BASIC_INFORMATION )) { 00216 00217 ObDereferenceObject( Object ); 00218 00219 return( STATUS_INFO_LENGTH_MISMATCH ); 00220 } 00221 00222 ObjectBasicInfo.Attributes = HandleInformation.HandleAttributes; 00223 00224 if (ObjectHeader->Flags & OB_FLAG_PERMANENT_OBJECT) { 00225 00226 ObjectBasicInfo.Attributes |= OBJ_PERMANENT; 00227 } 00228 00229 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE_OBJECT) { 00230 00231 ObjectBasicInfo.Attributes |= OBJ_EXCLUSIVE; 00232 } 00233 00234 ObjectBasicInfo.GrantedAccess = GrantedAccess; 00235 ObjectBasicInfo.HandleCount = ObjectHeader->HandleCount; 00236 ObjectBasicInfo.PointerCount = ObjectHeader->PointerCount; 00237 00238 QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader ); 00239 00240 if (QuotaInfo != NULL) { 00241 00242 ObjectBasicInfo.PagedPoolCharge = QuotaInfo->PagedPoolCharge; 00243 ObjectBasicInfo.NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge; 00244 00245 } else { 00246 00247 ObjectBasicInfo.PagedPoolCharge = 0; 00248 ObjectBasicInfo.NonPagedPoolCharge = 0; 00249 } 00250 00251 if (ObjectType == ObpSymbolicLinkObjectType) { 00252 00253 ObjectBasicInfo.CreationTime = ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime; 00254 00255 } else { 00256 00257 RtlZeroMemory( &ObjectBasicInfo.CreationTime, 00258 sizeof( ObjectBasicInfo.CreationTime )); 00259 } 00260 00261 // 00262 // Compute the size of the object name string by taking its name plus 00263 // seperators and traversing up to the root adding each directories 00264 // name length plus seperators 00265 // 00266 00267 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader ); 00268 00269 if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) { 00270 00271 ObpEnterRootDirectoryMutex(); 00272 00273 ObjectDirectory = NameInfo->Directory; 00274 00275 // 00276 // **** this "IF" is probably not needed because of the preceding 00277 // "IF" 00278 // 00279 00280 if (ObjectDirectory) { 00281 00282 NameInfoSize = sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length; 00283 00284 while (ObjectDirectory) { 00285 00286 ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory ); 00287 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader ); 00288 00289 if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) { 00290 00291 NameInfoSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length; 00292 ObjectDirectory = NameInfo->Directory; 00293 00294 } else { 00295 00296 break; 00297 } 00298 } 00299 00300 NameInfoSize += sizeof( OBJECT_NAME_INFORMATION ) + sizeof( UNICODE_NULL ); 00301 } 00302 00303 ObpLeaveRootDirectoryMutex(); 00304 00305 } else { 00306 00307 NameInfoSize = 0; 00308 } 00309 00310 ObjectBasicInfo.NameInfoSize = NameInfoSize; 00311 ObjectBasicInfo.TypeInfoSize = ObjectType->Name.Length + sizeof( UNICODE_NULL ) + 00312 sizeof( OBJECT_TYPE_INFORMATION ); 00313 00314 ObpAcquireDescriptorCacheReadLock(); 00315 00316 if ((GrantedAccess & READ_CONTROL) && 00317 ARGUMENT_PRESENT( ObjectHeader->SecurityDescriptor )) { 00318 00319 SecurityDescriptorSize = RtlLengthSecurityDescriptor( 00320 ObjectHeader->SecurityDescriptor); 00321 00322 } else { 00323 00324 SecurityDescriptorSize = 0; 00325 } 00326 00327 ObpReleaseDescriptorCacheLock(); 00328 00329 ObjectBasicInfo.SecurityDescriptorSize = SecurityDescriptorSize; 00330 00331 // 00332 // Now that we've packaged up our local copy of basic info we need 00333 // to copy it into the output buffer and set the return 00334 // length 00335 // 00336 00337 try { 00338 00339 *(POBJECT_BASIC_INFORMATION) ObjectInformation = ObjectBasicInfo; 00340 00341 TempReturnLength = ObjectInformationLength; 00342 00343 } except( EXCEPTION_EXECUTE_HANDLER ) { 00344 00345 // 00346 // Fall through, since we cannot undo what we have done. 00347 // 00348 } 00349 00350 break; 00351 00352 case ObjectNameInformation: 00353 00354 // 00355 // Call a local worker routine 00356 // 00357 00358 Status = ObQueryNameString( Object, 00359 (POBJECT_NAME_INFORMATION)ObjectInformation, 00360 ObjectInformationLength, 00361 &TempReturnLength ); 00362 break; 00363 00364 case ObjectTypeInformation: 00365 00366 // 00367 // Call a local worker routine 00368 // 00369 00370 Status = ObQueryTypeInfo( ObjectType, 00371 (POBJECT_TYPE_INFORMATION)ObjectInformation, 00372 ObjectInformationLength, 00373 &TempReturnLength ); 00374 break; 00375 00376 case ObjectTypesInformation: 00377 00378 try { 00379 00380 // 00381 // The first thing we do is set the return length to cover the 00382 // types info record. Later in each call to query type info 00383 // this value will be updated as necessary 00384 // 00385 00386 TempReturnLength = sizeof( OBJECT_TYPES_INFORMATION ); 00387 00388 // 00389 // Make sure there is enough room to hold the types info record 00390 // and if so then compute the number of defined types there are 00391 // 00392 00393 TypesInformation = (POBJECT_TYPES_INFORMATION)ObjectInformation; 00394 00395 if (ObjectInformationLength < sizeof( OBJECT_TYPES_INFORMATION ) ) { 00396 00397 Status = STATUS_INFO_LENGTH_MISMATCH; 00398 00399 } else { 00400 00401 TypesInformation->NumberOfTypes = 0; 00402 00403 for (i=0; i<OBP_MAX_DEFINED_OBJECT_TYPES; i++) { 00404 00405 ObjectType = ObpObjectTypes[ i ]; 00406 00407 if (ObjectType == NULL) { 00408 00409 break; 00410 } 00411 00412 TypesInformation->NumberOfTypes += 1; 00413 } 00414 } 00415 00416 // 00417 // For each defined type we will query the type info for the 00418 // object type and adjust the TypeInfo pointer to the next 00419 // free spot 00420 // 00421 00422 TypeInfo = (POBJECT_TYPE_INFORMATION)(TypesInformation + 1); 00423 00424 for (i=0; i<OBP_MAX_DEFINED_OBJECT_TYPES; i++) { 00425 00426 ObjectType = ObpObjectTypes[ i ]; 00427 00428 if (ObjectType == NULL) { 00429 00430 break; 00431 } 00432 00433 Status = ObQueryTypeInfo( ObjectType, 00434 TypeInfo, 00435 ObjectInformationLength, 00436 &TempReturnLength ); 00437 00438 if (NT_SUCCESS( Status )) { 00439 00440 TypeInfo = (POBJECT_TYPE_INFORMATION) 00441 ((PCHAR)(TypeInfo+1) + ALIGN_UP( TypeInfo->TypeName.MaximumLength, ULONG )); 00442 } 00443 } 00444 00445 } except( EXCEPTION_EXECUTE_HANDLER ) { 00446 00447 Status = GetExceptionCode(); 00448 } 00449 00450 break; 00451 00452 case ObjectHandleFlagInformation: 00453 00454 try { 00455 00456 // 00457 // Set the amount of data we are going to return 00458 // 00459 00460 TempReturnLength = sizeof(OBJECT_HANDLE_FLAG_INFORMATION); 00461 00462 HandleFlags = (POBJECT_HANDLE_FLAG_INFORMATION)ObjectInformation; 00463 00464 // 00465 // Make sure we have enough room for the query, and if so we'll 00466 // set the output based on the flags stored in the handle 00467 // 00468 00469 if (ObjectInformationLength < sizeof( OBJECT_HANDLE_FLAG_INFORMATION)) { 00470 00471 Status = STATUS_INFO_LENGTH_MISMATCH; 00472 00473 } else { 00474 00475 HandleFlags->Inherit = FALSE; 00476 00477 if (HandleInformation.HandleAttributes & OBJ_INHERIT) { 00478 00479 HandleFlags->Inherit = TRUE; 00480 } 00481 00482 HandleFlags->ProtectFromClose = FALSE; 00483 00484 if (HandleInformation.HandleAttributes & OBJ_PROTECT_CLOSE) { 00485 00486 HandleFlags->ProtectFromClose = TRUE; 00487 } 00488 } 00489 00490 } except( EXCEPTION_EXECUTE_HANDLER ) { 00491 00492 Status = GetExceptionCode(); 00493 } 00494 00495 break; 00496 00497 default: 00498 00499 // 00500 // To get to this point we must have had an object and the 00501 // information class is not defined, so we should dereference the 00502 // object and return to our user the bad status 00503 // 00504 00505 ObDereferenceObject( Object ); 00506 00507 return( STATUS_INVALID_INFO_CLASS ); 00508 } 00509 00510 // 00511 // Now if the caller asked for a return length we'll set it from 00512 // our local copy 00513 // 00514 00515 try { 00516 00517 if (ARGUMENT_PRESENT( ReturnLength ) ) { 00518 00519 *ReturnLength = TempReturnLength; 00520 } 00521 00522 } except( EXCEPTION_EXECUTE_HANDLER ) { 00523 00524 // 00525 // Fall through, since we cannot undo what we have done. 00526 // 00527 } 00528 00529 // 00530 // In the end we can free the object if there was one and return 00531 // to our caller 00532 // 00533 00534 if (Object != NULL) { 00535 00536 ObDereferenceObject( Object ); 00537 } 00538 00539 return( Status ); 00540 }

NTSTATUS NTAPI NtSetInformationObject IN HANDLE  Handle,
IN OBJECT_INFORMATION_CLASS  ObjectInformationClass,
IN PVOID  ObjectInformation,
IN ULONG  ObjectInformationLength
 

Definition at line 545 of file obquery.c.

References ASSERT, DecodeKernelHandle, ExChangeHandle(), ExSystemExceptionFilter(), FALSE, Handle, IsKernelHandle, KernelMode, KeStackAttachProcess(), KeUnstackDetachProcess(), KPROCESSOR_MODE, NTSTATUS(), __OBP_SET_HANDLE_ATTRIBUTES::ObjectInformation, ObpGetObjectTable, ObpKernelHandleTable, ObpSetHandleAttributes(), PAGED_CODE, _EPROCESS::Pcb, __OBP_SET_HANDLE_ATTRIBUTES::PreviousMode, ProbeForRead, PsGetCurrentProcess, PsInitialSystemProcess, Status, and TRUE.

Referenced by xProtectHandle().

00554 : 00555 00556 This routine is used to set handle information about a specified 00557 handle 00558 00559 Arguments: 00560 00561 Handle - Supplies the handle being modified 00562 00563 ObjectInformationClass - Specifies the class of information being 00564 modified. The only accepted value is ObjectHandleFlagInformation 00565 00566 ObjectInformation - Supplies the buffer containing the handle 00567 flag information structure 00568 00569 ObjectInformationLength - Specifies the length, in bytes, of the 00570 object information buffer 00571 00572 Return Value: 00573 00574 An appropriate status value 00575 00576 --*/ 00577 00578 { 00579 OBP_SET_HANDLE_ATTRIBUTES CapturedInformation; 00580 HANDLE ObjectHandle; 00581 PVOID ObjectTable; 00582 KPROCESSOR_MODE PreviousMode; 00583 NTSTATUS Status; 00584 BOOLEAN AttachedToProcess = FALSE; 00585 KAPC_STATE ApcState; 00586 00587 PAGED_CODE(); 00588 00589 // 00590 // Check if the information class and information length are correct. 00591 // 00592 00593 if (ObjectInformationClass != ObjectHandleFlagInformation) { 00594 00595 return STATUS_INVALID_INFO_CLASS; 00596 } 00597 00598 if (ObjectInformationLength != sizeof(OBJECT_HANDLE_FLAG_INFORMATION)) { 00599 00600 return STATUS_INFO_LENGTH_MISMATCH; 00601 } 00602 00603 // 00604 // Get previous processor mode and probe and capture the input 00605 // buffer 00606 // 00607 00608 CapturedInformation.PreviousMode = KeGetPreviousMode(); 00609 00610 try { 00611 00612 if (CapturedInformation.PreviousMode != KernelMode) { 00613 00614 ProbeForRead(ObjectInformation, ObjectInformationLength, 1); 00615 } 00616 00617 CapturedInformation.ObjectInformation = *(POBJECT_HANDLE_FLAG_INFORMATION)ObjectInformation; 00618 00619 } except(ExSystemExceptionFilter()) { 00620 00621 return GetExceptionCode(); 00622 } 00623 00624 #if 0 00625 00626 // 00627 // On checked builds, check that if the Kernel handle bit is set, 00628 // then we're coming from Kernel mode. We should probably fail the 00629 // call if bit set && !Kmode 00630 // 00631 00632 if ((Handle != NtCurrentThread()) && (Handle != NtCurrentProcess())) { 00633 00634 ASSERT((Handle < 0 ) ? (PreviousMode == KernelMode) : TRUE); 00635 } 00636 00637 #endif 00638 00639 // 00640 // Get the address of the object table for the current process. Or 00641 // get the system handle table if this is a kernel handle and we are 00642 // in kernel mode 00643 // 00644 00645 if (IsKernelHandle( Handle, CapturedInformation.PreviousMode )) { 00646 00647 // 00648 // Make the handle look like a regular handle 00649 // 00650 00651 ObjectHandle = DecodeKernelHandle( Handle ); 00652 00653 // 00654 // The global kernel handle table 00655 // 00656 00657 ObjectTable = ObpKernelHandleTable; 00658 00659 // 00660 // Go to the system process 00661 // 00662 00663 if (PsGetCurrentProcess() != PsInitialSystemProcess) { 00664 KeStackAttachProcess (&PsInitialSystemProcess->Pcb, &ApcState); 00665 AttachedToProcess = TRUE; 00666 } 00667 00668 } else { 00669 00670 ObjectTable = ObpGetObjectTable(); 00671 ObjectHandle = Handle; 00672 } 00673 00674 // 00675 // Make the change to the handle table entry. The callback 00676 // routine will do the actual change 00677 // 00678 00679 if (ExChangeHandle( ObjectTable, 00680 ObjectHandle, 00681 ObpSetHandleAttributes, 00682 (ULONG_PTR)&CapturedInformation) ) { 00683 00684 Status = STATUS_SUCCESS; 00685 00686 } else { 00687 00688 Status = STATUS_ACCESS_DENIED; 00689 } 00690 00691 // 00692 // If we are attached to the system process then return 00693 // back to our caller 00694 // 00695 00696 if (AttachedToProcess) { 00697 KeUnstackDetachProcess(&ApcState); 00698 AttachedToProcess = FALSE; 00699 } 00700 00701 // 00702 // And return to our caller 00703 // 00704 00705 return Status; 00706 }

BOOLEAN ObpSetHandleAttributes IN OUT PHANDLE_TABLE_ENTRY  ObjectTableEntry,
IN ULONG_PTR  Parameter
 

Definition at line 1469 of file obquery.c.

References FALSE, _OBJECT_HEADER::Flags, _OBJECT_TYPE_INITIALIZER::InvalidAttributes, KernelMode, OB_FLAG_KERNEL_OBJECT, OBJ_HANDLE_ATTRIBUTES, OBJ_PROTECT_CLOSE, __OBP_SET_HANDLE_ATTRIBUTES::ObjectInformation, POBP_SET_HANDLE_ATTRIBUTES, __OBP_SET_HANDLE_ATTRIBUTES::PreviousMode, TRUE, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

01476 : 01477 01478 This is the call back routine for the ExChangeHandle from 01479 NtSetInformationObject 01480 01481 Arguments: 01482 01483 ObjectTableEntry - Supplies a pointer to the object table entry being 01484 modified 01485 01486 Parameter - Supplies a pointer to the OBJECT_HANDLE_FLAG_INFORMATION 01487 structure to set into the table entry 01488 01489 Return Value: 01490 01491 Returns TRUE if the operation is successful otherwise FALSE 01492 01493 --*/ 01494 01495 { 01496 POBP_SET_HANDLE_ATTRIBUTES ObjectInformation; 01497 POBJECT_HEADER ObjectHeader; 01498 01499 ObjectInformation = (POBP_SET_HANDLE_ATTRIBUTES)Parameter; 01500 01501 // 01502 // Get a pointer to the object type via the object header and if the 01503 // caller has asked for inherit but the object type says that inherit 01504 // is an invalid flag then return false 01505 // 01506 01507 ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES); 01508 01509 if ((ObjectInformation->ObjectInformation.Inherit) && 01510 ((ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT) != 0)) { 01511 01512 return FALSE; 01513 } 01514 01515 // 01516 // User mode cannot set the object attributes for kernel objects 01517 // 01518 01519 if ((ObjectHeader->Flags & OB_FLAG_KERNEL_OBJECT) && 01520 (ObjectInformation->PreviousMode != KernelMode)) { 01521 01522 return FALSE; 01523 } 01524 01525 // 01526 // For each piece of information (inheriit and protect from close) that 01527 // is in the object information buffer we'll set or clear the bits in 01528 // the object table entry. The bits modified are the low order bits of 01529 // used to store the pointer to the object header. 01530 // 01531 01532 if (ObjectInformation->ObjectInformation.Inherit) { 01533 01534 ObjectTableEntry->ObAttributes |= OBJ_INHERIT; 01535 01536 } else { 01537 01538 ObjectTableEntry->ObAttributes &= ~OBJ_INHERIT; 01539 } 01540 01541 if (ObjectInformation->ObjectInformation.ProtectFromClose) { 01542 01543 ObjectTableEntry->ObAttributes |= OBJ_PROTECT_CLOSE; 01544 01545 } else { 01546 01547 ObjectTableEntry->ObAttributes &= ~OBJ_PROTECT_CLOSE; 01548 } 01549 01550 // 01551 // And return to our caller 01552 // 01553 01554 return TRUE; 01555 }

BOOLEAN ObpSetHandleAttributes IN OUT PVOID  TableEntry,
IN ULONG_PTR  Parameter
 

Referenced by NtSetInformationObject().

NTSTATUS ObQueryNameString IN PVOID  Object,
OUT POBJECT_NAME_INFORMATION  ObjectNameInfo,
IN ULONG  Length,
OUT PULONG  ReturnLength
 

Definition at line 713 of file obquery.c.

References _OBJECT_HEADER_NAME_INFO::Directory, EXCEPTION_EXECUTE_HANDLER, _OBJECT_HEADER_NAME_INFO::Name, NTSTATUS(), NULL, OBJECT_HEADER_TO_NAME_INFO, OBJECT_TO_OBJECT_HEADER, OBP_MISSING_NAME_LITERAL, OBP_MISSING_NAME_LITERAL_SIZE, ObpBeginTypeSpecificCallOut, ObpEndTypeSpecificCallOut, ObpEnterRootDirectoryMutex, ObpLeaveRootDirectoryMutex, ObpRootDirectoryObject, PAGED_CODE, _OBJECT_TYPE_INITIALIZER::QueryNameProcedure, Status, String, _OBJECT_HEADER::Type, _OBJECT_TYPE::TypeInfo, and USHORT.

Referenced by CcWriteBehind(), IoGetDeviceProperty(), IopBuildCmResourceList(), IopCaptureObjectName(), IopErrorLogThread(), IopQueryName(), IopRaiseHardError(), MmGetFileNameForSection(), NtQueryObject(), NtQueryVirtualMemory(), ObGetObjectInformation(), and SepQueryNameString().

00722 : 00723 00724 This routine processes a query of an object's name information 00725 00726 Arguments: 00727 00728 Object - Supplies the object being queried 00729 00730 ObjectNameInfo - Supplies the buffer to store the name string 00731 information 00732 00733 Length - Specifies the length, in bytes, of the original object 00734 name info buffer. 00735 00736 ReturnLength - Contains the number of bytes already used up 00737 in the object name info. On return this receives an updated 00738 byte count. 00739 00740 (Length minus ReturnLength) is really now many bytes are left 00741 in the output buffer. The buffer supplied to this call may 00742 actually be offset within the original users buffer 00743 00744 Return Value: 00745 00746 An appropriate status value 00747 00748 --*/ 00749 00750 { 00751 NTSTATUS Status; 00752 POBJECT_HEADER ObjectHeader; 00753 POBJECT_HEADER_NAME_INFO NameInfo; 00754 POBJECT_HEADER ObjectDirectoryHeader; 00755 POBJECT_DIRECTORY ObjectDirectory; 00756 ULONG NameInfoSize; 00757 PUNICODE_STRING String; 00758 PWCH StringBuffer; 00759 ULONG NameSize; 00760 00761 PAGED_CODE(); 00762 00763 // 00764 // Get the object header and name info record if it exists 00765 // 00766 00767 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00768 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader ); 00769 00770 // 00771 // If the object type has a query name callback routine then 00772 // that is how we get the name 00773 // 00774 00775 if (ObjectHeader->Type->TypeInfo.QueryNameProcedure != NULL) { 00776 00777 try { 00778 00779 KIRQL SaveIrql; 00780 00781 ObpBeginTypeSpecificCallOut( SaveIrql ); 00782 ObpEndTypeSpecificCallOut( SaveIrql, "Query", ObjectHeader->Type, Object ); 00783 00784 Status = (*ObjectHeader->Type->TypeInfo.QueryNameProcedure)( Object, 00785 (BOOLEAN)((NameInfo != NULL) && (NameInfo->Name.Length != 0)), 00786 ObjectNameInfo, 00787 Length, 00788 ReturnLength ); 00789 00790 } except( EXCEPTION_EXECUTE_HANDLER ) { 00791 00792 Status = GetExceptionCode(); 00793 } 00794 00795 return( Status ); 00796 } 00797 00798 // 00799 // Otherwise, the object type does not specify a query name 00800 // procedure so we get to do the work. The first thing 00801 // to check is if the object doesn't even have a name. If 00802 // object doesn't have a name then we'll return an empty name 00803 // info structure. 00804 // 00805 00806 if ((NameInfo == NULL) || (NameInfo->Name.Buffer == NULL)) { 00807 00808 // 00809 // Compute the length of our return buffer, set the output 00810 // if necessary and make sure the supplied buffer is large 00811 // enough 00812 // 00813 00814 NameInfoSize = sizeof( OBJECT_NAME_INFORMATION ); 00815 00816 try { 00817 00818 *ReturnLength = NameInfoSize; 00819 00820 } except( EXCEPTION_EXECUTE_HANDLER ) { 00821 00822 return( GetExceptionCode() ); 00823 } 00824 00825 if (Length < NameInfoSize) { 00826 00827 return( STATUS_INFO_LENGTH_MISMATCH ); 00828 } 00829 00830 // 00831 // Initialize the output buffer to be an empty string 00832 // and then return to our caller 00833 // 00834 00835 try { 00836 00837 ObjectNameInfo->Name.Length = 0; 00838 ObjectNameInfo->Name.MaximumLength = 0; 00839 ObjectNameInfo->Name.Buffer = NULL; 00840 00841 } except( EXCEPTION_EXECUTE_HANDLER ) { 00842 00843 // 00844 // Fall through, since we cannot undo what we have done. 00845 // 00846 // **** This should probably get the exception code and return 00847 // that value 00848 // 00849 } 00850 00851 return( STATUS_SUCCESS ); 00852 } 00853 00854 // 00855 // First lock the directory mutex to stop before we chase stuff down 00856 // 00857 00858 ObpEnterRootDirectoryMutex(); 00859 00860 try { 00861 00862 // 00863 // The object does have a name but now see if this is 00864 // just the root directory object in which case the name size 00865 // is only the "\" character 00866 // 00867 00868 if (Object == ObpRootDirectoryObject) { 00869 00870 NameSize = sizeof( OBJ_NAME_PATH_SEPARATOR ); 00871 00872 } else { 00873 00874 // 00875 // The named object is not the root so for every directory 00876 // working out way up we'll add its size to the name keeping 00877 // track of "\" characters inbetween each component. We first 00878 // start with the object name itself and then move on to 00879 // the directories 00880 // 00881 00882 ObjectDirectory = NameInfo->Directory; 00883 NameSize = sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length; 00884 00885 // 00886 // While we are not at the root we'll keep moving up 00887 // 00888 00889 while ((ObjectDirectory != ObpRootDirectoryObject) && (ObjectDirectory)) { 00890 00891 // 00892 // Get the name information for this directory 00893 // 00894 00895 ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory ); 00896 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader ); 00897 00898 if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) { 00899 00900 // 00901 // This directory has a name so add it to the accomulated 00902 // size and move up the tree 00903 // 00904 00905 NameSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length; 00906 ObjectDirectory = NameInfo->Directory; 00907 00908 } else { 00909 00910 // 00911 // This directory does not have a name so we'll give it 00912 // the "..." name and stop the loop 00913 // 00914 00915 NameSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + OBP_MISSING_NAME_LITERAL_SIZE; 00916 break; 00917 } 00918 } 00919 } 00920 00921 // 00922 // At this point NameSize is the number of bytes we need to store the 00923 // name of the object from the root down. The total buffer size we are 00924 // going to need will include this size, plus object name information 00925 // structure, plus an ending null character 00926 // 00927 00928 NameInfoSize = NameSize + sizeof( OBJECT_NAME_INFORMATION ) + sizeof( UNICODE_NULL ); 00929 00930 // 00931 // Set the output size and make sure the supplied buffer is large enough 00932 // to hold the information 00933 // 00934 00935 try { 00936 00937 *ReturnLength = NameInfoSize; 00938 00939 } except( EXCEPTION_EXECUTE_HANDLER ) { 00940 00941 Status = GetExceptionCode(); 00942 leave; 00943 } 00944 00945 if (Length < NameInfoSize) { 00946 00947 Status = STATUS_INFO_LENGTH_MISMATCH; 00948 leave; 00949 } 00950 00951 // 00952 // **** the following IF isn't necessary because name info size is 00953 // already guaranteed to be nonzero from about 23 lines above 00954 // 00955 00956 if (NameInfoSize != 0) { 00957 00958 // 00959 // Set the String buffer to point to the byte right after the 00960 // last byte in the output string. This following logic actually 00961 // fills in the buffer backwards working from the name back to the 00962 // root 00963 // 00964 00965 StringBuffer = (PWCH)ObjectNameInfo; 00966 StringBuffer = (PWCH)((PCH)StringBuffer + NameInfoSize); 00967 00968 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader ); 00969 00970 try { 00971 00972 // 00973 // Terminate the string with a null and backup one unicode 00974 // character 00975 // 00976 00977 *--StringBuffer = UNICODE_NULL; 00978 00979 // 00980 // If the object in question is not the root directory 00981 // then we are going to put its name in the string buffer 00982 // When we finally reach the root directory we'll append on 00983 // the final "\" 00984 // 00985 00986 if (Object != ObpRootDirectoryObject) { 00987 00988 // 00989 // Add in the objects name 00990 // 00991 00992 String = &NameInfo->Name; 00993 StringBuffer = (PWCH)((PCH)StringBuffer - String->Length); 00994 RtlMoveMemory( StringBuffer, String->Buffer, String->Length ); 00995 00996 // 00997 // While we are not at the root directory we'll keep 00998 // moving up 00999 // 01000 01001 ObjectDirectory = NameInfo->Directory; 01002 01003 while ((ObjectDirectory != ObpRootDirectoryObject) && (ObjectDirectory)) { 01004 01005 // 01006 // Get the name information for this directory 01007 // 01008 01009 ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory ); 01010 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader ); 01011 01012 // 01013 // Tack on the "\" between the last name we added and 01014 // this new name 01015 // 01016 01017 *--StringBuffer = OBJ_NAME_PATH_SEPARATOR; 01018 01019 // 01020 // Preappend the directory name, if it has one, and 01021 // move up to the next directory. 01022 // 01023 01024 if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) { 01025 01026 String = &NameInfo->Name; 01027 StringBuffer = (PWCH)((PCH)StringBuffer - String->Length); 01028 RtlMoveMemory( StringBuffer, String->Buffer, String->Length ); 01029 ObjectDirectory = NameInfo->Directory; 01030 01031 } else { 01032 01033 // 01034 // The directory is nameless so use the "..." for 01035 // its name and break out of the loop 01036 // 01037 01038 StringBuffer = (PWCH)((PCH)StringBuffer - OBP_MISSING_NAME_LITERAL_SIZE); 01039 RtlMoveMemory( StringBuffer, 01040 OBP_MISSING_NAME_LITERAL, 01041 OBP_MISSING_NAME_LITERAL_SIZE ); 01042 break; 01043 } 01044 } 01045 } 01046 01047 // 01048 // Tack on the "\" for the root directory and then set the 01049 // output unicode string variable to have the right size 01050 // and point to the right spot. 01051 // 01052 01053 *--StringBuffer = OBJ_NAME_PATH_SEPARATOR; 01054 01055 ObjectNameInfo->Name.Length = (USHORT)NameSize; 01056 ObjectNameInfo->Name.MaximumLength = (USHORT)(NameSize+sizeof( UNICODE_NULL )); 01057 ObjectNameInfo->Name.Buffer = StringBuffer; 01058 01059 } except( EXCEPTION_EXECUTE_HANDLER ) { 01060 01061 // 01062 // Fall through, since we cannot undo what we have done. 01063 // 01064 // **** This should probably get the exception code and return 01065 // that value 01066 // 01067 } 01068 } 01069 01070 Status = STATUS_SUCCESS; 01071 01072 } finally { 01073 01074 ObpLeaveRootDirectoryMutex(); 01075 } 01076 01077 return Status; 01078 }

NTSTATUS ObQueryObjectAuditingByHandle IN HANDLE  Handle,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 1319 of file obquery.c.

References ExMapHandleToPointer(), ExUnlockHandleTableEntry(), FALSE, Handle, KeEnterCriticalRegion, KeLeaveCriticalRegion, NTSTATUS(), NULL, _HANDLE_TABLE_ENTRY::ObAttributes, OBJ_AUDIT_OBJECT_CLOSE, ObpGetObjectTable, ObpValidateIrql, PAGED_CODE, Status, and TRUE.

01326 : 01327 01328 This routine tells the caller if the indicated handle will 01329 generate an audit if it is closed 01330 01331 Arguments: 01332 01333 Handle - Supplies the handle being queried 01334 01335 GenerateOnClose - Receives TRUE if the handle will generate 01336 an audit if closed and FALSE otherwise 01337 01338 Return Value: 01339 01340 An appropriate status value 01341 01342 --*/ 01343 01344 { 01345 PHANDLE_TABLE ObjectTable; 01346 PHANDLE_TABLE_ENTRY ObjectTableEntry; 01347 PVOID Object; 01348 ULONG CapturedGrantedAccess; 01349 ULONG CapturedAttributes; 01350 NTSTATUS Status; 01351 01352 PAGED_CODE(); 01353 01354 // 01355 // Protect ourselves from being interrupted while we hold a handle table 01356 // entry lock 01357 // 01358 01359 KeEnterCriticalRegion(); 01360 01361 try { 01362 01363 ObpValidateIrql( "ObQueryObjectAuditingByHandle" ); 01364 01365 01366 // 01367 // For the current process we'll grab its object table and 01368 // then get the object table entry 01369 // 01370 01371 ObjectTable = ObpGetObjectTable(); 01372 01373 ObjectTableEntry = ExMapHandleToPointer( ObjectTable, 01374 Handle ); 01375 01376 // 01377 // If we were given a valid handle we'll look at the attributes 01378 // stored in the object table entry to decide if we generate 01379 // an audit on close 01380 // 01381 01382 if (ObjectTableEntry != NULL) { 01383 01384 CapturedAttributes = ObjectTableEntry->ObAttributes; 01385 01386 if (CapturedAttributes & OBJ_AUDIT_OBJECT_CLOSE) { 01387 01388 *GenerateOnClose = TRUE; 01389 01390 } else { 01391 01392 *GenerateOnClose = FALSE; 01393 } 01394 01395 ExUnlockHandleTableEntry( ObjectTable, ObjectTableEntry ); 01396 01397 Status = STATUS_SUCCESS; 01398 01399 } else { 01400 01401 Status = STATUS_INVALID_HANDLE; 01402 } 01403 01404 } finally { 01405 01406 KeLeaveCriticalRegion(); 01407 } 01408 01409 return Status; 01410 }

NTSTATUS ObQueryTypeInfo IN POBJECT_TYPE  ObjectType,
OUT POBJECT_TYPE_INFORMATION  ObjectTypeInfo,
IN ULONG  Length,
OUT PULONG  ReturnLength
 

Definition at line 1216 of file obquery.c.

References ALIGN_UP, EXCEPTION_EXECUTE_HANDLER, NTSTATUS(), and Status.

Referenced by NtQueryObject().

01225 : 01226 01227 This routine processes the query for object type information 01228 01229 Arguments: 01230 01231 Object - Supplies a pointer to the object type being queried 01232 01233 ObjectTypeInfo - Supplies the buffer to store the type information 01234 01235 Length - Specifies the length, in bytes, of the object type 01236 information buffer 01237 01238 ReturnLength - Contains the number of bytes already used up 01239 in the object type information buffer. On return this receives 01240 an updated byte count 01241 01242 (Length minus ReturnLength) is really now many bytes are left 01243 in the output buffer. The buffer supplied to this call may 01244 actually be offset within the original users buffer 01245 01246 Return Value: 01247 01248 An appropriate status value 01249 01250 --*/ 01251 01252 { 01253 NTSTATUS Status; 01254 01255 try { 01256 01257 // 01258 // The total number of bytes needed for this query includes the 01259 // object type information structure plus the name of the type 01260 // rounded up to a ulong boundary 01261 // 01262 01263 *ReturnLength += sizeof( *ObjectTypeInfo ) + ALIGN_UP( ObjectType->Name.MaximumLength, ULONG ); 01264 01265 // 01266 // Make sure the buffer is large enough for this information and 01267 // then fill in the record 01268 // 01269 01270 if (Length < *ReturnLength) { 01271 01272 Status = STATUS_INFO_LENGTH_MISMATCH; 01273 01274 } else { 01275 01276 ObjectTypeInfo->TotalNumberOfObjects = ObjectType->TotalNumberOfObjects; 01277 ObjectTypeInfo->TotalNumberOfHandles = ObjectType->TotalNumberOfHandles; 01278 ObjectTypeInfo->HighWaterNumberOfObjects = ObjectType->HighWaterNumberOfObjects; 01279 ObjectTypeInfo->HighWaterNumberOfHandles = ObjectType->HighWaterNumberOfHandles; 01280 ObjectTypeInfo->InvalidAttributes = ObjectType->TypeInfo.InvalidAttributes; 01281 ObjectTypeInfo->GenericMapping = ObjectType->TypeInfo.GenericMapping; 01282 ObjectTypeInfo->ValidAccessMask = ObjectType->TypeInfo.ValidAccessMask; 01283 ObjectTypeInfo->SecurityRequired = ObjectType->TypeInfo.SecurityRequired; 01284 ObjectTypeInfo->MaintainHandleCount = ObjectType->TypeInfo.MaintainHandleCount; 01285 ObjectTypeInfo->PoolType = ObjectType->TypeInfo.PoolType; 01286 ObjectTypeInfo->DefaultPagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge; 01287 ObjectTypeInfo->DefaultNonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge; 01288 01289 // 01290 // The type name goes right after this structure. We cannot use 01291 // rtl routine like RtlCopyUnicodeString that might use the local 01292 // memory to keep state, because this is the user buffer and it 01293 // could be changing by user 01294 // 01295 01296 ObjectTypeInfo->TypeName.Buffer = (PWSTR)(ObjectTypeInfo+1); 01297 ObjectTypeInfo->TypeName.Length = ObjectType->Name.Length; 01298 ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength; 01299 01300 RtlMoveMemory( (PWSTR)(ObjectTypeInfo+1), 01301 ObjectType->Name.Buffer, 01302 ObjectType->Name.Length ); 01303 01304 ((PWSTR)(ObjectTypeInfo+1))[ ObjectType->Name.Length/sizeof(WCHAR) ] = UNICODE_NULL; 01305 01306 Status = STATUS_SUCCESS; 01307 } 01308 01309 } except( EXCEPTION_EXECUTE_HANDLER ) { 01310 01311 Status = GetExceptionCode(); 01312 } 01313 01314 return Status; 01315 }

NTSTATUS ObQueryTypeName IN PVOID  Object,
PUNICODE_STRING  ObjectTypeName,
IN ULONG  Length,
OUT PULONG  ReturnLength
 

Definition at line 1082 of file obquery.c.

References EXCEPTION_EXECUTE_HANDLER, _OBJECT_TYPE::Name, OBJECT_TO_OBJECT_HEADER, PAGED_CODE, String, _OBJECT_HEADER::Type, and USHORT.

Referenced by ObGetObjectInformation(), and SepQueryTypeString().

01091 : 01092 01093 This routine processes a query of an object's type name 01094 01095 Arguments: 01096 01097 Object - Supplies the object being queried 01098 01099 ObjectTypeName - Supplies the buffer to store the type name 01100 string information 01101 01102 Length - Specifies the length, in bytes, of the object type 01103 name buffer 01104 01105 ReturnLength - Contains the number of bytes already used up 01106 in the object type name buffer. On return this receives 01107 an updated byte count 01108 01109 (Length minus ReturnLength) is really now many bytes are left 01110 in the output buffer. The buffer supplied to this call may 01111 actually be offset within the original users buffer 01112 01113 Return Value: 01114 01115 An appropriate status value 01116 01117 --*/ 01118 01119 { 01120 POBJECT_TYPE ObjectType; 01121 POBJECT_HEADER ObjectHeader; 01122 ULONG TypeNameSize; 01123 PUNICODE_STRING String; 01124 PWCH StringBuffer; 01125 ULONG NameSize; 01126 01127 PAGED_CODE(); 01128 01129 // 01130 // From the object get its object type and from that get the size of 01131 // the object type name. The total size for we need for the output 01132 // buffer must fit the name, a terminating null, and a preceding 01133 // unicode string structure 01134 // 01135 01136 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 01137 ObjectType = ObjectHeader->Type; 01138 01139 NameSize = ObjectType->Name.Length; 01140 TypeNameSize = NameSize + sizeof( UNICODE_NULL ) + sizeof( UNICODE_STRING ); 01141 01142 // 01143 // Update the number of bytes we need and make sure the output buffer is 01144 // large enough 01145 // 01146 // **** to be consistent with all our callers and other routines in 01147 // this module this should probably be a "+=" and not just "=" 01148 // 01149 01150 try { 01151 01152 *ReturnLength = TypeNameSize; 01153 01154 } except( EXCEPTION_EXECUTE_HANDLER ) { 01155 01156 return( GetExceptionCode() ); 01157 } 01158 01159 if (Length < TypeNameSize) { 01160 01161 return( STATUS_INFO_LENGTH_MISMATCH ); 01162 } 01163 01164 // 01165 // **** this IF is probably not needed because of the earlier computation 01166 // of type name size 01167 // 01168 01169 if (TypeNameSize != 0) { 01170 01171 // 01172 // Set string buffer to point to the one byte beyond the 01173 // buffer that we're going to fill in 01174 // 01175 01176 StringBuffer = (PWCH)ObjectTypeName; 01177 StringBuffer = (PWCH)((PCH)StringBuffer + TypeNameSize); 01178 01179 String = &ObjectType->Name; 01180 01181 try { 01182 01183 // 01184 // Tack on the terminating null character and copy over 01185 // the type name 01186 // 01187 01188 *--StringBuffer = UNICODE_NULL; 01189 01190 StringBuffer = (PWCH)((PCH)StringBuffer - String->Length); 01191 01192 RtlMoveMemory( StringBuffer, String->Buffer, String->Length ); 01193 01194 // 01195 // Now set the preceding unicode string to have the right 01196 // lengths and to point to this buffer 01197 // 01198 01199 ObjectTypeName->Length = (USHORT)NameSize; 01200 ObjectTypeName->MaximumLength = (USHORT)(NameSize+sizeof( UNICODE_NULL )); 01201 ObjectTypeName->Buffer = StringBuffer; 01202 01203 } except( EXCEPTION_EXECUTE_HANDLER ) { 01204 01205 // 01206 // Fall through, since we cannot undo what we have done. 01207 // 01208 } 01209 } 01210 01211 return( STATUS_SUCCESS ); 01212 }


Generated on Sat May 15 19:44:59 2004 for test by doxygen 1.3.7