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

complete.c File Reference

#include "iop.h"

Go to the source code of this file.

Functions

VOID IopFreeMiniPacket (PIOP_MINI_COMPLETION_PACKET MiniPacket)
NTSTATUS NtCreateIoCompletion (IN PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN ULONG Count OPTIONAL)
NTSTATUS NtOpenIoCompletion (OUT PHANDLE IoCompletionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS NtQueryIoCompletion (IN HANDLE IoCompletionHandle, IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, OUT PVOID IoCompletionInformation, IN ULONG IoCompletionInformationLength, OUT PULONG ReturnLength OPTIONAL)
NTSTATUS NtSetIoCompletion (IN HANDLE IoCompletionHandle, IN PVOID KeyContext, IN PVOID ApcContext, IN NTSTATUS IoStatus, IN ULONG_PTR IoStatusInformation)
NTSTATUS NtRemoveIoCompletion (IN HANDLE IoCompletionHandle, OUT PVOID *KeyContext, OUT PVOID *ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER Timeout OPTIONAL)
NTKERNELAPI NTSTATUS IoSetIoCompletion (IN PVOID IoCompletion, IN PVOID KeyContext, IN PVOID ApcContext, IN NTSTATUS IoStatus, IN ULONG_PTR IoStatusInformation, IN BOOLEAN Quota)
VOID IopDeleteIoCompletion (IN PVOID Object)


Function Documentation

VOID IopDeleteIoCompletion IN PVOID  Object  ) 
 

Definition at line 864 of file complete.c.

References IoFreeIrp(), IopCompletionPacketIrp, IopFreeMiniPacket(), Irp, KeRundownQueue(), _IOP_MINI_COMPLETION_PACKET::ListEntry, NULL, and _IOP_MINI_COMPLETION_PACKET::PacketType.

Referenced by IopCreateObjectTypes().

00870 : 00871 00872 This function is the delete routine for I/O completion objects. Its 00873 function is to release all the entries in the repsective completion 00874 queue and to rundown all threads that are current associated. 00875 00876 Arguments: 00877 00878 Object - Supplies a pointer to an executive I/O completion object. 00879 00880 Return Value: 00881 00882 None. 00883 00884 --*/ 00885 00886 { 00887 00888 PLIST_ENTRY FirstEntry; 00889 PIRP Irp; 00890 PLIST_ENTRY NextEntry; 00891 PIOP_MINI_COMPLETION_PACKET MiniPacket; 00892 00893 // 00894 // Rundown threads associated with the I/O completion object and get 00895 // the list of unprocessed I/O completion IRPs. 00896 // 00897 00898 FirstEntry = KeRundownQueue((PKQUEUE)Object); 00899 if (FirstEntry != NULL) { 00900 NextEntry = FirstEntry; 00901 do { 00902 MiniPacket = CONTAINING_RECORD(NextEntry, 00903 IOP_MINI_COMPLETION_PACKET, 00904 ListEntry); 00905 00906 NextEntry = NextEntry->Flink; 00907 if (MiniPacket->PacketType == IopCompletionPacketIrp) { 00908 Irp = CONTAINING_RECORD(MiniPacket, IRP, Tail.Overlay.ListEntry); 00909 IoFreeIrp(Irp); 00910 00911 } else { 00912 IopFreeMiniPacket(MiniPacket); 00913 } 00914 00915 } while (FirstEntry != NextEntry); 00916 } 00917 00918 return; 00919 } }

VOID IopFreeMiniPacket PIOP_MINI_COMPLETION_PACKET  MiniPacket  ) 
 

Definition at line 797 of file complete.c.

References _GENERAL_LOOKASIDE::Depth, ExFreePool(), ExInterlockedPushEntrySList(), ExQueryDepthSList, ExReturnPoolQuota(), _GENERAL_LOOKASIDE::FreeMisses, IopCompletionPacketQuota, KeGetCurrentPrcb, _NPAGED_LOOKASIDE_LIST::L, _GENERAL_LOOKASIDE::ListHead, _NPAGED_LOOKASIDE_LIST::Lock, LookasideCompletionList, _IOP_MINI_COMPLETION_PACKET::PacketType, and _GENERAL_LOOKASIDE::TotalFrees.

