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

# Packet.c

Go to the documentation of this file.

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

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