当前位置: 首页 > news >正文

kernel32!GetQueuedCompletionStatus函数分析之返回值得有效性

第一部分://#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);

相关文章:

  • 2025蓝桥杯算法竞赛深度突破:创新题型与高阶策略全解析
  • 【2025年泰迪杯数据挖掘挑战赛】B题 详细解题思路+数据预处理+代码分享
  • AI 谄媚式回应 | 善用成器,滥用成殇
  • Linux基础2
  • MCU刷写——S19(S-Record)文件格式详解及Python代码
  • 图像前后处理代码
  • Web信息收集
  • 【STM32】ST7789屏幕驱动
  • Windows中xxx.dll动态链接库文件转xxx.a静态库文件
  • Python Cookbook-5.15 根据姓的首字母将人名排序和分组
  • 深入解析 Spring AI Alibaba 多模态对话模型:构建下一代智能应用的实践指南
  • QML 中的 QVariantMap
  • Python Cookbook-5.14 给字典类型增加排名功能
  • CSPM认证对项目论证的范式革新:从合规审查到价值创造的战略跃迁
  • MicroPython 开发ESP32应用教程 之 I2S、INMP441音频录制、MAX98357A音频播放、SD卡读写
  • 5Why分析法
  • 低压电工怎么备考,刷题题库分享
  • MySQL Slow Log
  • 三维凹多面体分解为凸多面体的MATLAB实现
  • 理解大模型论文中的名词部分
  • 网站建设设计报价/网推团队
  • 柳州 网站建设/互动营销名词解释
  • 浦城县规划建设旅游局网站/淘数据
  • 东莞企业网站制/搜索优化的培训免费咨询
  • 任经理 徐州网站建设/深圳网络营销网站设计
  • 建筑公司网站 新闻/关键洞察力