Читаем Windows® Internals, Sixth Edition, Part 1 полностью

Now you can use the pointer of the Device object with the !devhandles command. Each object shown points to a file:!devhandles fffffa8001bd3cd0 Checking handle table for process 0xfffffa8000c819e0 Kernel handle table at fffff8a000001830 with 434 entries in use PROCESS fffffa8000c819e0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00187000 ObjectTable: fffff8a000001830 HandleCount: 434. Image: System 0048: Object: fffffa8001d4f2a0 GrantedAccess: 0013008b Entry: fffff8a000003120 Object: fffffa8001d4f2a0 Type: (fffffa8000ca0360) File ObjectHeader: fffffa8001d4f270 (new version) HandleCount: 1 PointerCount: 19 Directory Object: 00000000 Name: \Windows\System32\LogFiles\WMI\ RtBackup\EtwRTEventLog-Application.etl {HarddiskVolume1}

Reserve Objects

Because objects represent anything from events to files to interprocess messages, the ability for applications and kernel code to create objects is essential to the normal and desired runtime behavior of any piece of Windows code. If an object allocation fails, this usually causes anywhere from loss of functionality (the process cannot open a file) to data loss or crashes (the process cannot allocate a synchronization object). Worse, in certain situations, the reporting of errors that led to object creation failure might themselves require new objects to be allocated. Windows implements two special reserve objects to deal with such situations: the User APC reserve object and the I/O Completion packet reserve object. Note that the reserve-object mechanism itself is fully extensible, and future versions of Windows might add other reserve object types—from a broad view, the reserve object is a mechanism enabling any kernel-mode data structure to be wrapped as an object (with an associated handle, name, and security) for later use.

As was discussed in the APC section earlier in this chapter, APCs are used for operations such as suspension, termination, and I/O completion, as well as communication between user-mode applications that want to provide asynchronous callbacks. When a user-mode application requests a User APC to be targeted to another thread, it uses the QueueUserApc API in Kernelbase.dll, which calls the NtQueueUserApcThread system call. In the kernel, this system call attempts to allocate a piece of paged pool in which to store the KAPC control object structure associated with an APC. In low-memory situations, this operation fails, preventing the delivery of the APC, which, depending on what the APC was used for, could cause loss of data or functionality.

To prevent this, the user-mode application, can, on startup, use the NtAllocateReserveObject system call to request the kernel to pre-allocate the KAPC structure. Then the application uses a different system call, NtQueueUserApcThreadEx, that contains an extra parameter that is used to store the handle to the reserve object. Instead of allocating a new structure, the kernel attempts to acquire the reserve object (by setting its InUse bit to true) and use it until the KAPC object is not needed anymore, at which point the reserve object is released back to the system. Currently, to prevent mismanagement of system resources by third-party developers, the reserve object API is available only internally through system calls for operating system components. For example, the RPC library uses reserved APC objects to guarantee asynchronous callbacks will still be able to return in low-memory situations.

A similar scenario can occur when applications need failure-free delivery of an I/O completion port message, or packet. Typically, packets are sent with the PostQueuedCompletionStatus API in Kernelbase.dll, which calls the NtSetIoCompletion API. Similarly to the user APC, the kernel must allocate an I/O manager structure to contain the completion-packet information, and if this allocation fails, the packet cannot be created. With reserve objects, the application can use the NtAllocateReserveObject API on startup to have the kernel pre-allocate the I/O completion packet, and the NtSetIoCompletionEx system call can be used to supply a handle to this reserve object, guaranteeing a success path. Just like User APC reserve objects, this functionality is reserved for system components and is used both by the RPC library and the Windows Peer-To-Peer BranchCache service (see Chapter 7, for more information on networking) to guarantee completion of asynchronous I/O operations.

Object Security

Перейти на страницу:

Похожие книги