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