#include <buffer.h>
-#undef NdisMSendComplete
-VOID
-EXPORT
-NdisMSendComplete(
- IN NDIS_HANDLE MiniportAdapterHandle,
- IN PNDIS_PACKET Packet,
- IN NDIS_STATUS Status);
-
-/* Root of the scm database */
-#define SERVICES_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
-
/*
* Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
* for each new miniport starting up
MiniDisplayPacket(
PNDIS_PACKET Packet)
{
-#ifdef DBG
+#if DBG
ULONG i, Length;
UCHAR Buffer[64];
if ((DebugTraceLevel & DEBUG_PACKET) > 0) {
PVOID LookaheadBuffer,
UINT LookaheadBufferSize)
{
-#ifdef DBG
+#if DBG
if ((DebugTraceLevel & DEBUG_PACKET) > 0) {
ULONG i, Length;
PUCHAR p;
if (CurrentEntry == &Adapter->ProtocolListHead)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("WARNING: No upper protocol layer.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("WARNING: No upper protocol layer.\n"));
}
while (CurrentEntry != &Adapter->ProtocolListHead)
{
AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
- if (AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)
+ for (i = 0; i < NumberOfPackets; i++)
{
- for (i = 0; i < NumberOfPackets; i++)
- {
+ if (AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler &&
+ NDIS_GET_PACKET_STATUS(PacketArray[i]) != NDIS_STATUS_RESOURCES)
+ {
(*AdapterBinding->ProtocolBinding->Chars.ReceivePacketHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
PacketArray[i]);
- }
- }
- else
- {
- for (i = 0; i < NumberOfPackets; i++)
- {
+ }
+ else
+ {
UINT FirstBufferLength, TotalBufferLength, LookAheadSize, HeaderSize;
PNDIS_BUFFER NdisBuffer;
PVOID NdisBufferVA, LookAheadBuffer;
PADAPTER_BINDING AdapterBinding;
KIRQL OldIrql;
+ if (AddressingReset)
+ MiniDoAddressingReset(Adapter);
+
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
+ if (Adapter->NdisMiniportBlock.ResetStatus != NDIS_STATUS_PENDING)
+ {
+ KeBugCheckEx(BUGCODE_ID_DRIVER,
+ (ULONG_PTR)MiniportAdapterHandle,
+ (ULONG_PTR)Status,
+ (ULONG_PTR)AddressingReset,
+ 0);
+ }
+
Adapter->NdisMiniportBlock.ResetStatus = Status;
CurrentEntry = Adapter->ProtocolListHead.Flink;
* Status = Status of send operation
*/
{
+ PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
PADAPTER_BINDING AdapterBinding;
KIRQL OldIrql;
+ PSCATTER_GATHER_LIST SGList;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1];
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+
+ if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0)
+ {
+ NDIS_DbgPrint(MAX_TRACE, ("Freeing Scatter/Gather list\n"));
+
+ SGList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet,
+ ScatterGatherListPacketInfo);
+
+ Adapter->NdisMiniportBlock.SystemAdapterObject->
+ DmaOperations->PutScatterGatherList(
+ Adapter->NdisMiniportBlock.SystemAdapterObject,
+ SGList,
+ TRUE);
+
+ NDIS_PER_PACKET_INFO_FROM_PACKET(Packet,
+ ScatterGatherListPacketInfo) = NULL;
+ }
+
(*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
Packet,
Status);
+
KeLowerIrql(OldIrql);
}
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
-#ifdef DBG
+#if DBG
if(!Adapter)
{
- NDIS_DbgPrint(MID_TRACE, ("Adapter object was null\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Adapter object was null\n"));
return FALSE;
}
if(!Packet)
{
- NDIS_DbgPrint(MID_TRACE, ("Packet was null\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Packet was null\n"));
return FALSE;
}
#endif
if (!NdisBuffer)
{
- NDIS_DbgPrint(MID_TRACE, ("Packet contains no buffers.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Packet contains no buffers.\n"));
return FALSE;
}
if (BufferLength < Length)
{
- NDIS_DbgPrint(MID_TRACE, ("Buffer is too small.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Buffer is too small.\n"));
return FALSE;
}
if(IsListEmpty(&AdapterListHead))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("No registered miniports for protocol to bind to\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("No registered miniports for protocol to bind to\n"));
return NULL;
}
}
else
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving (adapter not found).\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Leaving (adapter not found for %wZ).\n", AdapterName));
}
return Adapter;
}
-\f
+NDIS_STATUS
+MiniSetInformation(
+ PLOGICAL_ADAPTER Adapter,
+ NDIS_OID Oid,
+ ULONG Size,
+ PVOID Buffer,
+ PULONG BytesRead)
+{
+ NDIS_STATUS NdisStatus;
+ PNDIS_REQUEST NdisRequest;
+
+ NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+
+ NdisRequest = ExAllocatePool(NonPagedPool, sizeof(NDIS_REQUEST));
+ if (!NdisRequest) {
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
+ return NDIS_STATUS_RESOURCES;
+ }
+
+ RtlZeroMemory(NdisRequest, sizeof(NDIS_REQUEST));
+
+ NdisRequest->RequestType = NdisRequestSetInformation;
+ NdisRequest->DATA.SET_INFORMATION.Oid = Oid;
+ NdisRequest->DATA.SET_INFORMATION.InformationBuffer = Buffer;
+ NdisRequest->DATA.SET_INFORMATION.InformationBufferLength = Size;
+
+ NdisStatus = MiniDoRequest(Adapter, NdisRequest);
+
+ /* FIXME: Wait in pending case! */
+
+ ASSERT(NdisStatus != NDIS_STATUS_PENDING);
+
+ *BytesRead = NdisRequest->DATA.SET_INFORMATION.BytesRead;
+
+ ExFreePool(NdisRequest);
+
+ return NdisStatus;
+}
+
NDIS_STATUS
MiniQueryInformation(
PLOGICAL_ADAPTER Adapter,
* Size = Size of the passed buffer
* Buffer = Buffer for the output
* BytesWritten = Address of buffer to place number of bytes written
- * NOTES:
- * If the specified buffer is too small, a new buffer is allocated,
- * and the query is attempted again
* RETURNS:
* Status of operation
- * TODO:
- * Is there any way to use the buffer provided by the protocol?
*/
{
NDIS_STATUS NdisStatus;
- ULONG BytesNeeded;
- KIRQL OldIrql;
+ PNDIS_REQUEST NdisRequest;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- /* call the miniport's queryinfo handler */
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
- NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.QueryInformationHandler)(
- Adapter->NdisMiniportBlock.MiniportAdapterContext,
- Oid,
- Buffer,
- Size,
- BytesWritten,
- &BytesNeeded);
- KeLowerIrql(OldIrql);
+ NdisRequest = ExAllocatePool(NonPagedPool, sizeof(NDIS_REQUEST));
+ if (!NdisRequest) {
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
+ return NDIS_STATUS_RESOURCES;
+ }
+
+ RtlZeroMemory(NdisRequest, sizeof(NDIS_REQUEST));
+
+ NdisRequest->RequestType = NdisRequestQueryInformation;
+ NdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
+ NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = Buffer;
+ NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = Size;
+
+ NdisStatus = MiniDoRequest(Adapter, NdisRequest);
/* FIXME: Wait in pending case! */
+ ASSERT(NdisStatus != NDIS_STATUS_PENDING);
+
+ *BytesWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
+
+ ExFreePool(NdisRequest);
+
return NdisStatus;
}
return Ret;
}
+VOID
+MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter)
+{
+ ULONG BytesRead;
+
+ MiniSetInformation(Adapter,
+ OID_GEN_CURRENT_LOOKAHEAD,
+ sizeof(ULONG),
+ &Adapter->NdisMiniportBlock.CurrentLookahead,
+ &BytesRead);
+
+ /* FIXME: Set more stuff */
+}
+
NDIS_STATUS
MiniReset(
- PLOGICAL_ADAPTER Adapter,
- PBOOLEAN AddressingReset)
+ PLOGICAL_ADAPTER Adapter)
/*
* FUNCTION: Resets the miniport
* ARGUMENTS:
* Adapter = Pointer to the logical adapter object
- * AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
* RETURNS:
* Status of the operation
*/
{
NDIS_STATUS Status;
KIRQL OldIrql;
+ BOOLEAN AddressingReset = TRUE;
if (MiniIsBusy(Adapter, NdisWorkItemResetRequested)) {
MiniQueueWorkItem(Adapter, NdisWorkItemResetRequested, NULL, FALSE);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)(
Adapter->NdisMiniportBlock.MiniportAdapterContext,
- AddressingReset);
+ &AddressingReset);
KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
Adapter->NdisMiniportBlock.ResetStatus = Status;
KeLowerIrql(OldIrql);
if (Status != NDIS_STATUS_PENDING) {
+ if (AddressingReset)
+ MiniDoAddressingReset(Adapter);
+
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
}
PVOID SystemArgument2)
{
PLOGICAL_ADAPTER Adapter = DeferredContext;
- BOOLEAN AddressingReset = FALSE;
-
if (MiniCheckForHang(Adapter)) {
NDIS_DbgPrint(MIN_TRACE, ("Miniport detected adapter hang\n"));
- MiniReset(Adapter, &AddressingReset);
+ MiniReset(Adapter);
}
-
- /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
}
\f
}
else
{
+ NDIS_DbgPrint(MIN_TRACE, ("No work item to dequeue\n"));
+
return NDIS_STATUS_FAILURE;
}
}
Adapter->NdisMiniportBlock.PendingRequest = NdisRequest;
KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
- switch (NdisRequest->RequestType)
+ if (!Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CoRequestHandler)
{
- case NdisRequestQueryInformation:
- Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.QueryInformationHandler)(
- Adapter->NdisMiniportBlock.MiniportAdapterContext,
- NdisRequest->DATA.QUERY_INFORMATION.Oid,
- NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
- NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
- (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
- (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
- break;
+ switch (NdisRequest->RequestType)
+ {
+ case NdisRequestQueryInformation:
+ Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.QueryInformationHandler)(
+ Adapter->NdisMiniportBlock.MiniportAdapterContext,
+ NdisRequest->DATA.QUERY_INFORMATION.Oid,
+ NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
+ NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
+ (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
+ (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
+ break;
- case NdisRequestSetInformation:
- Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SetInformationHandler)(
- Adapter->NdisMiniportBlock.MiniportAdapterContext,
- NdisRequest->DATA.SET_INFORMATION.Oid,
- NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
- NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
- (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead,
- (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded);
- break;
+ case NdisRequestSetInformation:
+ Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SetInformationHandler)(
+ Adapter->NdisMiniportBlock.MiniportAdapterContext,
+ NdisRequest->DATA.SET_INFORMATION.Oid,
+ NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
+ NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
+ (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead,
+ (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded);
+ break;
- default:
- Status = NDIS_STATUS_FAILURE;
+ default:
+ NDIS_DbgPrint(MIN_TRACE, ("Bad request type\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CoRequestHandler)(
+ Adapter->NdisMiniportBlock.MiniportAdapterContext,
+ NULL, /* FIXME */
+ NdisRequest);
}
if (Status != NDIS_STATUS_PENDING) {
}
if( NdisStatus != NDIS_STATUS_PENDING ) {
- NdisMSendComplete
+ MiniSendComplete
( Adapter, (PNDIS_PACKET)WorkItemContext, NdisStatus );
}
break;
Adapter->NdisMiniportBlock.MiniportAdapterContext,
&AddressingReset);
- if (NdisStatus == NDIS_STATUS_PENDING)
- {
- KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
- Adapter->NdisMiniportBlock.ResetStatus = NDIS_STATUS_PENDING;
- KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
- }
+ KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
+ Adapter->NdisMiniportBlock.ResetStatus = NdisStatus;
+ KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
KeLowerIrql(OldIrql);
*NdisWrapperHandle = NULL;
#if BREAK_ON_MINIPORT_INIT
- __asm__ ("int $3\n");
+ DbgBreakPoint();
#endif
Miniport = ExAllocatePool(NonPagedPool, sizeof(NDIS_M_DRIVER_BLOCK));
return NdisStatus;
}
-#ifdef DBG
+#if DBG
{
/* 802.3 only */
return Status;
}
+NTSTATUS
+NTAPI
+NdisICreateClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
\f
NTSTATUS
NTAPI
LARGE_INTEGER Timeout;
UINT MaxMulticastAddresses;
ULONG BytesWritten;
+ PLIST_ENTRY CurrentEntry;
+ PPROTOCOL_BINDING ProtocolBinding;
/*
* Prepare wrapper context used by HW and configuration routines.
ExAllocatePool(PagedPool, ResourceListSize);
if (Adapter->NdisMiniportBlock.AllocatedResources == NULL)
{
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return STATUS_INSUFFICIENT_RESOURCES;
}
ExAllocatePool(PagedPool, ResourceListSize);
if (!Adapter->NdisMiniportBlock.Resources)
{
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
ExInterlockedRemoveEntryList(&Adapter->ListEntry, &AdapterListLock);
return STATUS_INSUFFICIENT_RESOURCES;
ExAllocatePool(PagedPool, ResourceListSize);
if (Adapter->NdisMiniportBlock.AllocatedResourcesTranslated == NULL)
{
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return STATUS_INSUFFICIENT_RESOURCES;
}
*/
NdisOpenConfiguration(&NdisStatus, &ConfigHandle, (NDIS_HANDLE)&WrapperContext);
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Failed to open configuration key\n"));
+ ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
+ return NdisStatus;
+ }
Size = sizeof(ULONG);
Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
Adapter->NdisMiniportBlock.SlotNumber = SlotNumber.u.AsULONG;
}
+ WrapperContext.SlotNumber = Adapter->NdisMiniportBlock.SlotNumber;
+
NdisCloseConfiguration(ConfigHandle);
/* Set handlers (some NDIS macros require these) */
{
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
+ if (Adapter->NdisMiniportBlock.Interrupt)
+ {
+ KeBugCheckEx(BUGCODE_ID_DRIVER,
+ (ULONG_PTR)Adapter,
+ (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt,
+ (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue,
+ 1);
+ }
+ if (Adapter->NdisMiniportBlock.TimerQueue)
+ {
+ KeBugCheckEx(BUGCODE_ID_DRIVER,
+ (ULONG_PTR)Adapter,
+ (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt,
+ (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue,
+ 1);
+ }
return NdisStatus;
}
if (SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{
- NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() selected a bad index\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
- NDIS_DbgPrint(MAX_TRACE, ("MiniQueryInformation failed (%x)\n", NdisStatus));
+ NDIS_DbgPrint(MIN_TRACE, ("MiniQueryInformation failed (%x)\n", NdisStatus));
return NdisStatus;
}
/* 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 (NdisStatus != NDIS_STATUS_SUCCESS)
{
- NDIS_DbgPrint(MAX_TRACE, ("couldn't create filter (%x)\n", NdisStatus));
+ NDIS_DbgPrint(MIN_TRACE, ("couldn't create filter (%x)\n", NdisStatus));
return NdisStatus;
}
Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStarted;
+ IoSetDeviceInterfaceState(&Adapter->NdisMiniportBlock.SymbolicLinkName, TRUE);
+
Timeout.QuadPart = Int32x32To64(Adapter->NdisMiniportBlock.CheckForHangSeconds, -1000000);
KeSetTimerEx(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer, Timeout,
Adapter->NdisMiniportBlock.CheckForHangSeconds * 1000,
/* Put adapter in adapter list for this miniport */
ExInterlockedInsertTailList(&Adapter->NdisMiniportBlock.DriverHandle->DeviceList, &Adapter->MiniportListEntry, &Adapter->NdisMiniportBlock.DriverHandle->Lock);
+ /* Refresh bindings for all protocols */
+ CurrentEntry = ProtocolListHead.Flink;
+ while (CurrentEntry != &ProtocolListHead)
+ {
+ ProtocolBinding = CONTAINING_RECORD(CurrentEntry, PROTOCOL_BINDING, ListEntry);
+
+ ndisBindMiniportsToProtocol(&NdisStatus, &ProtocolBinding->Chars);
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
return STATUS_SUCCESS;
}
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter);
+ IoSetDeviceInterfaceState(&Adapter->NdisMiniportBlock.SymbolicLinkName, FALSE);
+
if (Adapter->NdisMiniportBlock.AllocatedResources)
{
ExFreePool(Adapter->NdisMiniportBlock.AllocatedResources);
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+NdisIDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ NDIS_STATUS Status = STATUS_NOT_SUPPORTED;
+ ULONG Written;
+
+ Irp->IoStatus.Information = 0;
+
+ ASSERT(Adapter);
+
+ switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_NDIS_QUERY_GLOBAL_STATS:
+ Status = MiniQueryInformation(Adapter,
+ *(PNDIS_OID)Irp->AssociatedIrp.SystemBuffer,
+ Stack->Parameters.DeviceIoControl.OutputBufferLength,
+ MmGetSystemAddressForMdl(Irp->MdlAddress),
+ &Written);
+ Irp->IoStatus.Information = Written;
+ break;
+
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+ if (Status != NDIS_STATUS_PENDING)
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+ else
+ IoMarkIrpPending(Irp);
+
+ return Status;
+}
+
\f
NTSTATUS
NTAPI
{
Status = NdisIPnPStartDevice(DeviceObject, Irp);
}
+ else
+ NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device start\n"));
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
{
Status = NdisIPnPStopDevice(DeviceObject, Irp);
}
+ else
+ NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device stop\n"));
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
+
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ Status = NdisIPnPQueryStopDevice(DeviceObject, Irp);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
+
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ case IRP_MN_CANCEL_STOP_DEVICE:
+ Status = NdisIPnPCancelStopDevice(DeviceObject, Irp);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
+
+ case IRP_MN_QUERY_PNP_DEVICE_STATE:
+ Status = NDIS_STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information |= Adapter->NdisMiniportBlock.PnPFlags;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
* Gain the access to the miniport data structure first.
*/
- MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)TAG('D','I','M','N'));
+ MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)'NMID');
if (MiniportPtr == NULL)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get driver object extension.\n"));
- return STATUS_UNSUCCESSFUL;
+ NDIS_DbgPrint(MIN_TRACE, ("Can't get driver object extension.\n"));
+ return NDIS_STATUS_FAILURE;
}
Miniport = *MiniportPtr;
0, NULL, &DriverKeyLength);
if (Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_SUCCESS)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key length.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Can't get miniport driver key length.\n"));
return Status;
}
sizeof(ClassKeyName) + sizeof(LinkageKeyName));
if (LinkageKeyBuffer == NULL)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate memory for driver key name.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Can't allocate memory for driver key name.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
&DriverKeyLength);
if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport driver key.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Can't get miniport driver key.\n"));
ExFreePool(LinkageKeyBuffer);
return Status;
}
ExFreePool(LinkageKeyBuffer);
if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't get miniport device name. (%x)\n", Status));
+ NDIS_DbgPrint(MIN_TRACE, ("Can't get miniport device name. (%x)\n", Status));
return Status;
}
Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
InitializeListHead(&Adapter->ProtocolListHead);
- Adapter->NdisMiniportBlock.DriverHandle = Miniport;
- Adapter->NdisMiniportBlock.MiniportName = ExportName;
+ Status = IoRegisterDeviceInterface(PhysicalDeviceObject,
+ &GUID_DEVINTERFACE_NET,
+ NULL,
+ &Adapter->NdisMiniportBlock.SymbolicLinkName);
+ if (!NT_SUCCESS(Status))
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Could not create device interface.\n"));
+ IoDeleteDevice(DeviceObject);
+ RtlFreeUnicodeString(&ExportName);
+ return Status;
+ }
+
+ Adapter->NdisMiniportBlock.DriverHandle = Miniport;
+ Adapter->NdisMiniportBlock.MiniportName = ExportName;
Adapter->NdisMiniportBlock.DeviceObject = DeviceObject;
Adapter->NdisMiniportBlock.PhysicalDeviceObject = PhysicalDeviceObject;
Adapter->NdisMiniportBlock.NextDeviceObject =
break;
default:
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics version.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics version.\n"));
return NDIS_STATUS_BAD_VERSION;
}
+ NDIS_DbgPrint(MIN_TRACE, ("Initializing an NDIS %u.%u miniport\n",
+ MiniportCharacteristics->MajorNdisVersion,
+ MiniportCharacteristics->MinorNdisVersion));
+
if (CharacteristicsLength < MinSize)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics length.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
/* Check if mandatory MiniportXxx functions are specified */
if ((!MiniportCharacteristics->HaltHandler) ||
- (!MiniportCharacteristics->InitializeHandler)||
- (!MiniportCharacteristics->QueryInformationHandler) ||
- (!MiniportCharacteristics->ResetHandler) ||
- (!MiniportCharacteristics->SetInformationHandler))
+ (!MiniportCharacteristics->InitializeHandler)||
+ (!MiniportCharacteristics->ResetHandler))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics.\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
+ if (MiniportCharacteristics->MajorNdisVersion < 0x05)
+ {
+ if ((!MiniportCharacteristics->QueryInformationHandler) ||
+ (!MiniportCharacteristics->SetInformationHandler))
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics. (Set/Query)\n"));
+ return NDIS_STATUS_BAD_CHARACTERISTICS;
+ }
+ }
+ else
+ {
+ if (((!MiniportCharacteristics->QueryInformationHandler) ||
+ (!MiniportCharacteristics->SetInformationHandler)) &&
+ (!MiniportCharacteristics->CoRequestHandler))
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics. (Set/Query)\n"));
+ return NDIS_STATUS_BAD_CHARACTERISTICS;
+ }
+ }
+
if (MiniportCharacteristics->MajorNdisVersion == 0x03)
{
if (!MiniportCharacteristics->SendHandler)
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics. (NDIS 3.0)\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
}
- else if (MiniportCharacteristics->MajorNdisVersion >= 0x04)
+ else if (MiniportCharacteristics->MajorNdisVersion == 0x04)
{
- /* NDIS 4.0+ */
+ /* NDIS 4.0 */
if ((!MiniportCharacteristics->SendHandler) &&
(!MiniportCharacteristics->SendPacketsHandler))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics. (NDIS 4.0)\n"));
+ return NDIS_STATUS_BAD_CHARACTERISTICS;
+ }
+ }
+ else if (MiniportCharacteristics->MajorNdisVersion == 0x05)
+ {
+ /* TODO: Add more checks here */
+
+ if ((!MiniportCharacteristics->SendHandler) &&
+ (!MiniportCharacteristics->SendPacketsHandler) &&
+ (!MiniportCharacteristics->CoSendPacketsHandler))
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Bad miniport characteristics. (NDIS 5.0)\n"));
return NDIS_STATUS_BAD_CHARACTERISTICS;
}
}
* structure in the driver extension or what?
*/
- Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)TAG('D','I','M','N'),
+ Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)'NMID',
sizeof(PNDIS_M_DRIVER_BLOCK), (PVOID*)&MiniportPtr);
if (!NT_SUCCESS(Status))
{
- NDIS_DbgPrint(DEBUG_MINIPORT, ("Can't allocate driver object extension.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("Can't allocate driver object extension.\n"));
return NDIS_STATUS_RESOURCES;
}
*MiniportPtr = Miniport;
+ Miniport->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+ Miniport->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
Miniport->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown;
+ Miniport->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisIDeviceIoControl;
Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice;
return NDIS_STATUS_SUCCESS;
Adapter->NdisMiniportBlock.CheckForHangSeconds = CheckForHangTimeInSeconds;
if (AttributeFlags & NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER)
NDIS_DbgPrint(MAX_TRACE, ("Intermediate drivers not supported yet.\n"));
+
+
+ if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.AdapterShutdownHandler)
+ {
+ NDIS_DbgPrint(MAX_TRACE, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
+ NdisMRegisterAdapterShutdownHandler(Adapter,
+ Adapter->NdisMiniportBlock.MiniportAdapterContext,
+ Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.AdapterShutdownHandler);
+ }
}
\f
AdapterName.Length = 0;
AdapterName.MaximumLength = Adapter->NdisMiniportBlock.MiniportName.MaximumLength;
AdapterName.Buffer = ExAllocatePool(PagedPool, AdapterName.MaximumLength);
- if (!AdapterName.Buffer)
+ if (!AdapterName.Buffer) {
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
return NDIS_STATUS_RESOURCES;
+ }
RtlCopyUnicodeString(&AdapterName, &Adapter->NdisMiniportBlock.MiniportName);
if (!NT_SUCCESS(Status))
{
+ NDIS_DbgPrint(MIN_TRACE, ("IoCreateDevice failed (%x)\n", Status));
return Status;
}
if (!NT_SUCCESS(Status))
{
+ NDIS_DbgPrint(MIN_TRACE, ("IoCreateSymbolicLink failed (%x)\n", Status));
IoDeleteDevice(DeviceObject);
return Status;
}
if (!DeviceBlock)
{
+ NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
IoDeleteDevice(DeviceObject);
IoDeleteSymbolicLink(SymbolicName);
return NDIS_STATUS_RESOURCES;
}
- for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverBlock->DriverObject->MajorFunction[i] = MajorFunctions[i];
DriverBlock->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
- DriverBlock->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown;
+
+ if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE])
+ DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+
+ if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE])
+ DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
DeviceBlock->DeviceObject = DeviceObject;
DeviceBlock->SymbolicName = SymbolicName;
Adapter);
}
+/*
+ * @implemented
+ */
+VOID
+EXPORT
+NdisCompletePnPEvent(
+ IN NDIS_STATUS Status,
+ IN NDIS_HANDLE NdisBindingHandle,
+ IN PNET_PNP_EVENT NetPnPEvent)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * NOTES:
+ * NDIS 5.0
+ */
+{
+ PIRP Irp = (PIRP)NetPnPEvent->NdisReserved[0];
+ PLIST_ENTRY CurrentEntry = (PLIST_ENTRY)NetPnPEvent->NdisReserved[1];
+ PADAPTER_BINDING AdapterBinding = NdisBindingHandle;
+ PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
+ NDIS_STATUS NdisStatus;
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ if (NetPnPEvent->Buffer) ExFreePool(NetPnPEvent->Buffer);
+ ExFreePool(NetPnPEvent);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
+ }
+
+ while (CurrentEntry != &Adapter->ProtocolListHead)
+ {
+ AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry);
+
+ NdisStatus = (*AdapterBinding->ProtocolBinding->Chars.PnPEventHandler)(
+ AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
+ NetPnPEvent);
+
+ if (NdisStatus == NDIS_STATUS_PENDING)
+ {
+ NetPnPEvent->NdisReserved[1] = (ULONG_PTR)CurrentEntry->Flink;
+ return;
+ }
+ else if (NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ if (NetPnPEvent->Buffer) ExFreePool(NetPnPEvent->Buffer);
+ ExFreePool(NetPnPEvent);
+ Irp->IoStatus.Status = NdisStatus;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return;
+ }
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ if (NetPnPEvent->Buffer) ExFreePool(NetPnPEvent->Buffer);
+ ExFreePool(NetPnPEvent);
+
+ Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+/*
+ * @implemented
+ */
+VOID
+EXPORT
+NdisCancelSendPackets(
+ IN NDIS_HANDLE NdisBindingHandle,
+ IN PVOID CancelId)
+{
+ PADAPTER_BINDING AdapterBinding = NdisBindingHandle;
+ PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
+
+ NDIS_DbgPrint(MAX_TRACE, ("Called for ID %x.\n", CancelId));
+
+ if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CancelSendPacketsHandler)
+ {
+ (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CancelSendPacketsHandler)(
+ Adapter->NdisMiniportBlock.MiniportAdapterContext,
+ CancelId);
+ }
+}
+
+
+/*
+ * @implemented
+ */
+NDIS_HANDLE
+EXPORT
+NdisIMGetBindingContext(
+ IN NDIS_HANDLE NdisBindingHandle)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * NOTES:
+ * NDIS 5.0
+ */
+{
+ PADAPTER_BINDING AdapterBinding = NdisBindingHandle;
+ PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
+
+ NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ return Adapter->NdisMiniportBlock.DeviceContext;
+}
+
+
+/*
+ * @implemented
+ */
+NDIS_HANDLE
+EXPORT
+NdisIMGetDeviceContext(
+ IN NDIS_HANDLE MiniportAdapterHandle)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * NOTES:
+ * NDIS 5.0
+ */
+{
+ PLOGICAL_ADAPTER Adapter = MiniportAdapterHandle;
+
+ NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ return Adapter->NdisMiniportBlock.DeviceContext;
+}
+
/* EOF */