Tuesday, 10 August 2004

How does TransmitFile actually work?

Last week, Larry Osterman blogged a little about TransmitFile. I was sure I'd read somewhere that it was implemented entirely in kernel mode, but I couldn't find that assertion.

So I pulled out DUMPBIN. This is what I found, after writing a little test server I call Really Simple File Transfer Protocol - it listens on a socket, then when a client connects it dumps a file down the connection; like I said, Really Simple. It's so simple it doesn't allow concurrent connections.

The TransmitFile function in MSWSOCK.DLL is a simple wrapper around a call to WSAIoctl using the SIO_GET_EXTENSION_FUNCTION_POINTER control code, then calling the result (if WSAIoctl does not return SOCKET_ERROR). For a standard TCP socket using Microsoft's stack, the WSAIoctl call returns the address of mswsock!MSAFD_TransmitFile (an internal function, you won't see it in the export table). In turn, this function does a bit of checking then calls ntdll!NtDeviceIoControlFile, then waits for an object to be signalled and returns. NtDeviceIoControlFile is the underlying NT function called by DeviceIoControl - MSWSOCK.DLL is calling into the TCP device driver, MSAFD.SYS.

I decided to stop there, as I already had enough of a headache from reading x86 disassembly...

No comments: