Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

Packet.c

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

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.