Main Page   Modules   Data Structures   File List   Data Fields   Globals  

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

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