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

Openclos.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 "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.