📄 miniport.c
字号:
//
(void) GlobalInit(VA);
//
// Init VrrHelloParams.
//
VrrHelloInit(VA);
//
// Now we have our address we can set up our NTE.
//
VA->NT.Self = NodeInitSelf(VA);
if (NULL == VA->NT.Self)
goto ErrorFreeBufferPool;
//
// Set up our maintenance buffer.
//
VA->MaintBuf = MaintBufNew();
if (VA->MaintBuf == NULL)
goto ErrorFreeSelf;
//
// Set up our forwarding queue.
//
VA->ForwardLast = &VA->ForwardList;
VRRASSERT(VA->ForwardList == NULL);
VRRASSERT(VA->ForwardTime == 0);
//
// Initialize with NDIS as a protocol. This will bind
// our virtual adapter to physical adapters,
// based on the protocol name that we supply here.
//
Status = ProtocolInit(L"msvrrtp", VA);
if (Status != NDIS_STATUS_SUCCESS)
goto ErrorFreeMaintBuffer;
//
// We have an aperiodic timeout function,
// with a maximum timeout of MINIPORT_TIMEOUT.
//
VA->TimeoutMinLoops = MAXULONG;
KeInitializeDpc(&VA->TimeoutDpc, MiniportTimeout, VA);
KeInitializeTimer(&VA->Timer);
Timeout.QuadPart = - (LONGLONG) (MINIPORT_TIMEOUT * 10000);
VA->Timeout = KeQueryInterruptTime() - Timeout.QuadPart;
KeSetTimer(&VA->Timer, Timeout, &VA->TimeoutDpc);
//
// Add the virtual adapter to our list.
//
KeAcquireSpinLock(&MiniportAdapters.Lock, &OldIrql);
VA->Prev = &MiniportAdapters.VirtualAdapters;
VA->Next = MiniportAdapters.VirtualAdapters;
if (MiniportAdapters.VirtualAdapters != NULL)
MiniportAdapters.VirtualAdapters->Prev = &VA->Next;
MiniportAdapters.VirtualAdapters = VA;
KeReleaseSpinLock(&MiniportAdapters.Lock, OldIrql);
return NDIS_STATUS_SUCCESS;
ErrorCloseRegistry:
ZwClose(KeyHandle);
goto ErrorFreeBufferPool;
ErrorFreeMaintBuffer:
MaintBufFree(VA);
ErrorFreeSelf:
NodeTableCleanup(VA);
ErrorFreeBufferPool:
NdisFreeBufferPool(VA->BufferPool);
ErrorFreePacketPool:
NdisFreePacketPool(VA->PacketPool);
ErrorFreePool:
ExFreePool(VA);
ErrorReturn:
KdPrint(("VRR!MiniportInitialize -> %x\n", Status));
return Status;
}
NDIS_OID MiniportSupportedOidArray[] =
{
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_MAC_OPTIONS,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_DRIVER_VERSION,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_MAXIMUM_SEND_PACKETS,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST, // Set only?
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS,
OID_PNP_CAPABILITIES,
OID_PNP_SET_POWER, // Set only.
OID_PNP_QUERY_POWER,
};
uchar MiniportVendorDescription[] = "VRR Miniport Driver";
uchar MiniportVendorId[3] = {0xFF, 0xFF, 0xFF};
NDIS_PNP_CAPABILITIES MiniportPnpCapabilities = {
0,
NdisDeviceStateUnspecified,
NdisDeviceStateUnspecified,
NdisDeviceStateUnspecified
};
//* MiniportQueryInformation
//
// Called by NDIS to retrieve information about our virtual adapter.
//
NDIS_STATUS
MiniportQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded)
{
MiniportAdapter *VA = (MiniportAdapter *) MiniportAdapterContext;
uint GenericUint;
ushort GenericUshort;
void *Data;
uint DataLength;
//
// Prepare to return a uint - this is the common case.
//
Data = &GenericUint;
DataLength = sizeof GenericUint;
//
// If you change this switch, be sure to update MiniportSupportedOidArray.
//
switch (Oid) {
case OID_GEN_SUPPORTED_LIST:
Data = MiniportSupportedOidArray;
DataLength = sizeof MiniportSupportedOidArray;
break;
case OID_GEN_HARDWARE_STATUS:
GenericUint = NdisHardwareStatusReady;
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
GenericUint = VA->Medium;
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericUint = MINIPORT_MAX_LOOKAHEAD;
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericUint = VA->LookAhead;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericUint = VA->MediumMaxFrameLen;
break;
case OID_GEN_MAC_OPTIONS:
GenericUint = NDIS_MAC_OPTION_NO_LOOPBACK;
break;
case OID_GEN_LINK_SPEED:
GenericUint = VA->MediumLinkSpeed;
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
case OID_GEN_RECEIVE_BUFFER_SPACE:
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericUint = VA->MediumMaxPacketLen;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericUint = 1;
break;
case OID_GEN_VENDOR_ID:
Data = MiniportVendorId;
DataLength = sizeof MiniportVendorId;
break;
case OID_GEN_VENDOR_DESCRIPTION:
Data = MiniportVendorDescription;
DataLength = sizeof MiniportVendorDescription;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
GenericUint = VA->PacketFilter;
break;
case OID_GEN_DRIVER_VERSION:
GenericUshort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
Data = &GenericUshort;
DataLength = sizeof GenericUshort;
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
if (VA->PhysicalAdapters != NULL)
GenericUint = NdisMediaStateConnected;
else
GenericUint = NdisMediaStateDisconnected;
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
GenericUint = MAX_RECV_QUEUE_SIZE;
break;
case OID_802_3_PERMANENT_ADDRESS:
case OID_802_3_CURRENT_ADDRESS:
Data = VA->Address;
DataLength = sizeof VA->Address;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
GenericUint = MINIPORT_MAX_MULTICAST_ADDRESS;
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:
case OID_802_3_XMIT_ONE_COLLISION:
case OID_802_3_XMIT_MORE_COLLISIONS:
GenericUint = 0;
break;
case OID_PNP_CAPABILITIES:
Data = &MiniportPnpCapabilities;
DataLength = sizeof MiniportPnpCapabilities;
break;
case OID_PNP_QUERY_POWER:
DataLength = 0;
break;
default:
KdPrint(("VRR!MiniportQueryInformation(VA %p OID %x)\n", VA, Oid));
//
// The following OIDs are called in practice,
// but we do not support them.
//
case OID_GEN_VENDOR_DRIVER_VERSION:
case OID_GEN_SUPPORTED_GUIDS:
case OID_GEN_PHYSICAL_MEDIUM:
case OID_GEN_MEDIA_CAPABILITIES:
case OID_FFP_SUPPORT:
case OID_TCP_TASK_OFFLOAD:
case 0xff54554e: // OID_CUSTOM_TUNMP_INSTANCE_ID
return NDIS_STATUS_NOT_SUPPORTED;
}
*BytesNeeded = DataLength;
if (DataLength > InformationBufferLength)
return NDIS_STATUS_BUFFER_TOO_SHORT;
RtlCopyMemory(InformationBuffer, Data, DataLength);
*BytesWritten = DataLength;
return NDIS_STATUS_SUCCESS;
}
//* MiniportSetInformation
//
// Called by NDIS to specify information for our virtual adapter.
//
NDIS_STATUS
MiniportSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded)
{
MiniportAdapter *VA = (MiniportAdapter *) MiniportAdapterContext;
switch (Oid) {
case OID_GEN_CURRENT_LOOKAHEAD: {
uint LookAhead;
if (InformationBufferLength != sizeof LookAhead) {
*BytesNeeded = sizeof LookAhead;
return NDIS_STATUS_INVALID_LENGTH;
}
LookAhead = * (uint UNALIGNED *) InformationBuffer;
*BytesRead = sizeof LookAhead;
if (LookAhead > MINIPORT_MAX_LOOKAHEAD)
return NDIS_STATUS_INVALID_DATA;
if (LookAhead > VA->LookAhead)
VA->LookAhead = LookAhead;
return NDIS_STATUS_SUCCESS;
}
case OID_PNP_SET_POWER: {
NDIS_DEVICE_POWER_STATE PowerState;
if (InformationBufferLength != sizeof PowerState) {
*BytesNeeded = sizeof PowerState;
return NDIS_STATUS_INVALID_LENGTH;
}
PowerState = * (NDIS_DEVICE_POWER_STATE UNALIGNED *) InformationBuffer;
*BytesRead = sizeof PowerState;
KdPrint(("VRR!MiniportSetInformation(VA %p SetPower %x)\n",
VA, PowerState));
//
// Should we pend until any outstanding operations are completed,
// when transitioning to a sleep state?
//
if (PowerState == NdisDeviceStateD0) {
//
// We are waking up after being asleep.
// The environment has likely changed.
// The neighbor cache does not need to be flushed.
//
}
return NDIS_STATUS_SUCCESS;
}
case OID_802_3_MULTICAST_LIST:
case OID_GEN_CURRENT_PACKET_FILTER:
*BytesRead = InformationBufferLength;
return NDIS_STATUS_SUCCESS;
default:
KdPrint(("VRR!MiniportSetInformation(VA %p OID %x)\n", VA, Oid));
//
// The following OIDs are called in practice,
// but we do not support them.
//
case OID_GEN_TRANSPORT_HEADER_OFFSET:
case OID_GEN_NETWORK_LAYER_ADDRESSES:
case OID_PNP_ADD_WAKE_UP_PATTERN:
case OID_PNP_REMOVE_WAKE_UP_PATTERN:
return NDIS_STATUS_NOT_SUPPORTED;
}
}
//* MiniportControlSendComplete
//
// Completes the transmission of a Source-Routed control packet,
// such as a Route Request, Route Reply or Route Error.
//
static void
MiniportControlSendComplete(
MiniportAdapter *VA,
SRPacket *srp,
NDIS_STATUS Status)
{
UNREFERENCED_PARAMETER(VA);
UNREFERENCED_PARAMETER(Status);
SRPacketFree(srp);
}
//* MiniportForwardCleanup
//
// Cleans up the forwarding queue.
//
static void
MiniportForwardCleanup(MiniportAdapter *VA)
{
SRPacket *SRP;
while ((SRP = VA->ForwardList) != NULL) {
VA->ForwardList = SRP->Next;
(*SRP->TransmitComplete)(VA, SRP, NDIS_STATUS_FAILURE);
}
}
//* MiniportSendComplete
//
// Called when a MiniportSendPacket operation has finished
// and the packet must be returned to NDIS.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -