CreateIoCompletionPort 如何取消绑定

void UnBindSocketIOCP(SOCKET sk)
{
	/*反编译CreateIoCompletionPort 得知,用NtSetInformationFile可以
		FileInformation.hIocp = (int)IoCompletionHandle;
	FileInformation.nCompKey = CompletionKey;
	nRet = NtSetInformationFile(FileHandle, &IoStatusBlock, &FileInformation, 8u, FileCompletionInformation);
	if ( nRet >= 0 )
	  return IoCompletionHandle;
	BaseSetLastNTError(nRet);
	微软说的FILE_COMPLETION_INFORMATION结构用于替换端口中端口句柄集的完成信息。
	完成信息将替换为 ZwSetInformationFile 例程,
	并将 FileInformationClass 参数设置为 FileReplaceCompletionInformation。
	FILE_COMPLETION_INFORMATION的端口和键成员设置为其新值。 若要删除文件句柄的现有完成端口,
	请将 port 设置为 NULL。
	此结构可从 Windows 8.1 开始使用。
	*/
	MY_IO_STATUS_BLOCK IoStatusBlock = {};
	MY_FILE_COMPLETION_INFORMATION FileInformation = {};
	FileInformation.Port = (HANDLE)NULL;
	FileInformation.Key = 0;
	const int _FileCompletionInformation = 30; 
	const int _FileReplaceCompletionInformation = 61;
	LONG nRet = My_NtSetInformationFile((HANDLE)sk, &IoStatusBlock, &FileInformation, sizeof(FileInformation), _FileReplaceCompletionInformation);
	Debug_ViewA("nRet=%x", nRet);
}

[注意]Win7 XP 调用这个方法nRet=0xC0000003

C0000003    STATUS_INVALID_INFO_CLASS

关于为什么要取消iocp绑定的原因:比如原accept socket 采用了iocp方式,而后续需要进行传递给其他的框架使用,而那个框架可能不是基于iocp的方式,那么就遇到此问题

解决这个问题当然是取消iocp最有效,如果无法取消iocp 就利用Overlapped结构中增加一些特殊标记来从原来的框架中再次分离socket

如果非要在xp上取消iocp ,可以自己写驱动来做这件事

else if (FileInformationClass == FileCompletionInformation) {

        PFILE_COMPLETION_INFORMATION completion = irp->AssociatedIrp.SystemBuffer;
        PIO_COMPLETION_CONTEXT context;
        PVOID portObject;

        //
        // It is an error if this file object already has an LPC port associated
        // with it.
        //

        if (fileObject->CompletionContext || fileObject->Flags & FO_SYNCHRONOUS_IO) {

            status = STATUS_INVALID_PARAMETER;

        } else {

            //
            // Attempt to reference the port object by its handle and convert it
            // into a pointer to the port object itself.
            //

            status = ObReferenceObjectByHandle( completion->Port,
                                                IO_COMPLETION_MODIFY_STATE,
                                                IoCompletionObjectType,
                                                requestorMode,
                                                (PVOID *) &portObject,
                                                NULL );
            if (NT_SUCCESS( status )) {

                //
                // Allocate the memory to be associated w/this file object
                //

                context = ExAllocatePoolWithTag( PagedPool,
                                                 sizeof( IO_COMPLETION_CONTEXT ),
                                                 'cCoI' );
                if (!context) {

                    ObDereferenceObject( portObject );
                    status = STATUS_INSUFFICIENT_RESOURCES;

                } else {

                    //
                    // Everything was successful.  Capture the completion port
                    // and the key.
                    //

                    context->Port = portObject;
                    context->Key = completion->Key;

                    if (!InterlockedCompareExchangePointer( &fileObject->CompletionContext, context, NULL )) {

                        status = STATUS_SUCCESS;

                    } else {

                        //
                        // Someone set the completion context after the check.
                        // Simply drop everything on the floor and return an
                        // error.
                        //

                        ExFreePool( context );
                        ObDereferenceObject( portObject );
                        status = STATUS_INVALID_PARAMETER;
                    }
                }
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值