メイン   モジュール   デー タ構造   ファイルリスト   データフィールド   グローバル   関連ページ   注意事項   English

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.
2005 translated by Telebusiness,Inc.
 All rights reserved.