www.pudn.com > ntsniff.zip > OPENCLOS.C
/* * NtSniff by Davide Libenzi ( To rebuild NtSniff You need Microsoft SDK & DDK ) * Copyright (C) 1999 Davide Libenzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Davide Libenzi* */ #include "ntddk.h" #include "ntiologc.h" #include "ndis.h" #include "debug.h" #include "packet.h" NTSTATUS PacketOpen( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This is the dispatch routine for create/open and close requests. These requests complete successfully. Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: Status is returned. --*/ { PDEVICE_EXTENSION DeviceExtension; POPEN_INSTANCE Open; PIO_STACK_LOCATION IrpSp; NDIS_STATUS Status; NDIS_STATUS ErrorStatus; UINT Medium; NDIS_MEDIUM MediumArray=NdisMedium802_3; UINT i; IF_LOUD(DbgPrint("Packet: OpenAdapter\n");) DeviceExtension = DeviceObject->DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp); // // allocate some memory for the open structure // Open=ExAllocatePool(NonPagedPool,sizeof(OPEN_INSTANCE)); 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) ); // // Save or open here // IrpSp->FileObject->FsContext=Open; Open->DeviceExtension=DeviceExtension; // // Save the Irp here for the completion routine to retrieve // Open->OpenCloseIrp=Irp; Open->IrpCount = 0; NdisInitializeEvent(&Open->CleanupEvent); // // 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("Packet: Failed to allocate packet pool\n");) ExFreePool(Open); Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } // // list to hold irp's want to reset the adapter // InitializeListHead(&Open->ResetIrpList); // // Initialize list for holding pending read requests // KeInitializeSpinLock(&Open->RcvQSpinLock); InitializeListHead(&Open->RcvList); // // Initialize the request list // KeInitializeSpinLock(&Open->RequestSpinLock); InitializeListHead(&Open->RequestList); // // link up the request stored in our open block // for (i=0;i RequestList, &Open->Requests[i].ListElement, &Open->RequestSpinLock); } // // Important: Since we have marked the IRP pending, we must return // STATUS_PENDING even we happen to complete the IRP synchronously. // IoMarkIrpPending(Irp); // // Try to open the MAC // NdisOpenAdapter( &Status, &ErrorStatus, &Open->AdapterHandle, &Medium, &MediumArray, 1, DeviceExtension->NdisProtocolHandle, Open, &DeviceExtension->AdapterName, 0, NULL); if (Status != NDIS_STATUS_PENDING) { PacketOpenAdapterComplete( Open, Status, NDIS_STATUS_SUCCESS ); } return(STATUS_PENDING); } VOID PacketOpenAdapterComplete( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status, IN NDIS_STATUS OpenErrorStatus ) { PIRP Irp; POPEN_INSTANCE Open; IF_LOUD(DbgPrint("Packet: OpenAdapterComplete\n");) Open= (POPEN_INSTANCE)ProtocolBindingContext; // // get the open irp // Irp=Open->OpenCloseIrp; if (Status != NDIS_STATUS_SUCCESS) { IF_LOUD(DbgPrint("Packet: OpenAdapterComplete-FAILURE\n");) NdisFreePacketPool(Open->PacketPool); ExFreePool(Open); } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return; } NTSTATUS PacketClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This is the dispatch routine for create/open and close requests. These requests complete successfully. Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: Status is returned. --*/ { POPEN_INSTANCE Open; NDIS_STATUS Status; PIO_STACK_LOCATION IrpSp; IF_LOUD(DbgPrint("Packet: CloseAdapter\n");) IrpSp = IoGetCurrentIrpStackLocation(Irp); Open=IrpSp->FileObject->FsContext; // // Save the IRP // Open->OpenCloseIrp=Irp; // // Important: Since we have marked the IRP pending, we must return // STATUS_PENDING even we happen to complete the IRP synchronously. // IoMarkIrpPending(Irp); // // close the adapter // NdisCloseAdapter( &Status, Open->AdapterHandle ); if (Status != NDIS_STATUS_PENDING) { PacketCloseAdapterComplete( Open, Status ); } return(STATUS_PENDING); } VOID PacketCloseAdapterComplete( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status ) { POPEN_INSTANCE Open; PIRP Irp; IF_LOUD(DbgPrint("Packet: CloseAdapterComplete\n");) Open= (POPEN_INSTANCE)ProtocolBindingContext; Irp=Open->OpenCloseIrp; NdisFreePacketPool(Open->PacketPool); ExFreePool(Open); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return; } NTSTATUS PacketCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This is the dispatch routine for cleanup requests. This routine is called whenever a handle to the device is closed. Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: Status is returned. --*/ { POPEN_INSTANCE open; NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION irpSp; IF_LOUD(DbgPrint("Packet: Cleanup\n");) irpSp = IoGetCurrentIrpStackLocation(Irp); open=irpSp->FileObject->FsContext; // // Cancel all the pending reads. // PacketCancelReadIrps(open); if(open->IrpCount) { // // We might have pending Reset, Oid or Send requests. Since // we cannot cancel them we must here until they // complete. // NdisWaitEvent(&open->CleanupEvent, 0); } Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; }