summaryrefslogtreecommitdiffstats
path: root/private/ntos/afd/afdstr.h
blob: 813270194dd459ae8d62e56011bf3d4f29dede91 (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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    afdstr.h

Abstract:

    This module contains typedefs for structures used by AFD.

Author:

    David Treadwell (davidtr)    21-Feb-1992

Revision History:

--*/

#ifndef _AFDSTR_
#define _AFDSTR_

#ifndef REFERENCE_DEBUG
#if DBG
#define REFERENCE_DEBUG 1
#define GLOBAL_REFERENCE_DEBUG 0
#else
#define REFERENCE_DEBUG 0
#define GLOBAL_REFERENCE_DEBUG 0
#endif
#endif

#if REFERENCE_DEBUG

#define MAX_REFERENCE 64

typedef struct _AFD_REFERENCE_DEBUG {
    PVOID Info1;
    PVOID Info2;
    ULONG Action;
    ULONG NewCount;
} AFD_REFERENCE_DEBUG, *PAFD_REFERENCE_DEBUG;

#if GLOBAL_REFERENCE_DEBUG
#define MAX_GLOBAL_REFERENCE 4096

typedef struct _AFD_GLOBAL_REFERENCE_DEBUG {
    PVOID Info1;
    PVOID Info2;
    ULONG Action;
    ULONG NewCount;
    PVOID Connection;
    LARGE_INTEGER TickCounter;
    PVOID Dummy;
} AFD_GLOBAL_REFERENCE_DEBUG, *PAFD_GLOBAL_REFERENCE_DEBUG;
#endif

#endif

//
// A structure for maintaining work queue information in AFD.
//

typedef struct _AFD_WORK_ITEM {
    LIST_ENTRY WorkItemListEntry;
    PWORKER_THREAD_ROUTINE AfdWorkerRoutine;
    PVOID Context;
} AFD_WORK_ITEM, *PAFD_WORK_ITEM;

//
// Structures for holding connect data pointers and lengths.  This is
// kept separate from the normal structures to save space in those
// structures for transports that do not support and applications
// which do not use connect data.
//

typedef struct _AFD_CONNECT_DATA_INFO {
    PVOID Buffer;
    ULONG BufferLength;
} AFD_CONNECT_DATA_INFO, *PAFD_CONNECT_DATA_INFO;

typedef struct _AFD_CONNECT_DATA_BUFFERS {
    AFD_CONNECT_DATA_INFO SendConnectData;
    AFD_CONNECT_DATA_INFO SendConnectOptions;
    AFD_CONNECT_DATA_INFO ReceiveConnectData;
    AFD_CONNECT_DATA_INFO ReceiveConnectOptions;
    AFD_CONNECT_DATA_INFO SendDisconnectData;
    AFD_CONNECT_DATA_INFO SendDisconnectOptions;
    AFD_CONNECT_DATA_INFO ReceiveDisconnectData;
    AFD_CONNECT_DATA_INFO ReceiveDisconnectOptions;
    TDI_CONNECTION_INFORMATION TdiConnectionInfo;
} AFD_CONNECT_DATA_BUFFERS, *PAFD_CONNECT_DATA_BUFFERS;

//
// Structure used for holding disconnect context information.
//

struct _AFD_ENDPOINT;
struct _AFD_CONNECTION;

typedef struct _AFD_DISCONNECT_CONTEXT {
    LIST_ENTRY DisconnectListEntry;
    struct _AFD_ENDPOINT *Endpoint;
    PTDI_CONNECTION_INFORMATION TdiConnectionInformation;
    LARGE_INTEGER Timeout;
    struct _AFD_CONNECTION *Connection;
    PIRP Irp;
} AFD_DISCONNECT_CONTEXT, *PAFD_DISCONNECT_CONTEXT;

//
// Endpoint and connection structures and related informaion.
//

#define AfdBlockTypeEndpoint     0xAFD0
#define AfdBlockTypeVcConnecting 0xAFD1
#define AfdBlockTypeVcListening  0xAFD2
#define AfdBlockTypeDatagram     0xAFD3
#define AfdBlockTypeConnection   0xAFD4
#define AfdBlockTypeHelper       0xAFD5

#define IS_AFD_ENDPOINT_TYPE( endpoint )                         \
            ( (endpoint)->Type == AfdBlockTypeEndpoint ||        \
              (endpoint)->Type == AfdBlockTypeVcConnecting ||    \
              (endpoint)->Type == AfdBlockTypeVcListening ||     \
              (endpoint)->Type == AfdBlockTypeDatagram ||        \
              (endpoint)->Type == AfdBlockTypeHelper )

#define AfdConnectionStateFree       0
#define AfdConnectionStateUnaccepted 1
#define AfdConnectionStateReturned   2
#define AfdConnectionStateConnected  3
#define AfdConnectionStateClosing    4

typedef struct _AFD_CONNECTION {

    USHORT Type;
    USHORT State;
    LONG ReferenceCount;

    LIST_ENTRY ListEntry;
    HANDLE Handle;
    PFILE_OBJECT FileObject;
    LONGLONG ConnectTime;

    union {

        struct {
            LARGE_INTEGER ReceiveBytesIndicated;
            LARGE_INTEGER ReceiveBytesTaken;
            LARGE_INTEGER ReceiveBytesOutstanding;

            LARGE_INTEGER ReceiveExpeditedBytesIndicated;
            LARGE_INTEGER ReceiveExpeditedBytesTaken;
            LARGE_INTEGER ReceiveExpeditedBytesOutstanding;
            BOOLEAN NonBlockingSendPossible;
            BOOLEAN ZeroByteReceiveIndicated;
        } Bufferring;

        struct {
            LIST_ENTRY ReceiveIrpListHead;
            LIST_ENTRY ReceiveBufferListHead;
            LIST_ENTRY SendIrpListHead;

            CLONG BufferredReceiveBytes;
            CLONG BufferredExpeditedBytes;
            CSHORT BufferredReceiveCount;
            CSHORT BufferredExpeditedCount;

            CLONG ReceiveBytesInTransport;
            CLONG BufferredSendBytes;
            CSHORT ReceiveCountInTransport;
            CSHORT BufferredSendCount;

            PIRP DisconnectIrp;
        } NonBufferring;

    } Common;

    struct _AFD_ENDPOINT *Endpoint;

    CLONG MaxBufferredReceiveBytes;
    CLONG MaxBufferredSendBytes;
    CSHORT MaxBufferredReceiveCount;
    CSHORT MaxBufferredSendCount;

    PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
    PEPROCESS OwningProcess;
    PDEVICE_OBJECT DeviceObject;
    PTRANSPORT_ADDRESS RemoteAddress;
    ULONG RemoteAddressLength;
    BOOLEAN DisconnectIndicated;
    BOOLEAN AbortIndicated;
    BOOLEAN TdiBufferring;
    BOOLEAN ConnectedReferenceAdded;
    BOOLEAN SpecialCondition;
    BOOLEAN CleanupBegun;
    BOOLEAN ClosePendedTransmit;

    AFD_DISCONNECT_CONTEXT DisconnectContext;
    AFD_WORK_ITEM WorkItem;

#if ENABLE_ABORT_TIMER_HACK
    struct _AFD_ABORT_TIMER_INFO * AbortTimerInfo;
#endif  // ENABLE_ABORT_TIMER_HACK

#if REFERENCE_DEBUG
    LONG CurrentReferenceSlot;
    ULONG Dummy1;
    ULONG Dummy2;
    AFD_REFERENCE_DEBUG ReferenceDebug[MAX_REFERENCE];
#endif

} AFD_CONNECTION, *PAFD_CONNECTION;

//
// Some macros that make code more readable.
//

#define VcNonBlockingSendPossible Common.Bufferring.NonBlockingSendPossible
#define VcZeroByteReceiveIndicated Common.Bufferring.ZeroByteReceiveIndicated

#define VcReceiveIrpListHead Common.NonBufferring.ReceiveIrpListHead
#define VcReceiveBufferListHead Common.NonBufferring.ReceiveBufferListHead
#define VcSendIrpListHead Common.NonBufferring.SendIrpListHead

#define VcBufferredReceiveBytes Common.NonBufferring.BufferredReceiveBytes
#define VcBufferredExpeditedBytes Common.NonBufferring.BufferredExpeditedBytes
#define VcBufferredReceiveCount Common.NonBufferring.BufferredReceiveCount
#define VcBufferredExpeditedCount Common.NonBufferring.BufferredExpeditedCount

#define VcReceiveBytesInTransport Common.NonBufferring.ReceiveBytesInTransport
#define VcReceiveCountInTransport Common.NonBufferring.ReceiveCountInTransport

#define VcBufferredSendBytes Common.NonBufferring.BufferredSendBytes
#define VcBufferredSendCount Common.NonBufferring.BufferredSendCount

#define VcDisconnectIrp Common.NonBufferring.DisconnectIrp

//
// Information stored about each transport device name for which there
// is an open endpoint.
//

typedef struct _AFD_TRANSPORT_INFO {
    LIST_ENTRY TransportInfoListEntry;
    UNICODE_STRING TransportDeviceName;
    TDI_PROVIDER_INFO ProviderInfo;
    //WCHAR TransportDeviceNameStructure;
} AFD_TRANSPORT_INFO, *PAFD_TRANSPORT_INFO;

//
// Endpoint state definitions.
//

#define AfdEndpointStateOpen              0
#define AfdEndpointStateBound             1
#define AfdEndpointStateListening         2
#define AfdEndpointStateConnected         3
#define AfdEndpointStateCleanup           4
#define AfdEndpointStateClosing           5
#define AfdEndpointStateTransmitClosing   6
#define AfdEndpointStateInvalid           7

typedef struct _AFD_ENDPOINT {

    USHORT Type;
    UCHAR State;

    LONG ReferenceCount;

    BOOLEAN NonBlocking;
    BOOLEAN InLine;
    BOOLEAN TdiBufferring;

    LIST_ENTRY GlobalEndpointListEntry;
    LIST_ENTRY ConstrainedEndpointListEntry;
    AFD_ENDPOINT_TYPE EndpointType;
    HANDLE AddressHandle;
    PFILE_OBJECT AddressFileObject;

    //
    // Use a union to overlap the fields that are exclusive to datagram
    // connecting, or listening endpoints.  Since many fields are
    // relevant to only one type of socket, it makes no sense to
    // maintain the fields for all sockets--instead, save some nonpaged
    // pool by combining them.
    //

    union {

        //
        // Information for circuit-based connected endpoints.
        //

        struct {
            PAFD_CONNECTION Connection;
            NTSTATUS ConnectStatus;
            struct _AFD_ENDPOINT *ListenEndpoint;
        } VcConnecting;

        //
        // Information for circuit-based listening endpoints.
        //

        struct {
            LIST_ENTRY FreeConnectionListHead;
            LIST_ENTRY UnacceptedConnectionListHead;
            LIST_ENTRY ReturnedConnectionListHead;
            LIST_ENTRY ListeningIrpListHead;
            LONG FailedConnectionAdds;
            LONG FreeConnectionCount;
            LONG TdiAcceptPendingCount;
            BOOLEAN EnableDynamicBacklog;
        } VcListening;

        //
        // Information for datagram endpoints.  Note that different
        // information is kept depending on whether the underlying
        // transport buffers internally.
        //

        struct {
            PTRANSPORT_ADDRESS RemoteAddress;
            ULONG RemoteAddressLength;

            LIST_ENTRY ReceiveIrpListHead;
            LIST_ENTRY PeekIrpListHead;
            LIST_ENTRY ReceiveBufferListHead;
            CLONG BufferredDatagramBytes;
            CSHORT BufferredDatagramCount;

            CLONG MaxBufferredReceiveBytes;
            CLONG MaxBufferredSendBytes;
            CSHORT MaxBufferredReceiveCount;
            CSHORT MaxBufferredSendCount;

            BOOLEAN CircularQueueing;
        } Datagram;

    } Common;

    CLONG DisconnectMode;
    CLONG OutstandingIrpCount;
    PTRANSPORT_ADDRESS LocalAddress;
    ULONG LocalAddressLength;
    PVOID Context;
    CLONG ContextLength;
    KSPIN_LOCK SpinLock;
    PEPROCESS OwningProcess;
    PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
    PIRP TransmitIrp;
    struct _AFD_TRANSMIT_FILE_INFO_INTERNAL * TransmitInfo;
    PDEVICE_OBJECT AddressDeviceObject;
    PAFD_TRANSPORT_INFO TransportInfo;
    BOOLEAN ConnectOutstanding;
    BOOLEAN SendDisconnected;
    BOOLEAN EndpointCleanedUp;
    BOOLEAN TdiMessageMode;
    BOOLEAN PollCalled;

    AFD_WORK_ITEM WorkItem;

    //
    // EventSelect info.
    //

    PKEVENT EventObject;
    ULONG EventsEnabled;
    ULONG EventsDisabled;
    ULONG EventsActive;
    NTSTATUS EventStatus[AFD_NUM_POLL_EVENTS];

    //
    // Socket grouping.
    //

    LONG GroupID;
    AFD_GROUP_TYPE GroupType;

    //
    // Debug stuff.
    //

#if REFERENCE_DEBUG
    PAFD_REFERENCE_DEBUG ReferenceDebug;
    LONG CurrentReferenceSlot;
#endif

#if DBG
    LIST_ENTRY OutstandingIrpListHead;
    LONG ObReferenceBias;
#endif

} AFD_ENDPOINT, *PAFD_ENDPOINT;

//
// A couple of useful manifests that make code more readable.
//

#define ReceiveDatagramIrpListHead Common.Datagram.ReceiveIrpListHead
#define PeekDatagramIrpListHead Common.Datagram.PeekIrpListHead
#define ReceiveDatagramBufferListHead Common.Datagram.ReceiveBufferListHead
#define BufferredDatagramCount Common.Datagram.BufferredDatagramCount
#define BufferredDatagramBytes Common.Datagram.BufferredDatagramBytes

#define AFD_CONNECTION_FROM_ENDPOINT( endpoint )                        \
            ( (endpoint)->Type == AfdBlockTypeVcConnecting ?            \
                  (endpoint)->Common.VcConnecting.Connection : NULL )

//
// A structure which describes buffers used by AFD to perform bufferring
// for TDI providers which do not perform internal bufferring.
//

typedef struct _AFD_BUFFER {
    union {
        SINGLE_LIST_ENTRY SList;   // for buffer lookaside lists
        LIST_ENTRY BufferListEntry;// to place these structures on lists
    };
    PLIST_ENTRY BufferListHead;    // the global list this buffer belongs to
    struct _AFD_BUFFER *NextBuffer;// next buffer in chain
    PVOID Buffer;                  // a pointer to the actual data buffer
    CLONG BufferLength;            // amount of space allocated for the buffer
    CLONG DataLength;              // actual data in the buffer
    CLONG DataOffset;              // offset in buffer to start of unread data
    PIRP Irp;                      // pointer to the IRP associated w/the buffer
    PMDL Mdl;                      // pointer to an MDL describing the buffer
    PVOID Context;                 // stores context info
    PVOID SourceAddress;           // pointer to address of datagram sender
    CLONG SourceAddressLength;     // length of datagram sender's address
    PFILE_OBJECT FileObject;       // for fast-path TransmitFile
    LONGLONG FileOffset;           // for fast-path TransmitFile
    ULONG ReadLength;              // for fast-path TransmitFile
    USHORT AllocatedAddressLength; // length allocated for address
    BOOLEAN ExpeditedData;         // TRUE if the buffer contains expedited data
    BOOLEAN PartialMessage;        // TRUE if this is a partial message
    TDI_CONNECTION_INFORMATION TdiInputInfo;   // holds info for TDI requests
    TDI_CONNECTION_INFORMATION TdiOutputInfo;  // holds info for TDI requests
#if DBG
    CLONG TotalChainLength;
    LIST_ENTRY DebugListEntry;
    PVOID Caller;
    PVOID CallersCaller;
#endif
    // IRP Irp;                    // the IRP follows this structure
    // MDL Mdl;                    // the MDL follows the IRP
    // UCHAR Address[];            // address of datagram sender
    // UCHAR Buffer[BufferLength]; // the actual data buffer is last
} AFD_BUFFER, *PAFD_BUFFER;

//
// Macros for making it easier to deal with the debug-only TotalChainLength
// AFD_BUFFER field.
//

#if DBG
#define SET_CHAIN_LENGTH(b,l)   ((b)->TotalChainLength = (l))
#define RESET_CHAIN_LENGTH(b)   ((b)->TotalChainLength = (b)->BufferLength)
#else
#define SET_CHAIN_LENGTH(b,l)
#define RESET_CHAIN_LENGTH(b)
#endif

//
// Internal information for the transmit file IOCTL.  Note that
// this must be the same size as AFD_TRANSMIT_FILE_INFO in afd.h!!!!
//

typedef struct _AFD_TRANSMIT_IRP_INFO {
    PIRP Irp;
    PAFD_BUFFER AfdBuffer;
    ULONG Length;
} AFD_TRANSMIT_IRP_INFO, *PAFD_TRANSMIT_IRP_INFO;

typedef struct _AFD_TRANSMIT_FILE_INFO_INTERNAL {
    LONGLONG Offset;
    LONGLONG FileWriteLength;
    ULONG SendPacketLength;
    HANDLE FileHandle;
    PVOID Head;
    ULONG HeadLength;
    PVOID Tail;
    ULONG TailLength;
    ULONG Flags;
    PVOID _Dummy;
    LONGLONG TotalBytesToSend;
    LONGLONG BytesRead;
    LONGLONG BytesSent;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    PFILE_OBJECT TdiFileObject;
    PDEVICE_OBJECT TdiDeviceObject;
    PIRP TransmitIrp;
    PAFD_ENDPOINT Endpoint;
    PMDL FileMdl;
    PMDL HeadMdl;
    PMDL TailMdl;
    PMDL FirstFileMdlAfterHead;
    PMDL LastFileMdlBeforeTail;
    PIRP IrpUsedToSendTail;
    ULONG FileMdlLength;
    BOOLEAN ReadPending;
    BOOLEAN CompletionPending;
    BOOLEAN NeedToSendHead;
    BOOLEAN Queued;

    AFD_TRANSMIT_IRP_INFO Read;
    AFD_TRANSMIT_IRP_INFO Send1;
    AFD_TRANSMIT_IRP_INFO Send2;

    WORK_QUEUE_ITEM WorkQueueItem;

#if DBG
    BOOLEAN Completed;
    ULONG ReadPendingLastSetTrueLine;
    ULONG ReadPendingLastSetFalseLine;
    PVOID Debug1;
    PVOID Debug2;
#endif

} AFD_TRANSMIT_FILE_INFO_INTERNAL, *PAFD_TRANSMIT_FILE_INFO_INTERNAL;

//
// Pointer to an IRP cleanup routine. This is used as a parameter to
// AfdCompleteIrpList().
//

typedef
VOID
(NTAPI * PAFD_IRP_CLEANUP_ROUTINE)(
    IN PIRP Irp
    );

//
// Debug statistics.
//

typedef struct _AFD_QUOTA_STATS {
    LARGE_INTEGER Charged;
    LARGE_INTEGER Returned;
} AFD_QUOTA_STATS;

typedef struct _AFD_HANDLE_STATS {
    LONG AddrOpened;
    LONG AddrClosed;
    LONG AddrRef;
    LONG AddrDeref;
    LONG ConnOpened;
    LONG ConnClosed;
    LONG ConnRef;
    LONG ConnDeref;
    LONG FileRef;
    LONG FileDeref;
} AFD_HANDLE_STATS;

typedef struct _AFD_QUEUE_STATS {
    LONG AfdWorkItemsQueued;
    LONG ExWorkItemsQueued;
    LONG WorkerEnter;
    LONG WorkerLeave;
    LONG AfdWorkItemsProcessed;
    PETHREAD AfdWorkerThread;
} AFD_QUEUE_STATS;

typedef struct _AFD_CONNECTION_STATS {
    LONG ConnectedReferencesAdded;
    LONG ConnectedReferencesDeleted;
    LONG GracefulDisconnectsInitiated;
    LONG GracefulDisconnectsCompleted;
    LONG GracefulDisconnectIndications;
    LONG AbortiveDisconnectsInitiated;
    LONG AbortiveDisconnectsCompleted;
    LONG AbortiveDisconnectIndications;
} AFD_CONNECTION_STATS;

//
// Buffer for lookaside list descriptors. Lookaside list descriptors
// cannot be statically allocated, as they need to ALWAYS be nonpageable,
// even when the entire driver is paged out.
//

typedef struct _AFD_LOOKASIDE_LISTS {
    NPAGED_LOOKASIDE_LIST WorkQueueList;
    NPAGED_LOOKASIDE_LIST LargeBufferList;
    NPAGED_LOOKASIDE_LIST MediumBufferList;
    NPAGED_LOOKASIDE_LIST SmallBufferList;
} AFD_LOOKASIDE_LISTS, *PAFD_LOOKASIDE_LISTS;

#endif // ndef _AFDSTR_