📄 miniport.c
字号:
return Status;
}
/* Compose the linkage key name. */
RtlCopyMemory(LinkageKeyBuffer, ClassKeyName, sizeof(ClassKeyName));
RtlCopyMemory(LinkageKeyBuffer + ((sizeof(ClassKeyName) + DriverKeyLength) /
sizeof(WCHAR)) - 1, LinkageKeyName, sizeof(LinkageKeyName));
NDIS_DbgPrint(DEBUG_MINIPORT, ("LinkageKey: %S.\n", LinkageKeyBuffer));
/*
* Now open the linkage key and read the "Export" and "RootDevice" values
* which contains device name and root service respectively.
*/
RtlZeroMemory(QueryTable, sizeof(QueryTable));
RtlInitUnicodeString(&ExportName, NULL);
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].Name = L"Export";
QueryTable[0].EntryContext = &ExportName;
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, LinkageKeyBuffer,
QueryTable, NULL, NULL);
ExFreePool(LinkageKeyBuffer);
if (!NT_SUCCESS(Status))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport device name. (%x)\n", Status));
return Status;
}
/*
* Create the device object.
*/
NDIS_DbgPrint(MAX_TRACE, ("creating device %wZ\n", &ExportName));
Status = IoCreateDevice(Miniport->DriverObject, sizeof(LOGICAL_ADAPTER),
&ExportName, FILE_DEVICE_PHYSICAL_NETCARD,
0, FALSE, &DeviceObject);
if (!NT_SUCCESS(Status))
{
NDIS_DbgPrint(MIN_TRACE, ("Could not create device object.\n"));
RtlFreeUnicodeString(&ExportName);
return Status;
}
/*
* Initialize the adapter structure.
*/
Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
InitializeListHead(&Adapter->ProtocolListHead);
Adapter->NdisMiniportBlock.DriverHandle = Miniport;
Adapter->NdisMiniportBlock.MiniportName = ExportName;
Adapter->NdisMiniportBlock.DeviceObject = DeviceObject;
Adapter->NdisMiniportBlock.PhysicalDeviceObject = PhysicalDeviceObject;
Adapter->NdisMiniportBlock.NextDeviceObject =
IoAttachDeviceToDeviceStack(Adapter->NdisMiniportBlock.DeviceObject,
PhysicalDeviceObject);
Adapter->NdisMiniportBlock.OldPnPDeviceState = 0;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceAdded;
KeInitializeDpc(&Adapter->NdisMiniportBlock.DeferredDpc, MiniportDpc, (PVOID)Adapter);
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NDIS_STATUS
EXPORT
NdisMRegisterMiniport(
IN NDIS_HANDLE NdisWrapperHandle,
IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics,
IN UINT CharacteristicsLength)
/*
* FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
* ARGUMENTS:
* NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
* MiniportCharacteristics = Pointer to a buffer with miniport characteristics
* CharacteristicsLength = Number of bytes in characteristics buffer
* RETURNS:
* Status of operation
*/
{
UINT MinSize;
PNDIS_M_DRIVER_BLOCK Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
PNDIS_M_DRIVER_BLOCK *MiniportPtr;
NTSTATUS Status;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
switch (MiniportCharacteristics->MajorNdisVersion)
{
case 0x03:
MinSize = sizeof(NDIS30_MINIPORT_CHARACTERISTICS);
break;
case 0x04:
MinSize = sizeof(NDIS40_MINIPORT_CHARACTERISTICS);
break;
case 0x05:
MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS);
break;
default:
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics version.\n"));
return NDIS_STATUS_BAD_VERSION;
}
if (CharacteristicsLength < MinSize)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
/* Check if mandatory MiniportXxx functions are specified */
if ((!MiniportCharacteristics->HaltHandler) ||
(!MiniportCharacteristics->InitializeHandler)||
(!MiniportCharacteristics->QueryInformationHandler) ||
(!MiniportCharacteristics->ResetHandler) ||
(!MiniportCharacteristics->SetInformationHandler))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
if (MiniportCharacteristics->MajorNdisVersion == 0x03)
{
if (!MiniportCharacteristics->SendHandler)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
}
else if (MiniportCharacteristics->MajorNdisVersion >= 0x04)
{
/* NDIS 4.0+ */
if ((!MiniportCharacteristics->SendHandler) &&
(!MiniportCharacteristics->SendPacketsHandler))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
}
/* TODO: verify NDIS5 and NDIS5.1 */
RtlCopyMemory(&Miniport->MiniportCharacteristics, MiniportCharacteristics, MinSize);
/*
* NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
* structure in the driver extension or what?
*/
Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)TAG('D','I','M','N'),
sizeof(PNDIS_M_DRIVER_BLOCK), (PVOID*)&MiniportPtr);
if (!NT_SUCCESS(Status))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate driver object extension.\n"));
return NDIS_STATUS_RESOURCES;
}
*MiniportPtr = Miniport;
Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice;
return NDIS_STATUS_SUCCESS;
}
/*
* @implemented
*/
#undef NdisMResetComplete
VOID
EXPORT
NdisMResetComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status,
IN BOOLEAN AddressingReset)
{
MiniResetComplete(MiniportAdapterHandle, Status, AddressingReset);
}
/*
* @implemented
*/
#undef NdisMSendComplete
VOID
EXPORT
NdisMSendComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status)
/*
* FUNCTION: Forwards a message to the initiating protocol saying
* that a packet was handled
* ARGUMENTS:
* NdisAdapterHandle = Handle input to MiniportInitialize
* Packet = Pointer to NDIS packet that was sent
* Status = Status of send operation
*/
{
MiniSendComplete(MiniportAdapterHandle, Packet, Status);
}
/*
* @implemented
*/
#undef NdisMSendResourcesAvailable
VOID
EXPORT
NdisMSendResourcesAvailable(
IN NDIS_HANDLE MiniportAdapterHandle)
{
MiniSendResourcesAvailable(MiniportAdapterHandle);
}
/*
* @implemented
*/
#undef NdisMTransferDataComplete
VOID
EXPORT
NdisMTransferDataComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred)
{
MiniTransferDataComplete(MiniportAdapterHandle, Packet, Status, BytesTransferred);
}
/*
* @implemented
*/
#undef NdisMSetInformationComplete
VOID
EXPORT
NdisMSetInformationComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status)
{
(*((PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle))->SetCompleteHandler)(MiniportAdapterHandle, Status);
}
/*
* @implemented
*/
#undef NdisMSetAttributes
VOID
EXPORT
NdisMSetAttributes(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE MiniportAdapterContext,
IN BOOLEAN BusMaster,
IN NDIS_INTERFACE_TYPE AdapterType)
/*
* FUNCTION: Informs the NDIS library of significant features of the caller's NIC
* ARGUMENTS:
* MiniportAdapterHandle = Handle input to MiniportInitialize
* MiniportAdapterContext = Pointer to context information
* BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
* AdapterType = Specifies the I/O bus interface of the caller's NIC
*/
{
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
NdisMSetAttributesEx(MiniportAdapterHandle, MiniportAdapterContext, 0,
BusMaster ? NDIS_ATTRIBUTE_BUS_MASTER : 0,
AdapterType);
}
/*
* @implemented
*/
VOID
EXPORT
NdisMSetAttributesEx(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE MiniportAdapterContext,
IN UINT CheckForHangTimeInSeconds OPTIONAL,
IN ULONG AttributeFlags,
IN NDIS_INTERFACE_TYPE AdapterType)
/*
* FUNCTION: Informs the NDIS library of significant features of the caller's NIC
* ARGUMENTS:
* MiniportAdapterHandle = Handle input to MiniportInitialize
* MiniportAdapterContext = Pointer to context information
* CheckForHangTimeInSeconds = Specifies interval in seconds at which
* MiniportCheckForHang should be called
* AttributeFlags = Bitmask that indicates specific attributes
* AdapterType = Specifies the I/O bus interface of the caller's NIC
*/
{
/* TODO: Take CheckForHandTimeInSeconds into account! */
PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
Adapter->NdisMiniportBlock.Flags = AttributeFlags;
Adapter->NdisMiniportBlock.AdapterType = AdapterType;
if (AttributeFlags & NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER)
NDIS_DbgPrint(MAX_TRACE, ("Intermediate drivers not supported yet.\n"));
}
/*
* @implemented
*/
VOID
EXPORT
NdisMSleep(
IN ULONG MicrosecondsToSleep)
/*
* FUNCTION: delay the thread's execution for MicrosecondsToSleep
* ARGUMENTS:
* MicrosecondsToSleep: duh...
* NOTES:
* - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
*/
{
KTIMER Timer;
LARGE_INTEGER DueTime;
PAGED_CODE();
DueTime.QuadPart = (-1) * 10 * MicrosecondsToSleep;
KeInitializeTimer(&Timer);
KeSetTimer(&Timer, DueTime, 0);
KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, 0);
}
/*
* @implemented
*/
BOOLEAN
EXPORT
NdisMSynchronizeWithInterrupt(
IN PNDIS_MINIPORT_INTERRUPT Interrupt,
IN PVOID SynchronizeFunction,
IN PVOID SynchronizeContext)
{
return(KeSynchronizeExecution(Interrupt->InterruptObject,
(PKSYNCHRONIZE_ROUTINE)SynchronizeFunction,
SynchronizeContext));
}
/*
* @unimplemented
*/
NDIS_STATUS
EXPORT
NdisMWriteLogData(
IN NDIS_HANDLE LogHandle,
IN PVOID LogBuffer,
IN UINT LogBufferSize)
{
UNIMPLEMENTED
return NDIS_STATUS_FAILURE;
}
/*
* @implemented
*/
VOID
EXPORT
NdisTerminateWrapper(
IN NDIS_HANDLE NdisWrapperHandle,
IN PVOID SystemSpecific)
/*
* FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
* ARGUMENTS:
* NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
* SystemSpecific = Always NULL
*/
{
PNDIS_M_DRIVER_BLOCK Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
ExFreePool(Miniport->RegistryPath->Buffer);
ExFreePool(Miniport->RegistryPath);
ExFreePool(Miniport);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -