📄 miniport.c
字号:
KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, NdisIForwardIrpAndWaitCompletionRoutine, &Event,
TRUE, TRUE, TRUE);
Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Irp->IoStatus.Status;
}
return Status;
}
NTSTATUS
NTAPI
NdisIPnPStartDevice(
IN PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle the PnP start device event
* ARGUMENTS:
* DeviceObejct = Functional Device Object
* Irp = IRP_MN_START_DEVICE I/O request packet
* RETURNS:
* Status of operation
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
NDIS_WRAPPER_CONTEXT WrapperContext;
NDIS_STATUS NdisStatus;
NDIS_STATUS OpenErrorStatus;
NTSTATUS Status;
UINT SelectedMediumIndex = 0;
NDIS_OID AddressOID;
BOOLEAN Success = FALSE;
ULONG ResourceCount;
ULONG ResourceListSize;
UNICODE_STRING ParamName;
PNDIS_CONFIGURATION_PARAMETER ConfigParam;
NDIS_HANDLE ConfigHandle;
ULONG Size;
/* FIXME - KIRQL OldIrql; */
/*
* Prepare wrapper context used by HW and configuration routines.
*/
NDIS_DbgPrint(DEBUG_MINIPORT, ("Start Device %wZ\n", &Adapter->NdisMiniportBlock.MiniportName));
NDIS_DbgPrint(MAX_TRACE, ("Inserting adapter 0x%x into adapter list\n", Adapter));
/* Put adapter in global adapter list */
ExInterlockedInsertTailList(&AdapterListHead, &Adapter->ListEntry, &AdapterListLock);
Status = IoOpenDeviceRegistryKey(
Adapter->NdisMiniportBlock.PhysicalDeviceObject, PLUGPLAY_REGKEY_DRIVER,
KEY_ALL_ACCESS, &WrapperContext.RegistryHandle);
if (!NT_SUCCESS(Status))
{
NDIS_DbgPrint(MIN_TRACE,("failed to open adapter-specific reg key\n"));
return Status;
}
NDIS_DbgPrint(MAX_TRACE, ("opened device reg key\n"));
WrapperContext.DeviceObject = Adapter->NdisMiniportBlock.DeviceObject;
/*
* Store the adapter resources used by HW routines such as
* NdisMQueryAdapterResources.
*/
if (Stack->Parameters.StartDevice.AllocatedResources != NULL &&
Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL)
{
ResourceCount = Stack->Parameters.StartDevice.AllocatedResources->List[0].
PartialResourceList.Count;
ResourceListSize =
FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
PartialDescriptors[ResourceCount]);
Adapter->NdisMiniportBlock.AllocatedResources =
ExAllocatePool(PagedPool, ResourceListSize);
if (Adapter->NdisMiniportBlock.AllocatedResources == NULL)
{
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return STATUS_INSUFFICIENT_RESOURCES;
}
Adapter->NdisMiniportBlock.AllocatedResourcesTranslated =
ExAllocatePool(PagedPool, ResourceListSize);
if (Adapter->NdisMiniportBlock.AllocatedResourcesTranslated == NULL)
{
ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
Adapter->NdisMiniportBlock.AllocatedResources = NULL;
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(Adapter->NdisMiniportBlock.AllocatedResources,
Stack->Parameters.StartDevice.AllocatedResources,
ResourceListSize);
RtlCopyMemory(Adapter->NdisMiniportBlock.AllocatedResourcesTranslated,
Stack->Parameters.StartDevice.AllocatedResourcesTranslated,
ResourceListSize);
}
/*
* Store the Bus Type, Bus Number and Slot information. It's used by
* the hardware routines then.
*/
NdisOpenConfiguration(&NdisStatus, &ConfigHandle, (NDIS_HANDLE)&WrapperContext);
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
DevicePropertyLegacyBusType, Size,
&Adapter->NdisMiniportBlock.BusType, &Size);
if (!NT_SUCCESS(Status) || (INTERFACE_TYPE)Adapter->NdisMiniportBlock.BusType == InterfaceTypeUndefined)
{
NdisInitUnicodeString(&ParamName, L"BusType");
NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
&ParamName, NdisParameterInteger);
if (NdisStatus == NDIS_STATUS_SUCCESS)
Adapter->NdisMiniportBlock.BusType = ConfigParam->ParameterData.IntegerData;
else
Adapter->NdisMiniportBlock.BusType = Isa;
}
Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
DevicePropertyBusNumber, Size,
&Adapter->NdisMiniportBlock.BusNumber, &Size);
if (!NT_SUCCESS(Status) || Adapter->NdisMiniportBlock.BusNumber == 0xFFFFFFF0)
{
NdisInitUnicodeString(&ParamName, L"BusNumber");
NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
&ParamName, NdisParameterInteger);
if (NdisStatus == NDIS_STATUS_SUCCESS)
Adapter->NdisMiniportBlock.BusNumber = ConfigParam->ParameterData.IntegerData;
else
Adapter->NdisMiniportBlock.BusNumber = 0;
}
WrapperContext.BusNumber = Adapter->NdisMiniportBlock.BusNumber;
Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
DevicePropertyAddress, Size,
&Adapter->NdisMiniportBlock.SlotNumber, &Size);
if (!NT_SUCCESS(Status) || Adapter->NdisMiniportBlock.SlotNumber == (NDIS_INTERFACE_TYPE)-1)
{
NdisInitUnicodeString(&ParamName, L"SlotNumber");
NdisReadConfiguration(&NdisStatus, &ConfigParam, ConfigHandle,
&ParamName, NdisParameterInteger);
if (NdisStatus == NDIS_STATUS_SUCCESS)
Adapter->NdisMiniportBlock.SlotNumber = ConfigParam->ParameterData.IntegerData;
else
Adapter->NdisMiniportBlock.SlotNumber = 0;
}
NdisCloseConfiguration(ConfigHandle);
/*
* Call MiniportInitialize.
*/
NDIS_DbgPrint(MID_TRACE, ("calling MiniportInitialize\n"));
NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.InitializeHandler)(
&OpenErrorStatus, &SelectedMediumIndex, &MediaArray[0],
MEDIA_ARRAY_SIZE, Adapter, (NDIS_HANDLE)&WrapperContext);
ZwClose(WrapperContext.RegistryHandle);
if (NdisStatus != NDIS_STATUS_SUCCESS ||
SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return (NTSTATUS)NdisStatus;
}
/* Set handlers (some NDIS macros require these) */
Adapter->NdisMiniportBlock.EthRxCompleteHandler = EthFilterDprIndicateReceiveComplete;
Adapter->NdisMiniportBlock.EthRxIndicateHandler = EthFilterDprIndicateReceive;
Adapter->NdisMiniportBlock.SendCompleteHandler = MiniSendComplete;
Adapter->NdisMiniportBlock.SendResourcesHandler = MiniSendResourcesAvailable;
Adapter->NdisMiniportBlock.ResetCompleteHandler = MiniResetComplete;
Adapter->NdisMiniportBlock.TDCompleteHandler = MiniTransferDataComplete;
Adapter->NdisMiniportBlock.PacketIndicateHandler= MiniIndicateReceivePacket;
Adapter->NdisMiniportBlock.StatusHandler = MiniStatus;
Adapter->NdisMiniportBlock.StatusCompleteHandler= MiniStatusComplete;
Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
switch (Adapter->NdisMiniportBlock.MediaType)
{
case NdisMedium802_3:
Adapter->MediumHeaderSize = 14; /* XXX figure out what to do about LLC */
AddressOID = OID_802_3_CURRENT_ADDRESS;
Adapter->AddressLength = ETH_LENGTH_OF_ADDRESS;
NdisStatus = DoQueries(Adapter, AddressOID);
if (NdisStatus == NDIS_STATUS_SUCCESS)
{
Success = EthCreateFilter(32, /* FIXME: Query this from miniport. */
Adapter->Address.Type.Medium802_3,
&Adapter->NdisMiniportBlock.EthDB);
if (Success)
((PETHI_FILTER)Adapter->NdisMiniportBlock.EthDB)->Miniport = (PNDIS_MINIPORT_BLOCK)Adapter;
else
NdisStatus = NDIS_STATUS_RESOURCES;
}
break;
default:
/* FIXME: Support other types of media */
NDIS_DbgPrint(MIN_TRACE, ("error: unsupported media\n"));
ASSERT(FALSE);
/* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return STATUS_UNSUCCESSFUL;
}
if (!Success || NdisStatus != NDIS_STATUS_SUCCESS)
{
NDIS_DbgPrint(MAX_TRACE, ("couldn't create filter (%x)\n", NdisStatus));
if (Adapter->LookaheadBuffer)
{
ExFreePool(Adapter->LookaheadBuffer);
Adapter->LookaheadBuffer = NULL;
}
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return (NTSTATUS)NdisStatus;
}
Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStarted;
/* Put adapter in adapter list for this miniport */
ExInterlockedInsertTailList(&Adapter->NdisMiniportBlock.DriverHandle->DeviceList, &Adapter->MiniportListEntry, &Adapter->NdisMiniportBlock.DriverHandle->Lock);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
NdisIPnPStopDevice(
IN PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle the PnP stop device event
* ARGUMENTS:
* DeviceObejct = Functional Device Object
* Irp = IRP_MN_STOP_DEVICE I/O request packet
* RETURNS:
* Status of operation
*/
{
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
KIRQL OldIrql;
/* Remove adapter from adapter list for this miniport */
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.DriverHandle->Lock, &OldIrql);
RemoveEntryList(&Adapter->MiniportListEntry);
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.DriverHandle->Lock, OldIrql);
/* Remove adapter from global adapter list */
KeAcquireSpinLock(&AdapterListLock, &OldIrql);
RemoveEntryList(&Adapter->ListEntry);
KeReleaseSpinLock(&AdapterListLock, OldIrql);
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter);
if (Adapter->LookaheadBuffer)
{
ExFreePool(Adapter->LookaheadBuffer);
Adapter->LookaheadBuffer = NULL;
}
if (Adapter->NdisMiniportBlock.AllocatedResources)
{
ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
Adapter->NdisMiniportBlock.AllocatedResources = NULL;
}
if (Adapter->NdisMiniportBlock.AllocatedResourcesTranslated)
{
ExFreePool(Adapter->NdisMiniportBlock.AllocatedResourcesTranslated);
Adapter->NdisMiniportBlock.AllocatedResourcesTranslated = NULL;
}
Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
NdisIDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
NTSTATUS Status;
switch (Stack->MinorFunction)
{
case IRP_MN_START_DEVICE:
Status = NdisIForwardIrpAndWait(Adapter, Irp);
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
{
Status = NdisIPnPStartDevice(DeviceObject, Irp);
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_STOP_DEVICE:
Status = NdisIForwardIrpAndWait(Adapter, Irp);
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
{
Status = NdisIPnPStopDevice(DeviceObject, Irp);
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_QUERY_DEVICE_RELATIONS:
Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
break;
}
return Status;
}
NTSTATUS
NTAPI
NdisIAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
/*
* FUNCTION: Create a device for an adapter found using PnP
* ARGUMENTS:
* DriverObject = Pointer to the miniport driver object
* PhysicalDeviceObject = Pointer to the PDO for our adapter
*/
{
static const WCHAR ClassKeyName[] = {'C','l','a','s','s','\\'};
static const WCHAR LinkageKeyName[] = {'\\','L','i','n','k','a','g','e',0};
PNDIS_M_DRIVER_BLOCK Miniport;
PNDIS_M_DRIVER_BLOCK *MiniportPtr;
WCHAR *LinkageKeyBuffer;
ULONG DriverKeyLength;
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
UNICODE_STRING ExportName;
PDEVICE_OBJECT DeviceObject;
PLOGICAL_ADAPTER Adapter;
NTSTATUS Status;
/*
* Gain the access to the miniport data structure first.
*/
MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)TAG('D','I','M','N'));
if (MiniportPtr == NULL)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get driver object extension.\n"));
return STATUS_UNSUCCESSFUL;
}
Miniport = *MiniportPtr;
/*
* Get name of the Linkage registry key for our adapter. It's located under
* the driver key for our driver and so we have basicly two ways to do it.
* Either we can use IoOpenDriverRegistryKey or compose it using information
* gathered by IoGetDeviceProperty. I choosed the second because
* IoOpenDriverRegistryKey wasn't implemented at the time of writing.
*/
Status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDriverKeyName,
0, NULL, &DriverKeyLength);
if (Status != STATUS_BUFFER_TOO_SMALL)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key length.\n"));
return Status;
}
LinkageKeyBuffer = ExAllocatePool(PagedPool, DriverKeyLength +
sizeof(ClassKeyName) + sizeof(LinkageKeyName));
if (LinkageKeyBuffer == NULL)
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate memory for driver key name.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyDriverKeyName,
DriverKeyLength, LinkageKeyBuffer +
(sizeof(ClassKeyName) / sizeof(WCHAR)),
&DriverKeyLength);
if (!NT_SUCCESS(Status))
{
NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key.\n"));
ExFreePool(LinkageKeyBuffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -