update for HEAD-2003021201
[reactos.git] / drivers / net / packet / dump.c
index e7c40fb..99f916b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2000
- *     Politecnico di Torino.  All rights reserved.
+ *  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
@@ -27,6 +27,8 @@
 #else
 #include <ddk/ntddk.h>
 #include <net/ndis.h>
+//#define PsGetCurrentProcess() IoGetCurrentProcess()
+#define PsGetCurrentThread() ((PETHREAD) (KeGetCurrentThread()))
 #endif
 
 #include "debug.h"
 NTSTATUS
 NPF_OpenDumpFile(POPEN_INSTANCE Open , PUNICODE_STRING fileName, BOOLEAN Append)
 {
-       NTSTATUS ntStatus;
-       IO_STATUS_BLOCK IoStatus;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       PWCHAR PathPrefix;
-       USHORT PathLen;
-       UNICODE_STRING FullFileName;
-       ULONG FullFileNameLength;
-       PDEVICE_OBJECT fsdDevice;
-
-       FILE_STANDARD_INFORMATION StandardInfo;
-       
+    NTSTATUS ntStatus;
+    IO_STATUS_BLOCK IoStatus;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PWCHAR PathPrefix;
+    USHORT PathLen;
+    UNICODE_STRING FullFileName;
+    ULONG FullFileNameLength;
+    PDEVICE_OBJECT fsdDevice;
+
+    FILE_STANDARD_INFORMATION StandardInfo;
+    
     IF_LOUD(DbgPrint("NPF: OpenDumpFile.\n");)
 
-       if(fileName->Buffer[0] == L'\\' &&
-               fileName->Buffer[1] == L'?' &&
-               fileName->Buffer[2] == L'?' &&
-               fileName->Buffer[3] == L'\\'
-       ){
-               PathLen = 0;
-       }
-       else{
-               PathPrefix = L"\\??\\";
-               PathLen = 8;
-       }
-       
-       // Insert the correct path prefix.
-       FullFileNameLength = PathLen + fileName->MaximumLength;
-       
-       FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, 
-               FullFileNameLength,
-               '0DWA');
-       
-       if (FullFileName.Buffer == NULL) {
-               ntStatus = STATUS_INSUFFICIENT_RESOURCES;
-               return ntStatus;
-       }
-       
-       FullFileName.Length = PathLen;
-       FullFileName.MaximumLength = (USHORT)FullFileNameLength;
-       
-       if(PathLen)
-               RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
-       
-       RtlAppendUnicodeStringToString (&FullFileName, fileName);
-       
-       IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
-       
-       InitializeObjectAttributes ( &ObjectAttributes,
-               &FullFileName,
-               OBJ_CASE_INSENSITIVE,
-               NULL,
-               NULL );
-       
-       // Create the dump file
-       ntStatus = ZwCreateFile( &Open->DumpFileHandle,
-               SYNCHRONIZE | FILE_WRITE_DATA,
-               &ObjectAttributes,
-               &IoStatus,
-               NULL,
-               FILE_ATTRIBUTE_NORMAL,
-               FILE_SHARE_READ,
-               (Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
-               FILE_SYNCHRONOUS_IO_NONALERT,
-               NULL,
-               0 );
+    if(fileName->Buffer[0] == L'\\' &&
+        fileName->Buffer[1] == L'?' &&
+        fileName->Buffer[2] == L'?' &&
+        fileName->Buffer[3] == L'\\'
+    ){
+        PathLen = 0;
+    }
+    else{
+        PathPrefix = L"\\??\\";
+        PathLen = 8;
+    }
+    
+    // Insert the correct path prefix.
+    FullFileNameLength = PathLen + fileName->MaximumLength;
+    
+#define NPF_TAG_FILENAME  TAG('0', 'D', 'W', 'A')
+    FullFileName.Buffer = ExAllocatePoolWithTag(NonPagedPool, 
+        FullFileNameLength,
+        NPF_TAG_FILENAME);
+    
+    if (FullFileName.Buffer == NULL) {
+        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+        return ntStatus;
+    }
+    
+    FullFileName.Length = PathLen;
+    FullFileName.MaximumLength = (USHORT)FullFileNameLength;
+    
+    if(PathLen)
+        RtlMoveMemory (FullFileName.Buffer, PathPrefix, PathLen);
+    
+    RtlAppendUnicodeStringToString (&FullFileName, fileName);
+    
+    IF_LOUD(DbgPrint( "Packet: Attempting to open %wZ\n", &FullFileName);)
+    
+    InitializeObjectAttributes ( &ObjectAttributes,
+        &FullFileName,
+        OBJ_CASE_INSENSITIVE,
+        NULL,
+        NULL );
+    
+    // Create the dump file
+    ntStatus = ZwCreateFile( &Open->DumpFileHandle,
+        SYNCHRONIZE | FILE_WRITE_DATA,
+        &ObjectAttributes,
+        &IoStatus,
+        NULL,
+        FILE_ATTRIBUTE_NORMAL,
+        FILE_SHARE_READ,
+        (Append)?FILE_OPEN_IF:FILE_SUPERSEDE,
+        FILE_SYNCHRONOUS_IO_NONALERT,
+        NULL,
+        0 );
 
     if ( !NT_SUCCESS( ntStatus ) )
     {
         IF_LOUD(DbgPrint("NPF: Error opening file %x\n", ntStatus);)
-               
+        
         ExFreePool(FullFileName.Buffer);
-               Open->DumpFileHandle=NULL;
+        Open->DumpFileHandle=NULL;
         ntStatus = STATUS_NO_SUCH_FILE;
         return ntStatus;
     }
-       
-       ExFreePool(FullFileName.Buffer);
-       
-       ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
-               FILE_WRITE_ACCESS,
+    
+    ExFreePool(FullFileName.Buffer);
+    
+    ntStatus = ObReferenceObjectByHandle(Open->DumpFileHandle,
+        FILE_WRITE_ACCESS,
 #ifndef __GNUC__
-               *IoFileObjectType,
+        *IoFileObjectType,
 #else
-               IoFileObjectType,
+        IoFileObjectType,
 #endif
-               KernelMode,
-               &Open->DumpFileObject,
-               0);
-       
+        KernelMode,
+        (PVOID)&Open->DumpFileObject,
+        0);
+    
     if ( !NT_SUCCESS( ntStatus ) )
     {
         IF_LOUD(DbgPrint("NPF: Error creating file, status=%x\n", ntStatus);)
-                       
-               ZwClose( Open->DumpFileHandle );
-               Open->DumpFileHandle=NULL;
-               
+            
+        ZwClose( Open->DumpFileHandle );
+        Open->DumpFileHandle=NULL;
+        
         ntStatus = STATUS_NO_SUCH_FILE;
         return ntStatus;
     }
