windows-nt/Source/XPSP1/NT/net/rndis/rndismp/rndismp.h
2020-09-26 16:20:57 +08:00

1909 lines
68 KiB
C

/***************************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name:
RNDISMP.H
Abstract:
Header file for Remote NDIS Miniport driver. Sits on top of Remote
NDIS bus specific layers.
Environment:
kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
Revision History:
5/6/99 : created
Author:
Tom Green
****************************************************************************/
#ifndef _RNDISMP_H_
#define _RNDISMP_H_
#ifndef OID_GEN_RNDIS_CONFIG_PARAMETER
#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B // Set only
#endif
//
// DEBUG stuff
//
#if DBG
//
// Definitions for all of the Debug macros. If we're in a debug (DBG) mode,
// these macros will print information to the debug terminal. If the
// driver is compiled in a free (non-debug) environment the macros become
// NOPs.
//
VOID
NTAPI
DbgBreakPoint(VOID);
//
// DEBUG enable bit definitions
//
#define DBG_LEVEL0 0x1000 // Display TRACE0 messages
#define DBG_LEVEL1 0x0001 // Display TRACE1 messages
#define DBG_LEVEL2 0x0002 // Display TRACE2 messages
#define DBG_LEVEL3 0x0004 // Display TRACE3 messages
#define DBG_OID_LIST 0x0008 // display OID list
#define DBG_OID_NAME 0x0010 // display name of OID in query and set routines
#define DBG_DUMP 0x0020 // Display buffer dumps
#define DBG_LOG_SENDS 0x0100 // Log sent messages.
#define TRACE0(S) {if(RndismpDebugFlags & DBG_LEVEL0) {DbgPrint("RNDISMP: "); DbgPrint S;}}
#define TRACE1(S) {if(RndismpDebugFlags & DBG_LEVEL1) {DbgPrint("RNDISMP: "); DbgPrint S;}}
#define TRACE2(S) {if(RndismpDebugFlags & DBG_LEVEL2) {DbgPrint("RNDISMP: "); DbgPrint S;}}
#define TRACE3(S) {if(RndismpDebugFlags & DBG_LEVEL3) {DbgPrint("RNDISMP: "); DbgPrint S;}}
#define TRACEDUMP(_s, _buf, _len) {if(RndismpDebugFlags & DBG_DUMP) {DbgPrint("RNDISMP: "); DbgPrint _s; RndisPrintHexDump(_buf, _len);}}
#define DISPLAY_OID_LIST(Adapter) DisplayOidList(Adapter)
#define GET_OID_NAME(Oid) GetOidName(Oid)
#define OID_NAME_TRACE(Oid, s) \
{ \
if(RndismpDebugFlags & DBG_OID_NAME) \
DbgPrint("RNDISMP: %s: (%s) (%08X)\n", s, GET_OID_NAME(Oid), Oid); \
}
#undef ASSERT
#define ASSERT(exp) \
{ \
if(!(exp)) \
{ \
DbgPrint("Assertion Failed: %s:%d %s\n", \
__FILE__,__LINE__,#exp); \
DbgBreakPoint(); \
} \
}
#define DBGINT(S) \
{ \
DbgPrint("%s:%d - ", __FILE__, __LINE__); \
DbgPrint S; \
DbgBreakPoint(); \
}
// check frame for problems
#define CHECK_VALID_FRAME(Frame) \
{ \
ASSERT(Frame); \
if(Frame) \
{ \
if(Frame->Signature != FRAME_SIGNATURE) \
{ \
DbgPrint("RNDISMP: Invalid Frame (%p) Signature: %s:%d\n",\
Frame, __FILE__,__LINE__); \
DbgBreakPoint(); \
} \
} \
}
// check adapter for problems
#define CHECK_VALID_ADAPTER(Adapter) \
{ \
ASSERT(Adapter); \
if(Adapter) \
{ \
if(Adapter->Signature != ADAPTER_SIGNATURE) \
{ \
DbgPrint("RNDISMP: Invalid Adapter Signature: %s:%d\n",\
__FILE__,__LINE__); \
DbgBreakPoint(); \
} \
} \
}
// check block for problems
#define CHECK_VALID_BLOCK(Block) \
{ \
ASSERT(Block); \
if(Block) \
{ \
if(Block->Signature != BLOCK_SIGNATURE) \
{ \
DbgPrint("RNDISMP: Invalid Block Signature: %s:%d\n",\
__FILE__,__LINE__); \
DbgBreakPoint(); \
} \
} \
}
#define RNDISMP_ASSERT_AT_PASSIVE() \
{ \
KIRQL Irql = KeGetCurrentIrql(); \
if (Irql != PASSIVE_LEVEL) \
{ \
DbgPrint("RNDISMP: found IRQL %d instead of passive!\n", Irql); \
DbgPrint("RNDISMP: at line %d, file %s\n", __LINE__, __FILE__); \
DbgBreakPoint(); \
} \
}
#define RNDISMP_ASSERT_AT_DISPATCH() \
{ \
KIRQL Irql = KeGetCurrentIrql(); \
if (Irql != DISPATCH_LEVEL) \
{ \
DbgPrint("RNDISMP: found IRQL %d instead of dispatch!\n", Irql); \
DbgPrint("RNDISMP: at line %d, file %s\n", __LINE__, __FILE__); \
DbgBreakPoint(); \
} \
}
#define DBG_LOG_SEND_MSG(_pAdapter, _pMsgFrame) \
{ \
if (RndismpDebugFlags & DBG_LOG_SENDS) \
{ \
RndisLogSendMessage(_pAdapter, _pMsgFrame); \
} \
}
#else // !DBG
#define TRACE0(S)
#define TRACE1(S)
#define TRACE2(S)
#define TRACE3(S)
#define TRACEDUMP(_s, _buf, _len)
#undef ASSERT
#define ASSERT(exp)
#define DBGINT(S)
#define CHECK_VALID_FRAME(Frame)
#define CHECK_VALID_ADAPTER(Adapter)
#define CHECK_VALID_BLOCK(Block)
#define DISPLAY_OID_LIST(Adapter)
#define OID_NAME_TRACE(Oid, s)
#define RNDISMP_ASSERT_AT_PASSIVE()
#define RNDISMP_ASSERT_AT_DISPATCH()
#define DBG_LOG_SEND_MSG(_pAdapter, _pMsgFrame)
#endif //DBG
//
// Defines
//
#define MINIMUM_ETHERNET_PACKET_SIZE 60
#define MAXIMUM_ETHERNET_PACKET_SIZE 1514
#define NUM_BYTES_PROTOCOL_RESERVED_SECTION (4*sizeof(PVOID))
#define ETHERNET_HEADER_SIZE 14
#define INITIAL_RECEIVE_FRAMES 20
#define MAX_RECEIVE_FRAMES 400
// this is the size of the buffer we will use to pass Data packet header data
// to the remote device.
#define RNDIS_PACKET_MESSAGE_HEADER_SIZE 128
// align all RNDIS packets on 4 byte boundaries
#define RNDIS_PACKET_MESSAGE_BOUNDARY (4)
#define ONE_SECOND 1000 // in milliseconds
#define KEEP_ALIVE_TIMER (5 * ONE_SECOND)
#define REQUEST_TIMEOUT (10 * ONE_SECOND)
#define FRAME_SIGNATURE ((ULONG)('GSRF'))
#define ADAPTER_SIGNATURE ((ULONG)('GSDA'))
#define BLOCK_SIGNATURE ((ULONG)('GSLB'))
#define RNDISMP_TAG_GEN_ALLOC ((ULONG)(' MNR'))
#define RNDISMP_TAG_SEND_FRAME ((ULONG)('sMNR'))
#define RNDISMP_TAG_RECV_DATA_FRAME ((ULONG)('rMNR'))
#if DBG
#define MINIPORT_INIT_TIMEOUT (10 * ONE_SECOND)
#define MINIPORT_HALT_TIMEOUT (5 * ONE_SECOND)
#else
#define MINIPORT_INIT_TIMEOUT (5 * ONE_SECOND)
#define MINIPORT_HALT_TIMEOUT (2 * ONE_SECOND)
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
// flags for driver and device supported OIDs
#define OID_NOT_SUPPORTED 0x0000
#define DRIVER_SUPPORTED_OID 0x0001
#define DEVICE_SUPPORTED_OID 0x0002
//
// Defines for OID_GEN_MAC_OPTIONS - most of the bits returned
// in response to this query are driver-specific, however some
// are device-specific.
//
#define RNDIS_DRIVER_MAC_OPTIONS (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \
NDIS_MAC_OPTION_NO_LOOPBACK)
#define RNDIS_DEVICE_MAC_OPTIONS_MASK NDIS_MAC_OPTION_8021P_PRIORITY
//
// Data structures
//
typedef NDIS_SPIN_LOCK RNDISMP_SPIN_LOCK;
#ifdef BUILD_WIN9X
//
// Equivalents of types defined for Win9X config mgr.
//
typedef ULONG MY_CONFIGRET;
typedef ULONG MY_DEVNODE;
typedef ULONG MY_CONFIGFUNC;
typedef ULONG MY_SUBCONFIGFUNC;
typedef MY_CONFIGRET (_cdecl *MY_CMCONFIGHANDLER)(MY_CONFIGFUNC, MY_SUBCONFIGFUNC, MY_DEVNODE, ULONG, ULONG);
#define MY_CR_SUCCESS 0x00000000
#define MY_CONFIG_PREREMOVE 0x0000000C
#define MY_CONFIG_PRESHUTDOWN 0x00000012
#endif
//
// This structure contains information about a specific
// microport the miniport sits on top of. One of these
// per microport
//
typedef struct _DRIVER_BLOCK
{
// NDIS wrapper handle from NdisInitializeWrapper
NDIS_HANDLE NdisWrapperHandle;
// The NDIS version we manage to register this miniport instance as.
UCHAR MajorNdisVersion;
UCHAR MinorNdisVersion;
struct _DRIVER_BLOCK *NextDriverBlock;
// pointer to driver object this block is associated with
PDRIVER_OBJECT DriverObject;
// intercepted dispatch function for IRP_MJ_PNP
PDRIVER_DISPATCH SavedPnPDispatch;
// Handlers registered by Remote NDIS microport
RM_DEVICE_INIT_HANDLER RmInitializeHandler;
RM_DEVICE_INIT_CMPLT_NOTIFY_HANDLER RmInitCompleteNotifyHandler;
RM_DEVICE_HALT_HANDLER RmHaltHandler;
RM_SHUTDOWN_HANDLER RmShutdownHandler;
RM_UNLOAD_HANDLER RmUnloadHandler;
RM_SEND_MESSAGE_HANDLER RmSendMessageHandler;
RM_RETURN_MESSAGE_HANDLER RmReturnMessageHandler;
// "Global" context for Microport
PVOID MicroportContext;
// list of adapters registered for this Miniport driver.
struct _RNDISMP_ADAPTER *AdapterList;
// number of adapters in use with this driver block
ULONG NumberAdapters;
// sanity check
ULONG Signature;
} DRIVER_BLOCK, *PDRIVER_BLOCK;
typedef
VOID
(*PRNDISMP_MSG_COMPLETE_HANDLER) (
IN struct _RNDISMP_MESSAGE_FRAME * pMsgFrame,
IN NDIS_STATUS Status
);
typedef
BOOLEAN
(*PRNDISMP_MSG_HANDLER_FUNC) (
IN struct _RNDISMP_ADAPTER * pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied
);
//
// One of these structures for each NDIS_PACKET that we send.
//
typedef struct _RNDISMP_PACKET_WRAPPER
{
struct _RNDISMP_MESSAGE_FRAME * pMsgFrame;
PNDIS_PACKET pNdisPacket;
struct _RNDISMP_VC * pVc;
// MDL to describe the RNDIS NdisPacket header:
PMDL pHeaderMdl;
// Last MDL in the list of MDLs describing this RNDIS packet.
PMDL pTailMdl;
// Space for the RNDIS Packet header:
UCHAR Packet[sizeof(PVOID)];
} RNDISMP_PACKET_WRAPPER, *PRNDISMP_PACKET_WRAPPER;
//
// Structure used to overlay the MiniportReserved field
// of outgoing (sent) packets.
//
typedef struct _RNDISMP_SEND_PKT_RESERVED
{
// Points to the next packet for multi-packet sends.
PNDIS_PACKET pNext;
// Points to more detailed information about this packet, too much
// to fit into one PVOID.
PRNDISMP_PACKET_WRAPPER pPktWrapper;
} RNDISMP_SEND_PKT_RESERVED, *PRNDISMP_SEND_PKT_RESERVED;
//
// Structure used to TEMPORARILY overlay the MiniportReserved field
// of sent packets -- this is used to link packets in a list pending
// actual transmission from a timeout routine.
//
typedef struct _RNDISMP_SEND_PKT_RESERVED_TEMP
{
LIST_ENTRY Link;
} RNDISMP_SEND_PKT_RESERVED_TEMP, *PRNDISMP_SEND_PKT_RESERVED_TEMP;
//
// Request context - holds information about a pended request (Set or Query)
//
typedef struct _RNDISMP_REQUEST_CONTEXT
{
PNDIS_REQUEST pNdisRequest;
struct _RNDISMP_VC * pVc;
NDIS_OID Oid;
PVOID InformationBuffer;
UINT InformationBufferLength;
PUINT pBytesRead; // for Set
PUINT pBytesWritten; // for Query
PUINT pBytesNeeded;
BOOLEAN bInternal;
NDIS_STATUS CompletionStatus;
ULONG RetryCount;
PNDIS_EVENT pEvent;
} RNDISMP_REQUEST_CONTEXT, *PRNDISMP_REQUEST_CONTEXT;
//
// Message Frame - generic structure to hold context about all
// messages sent via the microport.
//
typedef struct _RNDISMP_MESSAGE_FRAME
{
LIST_ENTRY Link; // used to queue this if
// a response is expected
// from the device.
ULONG RefCount; // Determines when to free
// this message frame.
struct _RNDISMP_ADAPTER * pAdapter;
struct _RNDISMP_VC * pVc;
union
{
PNDIS_PACKET pNdisPacket; // if DATA message
PRNDISMP_REQUEST_CONTEXT pReqContext; // if Request message
};
PMDL pMessageMdl; // what goes to the microport
UINT32 NdisMessageType;// copied from the RNDIS message
UINT32 RequestId; // to match requests/responses
PRNDISMP_MSG_COMPLETE_HANDLER pCallback; // called on completion of message send
ULONG TicksOnQueue;
ULONG TimeSent;
#if THROTTLE_MESSAGES
LIST_ENTRY PendLink; // used to queue this
// pending send to microport
#endif
ULONG Signature;
} RNDISMP_MESSAGE_FRAME, *PRNDISMP_MESSAGE_FRAME;
//
// linked list entry for transport frames (transmit, receive, request)
//
typedef struct _RNDISMP_LIST_ENTRY
{
LIST_ENTRY Link;
} RNDISMP_LIST_ENTRY, *PRNDISMP_LIST_ENTRY;
//
// RNDIS VC states.
//
typedef enum
{
RNDISMP_VC_ALLOCATED = 0,
RNDISMP_VC_CREATING,
RNDISMP_VC_CREATING_ACTIVATE_PENDING,
RNDISMP_VC_CREATING_DELETE_PENDING,
RNDISMP_VC_CREATE_FAILURE,
RNDISMP_VC_CREATED,
RNDISMP_VC_ACTIVATING,
RNDISMP_VC_ACTIVATED,
RNDISMP_VC_DEACTIVATING,
RNDISMP_VC_DEACTIVATED,
RNDISMP_VC_DELETING,
RNDISMP_VC_DELETE_FAIL
} RNDISMP_VC_STATE;
//
// RNDIS Call states.
//
typedef enum
{
RNDISMP_CALL_IDLE
// others TBD
} RNDISMP_CALL_STATE;
#define NULL_DEVICE_CONTEXT 0
//
// All information about a single VC/call.
//
typedef struct _RNDISMP_VC
{
// link to list of VCs on adapter.
LIST_ENTRY VcList;
// owning adapter
struct _RNDISMP_ADAPTER * pAdapter;
// VC handle sent to the device, also our hash lookup key.
UINT32 VcId;
// base VC state
RNDISMP_VC_STATE VcState;
// call state, relevant only for devices that are call managers.
RNDISMP_CALL_STATE CallState;
ULONG RefCount;
// NDIS Wrapper's handle for this Vc
NDIS_HANDLE NdisVcHandle;
// remote device's context for this VC
RNDIS_HANDLE DeviceVcContext;
RNDISMP_SPIN_LOCK Lock;
// sends on this VC that haven't been completed.
ULONG PendingSends;
// receive indications that haven't been returned to us.
ULONG PendingReceives;
// NDIS requests that haven't been completed.
ULONG PendingRequests;
// VC activation (or call setup) parameters.
PCO_CALL_PARAMETERS pCallParameters;
} RNDISMP_VC, *PRNDISMP_VC;
//
// VC hash table.
//
#define RNDISMP_VC_HASH_TABLE_SIZE 41
typedef struct _RNDISMP_VC_HASH_TABLE
{
ULONG NumEntries;
LIST_ENTRY HashEntry[RNDISMP_VC_HASH_TABLE_SIZE];
} RNDISMP_VC_HASH_TABLE, *PRNDISMP_VC_HASH_TABLE;
#define RNDISMP_HASH_VCID(_VcId) ((_VcId) % RNDISMP_VC_HASH_TABLE_SIZE)
//
// High and low watermarks for messages pending
// at the microport
//
#define RNDISMP_PENDED_SEND_HIWAT 0xffff
#define RNDISMP_PENDED_SEND_LOWAT 0xfff
typedef VOID (*RM_MULTIPLE_SEND_HANDLER) ();
//
// This structure contains all the information about a single
// adapter that this driver is controlling
//
typedef struct _RNDISMP_ADAPTER
{
// This is the handle given by the wrapper for calling NDIS functions.
NDIS_HANDLE MiniportAdapterHandle;
// pointer to next adapter in list hanging off driver block
struct _RNDISMP_ADAPTER *NextAdapter;
// pointer to driver block for this adapter
PDRIVER_BLOCK DriverBlock;
// Friendly name:
ANSI_STRING FriendlyNameAnsi;
UNICODE_STRING FriendlyNameUnicode;
#if THROTTLE_MESSAGES
// Counters for messages pending at the microport
ULONG HiWatPendedMessages;
ULONG LoWatPendedMessages;
ULONG CurPendedMessages;
// Messages not yet sent to microport.
LIST_ENTRY WaitingMessageList;
BOOLEAN SendInProgress;
#endif // THROTTLE_MESSAGES
// Messages sent to microport, awaiting completion
LIST_ENTRY PendingAtMicroportList;
BOOLEAN SendProcessInProgress;
LIST_ENTRY PendingSendProcessList;
NDIS_TIMER SendProcessTimer;
// Pool of RNDISMP_MESSAGE_FRAME structures
NPAGED_LOOKASIDE_LIST MsgFramePool;
BOOLEAN MsgFramePoolAlloced;
RNDIS_REQUEST_ID RequestId;
// Receive Routine Data Area
NDIS_HANDLE ReceivePacketPool;
NDIS_HANDLE ReceiveBufferPool;
ULONG InitialReceiveFrames;
ULONG MaxReceiveFrames;
NPAGED_LOOKASIDE_LIST RcvFramePool;
BOOLEAN RcvFramePoolAlloced;
BOOLEAN IndicatingReceives;
// Messages to be processed.
LIST_ENTRY PendingRcvMessageList;
NDIS_TIMER IndicateTimer;
// handlers registered by Remote NDIS microport
RM_DEVICE_INIT_HANDLER RmInitializeHandler;
RM_DEVICE_INIT_CMPLT_NOTIFY_HANDLER RmInitCompleteNotifyHandler;
RM_DEVICE_HALT_HANDLER RmHaltHandler;
RM_SHUTDOWN_HANDLER RmShutdownHandler;
RM_SEND_MESSAGE_HANDLER RmSendMessageHandler;
RM_RETURN_MESSAGE_HANDLER RmReturnMessageHandler;
// handler for DoMultipleSend
RM_MULTIPLE_SEND_HANDLER MultipleSendFunc;
// context for microport adapter
NDIS_HANDLE MicroportAdapterContext;
// pointer to list of OIDs supported
PNDIS_OID SupportedOIDList;
// size of OID list
UINT SupportedOIDListSize;
// pointer to list of flags indicating whether the OID is driver or device supported
PUINT OIDHandlerList;
// size of OID handler list
UINT OIDHandlerListSize;
// pointer to list of Driver OIDs
PNDIS_OID DriverOIDList;
// size of Driver OID list, in OIDs
UINT NumDriverOIDs;
// total number of OIDs we support
UINT NumOIDSupported;
// medium type supported by the device.
NDIS_MEDIUM Medium;
// device flags reported by the device.
ULONG DeviceFlags;
// max NDIS_PACKETs that can be sent in one RNDIS message
ULONG MaxPacketsPerMessage;
BOOLEAN bMultiPacketSupported;
// max message size supported for receive by the microport
ULONG MaxReceiveSize;
// max message size supported by the device
ULONG MaxTransferSize;
// alignment required by the device
ULONG AlignmentIncr;
ULONG AlignmentMask;
// list of message frames pending completion by the device
LIST_ENTRY PendingFrameList;
// synchronization
NDIS_SPIN_LOCK Lock;
// timer to see if we need to send a keep alive message
NDIS_TIMER KeepAliveTimer;
BOOLEAN TimerCancelled;
// timer tick saved last time a message was received from device
ULONG LastMessageFromDevice;
// used by check for hang handler to determine if the device is in trouble
BOOLEAN NeedReset;
// are we waiting for a response to NdisReset?
BOOLEAN ResetPending;
// used by check for hang handler to determine if the device is in trouble
BOOLEAN KeepAliveMessagePending;
// are we initializing?
BOOLEAN Initing;
// are we halting?
BOOLEAN Halting;
// to wait until we complete sending the Halt message
NDIS_EVENT HaltWaitEvent;
// request ID of last Keepalive message we have sent
RNDIS_REQUEST_ID KeepAliveMessagePendingId;
PRNDIS_INITIALIZE_COMPLETE pInitCompleteMessage;
// are we running on Win9x (WinMe)?
BOOLEAN bRunningOnWin9x;
// are we running on Win98 Gold?
BOOLEAN bRunningOnWin98Gold;
// CONDIS - Vc hash table
PRNDISMP_VC_HASH_TABLE pVcHashTable;
ULONG LastVcId;
// Statistics
RNDISMP_ADAPTER_STATS Statistics;
ULONG MaxSendCompleteTime;
// FDO for this device.
PVOID pDeviceObject;
// PDO for this device.
PVOID pPhysDeviceObject;
// MAC options
ULONG MacOptions;
// sanity check
ULONG Signature;
#ifdef BUILD_WIN9X
MY_CMCONFIGHANDLER NdisCmConfigHandler;
MY_DEVNODE DevNode;
ULONG WrapContextOffset;
#endif
#if DBG
ULONG MicroportReceivesOutstanding;
PUCHAR pSendLogBuffer;
ULONG LogBufferSize;
PUCHAR pSendLogWrite;
#endif // DBG
} RNDISMP_ADAPTER, *PRNDISMP_ADAPTER;
typedef
VOID
(*RM_MULTIPLE_SEND_HANDLER) (
IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberofPackets);
//
// Structure to keep context about a single received RNDIS message.
//
typedef struct _RNDISMP_RECV_MSG_CONTEXT
{
LIST_ENTRY Link;
NDIS_HANDLE MicroportMessageContext;
PMDL pMdl;
ULONG TotalLength;
PRNDIS_MESSAGE pMessage;
NDIS_STATUS ReceiveStatus;
BOOLEAN bMessageCopied;
RM_CHANNEL_TYPE ChannelType;
} RNDISMP_RECV_MSG_CONTEXT, *PRNDISMP_RECV_MSG_CONTEXT;
//
// Structure to keep context about a single received RNDIS_PACKET -message-.
// Note that this can contain more than one packet. We store a pointer to
// this structure in our reserved section of each received NDIS_PACKET.
//
typedef struct _RNDISMP_RECV_DATA_FRAME
{
NDIS_HANDLE MicroportMessageContext;
union {
PMDL pMicroportMdl;
PRNDIS_MESSAGE pLocalMessageCopy;
};
ULONG ReturnsPending;
BOOLEAN bMessageCopy; // did we make a copy?
} RNDISMP_RECV_DATA_FRAME, *PRNDISMP_RECV_DATA_FRAME;
//
// Per NDIS_PACKET context for received packets. This goes into MiniportReserved.
//
typedef struct _RNDISMP_RECV_PKT_RESERVED
{
PRNDISMP_RECV_DATA_FRAME pRcvFrame;
PRNDISMP_VC pVc;
} RNDISMP_RECV_PKT_RESERVED, *PRNDISMP_RECV_PKT_RESERVED;
//
// Used to overlay ProtocolReserved in a packet queued for indicating up.
//
typedef struct _RNDISMP_RECV_PKT_LINKAGE
{
LIST_ENTRY Link;
} RNDISMP_RECV_PKT_LINKAGE, *PRNDISMP_RECV_PKT_LINKAGE;
//
// Global Data
//
extern DRIVER_BLOCK RndismpMiniportBlockListHead;
extern UINT RndismpNumMicroports;
extern NDIS_SPIN_LOCK RndismpGlobalLock;
extern NDIS_OID RndismpSupportedOids[];
extern UINT RndismpSupportedOidsNum;
extern NDIS_PHYSICAL_ADDRESS HighestAcceptableMax;
#if DBG
extern UINT RndismpDebugFlags;
#endif
//
// Macros
//
// Given a request message type value, return its completion message type
#define RNDIS_COMPLETION(_Type) ((_Type) | 0x80000000)
// Convert an RNdisMediumXXX value to its NdisMediumXXX equivalent
#define RNDIS_TO_NDIS_MEDIUM(_RndisMedium) ((NDIS_MEDIUM)(_RndisMedium))
#define RNDISMP_GET_ALIGNED_LENGTH(_AlignedLength, _InputLen, _pAdapter) \
{ \
ULONG _Length = _InputLen; \
if (_Length == 0) \
(_AlignedLength) = 0; \
else \
(_AlignedLength) = ((_Length + (_pAdapter)->AlignmentIncr) & \
(_pAdapter)->AlignmentMask); \
}
// The minimum MessageLength expected in an RNDIS message of a given type.
#define RNDISMP_MIN_MESSAGE_LENGTH(_MsgTypeField) \
FIELD_OFFSET(RNDIS_MESSAGE, Message) + sizeof(((PRNDIS_MESSAGE)0)->Message._MsgTypeField##)
// memory move macro
#define RNDISMP_MOVE_MEM(dest,src,size) NdisMoveMemory(dest,src,size)
// Macros to extract high and low bytes of a word.
#define MSB(Value) ((UCHAR)((((ULONG)Value) >> 8) & 0xff))
#define LSB(Value) ((UCHAR)(((ULONG)Value) & 0xff))
// Acquire the adapter lock
#define RNDISMP_ACQUIRE_ADAPTER_LOCK(_pAdapter) \
NdisAcquireSpinLock(&(_pAdapter)->Lock);
// Release the adapter lock
#define RNDISMP_RELEASE_ADAPTER_LOCK(_pAdapter) \
NdisReleaseSpinLock(&(_pAdapter)->Lock);
// Increment adapter statistics.
#define RNDISMP_INCR_STAT(_pAdapter, _StatsCount) \
NdisInterlockedIncrement(&(_pAdapter)->Statistics._StatsCount)
// Get adapter statistics
#define RNDISMP_GET_ADAPTER_STATS(_pAdapter, _StatsCount) \
((_pAdapter)->Statistics._StatsCount)
// Get the send packet reserved field
#define PRNDISMP_RESERVED_FROM_SEND_PACKET(_Packet) \
((PRNDISMP_SEND_PKT_RESERVED)((_Packet)->MiniportReserved))
#define PRNDISMP_RESERVED_TEMP_FROM_SEND_PACKET(_Packet) \
((PRNDISMP_SEND_PKT_RESERVED_TEMP)((_Packet)->MiniportReserved))
#define PRNDISMP_RESERVED_FROM_RECV_PACKET(_Packet) \
((PRNDISMP_RECV_PKT_RESERVED)((_Packet)->MiniportReserved))
// store receive frame context in miniport reserved field
#define RECEIVE_FRAME_TO_NDIS_PACKET(_Packet, _ReceiveFrame) \
{ \
PRNDISMP_RECEIVE_FRAME *TmpPtr; \
TmpPtr = (PRNDISMP_RECEIVE_FRAME *) \
&(_Packet->MiniportReserved); \
*TmpPtr = _ReceiveFrame; \
}
// Get adapter context from handle passed in NDIS routines
#define PRNDISMP_ADAPTER_FROM_CONTEXT_HANDLE(_Handle) \
((PRNDISMP_ADAPTER)(_Handle))
// Get miniport context handle from adapter context
#define CONTEXT_HANDLE_FROM_PRNDISMP_ADAPTER(_Ptr) \
((NDIS_HANDLE)(_Ptr))
// Get VC context from handle passed in from NDIS
#define PRNDISMP_VC_FROM_CONTEXT_HANDLE(_Handle) \
((PRNDISMP_VC)(_Handle))
// Get miniport context from VC
#define CONTEXT_HANDLE_FROM_PRNDISMP_VC(_pVc) \
((NDIS_HANDLE)(_Vc))
// Get message frame from message handle
#define MESSAGE_FRAME_FROM_HANDLE(_Handle) \
((PRNDISMP_MESSAGE_FRAME)(_Handle))
// Get a pointer to the data buff in an RNDIS_PACKET
#define GET_PTR_TO_RNDIS_DATA_BUFF(_Message) \
((PVOID) ((PUCHAR)(_Message) + _Message->DataOffset))
// Get a pointer to the OOBD data in an RNDIS_PACKET
#define GET_PTR_TO_OOB_DATA(_Message) \
((PVOID) ((PUCHAR)(_Message) + _Message->OOBDataOffset))
// Get a pointer to the per packet info in an RNDIS_PACKET
#define GET_PTR_TO_PER_PACKET_INFO(_Message) \
((PVOID) ((PUCHAR)(_Message) + _Message->PerPacketInfoOffset))
// Get an offset to the data buff in an RNDIS_PACKET
#define GET_OFFSET_TO_RNDIS_DATA_BUFF(_Message) \
(sizeof(RNDIS_PACKET))
// Get an offset to the OOBD data in an RNDIS_PACKET
#define GET_OFFSET_TO_OOB_DATA(_Message) \
(sizeof(RNDIS_PACKET) + Message->DataLength)
// Get an offset to the per packet info in an RNDIS_PACKET
#define GET_OFFSET_TO_PER_PACKET_INFO(_Message) \
(sizeof(RNDIS_PACKET) + _Message->DataLength + _Message->OOBDataLength)
#define RNDISMP_GET_INFO_BUFFER_FROM_QUERY_MSG(_Message) \
((PUCHAR)(_Message) + (_Message)->InformationBufferOffset)
#define MIN(x,y) ((x > y) ? y : x)
// Return the virtual address for a received message MDL.
#if NDIS_WDM
#define RNDISMP_GET_MDL_ADDRESS(_pMdl) MmGetSystemAddressForMdl(_pMdl)
#else
#define RNDISMP_GET_MDL_ADDRESS(_pMdl) MmGetSystemAddressForMdlSafe(_pMdl, NormalPagePriority)
#endif
// Return the MDL chained to this MDL
#define RNDISMP_GET_MDL_NEXT(_pMdl) ((_pMdl)->Next)
// Return the MDL length
#define RNDISMP_GET_MDL_LENGTH(_pMdl) MmGetMdlByteCount(_pMdl)
// Access the RNDIS message from our Message Frame structure.
#define RNDISMP_GET_MSG_FROM_FRAME(_pMsgFrame) \
RNDISMP_GET_MDL_ADDRESS(_pMsgFrame->pMessageMdl)
// Return an RNDIS message back to the microport.
#if DBG
#define RNDISMP_RETURN_TO_MICROPORT(_pAdapter, _pMdl, _MicroportMsgContext) \
{ \
NdisInterlockedDecrement(&(_pAdapter)->MicroportReceivesOutstanding); \
(_pAdapter)->RmReturnMessageHandler((_pAdapter)->MicroportAdapterContext,\
(_pMdl), \
(_MicroportMsgContext)); \
}
#else
#define RNDISMP_RETURN_TO_MICROPORT(_pAdapter, _pMdl, _MicroportMsgContext) \
(_pAdapter)->RmReturnMessageHandler((_pAdapter)->MicroportAdapterContext,\
(_pMdl), \
(_MicroportMsgContext))
#endif // DBG
// Send an RNDIS message to the microport.
#if THROTTLE_MESSAGES
#define RNDISMP_SEND_TO_MICROPORT(_pAdapter, _pMsgFrame, _bQueueForResponse, _CallbackFunc) \
{ \
TRACE2(("Send: Adapter %x, MsgFrame %x, Mdl %x\n", \
_pAdapter, _pMsgFrame, _pMsgFrame->pMessageMdl)); \
(_pMsgFrame)->pCallback = _CallbackFunc; \
QueueMessageToMicroport(_pAdapter, _pMsgFrame, _bQueueForResponse); \
}
#else
#define RNDISMP_SEND_TO_MICROPORT(_pAdapter, _pMsgFrame, _bQueueForResponse, _CallbackFunc) \
{ \
(_pMsgFrame)->pCallback = _CallbackFunc; \
if (_bQueueForResponse) \
{ \
RNDISMP_ACQUIRE_ADAPTER_LOCK(_pAdapter); \
InsertTailList(&(_pAdapter)->PendingFrameList, &(_pMsgFrame)->Link);\
RNDISMP_RELEASE_ADAPTER_LOCK(_pAdapter); \
} \
(_pAdapter)->RmSendMessageHandler((_pAdapter)->MicroportAdapterContext, \
(_pMsgFrame)->pMessageMdl, \
(_pMsgFrame)); \
}
#endif // THROTTLE_MESSAGES
// Return the handler function for a given message type.
#define RNDISMP_GET_MSG_HANDLER(_pMsgHandlerFunc, _MessageType) \
{ \
switch (_MessageType) \
{ \
case REMOTE_NDIS_HALT_MSG: \
_pMsgHandlerFunc = HaltMessage; \
break; \
case REMOTE_NDIS_PACKET_MSG: \
_pMsgHandlerFunc = ReceivePacketMessage; \
break; \
case REMOTE_NDIS_INDICATE_STATUS_MSG: \
_pMsgHandlerFunc = IndicateStatusMessage; \
break; \
case REMOTE_NDIS_QUERY_CMPLT: \
case REMOTE_NDIS_SET_CMPLT: \
_pMsgHandlerFunc = QuerySetCompletionMessage; \
break; \
case REMOTE_NDIS_KEEPALIVE_MSG: \
_pMsgHandlerFunc = KeepAliveMessage; \
break; \
case REMOTE_NDIS_KEEPALIVE_CMPLT: \
_pMsgHandlerFunc = KeepAliveCompletionMessage; \
break; \
case REMOTE_NDIS_RESET_CMPLT: \
_pMsgHandlerFunc = ResetCompletionMessage; \
break; \
case REMOTE_NDIS_INITIALIZE_CMPLT: \
_pMsgHandlerFunc = InitCompletionMessage; \
break; \
case REMOTE_CONDIS_MP_CREATE_VC_CMPLT: \
_pMsgHandlerFunc = ReceiveCreateVcComplete; \
break; \
case REMOTE_CONDIS_MP_DELETE_VC_CMPLT: \
_pMsgHandlerFunc = ReceiveDeleteVcComplete; \
break; \
case REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT: \
_pMsgHandlerFunc = ReceiveActivateVcComplete; \
break; \
case REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT: \
_pMsgHandlerFunc = ReceiveDeactivateVcComplete; \
break; \
default: \
_pMsgHandlerFunc = UnknownMessage; \
break; \
} \
}
//
// Look up a message frame on the adapter given a request ID. If found,
// remove it from the pending list and return it.
//
#define RNDISMP_LOOKUP_PENDING_MESSAGE(_pMsgFrame, _pAdapter, _ReqId) \
{ \
PLIST_ENTRY _pEnt; \
PRNDISMP_MESSAGE_FRAME _pFrame; \
\
(_pMsgFrame) = NULL; \
RNDISMP_ACQUIRE_ADAPTER_LOCK(_pAdapter); \
for (_pEnt = (_pAdapter)->PendingFrameList.Flink; \
_pEnt != &(_pAdapter)->PendingFrameList; \
_pEnt = _pEnt->Flink) \
{ \
_pFrame = CONTAINING_RECORD(_pEnt, RNDISMP_MESSAGE_FRAME, Link); \
if (_pFrame->RequestId == (_ReqId)) \
{ \
RemoveEntryList(_pEnt); \
(_pMsgFrame) = _pFrame; \
break; \
} \
} \
RNDISMP_RELEASE_ADAPTER_LOCK(_pAdapter); \
}
#if DBG_TIME_STAMPS
#define RNDISMP_GET_TIME_STAMP(_pTs) \
{ \
LONGLONG systime_usec; \
NdisGetCurrentSystemTime((PVOID)&systime_usec); \
*_pTs = (ULONG)((*(PULONG)&systime_usec)/1000); \
}
#else
#define RNDISMP_GET_TIME_STAMP(_pTs)
#endif
#define RNDISMP_INIT_LOCK(_pLock) \
NdisAllocateSpinLock((_pLock));
#define RNDISMP_ACQUIRE_LOCK(_pLock) \
NdisAcquireSpinLock((_pLock));
#define RNDISMP_RELEASE_LOCK(_pLock) \
NdisReleaseSpinLock((_pLock));
#define RNDISMP_ACQUIRE_LOCK_DPC(_pLock) \
NdisDprAcquireSpinLock((_pLock));
#define RNDISMP_RELEASE_LOCK_DPC(_pLock) \
NdisDprReleaseSpinLock((_pLock));
#define RNDISMP_INIT_VC_LOCK(_pVc) \
RNDISMP_INIT_LOCK(&((_pVc)->Lock))
#define RNDISMP_ACQUIRE_VC_LOCK(_pVc) \
RNDISMP_ACQUIRE_LOCK(&((_pVc))->Lock)
#define RNDISMP_RELEASE_VC_LOCK(_pVc) \
RNDISMP_RELEASE_LOCK(&((_pVc))->Lock)
#define RNDISMP_ACQUIRE_VC_LOCK_DPC(_pVc) \
RNDISMP_ACQUIRE_LOCK_DPC(&((_pVc))->Lock)
#define RNDISMP_RELEASE_VC_LOCK_DPC(_pVc) \
RNDISMP_RELEASE_LOCK_DPC(&((_pVc))->Lock)
#define RNDISMP_REF_VC(_pVc) \
NdisInterlockedIncrement(&(_pVc)->RefCount);
#define RNDISMP_DEREF_VC(_pVc, _pRefCount) \
{ \
ULONG _RefCount; \
\
RNDISMP_ACQUIRE_VC_LOCK(_pVc); \
\
RNDISMP_DEREF_VC_LOCKED(_pVc, &_RefCount); \
*(_pRefCount) = _RefCount; \
if (_RefCount != 0) \
{ \
RNDISMP_RELEASE_VC_LOCK(_pVc); \
} \
}
#define RNDISMP_DEREF_VC_LOCKED(_pVc, _pRefCount) \
{ \
ULONG __RefCount; \
NDIS_HANDLE __NdisVcHandle; \
\
__RefCount = NdisInterlockedDecrement(&(_pVc)->RefCount); \
*(_pRefCount) = __RefCount; \
if (__RefCount == 0) \
{ \
RNDISMP_RELEASE_VC_LOCK(_pVc); \
DeallocateVc(_pVc); \
} \
else \
{ \
if ((__RefCount == 1) && \
((_pVc)->VcState == RNDISMP_VC_DEACTIVATED)) \
{ \
__NdisVcHandle = (_pVc)->NdisVcHandle; \
(_pVc)->VcState = RNDISMP_VC_CREATED; \
NdisInterlockedIncrement(&(_pVc)->RefCount); \
\
RNDISMP_RELEASE_VC_LOCK(_pVc); \
\
NdisMCoDeactivateVcComplete(NDIS_STATUS_SUCCESS, \
__NdisVcHandle); \
\
RNDISMP_ACQUIRE_VC_LOCK(_pVc); \
\
__RefCount = NdisInterlockedDecrement(&(_pVc)->RefCount); \
*(_pRefCount) = __RefCount; \
if (__RefCount == 0) \
{ \
RNDISMP_RELEASE_VC_LOCK(_pVc); \
DeallocateVc(_pVc); \
} \
} \
} \
}
//
// Prototypes for functions in rndismp.c
//
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NDIS_STATUS
RndisMInitializeWrapper(OUT PNDIS_HANDLE pNdisWrapperHandle,
IN PVOID MicroportContext,
IN PVOID DriverObject,
IN PVOID RegistryPath,
IN PRNDIS_MICROPORT_CHARACTERISTICS pCharacteristics);
VOID
RndismpUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS
DllUnload(VOID);
VOID
RndismpHalt(IN NDIS_HANDLE MiniportAdapterContext);
VOID
RndismpInternalHalt(IN NDIS_HANDLE MiniportAdapterContext,
IN BOOLEAN bCalledFromHalt);
NDIS_STATUS
RndismpReconfigure(OUT PNDIS_STATUS pStatus,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE ConfigContext);
NDIS_STATUS
RndismpReset(OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext);
BOOLEAN
RndismpCheckForHang(IN NDIS_HANDLE MiniportAdapterContext);
NDIS_STATUS
RndismpInitialize(OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE ConfigurationHandle);
VOID
RndisMSendComplete(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE RndisMessageHandle,
IN NDIS_STATUS SendStatus);
BOOLEAN
InitCompletionMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
HaltMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
ResetCompletionMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
KeepAliveCompletionMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
KeepAliveMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
VOID
RndismpShutdownHandler(IN NDIS_HANDLE MiniportAdapterContext);
VOID
RndismpDisableInterrupt(IN NDIS_HANDLE MiniportAdapterContext);
VOID
RndismpEnableInterrupt(IN NDIS_HANDLE MiniportAdapterContext);
VOID
RndismpHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext);
VOID
RndismpIsr(OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueDpc,
IN PVOID Context);
VOID
CompleteSendHalt(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
VOID
CompleteSendReset(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
VOID
CompleteMiniportReset(IN PRNDISMP_ADAPTER pAdapter,
IN NDIS_STATUS ResetStatus,
IN BOOLEAN AddressingReset);
NDIS_STATUS
ReadAndSetRegistryParameters(IN PRNDISMP_ADAPTER pAdapter,
IN NDIS_HANDLE ConfigurationContext);
NDIS_STATUS
SendConfiguredParameter(IN PRNDISMP_ADAPTER pAdapter,
IN NDIS_HANDLE ConfigHandle,
IN PNDIS_STRING pParameterName,
IN PNDIS_STRING pParameterType);
VOID
RndismpPnPEventNotify(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_DEVICE_PNP_EVENT EventCode,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength);
//
// Prototypes for functions in init.c
//
NDIS_STATUS
SetupSendQueues(IN PRNDISMP_ADAPTER Adapter);
NDIS_STATUS
SetupReceiveQueues(IN PRNDISMP_ADAPTER Adapter);
NDIS_STATUS
AllocateTransportResources(IN PRNDISMP_ADAPTER Adapter);
VOID
FreeTransportResources(IN PRNDISMP_ADAPTER Adapter);
VOID
FreeSendResources(IN PRNDISMP_ADAPTER Adapter);
VOID
FreeReceiveResources(IN PRNDISMP_ADAPTER Adapter);
//
// Prototypes for functions in receive.c
//
VOID
RndismpReturnPacket(IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet);
VOID
DereferenceRcvFrame(IN PRNDISMP_RECV_DATA_FRAME pRcvFrame,
IN PRNDISMP_ADAPTER pAdapter);
VOID
RndisMIndicateReceive(IN NDIS_HANDLE MiniportAdapterContext,
IN PMDL pMessageHead,
IN NDIS_HANDLE MicroportMessageContext,
IN RM_CHANNEL_TYPE ChannelType,
IN NDIS_STATUS ReceiveStatus);
VOID
IndicateReceive(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PRNDISMP_RECV_DATA_FRAME pRcvFrame,
IN PPNDIS_PACKET PacketArray,
IN ULONG NumberOfPackets,
IN NDIS_STATUS ReceiveStatus);
PRNDIS_MESSAGE
CoalesceMultiMdlMessage(IN PMDL pMdl,
IN ULONG TotalLength);
VOID
FreeRcvMessageCopy(IN PRNDIS_MESSAGE pMessage);
BOOLEAN
ReceivePacketMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
ReceivePacketMessageRaw(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
IndicateStatusMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
UnknownMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
PRNDISMP_RECV_DATA_FRAME
AllocateReceiveFrame(IN PRNDISMP_ADAPTER pAdapter);
VOID
FreeReceiveFrame(IN PRNDISMP_RECV_DATA_FRAME pRcvFrame,
IN PRNDISMP_ADAPTER pAdapter);
VOID
IndicateTimeout(IN PVOID SystemSpecific1,
IN PVOID Context,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
//
// Prototypes for functions in send.c
//
VOID
RndismpMultipleSend(IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets);
VOID
DoMultipleSend(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets);
VOID
DoMultipleSendRaw(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets);
PRNDISMP_PACKET_WRAPPER
PrepareDataMessage(IN PNDIS_PACKET pNdisPacket,
IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN OUT PULONG pTotalMessageLength);
PRNDISMP_PACKET_WRAPPER
PrepareDataMessageRaw(IN PNDIS_PACKET pNdisPacket,
IN PRNDISMP_ADAPTER pAdapter,
IN OUT PULONG pTotalMessageLength);
PRNDISMP_PACKET_WRAPPER
AllocatePacketMsgWrapper(IN PRNDISMP_ADAPTER pAdapter,
IN ULONG MsgHeaderLength);
VOID
FreePacketMsgWrapper(IN PRNDISMP_PACKET_WRAPPER pPktWrapper);
VOID
CompleteSendData(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
VOID
FreeMsgAfterSend(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
#if THROTTLE_MESSAGES
VOID
QueueMessageToMicroport(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN BOOLEAN bQueueMessageForResponse);
VOID
FlushPendingMessages(IN PRNDISMP_ADAPTER pAdapter);
#endif
VOID
SendProcessTimeout(IN PVOID SystemSpecific1,
IN PVOID Context,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
//
// Prototypes for functions in request.c
//
NDIS_STATUS
RndismpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesWritten,
OUT PULONG pBytesNeeded);
NDIS_STATUS
ProcessQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc,
IN PNDIS_REQUEST pRequest,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesWritten,
OUT PULONG pBytesNeeded);
NDIS_STATUS
RndismpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesRead,
OUT PULONG pBytesNeeded);
NDIS_STATUS
ProcessSetInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PNDIS_REQUEST pRequest OPTIONAL,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesRead,
OUT PULONG pBytesNeeded);
NDIS_STATUS
DriverQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PNDIS_REQUEST pRequest OPTIONAL,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesWritten,
OUT PULONG pBytesNeeded);
NDIS_STATUS
DeviceQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PNDIS_REQUEST pRequest OPTIONAL,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesWritten,
OUT PULONG pBytesNeeded);
NDIS_STATUS
DriverSetInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PNDIS_REQUEST pRequest OPTIONAL,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesRead,
OUT PULONG pBytesNeeded);
NDIS_STATUS
DeviceSetInformation(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc OPTIONAL,
IN PNDIS_REQUEST pRequest OPTIONAL,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG pBytesRead,
OUT PULONG pBytesNeeded);
BOOLEAN
QuerySetCompletionMessage(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
VOID
CompleteSendDeviceRequest(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
#ifdef BUILD_WIN9X
VOID
CompleteSendDiscardDeviceRequest(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
#endif // BUILD_WIN9X
NDIS_STATUS
BuildOIDLists(IN PRNDISMP_ADAPTER Adapter,
IN PNDIS_OID DeviceOIDList,
IN UINT NumDeviceOID,
IN PNDIS_OID DriverOIDList,
IN UINT NumDriverOID);
UINT
GetOIDSupport(IN PRNDISMP_ADAPTER Adapter, IN NDIS_OID Oid);
VOID
FreeOIDLists(IN PRNDISMP_ADAPTER Adapter);
PRNDISMP_REQUEST_CONTEXT
AllocateRequestContext(IN PRNDISMP_ADAPTER pAdapter);
VOID
FreeRequestContext(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_REQUEST_CONTEXT pReqContext);
//
// Prototypes for functions in util.c
//
NDIS_STATUS
MemAlloc(OUT PVOID *Buffer, IN UINT Length);
VOID
MemFree(IN PVOID Buffer, IN UINT Length);
VOID
AddAdapter(IN PRNDISMP_ADAPTER Adapter);
VOID
RemoveAdapter(IN PRNDISMP_ADAPTER Adapter);
VOID
DeviceObjectToAdapterAndDriverBlock(IN PDEVICE_OBJECT pDeviceObject,
OUT PRNDISMP_ADAPTER * ppAdapter,
OUT PDRIVER_BLOCK * ppDriverBlock);
VOID
AddDriverBlock(IN PDRIVER_BLOCK Head, IN PDRIVER_BLOCK Item);
VOID
RemoveDriverBlock(IN PDRIVER_BLOCK BlockHead, IN PDRIVER_BLOCK Item);
PDRIVER_BLOCK
DeviceObjectToDriverBlock(IN PDRIVER_BLOCK Head,
IN PDEVICE_OBJECT DeviceObject);
PDRIVER_BLOCK
DriverObjectToDriverBlock(IN PDRIVER_BLOCK Head,
IN PDRIVER_OBJECT DriverObject);
PRNDISMP_MESSAGE_FRAME
AllocateMsgFrame(IN PRNDISMP_ADAPTER pAdapter);
VOID
DereferenceMsgFrame(IN PRNDISMP_MESSAGE_FRAME pMsgFrame);
VOID
ReferenceMsgFrame(IN PRNDISMP_MESSAGE_FRAME pMsgFrame);
VOID
EnqueueNDISPacket(IN PRNDISMP_ADAPTER Adapter, IN PNDIS_PACKET Packet);
PNDIS_PACKET
DequeueNDISPacket(IN PRNDISMP_ADAPTER Adapter);
VOID
KeepAliveTimerHandler(IN PVOID SystemSpecific1,
IN PVOID Context,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);
VOID
CompleteSendKeepAlive(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
PRNDISMP_MESSAGE_FRAME
BuildRndisMessageCommon(IN PRNDISMP_ADAPTER Adapter,
IN PRNDISMP_VC pVc,
IN UINT NdisMessageType,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength);
PRNDISMP_MESSAGE_FRAME
AllocateMessageAndFrame(IN PRNDISMP_ADAPTER Adapter,
IN UINT MessageSize);
VOID
FreeAdapter(IN PRNDISMP_ADAPTER pAdapter);
PRNDISMP_VC
AllocateVc(IN PRNDISMP_ADAPTER pAdapter);
VOID
DeallocateVc(IN PRNDISMP_VC pVc);
PRNDISMP_VC
LookupVcId(IN PRNDISMP_ADAPTER pAdapter,
IN UINT32 VcId);
VOID
EnterVcIntoHashTable(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc);
VOID
RemoveVcFromHashTable(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc);
//
// Prototypes for functions in comini.c
//
NDIS_STATUS
RndismpCoCreateVc(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE NdisVcHandle,
IN PNDIS_HANDLE pMiniportVcContext);
VOID
CompleteSendCoCreateVc(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
VOID
HandleCoCreateVcFailure(IN PRNDISMP_VC pVc,
IN NDIS_STATUS Status);
NDIS_STATUS
RndismpCoDeleteVc(IN NDIS_HANDLE MiniportVcContext);
NDIS_STATUS
StartVcDeletion(IN PRNDISMP_VC pVc);
VOID
CompleteSendCoDeleteVc(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
VOID
HandleCoDeleteVcFailure(IN PRNDISMP_VC pVc,
IN NDIS_STATUS Status);
NDIS_STATUS
RndismpCoActivateVc(IN NDIS_HANDLE MiniportVcContext,
IN PCO_CALL_PARAMETERS pCallParameters);
NDIS_STATUS
StartVcActivation(IN PRNDISMP_VC pVc);
VOID
CompleteSendCoActivateVc(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
NDIS_STATUS
RndismpCoDeactivateVc(IN NDIS_HANDLE MiniportVcContext);
VOID
CompleteSendCoDeactivateVc(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
IN NDIS_STATUS SendStatus);
NDIS_STATUS
RndismpCoRequest(IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportVcContext,
IN OUT PNDIS_REQUEST pRequest);
VOID
RndismpCoSendPackets(IN NDIS_HANDLE MiniportVcContext,
IN PNDIS_PACKET * PacketArray,
IN UINT NumberOfPackets);
BOOLEAN
ReceiveCreateVcComplete(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
ReceiveActivateVcComplete(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
ReceiveDeleteVcComplete(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
BOOLEAN
ReceiveDeactivateVcComplete(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDIS_MESSAGE pMessage,
IN PMDL pMdl,
IN ULONG TotalLength,
IN NDIS_HANDLE MicroportMessageContext,
IN NDIS_STATUS ReceiveStatus,
IN BOOLEAN bMessageCopied);
PRNDISMP_MESSAGE_FRAME
BuildRndisMessageCoMiniport(IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_VC pVc,
IN UINT NdisMessageType,
IN PCO_CALL_PARAMETERS pCallParameters OPTIONAL);
VOID
CompleteSendDataOnVc(IN PRNDISMP_VC pVc,
IN PNDIS_PACKET pNdisPacket,
IN NDIS_STATUS Status);
VOID
IndicateReceiveDataOnVc(IN PRNDISMP_VC pVc,
IN PNDIS_PACKET * PacketArray,
IN UINT NumberOfPackets);
//
// Prototypes for functions in wdmutil.c
//
PDRIVER_OBJECT
DeviceObjectToDriverObject(IN PDEVICE_OBJECT DeviceObject);
NTSTATUS
GetDeviceFriendlyName(IN PDEVICE_OBJECT pDeviceObject,
OUT PANSI_STRING pAnsiString,
OUT PUNICODE_STRING pUnicodeString);
VOID
HookPnpDispatchRoutine(IN PDRIVER_BLOCK DriverBlock);
NTSTATUS
PnPDispatch(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp);
#ifdef BUILD_WIN9X
VOID
HookNtKernCMHandler(IN PRNDISMP_ADAPTER pAdapter);
VOID
UnHookNtKernCMHandler(IN PRNDISMP_ADAPTER pAdapter);
MY_CONFIGRET __cdecl
RndisCMHandler(IN MY_CONFIGFUNC cfFuncName,
IN MY_SUBCONFIGFUNC cfSubFuncName,
IN MY_DEVNODE cfDevNode,
IN ULONG dwRefData,
IN ULONG ulFlags);
#endif
#if DBG
//
// Prototypes for functions in debug.c
//
PCHAR
GetOidName(IN NDIS_OID Oid);
VOID
DisplayOidList(IN PRNDISMP_ADAPTER Adapter);
VOID
RndisPrintHexDump(PVOID Pointer,
ULONG Length);
VOID
RndisLogSendMessage(
IN PRNDISMP_ADAPTER pAdapter,
IN PRNDISMP_MESSAGE_FRAME pMsgFrame);
#endif
#endif // _RNDISMP_H_