1626 lines
57 KiB
C
1626 lines
57 KiB
C
|
/*++
|
||
|
|
||
|
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_
|
||
|
|
||
|
//
|
||
|
// Make sure that queued spinlocks are not used with
|
||
|
// regular spinlock functions by wrapping them into
|
||
|
// a different structure.
|
||
|
//
|
||
|
typedef struct _AFD_QSPIN_LOCK {
|
||
|
KSPIN_LOCK ActualSpinLock;
|
||
|
} AFD_QSPIN_LOCK, *PAFD_QSPIN_LOCK;
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
#ifndef REFERENCE_DEBUG
|
||
|
#define REFERENCE_DEBUG 1
|
||
|
#endif
|
||
|
|
||
|
#ifndef GLOBAL_REFERENCE_DEBUG
|
||
|
#define GLOBAL_REFERENCE_DEBUG 0
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Debug aid for queued spinlocks
|
||
|
// Allows us to verify that spinlock is released using
|
||
|
// the same handle as it was taken with.
|
||
|
//
|
||
|
typedef struct _AFD_LOCK_QUEUE_HANDLE {
|
||
|
KLOCK_QUEUE_HANDLE LockHandle;
|
||
|
PAFD_QSPIN_LOCK SpinLock;
|
||
|
} AFD_LOCK_QUEUE_HANDLE, *PAFD_LOCK_QUEUE_HANDLE;
|
||
|
|
||
|
#else
|
||
|
|
||
|
#ifndef REFERENCE_DEBUG
|
||
|
#define REFERENCE_DEBUG 0
|
||
|
#endif
|
||
|
|
||
|
#ifndef GLOBAL_REFERENCE_DEBUG
|
||
|
#define GLOBAL_REFERENCE_DEBUG 0
|
||
|
#endif
|
||
|
|
||
|
#define AFD_LOCK_QUEUE_HANDLE KLOCK_QUEUE_HANDLE
|
||
|
#define PAFD_LOCK_QUEUE_HANDLE PKLOCK_QUEUE_HANDLE
|
||
|
|
||
|
#endif // DBG
|
||
|
|
||
|
#if REFERENCE_DEBUG
|
||
|
|
||
|
#define MAX_REFERENCE 64
|
||
|
|
||
|
typedef union _AFD_REFERENCE_DEBUG {
|
||
|
struct {
|
||
|
ULONGLONG NewCount:4;
|
||
|
ULONGLONG LocationId:12;
|
||
|
ULONGLONG TickCount:16;
|
||
|
ULONGLONG Param:32;
|
||
|
};
|
||
|
ULONGLONG QuadPart;
|
||
|
} AFD_REFERENCE_DEBUG, *PAFD_REFERENCE_DEBUG;
|
||
|
C_ASSERT (sizeof (AFD_REFERENCE_DEBUG)==sizeof (ULONGLONG));
|
||
|
|
||
|
typedef struct _AFD_REFERENCE_LOCATION {
|
||
|
PCHAR Format;
|
||
|
PVOID Address;
|
||
|
} AFD_REFERENCE_LOCATION, *PAFD_REFERENCE_LOCATION;
|
||
|
|
||
|
LONG
|
||
|
AfdFindReferenceLocation (
|
||
|
IN PCHAR Format,
|
||
|
OUT PLONG LocationId
|
||
|
);
|
||
|
|
||
|
#define AFD_GET_ARL(_s) (_arl ? _arl : AfdFindReferenceLocation((_s),&_arl))
|
||
|
|
||
|
#define AFD_UPDATE_REFERENCE_DEBUG(_rd,_r,_l,_p) { \
|
||
|
PAFD_REFERENCE_DEBUG _s; \
|
||
|
LONG _n; \
|
||
|
LARGE_INTEGER _t; \
|
||
|
_n = InterlockedIncrement( &(_rd)->CurrentReferenceSlot ); \
|
||
|
_s = &(_rd)->ReferenceDebug[_n % MAX_REFERENCE]; \
|
||
|
_s->NewCount = _r; \
|
||
|
_s->LocationId = _l; \
|
||
|
_s->Param = _p; \
|
||
|
KeQueryTickCount (&_t); \
|
||
|
_s->TickCount = _t.QuadPart; \
|
||
|
}
|
||
|
|
||
|
|
||
|
#if GLOBAL_REFERENCE_DEBUG
|
||
|
#define MAX_GLOBAL_REFERENCE 4096
|
||
|
|
||
|
typedef struct _AFD_GLOBAL_REFERENCE_DEBUG {
|
||
|
PVOID Info1;
|
||
|
PVOID Info2;
|
||
|
PVOID Connection;
|
||
|
ULONG_PTR Action;
|
||
|
LARGE_INTEGER TickCounter;
|
||
|
ULONG NewCount;
|
||
|
ULONG 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 RequestConnectionInfo;
|
||
|
TDI_CONNECTION_INFORMATION ReturnConnectionInfo;
|
||
|
ULONG Flags;
|
||
|
} 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 {
|
||
|
LARGE_INTEGER Timeout;
|
||
|
PIRP Irp;
|
||
|
} AFD_DISCONNECT_CONTEXT, *PAFD_DISCONNECT_CONTEXT;
|
||
|
|
||
|
|
||
|
typedef struct _AFD_LR_LIST_ITEM AFD_LR_LIST_ITEM, *PAFD_LR_LIST_ITEM;
|
||
|
typedef BOOLEAN (* PAFD_LR_LIST_ROUTINE) (PAFD_LR_LIST_ITEM Item);
|
||
|
|
||
|
struct _AFD_LR_LIST_ITEM {
|
||
|
SINGLE_LIST_ENTRY SListLink; // Link in the list
|
||
|
PAFD_LR_LIST_ROUTINE Routine; // Processing routine;
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// Endpoint and connection structures and related informaion.
|
||
|
//
|
||
|
//
|
||
|
// Block types that identify which fields are
|
||
|
// available in the strucutures.
|
||
|
//
|
||
|
|
||
|
#define AfdBlockTypeEndpoint 0xAFD0
|
||
|
#define AfdBlockTypeDatagram 0xAFD1
|
||
|
#define AfdBlockTypeVcConnecting 0xAFD2
|
||
|
#define AfdBlockTypeVcListening 0xAFD4
|
||
|
#define AfdBlockTypeVcBoth 0xAFD6
|
||
|
#define AfdBlockTypeConnection 0xAFD8
|
||
|
|
||
|
#define AfdBlockTypeHelper 0xAAFD
|
||
|
#define AfdBlockTypeInvalidConnection 0xEAFD
|
||
|
#define AfdBlockTypeInvalidEndpoint 0xCAFD
|
||
|
|
||
|
#define AfdBlockTypeSanHelper 0x0AFD
|
||
|
#define AfdBlockTypeSanEndpoint 0x1AFD
|
||
|
|
||
|
#if DBG
|
||
|
#define IS_AFD_ENDPOINT_TYPE( endpoint ) \
|
||
|
( (endpoint)->Type == AfdBlockTypeEndpoint || \
|
||
|
(endpoint)->Type == AfdBlockTypeDatagram || \
|
||
|
(endpoint)->Type == AfdBlockTypeVcConnecting || \
|
||
|
(endpoint)->Type == AfdBlockTypeVcListening || \
|
||
|
(endpoint)->Type == AfdBlockTypeVcBoth || \
|
||
|
(endpoint)->Type == AfdBlockTypeHelper || \
|
||
|
(endpoint)->Type == AfdBlockTypeSanHelper || \
|
||
|
(endpoint)->Type == AfdBlockTypeSanEndpoint )
|
||
|
#endif
|
||
|
|
||
|
#define AfdConnectionStateFree 0
|
||
|
#define AfdConnectionStateUnaccepted 1
|
||
|
#define AfdConnectionStateReturned 2
|
||
|
#define AfdConnectionStateConnected 3
|
||
|
#define AfdConnectionStateClosing 4
|
||
|
|
||
|
//
|
||
|
// Flags that further qualify the state of the connection
|
||
|
//
|
||
|
typedef struct AFD_CONNECTION_STATE_FLAGS {
|
||
|
union {
|
||
|
struct {
|
||
|
LOGICAL TdiBufferring:1, // (Does not really belon here)
|
||
|
:3, // This spacing makes strcutures
|
||
|
// much more readable (hex) in the
|
||
|
// debugger and has no effect
|
||
|
// on the generated code as long
|
||
|
// as number of flags is less than
|
||
|
// 8 (we still take up full 32 bits
|
||
|
// because of aligment requiremens
|
||
|
// of most other fields)
|
||
|
AbortIndicated:1,
|
||
|
:3,
|
||
|
DisconnectIndicated:1,
|
||
|
:3,
|
||
|
ConnectedReferenceAdded:1,
|
||
|
:3,
|
||
|
SpecialCondition:1,
|
||
|
:3,
|
||
|
CleanupBegun:1,
|
||
|
:3,
|
||
|
ClosePendedTransmit:1,
|
||
|
:3,
|
||
|
OnLRList:1,
|
||
|
SanConnection:1,
|
||
|
:2;
|
||
|
};
|
||
|
LOGICAL ConnectionStateFlags;
|
||
|
};
|
||
|
} AFD_CONNECTION_STATE_FLAGS;
|
||
|
C_ASSERT (sizeof (AFD_CONNECTION_STATE_FLAGS)==sizeof (LOGICAL));
|
||
|
|
||
|
typedef struct _AFD_CONNECTION {
|
||
|
// *** Frequently used, mostly read-only fields (state/type/flag changes are rare).
|
||
|
USHORT Type;
|
||
|
USHORT State;
|
||
|
AFD_CONNECTION_STATE_FLAGS ;
|
||
|
|
||
|
struct _AFD_ENDPOINT *Endpoint;
|
||
|
PFILE_OBJECT FileObject;
|
||
|
PDEVICE_OBJECT DeviceObject;
|
||
|
PEPROCESS OwningProcess;
|
||
|
|
||
|
|
||
|
union {
|
||
|
LONGLONG ConnectTime;
|
||
|
PIRP AcceptIrp;
|
||
|
PIRP ListenIrp;
|
||
|
PIRP ConnectIrp; // for SAN
|
||
|
};
|
||
|
|
||
|
// *** Frequently used volatile fields.
|
||
|
volatile LONG ReferenceCount;
|
||
|
|
||
|
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;
|
||
|
|
||
|
CLONG BufferredReceiveBytes;
|
||
|
CLONG BufferredExpeditedBytes;
|
||
|
|
||
|
USHORT BufferredReceiveCount;
|
||
|
USHORT BufferredExpeditedCount;
|
||
|
CLONG ReceiveBytesInTransport;
|
||
|
|
||
|
LIST_ENTRY SendIrpListHead;
|
||
|
|
||
|
CLONG BufferredSendBytes;
|
||
|
CLONG BufferredSendCount;
|
||
|
|
||
|
PIRP DisconnectIrp;
|
||
|
|
||
|
LONG ReceiveIrpsInTransport; // debug only.
|
||
|
} NonBufferring;
|
||
|
|
||
|
} Common;
|
||
|
|
||
|
|
||
|
CLONG MaxBufferredReceiveBytes;
|
||
|
CLONG MaxBufferredSendBytes;
|
||
|
|
||
|
PTRANSPORT_ADDRESS RemoteAddress;
|
||
|
ULONG RemoteAddressLength;
|
||
|
LONG Sequence;
|
||
|
|
||
|
HANDLE Handle;
|
||
|
|
||
|
|
||
|
|
||
|
union {
|
||
|
AFD_WORK_ITEM WorkItem; // Work item to free the connection
|
||
|
// Connection has to be at ref 0 to be
|
||
|
// on the work queue, so it cannot be
|
||
|
// on the lists below or being disconnected
|
||
|
// because when on any of these lists the
|
||
|
// ref count is above 0.
|
||
|
struct {
|
||
|
union {
|
||
|
AFD_DISCONNECT_CONTEXT DisconnectContext;
|
||
|
// Disconnect operation context, we cannot be
|
||
|
// on the listening endpoint list
|
||
|
SINGLE_LIST_ENTRY SListEntry;
|
||
|
// Links for listening endpoint lists
|
||
|
LIST_ENTRY ListEntry;
|
||
|
};
|
||
|
AFD_LR_LIST_ITEM LRListItem; // Link for low resource list. When on this
|
||
|
// list connection is referenced, but it can
|
||
|
// also be on the listening endpoint list or
|
||
|
// in the process of disconnecting.
|
||
|
};
|
||
|
};
|
||
|
|
||
|
PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
|
||
|
|
||
|
#if REFERENCE_DEBUG
|
||
|
LONG CurrentReferenceSlot;
|
||
|
AFD_REFERENCE_DEBUG ReferenceDebug[MAX_REFERENCE];
|
||
|
#endif
|
||
|
|
||
|
#ifdef _AFD_VERIFY_DATA_
|
||
|
ULONGLONG VerifySequenceNumber;
|
||
|
#endif // _AFD_VERIFY_DATA_
|
||
|
|
||
|
} AFD_CONNECTION, *PAFD_CONNECTION;
|
||
|
|
||
|
#ifdef _AFD_VERIFY_DATA_
|
||
|
VOID
|
||
|
AfdVerifyBuffer (
|
||
|
PAFD_CONNECTION Connection,
|
||
|
PVOID Buffer,
|
||
|
ULONG Length
|
||
|
);
|
||
|
VOID
|
||
|
AfdVerifyMdl (
|
||
|
PAFD_CONNECTION Connection,
|
||
|
PMDL Mdl,
|
||
|
ULONG Offset,
|
||
|
ULONG Length
|
||
|
);
|
||
|
VOID
|
||
|
AfdVerifyAddress (
|
||
|
PAFD_CONNECTION Connection,
|
||
|
PTRANSPORT_ADDRESS Address
|
||
|
);
|
||
|
|
||
|
#define AFD_VERIFY_BUFFER(_connection,_buffer,_length) \
|
||
|
AfdVerifyBuffer(_connection,_buffer,_length)
|
||
|
#define AFD_VERIFY_MDL(_connection,_mdl,_offset,_length) \
|
||
|
AfdVerifyMdl(_connection,_mdl,_offset,_length)
|
||
|
#define AFD_VERIFY_ADDRESS(_connection,_address) \
|
||
|
AfdVerifyAddress(_connection,_address)
|
||
|
#else
|
||
|
#define AFD_VERIFY_BUFFER(_connection,_buffer,_length)
|
||
|
#define AFD_VERIFY_MDL(_connection,_mdl,_offset,_length)
|
||
|
#define AFD_VERIFY_ADDRESS(_connection,_address)
|
||
|
#endif // _AFD_VERIFY_DATA_
|
||
|
|
||
|
//
|
||
|
// 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
|
||
|
#if DBG
|
||
|
#define VcReceiveIrpsInTransport Common.NonBufferring.ReceiveIrpsInTransport
|
||
|
#endif
|
||
|
|
||
|
#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;
|
||
|
volatile LONG ReferenceCount;
|
||
|
BOOLEAN InfoValid;
|
||
|
UNICODE_STRING TransportDeviceName;
|
||
|
TDI_PROVIDER_INFO ProviderInfo;
|
||
|
//WCHAR TransportDeviceNameStructure;
|
||
|
} AFD_TRANSPORT_INFO, *PAFD_TRANSPORT_INFO;
|
||
|
|
||
|
//
|
||
|
// Endpoint state definitions (can't be zero or state change
|
||
|
// macros won't work correctly).
|
||
|
//
|
||
|
|
||
|
#define AfdEndpointStateOpen 1
|
||
|
#define AfdEndpointStateBound 2
|
||
|
#define AfdEndpointStateConnected 3
|
||
|
#define AfdEndpointStateCleanup 4
|
||
|
#define AfdEndpointStateClosing 5
|
||
|
#define AfdEndpointStateTransmitClosing 6
|
||
|
#define AfdEndpointStateInvalid 7
|
||
|
|
||
|
//
|
||
|
// Flags that further qualify the state of the endpoint
|
||
|
//
|
||
|
typedef struct AFD_ENDPOINT_STATE_FLAGS {
|
||
|
union {
|
||
|
struct {
|
||
|
LOGICAL Listening:1,
|
||
|
DelayedAcceptance:1,
|
||
|
:2, // This spacing makes strcutures
|
||
|
// much more readable (hex) in the
|
||
|
// debugger and has no effect
|
||
|
// on the generated code as long
|
||
|
// as number of flags is less than
|
||
|
// 8 (we still take up full 32 bits
|
||
|
// because of aligment requiremens
|
||
|
// of most other fields)
|
||
|
NonBlocking:1,
|
||
|
:3,
|
||
|
InLine:1,
|
||
|
:3,
|
||
|
EndpointCleanedUp:1,
|
||
|
:3,
|
||
|
PollCalled:1,
|
||
|
:3,
|
||
|
RoutingQueryReferenced:1,
|
||
|
RoutingQueryIPv6:1,
|
||
|
:2,
|
||
|
DisableFastIoSend:1,
|
||
|
EnableSendEvent:1,
|
||
|
:2,
|
||
|
DisableFastIoRecv:1,
|
||
|
:3;
|
||
|
};
|
||
|
LOGICAL EndpointStateFlags;
|
||
|
};
|
||
|
} AFD_ENDPOINT_STATE_FLAGS;
|
||
|
C_ASSERT (sizeof (AFD_ENDPOINT_STATE_FLAGS)==sizeof (LOGICAL));
|
||
|
|
||
|
typedef struct _AFD_ENDPOINT {
|
||
|
// *** Frequently used, mostly read-only fields (state/type/flag changes are rare).
|
||
|
USHORT Type;
|
||
|
UCHAR State;
|
||
|
BOOLEAN AdminAccessGranted;
|
||
|
ULONG TdiServiceFlags; // Tdi transport flags cached for quick access.
|
||
|
|
||
|
AFD_ENDPOINT_FLAGS __f; // As requested by the application through the
|
||
|
// Winsock2 provider flags and/or socket type
|
||
|
AFD_ENDPOINT_STATE_FLAGS ;
|
||
|
|
||
|
PFILE_OBJECT AddressFileObject;
|
||
|
PDEVICE_OBJECT AddressDeviceObject;
|
||
|
PEPROCESS OwningProcess;
|
||
|
|
||
|
|
||
|
// *** Frequently used volatile fields.
|
||
|
|
||
|
AFD_QSPIN_LOCK SpinLock; // Pointer sized.
|
||
|
volatile LONG ReferenceCount;
|
||
|
ULONG EventsActive;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// 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 endpoints
|
||
|
//
|
||
|
struct {
|
||
|
union {
|
||
|
struct {
|
||
|
// These members are valid for listening endpoints
|
||
|
// (AfdBlockTypeVcListening).
|
||
|
LIST_ENTRY UnacceptedConnectionListHead;
|
||
|
LIST_ENTRY ReturnedConnectionListHead;
|
||
|
LIST_ENTRY ListeningIrpListHead;
|
||
|
|
||
|
// The below lists have their own lock which gets
|
||
|
// used on the machines that do not support 64-bit
|
||
|
// interlocked compare and exchange. On these machines
|
||
|
// using endpoint spinlock to synchronize causes all kinds
|
||
|
// of nasty deadlock conditions.
|
||
|
union {
|
||
|
LIST_ENTRY ListenConnectionListHead; // Delayed accept
|
||
|
SLIST_HEADER FreeConnectionListHead;
|
||
|
};
|
||
|
SLIST_HEADER PreacceptedConnectionsListHead;
|
||
|
|
||
|
LONG FailedConnectionAdds;
|
||
|
LONG TdiAcceptPendingCount;
|
||
|
|
||
|
LONG Sequence;
|
||
|
BOOLEAN EnableDynamicBacklog;
|
||
|
BOOLEAN BacklogReplenishActive; // Worker is scheduled
|
||
|
USHORT MaxExtraConnections; // Extra connections we keep in the free queue
|
||
|
// based on maximum number of AcceptEx requests
|
||
|
} Listening;
|
||
|
struct {
|
||
|
KAPC Apc;
|
||
|
USHORT RemoteSocketAddressOffset; // Offset inside of socket context
|
||
|
// pointing to remote address.
|
||
|
USHORT RemoteSocketAddressLength; // Length of the address.
|
||
|
#ifndef i386
|
||
|
BOOLEAN FixAddressAlignment; // Fix address alignment in
|
||
|
// SuperAccept
|
||
|
#endif
|
||
|
};
|
||
|
};
|
||
|
// These members are valid for all vc endpoints (but
|
||
|
// can be NULL)
|
||
|
PAFD_CONNECTION Connection;
|
||
|
struct _AFD_ENDPOINT *ListenEndpoint;
|
||
|
PAFD_CONNECT_DATA_BUFFERS ConnectDataBuffers;
|
||
|
} VirtualCircuit;
|
||
|
|
||
|
#define VcConnecting VirtualCircuit
|
||
|
#define VcListening VirtualCircuit.Listening
|
||
|
#define VcConnection VirtualCircuit.Connection
|
||
|
//
|
||
|
// Information for datagram endpoints. Note that different
|
||
|
// information is kept depending on whether the underlying
|
||
|
// transport buffers internally.
|
||
|
//
|
||
|
|
||
|
struct {
|
||
|
LIST_ENTRY ReceiveIrpListHead;
|
||
|
LIST_ENTRY PeekIrpListHead;
|
||
|
LIST_ENTRY ReceiveBufferListHead;
|
||
|
|
||
|
CLONG BufferredReceiveBytes;
|
||
|
CLONG BufferredReceiveCount;
|
||
|
|
||
|
CLONG MaxBufferredReceiveBytes;
|
||
|
CLONG BufferredSendBytes;
|
||
|
CLONG MaxBufferredSendBytes;
|
||
|
|
||
|
|
||
|
ULONG RemoteAddressLength;
|
||
|
PTRANSPORT_ADDRESS RemoteAddress;
|
||
|
|
||
|
union {
|
||
|
struct {
|
||
|
LOGICAL CircularQueueing:1,
|
||
|
:3,
|
||
|
HalfConnect:1,
|
||
|
:3,
|
||
|
DisablePUError:1,
|
||
|
:3,
|
||
|
AddressDrop:1,
|
||
|
ResourceDrop:1,
|
||
|
BufferDrop:1,
|
||
|
ErrorDrop:1;
|
||
|
};
|
||
|
LOGICAL Flags;
|
||
|
};
|
||
|
} Datagram;
|
||
|
|
||
|
struct {
|
||
|
LIST_ENTRY SanListLink;
|
||
|
PVOID IoCompletionPort;
|
||
|
PKEVENT IoCompletionEvent;
|
||
|
LONG Plsn; // Provider list sequence number
|
||
|
} SanHlpr;
|
||
|
|
||
|
struct {
|
||
|
struct _AFD_ENDPOINT *SanHlpr;
|
||
|
PFILE_OBJECT FileObject;
|
||
|
union {
|
||
|
//
|
||
|
// We can only have either one of two at any given time.
|
||
|
//
|
||
|
PAFD_SWITCH_CONTEXT SwitchContext;
|
||
|
PVOID SavedContext;
|
||
|
};
|
||
|
PAFD_SWITCH_CONTEXT LocalContext;
|
||
|
LIST_ENTRY IrpList;
|
||
|
ULONG SavedContextLength;
|
||
|
ULONG RequestId;
|
||
|
ULONG SelectEventsActive;
|
||
|
NTSTATUS CtxTransferStatus;
|
||
|
BOOLEAN ImplicitDup; // Dup-ed into another process without
|
||
|
// explicit request from the applicaiton
|
||
|
|
||
|
} SanEndp;
|
||
|
|
||
|
} Common;
|
||
|
|
||
|
|
||
|
volatile PVOID Context;
|
||
|
CLONG ContextLength;
|
||
|
|
||
|
ULONG LocalAddressLength;
|
||
|
PTRANSPORT_ADDRESS LocalAddress;
|
||
|
|
||
|
CLONG DisconnectMode;
|
||
|
CLONG OutstandingIrpCount;
|
||
|
|
||
|
HANDLE AddressHandle; // TDI transport address object
|
||
|
PAFD_TRANSPORT_INFO TransportInfo;
|
||
|
|
||
|
LIST_ENTRY RoutingNotifications; // For non-blocking sockets
|
||
|
LIST_ENTRY RequestList; // For misc requests
|
||
|
|
||
|
LIST_ENTRY GlobalEndpointListEntry;
|
||
|
AFD_WORK_ITEM WorkItem;
|
||
|
|
||
|
PIRP Irp; // AcceptEx or TransmitPackets IRP
|
||
|
//
|
||
|
// Non-zero when state change such as binding, accepting,
|
||
|
// conntecting, and transmit file are in progress.
|
||
|
LONG StateChangeInProgress;
|
||
|
|
||
|
//
|
||
|
// EventSelect info.
|
||
|
//
|
||
|
|
||
|
ULONG EventsEnabled;
|
||
|
NTSTATUS EventStatus[AFD_NUM_POLL_EVENTS]; // Currently 13 events
|
||
|
PKEVENT EventObject;
|
||
|
|
||
|
//
|
||
|
// Socket grouping.
|
||
|
//
|
||
|
|
||
|
LONG GroupID;
|
||
|
AFD_GROUP_TYPE GroupType;
|
||
|
LIST_ENTRY ConstrainedEndpointListEntry;
|
||
|
|
||
|
//
|
||
|
// Debug stuff.
|
||
|
//
|
||
|
|
||
|
#if REFERENCE_DEBUG
|
||
|
LONG CurrentReferenceSlot;
|
||
|
AFD_REFERENCE_DEBUG ReferenceDebug[MAX_REFERENCE];
|
||
|
#endif
|
||
|
|
||
|
#if DBG
|
||
|
LIST_ENTRY OutstandingIrpListHead;
|
||
|
LONG ObReferenceBias;
|
||
|
#endif
|
||
|
|
||
|
} AFD_ENDPOINT, *PAFD_ENDPOINT;
|
||
|
|
||
|
typedef struct _AFD_POLL_ENDPOINT_INFO {
|
||
|
PAFD_ENDPOINT Endpoint;
|
||
|
PFILE_OBJECT FileObject;
|
||
|
HANDLE Handle;
|
||
|
ULONG PollEvents;
|
||
|
} AFD_POLL_ENDPOINT_INFO, *PAFD_POLL_ENDPOINT_INFO;
|
||
|
|
||
|
typedef struct _AFD_POLL_INFO_INTERNAL {
|
||
|
LIST_ENTRY PollListEntry;
|
||
|
ULONG NumberOfEndpoints;
|
||
|
PIRP Irp;
|
||
|
union {
|
||
|
struct {
|
||
|
KDPC Dpc;
|
||
|
KTIMER Timer;
|
||
|
};
|
||
|
KAPC Apc; // for SAN
|
||
|
};
|
||
|
BOOLEAN Unique;
|
||
|
BOOLEAN TimerStarted;
|
||
|
BOOLEAN SanPoll;
|
||
|
AFD_POLL_ENDPOINT_INFO EndpointInfo[1];
|
||
|
} AFD_POLL_INFO_INTERNAL, *PAFD_POLL_INFO_INTERNAL;
|
||
|
|
||
|
//
|
||
|
// 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 DgBufferredReceiveCount Common.Datagram.BufferredReceiveCount
|
||
|
#define DgBufferredReceiveBytes Common.Datagram.BufferredReceiveBytes
|
||
|
#define DgBufferredSendBytes Common.Datagram.BufferredSendBytes
|
||
|
|
||
|
#define AFD_CONNECTION_FROM_ENDPOINT( endpoint ) ( \
|
||
|
(((endpoint)->Type & AfdBlockTypeVcConnecting)==AfdBlockTypeVcConnecting) \
|
||
|
? (endpoint)->Common.VirtualCircuit.Connection \
|
||
|
: NULL \
|
||
|
)
|
||
|
|
||
|
//
|
||
|
// A structure which describes buffers used by AFD to perform bufferring
|
||
|
// for TDI providers which do not perform internal bufferring.
|
||
|
// It is also used in other code path as buffer descriptors.
|
||
|
//
|
||
|
typedef struct _AFD_BUFFER_HEADER AFD_BUFFER_HEADER, *PAFD_BUFFER_HEADER;
|
||
|
|
||
|
#define _AFD_BUFFER_HEADER_ \
|
||
|
union { \
|
||
|
TDI_CONNECTION_INFORMATION TdiInfo; /*holds info for TDI requests */ \
|
||
|
/*with remote address */ \
|
||
|
struct { \
|
||
|
union { /* Links */ \
|
||
|
struct { \
|
||
|
union { \
|
||
|
SINGLE_LIST_ENTRY SList; /* for buffer lookaside lists */ \
|
||
|
PAFD_BUFFER_HEADER Next; /* for transmit packet lists */ \
|
||
|
}; \
|
||
|
PFILE_OBJECT FileObject; /* for cached file in transmit file */ \
|
||
|
}; \
|
||
|
LIST_ENTRY BufferListEntry; /* for endpoint/connection lists */ \
|
||
|
}; \
|
||
|
union { \
|
||
|
struct { \
|
||
|
CLONG DataOffset; /* offset in buffer to start of unread data*/\
|
||
|
union { \
|
||
|
ULONG DatagramFlags; /* flags for datagrams with control info */\
|
||
|
CLONG RefCount; /* Permit partial copy outside the lock*/ \
|
||
|
}; \
|
||
|
}; \
|
||
|
LARGE_INTEGER FileOffset; /* data offset from the start of the file */\
|
||
|
}; \
|
||
|
UCHAR _Test; /* used to test relative field pos in the union */ \
|
||
|
}; \
|
||
|
}; \
|
||
|
union { \
|
||
|
PVOID Context; /* stores context info (endp/conn/etc)*/ \
|
||
|
NTSTATUS Status;/* stores status of completed operation */ \
|
||
|
}; \
|
||
|
PMDL Mdl; /* pointer to an MDL describing the buffer*/ \
|
||
|
CLONG DataLength; /* actual data in the buffer */ \
|
||
|
CLONG BufferLength; /* amount of space allocated for the buffer */ \
|
||
|
union { \
|
||
|
struct { \
|
||
|
/* Flags that describe data in the buffer */ \
|
||
|
UCHAR ExpeditedData:1, /* The buffer contains expedited data*/ \
|
||
|
:3, \
|
||
|
PartialMessage:1,/* This is a partial message*/ \
|
||
|
:3; \
|
||
|
/* Flags that keep allocation information */ \
|
||
|
UCHAR NdisPacket:1, /* Context is a packet to return to NDIS/TDI*/ \
|
||
|
:3, \
|
||
|
Placement:2, /* Relative placement of the pieces */ \
|
||
|
AlignmentAdjusted:1, /* MM block alignment was adjusted to */ \
|
||
|
/* meet AFD buffer alignment requirement */ \
|
||
|
Lookaside:1; /* Poped from Slist (no quota charge)*/ \
|
||
|
}; \
|
||
|
USHORT Flags; \
|
||
|
}; \
|
||
|
USHORT AllocatedAddressLength/* length allocated for address */ \
|
||
|
|
||
|
|
||
|
struct _AFD_BUFFER_HEADER {
|
||
|
_AFD_BUFFER_HEADER_ ;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// The buffer management code makes the following assumptions
|
||
|
// about the union at the top the buffer header so that list
|
||
|
// links and DataOffset field are not in conflict with
|
||
|
// RemoteAddress fields of the TDI_CONNECTION_INFORMATION.
|
||
|
//
|
||
|
C_ASSERT (FIELD_OFFSET (AFD_BUFFER_HEADER, TdiInfo.RemoteAddress) >=
|
||
|
FIELD_OFFSET (AFD_BUFFER_HEADER, _Test));
|
||
|
C_ASSERT (FIELD_OFFSET (AFD_BUFFER_HEADER, TdiInfo.RemoteAddressLength)>=
|
||
|
FIELD_OFFSET (AFD_BUFFER_HEADER, _Test));
|
||
|
|
||
|
C_ASSERT(FIELD_OFFSET (AFD_BUFFER_HEADER, AllocatedAddressLength)==
|
||
|
FIELD_OFFSET(AFD_BUFFER_HEADER, Flags)+sizeof (USHORT));
|
||
|
|
||
|
typedef struct AFD_BUFFER_TAG {
|
||
|
union {
|
||
|
struct {
|
||
|
_AFD_BUFFER_HEADER_; // easy access to individual members
|
||
|
};
|
||
|
AFD_BUFFER_HEADER Header; // access to the header as a whole
|
||
|
};
|
||
|
#if DBG
|
||
|
PVOID Caller;
|
||
|
PVOID CallersCaller;
|
||
|
#endif
|
||
|
// UCHAR Address[]; // address of datagram sender
|
||
|
} AFD_BUFFER_TAG, *PAFD_BUFFER_TAG;
|
||
|
|
||
|
typedef DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) struct _AFD_BUFFER {
|
||
|
union {
|
||
|
struct {
|
||
|
_AFD_BUFFER_HEADER_; // easy access to individual members
|
||
|
};
|
||
|
AFD_BUFFER_HEADER Header; // access to the header as a whole
|
||
|
};
|
||
|
PIRP Irp; // pointer to the IRP associated w/the buffer
|
||
|
PVOID Buffer; // a pointer to the actual data buffer
|
||
|
|
||
|
#if DBG
|
||
|
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;
|
||
|
|
||
|
//
|
||
|
// Placement of pieces that comprise the AFD_BUFFER.
|
||
|
// We have four pieces: header, IRP, MDL, data buffer
|
||
|
// and use 2 bits to encode each.
|
||
|
// We need to save the first piece so we know where the memory block
|
||
|
// starts when we need to return it to the memory manager.
|
||
|
//
|
||
|
#define AFD_PLACEMENT_HDR 0
|
||
|
#define AFD_PLACEMENT_IRP 1
|
||
|
#define AFD_PLACEMENT_MDL 2
|
||
|
#define AFD_PLACEMENT_BUFFER 3
|
||
|
|
||
|
#define AFD_PLACEMENT_HDR_IRP (AFD_PLACEMENT_HDR|(AFD_PLACEMENT_IRP<<2))
|
||
|
#define AFD_PLACEMENT_HDR_MDL (AFD_PLACEMENT_HDR|(AFD_PLACEMENT_MDL<<2))
|
||
|
#define AFD_PLACEMENT_IRP_MDL (AFD_PLACEMENT_IRP|(AFD_PLACEMENT_MDL<<2))
|
||
|
|
||
|
#define AFD_PLACEMENT_HDR_IRP_MDL (AFD_PLACEMENT_HDR|(AFD_PLACEMENT_IRP<<2)|(AFD_PLACEMENT_MDL<<4))
|
||
|
|
||
|
|
||
|
//
|
||
|
// ALIGN_DOWN_A aligns to given alignment requirement
|
||
|
// (as opposed to the type in the original ALIGN_DOWN macro)
|
||
|
//
|
||
|
#define ALIGN_DOWN_A(length,alignment) \
|
||
|
(((ULONG)(length)) & ~ ((alignment)-1))
|
||
|
|
||
|
//
|
||
|
// ALIGN_DOWN_A for pointers.
|
||
|
//
|
||
|
#define ALIGN_DOWN_A_POINTER(address,alignment) \
|
||
|
((PVOID)(((ULONG_PTR)(address)) & ~ ((ULONG_PTR)(alignment)-1)))
|
||
|
|
||
|
|
||
|
//
|
||
|
// ALIGN_UP_A aligns to given alignment requirement
|
||
|
// (as opposed to the type in the original ALIGN_UP macro)
|
||
|
//
|
||
|
#define ALIGN_UP_A(length,alignment) \
|
||
|
((((ULONG)(length)) + (alignment)-1) & ~ ((alignment)-1))
|
||
|
|
||
|
//
|
||
|
// ALIGN_UP_A for pointers.
|
||
|
//
|
||
|
#define ALIGN_UP_A_POINTER(address,alignment) \
|
||
|
ALIGN_DOWN_A_POINTER(((ULONG_PTR)(address) + alignment-1), alignment)
|
||
|
|
||
|
//
|
||
|
// ALIGN_UP_TO_TYPE aligns size to make sure it meets
|
||
|
// the type alignment requirement
|
||
|
//
|
||
|
#define ALIGN_UP_TO_TYPE(length,type) \
|
||
|
ALIGN_UP_A(length,TYPE_ALIGNMENT(type))
|
||
|
|
||
|
//
|
||
|
// ALIGN_UP_TO_TYPE for pointers.
|
||
|
//
|
||
|
#define ALIGN_UP_TO_TYPE_POINTER(address,type) \
|
||
|
ALIGN_UP_A_POINTER(address,TYPE_ALIGNMENT(type))
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
#define IS_VALID_AFD_BUFFER(b) ( \
|
||
|
((b)->Placement==AFD_PLACEMENT_HDR) \
|
||
|
? ((PUCHAR)b<(PUCHAR)(b)->Buffer && (PUCHAR)b<(PUCHAR)(b)->Mdl && (PUCHAR)b<(PUCHAR)(b)->Irp) \
|
||
|
: (((b)->Placement==AFD_PLACEMENT_MDL) \
|
||
|
? ((PUCHAR)(b)->Mdl<(PUCHAR)(b)->Buffer && (PUCHAR)(b)->Mdl<(PUCHAR)b && (PUCHAR)(b)->Mdl<(PUCHAR)(b)->Irp) \
|
||
|
: ((b->Placement==AFD_PLACEMENT_IRP) \
|
||
|
? ((PUCHAR)(b)->Irp<(PUCHAR)(b)->Buffer && (PUCHAR)(b)->Irp<(PUCHAR)b && (PUCHAR)(b)->Irp<(PUCHAR)(b)->Mdl) \
|
||
|
: ((PUCHAR)(b)->Buffer<(PUCHAR)(b)->Irp && (PUCHAR)(b)->Buffer<(PUCHAR)b && (PUCHAR)(b)->Buffer<(PUCHAR)(b)->Mdl)) \
|
||
|
) \
|
||
|
) \
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// Pointer to an IRP cleanup routine. This is used as a parameter to
|
||
|
// AfdCompleteIrpList().
|
||
|
//
|
||
|
|
||
|
typedef
|
||
|
BOOLEAN
|
||
|
(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;
|
||
|
LONG ConnectionIndications;
|
||
|
LONG ConnectionsDropped;
|
||
|
LONG ConnectionsAccepted;
|
||
|
LONG ConnectionsPreaccepted;
|
||
|
LONG ConnectionsReused;
|
||
|
LONG EndpointsReused;
|
||
|
} AFD_CONNECTION_STATS;
|
||
|
|
||
|
//
|
||
|
// Global data. Resouces and lookaside list descriptors
|
||
|
// cannot be statically allocated, as they need to ALWAYS be nonpageable,
|
||
|
// even when the entire driver is paged out.
|
||
|
// Alignment table is variable-size and also cannot be statically allocated.
|
||
|
//
|
||
|
|
||
|
enum {
|
||
|
AFD_LARGE_BUFFER_LIST=0,
|
||
|
AFD_MEDIUM_BUFFER_LIST,
|
||
|
AFD_SMALL_BUFFER_LIST,
|
||
|
AFD_BUFFER_TAG_LIST,
|
||
|
AFD_TP_INFO_LIST,
|
||
|
AFD_REMOTE_ADDR_LIST,
|
||
|
AFD_NUM_LOOKASIDE_LISTS
|
||
|
} AFD_LOOKASIDE_LISTS_INDEX;
|
||
|
|
||
|
typedef struct _AFD_GLOBAL_DATA {
|
||
|
ERESOURCE Resource;
|
||
|
NPAGED_LOOKASIDE_LIST List[AFD_NUM_LOOKASIDE_LISTS];
|
||
|
#define LargeBufferList List[AFD_LARGE_BUFFER_LIST]
|
||
|
#define MediumBufferList List[AFD_MEDIUM_BUFFER_LIST]
|
||
|
#define SmallBufferList List[AFD_SMALL_BUFFER_LIST]
|
||
|
#define BufferTagList List[AFD_BUFFER_TAG_LIST]
|
||
|
#define TpInfoList List[AFD_TP_INFO_LIST]
|
||
|
#define RemoteAddrList List[AFD_REMOTE_ADDR_LIST]
|
||
|
LONG TrimFlags;
|
||
|
KTIMER Timer;
|
||
|
KDPC Dpc;
|
||
|
UCHAR BufferAlignmentTable[ANYSIZE_ARRAY];
|
||
|
} AFD_GLOBAL_DATA, *PAFD_GLOBAL_DATA;
|
||
|
|
||
|
//
|
||
|
// Context structure for misc requests pended in AFD.
|
||
|
//
|
||
|
typedef struct _AFD_REQUEST_CONTEXT AFD_REQUEST_CONTEXT, *PAFD_REQUEST_CONTEXT;
|
||
|
|
||
|
//
|
||
|
// The routine is called after request is removed from endpoint list
|
||
|
// for cleanup purposes
|
||
|
//
|
||
|
typedef BOOLEAN (* PAFD_REQUEST_CLEANUP) (
|
||
|
PAFD_ENDPOINT Endpoint,
|
||
|
PAFD_REQUEST_CONTEXT NotifyCtx
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// This structure has to no more 16 bytes long so we can
|
||
|
// reuse IrpSp->Parameters for it.
|
||
|
//
|
||
|
typedef struct _AFD_REQUEST_CONTEXT {
|
||
|
LIST_ENTRY EndpointListLink; // Link in endpoint list
|
||
|
PAFD_REQUEST_CLEANUP CleanupRoutine; // Routine to call to cancel
|
||
|
PVOID Context; // Request dependent context
|
||
|
// (PIRP)
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// We use list entry fields to synchronize completion with cleanup/cancel
|
||
|
// routine assuming that as long as the entry is in the list
|
||
|
// both Flink and Blink fields cannot be NULL. (using these
|
||
|
// fields for synchronization allows us to cut down on
|
||
|
// cancel spinlock usage)
|
||
|
//
|
||
|
|
||
|
#define AfdEnqueueRequest(Endpoint,Request) \
|
||
|
ExInterlockedInsertTailList(&(Endpoint)->RequestList, \
|
||
|
&(Request)->EndpointListLink, \
|
||
|
&(Endpoint)->SpinLock)
|
||
|
|
||
|
|
||
|
#define AfdIsRequestInQueue(Request) \
|
||
|
((Request)->EndpointListLink.Flink!=NULL)
|
||
|
|
||
|
#define AfdMarkRequestCompleted(Request) \
|
||
|
(Request)->EndpointListLink.Blink = NULL
|
||
|
|
||
|
#define AfdIsRequestCompleted(Request) \
|
||
|
((Request)->EndpointListLink.Blink==NULL)
|
||
|
|
||
|
|
||
|
typedef struct _ROUTING_NOTIFY {
|
||
|
LIST_ENTRY NotifyListLink;
|
||
|
PIRP NotifyIrp;
|
||
|
PVOID NotifyContext;
|
||
|
} ROUTING_NOTIFY, *PROUTING_NOTIFY;
|
||
|
|
||
|
typedef struct _AFD_ADDRESS_ENTRY {
|
||
|
LIST_ENTRY AddressListLink;
|
||
|
UNICODE_STRING DeviceName;
|
||
|
TA_ADDRESS Address;
|
||
|
} AFD_ADDRESS_ENTRY, *PAFD_ADDRESS_ENTRY;
|
||
|
|
||
|
typedef struct _AFD_ADDRESS_CHANGE {
|
||
|
LIST_ENTRY ChangeListLink;
|
||
|
union {
|
||
|
PAFD_ENDPOINT Endpoint;
|
||
|
PIRP Irp;
|
||
|
};
|
||
|
USHORT AddressType;
|
||
|
BOOLEAN NonBlocking;
|
||
|
} AFD_ADDRESS_CHANGE, *PAFD_ADDRESS_CHANGE;
|
||
|
|
||
|
|
||
|
typedef
|
||
|
NTSTATUS
|
||
|
(* PAFD_IMMEDIATE_CALL) (
|
||
|
IN PFILE_OBJECT FileObject,
|
||
|
IN ULONG IoctlCode,
|
||
|
IN KPROCESSOR_MODE RequestorMode,
|
||
|
IN PVOID InputBuffer,
|
||
|
IN ULONG InputBufferLength,
|
||
|
IN PVOID OutputBuffer,
|
||
|
IN ULONG OutputBufferLength,
|
||
|
OUT PUINT_PTR Information
|
||
|
);
|
||
|
|
||
|
typedef
|
||
|
NTSTATUS
|
||
|
(FASTCALL * PAFD_IRP_CALL) (
|
||
|
IN PIRP Irp,
|
||
|
IN PIO_STACK_LOCATION IrpSp
|
||
|
);
|
||
|
|
||
|
typedef struct _AFD_TRANSMIT_PACKETS_ELEMENT {
|
||
|
#define TP_MDL 0x80000000
|
||
|
#define TP_COMBINE 0x40000000
|
||
|
ULONG Flags;
|
||
|
ULONG Length;
|
||
|
union {
|
||
|
struct {
|
||
|
LARGE_INTEGER FileOffset;
|
||
|
PFILE_OBJECT FileObject;
|
||
|
};
|
||
|
struct {
|
||
|
PVOID Buffer;
|
||
|
PMDL Mdl;
|
||
|
};
|
||
|
};
|
||
|
} AFD_TRANSMIT_PACKETS_ELEMENT, *PAFD_TRANSMIT_PACKETS_ELEMENT;
|
||
|
|
||
|
//
|
||
|
// Structure to keep track of transmit packets request
|
||
|
//
|
||
|
typedef struct _AFD_TPACKETS_INFO_INTERNAL AFD_TPACKETS_INFO_INTERNAL, *PAFD_TPACKETS_INFO_INTERNAL;
|
||
|
struct _AFD_TPACKETS_INFO_INTERNAL {
|
||
|
union {
|
||
|
SINGLE_LIST_ENTRY SListEntry; // Link on S-List
|
||
|
PFILE_OBJECT TdiFileObject; // Tdi objects (sending to)
|
||
|
};
|
||
|
|
||
|
PDEVICE_OBJECT TdiDeviceObject;
|
||
|
|
||
|
PMDL HeadMdl; // Ready to send chain
|
||
|
PMDL *TailMdl;
|
||
|
|
||
|
PAFD_BUFFER_HEADER HeadPd; // Corresponding packet chain
|
||
|
PAFD_BUFFER_HEADER *TailPd;
|
||
|
|
||
|
PIRP ReadIrp; // Irp used for file reads.
|
||
|
PAFD_TRANSMIT_PACKETS_ELEMENT
|
||
|
ElementArray; // Packet array
|
||
|
|
||
|
ULONG NextElement; // Next element to send.
|
||
|
ULONG ElementCount; // Total number of elements in the array
|
||
|
|
||
|
ULONG RemainingPkts; // Number of packets remaining to be sent.
|
||
|
USHORT NumSendIrps; // Actual number of send IRPs
|
||
|
BOOLEAN ArrayAllocated; // Element array is allocated (not built-in).
|
||
|
BOOLEAN PdNeedsPps; // Packet descriptor being built needs post-
|
||
|
// processing after completion.
|
||
|
ULONG PdLength; // Currently accumulated send length
|
||
|
ULONG SendPacketLength; // Maximum length of the packet
|
||
|
// APC/Work item for worker scheduling
|
||
|
union {
|
||
|
KAPC Apc;
|
||
|
WORK_QUEUE_ITEM WorkItem;
|
||
|
};
|
||
|
|
||
|
#if REFERENCE_DEBUG
|
||
|
LONG CurrentReferenceSlot;
|
||
|
AFD_REFERENCE_DEBUG ReferenceDebug[MAX_REFERENCE];
|
||
|
#endif
|
||
|
#if AFD_PERF_DBG
|
||
|
LONG WorkersExecuted;
|
||
|
#endif
|
||
|
#define AFD_TP_MIN_SEND_IRPS 2 // Need at least two to keep transport busy
|
||
|
#define AFD_TP_MAX_SEND_IRPS 8 // Max is based on current flags layout below
|
||
|
PIRP SendIrp[AFD_TP_MAX_SEND_IRPS];
|
||
|
// ElementArray
|
||
|
// SendIrp1
|
||
|
// SendIrp2
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Structure maintained in driver context of the TPackets IRP
|
||
|
//
|
||
|
typedef struct _AFD_TPACKETS_IRP_CTX {
|
||
|
LIST_ENTRY EndpQueueEntry;
|
||
|
volatile LONG ReferenceCount;
|
||
|
volatile LONG StateFlags;
|
||
|
} AFD_TPACKETS_IRP_CTX, *PAFD_TPACKETS_IRP_CTX;
|
||
|
|
||
|
#define AFD_TP_ABORT_PENDING 0x00000001 // Request is being aborted
|
||
|
#define AFD_TP_WORKER_SCHEDULED 0x00000010 // Worker is scheduled or active
|
||
|
#ifdef TDI_SERVICE_SEND_AND_DISCONNECT
|
||
|
#define AFD_TP_SEND_AND_DISCONNECT 0x00000100 // S&D is enabled
|
||
|
#endif // TDI_SERVICE_SEND_AND_DISCONNECT
|
||
|
|
||
|
#define AFD_TP_READ_CALL_PENDING 0x00001000 // MDL_READ call is imminent or in progress on ReadIrp
|
||
|
#define AFD_TP_READ_COMP_PENDING 0x00002000 // Read completion is expected on ReadIrp
|
||
|
#define AFD_TP_READ_BUSY (AFD_TP_READ_CALL_PENDING|AFD_TP_READ_COMP_PENDING)
|
||
|
|
||
|
// TDI_SEND call is imminent or in progress on send Irp i
|
||
|
#define AFD_TP_SEND_CALL_PENDING(i) (0x00010000<<((i)*2))
|
||
|
// Send completion is expected on send Irp i
|
||
|
#define AFD_TP_SEND_COMP_PENDING(i) (0x00020000<<((i)*2))
|
||
|
#define AFD_TP_SEND_BUSY(i) (0x00030000<<((i)*2))
|
||
|
#define AFD_TP_SEND_MASK (0x55550000)
|
||
|
#define AFD_GET_TPIC(_i) ((PAFD_TPACKETS_IRP_CTX)&(_i)->Tail.Overlay.DriverContext)
|
||
|
|
||
|
//
|
||
|
// This macro verifies that the 32-bit mapping of the structures in 64-bit
|
||
|
// compiler match original 32-bit structures. Note, that the verification is
|
||
|
// performed when this file is compiled by 32 bit compiler, but
|
||
|
// the actual structures are used by 64 bit code.
|
||
|
//
|
||
|
|
||
|
#ifdef _WIN64
|
||
|
#define AFD_CHECK32on64(_str,_fld)
|
||
|
#define AFD_MAX_NATURAL_ALIGNMENT32 sizeof(ULONG)
|
||
|
#else
|
||
|
#define AFD_CHECK32on64(_str,_fld) \
|
||
|
C_ASSERT (FIELD_OFFSET (_str,_fld)==FIELD_OFFSET(_str##32,_fld))
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Structures for mapping IOCTL parameters for 32-bit clients on 64-bit
|
||
|
// platform.
|
||
|
//
|
||
|
typedef UNALIGNED struct _WSABUF32 {
|
||
|
ULONG len;
|
||
|
CHAR * POINTER_32 buf;
|
||
|
} WSABUF32, *LPWSABUF32;
|
||
|
AFD_CHECK32on64(WSABUF,len);
|
||
|
AFD_CHECK32on64(WSABUF,buf);
|
||
|
|
||
|
typedef UNALIGNED struct _QualityOfService32 {
|
||
|
FLOWSPEC SendingFlowspec; /* the flow spec for data sending */
|
||
|
FLOWSPEC ReceivingFlowspec; /* the flow spec for data receiving */
|
||
|
WSABUF32 ProviderSpecific; /* additional provider specific stuff */
|
||
|
} QOS32, * LPQOS32;
|
||
|
AFD_CHECK32on64(QOS,SendingFlowspec);
|
||
|
AFD_CHECK32on64(QOS,ReceivingFlowspec);
|
||
|
AFD_CHECK32on64(QOS,ProviderSpecific);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_ACCEPT_INFO32 {
|
||
|
BOOLEAN SanActive;
|
||
|
LONG Sequence;
|
||
|
VOID * POINTER_32 AcceptHandle;
|
||
|
} AFD_ACCEPT_INFO32, *PAFD_ACCEPT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_ACCEPT_INFO,SanActive);
|
||
|
AFD_CHECK32on64(AFD_ACCEPT_INFO,Sequence);
|
||
|
AFD_CHECK32on64(AFD_ACCEPT_INFO,AcceptHandle);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SUPER_ACCEPT_INFO32 {
|
||
|
BOOLEAN SanActive;
|
||
|
BOOLEAN FixAddressAlignment;
|
||
|
VOID * POINTER_32 AcceptHandle;
|
||
|
ULONG ReceiveDataLength;
|
||
|
ULONG LocalAddressLength;
|
||
|
ULONG RemoteAddressLength;
|
||
|
} AFD_SUPER_ACCEPT_INFO32, *PAFD_SUPER_ACCEPT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,SanActive);
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,FixAddressAlignment);
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,AcceptHandle);
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,ReceiveDataLength);
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,LocalAddressLength);
|
||
|
AFD_CHECK32on64(AFD_SUPER_ACCEPT_INFO,RemoteAddressLength);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_POLL_HANDLE_INFO32 {
|
||
|
VOID * POINTER_32 Handle;
|
||
|
ULONG PollEvents;
|
||
|
NTSTATUS Status;
|
||
|
} AFD_POLL_HANDLE_INFO32, *PAFD_POLL_HANDLE_INFO32;
|
||
|
AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,Handle);
|
||
|
AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,PollEvents);
|
||
|
AFD_CHECK32on64(AFD_POLL_HANDLE_INFO,Status);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_POLL_INFO32 {
|
||
|
LARGE_INTEGER Timeout;
|
||
|
ULONG NumberOfHandles;
|
||
|
BOOLEAN Unique;
|
||
|
AFD_POLL_HANDLE_INFO32 Handles[1];
|
||
|
} AFD_POLL_INFO32, *PAFD_POLL_INFO32;
|
||
|
AFD_CHECK32on64(AFD_POLL_INFO,Timeout);
|
||
|
AFD_CHECK32on64(AFD_POLL_INFO,NumberOfHandles);
|
||
|
AFD_CHECK32on64(AFD_POLL_INFO,Unique);
|
||
|
AFD_CHECK32on64(AFD_POLL_INFO,Handles);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_HANDLE_INFO632 {
|
||
|
VOID * POINTER_32 TdiAddressHandle;
|
||
|
VOID * POINTER_32 TdiConnectionHandle;
|
||
|
} AFD_HANDLE_INFO32, *PAFD_HANDLE_INFO32;
|
||
|
AFD_CHECK32on64(AFD_HANDLE_INFO,TdiAddressHandle);
|
||
|
AFD_CHECK32on64(AFD_HANDLE_INFO,TdiConnectionHandle);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_TRANSMIT_FILE_INFO32 {
|
||
|
LARGE_INTEGER Offset;
|
||
|
LARGE_INTEGER WriteLength;
|
||
|
ULONG SendPacketLength;
|
||
|
VOID * POINTER_32 FileHandle;
|
||
|
VOID * POINTER_32 Head;
|
||
|
ULONG HeadLength;
|
||
|
VOID * POINTER_32 Tail;
|
||
|
ULONG TailLength;
|
||
|
ULONG Flags;
|
||
|
} AFD_TRANSMIT_FILE_INFO32, *PAFD_TRANSMIT_FILE_INFO32;
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Offset);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,WriteLength);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,SendPacketLength);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,FileHandle);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Head);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,HeadLength);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Tail);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,TailLength);
|
||
|
AFD_CHECK32on64(AFD_TRANSMIT_FILE_INFO,Flags);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SEND_INFO32 {
|
||
|
WSABUF32 * POINTER_32 BufferArray;
|
||
|
ULONG BufferCount;
|
||
|
ULONG AfdFlags;
|
||
|
ULONG TdiFlags;
|
||
|
} AFD_SEND_INFO32, *PAFD_SEND_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SEND_INFO,BufferArray);
|
||
|
AFD_CHECK32on64(AFD_SEND_INFO,BufferCount);
|
||
|
AFD_CHECK32on64(AFD_SEND_INFO,AfdFlags);
|
||
|
AFD_CHECK32on64(AFD_SEND_INFO,TdiFlags);
|
||
|
|
||
|
typedef UNALIGNED struct _TDI_REQUEST32 {
|
||
|
union {
|
||
|
VOID * POINTER_32 AddressHandle;
|
||
|
VOID * POINTER_32 ConnectionContext;
|
||
|
VOID * POINTER_32 ControlChannel;
|
||
|
} Handle;
|
||
|
|
||
|
VOID * POINTER_32 RequestNotifyObject;
|
||
|
VOID * POINTER_32 RequestContext;
|
||
|
TDI_STATUS TdiStatus;
|
||
|
} TDI_REQUEST32, *PTDI_REQUEST32;
|
||
|
AFD_CHECK32on64(TDI_REQUEST,Handle);
|
||
|
AFD_CHECK32on64(TDI_REQUEST,RequestNotifyObject);
|
||
|
AFD_CHECK32on64(TDI_REQUEST,RequestContext);
|
||
|
AFD_CHECK32on64(TDI_REQUEST,TdiStatus);
|
||
|
|
||
|
typedef UNALIGNED struct _TDI_CONNECTION_INFORMATION32 {
|
||
|
LONG UserDataLength; // length of user data buffer
|
||
|
VOID * POINTER_32 UserData; // pointer to user data buffer
|
||
|
LONG OptionsLength; // length of follwoing buffer
|
||
|
VOID * POINTER_32 Options; // pointer to buffer containing options
|
||
|
LONG RemoteAddressLength; // length of following buffer
|
||
|
VOID * POINTER_32 RemoteAddress;// buffer containing the remote address
|
||
|
} TDI_CONNECTION_INFORMATION32, *PTDI_CONNECTION_INFORMATION32;
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,UserDataLength);
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,UserData);
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,OptionsLength);
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,Options);
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,RemoteAddressLength);
|
||
|
AFD_CHECK32on64(TDI_CONNECTION_INFORMATION,RemoteAddress);
|
||
|
|
||
|
typedef UNALIGNED struct _TDI_REQUEST_SEND_DATAGRAM32 {
|
||
|
TDI_REQUEST32 Request;
|
||
|
TDI_CONNECTION_INFORMATION32 * POINTER_32 SendDatagramInformation;
|
||
|
} TDI_REQUEST_SEND_DATAGRAM32, *PTDI_REQUEST_SEND_DATAGRAM32;
|
||
|
AFD_CHECK32on64(TDI_REQUEST_SEND_DATAGRAM,Request);
|
||
|
AFD_CHECK32on64(TDI_REQUEST_SEND_DATAGRAM,SendDatagramInformation);
|
||
|
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SEND_DATAGRAM_INFO32 {
|
||
|
WSABUF32 * POINTER_32 BufferArray;
|
||
|
ULONG BufferCount;
|
||
|
ULONG AfdFlags;
|
||
|
TDI_REQUEST_SEND_DATAGRAM32 TdiRequest;
|
||
|
TDI_CONNECTION_INFORMATION32 TdiConnInfo;
|
||
|
} AFD_SEND_DATAGRAM_INFO32, *PAFD_SEND_DATAGRAM_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,BufferArray);
|
||
|
AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,BufferCount);
|
||
|
AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,AfdFlags);
|
||
|
AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,TdiRequest);
|
||
|
AFD_CHECK32on64(AFD_SEND_DATAGRAM_INFO,TdiConnInfo);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_RECV_INFO32 {
|
||
|
WSABUF32 * POINTER_32 BufferArray;
|
||
|
ULONG BufferCount;
|
||
|
ULONG AfdFlags;
|
||
|
ULONG TdiFlags;
|
||
|
} AFD_RECV_INFO32, *PAFD_RECV_INFO32;
|
||
|
AFD_CHECK32on64(AFD_RECV_INFO,BufferArray);
|
||
|
AFD_CHECK32on64(AFD_RECV_INFO,BufferCount);
|
||
|
AFD_CHECK32on64(AFD_RECV_INFO,AfdFlags);
|
||
|
AFD_CHECK32on64(AFD_RECV_INFO,TdiFlags);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_RECV_DATAGRAM_INFO32 {
|
||
|
WSABUF32 * POINTER_32 BufferArray;
|
||
|
ULONG BufferCount;
|
||
|
ULONG AfdFlags;
|
||
|
ULONG TdiFlags;
|
||
|
VOID * POINTER_32 Address;
|
||
|
ULONG * POINTER_32 AddressLength;
|
||
|
} AFD_RECV_DATAGRAM_INFO32, *PAFD_RECV_DATAGRAM_INFO32;
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,BufferArray);
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,BufferCount);
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,AfdFlags);
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,TdiFlags);
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,Address);
|
||
|
AFD_CHECK32on64(AFD_RECV_DATAGRAM_INFO,AddressLength);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_CONNECT_JOIN_INFO32 {
|
||
|
BOOLEAN SanActive;
|
||
|
VOID * POINTER_32 RootEndpoint; // Root endpoint for joins
|
||
|
VOID * POINTER_32 ConnectEndpoint;// Connect/leaf endpoint for async connects
|
||
|
TRANSPORT_ADDRESS RemoteAddress; // Remote address
|
||
|
} AFD_CONNECT_JOIN_INFO32, *PAFD_CONNECT_JOIN_INFO32;
|
||
|
AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,SanActive);
|
||
|
AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,RootEndpoint);
|
||
|
AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,ConnectEndpoint);
|
||
|
AFD_CHECK32on64(AFD_CONNECT_JOIN_INFO,RemoteAddress);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_EVENT_SELECT_INFO32 {
|
||
|
VOID * POINTER_32 Event;
|
||
|
ULONG PollEvents;
|
||
|
} AFD_EVENT_SELECT_INFO32, *PAFD_EVENT_SELECT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_EVENT_SELECT_INFO,Event);
|
||
|
AFD_CHECK32on64(AFD_EVENT_SELECT_INFO,PollEvents);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_QOS_INFO32 {
|
||
|
QOS32 Qos;
|
||
|
BOOLEAN GroupQos;
|
||
|
} AFD_QOS_INFO32, *PAFD_QOS_INFO32;
|
||
|
AFD_CHECK32on64(AFD_QOS_INFO,Qos);
|
||
|
AFD_CHECK32on64(AFD_QOS_INFO,GroupQos);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_TRANSPORT_IOCTL_INFO32 {
|
||
|
VOID * POINTER_32 Handle;
|
||
|
VOID * POINTER_32 InputBuffer;
|
||
|
ULONG InputBufferLength;
|
||
|
ULONG IoControlCode;
|
||
|
ULONG AfdFlags;
|
||
|
ULONG PollEvent;
|
||
|
} AFD_TRANSPORT_IOCTL_INFO32, *PAFD_TRANSPORT_IOCTL_INFO32;
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,Handle);
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,InputBuffer);
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,InputBufferLength);
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,IoControlCode);
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,AfdFlags);
|
||
|
AFD_CHECK32on64(AFD_TRANSPORT_IOCTL_INFO,PollEvent);
|
||
|
|
||
|
typedef UNALIGNED struct _TRANSMIT_PACKETS_ELEMENT32 {
|
||
|
ULONG dwElFlags;
|
||
|
#define TP_MEMORY 1
|
||
|
#define TP_FILE 2
|
||
|
#define TP_EOP 4
|
||
|
ULONG cLength;
|
||
|
union {
|
||
|
struct {
|
||
|
LARGE_INTEGER nFileOffset;
|
||
|
VOID * POINTER_32 hFile;
|
||
|
};
|
||
|
VOID * POINTER_32 pBuffer;
|
||
|
};
|
||
|
} TRANSMIT_PACKETS_ELEMENT32, *LPTRANSMIT_PACKETS_ELEMENT32;
|
||
|
AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,dwElFlags);
|
||
|
AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,nFileOffset);
|
||
|
AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,hFile);
|
||
|
AFD_CHECK32on64(TRANSMIT_PACKETS_ELEMENT,pBuffer);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_TPACKETS_INFO32 {
|
||
|
TRANSMIT_PACKETS_ELEMENT * POINTER_32 ElementArray;
|
||
|
ULONG ElementCount;
|
||
|
ULONG SendSize;
|
||
|
ULONG Flags;
|
||
|
} AFD_TPACKETS_INFO32, *PAFD_TPACKETS_INFO32;
|
||
|
AFD_CHECK32on64(AFD_TPACKETS_INFO,ElementArray);
|
||
|
AFD_CHECK32on64(AFD_TPACKETS_INFO,ElementCount);
|
||
|
AFD_CHECK32on64(AFD_TPACKETS_INFO,SendSize);
|
||
|
AFD_CHECK32on64(AFD_TPACKETS_INFO,Flags);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_RECV_MESSAGE_INFO32 {
|
||
|
AFD_RECV_DATAGRAM_INFO32 dgi;
|
||
|
VOID * POINTER_32 ControlBuffer;
|
||
|
ULONG * POINTER_32 ControlLength;
|
||
|
ULONG * POINTER_32 MsgFlags;
|
||
|
} AFD_RECV_MESSAGE_INFO32, *PAFD_RECV_MESSAGE_INFO32;
|
||
|
AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,dgi);
|
||
|
AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,MsgFlags);
|
||
|
AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,ControlBuffer);
|
||
|
AFD_CHECK32on64(AFD_RECV_MESSAGE_INFO,ControlLength);
|
||
|
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_OPEN_PACKET32 {
|
||
|
VOID * POINTER_32 CompletionPort;
|
||
|
VOID * POINTER_32 CompletionEvent;
|
||
|
} AFD_SWITCH_OPEN_PACKET32, *PAFD_SWITCH_OPEN_PACKET32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_OPEN_PACKET,CompletionPort);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_OPEN_PACKET,CompletionEvent);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_CONTEXT_INFO32 {
|
||
|
VOID * POINTER_32 SocketHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
} AFD_SWITCH_CONTEXT_INFO32, *PAFD_SWITCH_CONTEXT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_CONTEXT_INFO,SocketHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_CONTEXT_INFO,SwitchContext);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_CONNECT_INFO32 {
|
||
|
VOID * POINTER_32 ListenHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
TRANSPORT_ADDRESS RemoteAddress;
|
||
|
} AFD_SWITCH_CONNECT_INFO32, *PAFD_SWITCH_CONNECT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,ListenHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,SwitchContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_CONNECT_INFO,RemoteAddress);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_ACCEPT_INFO32 {
|
||
|
VOID * POINTER_32 AcceptHandle;
|
||
|
ULONG ReceiveLength;
|
||
|
} AFD_SWITCH_ACCEPT_INFO32, *PAFD_SWITCH_ACCEPT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACCEPT_INFO,AcceptHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACCEPT_INFO,ReceiveLength);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_EVENT_INFO32 {
|
||
|
VOID * POINTER_32 SocketHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
ULONG EventBit;
|
||
|
NTSTATUS Status;
|
||
|
} AFD_SWITCH_EVENT_INFO32, *PAFD_SWITCH_EVENT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,SocketHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,SwitchContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,EventBit);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_EVENT_INFO,Status);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_REQUEST_INFO32 {
|
||
|
VOID * POINTER_32 SocketHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
VOID * POINTER_32 RequestContext;
|
||
|
NTSTATUS RequestStatus;
|
||
|
ULONG DataOffset;
|
||
|
} AFD_SWITCH_REQUEST_INFO32, *PAFD_SWITCH_REQUEST_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,SocketHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,SwitchContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,RequestContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,RequestStatus);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_REQUEST_INFO,DataOffset);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_ACQUIRE_CTX_INFO32 {
|
||
|
VOID * POINTER_32 SocketHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
VOID * POINTER_32 SocketCtxBuf;
|
||
|
ULONG SocketCtxBufSize;
|
||
|
} AFD_SWITCH_ACQUIRE_CTX_INFO32, *PAFD_SWITCH_ACQUIRE_CTX_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SwitchContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketCtxBuf);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_ACQUIRE_CTX_INFO,SocketCtxBufSize);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SWITCH_TRANSFER_CTX_INFO32 {
|
||
|
VOID * POINTER_32 SocketHandle;
|
||
|
AFD_SWITCH_CONTEXT * POINTER_32 SwitchContext;
|
||
|
VOID * POINTER_32 RequestContext;
|
||
|
VOID * POINTER_32 SocketCtxBuf;
|
||
|
ULONG SocketCtxBufSize;
|
||
|
WSABUF * POINTER_32 RcvBufferArray;
|
||
|
ULONG RcvBufferCount;
|
||
|
NTSTATUS Status;
|
||
|
} AFD_SWITCH_TRANSFER_CTX_INFO32, *PAFD_SWITCH_TRANSFER_CTX_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketHandle);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SwitchContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RequestContext);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketCtxBuf);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,SocketCtxBufSize);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RcvBufferArray);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,RcvBufferCount);
|
||
|
AFD_CHECK32on64(AFD_SWITCH_TRANSFER_CTX_INFO,Status);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_PARTIAL_DISCONNECT_INFO32 {
|
||
|
ULONG DisconnectMode;
|
||
|
LARGE_INTEGER Timeout;
|
||
|
} AFD_PARTIAL_DISCONNECT_INFO32, *PAFD_PARTIAL_DISCONNECT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_PARTIAL_DISCONNECT_INFO,DisconnectMode);
|
||
|
AFD_CHECK32on64(AFD_PARTIAL_DISCONNECT_INFO,Timeout);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_SUPER_DISCONNECT_INFO32 {
|
||
|
ULONG Flags;
|
||
|
} AFD_SUPER_DISCONNECT_INFO32, *PAFD_SUPER_DISCONNECT_INFO32;
|
||
|
AFD_CHECK32on64(AFD_SUPER_DISCONNECT_INFO,Flags);
|
||
|
|
||
|
typedef UNALIGNED struct _AFD_INFORMATION32 {
|
||
|
ULONG InformationType;
|
||
|
union {
|
||
|
BOOLEAN Boolean;
|
||
|
ULONG Ulong;
|
||
|
LARGE_INTEGER LargeInteger;
|
||
|
} Information;
|
||
|
} AFD_INFORMATION32, *PAFD_INFORMATION32;
|
||
|
AFD_CHECK32on64(AFD_INFORMATION,InformationType);
|
||
|
AFD_CHECK32on64(AFD_INFORMATION,Information);
|
||
|
AFD_CHECK32on64(AFD_INFORMATION,Information.Boolean);
|
||
|
AFD_CHECK32on64(AFD_INFORMATION,Information.Ulong);
|
||
|
AFD_CHECK32on64(AFD_INFORMATION,Information.LargeInteger);
|
||
|
|
||
|
|
||
|
typedef UNALIGNED struct _TDI_CMSGHDR32 {
|
||
|
ULONG cmsg_len;
|
||
|
LONG cmsg_level;
|
||
|
LONG cmsg_type;
|
||
|
/* followed by UCHAR cmsg_data[] */
|
||
|
} TDI_CMSGHDR32, *PTDI_CMSGHDR32;
|
||
|
AFD_CHECK32on64(TDI_CMSGHDR,cmsg_len);
|
||
|
AFD_CHECK32on64(TDI_CMSGHDR,cmsg_level);
|
||
|
AFD_CHECK32on64(TDI_CMSGHDR,cmsg_type);
|
||
|
|
||
|
#ifdef _WIN64
|
||
|
#define TDI_CMSGHDR_ALIGN32(length) \
|
||
|
( ((length) + TYPE_ALIGNMENT(TDI_CMSGHDR32)-1) &\
|
||
|
(~(TYPE_ALIGNMENT(TDI_CMSGHDR32)-1)) ) \
|
||
|
|
||
|
#define TDI_CMSGDATA_ALIGN32(length) \
|
||
|
( ((length) + AFD_MAX_NATURAL_ALIGNMENT32-1) & \
|
||
|
(~(AFD_MAX_NATURAL_ALIGNMENT32-1)) )
|
||
|
#endif //_WIN64
|
||
|
|
||
|
#endif // ndef _AFDSTR_
|
||
|
|