📄 common.h
字号:
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
common.h
Abstract:
Header for device data structure definitions and functions
that are common to USB-oriented souce modules and Ndis-oriented
source modules.
This header must not contain any references to types that are
either unique to NDIS or unique to USBD, as it must be usable with
either Wdm.h, or Ndis.h with BINARY_COMPATIBLE set to 1 for Win98 compatibility.
Unfortunately, Wdm.h cannot compile with Ndis.h in the same module
unless BINARY_COMPATIBLE == 0, but this causes the executable to be
incompatible with Win98.
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:
--*/
#ifndef _COM_H
#define _COM_H
//
// We use a pointer to the USB_DEVICE structure as the miniport's device context.
//
#define CONTEXT_TO_DEV(__deviceContext) ((PUSB_DEVICE)(__deviceContext))
#define DEV_TO_CONTEXT(__irdev) ((HANDLE)(__irdev))
#define USB_TAG 'HPNA'
#define MAX_PACKET_SIZE 0x00000600
#define USB_PACKET_LENGTH 2
// This is for use by check-for-hang handler and is just a reasonable guess;
// Total # of USBD control errors, read aerrors and write errors;
// Used by check-for-hang handler to decide if we need a reset
//
#define USB_100ns_PER_ms 10000
#define USB_100ns_PER_us 10
#define USB_ms_PER_SEC 1000
#define USB_100ns_PER_SEC ( USB_100ns_PER_ms * USB_ms_PER_SEC )
#define MAX_QUERY_TIME_100ns ( 8 * USB_100ns_PER_SEC ) //8 sec
#define MAX_SET_TIME_100ns MAX_QUERY_TIME_100ns
#define MAX_SEND_TIME_100ns ( 20 * USB_100ns_PER_SEC ) //20 sec
#define MAX_TURNAROUND_usec 10000
#define DEFAULT_TURNAROUND_usec 5000
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
/*
* A receive buffer is either FREE (not holding anything) FULL
* (holding undelivered data) or PENDING (holding data delivered
* asynchronously)
*/
typedef enum rcvbufferStates {
STATE_FREE,
STATE_FULL,
STATE_PENDING
} rcvBufferState;
//
// Structure to keep track of receive packets and buffers to indicate
// receive data to the protocol.
//
typedef struct
{
PVOID packet;
UINT dataLen;
PUCHAR dataBuf;
PVOID device;
PVOID Irp;
KEVENT Event;//内核事件
rcvBufferState state;
PVOID Urb;
} RCV_BUFFER, *PRCV_BUFFER;
//
// Enum of context types for SendPacket
//
typedef enum _CONTEXT_TYPE {
CONTEXT_NDIS_PACKET = 1,
CONTEXT_TERMINATOR
} CONTEXT_TYPE;
typedef VOID (*WORK_PROC)(struct _USB_WORK_ITEM *);
typedef struct _USB_WORK_ITEM
{
PVOID pDevice;
WORK_PROC Callback;
PUCHAR InfoBuf;
ULONG InfoBufLen;
ULONG fInUse; // declared as ulong for use with interlockedexchange
} USB_WORK_ITEM, *PUSB_WORK_ITEM;
typedef struct _USB_DEVICE//自定义结构,为保存设备信息,类似设备对象
{
//
// Keep track of various device objects.
//
PDEVICE_OBJECT pUsbDevObj; //'Next Device Object'
PDEVICE_OBJECT pPhysDevObj; // Physical Device Object
//
// This is the handle that the NDIS wrapper associates with a connection.
// (The handle that the miniport driver associates with the connection
// is just an index into the devStates array).
//
HANDLE hNdisAdapter;
//
// Maintain statistical debug info.
//
ULONG packetsReceived;
ULONG packetsReceivedDropped;
ULONG packetsReceivedOverflow;
ULONG packetsSent;
ULONG packetsSentDropped;
ULONG SendContextsInUse;
ULONG RcvBuffersInUse; //已用接收的缓冲数
// used by check hang handler to track Query, Set, and Send times
LARGE_INTEGER LastQueryTime;
LARGE_INTEGER LastSetTime;
BOOLEAN fSetpending;
BOOLEAN fQuerypending;
//
// Set when device has been started; use for safe cleanup after failed initialization
//
BOOLEAN fDeviceStarted;
//
// Indicates that we have received an OID_GEN_CURRENT_PACKET_FILTER
// indication from the protocol. We can deliver received packets to the
// protocol.
//
BOOLEAN fGotFilterIndication;
//
// NDIS calls most of the MiniportXxx function with IRQL DISPATCH_LEVEL.
// There are a number of instances where the ir device must send
// requests to the device which may be synchronous and
// we can't block in DISPATCH_LEVEL. Therefore, we set up a thread to deal
// with request which require PASSIVE_LEVEL. An event is used to signal
// the thread that work is required.
//
HANDLE hPassiveThread;
BOOLEAN fKillPassiveLevelThread;
KEVENT EventPassiveThread;
//
// The variable fReceiving is used to indicate that the device
// object in pending a receive from the USB device object. Note,
// that this does NOT necessarily mean that any data is being
// received from the USB device object, since we are constantly
// in a blocking receive call to the USB device object for data.
//
// Under normal circumstances fReceiving should always be TRUE.
// However, when usbHalt or usbReset are called, the receive
// has to be shut down and this variable is used to synchronize
// the halt and reset handler.
//
BOOLEAN fReceiving;
//
// The variables fPendingHalt and fPendingReset allow the send and receive
// completion routines to complete the current pending irp and
// then cleanup and stop sending irps to the USB driver.
//
BOOLEAN fPendingHalt;
BOOLEAN fPendingReset;
ULONG fPendingReadClearStall;
ULONG fPendingWriteClearStall;
//
// We keep an array of receive buffers so that we don't continually
// need to allocate buffers to indicate packets to the protocol.
// Since the protocol can retain ownership of up to eight packets
// and we can be receiving up to WindowSize ( 7 ) packets while the protocol has
// ownership of eight packets, we will allocate 16 packets for
// receiving.
//协议栈中可以保存8个包,滑动窗口大小为8,所有为16个包分配缓冲区
#define NUM_RCV_BUFS 16
RCV_BUFFER rcvBufs[NUM_RCV_BUFS];
PRCV_BUFFER pCurrentRcvBuf;
// Can have max of NUM_RCV_BUFS packets pending + one set and one query
//
#define NUM_WORK_ITEMS (NUM_RCV_BUFS + 3)
USB_WORK_ITEM WorkItems[ NUM_WORK_ITEMS ];
//
// Since we can have muliple write irps pending with the USB driver,
// we track the irp contexts for each one so we have all the info we need at each
// invokation of the USB write completion routine. See the USB_CONTEXT definition below
//
#define NUM_SEND_CONTEXTS NUM_RCV_BUFS
PVOID pSendContexts;
//
// Handles to the NDIS packet pool and NDIS buffer pool
// for allocating the receive buffers.
//
HANDLE hPacketPool;
HANDLE hBufferPool;
KEVENT EventUrb;
KEVENT EventIoCtl;//仅为调试用
NTSTATUS StatusControl;
NTSTATUS StatusReset;
ULONG BytesRead;
// track pending IRPS; this should be zero at halt time
UINT PendingIrpCount;
ULONG NumReads;
// total # of USBD control errors, read aerrors and write errors;
// used by check-for-hang handler to decide if we need a reset
//
ULONG NumDataErrors;
//这里要加上Interrupt pipeHandle和接收每个Internal的以太网状态
HANDLE BulkInPipeHandle;
HANDLE BulkOutPipeHandle;
HANDLE InterruptInPipeHandle;
UINT IntInternalTime;
HANDLE hPollingThread;
BOOLEAN fKillPollingThread;
//
// The IR USB dongle's USB Class-Specific Descriptor as per
// "Universal Serial Bus IrDA Bridge Device Definition" doc, section 7.2
// This is the struct returned by USBD as the result of a request with an urb
// of type _URB_CONTROL_VENDOR_OR_CLASS_REQUEST, function URB_FUNCTION_CLASS_DEVICE.
// Note this struct is in-line, not a pointer
//
// USB_CLASS_SPECIFIC_DESCRIPTOR ClassDesc;
UINT IdVendor; //USB vendor Id read from dongle
// We don't define it here because we need to isolate USB stuff so we
// can build things referencing NDIS with the BINARY_COMPATIBLE flag for win9x
PUCHAR pUsbInfo;
// Optional registry entry for debugging; limit baud rate.
// The mask is set up as per the USB Class-Specific descriptor 'wBaudRate'
// This is 'and'ed with value from Class descriptor to possibly limit baud rate;
// It defaults to 0xffff
//
UINT UrbLen;
}USB_DEVICE, *PUSB_DEVICE;
VOID PassiveLevelThread(
IN PVOID Context
);
VOID PollingThread(
IN PVOID Context
);
NTSTATUS StartUsbRead(IN PUSB_DEVICE Device);
NTSTATUS
SendPacket(
IN PUSB_DEVICE Device,
IN PVOID pPacket,
IN UINT Flags,
IN CONTEXT_TYPE Type
);
BOOLEAN NdisToUsbPacket(
IN PUSB_DEVICE thisDev,
IN PVOID Packet,
OUT UCHAR *usbPacketBuf,
IN UINT usbPacketBufLen
);
PRCV_BUFFER
GetRcvBuf(
PUSB_DEVICE Device,
OUT UINT *pIndex,
IN rcvBufferState state
);
PVOID
GetFreeContext(
PUSB_DEVICE Device
);
VOID
IndicateMediaBusy(
IN PUSB_DEVICE Device
);
NTSTATUS ProcessData(
IN PUSB_DEVICE Device,
IN PRCV_BUFFER pRecBuf
);
VOID
ProcessDataCallBack( PUSB_WORK_ITEM pWorkItem );
VOID ProcessReturnPacket(PUSB_DEVICE Device,
PRCV_BUFFER pReceiveBuffer);
NTSTATUS DeliverBuffer(
IN PUSB_DEVICE Device,
IN PRCV_BUFFER pRecBuf
);
NTSTATUS
ResetPipe (
IN PUSB_DEVICE Device,
IN HANDLE Pipe
);
VOID
ResetPipeCallback (
IN PUSB_WORK_ITEM pWorkItem
);
PVOID
AllocXferUrb ( VOID );
VOID
FreeXferUrb( PVOID Urb );
BOOLEAN
CancelPendingReadIo(
IN PUSB_DEVICE DeviceExt,
BOOLEAN fWaitCancelComplete
);
BOOLEAN
CancelPendingWriteIo(
IN PUSB_DEVICE DeviceExt
);
BOOLEAN
InitWdmStuff(
IN OUT PUSB_DEVICE Device
);
VOID
FreeWdmStuff(
IN OUT PUSB_DEVICE Device
);
BOOLEAN AllocUsbInfo(
PUSB_DEVICE Device );
VOID FreeUsbInfo(
PUSB_DEVICE Device );
PVOID MemAlloc(UINT);
VOID MemFree(
IN PVOID memptr,
IN UINT size
);
VOID
UsbIncIoCount(
IN PUSB_DEVICE Device
);
VOID
UsbDecIoCount(
IN PUSB_DEVICE Device
);
NTSTATUS InitializeReceive(
IN OUT PUSB_DEVICE Device
);
BOOLEAN
ScheduleWorkItem(
PUSB_DEVICE pDevice,
WORK_PROC Callback,
PVOID InfoBuf,
ULONG InfoBufLen);
VOID FreeWorkItem(
IN PUSB_WORK_ITEM pItem
);
void DumpStatsEverySec( PUSB_DEVICE Device, UINT NumSeconds ) ;
#endif// _IRCOM_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -