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