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 00183 00184 // list to hold irp's want to reset the adapter 00185 InitializeListHead(&Open->ResetIrpList); 00186 00187 00188 // Initialize the request list 00189 KeInitializeSpinLock(&Open->RequestSpinLock); 00190 InitializeListHead(&Open->RequestList); 00191 00192 // Initializes the extended memory of the NPF machine 00193 Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA'); 00194 if((Open->mem_ex.buffer) == NULL) 00195 { 00196 // no memory 00197 ExFreePool(Open); 00198 ExFreePool(EvName); 00199 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; 00200 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00201 return STATUS_INSUFFICIENT_RESOURCES; 00202 } 00203 00204 Open->mem_ex.size = DEFAULT_MEM_EX_SIZE; 00205 RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE); 00206 00207 // 00208 // Initialize the open instance 00209 // 00210 // Open->BufSize = 0; 00211 // Open->Buffer = NULL; 00212 // Open->Bhead = 0; 00213 // Open->Btail = 0; 00214 // (INT)Open->BLastByte = -1; 00215 // Open->Dropped = 0; //reset the dropped packets counter 00216 // Open->Received = 0; //reset the received packets counter 00217 // Open->Accepted = 0; //reset the accepted packets counter 00218 Open->bpfprogram = NULL; //reset the filter 00219 Open->mode = MODE_CAPT; 00220 Open->Nbytes.QuadPart = 0; 00221 Open->Npackets.QuadPart = 0; 00222 Open->Nwrites = 1; 00223 Open->Multiple_Write_Counter = 0; 00224 Open->MinToCopy = 0; 00225 Open->TimeOut.QuadPart = (LONGLONG)1; 00226 Open->Bound = TRUE; 00227 Open->DumpFileName.Buffer = NULL; 00228 Open->DumpFileHandle = NULL; 00229 Open->tme.active = TME_NONE_ACTIVE; 00230 Open->DumpLimitReached = FALSE; 00231 Open->MaxFrameSize = 0; 00232 Open->WriterSN=0; 00233 Open->ReaderSN=0; 00234 Open->Size=0; 00235 00236 00237 00238 //allocate the spinlock for the statistic counters 00239 NdisAllocateSpinLock(&Open->CountersLock); 00240 00241 //allocate the spinlock for the buffer pointers 00242 // NdisAllocateSpinLock(&Open->BufLock); 00243 00244 // 00245 // link up the request stored in our open block 00246 // 00247 for (i=0;i<MAX_REQUESTS;i++) { 00248 ExInterlockedInsertTailList( 00249 &Open->RequestList, 00250 &Open->Requests[i].ListElement, 00251 &Open->RequestSpinLock); 00252 00253 } 00254 00255 00256 IoMarkIrpPending(Irp); 00257 00258 // 00259 // Try to open the MAC 00260 // 00261 IF_LOUD(DbgPrint("NPF: Openinig the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);) 00262 00263 NdisOpenAdapter( 00264 &Status, 00265 &ErrorStatus, 00266 &Open->AdapterHandle, 00267 &Open->Medium, 00268 MediumArray, 00269 NUM_NDIS_MEDIA, 00270 DeviceExtension->NdisProtocolHandle, 00271 Open, 00272 &DeviceExtension->AdapterName, 00273 0, 00274 NULL); 00275 00276 IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);) 00277 00278 if (Status != NDIS_STATUS_PENDING) 00279 { 00280 NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS); 00281 } 00282 00283 return(STATUS_PENDING); 00284 } 00285 00286 //------------------------------------------------------------------- 00287 00288 VOID NPF_OpenAdapterComplete( 00289 IN NDIS_HANDLE ProtocolBindingContext, 00290 IN NDIS_STATUS Status, 00291 IN NDIS_STATUS OpenErrorStatus) 00292 { 00293 00294 PIRP Irp; 00295 POPEN_INSTANCE Open; 00296 PLIST_ENTRY RequestListEntry; 00297 PINTERNAL_REQUEST MaxSizeReq; 00298 NDIS_STATUS ReqStatus; 00299 00300 00301 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");) 00302 00303 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00304 00305 // 00306 // get the open irp 00307 // 00308 Irp=Open->OpenCloseIrp; 00309 00310 if (Status != NDIS_STATUS_SUCCESS) { 00311 00312 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");) 00313 00314 NdisFreePacketPool(Open->PacketPool); 00315 00316 //free mem_ex 00317 Open->mem_ex.size = 0; 00318 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00319 00320 ExFreePool(Open->ReadEventName.Buffer); 00321 00322 ZwClose(Open->ReadEventHandle); 00323 00324 00325 ExFreePool(Open); 00326 } 00327 else { 00328 NdisAcquireSpinLock(&Opened_Instances_Lock); 00329 n_Opened_Instances++; 00330 NdisReleaseSpinLock(&Opened_Instances_Lock); 00331 00332 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) 00333 00334 // Get the absolute value of the system boot time. 00335 // This is used for timestamp conversion. 00336 TIME_SYNCHRONIZE(&G_Start_Time); 00337 00338 // Extract a request from the list of free ones 00339 RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock); 00340 00341 if (RequestListEntry == NULL) 00342 { 00343 00344 Open->MaxFrameSize = 1514; // Assume Ethernet 00345 00346 Irp->IoStatus.Status = Status; 00347 Irp->IoStatus.Information = 0; 00348 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00349 00350 return; 00351 } 00352 00353 MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); 00354 MaxSizeReq->Irp = Irp; 00355 MaxSizeReq->Internal = TRUE; 00356 00357 00358 MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; 00359 MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; 00360 00361 00362 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize; 00363 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4; 00364 00365 // submit the request 00366 NdisRequest( 00367 &ReqStatus, 00368 Open->AdapterHandle, 00369 &MaxSizeReq->Request); 00370 00371 00372 if (ReqStatus != NDIS_STATUS_PENDING) { 00373 NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus); 00374 } 00375 00376 return; 00377 00378 } 00379 00380 Irp->IoStatus.Status = Status; 00381 Irp->IoStatus.Information = 0; 00382 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00383 00384 return; 00385 00386 } 00387 00388 //------------------------------------------------------------------- 00389 00390 NTSTATUS 00391 NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) 00392 { 00393 00394 POPEN_INSTANCE Open; 00395 NDIS_STATUS Status; 00396 PIO_STACK_LOCATION IrpSp; 00397 LARGE_INTEGER ThreadDelay; 00398 00399 IF_LOUD(DbgPrint("NPF: CloseAdapter\n");) 00400 00401 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00402 00403 Open=IrpSp->FileObject->FsContext; 00404 00405 // Reset the buffer size. This tells the dump thread to stop. 00406 // Open->BufSize = 0; 00407 00408 if( Open->Bound == FALSE){ 00409 00410 NdisWaitEvent(&Open->IOEvent,10000); 00411 00412 // Free the filter if it's present 00413 if(Open->bpfprogram != NULL) 00414 ExFreePool(Open->bpfprogram); 00415 00416 // Free the jitted filter if it's present 00417 if(Open->Filter != NULL) 00418 BPF_Destroy_JIT_Filter(Open->Filter); 00419 00420 //free the buffer 00421 // Open->BufSize=0; 00422 // if(Open->Buffer != NULL)ExFreePool(Open->Buffer); 00423 00424 if (Open->Size > 0) 00425 ExFreePool(Open->CpuData[0].Buffer); 00426 00427 //free mem_ex 00428 Open->mem_ex.size = 0; 00429 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00430 00431 NdisFreePacketPool(Open->PacketPool); 00432 00433 // Free the string with the name of the dump file 00434 if(Open->DumpFileName.Buffer!=NULL) 00435 ExFreePool(Open->DumpFileName.Buffer); 00436 00437 ExFreePool(Open->ReadEventName.Buffer); 00438 ExFreePool(Open); 00439 00440 Irp->IoStatus.Information = 0; 00441 Irp->IoStatus.Status = STATUS_SUCCESS; 00442 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00443 00444 return(STATUS_SUCCESS); 00445 } 00446 00447 // Unfreeze the consumer 00448 if(Open->mode & MODE_DUMP) 00449 NdisSetEvent(&Open->DumpEvent); 00450 else 00451 KeSetEvent(Open->ReadEvent,0,FALSE); 00452 00453 // Save the IRP 00454 Open->OpenCloseIrp = Irp; 00455 00456 IoMarkIrpPending(Irp); 00457 00458 // If this instance is in dump mode, complete the dump and close the file 00459 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){ 00460 00461 NTSTATUS wres; 00462 00463 ThreadDelay.QuadPart = -50000000; 00464 // Wait the completion of the thread 00465 wres = KeWaitForSingleObject(Open->DumpThreadObject, 00466 UserRequest, 00467 KernelMode, 00468 TRUE, 00469 &ThreadDelay); 00470 00471 ObDereferenceObject(Open->DumpThreadObject); 00472 00473 00474 // Flush and close the dump file 00475 NPF_CloseDumpFile(Open); 00476 } 00477 00478 // Destroy the read Event 00479 ZwClose(Open->ReadEventHandle); 00480 00481 // Close the adapter 00482 NdisCloseAdapter( 00483 &Status, 00484 Open->AdapterHandle 00485 ); 00486 00487 if (Status != NDIS_STATUS_PENDING) { 00488 00489 NPF_CloseAdapterComplete( 00490 Open, 00491 Status 00492 ); 00493 return STATUS_SUCCESS; 00494 00495 } 00496 00497 return(STATUS_PENDING); 00498 } 00499 00500 //------------------------------------------------------------------- 00501 00502 VOID 00503 NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) 00504 { 00505 POPEN_INSTANCE Open; 00506 PIRP Irp; 00507 00508 IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");) 00509 00510 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00511 00512 // free the allocated structures only if the instance is still bound to the adapter 00513 if(Open->Bound == TRUE){ 00514 00515 // Free the filter if it's present 00516 if(Open->bpfprogram != NULL) 00517 ExFreePool(Open->bpfprogram); 00518 00519 // Free the jitted filter if it's present 00520 if(Open->Filter != NULL) 00521 BPF_Destroy_JIT_Filter(Open->Filter); 00522 00523 //free the buffer 00524 // Open->BufSize = 0; 00525 // if(Open->Buffer!=NULL)ExFreePool(Open->Buffer); 00526 00527 if (Open->Size > 0) 00528 ExFreePool(Open->CpuData[0].Buffer); 00529 00530 //free mem_ex 00531 Open->mem_ex.size = 0; 00532 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer); 00533 00534 NdisFreePacketPool(Open->PacketPool); 00535 00536 Irp=Open->OpenCloseIrp; 00537 00538 // Free the string with the name of the dump file 00539 if(Open->DumpFileName.Buffer!=NULL) 00540 ExFreePool(Open->DumpFileName.Buffer); 00541 00542 ExFreePool(Open->ReadEventName.Buffer); 00543 ExFreePool(Open); 00544 00545 // Complete the request only if the instance is still bound to the adapter 00546 Irp->IoStatus.Status = STATUS_SUCCESS; 00547 Irp->IoStatus.Information = 0; 00548 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00549 } 00550 else 00551 NdisSetEvent(&Open->IOEvent); 00552 00553 // Decrease the counter of open instances 00554 NdisAcquireSpinLock(&Opened_Instances_Lock); 00555 n_Opened_Instances--; 00556 NdisReleaseSpinLock(&Opened_Instances_Lock); 00557 00558 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);) 00559 00560 if(n_Opened_Instances == 0){ 00561 // Force a synchronization at the next NPF_Open(). 00562 // This hopefully avoids the synchronization issues caused by hibernation or standby. 00563 TIME_DESYNCHRONIZE(&G_Start_Time); 00564 } 00565 00566 return; 00567 00568 } 00569 //------------------------------------------------------------------- 00570 00571 #ifdef NDIS50 00572 NDIS_STATUS 00573 NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent) 00574 { 00575 IF_LOUD(DbgPrint("NPF: PowerChange\n");) 00576 00577 TIME_DESYNCHRONIZE(&G_Start_Time); 00578 00579 TIME_SYNCHRONIZE(&G_Start_Time); 00580 00581 return STATUS_SUCCESS; 00582 } 00583 #endif 00584 00585 //------------------------------------------------------------------- 00586 00587 VOID 00588 NPF_BindAdapter( 00589 OUT PNDIS_STATUS Status, 00590 IN NDIS_HANDLE BindContext, 00591 IN PNDIS_STRING DeviceName, 00592 IN PVOID SystemSpecific1, 00593 IN PVOID SystemSpecific2 00594 ) 00595 { 00596 IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");) 00597 } 00598 00599 //------------------------------------------------------------------- 00600 00601 VOID 00602 NPF_UnbindAdapter( 00603 OUT PNDIS_STATUS Status, 00604 IN NDIS_HANDLE ProtocolBindingContext, 00605 IN NDIS_HANDLE UnbindContext 00606 ) 00607 { 00608 POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext; 00609 NDIS_STATUS lStatus; 00610 00611 IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");) 00612 00613 // Reset the buffer size. This tells the dump thread to stop. 00614 // Open->BufSize=0; 00615 00616 NdisResetEvent(&Open->IOEvent); 00617 00618 // This open instance is no more bound to the adapter, set Bound to False 00619 InterlockedExchange( (PLONG) &Open->Bound, FALSE ); 00620 00621 // Awake a possible pending read on this instance 00622 if(Open->mode & MODE_DUMP) 00623 NdisSetEvent(&Open->DumpEvent); 00624 else 00625 KeSetEvent(Open->ReadEvent,0,FALSE); 00626 00627 // If this instance is in dump mode, complete the dump and close the file 00628 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL) 00629 NPF_CloseDumpFile(Open); 00630 00631 // Destroy the read Event 00632 ZwClose(Open->ReadEventHandle); 00633 00634 // close the adapter 00635 NdisCloseAdapter( 00636 &lStatus, 00637 Open->AdapterHandle 00638 ); 00639 00640 if (lStatus != NDIS_STATUS_PENDING) { 00641 00642 NPF_CloseAdapterComplete( 00643 Open, 00644 lStatus 00645 ); 00646 00647 *Status = NDIS_STATUS_SUCCESS; 00648 return; 00649 00650 } 00651 00652 *Status = NDIS_STATUS_SUCCESS; 00653 return; 00654 } 00655 00656 //------------------------------------------------------------------- 00657 00658 VOID 00659 NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status) 00660 00661 { 00662 POPEN_INSTANCE Open; 00663 PIRP Irp; 00664 00665 PLIST_ENTRY ResetListEntry; 00666 00667 IF_LOUD(DbgPrint("NPF: PacketResetComplte\n");) 00668 00669 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00670 00671 00672 // 00673 // remove the reset IRP from the list 00674 // 00675 ResetListEntry=ExInterlockedRemoveHeadList( 00676 &Open->ResetIrpList, 00677 &Open->RequestSpinLock 00678 ); 00679 00680 #if DBG 00681 if (ResetListEntry == NULL) { 00682 DbgBreakPoint(); 00683 return; 00684 } 00685 #endif 00686 00687 Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry); 00688 00689 Irp->IoStatus.Status = STATUS_SUCCESS; 00690 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00691 00692 IF_LOUD(DbgPrint("NPF: PacketResetComplte exit\n");) 00693 00694 return; 00695 00696 }
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.