阅读:2830回复:12
TDI_LISTEN成功后,为什么不会产生一个新的连接对象
KeInitializeEvent(&event, NotificationEvent, FALSE);
pirp=TdiBuildInternalDeviceControlIrp(TDI_LISTEN,tcpdevice,pconn_point,&event,&iostatus); TdiBuildListen(pirp,tcpdevice,pconn_point,0,0,0,0,0); status=IoCallDriver(tcpdevice,pirp); if(status==STATUS_PENDING) { status=KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0);//在这里阻断,直到有连接过来. } 执行成功后,利用pconn_point就可以跟远程连接点进行通信. 但我有一个疑问,在应用态利用SOCKET编程, 侦听的SOCKET对象一直都处在侦听状态.当有连接过来时, 就会产生一个新的SOCKET对象,利用新产生的SOCKET对象跟客户端进行通信.为什么TDI不产生一个新 的连接对象.如果这样,那接收到一个连接后,不又要重复前面的操作(打开地址,打开连接,建立联系,开始侦 听). 高手能不能解释一下呀,初学TDI |
|
沙发#
发布于:2007-04-13 09:24
自己顶
|
|
板凳#
发布于:2007-04-13 14:29
应该是accept产生新的对象??!!!!!!
|
|
|
地板#
发布于:2007-04-13 16:23
引用第2楼cyliu于2007-04-13 14:29发表的“”: 谢谢版主的回答,修改后的代码如下: TDI_CONNECTION_INFORMATION in_conn_info,out_conn_info; 。 。 。 KeInitializeEvent(&event, NotificationEvent, FALSE); pirp=TdiBuildInternalDeviceControlIrp(TDI_LISTEN,tcpdevice,pconn_point,&event,&iostatus); in_conn_info.UserData=NULL; in_conn_info.UserDataLength=0; in_conn_info.Options=(PVOID)TDI_QUERY_ACCEPT; in_conn_info.OptionsLength=sizeof(ULONG); in_conn_info.RemoteAddress=NULL; in_conn_info.RemoteAddressLength=0; TdiBuildListen(pirp,tcpdevice,pconn_point,0,0,TDI_QUERY_ACCEPT,0,0); /* 如果将上面一句改成: TdiBuildListen(pirp,tcpdevice,pconn_point,0,0,TDI_QUERY_ACCEPT,i&n_conn_info,&out_conn_info); 就会蓝屏 错误为0xD1, */ status=IoCallDriver(tcpdevice,pirp); if(status==STATUS_PENDING) { status=KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0); } ///////////////accept KeInitializeEvent(&event, NotificationEvent, FALSE); pirp=TdiBuildInternalDeviceControlIrp(TDI_ACCEPT,tcpdevice,pconn_point,&event,&iostatus); TdiBuildAccept(pirp,tcpdevice,pconn_point,0,0,0,0); status=IoCallDriver(tcpdevice,pirp); if(status==STATUS_PENDING) { status=KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0); } 但我不知道那个参数是用于接收新的连接对象的。上面代码可以执行,但发送数据还是用pconn_point. 请版主明示,谢谢! |
|
地下室#
发布于:2007-04-16 13:41
TdiBuildListen(pirp,tcpdevice,pconn_point,0,0,TDI_QUERY_ACCEPT,i&n_conn_info,&out_conn_info);倒数第二个参数什么意思?
|
|
|
5楼#
发布于:2007-04-16 14:43
引用第4楼cyliu于2007-04-16 13:41发表的“”: 写错了,应该是: TdiBuildListen(pirp,tcpdevice,pconn_point,0,0,TDI_QUERY_ACCEPT,&in_conn_info,&out_conn_info); in_conn_info 用于接收指定的地址连接,如果为NULL,接收所有地址的连接。 |
|
6楼#
发布于:2007-04-17 10:09
有没有跟踪过TdiBuildListen?
获取新的连接对象应该在完成例程里面获取到。现在我没有办法去验证 |
|
|
7楼#
发布于:2007-04-17 10:49
谢谢楼主的热情,完成例程代码如下:
NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { PMDL mdl = NULL; PMDL nextMdl = NULL; PIO_STACK_LOCATION IrpSp; IrpSp=IoGetCurrentIrpStackLocation(Irp); if (Irp->MdlAddress != NULL) { for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl) { nextMdl = mdl->Next; MmUnlockPages(mdl); IoFreeMdl(mdl); } Irp->MdlAddress = NULL; } return STATUS_SUCCESS; } 在完成列程中有可能包含连接的对象只有IrpSp->FileObject, 但我追踪到完成列程中后,发现IrpSp->FileObject的值为0 这个问题搞了好久了,没搞定,希望版主帮我多看看,谢谢了 |
|
8楼#
发布于:2007-04-17 14:35
如果是Listen,对端进行主动连接的流程是:TdiEventConnect被触发,然后Windows系统在TdiEventConnect函数中会打开一个连接对象,并使用TDI_ASSOCIATE_ADDRESS将新创建的连接对象与本地的传输地址相关联,最后创建一个ACCEPT的IRP,并将这个IRP放到TdiEventConnect函数的最后一个参数中。你如果截获了TdiEventConnect函数,那么你就在原始的TdiEventConnect执行完之后,从它传回的ACCEPT IRP中获取连接对象就是了。
|
|
|
9楼#
发布于:2007-04-20 08:45
谢谢楼上的回答,按照大侠的提示,我试验了好几天,还是没搞定,请大侠指点迷经,现在代码如下:
我注册了ClientEventConnect: accepirp=TdiBuildInternalDeviceControlIrp(TDI_ACCEPT,tcpdevice,pconn_point,&event,&iostatus); TdiBuildAccept(accepirp,tcpdevice,pconn_point,0,0,0,0); /////////////////setevevnthandle KeInitializeEvent(&event, NotificationEvent, FALSE); pirp=TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,tcpdevice,ptrans_addr,&event,&iostatus); TdiBuildSetEventHandler(pirp,tcpdevice,ptrans_addr,0,0,TDI_EVENT_CONNECT,ClientConnectEvent,(PVOID)accepirp); status=IoCallDriver(tcpdevice,pirp); if(status==STATUS_PENDING) { status=KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, 0); } ClientConnectEvent函数如下: NTSTATUS ClientConnectEvent( IN PVOID TdiEventContext, IN LONG RemoteAddressLength, IN PVOID RemoteAddress, IN LONG UserDataLength, IN PVOID UserData, IN LONG OptionsLength, IN PVOID Options, OUT CONNECTION_CONTEXT *ConnectionContext, OUT PIRP *AcceptIrp ) { return STATUS_MORE_PROCESSING_REQUIRED; } 现在我不知道如何处理ConnectionContext,DDK上的说明如下: To accept an offered endpoint-to-endpoint connection, ClientEventConnect must set up the buffer at ConnectionContext, together with a TDI_ACCEPT request, and, then, return STATUS_MORE_PROCESSING_REQUIRED. The local-node transport notifies the remote node of the acceptance, transmitting any connect data that its client supplied in the accept IRP, and completes the TDI_ACCEPT request normally. 我不知道TDI_ACCEPT request是什么东东,设置成什么才能接受连接。 2。按大侠的提义,要截获TdiEventConnect,请问如何截获,是不是我第一步做的那样? 请大侠指点,请版主帮忙呀,急死人了 |
|
10楼#
发布于:2007-04-23 07:08
自己顶一下
|
|
11楼#
发布于:2007-04-24 14:15
继续顶
|
|
12楼#
发布于:2007-04-25 10:27
各位老救救我呀
|
|