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

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