Referenced by IopDeleteIoCompletion(), and NtRemoveIoCompletion().

00803 : 00804 00805 This function free the specefied I/O completion packet. 00806 00807 Arguments: 00808 00809 MiniPacket - Supplies a pointer to an I/O completion minipacket. 00810 00811 Return Value: 00812 00813 None. 00814 00815 --*/ 00816 00817 { 00818 00819 PNPAGED_LOOKASIDE_LIST Lookaside; 00820 PKPRCB Prcb; 00821 00822 // 00823 // If the minipacket cannot be returned to either the per processor or 00824 // system lookaside list, then free the minipacket to pool. Otherwise, 00825 // release the quota if quota was allocated and push the entry onto 00826 // one of the lookaside lists. 00827 // 00828 00829 Prcb = KeGetCurrentPrcb(); 00830 Lookaside = Prcb->PPLookasideList[LookasideCompletionList].P; 00831 Lookaside->L.TotalFrees += 1; 00832 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 00833 Lookaside->L.FreeMisses += 1; 00834 Lookaside = Prcb->PPLookasideList[LookasideCompletionList].L; 00835 Lookaside->L.TotalFrees += 1; 00836 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 00837 Lookaside->L.FreeMisses += 1; 00838 ExFreePool(MiniPacket); 00839 00840 } else { 00841 if (MiniPacket->PacketType == IopCompletionPacketQuota) { 00842 ExReturnPoolQuota(MiniPacket); 00843 } 00844 00845 ExInterlockedPushEntrySList(&Lookaside->L.ListHead, 00846 (PSINGLE_LIST_ENTRY)MiniPacket, 00847 &Lookaside->Lock); 00848 } 00849 00850 } else { 00851 if (MiniPacket->PacketType == IopCompletionPacketQuota) { 00852 ExReturnPoolQuota(MiniPacket); 00853 } 00854 00855 ExInterlockedPushEntrySList(&Lookaside->L.ListHead, 00856 (PSINGLE_LIST_ENTRY)MiniPacket, 00857 &Lookaside->Lock); 00858 } 00859 00860 return; 00861 }

NTKERNELAPI NTSTATUS IoSetIoCompletion IN PVOID  IoCompletion,
IN PVOID  KeyContext,
IN PVOID  ApcContext,
IN NTSTATUS  IoStatus,
IN ULONG_PTR  IoStatusInformation,
IN BOOLEAN  Quota
 

Definition at line 671 of file complete.c.

References _GENERAL_LOOKASIDE::AllocateMisses, _IOP_MINI_COMPLETION_PACKET::ApcContext, ExAllocatePoolWithQuotaTag, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExInterlockedPopEntrySList(), FALSE, IopCompletionPacketMini, IopCompletionPacketQuota, _IOP_MINI_COMPLETION_PACKET::IoStatus, _IOP_MINI_COMPLETION_PACKET::IoStatusInformation, KeGetCurrentPrcb, KeInsertQueue(), _IOP_MINI_COMPLETION_PACKET::KeyContext, _NPAGED_LOOKASIDE_LIST::L, _IOP_MINI_COMPLETION_PACKET::ListEntry, _GENERAL_LOOKASIDE::ListHead, _NPAGED_LOOKASIDE_LIST::Lock, LookasideCompletionList, NonPagedPool, NTSTATUS(), NULL, _IOP_MINI_COMPLETION_PACKET::PacketType, PAGED_CODE, PNPAGED_LOOKASIDE_LIST, Status, and _GENERAL_LOOKASIDE::TotalAllocates.

Referenced by IopXxxControlFile(), NtLockFile(), NtSetInformationJobObject(), NtSetIoCompletion(), PsChangeJobMemoryUsage(), PsEnforceExecutionTimeLimits(), PspAddProcessToJob(), PspCreateThread(), PspExitProcess(), PspFoldProcessAccountingIntoJob(), and PsReportProcessMemoryLimitViolation().

00681 : 00682 00683 This function allows the caller to queue an Irp to an I/O completion 00684 port and specify all of the information that is returned out the other 00685 end using NtRemoveIoCompletion. 00686 00687 Arguments: 00688 00689 IoCompletion - Supplies a a pointer to the completion port that the caller 00690 intends to queue a completion packet to. 00691 00692 KeyContext - Supplies the key context that is returned during a call 00693 to NtRemoveIoCompletion. 00694 00695 ApcContext - Supplies the apc context that is returned during a call 00696 to NtRemoveIoCompletion. 00697 00698 IoStatus - Supplies the IoStatus->Status data that is returned during 00699 a call to NtRemoveIoCompletion. 00700 00701 IoStatusInformation - Supplies the IoStatus->Information data that 00702 is returned during a call to NtRemoveIoCompletion. 00703 00704 Return Value: 00705 00706 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00707 error status is returned. 00708 00709 --*/ 00710 00711 { 00712 00713 PNPAGED_LOOKASIDE_LIST Lookaside; 00714 PIOP_MINI_COMPLETION_PACKET MiniPacket; 00715 ULONG PacketType; 00716 PKPRCB Prcb; 00717 NTSTATUS Status = STATUS_SUCCESS; 00718 00719 PAGED_CODE(); 00720 00721 // 00722 // Attempt to allocate the minpacket from the per processor lookaside list. 00723 // 00724 00725 PacketType = IopCompletionPacketMini; 00726 Prcb = KeGetCurrentPrcb(); 00727 Lookaside = Prcb->PPLookasideList[LookasideCompletionList].P; 00728 Lookaside->L.TotalAllocates += 1; 00729 MiniPacket = (PVOID)ExInterlockedPopEntrySList(&Lookaside->L.ListHead, 00730 &Lookaside->Lock); 00731 00732 // 00733 // If the per processor lookaside list allocation failed, then attempt to 00734 // allocate from the system lookaside list. 00735 // 00736 00737 if (MiniPacket == NULL) { 00738 Lookaside->L.AllocateMisses += 1; 00739 Lookaside = Prcb->PPLookasideList[LookasideCompletionList].L; 00740 Lookaside->L.TotalAllocates += 1; 00741 MiniPacket = (PVOID)ExInterlockedPopEntrySList(&Lookaside->L.ListHead, 00742 &Lookaside->Lock); 00743 } 00744 00745 // 00746 // If both lookaside allocation attempts failed, then attempt to allocate 00747 // from pool. 00748 // 00749 00750 if (MiniPacket == NULL) { 00751 Lookaside->L.AllocateMisses += 1; 00752 00753 // 00754 // If quota is specified, then allocate pool with quota charged. 00755 // Otherwise, allocate pool without quota. 00756 // 00757 00758 if (Quota != FALSE) { 00759 PacketType = IopCompletionPacketQuota; 00760 try { 00761 MiniPacket = ExAllocatePoolWithQuotaTag(NonPagedPool, 00762 sizeof(*MiniPacket), 00763 ' pcI'); 00764 00765 } except(EXCEPTION_EXECUTE_HANDLER) { 00766 NOTHING; 00767 } 00768 00769 } else { 00770 MiniPacket = ExAllocatePoolWithTag(NonPagedPool, 00771 sizeof(*MiniPacket), 00772 ' pcI'); 00773 } 00774 } 00775 00776 // 00777 // If a minipacket was successfully allocated, then initialize and 00778 // queue the packet to the specified I/O completion queue. 00779 // 00780 00781 if (MiniPacket != NULL) { 00782 MiniPacket->PacketType = PacketType; 00783 MiniPacket->KeyContext = KeyContext; 00784 MiniPacket->ApcContext = ApcContext; 00785 MiniPacket->IoStatus = IoStatus; 00786 MiniPacket->IoStatusInformation = IoStatusInformation; 00787 KeInsertQueue((PKQUEUE)IoCompletion, &MiniPacket->ListEntry); 00788 00789 } else { 00790 Status = STATUS_INSUFFICIENT_RESOURCES; 00791 } 00792 00793 return Status; 00794 }

NTSTATUS NtCreateIoCompletion IN PHANDLE  IoCompletionHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN ULONG Count  OPTIONAL
 

Definition at line 51 of file complete.c.

References Count, ExSystemExceptionFilter(), Handle, IoCompletionObjectType, KeInitializeQueue(), KernelMode, KPROCESSOR_MODE, KQUEUE, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObInsertObject(), ObjectAttributes, ProbeForWriteHandle, and Status.

Referenced by RtlpInitializeWorkerThreadPool().

00060 : 00061 00062 This function creates an I/O completion object, sets the maximum 00063 target concurrent thread count to the specified value, and opens 00064 a handle to the object with the specified desired access. 00065 00066 Arguments: 00067 00068 IoCompletionHandle - Supplies a pointer to a variable that receives 00069 the I/O completion object handle. 00070 00071 DesiredAccess - Supplies the desired types of access for the I/O 00072 completion object. 00073 00074 ObjectAttributes - Supplies a pointer to an object attributes structure. 00075 00076 Count - Supplies the target maximum number of threads that should 00077 be concurrently active. If this parameter is not specified, then 00078 the number of processors is used. 00079 00080 Return Value: 00081 00082 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00083 error status is returned. 00084 00085 --*/ 00086 00087 { 00088 00089 HANDLE Handle; 00090 KPROCESSOR_MODE PreviousMode; 00091 PVOID IoCompletion; 00092 NTSTATUS Status; 00093 00094 // 00095 // Establish an exception handler, probe the output handle address, and 00096 // attempt to create an I/O completion object. If the probe fails, then 00097 // return the exception code as the service status. Otherwise, return the 00098 // status value returned by the object insertion routine. 00099 // 00100 00101 try { 00102 00103 // 00104 // Get previous processor mode and probe output handle address if 00105 // necessary. 00106 // 00107 00108 PreviousMode = KeGetPreviousMode(); 00109 if (PreviousMode != KernelMode) { 00110 ProbeForWriteHandle(IoCompletionHandle); 00111 } 00112 00113 // 00114 // Allocate I/O completion object. 00115 // 00116 00117 Status = ObCreateObject(PreviousMode, 00118 IoCompletionObjectType, 00119 ObjectAttributes, 00120 PreviousMode, 00121 NULL, 00122 sizeof(KQUEUE), 00123 0, 00124 0, 00125 (PVOID *)&IoCompletion); 00126 00127 // 00128 // If the I/O completion object was successfully allocated, then 00129 // initialize the object and attempt to insert it in the handle 00130 // table of the current process. 00131 // 00132 00133 if (NT_SUCCESS(Status)) { 00134 KeInitializeQueue((PKQUEUE)IoCompletion, Count); 00135 Status = ObInsertObject(IoCompletion, 00136 NULL, 00137 DesiredAccess, 00138 0, 00139 (PVOID *)NULL, 00140 &Handle); 00141 00142 // 00143 // If the I/O completion object was successfully inserted in 00144 // the handle table of the current process, then attempt to 00145 // write the handle value. If the write attempt fails, then 00146 // do not report an error. When the caller attempts to access 00147 // the handle value, an access violation will occur. 00148 // 00149 00150 if (NT_SUCCESS(Status)) { 00151 try { 00152 *IoCompletionHandle = Handle; 00153 00154 } except(ExSystemExceptionFilter()) { 00155 NOTHING; 00156 } 00157 } 00158 } 00159 00160 // 00161 // If an exception occurs during the probe of the output handle address, 00162 // then always handle the exception and return the exception code as the 00163 // status value. 00164 // 00165 00166 } except(ExSystemExceptionFilter()) { 00167 Status = GetExceptionCode(); 00168 } 00169 00170 // 00171 // Return service status. 00172 // 00173 00174 return Status; 00175 }

NTSTATUS NtOpenIoCompletion OUT PHANDLE  IoCompletionHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes
 

Definition at line 178 of file complete.c.

References ExSystemExceptionFilter(), Handle, IoCompletionObjectType, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, ObOpenObjectByName(), ProbeForWriteHandle, and Status.

00186 : 00187 00188 This function opens a handle to an I/O completion object with the 00189 specified desired access. 00190 00191 Arguments: 00192 00193 IoCompletionHandle - Supplies a pointer to a variable that receives 00194 the completion object handle. 00195 00196 DesiredAccess - Supplies the desired types of access for the I/O 00197 completion object. 00198 00199 ObjectAttributes - Supplies a pointer to an object attributes structure. 00200 00201 Return Value: 00202 00203 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00204 error status is returned. 00205 00206 --*/ 00207 00208 { 00209 00210 HANDLE Handle; 00211 KPROCESSOR_MODE PreviousMode; 00212 NTSTATUS Status; 00213 00214 // 00215 // Establish an exception handler, probe the output handle address, 00216 // and attempt to open an I/O completion object. If the probe fails, 00217 // then return the exception code as the service status. Otherwise, 00218 // return the status value returned by the object open routine. 00219 // 00220 00221 try { 00222 00223 // 00224 // Get previous processor mode and probe output handle address if 00225 // necessary. 00226 // 00227 00228 PreviousMode = KeGetPreviousMode(); 00229 if (PreviousMode != KernelMode) { 00230 ProbeForWriteHandle(IoCompletionHandle); 00231 } 00232 00233 // 00234 // Open handle to the completion object with the specified desired 00235 // access. 00236 // 00237 00238 Status = ObOpenObjectByName(ObjectAttributes, 00239 IoCompletionObjectType, 00240 PreviousMode, 00241 NULL, 00242 DesiredAccess, 00243 NULL, 00244 &Handle); 00245 00246 // 00247 // If the open was successful, then attempt to write the I/O 00248 // completion object handle value. If the write attempt fails, 00249 // then do not report an error. When the caller attempts to 00250 // access the handle value, an access violation will occur. 00251 // 00252 00253 if (NT_SUCCESS(Status)) { 00254 try { 00255 *IoCompletionHandle = Handle; 00256 00257 } except(ExSystemExceptionFilter()) { 00258 NOTHING; 00259 } 00260 } 00261 00262 // 00263 // If an exception occurs during the probe of the output handle address, 00264 // then always handle the exception and return the exception code as the 00265 // status value. 00266 // 00267 00268 } except(ExSystemExceptionFilter()) { 00269 Status = GetExceptionCode(); 00270 } 00271 00272 00273 // 00274 // Return service status. 00275 // 00276 00277 return Status; 00278 }

NTSTATUS NtQueryIoCompletion IN HANDLE  IoCompletionHandle,
IN IO_COMPLETION_INFORMATION_CLASS  IoCompletionInformationClass,
OUT PVOID  IoCompletionInformation,
IN ULONG  IoCompletionInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 282 of file complete.c.

References ExSystemExceptionFilter(), IoCompletionObjectType, KeReadStateQueue(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), ProbeForWrite(), ProbeForWriteUlong, and Status.

Referenced by RtlpWorkerThreadTimerCallback().

00292 : 00293 00294 This function queries the state of an I/O completion object and returns 00295 the requested information in the specified record structure. 00296 00297 Arguments: 00298 00299 IoCompletionHandle - Supplies a handle to an I/O completion object. 00300 00301 IoCompletionInformationClass - Supplies the class of information being 00302 requested. 00303 00304 IoCompletionInformation - Supplies a pointer to a record that receives 00305 the requested information. 00306 00307 IoCompletionInformationLength - Supplies the length of the record that 00308 receives the requested information. 00309 00310 ReturnLength - Supplies an optional pointer to a variable that receives 00311 the actual length of the information that is returned. 00312 00313 Return Value: 00314 00315 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00316 error status is returned. 00317 00318 --*/ 00319 00320 { 00321 00322 PVOID IoCompletion; 00323 LONG Depth; 00324 KPROCESSOR_MODE PreviousMode; 00325 NTSTATUS Status; 00326 00327 // 00328 // Establish an exception handler, probe the output arguments, reference 00329 // the I/O completion object, and return the specified information. If 00330 // the probe fails, then return the exception code as the service status. 00331 // Otherwise return the status value returned by the reference object by 00332 // handle routine. 00333 // 00334 00335 try { 00336 00337 // 00338 // Get previous processor mode and probe output arguments if necessary. 00339 // 00340 00341 PreviousMode = KeGetPreviousMode(); 00342 if (PreviousMode != KernelMode) { 00343 ProbeForWrite(IoCompletionInformation, 00344 sizeof(IO_COMPLETION_BASIC_INFORMATION), 00345 sizeof(ULONG)); 00346 00347 if (ARGUMENT_PRESENT(ReturnLength)) { 00348 ProbeForWriteUlong(ReturnLength); 00349 } 00350 } 00351 00352 // 00353 // Check argument validity. 00354 // 00355 00356 if (IoCompletionInformationClass != IoCompletionBasicInformation) { 00357 return STATUS_INVALID_INFO_CLASS; 00358 } 00359 00360 if (IoCompletionInformationLength != sizeof(IO_COMPLETION_BASIC_INFORMATION)) { 00361 return STATUS_INFO_LENGTH_MISMATCH; 00362 } 00363 00364 // 00365 // Reference the I/O completion object by handle. 00366 // 00367 00368 Status = ObReferenceObjectByHandle(IoCompletionHandle, 00369 IO_COMPLETION_QUERY_STATE, 00370 IoCompletionObjectType, 00371 PreviousMode, 00372 &IoCompletion, 00373 NULL); 00374 00375 // 00376 // If the reference was successful, then read the current state of 00377 // the I/O completion object, dereference the I/O completion object, 00378 // fill in the information structure, and return the structure length 00379 // if specified. If the write of the I/O completion information or 00380 // the return length fails, then do not report an error. When the 00381 // caller accesses the information structure or length an access 00382 // violation will occur. 00383 // 00384 00385 if (NT_SUCCESS(Status)) { 00386 Depth = KeReadStateQueue((PKQUEUE)IoCompletion); 00387 ObDereferenceObject(IoCompletion); 00388 try { 00389 ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = Depth; 00390 if (ARGUMENT_PRESENT(ReturnLength)) { 00391 *ReturnLength = sizeof(IO_COMPLETION_BASIC_INFORMATION); 00392 } 00393 00394 } except(ExSystemExceptionFilter()) { 00395 NOTHING; 00396 } 00397 } 00398 00399 // 00400 // If an exception occurs during the probe of the output arguments, then 00401 // always handle the exception and return the exception code as the status 00402 // value. 00403 // 00404 00405 } except(ExSystemExceptionFilter()) { 00406 Status = GetExceptionCode(); 00407 } 00408 00409 // 00410 // Return service status. 00411 // 00412 00413 return Status; 00414 }

NTSTATUS NtRemoveIoCompletion IN HANDLE  IoCompletionHandle,
OUT PVOID *  KeyContext,
OUT PVOID *  ApcContext,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN PLARGE_INTEGER Timeout  OPTIONAL
 

Definition at line 485 of file complete.c.

References _IOP_MINI_COMPLETION_PACKET::ApcContext, ExSystemExceptionFilter(), IoCompletionObjectType, IoFreeIrp(), IOP_MINI_COMPLETION_PACKET, IopCompletionPacketIrp, IopFreeMiniPacket(), _IOP_MINI_COMPLETION_PACKET::IoStatus, _IRP::IoStatus, _IOP_MINI_COMPLETION_PACKET::IoStatusInformation, IRP, Irp, KeRemoveQueue(), KernelMode, _IOP_MINI_COMPLETION_PACKET::KeyContext, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), _IRP::Overlay, _IOP_MINI_COMPLETION_PACKET::PacketType, ProbeAndReadLargeInteger, ProbeForWriteIoStatus, ProbeForWriteUlong_ptr, Status, and _IRP::Tail.

Referenced by RtlpWorkerThread().

00495 : 00496 00497 This function removes an entry from an I/O completion object. If there 00498 are currently no entries available, then the calling thread waits for 00499 an entry. 00500 00501 Arguments: 00502 00503 Completion - Supplies a handle to an I/O completion object. 00504 00505 KeyContext - Supplies a pointer to a variable that receives the key 00506 context that was specified when the I/O completion object was 00507 assoicated with a file object. 00508 00509 ApcContext - Supplies a pointer to a variable that receives the 00510 context that was specified when the I/O operation was issued. 00511 00512 IoStatus - Supplies a pointer to a variable that receives the 00513 I/O completion status. 00514 00515 Timeout - Supplies a pointer to an optional time out value. 00516 00517 Return Value: 00518 00519 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00520 error status is returned. 00521 00522 --*/ 00523 00524 { 00525 00526 PLARGE_INTEGER CapturedTimeout; 00527 PLIST_ENTRY Entry; 00528 PVOID IoCompletion; 00529 PIRP Irp; 00530 KPROCESSOR_MODE PreviousMode; 00531 NTSTATUS Status; 00532 LARGE_INTEGER TimeoutValue; 00533 PVOID LocalApcContext; 00534 PVOID LocalKeyContext; 00535 IO_STATUS_BLOCK LocalIoStatusBlock; 00536 PIOP_MINI_COMPLETION_PACKET MiniPacket; 00537 00538 // 00539 // Establish an exception handler, probe the I/O context, the I/O 00540 // status, and the optional timeout value if specified, reference 00541 // the I/O completion object, and attempt to remove an entry from 00542 // the I/O completion object. If the probe fails, then return the 00543 // exception code as the service status. Otherwise, return a value 00544 // dependent on the outcome of the queue removal. 00545 // 00546 00547 try { 00548 00549 // 00550 // Get previous processor mode and probe the I/O context, status, 00551 // and timeout if necessary. 00552 // 00553 00554 CapturedTimeout = NULL; 00555 PreviousMode = KeGetPreviousMode(); 00556 if (PreviousMode != KernelMode) { 00557 ProbeForWriteUlong_ptr((PULONG_PTR)ApcContext); 00558 ProbeForWriteUlong_ptr((PULONG_PTR)KeyContext); 00559 ProbeForWriteIoStatus(IoStatusBlock); 00560 if (ARGUMENT_PRESENT(Timeout)) { 00561 CapturedTimeout = &TimeoutValue; 00562 TimeoutValue = ProbeAndReadLargeInteger(Timeout); 00563 } 00564 00565 } else{ 00566 if (ARGUMENT_PRESENT(Timeout)) { 00567 CapturedTimeout = Timeout; 00568 } 00569 } 00570 00571 // 00572 // Reference the I/O completion object by handle. 00573 // 00574 00575 Status = ObReferenceObjectByHandle(IoCompletionHandle, 00576 IO_COMPLETION_MODIFY_STATE, 00577 IoCompletionObjectType, 00578 PreviousMode, 00579 &IoCompletion, 00580 NULL); 00581 00582 // 00583 // If the reference was successful, then attempt to remove an entry 00584 // from the I/O completion object. If an entry is removed from the 00585 // I/O completion object, then capture the completion information, 00586 // release the associated IRP, and attempt to write the completion 00587 // inforamtion. If the write of the completion infomation fails, 00588 // then do not report an error. When the caller attempts to access 00589 // the completion information, an access violation will occur. 00590 // 00591 00592 if (NT_SUCCESS(Status)) { 00593 Entry = KeRemoveQueue((PKQUEUE)IoCompletion, 00594 PreviousMode, 00595 CapturedTimeout); 00596 00597 // 00598 // N.B. The entry value returned can be the address of a list 00599 // entry, STATUS_USER_APC, or STATUS_TIMEOUT. 00600 // 00601 00602 if (((LONG_PTR)Entry == STATUS_TIMEOUT) || 00603 ((LONG_PTR)Entry == STATUS_USER_APC)) { 00604 Status = (NTSTATUS)((LONG_PTR)Entry); 00605 00606 } else { 00607 00608 // 00609 // Set the completion status, capture the completion 00610 // information, deallocate the associated IRP, and 00611 // attempt to write the completion information. 00612 // 00613 00614 Status = STATUS_SUCCESS; 00615 try { 00616 MiniPacket = CONTAINING_RECORD(Entry, 00617 IOP_MINI_COMPLETION_PACKET, 00618 ListEntry); 00619 00620 if ( MiniPacket->PacketType == IopCompletionPacketIrp ) { 00621 Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); 00622 LocalApcContext = Irp->Overlay.AsynchronousParameters.UserApcContext; 00623 LocalKeyContext = (PVOID)Irp->Tail.CompletionKey; 00624 LocalIoStatusBlock = Irp->IoStatus; 00625 IoFreeIrp(Irp); 00626 00627 } else { 00628 00629 LocalApcContext = MiniPacket->ApcContext; 00630 LocalKeyContext = (PVOID)MiniPacket->KeyContext; 00631 LocalIoStatusBlock.Status = MiniPacket->IoStatus; 00632 LocalIoStatusBlock.Information = MiniPacket->IoStatusInformation; 00633 IopFreeMiniPacket(MiniPacket); 00634 } 00635 00636 *ApcContext = LocalApcContext; 00637 *KeyContext = LocalKeyContext; 00638 *IoStatusBlock = LocalIoStatusBlock; 00639 00640 } except(ExSystemExceptionFilter()) { 00641 NOTHING; 00642 } 00643 } 00644 00645 // 00646 // Deference I/O completion object. 00647 // 00648 00649 ObDereferenceObject(IoCompletion); 00650 } 00651 00652 // 00653 // If an exception occurs during the probe of the previous count, then 00654 // always handle the exception and return the exception code as the status 00655 // value. 00656 // 00657 00658 } except(ExSystemExceptionFilter()) { 00659 Status = GetExceptionCode(); 00660 } 00661 00662 // 00663 // Return service status. 00664 // 00665 00666 return Status; 00667 }

NTSTATUS NtSetIoCompletion IN HANDLE  IoCompletionHandle,
IN PVOID  KeyContext,
IN PVOID  ApcContext,
IN NTSTATUS  IoStatus,
IN ULONG_PTR  IoStatusInformation
 

Definition at line 417 of file complete.c.

References IoCompletionObjectType, IoSetIoCompletion(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, Status, and TRUE.

Referenced by RtlpQueueWorkerRequest(), and RtlThreadPoolCleanup().

00426 : 00427 00428 This function allows the caller to queue an Irp to an I/O completion 00429 port and specify all of the information that is returned out the other 00430 end using NtRemoveIoCompletion. 00431 00432 Arguments: 00433 00434 IoCompletionHandle - Supplies a handle to the io completion port 00435 that the caller intends to queue a completion packet to 00436 00437 KeyContext - Supplies the key context that is returned during a call 00438 to NtRemoveIoCompletion 00439 00440 ApcContext - Supplies the apc context that is returned during a call 00441 to NtRemoveIoCompletion 00442 00443 IoStatus - Supplies the IoStatus->Status data that is returned during 00444 a call to NtRemoveIoCompletion 00445 00446 IoStatusInformation - Supplies the IoStatus->Information data that 00447 is returned during a call to NtRemoveIoCompletion 00448 00449 Return Value: 00450 00451 STATUS_SUCCESS is returned if the function is success. Otherwise, an 00452 error status is returned. 00453 00454 --*/ 00455 00456 { 00457 PVOID IoCompletion; 00458 PIOP_MINI_COMPLETION_PACKET MiniPacket; 00459 NTSTATUS Status; 00460 00461 PAGED_CODE(); 00462 00463 Status = ObReferenceObjectByHandle(IoCompletionHandle, 00464 IO_COMPLETION_MODIFY_STATE, 00465 IoCompletionObjectType, 00466 KeGetPreviousMode(), 00467 &IoCompletion, 00468 NULL); 00469 00470 if (NT_SUCCESS(Status)) { 00471 Status = IoSetIoCompletion(IoCompletion, 00472 KeyContext, 00473 ApcContext, 00474 IoStatus, 00475 IoStatusInformation, 00476 TRUE); 00477 00478 ObDereferenceObject(IoCompletion); 00479 } 00480 return Status; 00481 00482 }


Generated on Sat May 15 19:43:12 2004 for test by doxygen 1.3.7