Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

Packet.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999 - 2003
00003  * NetGroup, Politecnico di Torino (Italy)
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  * notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  * notice, this list of conditions and the following disclaimer in the
00014  * documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Politecnico di Torino nor the names of its
00016  * contributors may be used to endorse or promote products derived from
00017  * this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 #include "stdarg.h"
00034 #include "ntddk.h"
00035 #include "ntiologc.h"
00036 #include "ndis.h"
00037 
00038 #include "ntddpack.h"
00039 
00040 #include "debug.h"
00041 #include "packet.h"
00042 #include "win_bpf.h"
00043 #include "win_bpf_filter_init.h"
00044 
00045 #include "tme.h"
00046 
00047 #if DBG
00048 // Declare the global debug flag for this driver.
00049 ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;
00050 
00051 #endif
00052 
00053 PDEVICE_EXTENSION GlobalDeviceExtension;
00054 
00055 //
00056 // Global strings
00057 //
00058 NDIS_STRING NPF_Prefix = NDIS_STRING_CONST("NPF_");
00059 NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\");
00060 NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\");
00061 NDIS_STRING tcpLinkageKeyName = NDIS_STRING_CONST("\\Registry\\Machine\\System"
00062                                 L"\\CurrentControlSet\\Services\\Tcpip\\Linkage");
00063 NDIS_STRING AdapterListKey = NDIS_STRING_CONST("\\Registry\\Machine\\System"
00064                                 L"\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
00065 NDIS_STRING bindValueName = NDIS_STRING_CONST("Bind");
00066 
00068 WCHAR* bindP = NULL;
00069 
00070 extern struct time_conv G_Start_Time; // from openclos.c
00071 
00072 extern NDIS_SPIN_LOCK Opened_Instances_Lock;
00073 
00074 ULONG NCpu;
00075 
00076 ULONG TimestampMode;
00077 
00078 //
00079 //  Packet Driver's entry routine.
00080 //
00081 NTSTATUS
00082 DriverEntry(
00083     IN PDRIVER_OBJECT DriverObject,
00084     IN PUNICODE_STRING RegistryPath
00085     )
00086 {
00087 
00088     NDIS_PROTOCOL_CHARACTERISTICS  ProtocolChar;
00089     UNICODE_STRING MacDriverName;
00090     UNICODE_STRING UnicodeDeviceName;
00091     PDEVICE_OBJECT DeviceObject = NULL;
00092     PDEVICE_EXTENSION DeviceExtension = NULL;
00093     NTSTATUS Status = STATUS_SUCCESS;
00094     NTSTATUS ErrorCode = STATUS_SUCCESS;
00095     NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver");
00096     ULONG          DevicesCreated=0;
00097     PWSTR          BindString;
00098     PWSTR          ExportString;
00099     PWSTR          BindStringSave;
00100     PWSTR          ExportStringSave;
00101     NDIS_HANDLE    NdisProtocolHandle;
00102     WCHAR* bindT;
00103     PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
00104     UNICODE_STRING macName;
00105     
00106     
00107     ReadTimeStampModeFromRegistry(RegistryPath);
00108 
00109 DbgPrint("%ws",RegistryPath->Buffer);
00110 
00111     NCpu = NdisSystemProcessorCount();
00112 
00113     IF_LOUD(DbgPrint("\n\nPacket: DriverEntry\n");)
00114 
00115     RtlZeroMemory(&ProtocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
00116 
00117 #ifdef NDIS50
00118     ProtocolChar.MajorNdisVersion            = 5;
00119 #else
00120     ProtocolChar.MajorNdisVersion            = 3;
00121 #endif
00122     ProtocolChar.MinorNdisVersion            = 0;
00123     ProtocolChar.Reserved                    = 0;
00124     ProtocolChar.OpenAdapterCompleteHandler  = NPF_OpenAdapterComplete;
00125     ProtocolChar.CloseAdapterCompleteHandler = NPF_CloseAdapterComplete;
00126     ProtocolChar.SendCompleteHandler         = NPF_SendComplete;
00127     ProtocolChar.TransferDataCompleteHandler = NPF_TransferDataComplete;
00128     ProtocolChar.ResetCompleteHandler        = NPF_ResetComplete;
00129     ProtocolChar.RequestCompleteHandler      = NPF_RequestComplete;
00130     ProtocolChar.ReceiveHandler              = NPF_tap;
00131     ProtocolChar.ReceiveCompleteHandler      = NPF_ReceiveComplete;
00132     ProtocolChar.StatusHandler               = NPF_Status;
00133     ProtocolChar.StatusCompleteHandler       = NPF_StatusComplete;
00134 #ifdef NDIS50
00135     ProtocolChar.BindAdapterHandler          = NPF_BindAdapter;
00136     ProtocolChar.UnbindAdapterHandler        = NPF_UnbindAdapter;
00137     ProtocolChar.PnPEventHandler             = NPF_PowerChange;
00138     ProtocolChar.ReceivePacketHandler        = NULL;
00139 #endif
00140     ProtocolChar.Name                        = ProtoName;
00141 
00142     NdisRegisterProtocol(
00143         &Status,
00144         &NdisProtocolHandle,
00145         &ProtocolChar,
00146         sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
00147 
00148     if (Status != NDIS_STATUS_SUCCESS) {
00149 
00150         IF_LOUD(DbgPrint("NPF: Failed to register protocol with NDIS\n");)
00151 
00152         return Status;
00153 
00154     }
00155     
00156     NdisAllocateSpinLock(&Opened_Instances_Lock);
00157 
00158     // Set up the device driver entry points.
00159     DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_Open;
00160     DriverObject->MajorFunction[IRP_MJ_CLOSE]  = NPF_Close;
00161     DriverObject->MajorFunction[IRP_MJ_READ]   = NPF_Read;
00162     DriverObject->MajorFunction[IRP_MJ_WRITE]  = NPF_Write;
00163     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = NPF_IoControl;
00164     DriverObject->DriverUnload = NPF_Unload;
00165 
00166     bindP = getAdaptersList();
00167 
00168     if (bindP == NULL) 
00169     {
00170         IF_LOUD(DbgPrint("Adapters not found in the registry, try to copy the bindings of TCP-IP.\n");)
00171 
00172         tcpBindingsP = getTcpBindings();
00173             
00174         if (tcpBindingsP == NULL)
00175         {
00176             IF_LOUD(DbgPrint("TCP-IP not found, quitting.\n");)
00177             goto RegistryError;
00178         }
00179             
00180         bindP = (WCHAR*)tcpBindingsP;
00181         bindT = (WCHAR*)(tcpBindingsP->Data);
00182             
00183     }
00184     else 
00185     {
00186         bindT = bindP;
00187     }
00188 
00189     for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) 
00190     {
00191         RtlInitUnicodeString(&macName, bindT);
00192         createDevice(DriverObject, &macName, NdisProtocolHandle);
00193     }
00194 
00195     return STATUS_SUCCESS;
00196 
00197 RegistryError:
00198 
00199     NdisDeregisterProtocol(
00200         &Status,
00201         NdisProtocolHandle
00202         );
00203 
00204     Status=STATUS_UNSUCCESSFUL;
00205 
00206     return(Status);
00207 
00208 }
00209 
00210 //-------------------------------------------------------------------
00211 
00212 PWCHAR getAdaptersList(void)
00213 {
00214     PKEY_VALUE_PARTIAL_INFORMATION result = NULL;
00215     OBJECT_ATTRIBUTES objAttrs;
00216     NTSTATUS status;
00217     HANDLE keyHandle;
00218     UINT BufPos=0;
00219     UINT BufLen=4096;
00220 
00221     
00222     PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, BufLen, '0PWA');
00223     
00224     if (DeviceNames == NULL) {
00225         IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");)
00226             return NULL;
00227     }
00228     
00229     InitializeObjectAttributes(&objAttrs, &AdapterListKey,
00230         OBJ_CASE_INSENSITIVE, NULL, NULL);
00231     status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
00232     if (!NT_SUCCESS(status)) {
00233         IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
00234     }
00235     else { //OK
00236         
00237         ULONG resultLength;
00238         KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00239         CHAR AdapInfo[1024];
00240         UINT i=0;
00241         
00242         IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%x\n",DeviceNames);)
00243             
00244             // Scan the list of the devices
00245             while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS)
00246             {
00247                 WCHAR ExportKeyName [512];
00248                 PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
00249                 UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
00250                 PWCHAR LinkageKeyPrefix = L"\\Linkage";
00251                 UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage");
00252                 NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export");
00253                 PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo;
00254                 UNICODE_STRING AdapterKeyName;
00255                 HANDLE ExportKeyHandle;
00256                 KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00257                 ULONG resultLength;
00258                 
00259                 RtlCopyMemory(ExportKeyName,
00260                     ExportKeyPrefix,
00261                     ExportKeyPrefixSize);
00262                 
00263                 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize,
00264                     tInfo->Name,
00265                     tInfo->NameLength+2);
00266                 
00267                 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength,
00268                     LinkageKeyPrefix,
00269                     LinkageKeyPrefixSize);
00270                 
00271                 IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);)
00272                                         
00273                 RtlInitUnicodeString(&AdapterKeyName, ExportKeyName);
00274                 
00275                 InitializeObjectAttributes(&objAttrs, &AdapterKeyName,
00276                     OBJ_CASE_INSENSITIVE, NULL, NULL);
00277                 
00278                 status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs);
00279                 
00280                 if (!NT_SUCCESS(status)) {
00281                     DbgPrint("OpenKey Failed, %d!\n",status);
00282                     i++;
00283                     continue;
00284                 }
00285                 
00286                 status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
00287                     KeyValuePartialInformation, &valueInfo,
00288                     sizeof(valueInfo), &resultLength);
00289                 
00290                 if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
00291                     IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
00292                 }
00293                 else {                      // We know how big it needs to be.
00294                     ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
00295                     PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, '1PWA');
00296                     if (valueInfoP != NULL) {
00297                         status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
00298                             KeyValuePartialInformation,
00299                             valueInfoP,
00300                             valueInfoLength, &resultLength);
00301                         if (!NT_SUCCESS(status)) {
00302                             IF_LOUD(DbgPrint("Status of %x querying key value\n", status);)
00303                         }
00304                         else{
00305                             IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);)
00306                                 if( BufPos + valueInfoP->DataLength > BufLen ) {
00307                                     // double the buffer size
00308                                     PWCHAR DeviceNames2 = (PWCHAR) ExAllocatePoolWithTag(PagedPool, BufLen
00309                                         << 1, '0PWA');
00310                                     if( DeviceNames2 ) {
00311                                         RtlCopyMemory((PCHAR)DeviceNames2, (PCHAR)DeviceNames, BufLen);
00312                                         BufLen <<= 1;
00313                                         ExFreePool(DeviceNames);
00314                                         DeviceNames = DeviceNames2;
00315                                     }
00316                                 } 
00317                                 if( BufPos + valueInfoP->DataLength < BufLen ) {
00318                                     RtlCopyMemory((PCHAR)DeviceNames+BufPos,
00319                                         valueInfoP->Data,
00320                                         valueInfoP->DataLength);
00321                                     BufPos+=valueInfoP->DataLength-2;
00322                                 }
00323                         }
00324                         
00325                         ExFreePool(valueInfoP);
00326                     }
00327                     else {
00328                         IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");)
00329                     }
00330                     
00331                 }
00332                 
00333                 // terminate the buffer
00334                 DeviceNames[BufPos/2]=0;
00335                 DeviceNames[BufPos/2+1]=0;
00336                 
00337                 ZwClose (ExportKeyHandle);
00338                 i++;
00339                 
00340             }
00341             
00342             ZwClose (keyHandle);
00343             
00344     }
00345     if(BufPos==0){
00346         ExFreePool(DeviceNames);
00347         return NULL;
00348     }
00349     return DeviceNames;
00350 }
00351 
00352 //-------------------------------------------------------------------
00353 
00354 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
00355 {
00356   PKEY_VALUE_PARTIAL_INFORMATION result = NULL;
00357   OBJECT_ATTRIBUTES objAttrs;
00358   NTSTATUS status;
00359   HANDLE keyHandle;
00360 
00361   InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName,
00362                              OBJ_CASE_INSENSITIVE, NULL, NULL);
00363   status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
00364   if (!NT_SUCCESS(status)) {
00365     IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
00366   }
00367   else {
00368     ULONG resultLength;
00369     KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00370 
00371     IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);)
00372 
00373     status = ZwQueryValueKey(keyHandle, &bindValueName,
00374                              KeyValuePartialInformation, &valueInfo,
00375                              sizeof(valueInfo), &resultLength);
00376     if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
00377       IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
00378     }
00379     else {                      // We know how big it needs to be.
00380       ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
00381       PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =
00382         (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, '2PWA');
00383       
00384       if (valueInfoP != NULL) {
00385         status = ZwQueryValueKey(keyHandle, &bindValueName,
00386                                  KeyValuePartialInformation,
00387                                  valueInfoP,
00388                                  valueInfoLength, &resultLength);
00389       
00390         if (!NT_SUCCESS(status)) {
00391           IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);)
00392         }
00393         else if (valueInfoLength != resultLength) {
00394           IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u "
00395                      "but previous len = %u\n",
00396                      resultLength, valueInfoLength);)
00397         }
00398         else if (valueInfoP->Type != REG_MULTI_SZ) {
00399           IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n",
00400                      valueInfoP->Type);)
00401         }
00402         else {                  // It's OK
00403 #if DBG
00404           ULONG i;
00405           WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]);
00406           IF_LOUD(DbgPrint("\n\nBind value:\n");)
00407           for (i = 0; *dataP != UNICODE_NULL; i++) {
00408             UNICODE_STRING macName;
00409             RtlInitUnicodeString(&macName, dataP);
00410             IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);)
00411             dataP +=
00412               (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
00413           }
00414 #endif // DBG
00415           result = valueInfoP;
00416         }
00417       }
00418     }
00419     ZwClose(keyHandle);
00420   }
00421   return result;
00422 }
00423 
00424 //-------------------------------------------------------------------
00425 
00426 BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
00427                      IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)
00428 {
00429     NTSTATUS status;
00430     PDEVICE_OBJECT devObjP;
00431     UNICODE_STRING deviceName;
00432     UNICODE_STRING deviceSymLink;
00433 
00434     IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
00435     if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
00436         devicePrefix.Length) < devicePrefix.Length) 
00437     {
00438         return FALSE;
00439     }
00440 
00441     deviceName.Length = 0;
00442     deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
00443     deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA');
00444 
00445     if (deviceName.Buffer == NULL)
00446         return FALSE;
00447 
00448     deviceSymLink.Length = 0;
00449     deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length 
00450         + symbolicLinkPrefix.Length 
00451         + NPF_Prefix.Length 
00452         + sizeof(UNICODE_NULL));
00453 
00454     deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA');
00455 
00456     if (deviceSymLink.Buffer  == NULL)
00457     {
00458         ExFreePool(deviceName.Buffer);
00459         return FALSE;
00460     }
00461 
00462     RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
00463     RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix);
00464     RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
00465         devicePrefix.Length / sizeof(WCHAR));
00466 
00467     RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
00468     RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix);
00469     RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
00470         devicePrefix.Length / sizeof(WCHAR));
00471 
00472     IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)
00473 
00474         status = IoCreateDevice(adriverObjectP, 
00475         sizeof(DEVICE_EXTENSION),
00476         &deviceName, 
00477         FILE_DEVICE_TRANSPORT, 
00478         0, 
00479         FALSE,
00480         &devObjP);
00481 
00482     if (NT_SUCCESS(status)) 
00483     {
00484         PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
00485         
00486         IF_LOUD(DbgPrint("Device created successfully\n"););
00487 
00488         devObjP->Flags |= DO_DIRECT_IO;
00489         RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);   
00490         devExtP->NdisProtocolHandle=aProtoHandle;
00491 
00492         IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););
00493 
00494         if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS)
00495         {
00496             IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););
00497 
00498             ExFreePool(deviceName.Buffer);
00499             ExFreePool(deviceSymLink.Buffer);
00500 
00501             devExtP->ExportString = NULL;
00502 
00503             return FALSE;
00504         }
00505 
00506         IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););
00507 
00508         devExtP->ExportString = deviceSymLink.Buffer;
00509 
00510         ExFreePool(deviceName.Buffer);
00511 
00512         return TRUE;
00513     }
00514 
00515     else 
00516     {
00517         IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
00518 
00519         ExFreePool(deviceName.Buffer);
00520         ExFreePool(deviceSymLink.Buffer);
00521         
00522         return FALSE;
00523     }
00524 }
00525 //-------------------------------------------------------------------
00526 
00527 VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject)
00528 {
00529     PDEVICE_OBJECT     DeviceObject;
00530     PDEVICE_OBJECT     OldDeviceObject;
00531     PDEVICE_EXTENSION  DeviceExtension;
00532 
00533     NDIS_HANDLE        NdisProtocolHandle;
00534     NDIS_STATUS        Status;
00535 
00536     NDIS_STRING        SymLink;
00537 
00538     IF_LOUD(DbgPrint("NPF: Unload\n"););
00539 
00540     DeviceObject    = DriverObject->DeviceObject;
00541 
00542     while (DeviceObject != NULL) {
00543         OldDeviceObject = DeviceObject;
00544 
00545         DeviceObject = DeviceObject->NextDevice;
00546 
00547         DeviceExtension = OldDeviceObject->DeviceExtension;
00548 
00549         NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
00550 
00551         IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
00552             DeviceExtension->AdapterName.Buffer,
00553             NdisProtocolHandle,
00554             DeviceObject,
00555             OldDeviceObject););
00556 
00557         if (DeviceExtension->ExportString)
00558         {
00559             RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
00560 
00561             IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
00562 
00563             IoDeleteSymbolicLink(&SymLink);
00564             ExFreePool(DeviceExtension->ExportString);
00565         }
00566 
00567         IoDeleteDevice(OldDeviceObject);
00568     }
00569 
00570     NdisDeregisterProtocol(
00571         &Status,
00572         NdisProtocolHandle
00573         );
00574 
00575     // Free the adapters names
00576     ExFreePool( bindP );
00577 }
00578 
00579 //-------------------------------------------------------------------
00580 
00581 NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
00582 {
00583     POPEN_INSTANCE      Open;
00584     PIO_STACK_LOCATION  IrpSp;
00585     PLIST_ENTRY         RequestListEntry;
00586     PINTERNAL_REQUEST   pRequest;
00587     ULONG               FunctionCode;
00588     NDIS_STATUS         Status;
00589     PLIST_ENTRY         PacketListEntry;
00590     UINT                i;
00591     PUCHAR              tpointer;
00592     ULONG               dim,timeout;
00593     PUCHAR              prog;
00594     PPACKET_OID_DATA    OidData;
00595     int                 *StatsBuf;
00596     PNDIS_PACKET        pPacket;
00597     ULONG               mode;
00598     PWSTR               DumpNameBuff;
00599     PUCHAR              TmpBPFProgram;
00600     INT                 WriteRes;
00601     BOOLEAN             SyncWrite = FALSE;
00602     struct bpf_insn     *initprogram;
00603     ULONG               insns;
00604     ULONG               cnt;
00605     BOOLEAN             IsExtendedFilter=FALSE;
00606 
00607     BOOLEAN             Flag;
00608 
00609     IF_LOUD(DbgPrint("NPF: IoControl\n");)
00610         
00611     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00612     FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
00613     Open=IrpSp->FileObject->FsContext;
00614 
00615     Irp->IoStatus.Status = STATUS_SUCCESS;
00616 
00617     IF_LOUD(DbgPrint("NPF: Function code is %08lx  buff size=%08lx  %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
00618 
00619     switch (FunctionCode){
00620         
00621     case BIOCGSTATS: //function to get the capture stats
00622         
00623         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){           
00624             EXIT_FAILURE(0);
00625         }
00626 
00627         *(((PUINT)Irp->UserBuffer)+3) = 0;
00628         *(((PUINT)Irp->UserBuffer)+0) = 0;
00629         *(((PUINT)Irp->UserBuffer)+1) = 0;
00630         *(((PUINT)Irp->UserBuffer)+2) = 0;      // Not yet supported
00631 
00632         for(i=0;i<NCpu;i++)
00633         {
00634 
00635             *(((PUINT)Irp->UserBuffer)+3) += Open->CpuData[i].Accepted;
00636             *(((PUINT)Irp->UserBuffer)+0) += Open->CpuData[i].Received;
00637             *(((PUINT)Irp->UserBuffer)+1) += Open->CpuData[i].Dropped;
00638             *(((PUINT)Irp->UserBuffer)+2) += 0;     // Not yet supported
00639         }
00640         EXIT_SUCCESS(4*sizeof(INT));
00641         
00642         break;
00643         
00644     case BIOCGEVNAME: //function to get the name of the event associated with the current instance
00645 
00646         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){            
00647             EXIT_FAILURE(0);
00648         }
00649 
00650         RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26);
00651 
00652         EXIT_SUCCESS(26);
00653 
00654         break;
00655 
00656     case BIOCSENDPACKETSSYNC:
00657 
00658         SyncWrite = TRUE;
00659 
00660     case BIOCSENDPACKETSNOSYNC:
00661         
00662         NdisAcquireSpinLock(&Open->WriteLock);
00663         if(Open->WriteInProgress)
00664         {
00665             // Another write operation is currently in progress
00666             EXIT_FAILURE(0);
00667         }
00668         else
00669         {
00670             Open->WriteInProgress = TRUE;
00671         }
00672         NdisReleaseSpinLock(&Open->WriteLock);
00673         
00674         WriteRes = NPF_BufferedWrite(Irp,
00675             (PUCHAR)Irp->AssociatedIrp.SystemBuffer,
00676             IrpSp->Parameters.DeviceIoControl.InputBufferLength,
00677             SyncWrite);
00678 
00679         NdisAcquireSpinLock(&Open->WriteLock);
00680         Open->WriteInProgress = FALSE;
00681         NdisReleaseSpinLock(&Open->WriteLock);
00682 
00683         if( WriteRes != -1)
00684         {
00685             EXIT_SUCCESS(WriteRes);
00686         }
00687         
00688         EXIT_FAILURE(WriteRes);
00689 
00690         break;
00691 
00692     case BIOCSETF:  
00693 
00694         Open->SkipProcessing = 1;
00695 
00696         do
00697         {
00698             Flag = FALSE;
00699             for(i=0;i<NCpu;i++)
00700                 if (Open->CpuData[i].Processing == 1)
00701                     Flag = TRUE;
00702         }
00703         while(Flag);  //BUSY FORM WAITING...
00704 
00705 
00706         // Free the previous buffer if it was present
00707         if(Open->bpfprogram!=NULL){
00708             TmpBPFProgram=Open->bpfprogram;
00709             Open->bpfprogram = NULL;
00710             ExFreePool(TmpBPFProgram);
00711         }
00712         
00713         if (Open->Filter!=NULL)
00714         {
00715             JIT_BPF_Filter *OldFilter=Open->Filter;
00716             Open->Filter=NULL;
00717             BPF_Destroy_JIT_Filter(OldFilter);
00718         }
00719         
00720         // Get the pointer to the new program
00721         prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
00722         
00723         if(prog==NULL)
00724         {
00725             Open->SkipProcessing = 0;
00726             EXIT_FAILURE(0);
00727         }
00728         
00729         insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
00730         
00731         //count the number of operative instructions
00732         for (cnt=0;(cnt<insns) &&(((struct bpf_insn*)prog)[cnt].code!=BPF_SEPARATION); cnt++);
00733         
00734         IF_LOUD(DbgPrint("Operative instructions=%u\n",cnt);)
00735 
00736         if ( cnt != insns && insns != cnt+1 && ((struct bpf_insn*)prog)[cnt].code == BPF_SEPARATION ) 
00737         {
00738             IF_LOUD(DbgPrint("Initialization instructions=%u\n",insns-cnt-1);)
00739     
00740             IsExtendedFilter=TRUE;
00741 
00742             initprogram=&((struct bpf_insn*)prog)[cnt+1];
00743             
00744             if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
00745             {
00746             
00747                 IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");)
00748                 
00749                 Open->SkipProcessing = 0;
00750                 EXIT_FAILURE(0);
00751             }
00752         }
00753 
00754         //the NPF processor has been initialized, we have to validate the operative instructions
00755         insns=cnt;
00756         
00757         if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0)
00758         {
00759             IF_LOUD(DbgPrint("Error validating program");)
00760             //FIXME: the machine has been initialized(?), but the operative code is wrong. 
00761             //we have to reset the machine!
00762             //something like: reallocate the mem_ex, and reset the tme_core
00763             Open->SkipProcessing = 0;
00764             EXIT_FAILURE(0);
00765         }
00766         
00767         // Allocate the memory to contain the new filter program
00768         // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
00769         TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA');
00770         if (TmpBPFProgram==NULL)
00771         {
00772             IF_LOUD(DbgPrint("Error - No memory for filter");)
00773             // no memory
00774             Open->SkipProcessing = 0;
00775             EXIT_FAILURE(0);
00776         }
00777         
00778         //copy the program in the new buffer
00779         RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn));
00780         Open->bpfprogram=TmpBPFProgram;
00781         
00782         // Create the new JIT filter function
00783         if(!IsExtendedFilter)
00784             if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL)
00785             {
00786                 IF_LOUD(DbgPrint("Error jittering filter");)
00787                 Open->SkipProcessing = 0;
00788                 EXIT_FAILURE(0);
00789             }
00790 
00791         //return
00792         for (i=0;i<NCpu;i++)
00793         {
00794             Open->CpuData[i].C=0;
00795             Open->CpuData[i].P=0;
00796             Open->CpuData[i].Free = Open->Size;
00797             Open->CpuData[i].Accepted=0;
00798             Open->CpuData[i].Dropped=0;
00799             Open->CpuData[i].Received = 0;
00800         }
00801 
00802         Open->ReaderSN=0;
00803         Open->WriterSN=0;
00804 
00805         Open->SkipProcessing = 0;
00806         EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
00807         
00808         break;      
00809         
00810     case BIOCSMODE:  //set the capture mode
00811         
00812         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
00813         {           
00814             EXIT_FAILURE(0);
00815         }
00816 
00817         mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
00818         
00820         if (mode & MODE_DUMP)
00821         {           
00822             EXIT_FAILURE(0);
00823         }
00825 
00826         if(mode == MODE_CAPT){
00827             Open->mode=MODE_CAPT;
00828             
00829             EXIT_SUCCESS(0);
00830         }
00831         else if (mode==MODE_MON){
00832             Open->mode=MODE_MON;
00833 
00834             EXIT_SUCCESS(0);
00835         }   
00836         else{
00837             if(mode & MODE_STAT){
00838                 Open->mode = MODE_STAT;
00839                 NdisAcquireSpinLock(&Open->CountersLock);
00840                 Open->Nbytes.QuadPart=0;
00841                 Open->Npackets.QuadPart=0;
00842                 NdisReleaseSpinLock(&Open->CountersLock);
00843                 
00844                 if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000;
00845                 
00846             }
00847             
00848             if(mode & MODE_DUMP){
00849                 
00850                 Open->mode |= MODE_DUMP;
00851 //              Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000;
00852                 
00853             }   
00854             EXIT_SUCCESS(0);
00855         }
00856         
00857         EXIT_FAILURE(0);
00858         
00859         break;
00860 
00861     case BIOCSETDUMPFILENAME:
00862 
00864         EXIT_FAILURE(0);
00866 
00867         if(Open->mode & MODE_DUMP)
00868         {
00869             
00870             // Close current dump file
00871             if(Open->DumpFileHandle != NULL)
00872             {
00873                 NPF_CloseDumpFile(Open);
00874                 Open->DumpFileHandle = NULL;
00875             }
00876             
00877             if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){
00878                 EXIT_FAILURE(0);
00879             }
00880             
00881             // Allocate the buffer that will contain the string
00882             DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA');
00883             if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
00884                 IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
00885                     EXIT_FAILURE(0);
00886             }
00887             
00888             // Copy the buffer
00889             RtlCopyBytes((PVOID)DumpNameBuff, 
00890                 Irp->AssociatedIrp.SystemBuffer, 
00891                 IrpSp->Parameters.DeviceIoControl.InputBufferLength);
00892             
00893             // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system 
00894             ((PSHORT)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0;
00895             
00896             // Create the unicode string
00897             RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff);
00898             
00899             IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n",
00900                 Open->DumpFileName.Buffer,
00901                 IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
00902                 
00903             // Try to create the file
00904             if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) &&
00905                 NT_SUCCESS( NPF_StartDump(Open)))
00906             {
00907                 EXIT_SUCCESS(0);
00908             }
00909         }
00910         
00911         EXIT_FAILURE(0);
00912         
00913         break;
00914                 
00915     case BIOCSETDUMPLIMITS:
00916 
00918         EXIT_FAILURE(0);
00920 
00921         if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 2*sizeof(ULONG))
00922         {
00923             EXIT_FAILURE(0);
00924         }
00925 
00926         Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
00927         Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1);
00928 
00929         IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);)
00930 
00931         EXIT_SUCCESS(0);
00932 
00933         break;
00934 
00935     case BIOCISDUMPENDED:
00936 
00938         EXIT_FAILURE(0);
00940 
00941         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT))
00942         {           
00943             EXIT_FAILURE(0);
00944         }
00945 
00946         *((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
00947 
00948         EXIT_SUCCESS(4);
00949 
00950         break;
00951 
00952     case BIOCSETBUFFERSIZE:
00953         
00954 
00955         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
00956         {           
00957             EXIT_FAILURE(0);
00958         }
00959 
00960         // Get the number of bytes to allocate
00961         dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
00962 
00963         Open->SkipProcessing = 1;
00964 
00965         do
00966         {
00967             Flag = FALSE;
00968             for(i=0;i<NCpu;i++)
00969                 if (Open->CpuData[i].Processing == 1)
00970                     Flag = TRUE;
00971         }
00972         while(Flag);  //BUSY FORM WAITING...
00973 
00974         if (dim / NCpu < sizeof(struct PacketHeader))
00975             dim = 0;
00976         else
00977         {
00978             tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA');
00979             if (tpointer==NULL)
00980             {
00981                 // no memory
00982                 Open->SkipProcessing = 0;
00983                 EXIT_FAILURE(0);
00984             }
00985         }
00986 
00987         if (Open->CpuData[0].Buffer != NULL)
00988             ExFreePool(Open->CpuData[0].Buffer);
00989 
00990         for (i=0;i<NCpu;i++)
00991         {
00992             if (dim > 0) 
00993                 Open->CpuData[i].Buffer=(PUCHAR)tpointer + (dim/NCpu)*i;
00994             else
00995                 Open->CpuData[i].Buffer = NULL;
00996             IF_LOUD(DbgPrint("Loop %p\n",Open->CpuData[i].Buffer);)
00997             Open->CpuData[i].Free = dim/NCpu;
00998             Open->CpuData[i].P = 0;
00999         }
01000 
01001         Open->Size = dim/NCpu;
01002     
01003         Open->SkipProcessing = 0;
01004         EXIT_SUCCESS(dim);
01005         
01006         break;
01007         
01008     case BIOCSRTIMEOUT: //set the timeout on the read calls
01009         
01010 
01011         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
01012         {           
01013             EXIT_FAILURE(0);
01014         }
01015 
01016         timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
01017         if((int)timeout==-1)
01018             Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE;
01019         else
01020         {
01021             Open->TimeOut.QuadPart=(LONGLONG)timeout;
01022             Open->TimeOut.QuadPart*=10000;
01023             Open->TimeOut.QuadPart=-Open->TimeOut.QuadPart;
01024         }
01025 
01026         IF_LOUD(DbgPrint("NPF: read timeout set to %d:%d\n",Open->TimeOut.HighPart,Open->TimeOut.LowPart);)
01027         EXIT_SUCCESS(timeout);
01028         
01029         break;
01030         
01031     case BIOCSWRITEREP: //set the writes repetition number
01032         
01033     if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
01034     {           
01035         EXIT_FAILURE(0);
01036     }
01037 
01038         Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
01039         
01040         EXIT_SUCCESS(Open->Nwrites);
01041         
01042         break;
01043 
01044     case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application
01045 
01046         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
01047         {           
01048             EXIT_FAILURE(0);
01049         }
01050 
01051         Open->MinToCopy = (*((PULONG)Irp->AssociatedIrp.SystemBuffer))/NCpu;  //An hack to make the NCPU-buffers behave like a larger one
01052         
01053         EXIT_SUCCESS(Open->MinToCopy);
01054         
01055         break;
01056         
01057     case IOCTL_PROTOCOL_RESET:
01058         
01059         IF_LOUD(DbgPrint("NPF: IoControl - Reset request\n");)
01060 
01061         IoMarkIrpPending(Irp);
01062         Irp->IoStatus.Status = STATUS_SUCCESS;
01063 
01064         ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock);
01065         NdisReset(&Status,Open->AdapterHandle);
01066         if (Status != NDIS_STATUS_PENDING)
01067         {
01068             IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");)
01069                 NPF_ResetComplete(Open,Status);
01070         }
01071         
01072         break;
01073         
01074         
01075     case BIOCSETOID:
01076     case BIOCQUERYOID:
01077         
01078         // Extract a request from the list of free ones
01079         RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
01080         if (RequestListEntry == NULL)
01081         {
01082             EXIT_FAILURE(0);
01083         }
01084 
01085         pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
01086         pRequest->Irp = Irp;
01087         pRequest->Internal = FALSE;
01088 
01089         
01090         //
01091         //  See if it is an Ndis request
01092         //
01093         OidData=Irp->AssociatedIrp.SystemBuffer;
01094         
01095         if (((FunctionCode == BIOCSETOID) || (FunctionCode == BIOCQUERYOID))
01096             &&
01097             (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength)
01098             &&
01099             (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA))
01100             &&
01101             (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) {
01102             
01103             IF_LOUD(DbgPrint("NPF: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);)
01104                 
01105                 //
01106                 //  The buffer is valid
01107                 //
01108                 if (FunctionCode == BIOCSETOID){
01109                     
01110                     pRequest->Request.RequestType=NdisRequestSetInformation;
01111                     pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
01112                     
01113                     pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data;
01114                     pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length;
01115                     
01116                     
01117                 } 
01118                 else{
01119                                 
01120                     pRequest->Request.RequestType=NdisRequestQueryInformation;
01121                     pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid;
01122                     
01123                     pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data;
01124                     pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length;
01125                     
01126                 }
01127 
01128                 NdisResetEvent(&Open->IOEvent);
01129                 //
01130                 //  submit the request
01131                 //
01132                 NdisRequest(
01133                     &Status,
01134                     Open->AdapterHandle,
01135                     &pRequest->Request
01136                     );
01137                 
01138         } else {
01139             //
01140             //  buffer too small
01141             //
01142             Status=NDIS_STATUS_FAILURE;
01143             pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
01144             pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
01145             
01146         }
01147         
01148         if (Status != NDIS_STATUS_PENDING) {
01149             IF_LOUD(DbgPrint("NPF: Calling RequestCompleteHandler\n");)
01150                 
01151             NPF_RequestComplete(Open, &pRequest->Request, Status);
01152             return Status;
01153             
01154         }
01155 
01156         NdisWaitEvent(&Open->IOEvent, 5000);
01157 
01158         return(Open->IOStatus);
01159         
01160         break;
01161         
01162         
01163     default:
01164         
01165         EXIT_FAILURE(0);
01166     }
01167     
01168     return Status;
01169 }
01170 
01171 //-------------------------------------------------------------------
01172 
01173 VOID
01174 NPF_RequestComplete(
01175     IN NDIS_HANDLE   ProtocolBindingContext,
01176     IN PNDIS_REQUEST NdisRequest,
01177     IN NDIS_STATUS   Status
01178     )
01179 
01180 {
01181     POPEN_INSTANCE      Open;
01182     PIO_STACK_LOCATION  IrpSp;
01183     PIRP                Irp;
01184     PINTERNAL_REQUEST   pRequest;
01185     UINT                FunctionCode;
01186 //  KIRQL               OldIrq;
01187 
01188     PPACKET_OID_DATA    OidData;
01189 
01190     IF_LOUD(DbgPrint("NPF: RequestComplete\n");)
01191 
01192     Open= (POPEN_INSTANCE)ProtocolBindingContext;
01193 
01194     pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
01195     Irp=pRequest->Irp;
01196 
01197     if(pRequest->Internal == TRUE){
01198 
01199         // Put the request in the list of the free ones
01200         ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock);
01201 
01202         if(Status != NDIS_STATUS_SUCCESS)
01203             Open->MaxFrameSize = 1514;  // Assume Ethernet
01204 
01205         // We always return success, because the adapter has been already opened
01206         Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
01207         Irp->IoStatus.Information = 0;
01208         IoCompleteRequest(Irp, IO_NO_INCREMENT);
01209         return;
01210     }
01211 
01212     IrpSp = IoGetCurrentIrpStackLocation(Irp);
01213 
01214     FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
01215 
01216     OidData=Irp->AssociatedIrp.SystemBuffer;
01217 
01218     if (FunctionCode == BIOCSETOID) {
01219 
01220         OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
01221 
01222     } else {
01223 
01224         if (FunctionCode == BIOCQUERYOID) {
01225 
01226             OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
01227 
01228             IF_LOUD(DbgPrint("RequestComplete: BytesWritten=%d\n",pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten);)
01229         }
01230 
01231     }
01232 
01233     Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
01234 
01235     IF_LOUD(DbgPrint("RequestComplete: BytesReturned=%d\n",IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
01236 
01237     ExInterlockedInsertTailList(
01238         &Open->RequestList,
01239         &pRequest->ListElement,
01240         &Open->RequestSpinLock);
01241 
01242     Irp->IoStatus.Status = Status;
01243 
01244     Open->IOStatus = Status;
01245 
01246     IoCompleteRequest(Irp, IO_NO_INCREMENT);
01247 
01248     // Unlock the caller
01249     NdisSetEvent(&Open->IOEvent);
01250 
01251     return;
01252 
01253 
01254 }
01255 
01256 //-------------------------------------------------------------------
01257 
01258 VOID
01259 NPF_Status(
01260     IN NDIS_HANDLE   ProtocolBindingContext,
01261     IN NDIS_STATUS   Status,
01262     IN PVOID         StatusBuffer,
01263     IN UINT          StatusBufferSize
01264     )
01265 
01266 {
01267 
01268     IF_LOUD(DbgPrint("NPF: Status Indication\n");)
01269 
01270     return;
01271 
01272 }
01273 
01274 //-------------------------------------------------------------------
01275 
01276 VOID
01277 NPF_StatusComplete(
01278     IN NDIS_HANDLE  ProtocolBindingContext
01279     )
01280 
01281 {
01282 
01283     IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");)
01284 
01285     return;
01286 
01287 }
01288 
01289 //-------------------------------------------------------------------
01290 
01291 NTSTATUS
01292 NPF_ReadRegistry(
01293     IN  PWSTR              *MacDriverName,
01294     IN  PWSTR              *PacketDriverName,
01295     IN  PUNICODE_STRING     RegistryPath
01296     )
01297 
01298 {
01299     NTSTATUS   Status;
01300 
01301     RTL_QUERY_REGISTRY_TABLE ParamTable[4];
01302 
01303     PWSTR      Bind       = L"Bind";
01304     PWSTR      Export     = L"Export";
01305     PWSTR      Parameters = L"Parameters";
01306     PWSTR      Linkage    = L"Linkage";
01307 
01308     PWCHAR     Path;
01309 
01310 
01311 
01312     Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA');
01313 
01314     if (Path == NULL) {
01315         return STATUS_INSUFFICIENT_RESOURCES;
01316     }
01317 
01318     RtlZeroMemory(
01319         Path,
01320         RegistryPath->Length+sizeof(WCHAR)
01321         );
01322 
01323     RtlCopyMemory(
01324         Path,
01325         RegistryPath->Buffer,
01326         RegistryPath->Length
01327         );
01328 
01329     IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);)
01330 
01331     RtlZeroMemory(
01332         ParamTable,
01333         sizeof(ParamTable)
01334         );
01335 
01336 
01337 
01338     //
01339     //  change to the linkage key
01340     //
01341 
01342     ParamTable[0].QueryRoutine = NULL;
01343     ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
01344     ParamTable[0].Name = Linkage;
01345 
01346 
01347     //
01348     //  Get the name of the mac driver we should bind to
01349     //
01350 
01351     ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine;
01352     ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
01353                           RTL_QUERY_REGISTRY_NOEXPAND;
01354 
01355     ParamTable[1].Name = Bind;
01356     ParamTable[1].EntryContext = (PVOID)MacDriverName;
01357     ParamTable[1].DefaultType = REG_MULTI_SZ;
01358 
01359     //
01360     //  Get the name that we should use for the driver object
01361     //
01362 
01363     ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine;
01364     ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
01365                           RTL_QUERY_REGISTRY_NOEXPAND;
01366 
01367     ParamTable[2].Name = Export;
01368     ParamTable[2].EntryContext = (PVOID)PacketDriverName;
01369     ParamTable[2].DefaultType = REG_MULTI_SZ;
01370 
01371 
01372     Status=RtlQueryRegistryValues(
01373                RTL_REGISTRY_ABSOLUTE,
01374                Path,
01375                ParamTable,
01376                NULL,
01377                NULL
01378                );
01379 
01380 
01381     ExFreePool(Path);
01382 
01383     return Status;
01384 }
01385 
01386 //-------------------------------------------------------------------
01387 
01388 NTSTATUS
01389 NPF_QueryRegistryRoutine(
01390     IN PWSTR     ValueName,
01391     IN ULONG     ValueType,
01392     IN PVOID     ValueData,
01393     IN ULONG     ValueLength,
01394     IN PVOID     Context,
01395     IN PVOID     EntryContext
01396     )
01397 
01398 {
01399 
01400     PUCHAR       Buffer;
01401 
01402     IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
01403 
01404     if (ValueType != REG_MULTI_SZ) {
01405 
01406         return STATUS_OBJECT_NAME_NOT_FOUND;
01407 
01408     }
01409 
01410     Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA');
01411 
01412     if (Buffer==NULL) {
01413 
01414         return STATUS_INSUFFICIENT_RESOURCES;
01415 
01416     }
01417 
01418     RtlCopyMemory(
01419         Buffer,
01420         ValueData,
01421         ValueLength
01422         );
01423 
01424     *((PUCHAR *)EntryContext)=Buffer;
01425 
01426     return STATUS_SUCCESS;
01427 
01428 }

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