summaryrefslogtreecommitdiffstats
path: root/private/ntos/nbt/vxd/tdiaddr.c
blob: 7b2727dfabb01e65bf4b0260f578df2338aeeaf7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//
//
//  tdiaddr.c
//
//  This file contains code relating to manipulation of address objects
//  that is specific to the VXD environment.  It creates address endpoints
//  with the transport provider.

#include <nbtprocs.h>
#include <tdistat.h>    // TDI error codes

//----------------------------------------------------------------------------
NTSTATUS
NbtTdiOpenAddress (
    OUT PHANDLE             pFileHandle,
    OUT PDEVICE_OBJECT      *ppDeviceObject,
    OUT PFILE_OBJECT        *ppFileObject,
    IN  tDEVICECONTEXT      *pDeviceContext,
    IN  USHORT               PortNumber,
    IN  ULONG               IpAddress,
    IN  ULONG               Flags
    )
/*++

Routine Description:

    Note: This synchronous call may take a number of seconds. It runs in
    the context of the caller.  The code Opens an Address object with the
    transport provider and then sets up event handlers for Receive,
    Disconnect, Datagrams and Errors.

    The address data structures are found in tdi.h , but they are rather
    confusing since the definitions have been spread across several data types.
    This section shows the complete data type for Ip address:

    typedef struct
    {
        int     TA_AddressCount;
        struct _TA_ADDRESS
        {
            USHORT  AddressType;
            USHORT  AddressLength;
            struct _TDI_ADDRESS_IP
            {
                USHORT  sin_port;
                USHORT  in_addr;
                UCHAR   sin_zero[8];
            } TDI_ADDRESS_IP

        } TA_ADDRESS[AddressCount];

    } TRANSPORT_ADDRESS

    An EA buffer is allocated (for the IRP), with an EA name of "TransportAddress"
    and value is a structure of type TRANSPORT_ADDRESS.

Arguments:

    bTCP    - a boolean to say if we are openning a TCP port or a UDP port

Return Value:

    The function value is the status of the operation.

--*/
{
    NTSTATUS                    status = STATUS_SUCCESS ;
    TA_IP_ADDRESS               taip ;   // This is really a TRANSPORT_ADDRESS
    TDI_REQUEST                 tdirequest ;

    DbgPrint("TdiOpenAddress called\n\r");


    taip.TAAddressCount = 1 ;
    taip.Address[0].AddressLength       = sizeof( TDI_ADDRESS_IP ) ;
    taip.Address[0].AddressType         = TDI_ADDRESS_TYPE_IP ;
    taip.Address[0].Address[0].sin_port = htons(PortNumber);    // put in network order
    taip.Address[0].Address[0].in_addr  = htonl(IpAddress);
    CTEZeroMemory( taip.Address[0].Address[0].sin_zero,
                   sizeof( taip.Address[0].Address[0].sin_zero ) ) ;

    #define TCP_PORT    6
    #define UDP_PORT   17
    status = TdiVxdOpenAddress( &tdirequest,
                                (PTRANSPORT_ADDRESS) &taip,
                                Flags & SESSION_FLAG ? TCP_PORT : UDP_PORT,
                                NULL ) ;

    if ( status == TDI_SUCCESS )
    {
        HANDLE hAddress = tdirequest.Handle.AddressHandle ;

        //
        //  As a VXD, the p*FileObject in the DeviceContext structure will
        //  contain the TDI Address.  For compatibility with NT (may want
        //  to change this with an environment specific address).
        //
        *ppFileObject = (PFILE_OBJECT) hAddress ;

        if (Flags & TCP_FLAG)
        {
            // TCP port needs several event handlers for connection
            // management
            status = TdiVxdSetEventHandler(
                            hAddress,
                            TDI_EVENT_RECEIVE,
                            (PVOID)TdiReceiveHandler,
                            (PVOID)pDeviceContext);

            ASSERTMSG( "Failed to set Receive event handler",
                       status == TDI_SUCCESS );

            status = TdiVxdSetEventHandler(
                            hAddress,
                            TDI_EVENT_DISCONNECT,
                            (PVOID)TdiDisconnectHandler,
                            (PVOID)pDeviceContext);
            ASSERTMSG( "Failed to set Disconnect event handler",
                       status == TDI_SUCCESS);

            // only set an connect handler if the session flag is set.
            // In this case the address being opened is the Netbios session
            // port 139
            if (Flags & SESSION_FLAG)
            {
                status = TdiVxdSetEventHandler(
                                hAddress,
                                TDI_EVENT_CONNECT,
                                (PVOID)TdiConnectHandler,
                                (PVOID)pDeviceContext);

                ASSERTMSG((PUCHAR)"Failed to set Receive event handler",
                          status == TDI_SUCCESS );
            }
        }
        else
        {
            // Datagram ports only need this event handler
            if (PortNumber == NBT_DATAGRAM_UDP_PORT)
            {
                // Datagram Udp Handler
                status = TdiVxdSetEventHandler(
                                hAddress,
                                TDI_EVENT_RECEIVE_DATAGRAM,
                                (PVOID)TdiRcvDatagramHandler,
                                (PVOID)pDeviceContext);
                ASSERTMSG("Failed to set Receive Datagram event handler",
                          status == TDI_SUCCESS );
            }
            else
            {
                // Name Service Udp handler
                status = TdiVxdSetEventHandler(
                                hAddress,
                                TDI_EVENT_RECEIVE_DATAGRAM,
                                (PVOID)TdiRcvNameSrvHandler,
                                (PVOID)pDeviceContext);
                ASSERTMSG( "Failed to set Receive Datagram event handler",
                           status == TDI_SUCCESS );
            }
        }

        status = TdiVxdSetEventHandler(
                        hAddress,
                        TDI_EVENT_ERROR,
                        (PVOID)TdiErrorHandler,
                        (PVOID)pDeviceContext);
        ASSERTMSG("Failed to set Error event handler",
                  status == TDI_SUCCESS );


    }

#ifdef DEBUG
    if ( status != STATUS_SUCCESS )
    {
        DbgPrint("NbtTdiOpenAddress: status == ") ;
        DbgPrintNum( status ) ; DbgPrint("\n\r") ;
    }
#endif
    return(status);
}