mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
![Robert Dickenson](/assets/img/avatar_default.png)
Seems I'll need to do some work on the SCM before this'll be running for me. svn path=/trunk/; revision=3883
683 lines
17 KiB
C
683 lines
17 KiB
C
/*
|
|
* Copyright (c) 1999, 2000
|
|
* Politecnico di Torino. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that: (1) source code distributions
|
|
* retain the above copyright notice and this paragraph in its entirety, (2)
|
|
* distributions including binary code include the above copyright notice and
|
|
* this paragraph in its entirety in the documentation or other materials
|
|
* provided with the distribution, and (3) all advertising materials mentioning
|
|
* features or use of this software display the following acknowledgement:
|
|
* ``This product includes software developed by the Politecnico
|
|
* di Torino, and its contributors.'' Neither the name of
|
|
* the University nor the names of its contributors may be used to endorse
|
|
* or promote products derived from this software without specific prior
|
|
* written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
#ifdef _MSC_VER
|
|
#include "ntddk.h"
|
|
#include "ntiologc.h"
|
|
#include "ndis.h"
|
|
#else
|
|
#include <ddk/ntddk.h>
|
|
#include <net/ndis.h>
|
|
#endif
|
|
#include "debug.h"
|
|
#include "packet.h"
|
|
|
|
static NDIS_MEDIUM MediumArray[] = {
|
|
NdisMedium802_3,
|
|
NdisMediumWan,
|
|
NdisMediumFddi,
|
|
NdisMediumArcnet878_2,
|
|
NdisMediumAtm,
|
|
NdisMedium802_5
|
|
};
|
|
|
|
#define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0])
|
|
|
|
ULONG NamedEventsCounter=0;
|
|
|
|
//Itoa. Replaces the buggy RtlIntegerToUnicodeString
|
|
void PacketItoa(UINT n,PUCHAR buf){
|
|
int i;
|
|
|
|
for(i=0;i<20;i+=2){
|
|
buf[18-i]=(n%10)+48;
|
|
buf[19-i]=0;
|
|
n/=10;
|
|
}
|
|
|
|
}
|
|
|
|
/// Global start time. Used as an absolute reference for timestamp conversion.
|
|
struct time_conv G_Start_Time = {
|
|
0,
|
|
{0, 0},
|
|
};
|
|
|
|
UINT n_Opened_Instances = 0;
|
|
|
|
NDIS_SPIN_LOCK Opened_Instances_Lock;
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|
{
|
|
|
|
PDEVICE_EXTENSION DeviceExtension;
|
|
|
|
POPEN_INSTANCE Open;
|
|
|
|
PIO_STACK_LOCATION IrpSp;
|
|
|
|
NDIS_STATUS Status;
|
|
NDIS_STATUS ErrorStatus;
|
|
UINT i;
|
|
PUCHAR tpointer;
|
|
PLIST_ENTRY PacketListEntry;
|
|
PCHAR EvName;
|
|
|
|
IF_LOUD(DbgPrint("NPF: OpenAdapter\n");)
|
|
|
|
DeviceExtension = DeviceObject->DeviceExtension;
|
|
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
// allocate some memory for the open structure
|
|
#define NPF_TAG_OPENSTRUCT TAG('0', 'O', 'W', 'A')
|
|
Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), NPF_TAG_OPENSTRUCT);
|
|
|
|
|
|
if (Open==NULL) {
|
|
// no memory
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
Open,
|
|
sizeof(OPEN_INSTANCE)
|
|
);
|
|
|
|
|
|
#define NPF_TAG_EVNAME TAG('1', 'O', 'W', 'A')
|
|
EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), NPF_TAG_EVNAME);
|
|
|
|
if (EvName==NULL) {
|
|
// no memory
|
|
ExFreePool(Open);
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
// Save or open here
|
|
IrpSp->FileObject->FsContext=Open;
|
|
|
|
Open->DeviceExtension=DeviceExtension;
|
|
|
|
|
|
// Save the Irp here for the completeion routine to retrieve
|
|
Open->OpenCloseIrp=Irp;
|
|
|
|
// Allocate a packet pool for our xmit and receive packets
|
|
NdisAllocatePacketPool(
|
|
&Status,
|
|
&Open->PacketPool,
|
|
TRANSMIT_PACKETS,
|
|
sizeof(PACKET_RESERVED));
|
|
|
|
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_LOUD(DbgPrint("NPF: Failed to allocate packet pool\n");)
|
|
|
|
ExFreePool(Open);
|
|
ExFreePool(EvName);
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
|
|
RtlCopyBytes(EvName,L"\\BaseNamedObjects\\NPF0000000000",sizeof(L"\\BaseNamedObjects\\NPF0000000000"));
|
|
|
|
//Create the string containing the name of the read event
|
|
RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName);
|
|
|
|
PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21));
|
|
|
|
InterlockedIncrement(&NamedEventsCounter);
|
|
|
|
IF_LOUD(DbgPrint("\nCreated the named event for the read; name=%ws, counter=%d\n", Open->ReadEventName.Buffer,NamedEventsCounter-1);)
|
|
|
|
//allocate the event objects
|
|
Open->ReadEvent=IoCreateNotificationEvent(&Open->ReadEventName,&Open->ReadEventHandle);
|
|
if(Open->ReadEvent==NULL){
|
|
ExFreePool(Open);
|
|
ExFreePool(EvName);
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
KeInitializeEvent(Open->ReadEvent, NotificationEvent, FALSE);
|
|
KeClearEvent(Open->ReadEvent);
|
|
NdisInitializeEvent(&Open->WriteEvent);
|
|
NdisInitializeEvent(&Open->IOEvent);
|
|
NdisInitializeEvent(&Open->DumpEvent);
|
|
NdisInitializeEvent(&Open->IOEvent);
|
|
NdisAllocateSpinLock(&Open->machine_lock);
|
|
|
|
|
|
// list to hold irp's want to reset the adapter
|
|
InitializeListHead(&Open->ResetIrpList);
|
|
|
|
|
|
// Initialize the request list
|
|
KeInitializeSpinLock(&Open->RequestSpinLock);
|
|
InitializeListHead(&Open->RequestList);
|
|
|
|
// Initializes the extended memory of the NPF machine
|
|
#define NPF_TAG_MACHINE TAG('2', 'O', 'W', 'A')
|
|
Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, NPF_TAG_MACHINE);
|
|
if((Open->mem_ex.buffer) == NULL)
|
|
{
|
|
// no memory
|
|
ExFreePool(Open);
|
|
ExFreePool(EvName);
|
|
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
Open->mem_ex.size = DEFAULT_MEM_EX_SIZE;
|
|
RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE);
|
|
|
|
//
|
|
// Initialize the open instance
|
|
//
|
|
Open->BufSize = 0;
|
|
Open->Buffer = NULL;
|
|
Open->Bhead = 0;
|
|
Open->Btail = 0;
|
|
(INT)Open->BLastByte = -1;
|
|
Open->Dropped = 0; //reset the dropped packets counter
|
|
Open->Received = 0; //reset the received packets counter
|
|
Open->Accepted = 0; //reset the accepted packets counter
|
|
Open->bpfprogram = NULL; //reset the filter
|
|
Open->mode = MODE_CAPT;
|
|
Open->Nbytes.QuadPart = 0;
|
|
Open->Npackets.QuadPart = 0;
|
|
Open->Nwrites = 1;
|
|
Open->Multiple_Write_Counter = 0;
|
|
Open->MinToCopy = 0;
|
|
Open->TimeOut.QuadPart = (LONGLONG)1;
|
|
Open->Bound = TRUE;
|
|
Open->DumpFileName.Buffer = NULL;
|
|
Open->DumpFileHandle = NULL;
|
|
Open->tme.active = TME_NONE_ACTIVE;
|
|
Open->DumpLimitReached = FALSE;
|
|
Open->MaxFrameSize = 0;
|
|
|
|
//allocate the spinlock for the statistic counters
|
|
NdisAllocateSpinLock(&Open->CountersLock);
|
|
|
|
//allocate the spinlock for the buffer pointers
|
|
NdisAllocateSpinLock(&Open->BufLock);
|
|
|
|
//
|
|
// link up the request stored in our open block
|
|
//
|
|
for (i=0;i<MAX_REQUESTS;i++) {
|
|
ExInterlockedInsertTailList(
|
|
&Open->RequestList,
|
|
&Open->Requests[i].ListElement,
|
|
&Open->RequestSpinLock);
|
|
|
|
}
|
|
|
|
|
|
IoMarkIrpPending(Irp);
|
|
|
|
//
|
|
// Try to open the MAC
|
|
//
|
|
IF_LOUD(DbgPrint("NPF: Openinig the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);)
|
|
|
|
NdisOpenAdapter(
|
|
&Status,
|
|
&ErrorStatus,
|
|
&Open->AdapterHandle,
|
|
&Open->Medium,
|
|
MediumArray,
|
|
NUM_NDIS_MEDIA,
|
|
DeviceExtension->NdisProtocolHandle,
|
|
Open,
|
|
&DeviceExtension->AdapterName,
|
|
0,
|
|
NULL);
|
|
|
|
IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);)
|
|
|
|
if (Status != NDIS_STATUS_PENDING)
|
|
{
|
|
NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS);
|
|
}
|
|
|
|
return(STATUS_PENDING);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
VOID NPF_OpenAdapterComplete(
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN NDIS_STATUS Status,
|
|
IN NDIS_STATUS OpenErrorStatus)
|
|
{
|
|
|
|
PIRP Irp;
|
|
POPEN_INSTANCE Open;
|
|
PLIST_ENTRY RequestListEntry;
|
|
PINTERNAL_REQUEST MaxSizeReq;
|
|
NDIS_STATUS ReqStatus;
|
|
|
|
|
|
IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");)
|
|
|
|
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
|
|
|
//
|
|
// get the open irp
|
|
//
|
|
Irp=Open->OpenCloseIrp;
|
|
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");)
|
|
|
|
NdisFreePacketPool(Open->PacketPool);
|
|
|
|
//free mem_ex
|
|
Open->mem_ex.size = 0;
|
|
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
|
|
|
ExFreePool(Open->ReadEventName.Buffer);
|
|
|
|
ZwClose(Open->ReadEventHandle);
|
|
|
|
|
|
ExFreePool(Open);
|
|
}
|
|
else {
|
|
NdisAcquireSpinLock(&Opened_Instances_Lock);
|
|
n_Opened_Instances++;
|
|
NdisReleaseSpinLock(&Opened_Instances_Lock);
|
|
|
|
IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
|
|
|
|
// Get the absolute value of the system boot time.
|
|
// This is used for timestamp conversion.
|
|
TIME_SYNCHRONIZE(&G_Start_Time);
|
|
|
|
// Extract a request from the list of free ones
|
|
RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock);
|
|
|
|
if (RequestListEntry == NULL)
|
|
{
|
|
|
|
Open->MaxFrameSize = 1514; // Assume Ethernet
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return;
|
|
}
|
|
|
|
MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
|
|
MaxSizeReq->Irp = Irp;
|
|
MaxSizeReq->Internal = TRUE;
|
|
|
|
|
|
MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
|
|
MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
|
|
|
|
|
|
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize;
|
|
MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
|
|
|
|
// submit the request
|
|
NdisRequest(
|
|
&ReqStatus,
|
|
Open->AdapterHandle,
|
|
&MaxSizeReq->Request);
|
|
|
|
|
|
if (ReqStatus != NDIS_STATUS_PENDING) {
|
|
NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus);
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
|
|
{
|
|
|
|
POPEN_INSTANCE Open;
|
|
NDIS_STATUS Status;
|
|
PIO_STACK_LOCATION IrpSp;
|
|
LARGE_INTEGER ThreadDelay;
|
|
|
|
IF_LOUD(DbgPrint("NPF: CloseAdapter\n");)
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
Open=IrpSp->FileObject->FsContext;
|
|
|
|
// Reset the buffer size. This tells the dump thread to stop.
|
|
Open->BufSize = 0;
|
|
|
|
if( Open->Bound == FALSE){
|
|
|
|
NdisWaitEvent(&Open->IOEvent,10000);
|
|
|
|
// Free the filter if it's present
|
|
if(Open->bpfprogram != NULL)
|
|
ExFreePool(Open->bpfprogram);
|
|
|
|
// Free the jitted filter if it's present
|
|
if(Open->Filter != NULL)
|
|
BPF_Destroy_JIT_Filter(Open->Filter);
|
|
|
|
//free the buffer
|
|
Open->BufSize=0;
|
|
if(Open->Buffer != NULL)ExFreePool(Open->Buffer);
|
|
|
|
//free mem_ex
|
|
Open->mem_ex.size = 0;
|
|
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
|
|
|
NdisFreePacketPool(Open->PacketPool);
|
|
|
|
// Free the string with the name of the dump file
|
|
if(Open->DumpFileName.Buffer!=NULL)
|
|
ExFreePool(Open->DumpFileName.Buffer);
|
|
|
|
ExFreePool(Open->ReadEventName.Buffer);
|
|
ExFreePool(Open);
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
// Unfreeze the consumer
|
|
if(Open->mode & MODE_DUMP)
|
|
NdisSetEvent(&Open->DumpEvent);
|
|
else
|
|
KeSetEvent(Open->ReadEvent,0,FALSE);
|
|
|
|
// Save the IRP
|
|
Open->OpenCloseIrp = Irp;
|
|
|
|
IoMarkIrpPending(Irp);
|
|
|
|
// If this instance is in dump mode, complete the dump and close the file
|
|
if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){
|
|
NTSTATUS wres;
|
|
|
|
ThreadDelay.QuadPart = -50000000;
|
|
// Wait the completion of the thread
|
|
wres = KeWaitForSingleObject(Open->DumpThreadObject,
|
|
UserRequest,
|
|
KernelMode,
|
|
TRUE,
|
|
&ThreadDelay);
|
|
|
|
ObDereferenceObject(Open->DumpThreadObject);
|
|
|
|
|
|
// Flush and close the dump file
|
|
NPF_CloseDumpFile(Open);
|
|
}
|
|
|
|
// Destroy the read Event
|
|
ZwClose(Open->ReadEventHandle);
|
|
|
|
// Close the adapter
|
|
NdisCloseAdapter(
|
|
&Status,
|
|
Open->AdapterHandle
|
|
);
|
|
|
|
if (Status != NDIS_STATUS_PENDING) {
|
|
|
|
NPF_CloseAdapterComplete(
|
|
Open,
|
|
Status
|
|
);
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
return(STATUS_PENDING);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
VOID
|
|
NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
|
|
{
|
|
POPEN_INSTANCE Open;
|
|
PIRP Irp;
|
|
|
|
IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");)
|
|
|
|
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
|
|
|
// free the allocated structures only if the instance is still bound to the adapter
|
|
if(Open->Bound == TRUE){
|
|
|
|
// Free the filter if it's present
|
|
if(Open->bpfprogram != NULL)
|
|
ExFreePool(Open->bpfprogram);
|
|
|
|
// Free the jitted filter if it's present
|
|
if(Open->Filter != NULL)
|
|
BPF_Destroy_JIT_Filter(Open->Filter);
|
|
|
|
//free the buffer
|
|
Open->BufSize = 0;
|
|
if(Open->Buffer!=NULL)ExFreePool(Open->Buffer);
|
|
|
|
//free mem_ex
|
|
Open->mem_ex.size = 0;
|
|
if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
|
|
|
|
NdisFreePacketPool(Open->PacketPool);
|
|
|
|
Irp=Open->OpenCloseIrp;
|
|
|
|
// Free the string with the name of the dump file
|
|
if(Open->DumpFileName.Buffer!=NULL)
|
|
ExFreePool(Open->DumpFileName.Buffer);
|
|
|
|
ExFreePool(Open->ReadEventName.Buffer);
|
|
ExFreePool(Open);
|
|
|
|
// Complete the request only if the instance is still bound to the adapter
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
else
|
|
NdisSetEvent(&Open->IOEvent);
|
|
|
|
// Decrease the counter of open instances
|
|
NdisAcquireSpinLock(&Opened_Instances_Lock);
|
|
n_Opened_Instances--;
|
|
NdisReleaseSpinLock(&Opened_Instances_Lock);
|
|
|
|
IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
|
|
|
|
if(n_Opened_Instances == 0){
|
|
// Force a synchronization at the next NPF_Open().
|
|
// This hopefully avoids the synchronization issues caused by hibernation or standby.
|
|
TIME_DESYNCHRONIZE(&G_Start_Time);
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
//-------------------------------------------------------------------
|
|
|
|
#ifdef NDIS50
|
|
NDIS_STATUS
|
|
NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
|
|
{
|
|
IF_LOUD(DbgPrint("NPF: PowerChange\n");)
|
|
|
|
TIME_DESYNCHRONIZE(&G_Start_Time);
|
|
|
|
TIME_SYNCHRONIZE(&G_Start_Time);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
VOID
|
|
NPF_BindAdapter(
|
|
OUT PNDIS_STATUS Status,
|
|
IN NDIS_HANDLE BindContext,
|
|
IN PNDIS_STRING DeviceName,
|
|
IN PVOID SystemSpecific1,
|
|
IN PVOID SystemSpecific2
|
|
)
|
|
{
|
|
IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");)
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
VOID
|
|
NPF_UnbindAdapter(
|
|
OUT PNDIS_STATUS Status,
|
|
IN NDIS_HANDLE ProtocolBindingContext,
|
|
IN NDIS_HANDLE UnbindContext
|
|
)
|
|
{
|
|
POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext;
|
|
NDIS_STATUS lStatus;
|
|
|
|
IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");)
|
|
|
|
// Reset the buffer size. This tells the dump thread to stop.
|
|
Open->BufSize=0;
|
|
|
|
NdisResetEvent(&Open->IOEvent);
|
|
|
|
// This open instance is no more bound to the adapter, set Bound to False
|
|
InterlockedExchange( (PLONG) &Open->Bound, FALSE );
|
|
|
|
// Awake a possible pending read on this instance
|
|
if(Open->mode & MODE_DUMP)
|
|
NdisSetEvent(&Open->DumpEvent);
|
|
else
|
|
KeSetEvent(Open->ReadEvent,0,FALSE);
|
|
|
|
// If this instance is in dump mode, complete the dump and close the file
|
|
if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
|
|
NPF_CloseDumpFile(Open);
|
|
|
|
// Destroy the read Event
|
|
ZwClose(Open->ReadEventHandle);
|
|
|
|
// close the adapter
|
|
NdisCloseAdapter(
|
|
&lStatus,
|
|
Open->AdapterHandle
|
|
);
|
|
|
|
if (lStatus != NDIS_STATUS_PENDING) {
|
|
|
|
NPF_CloseAdapterComplete(
|
|
Open,
|
|
lStatus
|
|
);
|
|
|
|
*Status = NDIS_STATUS_SUCCESS;
|
|
return;
|
|
|
|
}
|
|
|
|
*Status = NDIS_STATUS_SUCCESS;
|
|
return;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
VOID
|
|
NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
|
|
|
|
{
|
|
POPEN_INSTANCE Open;
|
|
PIRP Irp;
|
|
|
|
PLIST_ENTRY ResetListEntry;
|
|
|
|
IF_LOUD(DbgPrint("NPF: PacketResetComplte\n");)
|
|
|
|
Open= (POPEN_INSTANCE)ProtocolBindingContext;
|
|
|
|
|
|
//
|
|
// remove the reset IRP from the list
|
|
//
|
|
ResetListEntry=ExInterlockedRemoveHeadList(
|
|
&Open->ResetIrpList,
|
|
&Open->RequestSpinLock
|
|
);
|
|
|
|
#if DBG
|
|
if (ResetListEntry == NULL) {
|
|
DbgBreakPoint();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry);
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
IF_LOUD(DbgPrint("NPF: PacketResetComplte exit\n");)
|
|
|
|
return;
|
|
|
|
}
|