-       
+    
     fsdDevice = IoGetRelatedDeviceObject(Open->DumpFileObject);
 
-       IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);)
+    IF_LOUD(DbgPrint("NPF: Dump: write file created succesfully, status=%d \n",ntStatus);)
 
-       return ntStatus;
-}      
+    return ntStatus;
+}   
 
 //-------------------------------------------------------------------
 
 NTSTATUS
 NPF_StartDump(POPEN_INSTANCE Open)
 {
-       NTSTATUS ntStatus;
-       struct packet_file_header hdr;
-       IO_STATUS_BLOCK IoStatus;
+    NTSTATUS ntStatus;
+    struct packet_file_header hdr;
+    IO_STATUS_BLOCK IoStatus;
     NDIS_REQUEST pRequest;
-       ULONG MediaType;
-       OBJECT_ATTRIBUTES ObjectAttributes;
+    ULONG MediaType;
+    OBJECT_ATTRIBUTES ObjectAttributes;
 
     IF_LOUD(DbgPrint("NPF: StartDump.\n");)
 
-       // Init the file header
-       hdr.magic = TCPDUMP_MAGIC;
-       hdr.version_major = PCAP_VERSION_MAJOR;
-       hdr.version_minor = PCAP_VERSION_MINOR;
-       hdr.thiszone = 0; /*Currently not set*/
-       hdr.snaplen = 1514;
-       hdr.sigfigs = 0;
-
-       // Detect the medium type
-       switch (Open->Medium){
-               
-       case NdisMediumWan:
-               hdr.linktype = DLT_EN10MB;
-               break;
-               
-       case NdisMedium802_3:
-               hdr.linktype = DLT_EN10MB;
-               break;
-               
-       case NdisMediumFddi:
-               hdr.linktype = DLT_FDDI;
-               break;
-               
-       case NdisMedium802_5:                   
-               hdr.linktype = DLT_IEEE802;     
-               break;
-               
-       case NdisMediumArcnet878_2:
-               hdr.linktype = DLT_ARCNET;
-               break;
-               
-       case NdisMediumAtm:
-               hdr.linktype = DLT_ATM_RFC1483;
-               break;
-               
-       default:
-               hdr.linktype = DLT_EN10MB;
-       }
-
-       // Write the header.
-       // We can use ZwWriteFile because we are in the context of the application
-       ntStatus = ZwWriteFile(Open->DumpFileHandle,
-               NULL,
-               NULL,
-               NULL,
-               &IoStatus,
-               &hdr,
-               sizeof(hdr),
-               NULL,
-               NULL );
-
-       
+    // Init the file header
+    hdr.magic = TCPDUMP_MAGIC;
+    hdr.version_major = PCAP_VERSION_MAJOR;
+    hdr.version_minor = PCAP_VERSION_MINOR;
+    hdr.thiszone = 0; /*Currently not set*/
+    hdr.snaplen = 1514;
+    hdr.sigfigs = 0;
+
+    // Detect the medium type
+    switch (Open->Medium){
+        
+    case NdisMediumWan:
+        hdr.linktype = DLT_EN10MB;
+        break;
+        
+    case NdisMedium802_3:
+        hdr.linktype = DLT_EN10MB;
+        break;
+        
+    case NdisMediumFddi:
+        hdr.linktype = DLT_FDDI;
+        break;
+        
+    case NdisMedium802_5:           
+        hdr.linktype = DLT_IEEE802; 
+        break;
+        
+    case NdisMediumArcnet878_2:
+        hdr.linktype = DLT_ARCNET;
+        break;
+        
+    case NdisMediumAtm:
+        hdr.linktype = DLT_ATM_RFC1483;
+        break;
+        
+    default:
+        hdr.linktype = DLT_EN10MB;
+    }
+
+    // Write the header.
+    // We can use ZwWriteFile because we are in the context of the application
+    ntStatus = ZwWriteFile(Open->DumpFileHandle,
+        NULL,
+        NULL,
+        NULL,
+        &IoStatus,
+        &hdr,
+        sizeof(hdr),
+        NULL,
+        NULL );
+
+    
     if ( !NT_SUCCESS( ntStatus ) )
     {
         IF_LOUD(DbgPrint("NPF: Error dumping file %x\n", ntStatus);)
-               
-               ZwClose( Open->DumpFileHandle );
-               Open->DumpFileHandle=NULL;
-               
+        
+        ZwClose( Open->DumpFileHandle );
+        Open->DumpFileHandle=NULL;
+        
         ntStatus = STATUS_NO_SUCH_FILE;
         return ntStatus;
     }
 
-       Open->DumpOffset.QuadPart=24;
-                       
-       ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle,
-               THREAD_ALL_ACCESS,
-               (ACCESS_MASK)0L,
-               0,
-               0,
-               NPF_DumpThread,
-               Open);
-       
+    Open->DumpOffset.QuadPart=24;
+            
+    ntStatus = PsCreateSystemThread(&Open->DumpThreadHandle,
+        THREAD_ALL_ACCESS,
+        (ACCESS_MASK)0L,
+        0,
+        0,
+        (PKSTART_ROUTINE)NPF_DumpThread,
+        Open);
+    
     if ( !NT_SUCCESS( ntStatus ) )
     {
         IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
-               
-               ZwClose( Open->DumpFileHandle );
-               Open->DumpFileHandle=NULL;
+        
+        ZwClose( Open->DumpFileHandle );
+        Open->DumpFileHandle=NULL;
 
         return ntStatus;
     }  
