www.pudn.com > ntsniff.zip > WRITE.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 "stdarg.h" 
#include "ntddk.h" 
#include "ntiologc.h" 
#include "ndis.h" 
 
#include "debug.h" 
#include "packet.h" 
 
 
NTSTATUS 
PacketWrite( 
    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; 
    PIO_STACK_LOCATION IrpSp; 
    PNDIS_PACKET       pPacket; 
 
    NDIS_STATUS     Status; 
 
    IF_LOUD(DbgPrint("Packet: SendAdapter\n");) 
 
    IrpSp = IoGetCurrentIrpStackLocation(Irp); 
 
    Open=IrpSp->FileObject->FsContext; 
 
    IoIncrement(Open); 
 
    // 
    //  Try to get a packet from our list of free ones 
    // 
 
    NdisAllocatePacket( 
        &Status, 
        &pPacket, 
        Open->PacketPool 
        ); 
 
    if (Status != NDIS_STATUS_SUCCESS) { 
 
        // 
        //  No free packets 
        // 
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 
        IoCompleteRequest (Irp, IO_NO_INCREMENT); 
        IoDecrement(Open); 
        return STATUS_INSUFFICIENT_RESOURCES; 
    } 
 
    RESERVED(pPacket)->Irp=Irp; 
 
    // 
    //  Attach the writes buffer to the packet 
    // 
    NdisChainBufferAtFront(pPacket,Irp->MdlAddress); 
 
    // 
    // Important: Since we have marked the IRP pending, we must return  
    // STATUS_PENDING even we happen to complete the IRP synchronously. 
    //  
 
    IoMarkIrpPending(Irp); 
 
    // 
    //  Call the MAC 
    // 
     
    NdisSend( 
        &Status, 
        Open->AdapterHandle, 
        pPacket); 
 
 
    if (Status != NDIS_STATUS_PENDING) { 
        // 
        //  The send didn't pend so call the completion handler now 
        // 
        PacketSendComplete( 
            Open, 
            pPacket, 
            Status 
            ); 
    } 
 
    return(STATUS_PENDING); 
 
} 
 
VOID 
PacketSendComplete( 
    IN NDIS_HANDLE   ProtocolBindingContext, 
    IN PNDIS_PACKET  pPacket, 
    IN NDIS_STATUS   Status 
    ) 
 
{ 
    PIRP              Irp; 
    PIO_STACK_LOCATION  irpSp; 
    POPEN_INSTANCE      open;  
 
 
 
    IF_LOUD(DbgPrint("Packet: SendComplete\n");) 
 
    Irp=RESERVED(pPacket)->Irp; 
    irpSp = IoGetCurrentIrpStackLocation(Irp); 
    open=irpSp->FileObject->FsContext; 
 
    // 
    //  Put the packet back on the free list 
    // 
    NdisFreePacket(pPacket); 
 
    if(Status == NDIS_STATUS_SUCCESS) { 
        Irp->IoStatus.Information = irpSp->Parameters.Write.Length; 
        Irp->IoStatus.Status = STATUS_SUCCESS;         
    } else { 
        Irp->IoStatus.Information = 0; 
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;         
    } 
 
    IoCompleteRequest(Irp, IO_NO_INCREMENT); 
    IoDecrement(open); 
    return; 
 
}