B.8.4  Using Paired NetBIOS Providers

A NetBIOS provider must closely couple its connection-oriented services with its connectionless services. However, through TPI, a STREAMS stack must declare itself as either a connection-oriented (T_COTS) or a connectionless (T_CLTS) provider. Therefore a STREAMS NetBIOS provider has to be implemented via two drivers: a T_COTS driver and a T_CTLS driver. For example, NetBIOS over TCP/IP is provided by the following STREAMS drivers:

\device\streams\nbt

\device\streams\nbdg

Example: DriverEntry Routine for nbt.sys

#include <ntddk.h>

#include <tdi.h>

#include <stream.h>

#include <xti.h>

 

**********************

extern struct streamtab nbtinfo, nbdginfo;

 

static struct nbaddr BroadcastName = {

    NBBROADCAST | NBGROUPNM,

    "*"

};

 

static STREAMS_TDI_ADDRESS_INFO AddressInfo = {

    sizeof(BroadcastName),                  // Broadcast address length

    TDI_ADDRESS_TYPE_NETBIOS,               // TDI address type

    TRUE,                                   // Directed message goes farther

                                            // than broadcast or multicast

    &BroadcastName                          // Broadcast address

};

 

STREAMS_TDI_INFO NbtTdiInfo = {

    T_COTS_ORD,                             // SERV_type

    &nbdginfo,                              // Partner streamtab

    T_CLTS,                                 // Partner SERV_type

    0,                                      // Option length

    NULL,                                   // Option pointer

    TRUE,                                   // Reuseaddr set by default

    1,                                      // One address info structure

    &AddressInfo                            // AddressInfo

};

 

STREAMS_TDI_INFO NbdgTdiInfo = {

    T_CLTS,                                 // SERV_type

    &nbtinfo,                               // Partner streamtab

    T_COTS_ORD,                             // Partner SERV_type

    0,                                      // Option length

    NULL,                                   // Option pointer

    TRUE,                                   // Reuseaddr set by default

    1,                                      // One address info structure

    &AddressInfo                            // AddressInfo

};

 

NTSTATUS

DriverEntry(

    IN PDRIVER_OBJECT driver,

    PUNICODE_STRING description

    )

{

    NTSTATUS status;

 

    status = ExtractRegistry();

 

    if (status != STATUS_SUCCESS) {

        return(status);

    }

 

    if (nbtinit()) {

        return(STATUS_NO_MEMORY);

    }

 

    status = StrmRegisterDriver(driver, &nbtinfo, NULL, &NbtTdiInfo);

 

    if (status != STATUS_SUCCESS) {

        return(status);

    }

    status = StrmRegisterDriver(driver, &nbdginfo, NULL, &NbdgTdiInfo);

 

    if (status != STATUS_SUCCESS) {

        return(status);

    }

 

    return(status);

 

}