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

# Packet.c

Go to the documentation of this file.

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

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