-#ifndef __GNUC__
-       ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
-               THREAD_ALL_ACCESS,
-               NULL,
-               KernelMode,
-               &Open->DumpThreadObject,
-               0);
-#else
-#endif
+    ntStatus = ObReferenceObjectByHandle(Open->DumpThreadHandle,
+        THREAD_ALL_ACCESS,
+        NULL,
+        KernelMode,
+        &Open->DumpThreadObject,
+        0);
     if ( !NT_SUCCESS( ntStatus ) )
     {
         IF_LOUD(DbgPrint("NPF: Error creating dump thread, status=%x\n", ntStatus);)
-               
-               ObDereferenceObject(Open->DumpFileObject);
-               ZwClose( Open->DumpFileHandle );
-               Open->DumpFileHandle=NULL;
+        
+        ObDereferenceObject(Open->DumpFileObject);
+        ZwClose( Open->DumpFileHandle );
+        Open->DumpFileHandle=NULL;
 
         return ntStatus;
     }  
-
-       
-       return ntStatus;
-       
+  
+    return ntStatus;
+    
 }
 
 //-------------------------------------------------------------------
@@ -272,245 +271,250 @@ NPF_StartDump(POPEN_INSTANCE Open)
 
 VOID NPF_DumpThread(POPEN_INSTANCE Open)
 {
-       ULONG           FrozenNic;
+    ULONG       FrozenNic;
 
     IF_LOUD(DbgPrint("NPF: In the work routine.  Parameter = 0x%0x\n",Open);)
 
-       while(TRUE){
-
-               // Wait until some packets arrive or the timeout expires
-               NdisWaitEvent(&Open->DumpEvent, 5000);  
-
-               IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");)
-                       
-               if(Open->DumpLimitReached ||
-                       Open->BufSize==0){              // BufSize=0 means that this instance was closed, or that the buffer is too
-                                                                       // small for any capture. In both cases it is better to end the dump
-
-                       IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
-                       IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
-
-                       PsTerminateSystemThread(STATUS_SUCCESS);
-                       return;
-               }
-               
-               NdisResetEvent(&Open->DumpEvent);
-
-               // Write the content of the buffer to the file
-               if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){
-                       PsTerminateSystemThread(STATUS_SUCCESS);
-                       return;
-               }
-       
-       }
-       
+    while(TRUE){
+
+        // Wait until some packets arrive or the timeout expires
+        NdisWaitEvent(&Open->DumpEvent, 5000);  
+
+        IF_LOUD(DbgPrint("NPF: Worker Thread - event signalled\n");)
+            
+        if(Open->DumpLimitReached ||
+            Open->BufSize==0){      // BufSize=0 means that this instance was closed, or that the buffer is too
+                                    // small for any capture. In both cases it is better to end the dump
+
+            IF_LOUD(DbgPrint("NPF: Worker Thread - Exiting happily\n");)
+            IF_LOUD(DbgPrint("Thread: Dumpoffset=%I64d\n",Open->DumpOffset.QuadPart);)
+
+            PsTerminateSystemThread(STATUS_SUCCESS);
+            return;
+        }
+        
+        NdisResetEvent(&Open->DumpEvent);
+
+        // Write the content of the buffer to the file
+        if(NPF_SaveCurrentBuffer(Open) != STATUS_SUCCESS){
+            PsTerminateSystemThread(STATUS_SUCCESS);
+            return;
+        }
+    
+    }
+    
 }
 
 //-------------------------------------------------------------------
 
 NTSTATUS NPF_SaveCurrentBuffer(POPEN_INSTANCE Open)
 {
-       UINT            Thead;
-       UINT            Ttail;
-       UINT            TLastByte;
-       PUCHAR          CurrBuff;
-       NTSTATUS        ntStatus;
-       IO_STATUS_BLOCK IoStatus;
-    PMDL               lMdl;
-       UINT            SizeToDump;
-
-       
-       Thead=Open->Bhead;
-       Ttail=Open->Btail;
-       TLastByte=Open->BLastByte;
-       
+    UINT        Thead;
+    UINT        Ttail;
+    UINT        TLastByte;
+    PUCHAR      CurrBuff;
+    NTSTATUS    ntStatus;
+    IO_STATUS_BLOCK IoStatus;
+    PMDL        lMdl;
+    UINT        SizeToDump;
+
+    
+    Thead=Open->Bhead;
+    Ttail=Open->Btail;
+    TLastByte=Open->BLastByte;
+    
     IF_LOUD(DbgPrint("NPF: NPF_SaveCurrentBuffer.\n");)
 
-       // Get the address of the buffer
-       CurrBuff=Open->Buffer;
-       //
-       // Fill the application buffer
-       //
-       if( Ttail < Thead )
-       {
-               if(Open->MaxDumpBytes &&
-                       (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
-               {
-                       // Size limit reached
-                       UINT PktLen;
-                       
-                       SizeToDump = 0;
-                       
-                       // Scan the buffer to detect the exact amount of data to save
-                       while(TRUE){
-                               PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
-                               
-                               if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
-                                       break;
-                               
-                               SizeToDump += PktLen;
-                       }
-                       
-               }
-               else
-                       SizeToDump = TLastByte-Thead;
-               
-               lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
-               if (lMdl == NULL)
-               {
-                       // No memory: stop dump
-                       IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               MmBuildMdlForNonPagedPool(lMdl);
-               
-               // Write to disk
-               NPF_WriteDumpFile(Open->DumpFileObject,
-                       &Open->DumpOffset,
-                       SizeToDump,
-                       lMdl,
-                       &IoStatus);
-               
-               IoFreeMdl(lMdl);
-               
-               if(!NT_SUCCESS(IoStatus.Status)){
-                       // Error
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               if(SizeToDump != TLastByte-Thead){
-                       // Size limit reached.
-                       Open->DumpLimitReached = TRUE;
-       
-                       // Awake the application
-                       KeSetEvent(Open->ReadEvent,0,FALSE);
-
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               // Update the packet buffer
-               Open->DumpOffset.QuadPart+=(TLastByte-Thead);
-               Open->BLastByte=Ttail;
-               Open->Bhead=0;
-       }
-
-       if( Ttail > Thead ){
-               
-               if(Open->MaxDumpBytes &&
-                       (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
-               {
-                       // Size limit reached
-                       UINT PktLen;
-                                               
-                       SizeToDump = 0;
-                       
-                       // Scan the buffer to detect the exact amount of data to save
-                       while(Thead + SizeToDump < Ttail){
-
-                               PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
-                               
-                               if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
-                                       break;
-                               
-                               SizeToDump += PktLen;
-                       }
-                       
-               }
-               else
-                       SizeToDump = Ttail-Thead;
-                               
-               lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
-               if (lMdl == NULL)
-               {
-                       // No memory: stop dump
-                       IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               MmBuildMdlForNonPagedPool(lMdl);
-               
-               // Write to disk
-               NPF_WriteDumpFile(Open->DumpFileObject,
-                       &Open->DumpOffset,
-                       SizeToDump,
-                       lMdl,
-                       &IoStatus);
-               
-               IoFreeMdl(lMdl);
-               
-               if(!NT_SUCCESS(IoStatus.Status)){
-                       // Error
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               if(SizeToDump != Ttail-Thead){
-                       // Size limit reached.
-                       Open->DumpLimitReached = TRUE;
-
-                       // Awake the application
-                       KeSetEvent(Open->ReadEvent,0,FALSE);
-                       
-                       return STATUS_UNSUCCESSFUL;
-               }
-               
-               // Update the packet buffer
-               Open->DumpOffset.QuadPart+=(Ttail-Thead);                       
-               Open->Bhead=Ttail;
-               
-       }
-
-       return STATUS_SUCCESS;
+    // Get the address of the buffer
+    CurrBuff=Open->Buffer;
+    //
+    // Fill the application buffer
+    //
+    if( Ttail < Thead )
+    {
+        if(Open->MaxDumpBytes &&
+            (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
+        {
+            // Size limit reached
+            UINT PktLen;
+            
+            SizeToDump = 0;
+            
+            // Scan the buffer to detect the exact amount of data to save
+            while(TRUE){
+                PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
+                
+                if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
+                    break;
+                
+                SizeToDump += PktLen;
+            }
+            
+        }
+        else
+            SizeToDump = TLastByte-Thead;
+        
+        lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
+        if (lMdl == NULL)
+        {
+            // No memory: stop dump
+            IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        MmBuildMdlForNonPagedPool(lMdl);
+        
+        // Write to disk
+        NPF_WriteDumpFile(Open->DumpFileObject,
+            &Open->DumpOffset,
+            SizeToDump,
+            lMdl,
+            &IoStatus);
+        
+        IoFreeMdl(lMdl);
+        
+        if(!NT_SUCCESS(IoStatus.Status)){
+            // Error
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        if(SizeToDump != TLastByte-Thead){
+            // Size limit reached.
+            Open->DumpLimitReached = TRUE;
+    
+            // Awake the application
+            KeSetEvent(Open->ReadEvent,0,FALSE);
+
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        // Update the packet buffer
+        Open->DumpOffset.QuadPart+=(TLastByte-Thead);
+        Open->BLastByte=Ttail;
+        Open->Bhead=0;
+    }
+
+    if( Ttail > Thead ){
+        
+        if(Open->MaxDumpBytes &&
+            (UINT)Open->DumpOffset.QuadPart + GetBuffOccupation(Open) > Open->MaxDumpBytes)
+        {
+            // Size limit reached
+            UINT PktLen;
+                        
+            SizeToDump = 0;
+            
+            // Scan the buffer to detect the exact amount of data to save
+            while(Thead + SizeToDump < Ttail){
+
+                PktLen = ((struct sf_pkthdr*)(CurrBuff + Thead + SizeToDump))->caplen + sizeof(struct sf_pkthdr);
+                
+                if((UINT)Open->DumpOffset.QuadPart + SizeToDump + PktLen > Open->MaxDumpBytes)
+                    break;
+                
+                SizeToDump += PktLen;
+            }
+            
+        }
+        else
+            SizeToDump = Ttail-Thead;
+                
+        lMdl=IoAllocateMdl(CurrBuff+Thead, SizeToDump, FALSE, FALSE, NULL);
+        if (lMdl == NULL)
+        {
+            // No memory: stop dump
+            IF_LOUD(DbgPrint("NPF: dump thread: Failed to allocate Mdl\n");)
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        MmBuildMdlForNonPagedPool(lMdl);
+        
+        // Write to disk
+        NPF_WriteDumpFile(Open->DumpFileObject,
+            &Open->DumpOffset,
+            SizeToDump,
+            lMdl,
+            &IoStatus);
+        
+        IoFreeMdl(lMdl);
+        
+        if(!NT_SUCCESS(IoStatus.Status)){
+            // Error
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        if(SizeToDump != Ttail-Thead){
+            // Size limit reached.
+            Open->DumpLimitReached = TRUE;
+
+            // Awake the application
+            KeSetEvent(Open->ReadEvent,0,FALSE);
+            
+            return STATUS_UNSUCCESSFUL;
+        }
+        
+        // Update the packet buffer
+        Open->DumpOffset.QuadPart+=(Ttail-Thead);           
+        Open->Bhead=Ttail;
+        
+    }
+
+    return STATUS_SUCCESS;
 }
 
 //-------------------------------------------------------------------
 
 NTSTATUS NPF_CloseDumpFile(POPEN_INSTANCE Open){
-       NTSTATUS        ntStatus;
-       IO_STATUS_BLOCK IoStatus;
-    PMDL               WriteMdl;
-    PUCHAR             VMBuff;
-       UINT            VMBufLen;
+    NTSTATUS    ntStatus;
+    IO_STATUS_BLOCK IoStatus;
+    PMDL        WriteMdl;
+    PUCHAR      VMBuff;
+    UINT        VMBufLen;
 
 
     IF_LOUD(DbgPrint("NPF: NPF_CloseDumpFile.\n");)
     IF_LOUD(DbgPrint("Dumpoffset=%d\n",Open->DumpOffset.QuadPart);)
 
 DbgPrint("1\n");
-       // Consistency check
-       if(Open->DumpFileHandle == NULL)
-               return STATUS_UNSUCCESSFUL;
+    // Consistency check
+    if(Open->DumpFileHandle == NULL)
+        return STATUS_UNSUCCESSFUL;
 
 DbgPrint("2\n");
-       ZwClose( Open->DumpFileHandle );
+    ZwClose( Open->DumpFileHandle );
 
-       ObDereferenceObject(Open->DumpFileObject);
+    ObDereferenceObject(Open->DumpFileObject);
 /*
-       if(Open->DumpLimitReached == TRUE)
-               // Limit already reached: don't save the rest of the buffer.
-               return STATUS_SUCCESS;
+    if(Open->DumpLimitReached == TRUE)
+        // Limit already reached: don't save the rest of the buffer.
+        return STATUS_SUCCESS;
 */
 DbgPrint("3\n");
 
-       NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE);
+    NPF_OpenDumpFile(Open,&Open->DumpFileName, TRUE);
 
-       // Flush the buffer to file 
-       NPF_SaveCurrentBuffer(Open);
+    // Flush the buffer to file 
+    NPF_SaveCurrentBuffer(Open);
 
-       // Close The file
-       ObDereferenceObject(Open->DumpFileObject);
-       ZwClose( Open->DumpFileHandle );
-       
-       Open->DumpFileHandle = NULL;
+    // Close The file
+    ObDereferenceObject(Open->DumpFileObject);
+    ZwClose( Open->DumpFileHandle );
+    
+    Open->DumpFileHandle = NULL;
 
-       ObDereferenceObject(Open->DumpFileObject);
+    ObDereferenceObject(Open->DumpFileObject);
 
-       return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 //-------------------------------------------------------------------
 
-static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
+#ifndef __GNUC__
+static NTSTATUS 
+#else
+NTSTATUS STDCALL
+#endif
+PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
                                 PIRP Irp,
                                 PVOID Context)
 {
@@ -527,10 +531,10 @@ static NTSTATUS PacketDumpCompletion(PDEVICE_OBJECT DeviceObject,
 //-------------------------------------------------------------------
 
 VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
-                                           PLARGE_INTEGER Offset,
-                                                               ULONG Length,
-                                                               PMDL Mdl,
-                                                               PIO_STATUS_BLOCK IoStatusBlock)
+                                PLARGE_INTEGER Offset,
+                                ULONG Length,
+                                PMDL Mdl,
+                                PIO_STATUS_BLOCK IoStatusBlock)
 {
     PIRP irp;
     KEVENT event;
@@ -549,33 +553,33 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
         IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
         IoStatusBlock->Information = 0;
 
-               return;
+        return;
     }
-    
+
     irp->MdlAddress = Mdl;
     irp->UserEvent = &event;
     irp->UserIosb = IoStatusBlock;
     irp->Tail.Overlay.Thread = PsGetCurrentThread();
-    irp->Tail.Overlay.OriginalFileObject= FileObject;    
+    irp->Tail.Overlay.OriginalFileObject= FileObject;
     irp->RequestorMode = KernelMode;
-    
+
     // Indicate that this is a WRITE operation
-    irp->Flags = IRP_WRITE_OPERATION;    
-    
+    irp->Flags = IRP_WRITE_OPERATION;
+
     // Set up the next I/O stack location
     ioStackLocation = IoGetNextIrpStackLocation(irp);
     ioStackLocation->MajorFunction = IRP_MJ_WRITE;
     ioStackLocation->MinorFunction = 0;
     ioStackLocation->DeviceObject = fsdDevice;
     ioStackLocation->FileObject = FileObject;
-    IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE);    
-    ioStackLocation->Parameters.Write.Length = Length;    
+    IoSetCompletionRoutine(irp, PacketDumpCompletion, 0, TRUE, TRUE, TRUE);
+    ioStackLocation->Parameters.Write.Length = Length;
     ioStackLocation->Parameters.Write.ByteOffset = *Offset;
-    
+
 
     // Send it on.  Ignore the return code
     (void) IoCallDriver(fsdDevice, irp);
-     
+
     // Wait for the I/O to complete.
     KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
 
@@ -583,5 +587,4 @@ VOID NPF_WriteDumpFile(PFILE_OBJECT FileObject,
     IoFreeIrp(irp);
 
     return;
-
 }