TDISAMPLE.SYS -- Sample Tdi Client Driver

SUMMARY

Sample Tdi Client Driver

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.

BUILDING THE SAMPLE

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.

INSTALLING THE SAMPLE

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.

RUNNING THE SAMPLE

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

CODE TOUR

File Manifest

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

Programming Tour

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