📄 usb_wirlessadapter.cpp
字号:
//////////////////////////////////////////////////////////////////////////
// Copyright @2003 Peng He,Information Science Insititute,XiDian University
// MyNdis_Wdm example
//Abstract:
// Main Module
//Environment:
// kernel mode only
// Version history:
//
// Peng.He - 04/17/03: this source code for USB to fast Ethernet adapter driver
// show how an NDIS miniport driver can interface with an USB device.
// 17-Apr-2003 creation
/////////////////////////////////////////////////////////////////////////
#define BINARY_COMPATIBLE 1 // for win9x compatibility with ndis.h
#define DOBREAKS // enable debug breaks
#include <ndis.h>
#include <ntddndis.h> // defines OID's
#include "debug.h"
#include "common.h"
#include "USBNDIS.h"
//
//
//初始化NDIS库和注册微端口驱动程序
//
NDIS_STATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath);
#pragma NDIS_INIT_FUNCTION(DriverEntry)
//开始程序
/////////////
NDIS_STATUS
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
{
NDIS_STATUS status=NDIS_STATUS_SUCCESS; // 接收到NdisMRegisterMiniport操作后返回的状态,置初始状态为成功
NDIS_MINIPORT_CHARACTERISTICS characteristics; //定义驱动程序的状态表
NDIS_HANDLE NdisWrapperHandle; //定义驱动程序的包裹句柄
//初始化NDIS库
NdisMInitializeWrapper(
&NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL
);
NdisZeroMemory( //对驱动程序状态表的数据缓冲区清零
&characteristics,
sizeof(characteristics)
);
//NDIS库保存一些微端口入口点指针,以供以后调用微端口时使用
characteristics.MajorNdisVersion = (UCHAR)NDIS_MAJOR_VERSION;
characteristics.MinorNdisVersion = (UCHAR)NDIS_MINOR_VERSION;
characteristics.Reserved = 0;
characteristics.InitializeHandler = MiniportInitialize;
characteristics.QueryInformationHandler = MiniportQueryInformation;
characteristics.SetInformationHandler = MiniportSetInformation;
characteristics.ResetHandler = MiniportReset;
//某一时刻只允许NDIS进行单包发送
characteristics.SendHandler = MiniportSend;
characteristics.SendPacketsHandler = NULL;
//包描述符所描述的资源返回给微端口的MiniportReturnPacket函数
characteristics.ReturnPacketHandler = MiniportReturnPacket;
//终止微端口函数的入口点指针
characteristics.HaltHandler = MiniportHalt;
characteristics.TransferDataHandler = NULL;
//NDIS从来不调用微端口的重新配置函数
characteristics.ReconfigureHandler = NULL;
//该微端口驱动程序不支持中断处理
characteristics.HandleInterruptHandler = NULL;
characteristics.ISRHandler = NULL;
characteristics.DisableInterruptHandler = NULL;
characteristics.EnableInterruptHandler = NULL;
//该微端口驱动程序不支持总线控制的DMA操作
characteristics.AllocateCompleteHandler = NULL;
//注册微端口驱动程序,将返回状态附值给status
status=NdisMRegisterMiniport(
NdisWrapperHandle,
&characteristics,
sizeof(characteristics)
);
if (Status == NDIS_STATUS_SUCCESS) {
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/*****************************************************************************
//
//注册网络接口卡NIC,为维护NIC运行时状态的、与适配器相关的环境区分配内存
//
*****************************************************************************/
#pragma NDIS_PAGEABLE_FUNCTION(MiniportInitialize)
extern
NDIS_STATUS
MiniportInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArrySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext
)
{
ULONG i;
PDEVICE_OBJECT PhysicalDeviceObject; //物理设备对象
PDEVICE_OBJECT NextDeviceObject; //总线设备对象
NDIS_STATUS status;
NDIS_STATUS Usbstatus;
PUSB_DEVICE Adapter; //指向USB网络适配器逻辑结构的指针
NDIS_HANDLE ConfigHandle; //读取注册表信息的函数句柄
PNDIS_CONFIGURATION_PARAMETER ReturnValue; //指向存储有注册表信息的数据结构区的指针
//被读取的注册表参数信息用字符串表示
NDIS_STRING IOAddressStr=NDIS_STRING_CONST("IOBaseAddress");
NDIS_STRING InterruptStr = NDIS_STRING_CONST("InterruptNumber");
NDIS_STRING MaxMulticastListStr = NDIS_STRING_CONST("MaximumMulticastList");
NDIS_STRING NetworkAddressStr = NDIS_STRING_CONST("NetworkAddress");
NDIS_STRING BusTypeStr = NDIS_STRING_CONST("BusType");
NDIS_STRING CardTypeStr = NDIS_STRING_CONST("CardType");
PVOID NetAddress; //网络适配器地址
PVOID IoBaseAddr; //设备I/O的端口地址
CCHAR InterruptNumber; //中断向量值
BOOLEAN Finfor;
//
// 在给定的传输介质链表中寻找以太网介质类型(802 .3)
//
for (i=0; i<MediumArraySize;i++)
{
if (MediumArray[i]==NdisMedium802_3)
{
break;
}
}
if (i==MediumArraySize)
{
return(NDIS_STATUS_UNSUPPORTED_MEDIA);
goto release;
}
*SelectedMediumIndex=i;
//
// 设置默认值
//
IoBaseAddr = DEFAULT_IOBASEADDR;
InterruptNumber = DEFAULT_INTERRUPTNUMBER;
//
// 获取设备对象,该对象是建立通过总线驱动程序与NIC通信所需的
//
NdisMGetDeviceProperty(
MiniportAdapterHandle, //获取逻辑适配器结构句柄
&PhysicalDeviceObject,//物理
NULL,
&NextDeviceObject,//总线
NULL,
NULL);
//
// 为NDIS网络适配器分配内存并清零
//
Adapter=MemAlloc(sizeof(USB_DEVICE))
if (Adapter==NULL)
{
status=NDIS_STATUS_RESOURCES;
goto release;
}
NdisZeroMemory((PVIOD)Adapter,sizeof(USB_DEVICE));
//
// 为保存USB设备信息分配内存和清零
//
Finfor=AllocUsbInfor(Adapter); //调用保存设备信息的内存分配函数,返回一布尔变量
if (!Finfor)
{
status=NDIS_STATUS_RESORUCES;
goto release;
}
Adapter->PUsbDevObj=NextDeviceObject;
Adapter->PPhysDevObj=PhysicalDeviceObject;
//
// 给NDIS网络适配器Adapter结构附初值,调用InitializeDevice函数
//
status=InitializeDevice(Adapter)
if (status!=NDIS_STATUS_SUCCESS)
{
goto release;
}
` Adapter->MiniportHandle=MiniportAdapterHandle; //将获取的逻辑适配器结构句柄传递给Adapter结构体中的MiniportHandle
//
// 向NDIS库报告微端口驱动程序所支持的NIC类型,并且传递指向微端口环境区的句柄
//
NdisMSetAttributesEx( // 通过 NdisMSetAttributesEx建立NDIS的包裹句柄和逻辑适配器结构句柄间的关系
MiniportAdapterHandle, // 逻辑适配器结构句柄
(NDIS_HANDLE)Adapter, // 指向微端口环境区的句柄
0, // CheckForHangTimeInSeconds的时间间隔
NDIS_ATTRIBUTE_DESERIALIZE // NIC的属性标志位,为非串行NIC类型
NdisInterfaceInternal); // NIC微端口的I/O总线接口类型
// Now we're ready to do our own startup processing.
// USB client drivers such as set up URBs (USB Request Packets) to send requests
// to the host controller driver (HCD). The URB structure defines a format for all
// possible commands that can be sent to a USB device.
// Here, we request the device descriptor and store it,
// and configure the device.
// In USB, no special HW processing is required to 'open' or 'close' the pipes
// 现在我们可以着手处理USB驱动程序,初始化USB设备,获取设备描述符,创建URB结构,配置USB设备
Usbstatus=StartDevice(Adapter); // 开始USB设备
if (Usbstatus!=NDIS_STATUS_SUCCESS)
{
status=NDIS_STATUS_ADAPTER_NOT_FOUND;
goto release;
}
//
// 调用InitializeReceive函数,该函数创建了PassiveLevelThread,PollingThread两个内核线程用以接收
//
status=InitializeReceive(Adapter)
if (status!=NDIS_STATUS_SUCCESS)
{
goto release;
}
release:
if (status != NDIS_STATUS_SUCCESS)
{
if (device != NULL)
{
DeinitializeDevice(Adapter);
MemFree( Adapter, sizeof(USB_DEVICE));
FreeUsbInfo( Adapter );
}
}
return status;
}
/*****************************************************************************
//
// 初始化USB总线设备,对软件逻辑对象Adapter结构中的USB设备附初值
//
*****************************************************************************/
NDIS_STATUS
InitializeDevice(
IN OUT PUSB_DEVICE Adapter)
{
int i;
NDIS_STATUS status=NDIS_STATUS_SUCCESS;
DEBUGMSG(DBG_FUNC|DBG_PNP, ("+InitializeDevice\n"));
ASSERT(Adapter!=NULL)
//
// 初始化软件逻辑适配器对象Adapter结构中的USB设备信息
//
Adapter->PacketsReceived =0; // 已接受的数据包数目为零
Adapter->PacketsReceivedDropped =0; // 接受过程中的丢包数目为零
Adapter->PacketsReceivedOverflow =0; // 包队列中的溢出包数目为零
Adapter->PacketsSend =0; // 已发送的数据包数目为零
Adapter->PacketsSendDropped =0; // 发送过程中的丢包数目为零
Adapter->SendBuffersInUse =0; // 已用发送的缓冲数为零
Adapter->RcvBuffersInUse =0; // 已用接收的缓冲数为零
Adapter->fDeviceStarted =FALSE; // 设备还未开始
Adapter->fGotFilterIndication =FALSE; // 尚未从上层协议驱动程序接收到网络包标志符为OID_GEN_CURRENT_PACKET_FILTER网络数据包
Adapter->fPendingHalt =FALSE; // 处理接收与发送完成例程中被挂起的IRP,随后终止IRP
Adapter->fPendingReset =FALSE; // 清除接收与发送完成例程中被挂起的IRP,并且停止向USB驱动程序发送IRP
Adapter->fPendingReadClearStall =FALSE;
Adapter->fPendingWriteClearStall =FALSE;
Adapter->fKillPassiveLevelThread =FALSE; // 是否终止已建立的 PASSIVE_LEVEL级线程
Adapter->fKillPollingThread =FALSE; // 是否终止已建立的PollingThread线程
Adapter->LastQueryTime.QuadPart = 0; // 查询时间
Adapter->LastSetTime.QuadPart = 0; // 设置时间
Adapter->PendingIrpCount = 0; // 挂起的IRP数目为零
Adapter->IntInternalTime = 0; // 为USB设备的管道指定一个查询周期
Adapter->fQuerypending = FALSE; // 是否查询挂起
Adapter->fSetpending = FALSE; // 是否设置挂起
Adapter->PCurrentRcvBuf = NULL; // 当前接收包分配的缓冲区指针指向空
Adapter->fReceiveing = FALSE; // 该非串行化的微端口是否为接受到的数据包进行内部排队
//
// 初始化微端口接收的数据包队列
//
if (TURE!=InitWdmQueues(Adapter))
{
goto release;
}
//
// 分配和初始化一个不分页包池块,调用者提供所请求的包描述符数量和以字节为单位的每个固定包的大小
//
NdisAllocatePacketPool(
&status, // 该函数的返回状态
&Adapter->PacketPoolHandle, // 指向该不分页包池块的句柄
NUM_RCV_BUFS, // 该池中包含的包描述符数量
16) // 每个固定包的大小为16个字节
if (status!=NDIS_STATUS_SUCCESS)
{
goto release;
}
//
// 分配和初始化一个不分页的内存块,返回一个调用者可用NdisAllocateBuffer来分配缓冲区描述符的句柄
//
NdisAllocateBufferPool(
&status, // 该函数的返回状态
&Adapter->BufferPoolHandle, // 指向该内存块的句柄
NUM_RCV_BUFS) // 该内存块中缓冲区描述符的数量
if (status!=NDIS_STATUS_SUCCESS)
{
goto release;
}
for (i=0;i<NUM_WORK_ITEMS;i++) // NUM_WORK_ITEMS是为接收包分配的最大缓冲区数目
{
PUSB_WORK_ITEMS PWorkItem;
PWorkItem=&(Adapter->WorkItems[i]); // 将适配器
PWorkItem->PDevice = Adapter;
PWorkItem->Callback = NULL;
PWorkItem->InfoBuf = NULL;
pWorkItem->InfoBufLen = 0;
pWorkItem->fInUse = FALSE;
}
//
// 为设备初始化每个接收对象
//
// 为16个包创建接收缓冲
for (i=0;i<NUM_RCV_BUFS;i++)
{
PNDIS_BUFFER PBuffer = NULL;
PRCV_BUFFER PReceiveBuffer = &(Adapter->rcvBufs[i]);
//
// 分配包数据缓冲区
//
// 包缓冲大小1514字节
PReceiveBuffer->dataBuf = MemAlloc(MAX_PACKET_SIZE);
//分配一个Bulk或Interrupt传输的Urb内存块
pReceivBuffer->Urb = AllocXferUrb();
if (pReceivBuffer->dataBuf == NULL)
{
status = NDIS_STATUS_RESOURCES;
goto release;
}
NdisZeroMemory( // 对分配的包数据缓冲区清零
pReceivBuffer->dataBuf,
MAX_PACKET_SIZE
);
pReceivBuffer->device = Adapter;
pReceivBuffer->dataLen = 0;
pReceivBuffer->state = STATE_FREE;
//
// 分配NDIS包
// 从NdisAllocatePacketPool返回的包池中分配一个固定大小的包描述符
// 即从PacketPool给Rev_Buffer结构分配一个包描述符
NdisAllocatePacket(
&status, // 该函数的返回状态
&((PNDIS_PACKET)pReceiveBuffer->Packet), // 指向这个包描述符的指针
&Adapter->PacketPoolHandle) // 由NdisAllocatePacketPool返回的包池块句柄
if (status != NDIS_STATUS_SUCCESS)
{
goto release;
}
}
release:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -