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