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.