第一部分://#define STATUS_SUCCESS 0x0返回值为0
} else {
//
// Set the completion status, capture the completion
// information, deallocate the associated IRP, and
// attempt to write the completion information.
//
Status = STATUS_SUCCESS ; //#define STATUS_SUCCESS 0x0返回值为0
try {
MiniPacket = CONTAINING_RECORD(Entry,
IOP_MINI_COMPLETION_PACKET,
ListEntry);
if ( MiniPacket->PacketType == IopCompletionPacketIrp ) {
Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
LocalApcContext = Irp->Overlay.AsynchronousParameters.UserApcContext;
LocalKeyContext = (PVOID)Irp->Tail.CompletionKey;
LocalIoStatusBlock = Irp->IoStatus;
IoFreeIrp(Irp);
} else {
LocalApcContext = MiniPacket->ApcContext;
LocalKeyContext = (PVOID)MiniPacket->KeyContext;
LocalIoStatusBlock.Status = MiniPacket->IoStatus;
LocalIoStatusBlock.Information = MiniPacket->IoStatusInformation;
IopFreeMiniPacket(MiniPacket);
}
*ApcContext = LocalApcContext;
*KeyContext = LocalKeyContext;
*IoStatusBlock = LocalIoStatusBlock;
} except(ExSystemExceptionFilter ()) {
NOTHING;
}
}
//
// Deference I/O completion object.
//
ObDereferenceObject(IoCompletion);
}
//
// If an exception occurs during the probe of the previous count, then
// always handle the exception and return the exception code as the status
// value.
//
} except(ExSystemExceptionFilter()) {
Status = GetExceptionCode();
}
//
// Return service status.
//
return Status ;
}
第二部分:
BOOL
WINAPI
GetQueuedCompletionStatus(
HANDLE CompletionPort,
LPDWORD lpNumberOfBytesTransferred,
PULONG_PTR lpCompletionKey,
LPOVERLAPPED *lpOverlapped,
DWORD dwMilliseconds
)
{
LARGE_INTEGER TimeOut;
PLARGE_INTEGER pTimeOut;
IO_STATUS_BLOCK IoSb;
NTSTATUS Status;
LPOVERLAPPED LocalOverlapped;
BOOL rv;
pTimeOut = BaseFormatTimeOut(&TimeOut,dwMilliseconds);
Status = NtRemoveIoCompletion(
CompletionPort,
(PVOID *)lpCompletionKey,
(PVOID *)&LocalOverlapped,
&IoSb,
pTimeOut
);
if ( !NT_SUCCESS(Status) || Status == STATUS_TIMEOUT ) {
*lpOverlapped = NULL;
if ( Status == STATUS_TIMEOUT ) {
SetLastError(WAIT_TIMEOUT);
}
else {
BaseSetLastNTError(Status);
}
rv = FALSE;
}
else {
*lpOverlapped = LocalOverlapped; //lpOverlapped 有非0值
*lpNumberOfBytesTransferred = (DWORD)IoSb.Information;
if ( !NT_SUCCESS(IoSb.Status) ){
BaseSetLastNTError( IoSb.Status );
rv = FALSE;
}
else {
rv = TRUE; //成功。返回1!!!
}
}
return rv;
}
第三部分:
参考:
1: kd> kc
00 nt!NtRemoveIoCompletion
01 nt!_KiSystemService
02 SharedUserData!SystemCallStub
03 ntdll!ZwRemoveIoCompletion
04 kernel32!GetQueuedCompletionStatus
05 RPCRT4!COMMON_ProcessCalls
06 RPCRT4!LOADABLE_TRANSPORT::ProcessIOEvents
07 RPCRT4!ProcessIOEventsWrapper
08 RPCRT4!BaseCachedThreadRoutine
09 RPCRT4!ThreadStartRoutine
0a kernel32!BaseThreadStart
1: kd> p
Breakpoint 40 hit
RPCRT4!COMMON_ProcessCalls+0xe9:
001b:77c66f8d 85c0 test eax,eax
1: kd> r
eax=00000001 ebx=77e47889 ecx=00000000 edx=7ffe0304 esi=77be9fc4 edi=77f6a8dc
eip=77c66f8d esp=00acfef0 ebp=00acff18 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
RPCRT4!COMMON_ProcessCalls+0xe9:
001b:77c66f8d 85c0 test eax,eax
1: kd> dv
b = 0n1
lpOverlapped = 0x00b002b8
第一种情况:都为0
if (!b && !lpOverlapped)
{
// If lpOverlapped is NULL this mean no IO completed.
第二种情况:b为0,lpOverlapped)不为0。调用GetLastError();,前面有BaseSetLastNTError( IoSb.Status );
if (!b)
{
pBaseOverlapped = FindOverlapped(lpOverlapped);
pRequest = FindRequest(lpOverlapped);
LastError = GetLastError();
第三种情况:成功,有数据完成了。
// here we actually have a completed IO
pBaseOverlapped = FindOverlapped(lpOverlapped);
pRequest = FindRequest(lpOverlapped);