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

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