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     
00220     PWCHAR DeviceNames = (PWCHAR) ExAllocatePoolWithTag(PagedPool, 4096, '0PWA');
00221     
00222     if (DeviceNames == NULL) {
00223         IF_LOUD(DbgPrint("Unable the allocate the buffer for the list of the network adapters\n");)
00224             return NULL;
00225     }
00226     
00227     InitializeObjectAttributes(&objAttrs, &AdapterListKey,
00228         OBJ_CASE_INSENSITIVE, NULL, NULL);
00229     status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
00230     if (!NT_SUCCESS(status)) {
00231         IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
00232     }
00233     else { //OK
00234         
00235         ULONG resultLength;
00236         KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00237         CHAR AdapInfo[1024];
00238         UINT i=0;
00239         
00240         IF_LOUD(DbgPrint("getAdaptersList: scanning the list of the adapters in the registry, DeviceNames=%x\n",DeviceNames);)
00241             
00242             // Scan the list of the devices
00243             while((status=ZwEnumerateKey(keyHandle,i,KeyBasicInformation,AdapInfo,sizeof(AdapInfo),&resultLength))==STATUS_SUCCESS)
00244             {
00245                 WCHAR ExportKeyName [512];
00246                 PWCHAR ExportKeyPrefix = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
00247                 UINT ExportKeyPrefixSize = sizeof(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
00248                 PWCHAR LinkageKeyPrefix = L"\\Linkage";
00249                 UINT LinkageKeyPrefixSize = sizeof(L"\\Linkage");
00250                 NDIS_STRING FinalExportKey = NDIS_STRING_CONST("Export");
00251                 PKEY_BASIC_INFORMATION tInfo= (PKEY_BASIC_INFORMATION)AdapInfo;
00252                 UNICODE_STRING AdapterKeyName;
00253                 HANDLE ExportKeyHandle;
00254                 KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00255                 ULONG resultLength;
00256                 
00257                 RtlCopyMemory(ExportKeyName,
00258                     ExportKeyPrefix,
00259                     ExportKeyPrefixSize);
00260                 
00261                 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize,
00262                     tInfo->Name,
00263                     tInfo->NameLength+2);
00264                 
00265                 RtlCopyMemory((PCHAR)ExportKeyName+ExportKeyPrefixSize+tInfo->NameLength,
00266                     LinkageKeyPrefix,
00267                     LinkageKeyPrefixSize);
00268                 
00269                 IF_LOUD(DbgPrint("Key name=%ws\n", ExportKeyName);)
00270                                         
00271                 RtlInitUnicodeString(&AdapterKeyName, ExportKeyName);
00272                 
00273                 InitializeObjectAttributes(&objAttrs, &AdapterKeyName,
00274                     OBJ_CASE_INSENSITIVE, NULL, NULL);
00275                 
00276                 status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs);
00277                 
00278                 if (!NT_SUCCESS(status)) {
00279                     DbgPrint("OpenKey Failed, %d!\n",status);
00280                     i++;
00281                     continue;
00282                 }
00283                 
00284                 status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
00285                     KeyValuePartialInformation, &valueInfo,
00286                     sizeof(valueInfo), &resultLength);
00287                 
00288                 if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
00289                     IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
00290                 }
00291                 else {                      // We know how big it needs to be.
00292                     ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
00293                     PKEY_VALUE_PARTIAL_INFORMATION valueInfoP = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePoolWithTag(PagedPool, valueInfoLength, '1PWA');
00294                     if (valueInfoP != NULL) {
00295                         status = ZwQueryValueKey(ExportKeyHandle, &FinalExportKey,
00296                             KeyValuePartialInformation,
00297                             valueInfoP,
00298                             valueInfoLength, &resultLength);
00299                         if (!NT_SUCCESS(status)) {
00300                             IF_LOUD(DbgPrint("Status of %x querying key value\n", status);)
00301                         }
00302                         else{
00303                             IF_LOUD(DbgPrint("Device %d = %ws\n", i, valueInfoP->Data);)
00304                                 RtlCopyMemory((PCHAR)DeviceNames+BufPos,
00305                                 valueInfoP->Data,
00306                                 valueInfoP->DataLength);
00307                             BufPos+=valueInfoP->DataLength-2;
00308                         }
00309                         
00310                         ExFreePool(valueInfoP);
00311                     }
00312                     else {
00313                         IF_LOUD(DbgPrint("Error Allocating the buffer for the device name\n");)
00314                     }
00315                     
00316                 }
00317                 
00318                 // terminate the buffer
00319                 DeviceNames[BufPos/2]=0;
00320                 DeviceNames[BufPos/2+1]=0;
00321                 
00322                 ZwClose (ExportKeyHandle);
00323                 i++;
00324                 
00325             }
00326             
00327             ZwClose (keyHandle);
00328             
00329     }
00330     if(BufPos==0){
00331         ExFreePool(DeviceNames);
00332         return NULL;
00333     }
00334     return DeviceNames;
00335 }
00336 
00337 //-------------------------------------------------------------------
00338 
00339 PKEY_VALUE_PARTIAL_INFORMATION getTcpBindings(void)
00340 {
00341   PKEY_VALUE_PARTIAL_INFORMATION result = NULL;
00342   OBJECT_ATTRIBUTES objAttrs;
00343   NTSTATUS status;
00344   HANDLE keyHandle;
00345 
00346   InitializeObjectAttributes(&objAttrs, &tcpLinkageKeyName,
00347                              OBJ_CASE_INSENSITIVE, NULL, NULL);
00348   status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
00349   if (!NT_SUCCESS(status)) {
00350     IF_LOUD(DbgPrint("\n\nStatus of %x opening %ws\n", status, tcpLinkageKeyName.Buffer);)
00351   }
00352   else {
00353     ULONG resultLength;
00354     KEY_VALUE_PARTIAL_INFORMATION valueInfo;
00355 
00356     IF_LOUD(DbgPrint("\n\nOpened %ws\n", tcpLinkageKeyName.Buffer);)
00357 
00358     status = ZwQueryValueKey(keyHandle, &bindValueName,
00359                              KeyValuePartialInformation, &valueInfo,
00360                              sizeof(valueInfo), &resultLength);
00361     if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW)) {
00362       IF_LOUD(DbgPrint("\n\nStatus of %x querying key value for size\n", status);)
00363     }
00364     else {                      // We know how big it needs to be.
00365       ULONG valueInfoLength = valueInfo.DataLength + FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
00366       PKEY_VALUE_PARTIAL_INFORMATION valueInfoP =
00367         (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(PagedPool, valueInfoLength, '2PWA');
00368       
00369       if (valueInfoP != NULL) {
00370         status = ZwQueryValueKey(keyHandle, &bindValueName,
00371                                  KeyValuePartialInformation,
00372                                  valueInfoP,
00373                                  valueInfoLength, &resultLength);
00374       
00375         if (!NT_SUCCESS(status)) {
00376           IF_LOUD(DbgPrint("\n\nStatus of %x querying key value\n", status);)
00377         }
00378         else if (valueInfoLength != resultLength) {
00379           IF_LOUD(DbgPrint("\n\nQuerying key value result len = %u "
00380                      "but previous len = %u\n",
00381                      resultLength, valueInfoLength);)
00382         }
00383         else if (valueInfoP->Type != REG_MULTI_SZ) {
00384           IF_LOUD(DbgPrint("\n\nTcpip bind value not REG_MULTI_SZ but %u\n",
00385                      valueInfoP->Type);)
00386         }
00387         else {                  // It's OK
00388 #if DBG
00389           ULONG i;
00390           WCHAR* dataP = (WCHAR*)(&valueInfoP->Data[0]);
00391           IF_LOUD(DbgPrint("\n\nBind value:\n");)
00392           for (i = 0; *dataP != UNICODE_NULL; i++) {
00393             UNICODE_STRING macName;
00394             RtlInitUnicodeString(&macName, dataP);
00395             IF_LOUD(DbgPrint("\n\nMac %u = %ws\n", i, macName.Buffer);)
00396             dataP +=
00397               (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
00398           }
00399 #endif // DBG
00400           result = valueInfoP;
00401         }
00402       }
00403     }
00404     ZwClose(keyHandle);
00405   }
00406   return result;
00407 }
00408 
00409 //-------------------------------------------------------------------
00410 
00411 BOOLEAN createDevice(IN OUT PDRIVER_OBJECT adriverObjectP,
00412                      IN PUNICODE_STRING amacNameP, NDIS_HANDLE aProtoHandle)
00413 {
00414     NTSTATUS status;
00415     PDEVICE_OBJECT devObjP;
00416     UNICODE_STRING deviceName;
00417     UNICODE_STRING deviceSymLink;
00418 
00419     IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
00420     if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer,
00421         devicePrefix.Length) < devicePrefix.Length) 
00422     {
00423         return FALSE;
00424     }
00425 
00426     deviceName.Length = 0;
00427     deviceName.MaximumLength = (USHORT)(amacNameP->Length + NPF_Prefix.Length + sizeof(UNICODE_NULL));
00428     deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA');
00429 
00430     if (deviceName.Buffer == NULL)
00431         return FALSE;
00432 
00433     deviceSymLink.Length = 0;
00434     deviceSymLink.MaximumLength =(USHORT)(amacNameP->Length-devicePrefix.Length 
00435         + symbolicLinkPrefix.Length 
00436         + NPF_Prefix.Length 
00437         + sizeof(UNICODE_NULL));
00438 
00439     deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA');
00440 
00441     if (deviceSymLink.Buffer  == NULL)
00442     {
00443         ExFreePool(deviceName.Buffer);
00444         return FALSE;
00445     }
00446 
00447     RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
00448     RtlAppendUnicodeStringToString(&deviceName, &NPF_Prefix);
00449     RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer +
00450         devicePrefix.Length / sizeof(WCHAR));
00451 
00452     RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
00453     RtlAppendUnicodeStringToString(&deviceSymLink, &NPF_Prefix);
00454     RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer +
00455         devicePrefix.Length / sizeof(WCHAR));
00456 
00457     IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)
00458 
00459         status = IoCreateDevice(adriverObjectP, 
00460         sizeof(DEVICE_EXTENSION),
00461         &deviceName, 
00462         FILE_DEVICE_TRANSPORT, 
00463         0, 
00464         FALSE,
00465         &devObjP);
00466 
00467     if (NT_SUCCESS(status)) 
00468     {
00469         PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;
00470         
00471         IF_LOUD(DbgPrint("Device created successfully\n"););
00472 
00473         devObjP->Flags |= DO_DIRECT_IO;
00474         RtlInitUnicodeString(&devExtP->AdapterName,amacNameP->Buffer);   
00475         devExtP->NdisProtocolHandle=aProtoHandle;
00476 
00477         IF_LOUD(DbgPrint("Trying to create SymLink %ws\n",deviceSymLink.Buffer););
00478 
00479         if (IoCreateSymbolicLink(&deviceSymLink,&deviceName) != STATUS_SUCCESS)
00480         {
00481             IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););
00482 
00483             ExFreePool(deviceName.Buffer);
00484             ExFreePool(deviceSymLink.Buffer);
00485 
00486             devExtP->ExportString = NULL;
00487 
00488             return FALSE;
00489         }
00490 
00491         IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););
00492 
00493         devExtP->ExportString = deviceSymLink.Buffer;
00494 
00495         ExFreePool(deviceName.Buffer);
00496 
00497         return TRUE;
00498     }
00499 
00500     else 
00501     {
00502         IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););
00503 
00504         ExFreePool(deviceName.Buffer);
00505         ExFreePool(deviceSymLink.Buffer);
00506         
00507         return FALSE;
00508     }
00509 }
00510 //-------------------------------------------------------------------
00511 
00512 VOID NPF_Unload(IN PDRIVER_OBJECT DriverObject)
00513 {
00514     PDEVICE_OBJECT     DeviceObject;
00515     PDEVICE_OBJECT     OldDeviceObject;
00516     PDEVICE_EXTENSION  DeviceExtension;
00517 
00518     NDIS_HANDLE        NdisProtocolHandle;
00519     NDIS_STATUS        Status;
00520 
00521     NDIS_STRING        SymLink;
00522 
00523     IF_LOUD(DbgPrint("NPF: Unload\n"););
00524 
00525     DeviceObject    = DriverObject->DeviceObject;
00526 
00527     while (DeviceObject != NULL) {
00528         OldDeviceObject = DeviceObject;
00529 
00530         DeviceObject = DeviceObject->NextDevice;
00531 
00532         DeviceExtension = OldDeviceObject->DeviceExtension;
00533 
00534         NdisProtocolHandle=DeviceExtension->NdisProtocolHandle;
00535 
00536         IF_LOUD(DbgPrint("Deleting Adapter %ws, Protocol Handle=%x, Device Obj=%x (%x)\n",
00537             DeviceExtension->AdapterName.Buffer,
00538             NdisProtocolHandle,
00539             DeviceObject,
00540             OldDeviceObject););
00541 
00542         if (DeviceExtension->ExportString)
00543         {
00544             RtlInitUnicodeString(&SymLink , DeviceExtension->ExportString);
00545 
00546             IF_LOUD(DbgPrint("Deleting SymLink at %p\n", SymLink.Buffer););
00547 
00548             IoDeleteSymbolicLink(&SymLink);
00549             ExFreePool(DeviceExtension->ExportString);
00550         }
00551 
00552         IoDeleteDevice(OldDeviceObject);
00553     }
00554 
00555     NdisDeregisterProtocol(
00556         &Status,
00557         NdisProtocolHandle
00558         );
00559 
00560     // Free the adapters names
00561     ExFreePool( bindP );
00562 }
00563 
00564 //-------------------------------------------------------------------
00565 
00566 NTSTATUS NPF_IoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
00567 {
00568     POPEN_INSTANCE      Open;
00569     PIO_STACK_LOCATION  IrpSp;
00570     PLIST_ENTRY         RequestListEntry;
00571     PINTERNAL_REQUEST   pRequest;
00572     ULONG               FunctionCode;
00573     NDIS_STATUS         Status;
00574     PLIST_ENTRY         PacketListEntry;
00575     UINT                i;
00576     PUCHAR              tpointer;
00577     ULONG               dim,timeout;
00578     PUCHAR              prog;
00579     PPACKET_OID_DATA    OidData;
00580     int                 *StatsBuf;
00581     PNDIS_PACKET        pPacket;
00582     ULONG               mode;
00583     PWSTR               DumpNameBuff;
00584     PUCHAR              TmpBPFProgram;
00585     INT                 WriteRes;
00586     BOOLEAN             SyncWrite = FALSE;
00587     struct bpf_insn     *initprogram;
00588     ULONG               insns;
00589     ULONG               cnt;
00590     BOOLEAN             IsExtendedFilter=FALSE;
00591 
00592     BOOLEAN             Flag;
00593 
00594     IF_LOUD(DbgPrint("NPF: IoControl\n");)
00595         
00596     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00597     FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
00598     Open=IrpSp->FileObject->FsContext;
00599 
00600     Irp->IoStatus.Status = STATUS_SUCCESS;
00601 
00602     IF_LOUD(DbgPrint("NPF: Function code is %08lx  buff size=%08lx  %08lx\n",FunctionCode,IrpSp->Parameters.DeviceIoControl.InputBufferLength,IrpSp->Parameters.DeviceIoControl.OutputBufferLength);)
00603 
00604     switch (FunctionCode){
00605         
00606     case BIOCGSTATS: //function to get the capture stats
00607         
00608         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < 4*sizeof(INT)){           
00609             EXIT_FAILURE(0);
00610         }
00611 
00612         *(((PUINT)Irp->UserBuffer)+3) = 0;
00613         *(((PUINT)Irp->UserBuffer)+0) = 0;
00614         *(((PUINT)Irp->UserBuffer)+1) = 0;
00615         *(((PUINT)Irp->UserBuffer)+2) = 0;      // Not yet supported
00616 
00617         for(i=0;i<NCpu;i++)
00618         {
00619 
00620             *(((PUINT)Irp->UserBuffer)+3) += Open->CpuData[i].Accepted;
00621             *(((PUINT)Irp->UserBuffer)+0) += Open->CpuData[i].Received;
00622             *(((PUINT)Irp->UserBuffer)+1) += Open->CpuData[i].Dropped;
00623             *(((PUINT)Irp->UserBuffer)+2) += 0;     // Not yet supported
00624         }
00625         EXIT_SUCCESS(4*sizeof(INT));
00626         
00627         break;
00628         
00629     case BIOCGEVNAME: //function to get the name of the event associated with the current instance
00630 
00631         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength<26){            
00632             EXIT_FAILURE(0);
00633         }
00634 
00635         RtlCopyMemory(Irp->UserBuffer,(Open->ReadEventName.Buffer)+18,26);
00636 
00637         EXIT_SUCCESS(26);
00638 
00639         break;
00640 
00641     case BIOCSENDPACKETSSYNC:
00642 
00643         SyncWrite = TRUE;
00644 
00645     case BIOCSENDPACKETSNOSYNC:
00646         
00647         NdisAcquireSpinLock(&Open->WriteLock);
00648         if(Open->WriteInProgress)
00649         {
00650             // Another write operation is currently in progress
00651             EXIT_FAILURE(0);
00652         }
00653         else
00654         {
00655             Open->WriteInProgress = TRUE;
00656         }
00657         NdisReleaseSpinLock(&Open->WriteLock);
00658         
00659         WriteRes = NPF_BufferedWrite(Irp,
00660             (PUCHAR)Irp->AssociatedIrp.SystemBuffer,
00661             IrpSp->Parameters.DeviceIoControl.InputBufferLength,
00662             SyncWrite);
00663 
00664         NdisAcquireSpinLock(&Open->WriteLock);
00665         Open->WriteInProgress = FALSE;
00666         NdisReleaseSpinLock(&Open->WriteLock);
00667 
00668         if( WriteRes != -1)
00669         {
00670             EXIT_SUCCESS(WriteRes);
00671         }
00672         
00673         EXIT_FAILURE(WriteRes);
00674 
00675         break;
00676 
00677     case BIOCSETF:  
00678 
00679         Open->SkipProcessing = 1;
00680 
00681         do
00682         {
00683             Flag = FALSE;
00684             for(i=0;i<NCpu;i++)
00685                 if (Open->CpuData[i].Processing == 1)
00686                     Flag = TRUE;
00687         }
00688         while(Flag);  //BUSY FORM WAITING...
00689 
00690 
00691         // Free the previous buffer if it was present
00692         if(Open->bpfprogram!=NULL){
00693             TmpBPFProgram=Open->bpfprogram;
00694             Open->bpfprogram = NULL;
00695             ExFreePool(TmpBPFProgram);
00696         }
00697         
00698         if (Open->Filter!=NULL)
00699         {
00700             JIT_BPF_Filter *OldFilter=Open->Filter;
00701             Open->Filter=NULL;
00702             BPF_Destroy_JIT_Filter(OldFilter);
00703         }
00704         
00705         // Get the pointer to the new program
00706         prog=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
00707         
00708         if(prog==NULL)
00709         {
00710             Open->SkipProcessing = 0;
00711             EXIT_FAILURE(0);
00712         }
00713         
00714         insns=(IrpSp->Parameters.DeviceIoControl.InputBufferLength)/sizeof(struct bpf_insn);
00715         
00716         //count the number of operative instructions
00717         for (cnt=0;(cnt<insns) &&(((struct bpf_insn*)prog)[cnt].code!=BPF_SEPARATION); cnt++);
00718         
00719         IF_LOUD(DbgPrint("Operative instructions=%u\n",cnt);)
00720 
00721         if ( cnt != insns && insns != cnt+1 && ((struct bpf_insn*)prog)[cnt].code == BPF_SEPARATION ) 
00722         {
00723             IF_LOUD(DbgPrint("Initialization instructions=%u\n",insns-cnt-1);)
00724     
00725             IsExtendedFilter=TRUE;
00726 
00727             initprogram=&((struct bpf_insn*)prog)[cnt+1];
00728             
00729             if(bpf_filter_init(initprogram,&(Open->mem_ex),&(Open->tme), &G_Start_Time)!=INIT_OK)
00730             {
00731             
00732                 IF_LOUD(DbgPrint("Error initializing NPF machine (bpf_filter_init)\n");)
00733                 
00734                 Open->SkipProcessing = 0;
00735                 EXIT_FAILURE(0);
00736             }
00737         }
00738 
00739         //the NPF processor has been initialized, we have to validate the operative instructions
00740         insns=cnt;
00741         
00742         if(bpf_validate((struct bpf_insn*)prog,cnt,Open->mem_ex.size)==0)
00743         {
00744             IF_LOUD(DbgPrint("Error validating program");)
00745             //FIXME: the machine has been initialized(?), but the operative code is wrong. 
00746             //we have to reset the machine!
00747             //something like: reallocate the mem_ex, and reset the tme_core
00748             Open->SkipProcessing = 0;
00749             EXIT_FAILURE(0);
00750         }
00751         
00752         // Allocate the memory to contain the new filter program
00753         // We could need the original BPF binary if we are forced to use bpf_filter_with_2_buffers()
00754         TmpBPFProgram=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool, cnt*sizeof(struct bpf_insn), '4PWA');
00755         if (TmpBPFProgram==NULL)
00756         {
00757             IF_LOUD(DbgPrint("Error - No memory for filter");)
00758             // no memory
00759             Open->SkipProcessing = 0;
00760             EXIT_FAILURE(0);
00761         }
00762         
00763         //copy the program in the new buffer
00764         RtlCopyMemory(TmpBPFProgram,prog,cnt*sizeof(struct bpf_insn));
00765         Open->bpfprogram=TmpBPFProgram;
00766         
00767         // Create the new JIT filter function
00768         if(!IsExtendedFilter)
00769             if((Open->Filter=BPF_jitter((struct bpf_insn*)Open->bpfprogram,cnt)) == NULL)
00770             {
00771                 IF_LOUD(DbgPrint("Error jittering filter");)
00772                 Open->SkipProcessing = 0;
00773                 EXIT_FAILURE(0);
00774             }
00775 
00776         //return
00777         for (i=0;i<NCpu;i++)
00778         {
00779             Open->CpuData[i].C=0;
00780             Open->CpuData[i].P=0;
00781             Open->CpuData[i].Free = Open->Size;
00782             Open->CpuData[i].Accepted=0;
00783             Open->CpuData[i].Dropped=0;
00784             Open->CpuData[i].Received = 0;
00785         }
00786 
00787         Open->ReaderSN=0;
00788         Open->WriterSN=0;
00789 
00790         Open->SkipProcessing = 0;
00791         EXIT_SUCCESS(IrpSp->Parameters.DeviceIoControl.InputBufferLength);
00792         
00793         break;      
00794         
00795     case BIOCSMODE:  //set the capture mode
00796         
00797         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
00798         {           
00799             EXIT_FAILURE(0);
00800         }
00801 
00802         mode=*((PULONG)Irp->AssociatedIrp.SystemBuffer);
00803         
00805         if (mode & MODE_DUMP)
00806         {           
00807             EXIT_FAILURE(0);
00808         }
00810 
00811         if(mode == MODE_CAPT){
00812             Open->mode=MODE_CAPT;
00813             
00814             EXIT_SUCCESS(0);
00815         }
00816         else if (mode==MODE_MON){
00817             Open->mode=MODE_MON;
00818 
00819             EXIT_SUCCESS(0);
00820         }   
00821         else{
00822             if(mode & MODE_STAT){
00823                 Open->mode = MODE_STAT;
00824                 NdisAcquireSpinLock(&Open->CountersLock);
00825                 Open->Nbytes.QuadPart=0;
00826                 Open->Npackets.QuadPart=0;
00827                 NdisReleaseSpinLock(&Open->CountersLock);
00828                 
00829                 if(Open->TimeOut.QuadPart==0)Open->TimeOut.QuadPart=-10000000;
00830                 
00831             }
00832             
00833             if(mode & MODE_DUMP){
00834                 
00835                 Open->mode |= MODE_DUMP;
00836 //              Open->MinToCopy=(Open->BufSize<2000000)?Open->BufSize/2:1000000;
00837                 
00838             }   
00839             EXIT_SUCCESS(0);
00840         }
00841         
00842         EXIT_FAILURE(0);
00843         
00844         break;
00845 
00846     case BIOCSETDUMPFILENAME:
00847 
00849         EXIT_FAILURE(0);
00851 
00852         if(Open->mode & MODE_DUMP)
00853         {
00854             
00855             // Close current dump file
00856             if(Open->DumpFileHandle != NULL)
00857             {
00858                 NPF_CloseDumpFile(Open);
00859                 Open->DumpFileHandle = NULL;
00860             }
00861             
00862             if(IrpSp->Parameters.DeviceIoControl.InputBufferLength == 0){
00863                 EXIT_FAILURE(0);
00864             }
00865             
00866             // Allocate the buffer that will contain the string
00867             DumpNameBuff=ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.DeviceIoControl.InputBufferLength, '5PWA');
00868             if(DumpNameBuff==NULL || Open->DumpFileName.Buffer!=NULL){
00869                 IF_LOUD(DbgPrint("NPF: unable to allocate the dump filename: not enough memory or name already set\n");)
00870                     EXIT_FAILURE(0);
00871             }
00872             
00873             // Copy the buffer
00874             RtlCopyBytes((PVOID)DumpNameBuff, 
00875                 Irp->AssociatedIrp.SystemBuffer, 
00876                 IrpSp->Parameters.DeviceIoControl.InputBufferLength);
00877             
00878             // Force a \0 at the end of the filename to avoid that malformed strings cause RtlInitUnicodeString to crash the system 
00879             ((PSHORT)DumpNameBuff)[IrpSp->Parameters.DeviceIoControl.InputBufferLength/2-1]=0;
00880             
00881             // Create the unicode string
00882             RtlInitUnicodeString(&Open->DumpFileName, DumpNameBuff);
00883             
00884             IF_LOUD(DbgPrint("NPF: dump file name set to %ws, len=%d\n",
00885                 Open->DumpFileName.Buffer,
00886                 IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
00887                 
00888             // Try to create the file
00889             if ( NT_SUCCESS( NPF_OpenDumpFile(Open,&Open->DumpFileName,FALSE)) &&
00890                 NT_SUCCESS( NPF_StartDump(Open)))
00891             {
00892                 EXIT_SUCCESS(0);
00893             }
00894         }
00895         
00896         EXIT_FAILURE(0);
00897         
00898         break;
00899                 
00900     case BIOCSETDUMPLIMITS:
00901 
00903         EXIT_FAILURE(0);
00905 
00906         if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < 2*sizeof(ULONG))
00907         {
00908             EXIT_FAILURE(0);
00909         }
00910 
00911         Open->MaxDumpBytes = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
00912         Open->MaxDumpPacks = *((PULONG)Irp->AssociatedIrp.SystemBuffer + 1);
00913 
00914         IF_LOUD(DbgPrint("NPF: Set dump limits to %u bytes, %u packs\n", Open->MaxDumpBytes, Open->MaxDumpPacks);)
00915 
00916         EXIT_SUCCESS(0);
00917 
00918         break;
00919 
00920     case BIOCISDUMPENDED:
00921 
00923         EXIT_FAILURE(0);
00925 
00926         if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UINT))
00927         {           
00928             EXIT_FAILURE(0);
00929         }
00930 
00931         *((UINT*)Irp->UserBuffer) = (Open->DumpLimitReached)?1:0;
00932 
00933         EXIT_SUCCESS(4);
00934 
00935         break;
00936 
00937     case BIOCSETBUFFERSIZE:
00938         
00939 
00940         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
00941         {           
00942             EXIT_FAILURE(0);
00943         }
00944 
00945         // Get the number of bytes to allocate
00946         dim = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
00947 
00948         Open->SkipProcessing = 1;
00949 
00950         do
00951         {
00952             Flag = FALSE;
00953             for(i=0;i<NCpu;i++)
00954                 if (Open->CpuData[i].Processing == 1)
00955                     Flag = TRUE;
00956         }
00957         while(Flag);  //BUSY FORM WAITING...
00958 
00959         if (dim / NCpu < sizeof(struct PacketHeader))
00960             dim = 0;
00961         else
00962         {
00963             tpointer = ExAllocatePoolWithTag(NonPagedPool, dim, '6PWA');
00964             if (tpointer==NULL)
00965             {
00966                 // no memory
00967                 Open->SkipProcessing = 0;
00968                 EXIT_FAILURE(0);
00969             }
00970         }
00971 
00972         if (Open->CpuData[0].Buffer != NULL)
00973             ExFreePool(Open->CpuData[0].Buffer);
00974 
00975         for (i=0;i<NCpu;i++)
00976         {
00977             if (dim > 0) 
00978                 Open->CpuData[i].Buffer=(PUCHAR)tpointer + (dim/NCpu)*i;
00979             else
00980                 Open->CpuData[i].Buffer = NULL;
00981             IF_LOUD(DbgPrint("Loop %p\n",Open->CpuData[i].Buffer);)
00982             Open->CpuData[i].Free = dim/NCpu;
00983             Open->CpuData[i].P = 0;
00984         }
00985 
00986         Open->Size = dim/NCpu;
00987     
00988         Open->SkipProcessing = 0;
00989         EXIT_SUCCESS(dim);
00990         
00991         break;
00992         
00993     case BIOCSRTIMEOUT: //set the timeout on the read calls
00994         
00995 
00996         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
00997         {           
00998             EXIT_FAILURE(0);
00999         }
01000 
01001         timeout = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
01002         if((int)timeout==-1)
01003             Open->TimeOut.QuadPart=(LONGLONG)IMMEDIATE;
01004         else
01005         {
01006             Open->TimeOut.QuadPart=(LONGLONG)timeout;
01007             Open->TimeOut.QuadPart*=10000;
01008             Open->TimeOut.QuadPart=-Open->TimeOut.QuadPart;
01009         }
01010 
01011         IF_LOUD(DbgPrint("NPF: read timeout set to %d:%d\n",Open->TimeOut.HighPart,Open->TimeOut.LowPart);)
01012         EXIT_SUCCESS(timeout);
01013         
01014         break;
01015         
01016     case BIOCSWRITEREP: //set the writes repetition number
01017         
01018     if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
01019     {           
01020         EXIT_FAILURE(0);
01021     }
01022 
01023         Open->Nwrites = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
01024         
01025         EXIT_SUCCESS(Open->Nwrites);
01026         
01027         break;
01028 
01029     case BIOCSMINTOCOPY: //set the minimum buffer's size to copy to the application
01030 
01031         if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
01032         {           
01033             EXIT_FAILURE(0);
01034         }
01035 
01036         Open->MinToCopy = (*((PULONG)Irp->AssociatedIrp.SystemBuffer))/NCpu;  //An hack to make the NCPU-buffers behave like a larger one
01037         
01038         EXIT_SUCCESS(Open->MinToCopy);
01039         
01040         break;
01041         
01042     case IOCTL_PROTOCOL_RESET:
01043         
01044         IF_LOUD(DbgPrint("NPF: IoControl - Reset request\n");)
01045 
01046         IoMarkIrpPending(Irp);
01047         Irp->IoStatus.Status = STATUS_SUCCESS;
01048 
01049         ExInterlockedInsertTailList(&Open->ResetIrpList,&Irp->Tail.Overlay.ListEntry,&Open->RequestSpinLock);
01050         NdisReset(&Status,Open->AdapterHandle);
01051         if (Status != NDIS_STATUS_PENDING)
01052         {
01053             IF_LOUD(DbgPrint("NPF: IoControl - ResetComplete being called\n");)
01054                 NPF_ResetComplete(Open,Status);
01055         }
01056         
01057         break;
01058         
01059         
01060     case BIOCSETOID:
01061     case BIOCQUERYOID:
01062         
01063         // Extract a request from the list of free ones
01064         RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList,&Open->RequestSpinLock);
01065         if (RequestListEntry == NULL)
01066         {
01067             EXIT_FAILURE(0);
01068         }
01069 
01070         pRequest=CONTAINING_RECORD(RequestListEntry,INTERNAL_REQUEST,ListElement);
01071         pRequest->Irp = Irp;
01072         pRequest->Internal = FALSE;
01073 
01074         
01075         //
01076         //  See if it is an Ndis request
01077         //
01078         OidData=Irp->AssociatedIrp.SystemBuffer;
01079         
01080         if (((FunctionCode == BIOCSETOID) || (FunctionCode == BIOCQUERYOID))
01081             &&
01082             (IrpSp->Parameters.DeviceIoControl.InputBufferLength == IrpSp->Parameters.DeviceIoControl.OutputBufferLength)
01083             &&
01084             (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA))
01085             &&
01086             (IrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof(PACKET_OID_DATA)-1+OidData->Length)) {
01087             
01088             IF_LOUD(DbgPrint("NPF: IoControl: Request: Oid=%08lx, Length=%08lx\n",OidData->Oid,OidData->Length);)
01089                 
01090                 //
01091                 //  The buffer is valid
01092                 //
01093                 if (FunctionCode == BIOCSETOID){
01094                     
01095                     pRequest->Request.RequestType=NdisRequestSetInformation;
01096                     pRequest->Request.DATA.SET_INFORMATION.Oid=OidData->Oid;
01097                     
01098                     pRequest->Request.DATA.SET_INFORMATION.InformationBuffer=OidData->Data;
01099                     pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength=OidData->Length;
01100                     
01101                     
01102                 } 
01103                 else{
01104                                 
01105                     pRequest->Request.RequestType=NdisRequestQueryInformation;
01106                     pRequest->Request.DATA.QUERY_INFORMATION.Oid=OidData->Oid;
01107                     
01108                     pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer=OidData->Data;
01109                     pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength=OidData->Length;
01110                     
01111                 }
01112 
01113                 NdisResetEvent(&Open->IOEvent);
01114                 //
01115                 //  submit the request
01116                 //
01117                 NdisRequest(
01118                     &Status,
01119                     Open->AdapterHandle,
01120                     &pRequest->Request
01121                     );
01122                 
01123         } else {
01124             //
01125             //  buffer too small
01126             //
01127             Status=NDIS_STATUS_FAILURE;
01128             pRequest->Request.DATA.SET_INFORMATION.BytesRead=0;
01129             pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten=0;
01130             
01131         }
01132         
01133         if (Status != NDIS_STATUS_PENDING) {
01134             IF_LOUD(DbgPrint("NPF: Calling RequestCompleteHandler\n");)
01135                 
01136             NPF_RequestComplete(Open, &pRequest->Request, Status);
01137             return Status;
01138             
01139         }
01140 
01141         NdisWaitEvent(&Open->IOEvent, 5000);
01142 
01143         return(Open->IOStatus);
01144         
01145         break;
01146         
01147         
01148     default:
01149         
01150         EXIT_FAILURE(0);
01151     }
01152     
01153     return Status;
01154 }
01155 
01156 //-------------------------------------------------------------------
01157 
01158 VOID
01159 NPF_RequestComplete(
01160     IN NDIS_HANDLE   ProtocolBindingContext,
01161     IN PNDIS_REQUEST NdisRequest,
01162     IN NDIS_STATUS   Status
01163     )
01164 
01165 {
01166     POPEN_INSTANCE      Open;
01167     PIO_STACK_LOCATION  IrpSp;
01168     PIRP                Irp;
01169     PINTERNAL_REQUEST   pRequest;
01170     UINT                FunctionCode;
01171 //  KIRQL               OldIrq;
01172 
01173     PPACKET_OID_DATA    OidData;
01174 
01175     IF_LOUD(DbgPrint("NPF: RequestComplete\n");)
01176 
01177     Open= (POPEN_INSTANCE)ProtocolBindingContext;
01178 
01179     pRequest=CONTAINING_RECORD(NdisRequest,INTERNAL_REQUEST,Request);
01180     Irp=pRequest->Irp;
01181 
01182     if(pRequest->Internal == TRUE){
01183 
01184         // Put the request in the list of the free ones
01185         ExInterlockedInsertTailList(&Open->RequestList, &pRequest->ListElement, &Open->RequestSpinLock);
01186 
01187         if(Status != NDIS_STATUS_SUCCESS)
01188             Open->MaxFrameSize = 1514;  // Assume Ethernet
01189 
01190         // We always return success, because the adapter has been already opened
01191         Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;
01192         Irp->IoStatus.Information = 0;
01193         IoCompleteRequest(Irp, IO_NO_INCREMENT);
01194         return;
01195     }
01196 
01197     IrpSp = IoGetCurrentIrpStackLocation(Irp);
01198 
01199     FunctionCode=IrpSp->Parameters.DeviceIoControl.IoControlCode;
01200 
01201     OidData=Irp->AssociatedIrp.SystemBuffer;
01202 
01203     if (FunctionCode == BIOCSETOID) {
01204 
01205         OidData->Length=pRequest->Request.DATA.SET_INFORMATION.BytesRead;
01206 
01207     } else {
01208 
01209         if (FunctionCode == BIOCQUERYOID) {
01210 
01211             OidData->Length=pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten;
01212 
01213             IF_LOUD(DbgPrint("RequestComplete: BytesWritten=%d\n",pRequest->Request.DATA.QUERY_INFORMATION.BytesWritten);)
01214         }
01215 
01216     }
01217 
01218     Irp->IoStatus.Information=IrpSp->Parameters.DeviceIoControl.InputBufferLength;
01219 
01220     IF_LOUD(DbgPrint("RequestComplete: BytesReturned=%d\n",IrpSp->Parameters.DeviceIoControl.InputBufferLength);)
01221 
01222     ExInterlockedInsertTailList(
01223         &Open->RequestList,
01224         &pRequest->ListElement,
01225         &Open->RequestSpinLock);
01226 
01227     Irp->IoStatus.Status = Status;
01228 
01229     Open->IOStatus = Status;
01230 
01231     IoCompleteRequest(Irp, IO_NO_INCREMENT);
01232 
01233     // Unlock the caller
01234     NdisSetEvent(&Open->IOEvent);
01235 
01236     return;
01237 
01238 
01239 }
01240 
01241 //-------------------------------------------------------------------
01242 
01243 VOID
01244 NPF_Status(
01245     IN NDIS_HANDLE   ProtocolBindingContext,
01246     IN NDIS_STATUS   Status,
01247     IN PVOID         StatusBuffer,
01248     IN UINT          StatusBufferSize
01249     )
01250 
01251 {
01252 
01253     IF_LOUD(DbgPrint("NPF: Status Indication\n");)
01254 
01255     return;
01256 
01257 }
01258 
01259 //-------------------------------------------------------------------
01260 
01261 VOID
01262 NPF_StatusComplete(
01263     IN NDIS_HANDLE  ProtocolBindingContext
01264     )
01265 
01266 {
01267 
01268     IF_LOUD(DbgPrint("NPF: StatusIndicationComplete\n");)
01269 
01270     return;
01271 
01272 }
01273 
01274 //-------------------------------------------------------------------
01275 
01276 NTSTATUS
01277 NPF_ReadRegistry(
01278     IN  PWSTR              *MacDriverName,
01279     IN  PWSTR              *PacketDriverName,
01280     IN  PUNICODE_STRING     RegistryPath
01281     )
01282 
01283 {
01284     NTSTATUS   Status;
01285 
01286     RTL_QUERY_REGISTRY_TABLE ParamTable[4];
01287 
01288     PWSTR      Bind       = L"Bind";
01289     PWSTR      Export     = L"Export";
01290     PWSTR      Parameters = L"Parameters";
01291     PWSTR      Linkage    = L"Linkage";
01292 
01293     PWCHAR     Path;
01294 
01295 
01296 
01297     Path=ExAllocatePoolWithTag(PagedPool, RegistryPath->Length+sizeof(WCHAR), '7PWA');
01298 
01299     if (Path == NULL) {
01300         return STATUS_INSUFFICIENT_RESOURCES;
01301     }
01302 
01303     RtlZeroMemory(
01304         Path,
01305         RegistryPath->Length+sizeof(WCHAR)
01306         );
01307 
01308     RtlCopyMemory(
01309         Path,
01310         RegistryPath->Buffer,
01311         RegistryPath->Length
01312         );
01313 
01314     IF_LOUD(DbgPrint("NPF: Reg path is %ws\n",RegistryPath->Buffer);)
01315 
01316     RtlZeroMemory(
01317         ParamTable,
01318         sizeof(ParamTable)
01319         );
01320 
01321 
01322 
01323     //
01324     //  change to the linkage key
01325     //
01326 
01327     ParamTable[0].QueryRoutine = NULL;
01328     ParamTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
01329     ParamTable[0].Name = Linkage;
01330 
01331 
01332     //
01333     //  Get the name of the mac driver we should bind to
01334     //
01335 
01336     ParamTable[1].QueryRoutine = NPF_QueryRegistryRoutine;
01337     ParamTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED |
01338                           RTL_QUERY_REGISTRY_NOEXPAND;
01339 
01340     ParamTable[1].Name = Bind;
01341     ParamTable[1].EntryContext = (PVOID)MacDriverName;
01342     ParamTable[1].DefaultType = REG_MULTI_SZ;
01343 
01344     //
01345     //  Get the name that we should use for the driver object
01346     //
01347 
01348     ParamTable[2].QueryRoutine = NPF_QueryRegistryRoutine;
01349     ParamTable[2].Flags = RTL_QUERY_REGISTRY_REQUIRED |
01350                           RTL_QUERY_REGISTRY_NOEXPAND;
01351 
01352     ParamTable[2].Name = Export;
01353     ParamTable[2].EntryContext = (PVOID)PacketDriverName;
01354     ParamTable[2].DefaultType = REG_MULTI_SZ;
01355 
01356 
01357     Status=RtlQueryRegistryValues(
01358                RTL_REGISTRY_ABSOLUTE,
01359                Path,
01360                ParamTable,
01361                NULL,
01362                NULL
01363                );
01364 
01365 
01366     ExFreePool(Path);
01367 
01368     return Status;
01369 }
01370 
01371 //-------------------------------------------------------------------
01372 
01373 NTSTATUS
01374 NPF_QueryRegistryRoutine(
01375     IN PWSTR     ValueName,
01376     IN ULONG     ValueType,
01377     IN PVOID     ValueData,
01378     IN ULONG     ValueLength,
01379     IN PVOID     Context,
01380     IN PVOID     EntryContext
01381     )
01382 
01383 {
01384 
01385     PUCHAR       Buffer;
01386 
01387     IF_LOUD(DbgPrint("Perf: QueryRegistryRoutine\n");)
01388 
01389     if (ValueType != REG_MULTI_SZ) {
01390 
01391         return STATUS_OBJECT_NAME_NOT_FOUND;
01392 
01393     }
01394 
01395     Buffer=ExAllocatePoolWithTag(NonPagedPool, ValueLength, '8PWA');
01396 
01397     if (Buffer==NULL) {
01398 
01399         return STATUS_INSUFFICIENT_RESOURCES;
01400 
01401     }
01402 
01403     RtlCopyMemory(
01404         Buffer,
01405         ValueData,
01406         ValueLength
01407         );
01408 
01409     *((PUCHAR *)EntryContext)=Buffer;
01410 
01411     return STATUS_SUCCESS;
01412 
01413 }

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