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