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