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 "ntddk.h" 00034 #include "ntiologc.h" 00035 #include "ndis.h" 00036 00037 #include "debug.h" 00038 #include "packet.h" 00039 00040 static NDIS_MEDIUM MediumArray[] = { 00041 NdisMedium802_3, 00042 // NdisMediumWan, 00043 NdisMediumFddi, 00044 NdisMediumArcnet878_2, 00045 NdisMediumAtm, 00046 NdisMedium802_5 00047 }; 00048 00049 #define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0]) 00050 00051 ULONG NamedEventsCounter=0; 00052 00053 //Itoa. Replaces the buggy RtlIntegerToUnicodeString 00054 void PacketItoa(UINT n,PUCHAR buf){ 00055 int i; 00056 00057 for(i=0;i<20;i+=2){ 00058 buf[18-i]=(n%10)+48; 00059 buf[19-i]=0; 00060 n/=10; 00061 } 00062 00063 } 00064 00066 struct time_conv G_Start_Time = { 00067 0, 00068 {0, 0}, 00069 }; 00070 00071 UINT n_Opened_Instances = 0; 00072 00073 NDIS_SPIN_LOCK Opened_Instances_Lock; 00074 00075 //------------------------------------------------------------------- 00076 00077 NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00078 { 00079 00080 PDEVICE_EXTENSION DeviceExtension; 00081 00082 POPEN_INSTANCE Open; 00083 00084 PIO_STACK_LOCATION IrpSp; 00085 00086 NDIS_STATUS Status; 00087 NDIS_STATUS ErrorStatus; 00088 UINT i; 00089 PUCHAR tpointer; 00090 PLIST_ENTRY PacketListEntry; 00091 PCHAR EvName; 00092 00093 IF_LOUD(DbgPrint("NPF: OpenAdapter\n");) 00094 00095 DeviceExtension = DeviceObject->DeviceExtension; 00096 00097 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00098 00099 // allocate some memory for the open structure 00100 Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA'); 00101 00102 if (Open==NULL) { 00103 // no memory 00104 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00105 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00106 return STATUS_INSUFFICIENT_RESOURCES; 00107 } 00108 00109 RtlZeroMemory( 00110 Open, 00111 sizeof(OPEN_INSTANCE) 00112 ); 00113 00114 00115 EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\NPF0000000000"), '1OWA'); 00116 00117 if (EvName==NULL) { 00118 // no memory 00119 ExFreePool(Open); 00120 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00121 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00122 return STATUS_INSUFFICIENT_RESOURCES; 00123 } 00124 00125 // Save or open here 00126 IrpSp->FileObject->FsContext=Open; 00127 00128 Open->DeviceExtension=DeviceExtension; 00129 00130 00131 // Save the Irp here for the completeion routine to retrieve 00132 Open->OpenCloseIrp=Irp; 00133 00134 // Allocate a packet pool for our xmit and receive packets 00135 NdisAllocatePacketPool( 00136 &Status, 00137 &Open->PacketPool, 00138 TRANSMIT_PACKETS, 00139 sizeof(PACKET_RESERVED)); 00140 00141 00142 if (Status != NDIS_STATUS_SUCCESS) { 00143 00144 IF_LOUD(DbgPrint("NPF: Failed to allocate packet pool\n");) 00145 00146 ExFreePool(Open); 00147 ExFreePool(EvName); 00148 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00149 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00150 return STATUS_INSUFFICIENT_RESOURCES; 00151 } 00152 00153 00154 RtlCopyBytes(EvName,L"\\BaseNamedObjects\\NPF0000000000",sizeof(L"\\BaseNamedObjects\\NPF0000000000")); 00155 00156 //Create the string containing the name of the read event 00157 RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName); 00158 00159 PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21)); 00160 00161 InterlockedIncrement(&NamedEventsCounter); 00162 00163 IF_LOUD(DbgPrint("\nCreated the named event for the read; name=%ws, counter=%d\n", Open->ReadEventName.Buffer,NamedEventsCounter-1);) 00164 00165 //allocate the event objects 00166 Open->ReadEvent=IoCreateNotificationEvent(&Open->ReadEventName,&Open->ReadEventHandle); 00167 if(Open->ReadEvent==NULL){ 00168 ExFreePool(Open); 00169 ExFreePool(EvName); 00170 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00171 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00172 return STATUS_INSUFFICIENT_RESOURCES; 00173 } 00174 00175 KeInitializeEvent(Open->ReadEvent, NotificationEvent, FALSE); 00176 KeClearEvent(Open->ReadEvent); 00177 NdisInitializeEvent(&Open->WriteEvent); 00178 NdisInitializeEvent(&Open->IOEvent); 00179 NdisInitializeEvent(&Open->DumpEvent); 00180 NdisInitializeEvent(&Open->IOEvent); 00181 NdisAllocateSpinLock(&Open->MachineLock); 00182 NdisAllocateSpinLock(&Open->WriteLock); 00183 Open->WriteInProgress = FALSE; 00184 00185 // list to hold irp's want to reset the adapter 00186 InitializeListHead(&Open->ResetIrpList); 00187 00188 00189 // Initialize the request list 00190 KeInitializeSpinLock(&Open->RequestSpinLock); 00191 InitializeListHead(&Open->RequestList); 00192 00193 // Initializes the extended memory of the NPF machine 00194 Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA'); 00195 if((Open->mem_ex.buffer) == NULL) 00196 { 00197 // no memory 00198 ExFreePool(Open); 00199 ExFreePool(EvName); 00200 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00201 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00202 return STATUS_INSUFFICIENT_RESOURCES; 00203 } 00204 00205 Open->mem_ex.size = DEFAULT_MEM_EX_SIZE; 00206 RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE); 00207 00208 // 00209 // Initialize the open instance 00210 // 00211 // Open->BufSize = 0; 00212 // Open->Buffer = NULL; 00213 // Open->Bhead = 0; 00214 // Open->Btail = 0; 00215 // (INT)Open->BLastByte = -1; 00216 // Open->Dropped = 0; //reset the dropped packets counter 00217 // Open->Received = 0; //reset the received packets counter 00218 // Open->Accepted = 0; //reset the accepted packets counter 00219 Open->bpfprogram = NULL; //reset the filter 00220 Open->mode = MODE_CAPT; 00221 Open->Nbytes.QuadPart = 0; 00222 Open->Npackets.QuadPart = 0; 00223 Open->Nwrites = 1; 00224 Open->Multiple_Write_Counter = 0; 00225 Open->MinToCopy = 0; 00226 Open->TimeOut.QuadPart = (LONGLONG)1; 00227 Open->Bound = TRUE; 00228 Open->DumpFileName.Buffer = NULL; 00229 Open->DumpFileHandle = NULL; 00230 Open->tme.active = TME_NONE_ACTIVE; 00231 Open->DumpLimitReached = FALSE; 00232 Open->MaxFrameSize = 0; 00233 Open->WriterSN=0; 00234 Open->ReaderSN=0; 00235 Open->Size=0; 00236 00237 00238 00239 //allocate the spinlock for the statistic counters 00240 NdisAllocateSpinLock(&Open->CountersLock); 00241 00242 //allocate the spinlock for the buffer pointers 00243 // NdisAllocateSpinLock(&Open->BufLock); 00244 00245 // 00246 // link up the request stored in our open block 00247 // 00248 for (i=0;i<MAX_REQUESTS;i++) { 00249 ExInterlockedInsertTailList( 00250 &Open->RequestList, 00251 &Open->Requests[i].ListElement, 00252 &Open->RequestSpinLock); 00253 00254 } 00255 00256 00257 IoMarkIrpPending(Irp); 00258 00259 // 00260 // Try to open the MAC 00261 // 00262 IF_LOUD(DbgPrint("NPF: Openinig the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);) 00263 00264 NdisOpenAdapter( 00265 &Status, 00266 &ErrorStatus, 00267 &Open->AdapterHandle, 00268 &Open->Medium, 00269 MediumArray, 00270 NUM_NDIS_MEDIA, 00271 DeviceExtension->NdisProtocolHandle, 00272 Open, 00273 &DeviceExtension->AdapterName, 00274 0, 00275 NULL); 00276 00277 IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);) 00278 00279 if (Status != NDIS_STATUS_PENDING) 00280 { 00281 NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS); 00282 } 00283 00284 return(STATUS_PENDING); 00285 } 00286 00287 //------------------------------------------------------------------- 00288 00289 VOID NPF_OpenAdapterComplete( 00290 IN NDIS_HANDLE ProtocolBindingContext, 00291 IN NDIS_STATUS Status, 00292 IN NDIS_STATUS OpenErrorStatus) 00293 { 00294 00295 PIRP Irp; 00296 POPEN_INSTANCE Open; 00297 PLIST_ENTRY RequestListEntry; 00298 PINTERNAL_REQUEST MaxSizeReq; 00299 NDIS_STATUS ReqStatus; 00300 00301 00302 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");) 00303 00304 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00305 00306 // 00307 // get the open irp 00308 // 00309 Irp=Open->OpenCloseIrp; 00310 00311 if (Status != NDIS_STATUS_SUCCESS) { 00312 00313 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");) 00314 00315 NdisFreePacketPool(Open->PacketPool); 00316 00317 //free mem_ex 00318 Open->mem_ex.size = 0; 00319 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00320 00321 ExFreePool(Open->ReadEventName.Buffer); 00322 00323 ZwClose(Open->ReadEventHandle); 00324 00325 00326 ExFreePool(Open); 00327 } 00328 else { 00329 NdisAcquireSpinLock(&Opened_Instances_Lock); 00330 n_Opened_Instances++; 00331 NdisReleaseSpinLock(&Opened_Instances_Lock); 00332 00333 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) 00334 00335 // Get the absolute value of the system boot time. 00336 // This is used for timestamp conversion. 00337 TIME_SYNCHRONIZE(&G_Start_Time); 00338 00339 // Extract a request from the list of free ones 00340 RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock); 00341 00342 if (RequestListEntry == NULL) 00343 { 00344 00345 Open->MaxFrameSize = 1514; // Assume Ethernet 00346 00347 Irp->IoStatus.Status = Status; 00348 Irp->IoStatus.Information = 0; 00349 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00350 00351 return; 00352 } 00353 00354 MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); 00355 MaxSizeReq->Irp = Irp; 00356 MaxSizeReq->Internal = TRUE; 00357 00358 00359 MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; 00360 MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; 00361 00362 00363 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize; 00364 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4; 00365 00366 // submit the request 00367 NdisRequest( 00368 &ReqStatus, 00369 Open->AdapterHandle, 00370 &MaxSizeReq->Request); 00371 00372 00373 if (ReqStatus != NDIS_STATUS_PENDING) { 00374 NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus); 00375 } 00376 00377 return; 00378 00379 } 00380 00381 Irp->IoStatus.Status = Status; 00382 Irp->IoStatus.Information = 0; 00383 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00384 00385 return; 00386 00387 } 00388 00389 //------------------------------------------------------------------- 00390 00391 NTSTATUS 00392 NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) 00393 { 00394 00395 POPEN_INSTANCE Open; 00396 NDIS_STATUS Status; 00397 PIO_STACK_LOCATION IrpSp; 00398 LARGE_INTEGER ThreadDelay; 00399 00400 IF_LOUD(DbgPrint("NPF: CloseAdapter\n");) 00401 00402 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00403 00404 Open=IrpSp->FileObject->FsContext; 00405 00406 // Reset the buffer size. This tells the dump thread to stop. 00407 // Open->BufSize = 0; 00408 00409 if( Open->Bound == FALSE){ 00410 00411 NdisWaitEvent(&Open->IOEvent,10000); 00412 00413 // Free the filter if it's present 00414 if(Open->bpfprogram != NULL) 00415 ExFreePool(Open->bpfprogram); 00416 00417 // Free the jitted filter if it's present 00418 if(Open->Filter != NULL) 00419 BPF_Destroy_JIT_Filter(Open->Filter); 00420 00421 //free the buffer 00422 // Open->BufSize=0; 00423 // if(Open->Buffer != NULL)ExFreePool(Open->Buffer); 00424 00425 if (Open->Size > 0) 00426 ExFreePool(Open->CpuData[0].Buffer); 00427 00428 //free mem_ex 00429 Open->mem_ex.size = 0; 00430 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00431 00432 NdisFreePacketPool(Open->PacketPool); 00433 00434 // Free the string with the name of the dump file 00435 if(Open->DumpFileName.Buffer!=NULL) 00436 ExFreePool(Open->DumpFileName.Buffer); 00437 00438 ExFreePool(Open->ReadEventName.Buffer); 00439 ExFreePool(Open); 00440 00441 Irp->IoStatus.Information = 0; 00442 Irp->IoStatus.Status = STATUS_SUCCESS; 00443 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00444 00445 return(STATUS_SUCCESS); 00446 } 00447 00448 // Unfreeze the consumer 00449 if(Open->mode & MODE_DUMP) 00450 NdisSetEvent(&Open->DumpEvent); 00451 else 00452 KeSetEvent(Open->ReadEvent,0,FALSE); 00453 00454 // Save the IRP 00455 Open->OpenCloseIrp = Irp; 00456 00457 IoMarkIrpPending(Irp); 00458 00459 // If this instance is in dump mode, complete the dump and close the file 00460 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){ 00461 00462 NTSTATUS wres; 00463 00464 ThreadDelay.QuadPart = -50000000; 00465 // Wait the completion of the thread 00466 wres = KeWaitForSingleObject(Open->DumpThreadObject, 00467 UserRequest, 00468 KernelMode, 00469 TRUE, 00470 &ThreadDelay); 00471 00472 ObDereferenceObject(Open->DumpThreadObject); 00473 00474 00475 // Flush and close the dump file 00476 NPF_CloseDumpFile(Open); 00477 } 00478 00479 // Destroy the read Event 00480 ZwClose(Open->ReadEventHandle); 00481 00482 // Close the adapter 00483 NdisCloseAdapter( 00484 &Status, 00485 Open->AdapterHandle 00486 ); 00487 00488 if (Status != NDIS_STATUS_PENDING) { 00489 00490 NPF_CloseAdapterComplete( 00491 Open, 00492 Status 00493 ); 00494 return STATUS_SUCCESS; 00495 00496 } 00497 00498 return(STATUS_PENDING); 00499 } 00500 00501 //------------------------------------------------------------------- 00502 00503 VOID 00504 NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) 00505 { 00506 POPEN_INSTANCE Open; 00507 PIRP Irp; 00508 00509 IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");) 00510 00511 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00512 00513 // free the allocated structures only if the instance is still bound to the adapter 00514 if(Open->Bound == TRUE){ 00515 00516 // Free the filter if it's present 00517 if(Open->bpfprogram != NULL) 00518 ExFreePool(Open->bpfprogram); 00519 00520 // Free the jitted filter if it's present 00521 if(Open->Filter != NULL) 00522 BPF_Destroy_JIT_Filter(Open->Filter); 00523 00524 //free the buffer 00525 // Open->BufSize = 0; 00526 // if(Open->Buffer!=NULL)ExFreePool(Open->Buffer); 00527 00528 if (Open->Size > 0) 00529 ExFreePool(Open->CpuData[0].Buffer); 00530 00531 //free mem_ex 00532 Open->mem_ex.size = 0; 00533 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00534 00535 NdisFreePacketPool(Open->PacketPool); 00536 00537 Irp=Open->OpenCloseIrp; 00538 00539 // Free the string with the name of the dump file 00540 if(Open->DumpFileName.Buffer!=NULL) 00541 ExFreePool(Open->DumpFileName.Buffer); 00542 00543 ExFreePool(Open->ReadEventName.Buffer); 00544 ExFreePool(Open); 00545 00546 // Complete the request only if the instance is still bound to the adapter 00547 Irp->IoStatus.Status = STATUS_SUCCESS; 00548 Irp->IoStatus.Information = 0; 00549 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00550 } 00551 else 00552 NdisSetEvent(&Open->IOEvent); 00553 00554 // Decrease the counter of open instances 00555 NdisAcquireSpinLock(&Opened_Instances_Lock); 00556 n_Opened_Instances--; 00557 NdisReleaseSpinLock(&Opened_Instances_Lock); 00558 00559 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) 00560 00561 if(n_Opened_Instances == 0){ 00562 // Force a synchronization at the next NPF_Open(). 00563 // This hopefully avoids the synchronization issues caused by hibernation or standby. 00564 TIME_DESYNCHRONIZE(&G_Start_Time); 00565 } 00566 00567 return; 00568 00569 } 00570 //------------------------------------------------------------------- 00571 00572 #ifdef NDIS50 00573 NDIS_STATUS 00574 NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) 00575 { 00576 IF_LOUD(DbgPrint("NPF: PowerChange\n");) 00577 00578 TIME_DESYNCHRONIZE(&G_Start_Time); 00579 00580 TIME_SYNCHRONIZE(&G_Start_Time); 00581 00582 return STATUS_SUCCESS; 00583 } 00584 #endif 00585 00586 //------------------------------------------------------------------- 00587 00588 VOID 00589 NPF_BindAdapter( 00590 OUT PNDIS_STATUS Status, 00591 IN NDIS_HANDLE BindContext, 00592 IN PNDIS_STRING DeviceName, 00593 IN PVOID SystemSpecific1, 00594 IN PVOID SystemSpecific2 00595 ) 00596 { 00597 IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");) 00598 } 00599 00600 //------------------------------------------------------------------- 00601 00602 VOID 00603 NPF_UnbindAdapter( 00604 OUT PNDIS_STATUS Status, 00605 IN NDIS_HANDLE ProtocolBindingContext, 00606 IN NDIS_HANDLE UnbindContext 00607 ) 00608 { 00609 POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext; 00610 NDIS_STATUS lStatus; 00611 00612 IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");) 00613 00614 // Reset the buffer size. This tells the dump thread to stop. 00615 // Open->BufSize=0; 00616 00617 NdisResetEvent(&Open->IOEvent); 00618 00619 // This open instance is no more bound to the adapter, set Bound to False 00620 InterlockedExchange( (PLONG) &Open->Bound, FALSE ); 00621 00622 // Awake a possible pending read on this instance 00623 if(Open->mode & MODE_DUMP) 00624 NdisSetEvent(&Open->DumpEvent); 00625 else 00626 KeSetEvent(Open->ReadEvent,0,FALSE); 00627 00628 // If this instance is in dump mode, complete the dump and close the file 00629 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) 00630 NPF_CloseDumpFile(Open); 00631 00632 // Destroy the read Event 00633 ZwClose(Open->ReadEventHandle); 00634 00635 // close the adapter 00636 NdisCloseAdapter( 00637 &lStatus, 00638 Open->AdapterHandle 00639 ); 00640 00641 if (lStatus != NDIS_STATUS_PENDING) { 00642 00643 NPF_CloseAdapterComplete( 00644 Open, 00645 lStatus 00646 ); 00647 00648 *Status = NDIS_STATUS_SUCCESS; 00649 return; 00650 00651 } 00652 00653 *Status = NDIS_STATUS_SUCCESS; 00654 return; 00655 } 00656 00657 //------------------------------------------------------------------- 00658 00659 VOID 00660 NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) 00661 00662 { 00663 POPEN_INSTANCE Open; 00664 PIRP Irp; 00665 00666 PLIST_ENTRY ResetListEntry; 00667 00668 IF_LOUD(DbgPrint("NPF: PacketResetComplte\n");) 00669 00670 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00671 00672 00673 // 00674 // remove the reset IRP from the list 00675 // 00676 ResetListEntry=ExInterlockedRemoveHeadList( 00677 &Open->ResetIrpList, 00678 &Open->RequestSpinLock 00679 ); 00680 00681 #if DBG 00682 if (ResetListEntry == NULL) { 00683 DbgBreakPoint(); 00684 return; 00685 } 00686 #endif 00687 00688 Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); 00689 00690 Irp->IoStatus.Status = STATUS_SUCCESS; 00691 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00692 00693 IF_LOUD(DbgPrint("NPF: PacketResetComplte exit\n");) 00694 00695 return; 00696 00697 }
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.