The TdiClient sample is a simple driver that demonstrates many of the
the basic principles involved in a Tdi Client. It is written to work with a variety
of Tdi providers in order to more completely demonstrate how the Tdi interface is used.
The sample is composed of the Tdisample.sys driver, which is the actual Tdi client, and
a simple user application, Tdisamp.exe, which communicates through this driver. The user
application is itself divided into two parts--a library, which knows how to talk to Tdisample.sys,
and the actual program, which uses these library functions to communicate between two machines.
Run the build command from this directory to build the sample—it creates the
binaries Tdisample.sys and Tdisamp.exe.
To install this driver on Windows® 2000, use the INF also found in this directory.
Tdisample is installed as a service (called “Tdisample Driver” in the supplied
INFs/notification object). To install, follow the steps below.
Prepare a floppy disk (or installation directory) that contains these files:
nettdic.inf, Tdisample.sys and Tdisamp.exe.
On the desktop, right-click the My Network Places icon and choose Properties.
Right-click on any Local Area Connection icon and choose Properties.
Click Install, then Service, then Add, then Have Disk.
Browse to the drive/directory containing the files listed above. Click OK. This
should show “Tdisample Driver” in a list of Network Services. Highlight this and
click OK. This should install the Tdisample driver.
Click OK or Yes each time the system prompts with a warning regarding
installation of unsigned files. This is necessary because binaries generated via
the DDK build environment are not signed.
The sample is designed to be run between two machines, one running as the server and the
other running as the client. In addition, it can be run over several different Tdi providers
(ie, protocols). The server should always be started first, then the client. The two machines must
be on the same network--preferable on the same network segment--in order for the test to run. Also,
they must both be running over the same protocol. The examples below show the various ways in
which the tests can be run.
Running test over ipx:
tdisamp /server /ipx
tdisamp /ipx
Running test over tcpip (ipv4)
tdisamp /server /ipv4
tdisamp /ipv4
Running test over Netbios
tdisamp /server /netbt
tdisamp /netbt
File Description
dirs causes lib, sys, and tdisamp directories to be built tdiclient.htm this help file nettdic.inf installation file inc\glbconst.h constants shared between library and driver inc\glbtypes.h structure types shared between library and driver inc\libbase.h constants and structures shared between library and application inc\libprocs.h library functions available to the application lib\makefile makefile for the library lib\sources file listing sources to be used in building the library lib\libvars.h defines private to the library lib\stdafx.h precompiled header for library lib\connect.cpp user mode apis for making and breaking connections lib\events.cpp user mode apis for enabling event handlers lib\misc.cpp user mode apis for miscellaneous operations lib\open.cpp user mode apis for opening and close control, address, and endpoint objects lib\receive.cpp user mode apis for receiving data lib\send.cpp user mode apis for sending data lib\stdafx.cpp for creating binary associated with precompiled header lib\tdilib.cpp user mode apis for starting and ending communication with driver lib\tdiquery.cpp user mode apis for querying tdi provider lib\utils.cpp library internal functions for communicating with the driver tdisamp\makefile makefile for user mode application tdisamp\sources file listing sources used in building the user mode application tdisamp\tdisamp.cpp actual source for user mode application sys\makefile makefile for driver sys\sources file listing sources used in building the driver sys\sysprocs.h prototypes for driver functions sys\sysvars.h driver-specific types and constants sys\buffer.cpp functions for doing posted receives sys\connect.cpp functions for establishing and breaking connections sys\events.cpp functions for enabling event handlers sys\open.cpp functions for opening and closing control, address, and endpoint objects sys\rcvdgram.cpp functions for receiving datagrams using event handlers sys\receive.cpp functions for receiving data over a connection using event handlers sys\recvcom.cpp common receive utilities sys\requests.cpp function dealing with device io requests sys\send.cpp functions for sending data or datagrams sys\tdipnp.cpp functions for dealing with pnp and power management events sys\tdiquery.cpp functions for dealing with tdi requests sys\tdisample.cpp functions dealing with driver initialization and unloading sys\utils.cpp some utility functions sys\tdisample.rc resources file for driver
The general layout of the source code is that the user application calls the functions provided by
the library to do all the work. The library function packs up the arguments for the driver and calls
TdiLibDeviceIO. This function is essentially a wrapper for the system's DeviceIoControl function,
which calls the driver at its TSDispatch entry point. The execution is then routed to TSIssueRequest,
which determines what driver function needs to be called to support the request. The appropriate
function is then called. In most cases, the function called in the driver is in a file having the
same name as the function originally called in the library.
Tdisample.sys is writen to be as independent as possible of which protocol is being used as the
tdi provider. For this reason, opening devices as well as sending and receiving data is handled
through the DeviceIoControl mechanism rather than through Open, Read, and Write. An actual Tdi client
is more likely to use these rather than DeviceIoControl.
Since the more interesting part of this sample is the driver, the rest of this section will concentrate
on what goes on there. Hopefully, the inline comments will be helpful in understanding what is
going on throughout the code.
1) During DriverEntry, the TdiSample driver registers itself with the system, informing it of its
various entry points. It then registers itself with TDI by informing it of its pnp handlers
(see sys\tdisample.cpp, function DriverEntry).
Intermediate miniport driver.
2) TDI next calls the TSPnpAddAddressCallback handler once for every address which has been
registered with it. This function will store the name and address of each one received. Both the
name and address are required, since NetBios opens devices on the basis of their name, while ipx
and ipv4 open devices on the basis of their address.
3) TDI also calls the TSPnpBindCallback handler once for each protocol. The sample does nothing
with these calls except to output the call information to the debugger.
4) Memory Management The driver uses a wrapper around the system memory management functions.
This is useful during development and debugging to help track memory leaks and overwrites.
5) Handling Power Management
5.1 During initialization, the TdiSample registers its power management handler
with TDI.
5.2 Power management messages are handled by the TSPnpPowerHandler function. Note that it does
not do anything useful with these messages, but just outputs the messages to the debugger.
Top of page
© 1999 Microsoft Corporation