Re: help me with my understanding of WSPRecv/From
From: Maxim S. Shatskih (maxim_at_storagecraft.com)
Date: 09/10/04
- Next message: Maxim S. Shatskih: "Re: IoGetDeviceObjectPointer ok but IoGetDeviceProperty crashed"
- Previous message: Maxim S. Shatskih: "Re: Softice Symbol table"
- In reply to: Harry Potter: "help me with my understanding of WSPRecv/From"
- Next in thread: Harry Potter: "Re: help me with my understanding of WSPRecv/From"
- Reply: Harry Potter: "Re: help me with my understanding of WSPRecv/From"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 10 Sep 2004 16:35:19 +0400
> I understand that LSP resides between the Wsock32.dll and TCP.sys... so if
Long explanation (a FAQ candidate :)):
WinSock is a user-mode layer (wsock32.dll and others below it) to provide
Berkeley Sockets-style API for the apps.
Besides Berkeley, WinSock has some MS-specific functions to employ the NT
kernel's async IO facilities better - like AcceptEx and so on.
Sockets API deals with protocol families (which determine the physical medium
below and the addressing format - so, also called "address families"). To
understand several address families, WinSock needs a Provider DLL for each -
like ODBC needs a "driver DLL" to talk to particular SQL engine.
Lots of address families (IPv4 and IPv6 included) are implemented in the
kernel-mode protocol driver with TDI upper edge. For such address families,
WinSock has a common provider DLL called MSAFD.DLL. It is nothing more then a
wrapper from WSPxxx routines called by WinSock upper layer to DeviceIoControl
calls to AFD.SYS.
AFD.SYS is a kernel module which implements the sockets semantics on top of
TDI. It implements things like SO_SNDBUF, SO_RCVBUF, SO_LINGER (all SOL_SOCKET
in fact), and listen backlog, to avoid re-implementing them in each transport.
Other OSes also have the analog of AFD. For instance, FreeBSD has a module with
soisconnected() and soreceive() functions, which are not tied to TCP/IP, but
called from inside the "netinet" TCP/IP code.
Now let's return to WinSock. So, if your implementation is a kernel driver with
TDI upper edge, then you already have AFD.SYS for you, and MSAFD.DLL WinSock
provider for you. This will give you lots of socket stuff, including all async
IO, FIONREAD, SO_SNDBUF, SO_RCVBUF, SO_LINGER, and listen backlog.
Nevertheless, some things are still not covered. They are your
protocol-speficic things like gethostbyname() or protocol-specific
non-SOL_SOCKET socket options (like TCP_NODELAY). To handle this, you must
write a Provider Helper DLL, which is loaded as a side add-on to MSAFD and
handles what MSAFD cannot. Usually, it does this by private IOCTLs to the
kernel protocol driver, which can even bypass TDI.
TCP/IP (AF_INET) family has such a DLL called WSHTCPIP.DLL, and its simplified
source named WSHSMPLE is in the DDK.
Now the second song. What if your protocol is not a kernel module at all? Or a
kernel module, but with no TDI upper edge? In this case, you cannot use MSAFD
and AFD.SYS, and thus will need to write your Provider DLL from scratch,
exporting all necessary WSPxxx functions.
There is also some subtle moment here. Lots of Win32 apps assumes that the
SOCKET value is the same as Win32 file handle, and are using the return value
of socket() in ReadFile or such.
With AFD (and thus TCP/IP), this works, since in this case SOCKET is a real
file handle pointing to inside AFD.SYS.
But, if your particular protocol has no kernel mode module, you will have
troubles with these apps which will use ReadFile on your socket handle. To
handle this, there is a WS2IFSL.SYS auxiliary driver and WPUCreateSocketHandle
function. This must be called by your provider's WSPSocket path. It calls
CreateFile on WS2IFSL.SYS and registers the resulting handle in WinSock. After
this, if any other app will do Read/WriteFile on this handle, WS2IFSL will
redirect them to the same process's WinSock DLLs and to your provider's
WSPSend/Recv which will do the real job.
If your protocol has the kernel mode part, but is not TDI, then you already
have a handle suitable for Read/WriteFile. Nevertheless, for routing of
setsockopt() to your particular DLL and some other purposes, the handle must be
registered in WinSock using WPUModifyIFSHandle. The provider's WSPSocket path
calls CreateFile on your kernel component, and then WPUModifyIFSHandle.
Now the third song. Layered service providers. They are "providers over
providers", like the stackable filters. Its job is to alter the functionality
of the base provider (usually MSAFD for TCP/IP).
Not so good a thing. Lots of TCP/IP traffic does not go via WinSock and thus is
invisible to LSP. All SMB traffic. PPTP/L2TP traffic. HTTP traffic on Windows
2003 webserver (http.sys). These kernel facilities talk directly to TDI upper
edge of TCPIP and bypass WinSock at all. Be prepared for this.
On Windows CE 4.2, SSL is implemented as a LSP - so, just call socket() with a
proper address family and you will have SSL. Dunno on usual Windows, maybe it
is also such.
-- Maxim Shatskih, Windows DDK MVP StorageCraft Corporation maxim@storagecraft.com http://www.storagecraft.com
- Next message: Maxim S. Shatskih: "Re: IoGetDeviceObjectPointer ok but IoGetDeviceProperty crashed"
- Previous message: Maxim S. Shatskih: "Re: Softice Symbol table"
- In reply to: Harry Potter: "help me with my understanding of WSPRecv/From"
- Next in thread: Harry Potter: "Re: help me with my understanding of WSPRecv/From"
- Reply: Harry Potter: "Re: help me with my understanding of WSPRecv/From"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|