📄 driver.c
字号:
#define NDIS_WDM 1
#define NDIS_MINIPORT_DRIVER
#define NDIS50_MINIPORT 1
#include "ndis.h" // AFTER preceding directives
#include "driver.h"
#include "8139.h"
PDEVICE_OBJECT g_deviceObject;
PADAPTER g_adapter;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_HANDLE NdisWrapperHandle;
NDIS_MINIPORT_CHARACTERISTICS R8139Char;
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
RtlInitUnicodeString(&ntDeviceName, L"\\Device\\miniport-rtl");
Status = IoCreateDevice (
DriverObject,
0,
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&g_deviceObject
);
if(Status != NDIS_STATUS_SUCCESS)
DbgPrint("DriverEntry:IoCreateDevice failure. \n");
else{
RtlInitUnicodeString(&win32DeviceName, L"\\DosDevices\\miniport-rtl");
Status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );
if(Status != NDIS_STATUS_SUCCESS){
IoDeleteDevice(g_deviceObject);
DbgPrint("DriverEntry:IoCreateSymbolicLink failure. \n");
}else
DbgPrint("DriverEntry:IoCreateDevice success. \n");
}
// g_deviceObject->Flags |= DO_DIRECT_IO;
//init wrapper
NdisMInitializeWrapper(
&NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL
);
//clear zero
NdisZeroMemory(&R8139Char, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
R8139Char.MajorNdisVersion = 5;
R8139Char.MinorNdisVersion = 0;
R8139Char.InitializeHandler = RInit;
R8139Char.HaltHandler = RHalt;
R8139Char.QueryInformationHandler = RQuery;
R8139Char.SetInformationHandler = RSet;
R8139Char.ResetHandler = RReset;
R8139Char.ReturnPacketHandler = RReturnPkt;
R8139Char.SendPacketsHandler = RSendPkts;
R8139Char.ISRHandler = RIsr;
R8139Char.HandleInterruptHandler= RIsrDpc;
R8139Char.CheckForHangHandler= RCheck;
// R8139Char.DisableInterruptHandler = RDisint;
//register miniport
Status = NdisMRegisterMiniport(
NdisWrapperHandle,
&R8139Char,
sizeof(NDIS_MINIPORT_CHARACTERISTICS)
);
if(Status != NDIS_STATUS_SUCCESS)
NdisTerminateWrapper(NdisWrapperHandle, NULL);
DriverObject->MajorFunction[IRP_MJ_CREATE] = ROpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = RClose;
DriverObject->MajorFunction[IRP_MJ_READ] = RRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = RWrite;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = RCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RIoControl;
DriverObject->DriverUnload = RUnload;
return Status;
}
NDIS_STATUS
RInit(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UINT i;
ULONG ulReadSize;
ULONG ulVenDevID;
PNDIS_RESOURCE_LIST resList;
CM_PARTIAL_RESOURCE_DESCRIPTOR resDesc;
PADAPTER adapter;
NDIS_HANDLE ConfigurationHandle;
USHORT TmpCommand;
KdPrint(("go into RInit \n"));
for (i = 0; i < MediumArraySize; i++){
if (MediumArray[i] == NdisMedium802_3)
break;
}
if (i == MediumArraySize){
KdPrint(("802.3 Media type not found.\n"));
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
// Select ethernet
*SelectedMediumIndex = i;
//alloc adapter context mem
Status = NdisAllocateMemoryWithTag(
&adapter,
sizeof(ADAPTER),
'9318'
);
if(Status != NDIS_STATUS_SUCCESS) goto err;
NdisZeroMemory(adapter, sizeof(ADAPTER));
g_adapter = adapter;
adapter->MiniportAdapterHandle = MiniportAdapterHandle;
adapter->WrapperConfigurationContext = WrapperConfigurationContext;
//find resourcs
ulReadSize = NdisReadPciSlotInformation(
MiniportAdapterHandle,
0,
0,
&ulVenDevID,
4
);
if(ulVenDevID != 0x813910ec){
DbgPrint("no find our nic card. \n");
Status = NDIS_STATUS_FAILURE;
goto err;
}
//我们的设备,获得资源
Status = NdisMPciAssignResources(
MiniportAdapterHandle,
i,
&resList
);
if(Status != NDIS_STATUS_SUCCESS) goto err;
for(i = 0; i < resList->Count; i ++){
resDesc = resList->PartialDescriptors[i];
switch(resDesc.Type){
// I/O 端口
case CmResourceTypePort:
adapter->BaseIO = (ULONG)resDesc.u.Port.Start.LowPart;
ASSERT(0x100 == resDesc.u.Port.Length);
break;
// IRQ
case CmResourceTypeInterrupt:
adapter->IRQLevel = resDesc.u.Interrupt.Level;
adapter->IRQVector = resDesc.u.Interrupt.Vector;
adapter->IRQAffinity = resDesc.u.Interrupt.Affinity;
//share
adapter->IRQMode = resDesc.Flags & (CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE | CM_RESOURCE_INTERRUPT_LATCHED);
break;
// MEMERY
case CmResourceTypeMemory:
ASSERT(0x100 == resDesc.u.Memory.Length);
break;
// DMA
case CmResourceTypeDma:
break;
default:
break;
}
}//for
//regist to NDIS library
NdisMSetAttributes(
MiniportAdapterHandle,
adapter,
TRUE,//DMABusMaster,
NdisInterfacePci
);
//enable dma
NdisReadPciSlotInformation(
adapter->MiniportAdapterHandle,
0,
PCI_COMMAND,
&TmpCommand,
2
);
TmpCommand |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
NdisWritePciSlotInformation(
adapter->MiniportAdapterHandle,
0,
PCI_COMMAND,
&TmpCommand,
2
);
//Registering Ports
Status = NdisMRegisterIoPortRange(
(PVOID*)&adapter->ioaddr,
adapter->MiniportAdapterHandle,
adapter->BaseIO,
0x100
);
if(NDIS_STATUS_SUCCESS != Status) goto err;
//interrupt
Status = NdisMRegisterInterrupt(
&adapter->IntObj,
adapter->MiniportAdapterHandle,
adapter->IRQVector,
adapter->IRQLevel,
TRUE,
TRUE,
adapter->IRQMode
);
if(NDIS_STATUS_SUCCESS != Status) goto err;
//dma
Status = NdisMAllocateMapRegisters(
adapter->MiniportAdapterHandle,
0,//must 0
CM_RESOURCE_DMA_32,
1,
256//dma transtrate max = 2k
);
if(NDIS_STATUS_SUCCESS != Status) goto err;
//RESET
ResetNIC(adapter);
((USHORT*)adapter->NetworkAddress)[0] = opEEPROM((PUCHAR)(adapter->ioaddr+Cfg9346), 7, OP_READ, 0);
((USHORT*)adapter->NetworkAddress)[1] = opEEPROM((PUCHAR)(adapter->ioaddr+Cfg9346), 8, OP_READ, 0);
((USHORT*)adapter->NetworkAddress)[2] = opEEPROM((PUCHAR)(adapter->ioaddr+Cfg9346), 9, OP_READ, 0);
DbgPrint("NodeAddress = %x-%x-%x-%x-%x-%x \n",
adapter->NetworkAddress[0],adapter->NetworkAddress[1],adapter->NetworkAddress[2],adapter->NetworkAddress[3],adapter->NetworkAddress[4],adapter->NetworkAddress[5]
);
Status = AllocRes(adapter);
if(NDIS_STATUS_SUCCESS != Status) goto err;
Status = StartDevice(adapter);
if(NDIS_STATUS_SUCCESS != Status) goto err;
KdPrint(("claim system resource succeesfully. \n"));
return Status;
err:
KdPrint(("claim system resource failure. \n"));
FreeRes(adapter);
return Status;
}
//IRQL:DISPATCH_LEVEL
NDIS_STATUS
RSet(
IN NDIS_HANDLE Context,
IN NDIS_OID Oid,
IN PVOID inbuf,
IN ULONG buf_size,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UINT i;
PADAPTER adapter = (PADAPTER)Context;
switch(Oid){
case OID_802_3_MULTICAST_LIST:
// DbgPrint("OID_802_3_MULTICAST_LIST. \n");
if ( buf_size > 8)
return (NDIS_STATUS_INVALID_LENGTH);
else
NdisMoveMemory(adapter->mc_filter, inbuf, buf_size);
break;
case OID_GEN_CURRENT_PACKET_FILTER:
// DbgPrint("OID_GEN_CURRENT_PACKET_FILTER. \n");
// Verify the Length
if (buf_size != 4)
return (NDIS_STATUS_INVALID_LENGTH);
adapter->PacketFilter = *(PULONG)inbuf;
*BytesRead = buf_size;
break;
case OID_GEN_CURRENT_LOOKAHEAD:
if (buf_size != 4)
return (NDIS_STATUS_INVALID_LENGTH);
*BytesRead = 4;
break;
default:
Status = NDIS_STATUS_INVALID_OID;
break;
}
return Status;
}
NDIS_STATUS
RQuery(
IN NDIS_HANDLE Context,
IN NDIS_OID Oid,
IN PVOID inbuf,
IN ULONG buf_size,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UINT i;
PADAPTER adapter = (PADAPTER)Context;
static NDIS_OID OID_LIST[] =
{
// Required OIDs
OID_GEN_SUPPORTED_LIST,// 0x00010101
OID_GEN_HARDWARE_STATUS,// 0x00010102
OID_GEN_MEDIA_SUPPORTED,// 0x00010103
OID_GEN_MEDIA_IN_USE,// 0x00010104
OID_GEN_MAXIMUM_LOOKAHEAD,// 0x00010105
OID_GEN_MAXIMUM_FRAME_SIZE,// 0x00010106
OID_GEN_LINK_SPEED,// 0x00010107
OID_GEN_TRANSMIT_BUFFER_SPACE,// 0x00010108
OID_GEN_RECEIVE_BUFFER_SPACE,// 0x00010109
OID_GEN_TRANSMIT_BLOCK_SIZE,// 0x0001010A
OID_GEN_RECEIVE_BLOCK_SIZE,// 0x0001010B
OID_GEN_VENDOR_ID,// 0x0001010C
OID_GEN_VENDOR_DESCRIPTION,// 0x0001010D
OID_GEN_CURRENT_PACKET_FILTER,// 0x0001010E
OID_GEN_CURRENT_LOOKAHEAD,// 0x0001010F
OID_GEN_DRIVER_VERSION,// 0x00010110
OID_GEN_MAXIMUM_TOTAL_SIZE,// 0x00010111
OID_GEN_PROTOCOL_OPTIONS,// 0x00010112
OID_GEN_MAC_OPTIONS,// 0x00010113
OID_GEN_MEDIA_CONNECT_STATUS,// 0x00010114
OID_GEN_MAXIMUM_SEND_PACKETS,// 0x00010115
OID_GEN_VENDOR_DRIVER_VERSION,// 0x00010116
OID_GEN_SUPPORTED_GUIDS,// 0x00010117
OID_GEN_NETWORK_LAYER_ADDRESSES,// 0x00010118 // Set only
OID_GEN_TRANSPORT_HEADER_OFFSET,// 0x00010119 // Set only
// 802.3 Objects (Ethernet)
OID_802_3_PERMANENT_ADDRESS,// 0x01010101
OID_802_3_CURRENT_ADDRESS,// 0x01010102
OID_802_3_MULTICAST_LIST,// 0x01010103
OID_802_3_MAXIMUM_LIST_SIZE,// 0x01010104
OID_802_3_MAC_OPTIONS,// 0x01010105
NDIS_802_3_MAC_OPTION_PRIORITY,// 0x00000001
OID_802_3_RCV_ERROR_ALIGNMENT,// 0x01020101
OID_802_3_XMIT_ONE_COLLISION,// 0x01020102
OID_802_3_XMIT_MORE_COLLISIONS,// 0x01020103
OID_802_3_XMIT_DEFERRED,// 0x01020201
OID_802_3_XMIT_MAX_COLLISIONS,// 0x01020202
OID_802_3_RCV_OVERRUN,// 0x01020203
OID_802_3_XMIT_UNDERRUN,// 0x01020204
OID_802_3_XMIT_HEARTBEAT_FAILURE,// 0x01020205
OID_802_3_XMIT_TIMES_CRS_LOST,// 0x01020206
OID_802_3_XMIT_LATE_COLLISIONS,// 0x01020207
// 用户定义
USER_OID_REV_BYTE,// 0x02000000
USER_OID_XMIT_BYTE ,// 0x02000001
// Required statistics
OID_GEN_XMIT_OK,// 0x00020101
OID_GEN_RCV_OK,// 0x00020102
OID_GEN_XMIT_ERROR,// 0x00020103
OID_GEN_RCV_ERROR,// 0x00020104
OID_GEN_RCV_NO_BUFFER,// 0x00020105
};
*BytesWritten = 4;
switch (Oid){
case USER_OID_REV_BYTE:
*((PULONG)inbuf) = adapter->rev_byte;
break;
case USER_OID_XMIT_BYTE:
*((PULONG)inbuf) = adapter->xmit_byte;
break;
case OID_GEN_SUPPORTED_LIST:
if(buf_size < sizeof(OID_LIST)){
*BytesNeeded = sizeof(OID_LIST);
Status = NDIS_STATUS_INVALID_LENGTH;
}else{
NdisMoveMemory(inbuf, OID_LIST, sizeof(OID_LIST));
*BytesWritten = sizeof(OID_LIST);
}
break;
case OID_GEN_CURRENT_PACKET_FILTER:
if(buf_size >= 4){
*(PULONG)inbuf = adapter->PacketFilter;
*BytesWritten = 4;
}else
*BytesNeeded = 4;
break;
case OID_GEN_MAC_OPTIONS:
*((PULONG)inbuf) = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK
);
break;
case OID_GEN_HARDWARE_STATUS:
*((NDIS_HARDWARE_STATUS*)inbuf) = NdisHardwareStatusReady;
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
*((NDIS_MEDIUM*)inbuf) = (NDIS_MEDIUM)(NdisMedium802_3);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
case OID_GEN_CURRENT_LOOKAHEAD:
case OID_GEN_MAXIMUM_FRAME_SIZE:
*((PULONG)inbuf) = MAX_ETHERNET_FRAME_SIZE - MAC_HEADER_SIZE;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
*((PULONG)inbuf) = (ULONG)MAX_ETHERNET_FRAME_SIZE;
break;
case OID_GEN_LINK_SPEED:
*((PULONG)inbuf) = 1000000; //100m
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
DbgPrint("data=%x, len=%x\n", inbuf, buf_size);
*((PULONG)inbuf) = (ULONG) MAX_ETHERNET_FRAME_SIZE * 4;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
*((PULONG)inbuf) = (ULONG)RING_BUF_SIZE;
break;
case OID_GEN_VENDOR_ID:
*((PULONG)inbuf) = *(PULONG)adapter->NetworkAddress;
break;
case OID_GEN_VENDOR_DESCRIPTION:
*((PULONG)inbuf) = (ULONG)'0900';
break;
case OID_GEN_DRIVER_VERSION:
*((PULONG)inbuf) = (USHORT)0x0201;
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
*((PULONG)inbuf) = (ULONG) NUM_OF_DESC;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
*((PULONG)inbuf) = (ULONG)NdisMediaStateConnected;
break;
//
// 802.3 Objects (Ethernet)
//
case OID_802_3_PERMANENT_ADDRESS:// 0x01010101
NdisMoveMemory(inbuf, adapter->NetworkAddress, 6);
*BytesWritten = 6;
break;
case OID_802_3_CURRENT_ADDRESS:// 0x01010102
NdisMoveMemory(inbuf, adapter->NetworkAddress, 6);
*BytesWritten = 6;
break;
case OID_802_3_MULTICAST_LIST:// 0x01010103
if (buf_size < 8)
return (NDIS_STATUS_INVALID_LENGTH);
else
NdisMoveMemory(inbuf, adapter->mc_filter, buf_size);
break;
case OID_802_3_MAXIMUM_LIST_SIZE:// 0x01010104
*((PULONG)inbuf) = (ULONG)MULTICAST_FILTER_LIMIT;
break;
case OID_802_3_MAC_OPTIONS:// 0x01010105
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
case NDIS_802_3_MAC_OPTION_PRIORITY:// 0x00000001
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:// 0x01020101
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_ONE_COLLISION:// 0x01020102
*((PULONG)inbuf) = (ULONG)0;
break;
case OID_802_3_XMIT_MORE_COLLISIONS:// 0x01020103
*((PULONG)inbuf) = (ULONG)0;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -