#include "ndissys.h"
+#include <ndisguid.h>
+
/*
* Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
* for each new miniport starting up
while (CurrentEntry)
{
- if (CurrentEntry->WorkItemType == Type)
+ if (CurrentEntry->WorkItemType == Type || Type == NdisMaxWorkItems)
return CurrentEntry;
CurrentEntry = (PNDIS_MINIPORT_WORK_ITEM)CurrentEntry->Link.Next;
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
- if (Type == NdisWorkItemRequest &&
- (Adapter->NdisMiniportBlock.PendingRequest || MiniGetFirstWorkItem(Adapter, NdisWorkItemRequest)))
+ if (MiniGetFirstWorkItem(Adapter, Type))
+ {
+ Busy = TRUE;
+ }
+ else if (Type == NdisWorkItemRequest && Adapter->NdisMiniportBlock.PendingRequest)
{
Busy = TRUE;
}
- else if (Type == NdisWorkItemSend &&
- (Adapter->NdisMiniportBlock.FirstPendingPacket || MiniGetFirstWorkItem(Adapter, NdisWorkItemSend)))
+ else if (Type == NdisWorkItemSend && Adapter->NdisMiniportBlock.FirstPendingPacket)
{
Busy = TRUE;
}
else if (Type == NdisWorkItemResetRequested &&
- (Adapter->NdisMiniportBlock.ResetStatus == NDIS_STATUS_PENDING || MiniGetFirstWorkItem(Adapter, NdisWorkItemResetRequested)))
+ Adapter->NdisMiniportBlock.ResetStatus == NDIS_STATUS_PENDING)
{
Busy = TRUE;
}
return Busy;
}
-\f
VOID
MiniIndicateData(
PLOGICAL_ADAPTER Adapter,
KeLowerIrql(OldIrql);
}
}
-}\f
+}
+
VOID NTAPI
MiniIndicateReceivePacket(
IN NDIS_HANDLE MiniportAdapterHandle,
&NdisBufferVA,
&FirstBufferLength,
&TotalBufferLength);
-
+
HeaderSize = NDIS_GET_PACKET_HEADER_SIZE(PacketArray[i]);
- if (Adapter->NdisMiniportBlock.CurrentLookahead < (TotalBufferLength - HeaderSize))
- {
- LookAheadSize = Adapter->NdisMiniportBlock.CurrentLookahead;
- }
- else
- {
- LookAheadSize = TotalBufferLength - HeaderSize;
- }
+ LookAheadSize = TotalBufferLength - HeaderSize;
LookAheadBuffer = ExAllocatePool(NonPagedPool, LookAheadSize);
if (!LookAheadBuffer)
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
return;
}
-
+
CopyBufferChainToBuffer(LookAheadBuffer,
NdisBuffer,
HeaderSize,
LookAheadSize);
-
+
NDIS_DbgPrint(MID_TRACE, ("Indicating packet to protocol's legacy Receive handler\n"));
(*AdapterBinding->ProtocolBinding->Chars.ReceiveHandler)(
AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
LookAheadBuffer,
LookAheadSize,
TotalBufferLength - HeaderSize);
-
+
ExFreePool(LookAheadBuffer);
}
}
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
}
-\f
VOID NTAPI
MiniResetComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
MacBlock = (PNDIS_REQUEST_MAC_BLOCK)Request->MacReserved;
- if( MacBlock->Binding->RequestCompleteHandler ) {
- (*MacBlock->Binding->RequestCompleteHandler)(
- MacBlock->Binding->ProtocolBindingContext,
- Request,
- Status);
+ /* We may or may not be doing this request on behalf of an adapter binding */
+ if (MacBlock->Binding != NULL)
+ {
+ /* We are, so invoke its request complete handler */
+ if (MacBlock->Binding->RequestCompleteHandler != NULL)
+ {
+ (*MacBlock->Binding->RequestCompleteHandler)(
+ MacBlock->Binding->ProtocolBindingContext,
+ Request,
+ Status);
+ }
+ }
+ else
+ {
+ /* We are doing this internally, so we'll signal this event we've stashed in the MacBlock */
+ ASSERT(MacBlock->Unknown1 != NULL);
+ ASSERT(MacBlock->Unknown3 == NULL);
+ MacBlock->Unknown3 = (PVOID)Status;
+ KeSetEvent(MacBlock->Unknown1, IO_NO_INCREMENT, FALSE);
}
KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
Adapter->NdisMiniportBlock.PendingRequest = NULL;
KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
-
KeLowerIrql(OldIrql);
+
+ MiniWorkItemComplete(Adapter, NdisWorkItemRequest);
}
VOID NTAPI
Status);
KeLowerIrql(OldIrql);
+
+ MiniWorkItemComplete(Adapter, NdisWorkItemSend);
}
MiniSendResourcesAvailable(
IN NDIS_HANDLE MiniportAdapterHandle)
{
-/*
- UNIMPLEMENTED
-*/
+ /* Run the work if anything is waiting */
+ MiniWorkItemComplete((PLOGICAL_ADAPTER)MiniportAdapterHandle, NdisWorkItemSend);
}
KeAcquireSpinLock(&AdapterListLock, &OldIrql);
{
CurrentEntry = AdapterListHead.Flink;
-
+
while (CurrentEntry != &AdapterListHead)
{
Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry);
{
NDIS_STATUS NdisStatus;
PNDIS_REQUEST NdisRequest;
+ KEVENT Event;
+ PNDIS_REQUEST_MAC_BLOCK MacBlock;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
NdisRequest->DATA.SET_INFORMATION.InformationBuffer = Buffer;
NdisRequest->DATA.SET_INFORMATION.InformationBufferLength = Size;
- NdisStatus = MiniDoRequest(Adapter, NdisRequest);
+ /* We'll need to give the completion routine some way of letting us know
+ * when it's finished. We'll stash a pointer to an event in the MacBlock */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ MacBlock = (PNDIS_REQUEST_MAC_BLOCK)NdisRequest->MacReserved;
+ MacBlock->Unknown1 = &Event;
- /* FIXME: Wait in pending case! */
+ NdisStatus = MiniDoRequest(Adapter, NdisRequest);
- ASSERT(NdisStatus != NDIS_STATUS_PENDING);
+ if (NdisStatus == NDIS_STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ NdisStatus = (NDIS_STATUS)MacBlock->Unknown3;
+ }
*BytesRead = NdisRequest->DATA.SET_INFORMATION.BytesRead;
{
NDIS_STATUS NdisStatus;
PNDIS_REQUEST NdisRequest;
+ KEVENT Event;
+ PNDIS_REQUEST_MAC_BLOCK MacBlock;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = Buffer;
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = Size;
- NdisStatus = MiniDoRequest(Adapter, NdisRequest);
+ /* We'll need to give the completion routine some way of letting us know
+ * when it's finished. We'll stash a pointer to an event in the MacBlock */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ MacBlock = (PNDIS_REQUEST_MAC_BLOCK)NdisRequest->MacReserved;
+ MacBlock->Unknown1 = &Event;
- /* FIXME: Wait in pending case! */
+ NdisStatus = MiniDoRequest(Adapter, NdisRequest);
- ASSERT(NdisStatus != NDIS_STATUS_PENDING);
+ if (NdisStatus == NDIS_STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ NdisStatus = (NDIS_STATUS)MacBlock->Unknown3;
+ }
*BytesWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
NdisMIndicateStatusComplete(Adapter);
+
+ MiniWorkItemComplete(Adapter, NdisWorkItemResetRequested);
}
return Status;
}
}
-\f
+VOID
+MiniWorkItemComplete(
+ PLOGICAL_ADAPTER Adapter,
+ NDIS_WORK_ITEM_TYPE WorkItemType)
+{
+ PIO_WORKITEM IoWorkItem;
+
+ /* Check if there's anything queued to run after this work item */
+ if (!MiniIsBusy(Adapter, WorkItemType))
+ return;
+
+ /* There is, so fire the worker */
+ IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject);
+ if (IoWorkItem)
+ IoQueueWorkItem(IoWorkItem, MiniportWorker, DelayedWorkQueue, IoWorkItem);
+}
+
VOID
FASTCALL
MiniQueueWorkItem(
*/
{
PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem;
- PIO_WORKITEM IoWorkItem;
KIRQL OldIrql;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
}
}
- IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject);
- if (IoWorkItem)
- IoQueueWorkItem(IoWorkItem, MiniportWorker, DelayedWorkQueue, IoWorkItem);
-
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
}
-\f
NDIS_STATUS
FASTCALL
MiniDequeueWorkItem(
}
}
-\f
NDIS_STATUS
MiniDoRequest(
PLOGICAL_ADAPTER Adapter,
}
KeLowerIrql(OldIrql);
+
+ if (Status != NDIS_STATUS_PENDING) {
+ MiniWorkItemComplete(Adapter, NdisWorkItemRequest);
+ }
+
return Status;
}
-\f
/*
* @implemented
*/
KeLowerIrql(OldIrql);
}
-\f
/*
* @implemented
*/
if (NdisStatus == NDIS_STATUS_PENDING)
break;
+ Adapter->NdisMiniportBlock.PendingRequest = (PNDIS_REQUEST)WorkItemContext;
switch (((PNDIS_REQUEST)WorkItemContext)->RequestType)
{
case NdisRequestQueryInformation:
- NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
+ NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
break;
case NdisRequestSetInformation:
NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS request type.\n"));
break;
}
+ Adapter->NdisMiniportBlock.PendingRequest = NULL;
break;
default:
}
-\f
VOID
NTAPI
MiniStatus(
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
}
-\f
VOID
NTAPI
MiniStatusComplete(
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
}
-\f
/*
* @implemented
*/
MiniStatusComplete(MiniportAdapterHandle);
}
-\f
/*
* @implemented
*/
*NdisWrapperHandle = Miniport;
}
-\f
VOID NTAPI NdisIBugcheckCallback(
IN PVOID Buffer,
IN ULONG Length)
sh(Context->DriverContext);
}
-\f
/*
* @implemented
*/
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+ if (Adapter->BugcheckContext != NULL)
+ {
+ NDIS_DbgPrint(MIN_TRACE, ("Attempted to register again for a shutdown callback\n"));
+ return;
+ }
+
BugcheckContext = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_BUGCHECK_CONTEXT));
if(!BugcheckContext)
{
IoRegisterShutdownNotification(Adapter->NdisMiniportBlock.DeviceObject);
}
-\f
NDIS_STATUS
DoQueries(
PLOGICAL_ADAPTER Adapter,
return STATUS_SUCCESS;
}
-\f
NTSTATUS
NTAPI
NdisIForwardIrpAndWaitCompletionRoutine(
return STATUS_MORE_PROCESSING_REQUIRED;
}
-\f
NTSTATUS
NTAPI
NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter, PIRP Irp)
return STATUS_SUCCESS;
}
-\f
NTSTATUS
NTAPI
NdisIPnPStartDevice(
/*
* FUNCTION: Handle the PnP start device event
* ARGUMENTS:
- * DeviceObejct = Functional Device Object
+ * DeviceObject = Functional Device Object
* Irp = IRP_MN_START_DEVICE I/O request packet
* RETURNS:
* Status of operation
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
- NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
+ NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter (%lx).\n", NdisStatus));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
if (Adapter->NdisMiniportBlock.Interrupt)
{
return STATUS_SUCCESS;
}
-\f
NTSTATUS
NTAPI
NdisIPnPStopDevice(
/*
* FUNCTION: Handle the PnP stop device event
* ARGUMENTS:
- * DeviceObejct = Functional Device Object
+ * DeviceObject = Functional Device Object
* Irp = IRP_MN_STOP_DEVICE I/O request packet
* RETURNS:
* Status of operation
KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
+ /* Set this here so MiniportISR will be forced to run for interrupts generated in MiniportHalt */
+ Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
+ Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
+
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter);
IoSetDeviceInterfaceState(&Adapter->NdisMiniportBlock.SymbolicLinkName, FALSE);
Adapter->NdisMiniportBlock.EthDB = NULL;
}
- Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
- Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
-
return STATUS_SUCCESS;
}
PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NDIS_STATUS Status = STATUS_NOT_SUPPORTED;
+ ULONG ControlCode;
ULONG Written;
Irp->IoStatus.Information = 0;
ASSERT(Adapter);
- switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ ControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+ switch (ControlCode)
{
case IOCTL_NDIS_QUERY_GLOBAL_STATS:
Status = MiniQueryInformation(Adapter,
break;
default:
- ASSERT(FALSE);
+ NDIS_DbgPrint(MIN_TRACE, ("NdisIDeviceIoControl: unsupported control code 0x%lx\n", ControlCode));
break;
}
return Status;
}
-\f
NTSTATUS
NTAPI
NdisIDispatchPnp(
return IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
}
-\f
+NTSTATUS
+NTAPI
+NdisIPower(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIRP Irp)
+{
+ PLOGICAL_ADAPTER Adapter = DeviceObject->DeviceExtension;
+
+ PoStartNextPowerIrp(Irp);
+ IoSkipCurrentIrpStackLocation(Irp);
+ return PoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
+}
+
NTSTATUS
NTAPI
NdisIAddDevice(
* 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
+ * gathered by IoGetDeviceProperty. I chose the second because
* IoOpenDriverRegistryKey wasn't implemented at the time of writing.
*/
return STATUS_SUCCESS;
}
-\f
+NTSTATUS
+NTAPI
+NdisGenericIrpHandler(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Use the characteristics to classify the device */
+ if (DeviceObject->DeviceType == FILE_DEVICE_PHYSICAL_NETCARD)
+ {
+ if ((IrpSp->MajorFunction == IRP_MJ_CREATE) ||
+ (IrpSp->MajorFunction == IRP_MJ_CLOSE) ||
+ (IrpSp->MajorFunction == IRP_MJ_CLEANUP))
+ {
+ return NdisICreateClose(DeviceObject, Irp);
+ }
+ else if (IrpSp->MajorFunction == IRP_MJ_PNP)
+ {
+ return NdisIDispatchPnp(DeviceObject, Irp);
+ }
+ else if (IrpSp->MajorFunction == IRP_MJ_SHUTDOWN)
+ {
+ return NdisIShutdown(DeviceObject, Irp);
+ }
+ else if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
+ {
+ return NdisIDeviceIoControl(DeviceObject, Irp);
+ }
+ else if (IrpSp->MajorFunction == IRP_MJ_POWER)
+ {
+ return NdisIPower(DeviceObject, Irp);
+ }
+ NDIS_DbgPrint(MIN_TRACE, ("Unexpected IRP MajorFunction 0x%x\n", IrpSp->MajorFunction));
+ ASSERT(FALSE);
+ }
+ else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK)
+ {
+ PNDIS_M_DEVICE_BLOCK DeviceBlock = DeviceObject->DeviceExtension;
+
+ ASSERT(DeviceBlock->DeviceObject == DeviceObject);
+
+ if (DeviceBlock->MajorFunction[IrpSp->MajorFunction] != NULL)
+ {
+ return DeviceBlock->MajorFunction[IrpSp->MajorFunction](DeviceObject, Irp);
+ }
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_INVALID_DEVICE_REQUEST;
+}
+
/*
* @implemented
*/
PNDIS_M_DRIVER_BLOCK Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
PNDIS_M_DRIVER_BLOCK *MiniportPtr;
NTSTATUS Status;
+ ULONG i;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
case 0x00:
MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS);
break;
-
+
case 0x01:
MinSize = sizeof(NDIS51_MINIPORT_CHARACTERISTICS);
break;
-
+
default:
NDIS_DbgPrint(MIN_TRACE, ("Bad 5.x minor characteristics version.\n"));
return NDIS_STATUS_BAD_VERSION;
return NDIS_STATUS_BAD_VERSION;
}
- NDIS_DbgPrint(MIN_TRACE, ("Initializing an NDIS %u.%u miniport\n",
+ NDIS_DbgPrint(MID_TRACE, ("Initializing an NDIS %u.%u miniport\n",
MiniportCharacteristics->MajorNdisVersion,
MiniportCharacteristics->MinorNdisVersion));
*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;
+ /* We have to register for all of these so handler registered in NdisMRegisterDevice work */
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ {
+ Miniport->DriverObject->MajorFunction[i] = NdisGenericIrpHandler;
+ }
+
Miniport->DriverObject->DriverExtension->AddDevice = NdisIAddDevice;
return NDIS_STATUS_SUCCESS;
}
-\f
/*
* @implemented
*/
MiniResetComplete(MiniportAdapterHandle, Status, AddressingReset);
}
-\f
/*
* @implemented
*/
MiniSendComplete(MiniportAdapterHandle, Packet, Status);
}
-\f
/*
* @implemented
*/
MiniSendResourcesAvailable(MiniportAdapterHandle);
}
-\f
/*
* @implemented
*/
MiniTransferDataComplete(MiniportAdapterHandle, Packet, Status, BytesTransferred);
}
-\f
/*
* @implemented
*/
AdapterType);
}
-\f
/*
* @implemented
*/
if (AttributeFlags & NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER)
NDIS_DbgPrint(MIN_TRACE, ("Intermediate drivers not supported yet.\n"));
- NDIS_DbgPrint(MIN_TRACE, ("Miniport attribute flags: 0x%x\n", AttributeFlags));
+ NDIS_DbgPrint(MID_TRACE, ("Miniport attribute flags: 0x%x\n", AttributeFlags));
if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.AdapterShutdownHandler)
{
}
}
-\f
/*
* @implemented
*/
KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, 0);
}
-\f
/*
* @implemented
*/
SynchronizeContext));
}
-\f
/*
* @unimplemented
*/
return NDIS_STATUS_FAILURE;
}
-\f
/*
* @implemented
*/
NDIS_DbgPrint(MAX_TRACE, ("Called\n"));
Status = IoCreateDevice(DriverBlock->DriverObject,
- 0, /* This space is reserved for us. Should we use it? */
+ sizeof(NDIS_M_DEVICE_BLOCK),
DeviceName,
FILE_DEVICE_NETWORK,
0,
NDIS_DbgPrint(MIN_TRACE, ("IoCreateDevice failed (%x)\n", Status));
return Status;
}
-
+
Status = IoCreateSymbolicLink(SymbolicName, DeviceName);
if (!NT_SUCCESS(Status))
return Status;
}
- DeviceBlock = ExAllocatePool(NonPagedPool, sizeof(NDIS_M_DEVICE_BLOCK));
+ DeviceBlock = DeviceObject->DeviceExtension;
if (!DeviceBlock)
{
}
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- DriverBlock->DriverObject->MajorFunction[i] = MajorFunctions[i];
-
- DriverBlock->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
-
- 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->MajorFunction[i] = MajorFunctions[i];
DeviceBlock->DeviceObject = DeviceObject;
DeviceBlock->SymbolicName = SymbolicName;
IoDeleteSymbolicLink(DeviceBlock->SymbolicName);
- ExFreePool(DeviceBlock);
-
return NDIS_STATUS_SUCCESS;
}
}
/* EOF */
-