Main Page   Modules   Data Structures   File List   Data Fields   Globals  

Read.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999, 2000
00003  *  Politecnico di Torino.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that: (1) source code distributions
00007  * retain the above copyright notice and this paragraph in its entirety, (2)
00008  * distributions including binary code include the above copyright notice and
00009  * this paragraph in its entirety in the documentation or other materials
00010  * provided with the distribution, and (3) all advertising materials mentioning
00011  * features or use of this software display the following acknowledgement:
00012  * ``This product includes software developed by the Politecnico
00013  * di Torino, and its contributors.'' Neither the name of
00014  * the University nor the names of its contributors may be used to endorse
00015  * or promote products derived from this software without specific prior
00016  * written permission.
00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00020  */
00021 
00022 #include <stdarg.h>
00023 #include "ntddk.h"
00024 #include <ntiologc.h>
00025 #include <ndis.h>
00026 #include "debug.h"
00027 #include "packet.h"
00028 #include "win_bpf.h"
00029 
00030 #include "tme.h"
00031 #include "time_calls.h"
00032 
00033 extern struct time_conv G_Start_Time; // from openclos.c
00034 
00035 //-------------------------------------------------------------------
00036 
00037 UINT GetBuffOccupation(POPEN_INSTANCE Open)
00038 {
00039     UINT Occupation;
00040 
00041     NdisAcquireSpinLock( &Open->BufLock );
00042     
00043     if(Open->Btail >= Open->Bhead) Occupation = Open->Btail-Open->Bhead;
00044     else Occupation = Open->BLastByte-Open->Bhead+Open->Btail;
00045 
00046     NdisReleaseSpinLock( &Open->BufLock );
00047 
00048     return Occupation;
00049 }
00050 
00051 //-------------------------------------------------------------------
00052 
00053 void PacketMoveMem(PVOID Destination, PVOID Source, ULONG Length, UINT   *Bhead)
00054 {
00055 ULONG WordLength;
00056 UINT n,i,NBlocks;
00057 
00058     WordLength=Length>>2;
00059     NBlocks=WordLength>>8;
00060     
00061     for(n=0;n<NBlocks;n++){
00062         for(i=0;i<256;i++){
00063             *((PULONG)Destination)++=*((PULONG)Source)++;
00064         }
00065     *Bhead+=1024;
00066     }
00067 
00068     n=WordLength-(NBlocks<<8);
00069     for(i=0;i<n;i++){
00070         *((PULONG)Destination)++=*((PULONG)Source)++;
00071     }
00072     *Bhead+=n<<2;
00073     
00074     n=Length-(WordLength<<2);
00075     for(i=0;i<n;i++){
00076         *((PUCHAR)Destination)++=*((PUCHAR)Source)++;
00077     }
00078     *Bhead+=n;
00079 }
00080 
00081 //-------------------------------------------------------------------
00082 
00083 NTSTATUS NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
00084 {
00085     POPEN_INSTANCE      Open;
00086     PIO_STACK_LOCATION  IrpSp;
00087     PUCHAR              packp;
00088     UINT                i;
00089     ULONG               Input_Buffer_Length;
00090     UINT                Thead;
00091     UINT                Ttail;
00092     UINT                TLastByte;
00093     PUCHAR              CurrBuff;
00094     UINT                cplen;
00095     UINT                CpStart;
00096     LARGE_INTEGER       CapTime;
00097     LARGE_INTEGER       TimeFreq;
00098     struct bpf_hdr      *header;
00099     KIRQL               Irql;
00100     PUCHAR              UserPointer;
00101     ULONG               bytecopy;
00102 
00103     IF_LOUD(DbgPrint("NPF: Read\n");)
00104         
00105     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00106     Open=IrpSp->FileObject->FsContext;
00107     
00108     if( Open->Bound == FALSE ){
00109         // The Network adapter was removed.
00110         EXIT_FAILURE(0);
00111     }
00112     
00113     if( Open->mode & MODE_DUMP && Open->DumpFileHandle == NULL ){  
00114         // this instance is in dump mode, but the dump file has still not been opened
00115         EXIT_FAILURE(0);
00116     }
00117 
00118     //See if the buffer is full enough to be copied
00119     if( GetBuffOccupation(Open) <= Open->MinToCopy || Open->mode & MODE_DUMP )
00120     {
00121         //wait until some packets arrive or the timeout expires     
00122         if(Open->TimeOut.QuadPart != (LONGLONG)IMMEDIATE)
00123             KeWaitForSingleObject(Open->ReadEvent,
00124                 UserRequest,
00125                 KernelMode,
00126                 TRUE,
00127                 (Open->TimeOut.QuadPart == (LONGLONG)0)? NULL: &(Open->TimeOut));
00128 
00129         KeClearEvent(Open->ReadEvent);
00130         
00131         if(Open->mode & MODE_STAT){   //this capture instance is in statistics mode
00132             CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress);
00133             
00134             //fill the bpf header for this packet
00135             header=(struct bpf_hdr*)CurrBuff;
00136             GET_TIME(&header->bh_tstamp,&G_Start_Time);
00137 
00138             if(Open->mode & MODE_DUMP){
00139                 *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+16)=Open->DumpOffset.QuadPart;
00140                 header->bh_caplen=24;
00141                 header->bh_datalen=24;
00142                 Irp->IoStatus.Information = 24 + sizeof(struct bpf_hdr);
00143             }
00144             else{
00145                 header->bh_caplen=16;
00146                 header->bh_datalen=16;
00147                 header->bh_hdrlen=sizeof(struct bpf_hdr);
00148                 Irp->IoStatus.Information = 16 + sizeof(struct bpf_hdr);
00149             }
00150 
00151             *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets.QuadPart;
00152             *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes.QuadPart;
00153             
00154             //reset the countetrs
00155             NdisAcquireSpinLock( &Open->CountersLock );
00156             Open->Npackets.QuadPart=0;
00157             Open->Nbytes.QuadPart=0;
00158             NdisReleaseSpinLock( &Open->CountersLock );
00159             
00160             Irp->IoStatus.Status = STATUS_SUCCESS;
00161             IoCompleteRequest(Irp, IO_NO_INCREMENT);
00162             
00163             return STATUS_SUCCESS;
00164         }
00165         
00166         if(Open->mode==MODE_MON)   //this capture instance is in monitor mode
00167         {   
00168             PTME_DATA data;
00169             ULONG cnt;
00170             ULONG block_size;
00171             PUCHAR tmp;
00172 
00173             UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress);
00174             
00175             if ((!IS_VALIDATED(Open->tme.validated_blocks,Open->tme.active_read))||(IrpSp->Parameters.Read.Length<sizeof(struct bpf_hdr)))
00176             {   
00177                 EXIT_FAILURE(0);
00178             }
00179             
00180             header=(struct bpf_hdr*)UserPointer;
00181     
00182             GET_TIME(&header->bh_tstamp,&G_Start_Time);
00183 
00184             
00185             header->bh_hdrlen=sizeof(struct bpf_hdr);
00186             
00187 
00188             //moves user memory pointer
00189             UserPointer+=sizeof(struct bpf_hdr);
00190             
00191             //calculus of data to be copied
00192             //if the user buffer is smaller than data to be copied,
00193             //only some data will be copied
00194             data=&Open->tme.block_data[Open->tme.active_read];
00195 
00196             if (data->last_read.tv_sec!=0)
00197                 data->last_read=header->bh_tstamp;
00198             
00199 
00200             bytecopy=data->block_size*data->filled_blocks;
00201             
00202             if ((IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))<bytecopy)
00203                 bytecopy=(IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))/ data->block_size;
00204             else 
00205                 bytecopy=data->filled_blocks;
00206 
00207             tmp=data->shared_memory_base_address;
00208             block_size=data->block_size;
00209             
00210             for (cnt=0;cnt<bytecopy;cnt++)
00211             {
00212                 NdisAcquireSpinLock(&Open->machine_lock);
00213                 RtlCopyMemory(UserPointer,tmp,block_size);
00214                 NdisReleaseSpinLock(&Open->machine_lock);
00215                 tmp+=block_size;
00216                 UserPointer+=block_size;
00217             }
00218                         
00219             bytecopy*=block_size;
00220 
00221             header->bh_caplen=bytecopy;
00222             header->bh_datalen=header->bh_caplen;
00223 
00224             EXIT_SUCCESS(bytecopy+sizeof(struct bpf_hdr));
00225         }
00226 
00227         if (Open->Bhead == Open->Btail || Open->mode & MODE_DUMP)
00228             // The timeout has expired, but the buffer is still empty (or the packets must be written to file).
00229             // We must awake the application, returning an empty buffer.
00230         {
00231             EXIT_SUCCESS(0);
00232         }
00233                 
00234     }
00235 
00236     //
00237     // The buffer if full enough to be copied,
00238     //
00239     NdisAcquireSpinLock( &Open->BufLock );
00240     
00241     Thead = Open->Bhead;
00242     Ttail = Open->Btail;
00243     TLastByte = Open->BLastByte;
00244 
00245     //get the address of the buffer
00246     CurrBuff=Open->Buffer;
00247     
00248     NdisReleaseSpinLock( &Open->BufLock );
00249     
00250     Input_Buffer_Length=IrpSp->Parameters.Read.Length;
00251     packp=(PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress);
00252     
00253 
00254     //
00255     //fill the application buffer
00256     //
00257     if(Ttail > Thead){  //first of all see if it we can copy all the buffer in one time
00258         if((Ttail-Thead)<Input_Buffer_Length){
00259             KeResetEvent(Open->ReadEvent);
00260 
00261             PacketMoveMem(packp,CurrBuff+Thead,Ttail-Thead,&(Open->Bhead));
00262             EXIT_SUCCESS(Ttail-Thead);
00263         }
00264     }
00265     else if((TLastByte - Thead) < Input_Buffer_Length){
00266         PacketMoveMem(packp, CurrBuff+Thead, TLastByte - Thead, &(Open->Bhead));
00267 
00268         NdisAcquireSpinLock( &Open->BufLock );
00269         
00270         Open->BLastByte = Open->Btail;
00271         Open->Bhead = 0;
00272 
00273         NdisReleaseSpinLock( &Open->BufLock );
00274         
00275         EXIT_SUCCESS(TLastByte-Thead);
00276     }
00277     
00278     //the buffer must be scannned to determine the number of bytes to copy
00279     CpStart=Thead;
00280     i=0;
00281     while(TRUE){
00282         if(Thead == Ttail)break;
00283 
00284         if(Thead == TLastByte){
00285             // Copy the portion between thead and TLastByte
00286             PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
00287             packp+=(Thead-CpStart);
00288 
00289             NdisAcquireSpinLock( &Open->BufLock );
00290             
00291             Open->BLastByte = Open->Btail;
00292             Open->Bhead = 0;
00293             
00294             NdisReleaseSpinLock( &Open->BufLock );
00295 
00296             Thead=0;
00297             CpStart=0;
00298         }
00299         cplen=((struct bpf_hdr*)(CurrBuff+Thead))->bh_caplen+sizeof(struct bpf_hdr);
00300 
00301         if((i+cplen > Input_Buffer_Length)){//no more space in the application's buffer
00302             PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
00303 
00304             EXIT_SUCCESS(i);
00305         }
00306         cplen=Packet_WORDALIGN(cplen);
00307         i+=cplen;
00308         Thead+=cplen;
00309     }
00310     
00311 
00312     KeResetEvent(Open->ReadEvent);
00313     
00314     PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead));
00315     
00316     Open->Bhead=Thead;
00317     
00318     
00319     EXIT_SUCCESS(i);    
00320 }
00321 
00322 //-------------------------------------------------------------------
00323 
00324 NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacReceiveContext,
00325                         IN PVOID HeaderBuffer,IN UINT HeaderBufferSize,IN PVOID LookAheadBuffer,
00326                         IN UINT LookaheadBufferSize,IN UINT PacketSize)
00327 {
00328     POPEN_INSTANCE      Open;
00329     PNDIS_PACKET        pPacketb;
00330     ULONG               SizeToTransfer;
00331     NDIS_STATUS         Status;
00332     UINT                BytesTransfered;
00333     ULONG               BufferLength;
00334     PMDL                pMdl;
00335     LARGE_INTEGER       CapTime;
00336     LARGE_INTEGER       TimeFreq;
00337     struct bpf_hdr      *header;
00338     PUCHAR              CurrBuff;
00339     UINT                Thead;
00340     UINT                Ttail;
00341     UINT                TLastByte;
00342     UINT                fres;
00343     UINT                maxbufspace;
00344     USHORT              NPFHdrSize;
00345     UINT                BufOccupation;
00346 
00347     IF_VERY_LOUD(DbgPrint("NPF: tap\n");)
00348 
00349     Open= (POPEN_INSTANCE)ProtocolBindingContext;
00350 
00351     Open->Received++;       // Number of packets received by filter ++
00352 
00353     BufOccupation = GetBuffOccupation(Open);    // Get the full buffer space
00354 
00355     if(((Open->mode&MODE_CAPT)||(Open->mode&MODE_DUMP)) && Open->BufSize - BufOccupation < PacketSize+HeaderBufferSize+sizeof(struct bpf_hdr)){
00356         // Heuristic that drops the packet also if it possibly fits in the buffer.
00357         // It allows to avoid filtering in critical situations when CPU is very important.
00358         Open->Dropped++;
00359         return NDIS_STATUS_NOT_ACCEPTED;
00360     }
00361 
00362     NdisAcquireSpinLock(&Open->machine_lock);
00363     
00364     //
00365     //Check if the lookahead buffer follows the mac header.
00366     //If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is
00367     //executed on the packet.
00368     //Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or
00369     //things like this) bpf_filter_with_2_buffers() is executed.
00370     //
00371     if((UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize)
00372         fres=bpf_filter_with_2_buffers((struct bpf_insn*)(Open->bpfprogram),
00373                                        HeaderBuffer,
00374                                        LookAheadBuffer,
00375                                        HeaderBufferSize,
00376                                        PacketSize+HeaderBufferSize,
00377                                        LookaheadBufferSize+HeaderBufferSize,
00378                                        &Open->mem_ex,
00379                                        &Open->tme,
00380                                        &G_Start_Time);
00381     
00382     
00383     else 
00384         if(Open->Filter != NULL)
00385         {
00386             if (Open->bpfprogram != NULL)
00387             {
00388                 fres=Open->Filter->Function(HeaderBuffer,
00389                                     PacketSize+HeaderBufferSize,
00390                                     LookaheadBufferSize+HeaderBufferSize);
00391         
00392                 // Restore the stack. 
00393                 // I ignore the reason, but this instruction is needed only at kernel level
00394                 _asm add esp,12     
00395             }
00396             else
00397                 fres = -1;
00398         }
00399         else
00400             fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram),
00401                         HeaderBuffer,
00402                         PacketSize+HeaderBufferSize,
00403                         LookaheadBufferSize+HeaderBufferSize,
00404                         &Open->mem_ex,
00405                         &Open->tme,
00406                         &G_Start_Time);
00407 
00408     NdisReleaseSpinLock(&Open->machine_lock);
00409     
00410     if(Open->mode==MODE_MON)
00411     // we are in monitor mode
00412     {
00413         if (fres==1) 
00414             KeSetEvent(Open->ReadEvent,0,FALSE);
00415         return NDIS_STATUS_NOT_ACCEPTED;
00416 
00417     }
00418 
00419     if(fres==0)
00420         // Packet not accepted by the filter, ignore it.
00421         return NDIS_STATUS_NOT_ACCEPTED;
00422 
00423     //if the filter returns -1 the whole packet must be accepted
00424     if(fres==-1 || fres > PacketSize+HeaderBufferSize)fres=PacketSize+HeaderBufferSize; 
00425 
00426     if(Open->mode & MODE_STAT){
00427     // we are in statistics mode
00428         NdisAcquireSpinLock( &Open->CountersLock );
00429 
00430         Open->Npackets.QuadPart++;
00431         
00432         if(PacketSize+HeaderBufferSize<60)
00433             Open->Nbytes.QuadPart+=60;
00434         else
00435             Open->Nbytes.QuadPart+=PacketSize+HeaderBufferSize;
00436         // add preamble+SFD+FCS to the packet
00437         // these values must be considered because are not part of the packet received from NDIS
00438         Open->Nbytes.QuadPart+=12;
00439 
00440         NdisReleaseSpinLock( &Open->CountersLock );
00441         
00442         if(!(Open->mode & MODE_DUMP)){
00443             return NDIS_STATUS_NOT_ACCEPTED;
00444         }
00445     }
00446 
00447     if(Open->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED;
00448     
00449     if(Open->mode & MODE_DUMP && Open->MaxDumpPacks &&  (UINT)Open->Accepted > Open->MaxDumpPacks){
00450         // Reached the max number of packets to save in the dump file. Discard the packet and stop the dump thread.
00451         Open->DumpLimitReached = TRUE; // This stops the thread
00452         // Awake the dump thread
00453         NdisSetEvent(&Open->DumpEvent);
00454 
00455         // Awake the application
00456         KeSetEvent(Open->ReadEvent,0,FALSE);
00457 
00458         return NDIS_STATUS_NOT_ACCEPTED;
00459     }
00460 
00461     // Calculate the correct size for the header associated with the packet
00462     NPFHdrSize=(Open->mode==MODE_CAPT)? sizeof(struct bpf_hdr): sizeof(struct sf_pkthdr);
00463  
00464     NdisAcquireSpinLock( &Open->BufLock );
00465 
00466     Thead=Open->Bhead;
00467     Ttail=Open->Btail;
00468     TLastByte = Open->BLastByte;
00469 
00470     NdisReleaseSpinLock( &Open->BufLock );
00471     
00472     maxbufspace=Packet_WORDALIGN(fres+NPFHdrSize);
00473 
00474     if(Ttail+maxbufspace >= Open->BufSize){
00475         if(Thead <= maxbufspace)
00476         {
00477             Open->Dropped++;
00478             return NDIS_STATUS_NOT_ACCEPTED;
00479         }
00480         else{
00481             Ttail=0;
00482         }
00483     }
00484     
00485     CurrBuff=Open->Buffer+Ttail;
00486 
00487     if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize)
00488     {
00489         //  Allocate an MDL to map the portion of the buffer following the header
00490         pMdl=IoAllocateMdl(CurrBuff+HeaderBufferSize+LookaheadBufferSize+NPFHdrSize,
00491             maxbufspace,
00492             FALSE,
00493             FALSE,
00494             NULL);
00495 
00496         if (pMdl == NULL)
00497         {
00498             // Unable to map the memory: packet lost
00499             IF_LOUD(DbgPrint("NPF: Read-Failed to allocate Mdl\n");)
00500                 Open->Dropped++;
00501             return NDIS_STATUS_NOT_ACCEPTED;
00502         }
00503         MmBuildMdlForNonPagedPool(pMdl);
00504         
00505         //allocate the packet from NDIS
00506         NdisAllocatePacket(&Status, &pPacketb, Open->PacketPool);
00507         if (Status != NDIS_STATUS_SUCCESS)
00508         {
00509             IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");)
00510             IoFreeMdl(pMdl);
00511             Open->Dropped++;
00512             return NDIS_STATUS_NOT_ACCEPTED;
00513         }
00514         //link the buffer to the packet
00515         NdisChainBufferAtFront(pPacketb,pMdl);
00516         
00517         BufferLength=fres-HeaderBufferSize;
00518         //Find out how much to transfer
00519         SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength;
00520         
00521         //copy the ethernet header into buffer
00522         NdisMoveMappedMemory((CurrBuff)+NPFHdrSize,HeaderBuffer,HeaderBufferSize);
00523         
00524         //Copy the look ahead buffer
00525         if(LookaheadBufferSize)
00526         {
00527             NdisMoveMappedMemory((CurrBuff) + NPFHdrSize + HeaderBufferSize,
00528                 LookAheadBuffer, 
00529                 (SizeToTransfer < LookaheadBufferSize)? SizeToTransfer : LookaheadBufferSize );
00530             
00531             SizeToTransfer = (SizeToTransfer > LookaheadBufferSize)?
00532                 SizeToTransfer - LookaheadBufferSize : 0;
00533         }
00534         
00535         Open->TransferMdl=pMdl;
00536         
00537         if(SizeToTransfer)
00538         {
00539             //Call the Mac to transfer the packet
00540             NdisTransferData(&Status,
00541                 Open->AdapterHandle,
00542                 MacReceiveContext,
00543                 LookaheadBufferSize,
00544                 SizeToTransfer,
00545                 pPacketb,
00546                 &BytesTransfered);
00547         }
00548         else{
00549             BytesTransfered = 0;
00550         }
00551         
00552     }
00553     else
00554     {
00555     // The whole packet is in the lookahead buffer, we can avoid the call to NdisTransferData.
00556     // This allows us to avoid the allocation of the MDL and the NDIS packet as well
00557     RtlCopyMemory((CurrBuff) + NPFHdrSize,
00558         HeaderBuffer,
00559         HeaderBufferSize + LookaheadBufferSize);
00560 
00561         Open->TransferMdl = NULL;
00562         Status = NDIS_STATUS_SUCCESS;
00563     }
00564 
00565     Open->Accepted++;       // Increase the accepted packets counter
00566 
00567     if (Status != NDIS_STATUS_FAILURE)
00568     {
00569 
00570         if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) )
00571             fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize;
00572         
00573         //
00574         // Build the header
00575         //
00576         header=(struct bpf_hdr*)CurrBuff;
00577         GET_TIME(&header->bh_tstamp,&G_Start_Time);
00578         header->bh_caplen=fres;
00579         header->bh_datalen=PacketSize+HeaderBufferSize;
00580         if(Open->mode==MODE_CAPT){
00581             header->bh_hdrlen=NPFHdrSize;
00582             // Don't align if the packet goes to disk
00583             Ttail+=Packet_WORDALIGN(fres + NPFHdrSize);
00584         }
00585         else
00586             Ttail+=fres+NPFHdrSize;
00587         
00588         //update the buffer 
00589         if(Ttail > Thead)TLastByte = Ttail;
00590 
00591         NdisAcquireSpinLock( &Open->BufLock );
00592         
00593         Open->Btail=Ttail;
00594         Open->BLastByte=TLastByte;
00595         
00596         NdisReleaseSpinLock( &Open->BufLock );
00597     }
00598 
00599     if (Status != NDIS_STATUS_PENDING){
00600 
00601         if( Open->TransferMdl != NULL)
00602             // Complete the request and free the buffers
00603             NPF_TransferDataComplete(Open,pPacketb,Status,fres);
00604         else{
00605             // Unfreeze the consumer
00606             if(GetBuffOccupation(Open)>Open->MinToCopy){
00607                 if(Open->mode & MODE_DUMP){
00608                     NdisSetEvent(&Open->DumpEvent);
00609                 }
00610                 else
00611                     KeSetEvent(Open->ReadEvent,0,FALSE);    
00612             }
00613             
00614         }
00615     }
00616     
00617     return NDIS_STATUS_SUCCESS;
00618     
00619 }
00620 
00621 //-------------------------------------------------------------------
00622 
00623 VOID NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket,
00624                                  IN NDIS_STATUS Status,IN UINT BytesTransfered)
00625 {
00626     POPEN_INSTANCE      Open;
00627 
00628     IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");)
00629     
00630     Open= (POPEN_INSTANCE)ProtocolBindingContext;
00631 
00632     IoFreeMdl(Open->TransferMdl);
00633     //recylcle the packet
00634     NdisReinitializePacket(pPacket);
00635     //Put the packet on the free queue
00636     NdisFreePacket(pPacket);
00637     // Unfreeze the consumer
00638     if(GetBuffOccupation(Open)>Open->MinToCopy){
00639         if(Open->mode & MODE_DUMP){
00640             NdisSetEvent(&Open->DumpEvent);
00641         }
00642         else
00643             KeSetEvent(Open->ReadEvent,0,FALSE);    
00644     }
00645     return;
00646 }
00647 
00648 //-------------------------------------------------------------------
00649 
00650 VOID NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
00651 {
00652     IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");)
00653     return;
00654 }

documentation. Copyright (c) 2002 Politecnico di Torino. All rights reserved.