windows socket

 
WSAStartup(MAKEWORD(2,2), &Ws)
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0);


1. WSAStartup
   准备模块
2. socket函数
    调用WSASocketW(IN INT af,IN INT type, IN INT protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags)
在WSASocketW函数中:

 if (!lpProtocolInfo)
      {
          lpProtocolInfo = &ProtocolInfo;
          ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
  
          ProtocolInfo.iAddressFamily = af;
         ProtocolInfo.iSocketType    = type;
         ProtocolInfo.iProtocol      = protocol;
     }
    PCATALOG_ENTRY Provider = LocateProvider(lpProtocolInfo);   查找provider所在的dll名
    Status = LoadProvider(Provider, lpProtocolInfo);加载dll,并调用此dll的导出函数 WSPStartup()初始化provider
。。。
    Socket = Provider->ProcTable.lpWSPSocket(af,type,protocol,lpProtocolInfo,g,dwFlags,&Status);


 



在catalog.c中,有 VOID   CreateCatalog(VOID),其中有一句 Provider = CreateCatalogEntry(L"msafd.dll");目前provider只有这一个
在msafd.dll的dllmain.c中有SOCKET WSPAPI WSPSocket(int AddressFamily, int SocketType, 
int Protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)


在此函数中有 SockGetTdiName,它根据输入参数可取得&TransportName等值;此&TransportName是具体协议驱动的名称。
SockGetTdiName (&AddressFamily, &SocketType, &Protocol, g, dwFlags, &TransportName, &HelperDLLContext, &HelperData, &HelperEvents);


接着将取出来的驱动名放入EaBuffer中:

AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
RtlCopyMemory (AfdPacket->TransportName, TransportName.Buffer, TransportName.Length + sizeof(WCHAR));

 

构建一个内核对象:


RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
InitializeObjectAttributes (&Object,&DevName,OBJ_CASE_INSENSITIVE | OBJ_INHERIT,0,0);

 

打开驱动设备,取得驱动句柄放入sock中,注意EABuffer已经传入


 Status = NtCreateFile(&Sock, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &Object, &IOSB, NULL,
0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, 0, EABuffer, SizeOfEA);

 



驱动层:


在afd驱动中有 AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
case IRP_MJ_CREATE: 
   return AfdCreateSocket(DeviceObject, Irp, IrpSp);
case IOCTL_AFD_SEND_DATAGRAM:
   return AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp );



 


驱动中有 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION IrpSp)

在此函数中EaBuffer被取出:

EaInfo = Irp->AssociatedIrp.SystemBuffer;
PAFD_CREATE_PACKET ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);

 

随后TdiDeviceName被存入FCB中

RtlCopyMemory( FCB->TdiDeviceName.Buffer, ConnectInfo->TransportName, FCB->TdiDeviceName.Length );

 

然后FCB被存储到IrpSp

  FileObject = IrpSp->FileObject;
  FileObject->FsContext = FCB 

至此, 传输层协议名被保存到了设备栈中。


在应用层:send()->WSPSendTo():
  Status = NtDeviceIoControlFile((HANDLE)Handle, Event, APCFunction, APCContext, IOSB, IOCTL_AFD_SEND_DATAGRAM, &SendInfo, sizeof(SendInfo), NULL, 0);

 

说明发送数据的IO号是IOCTL_AFD_SEND_DATAGRAM,在afd驱动中找到它,

对应的是AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp )。在此函数中:

PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
WarmSocketForBind( FCB );
 

而WarmSocketForBind函数是根据 TdiDeviceName取到FCB->AddressFile.Object文件对象的,在WarmSocketForBind函数中

TdiOpenAddressFile(&FCB->TdiDeviceName, FCB->LocalAddress, &FCB->AddressFile.Handle, &FCB->AddressFile.Object );

 

然后TdiOpenAddressFile继续调用:

TdiOpenDevice(DeviceName, EaLength, EaInfo, AddressHandle, AddressObject);


此函数再调用ZwCreateFile、ObReferenceObjectByHandle等函数取得AddressObject
继续AfdPacketSocketWriteData的执行,TdiSendDatagram被用来将数据包发给协议驱动
TdiSendDatagram(&FCB->SendIrp.InFlightRequest, FCB->AddressFile.Object, SendReq->BufferArray[0].buf, SendReq->BufferArray[0].len,
TargetAddress, &FCB->SendIrp.Iosb, PacketSocketSendComplete, FCB);





TdiSendDatagram执行DeviceObject = IoGetRelatedDeviceObject(TransportObject);
和 TdiCall(*Irp, DeviceObject, NULL, Iosb);-> Status = IoCallDriver(DeviceObject, Irp);




总的来说,AfdPacketSocketWriteData通过FCB中的TdiDeviceName取到TransPortObject,然后再通过IoGetRelatedDeviceObject取得设备对象DeviceObject,
并将Irp发给此DeviceObject
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值