1 /*
2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3 * Copyright (c) 2005 CACE Technologies, Davis (California)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies
16 * nor the names of its contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #include <GlobalConst.h>
35
36 #include "ntddk.h"
37 #include "ntiologc.h"
38 #include "ndis.h"
39
40 #include "debug.h"
41 #include "packet.h"
42
43 static NDIS_MEDIUM MediumArray[] = {
44 NdisMedium802_3,
45 // NdisMediumWan,
46 NdisMediumFddi,
47 NdisMediumArcnet878_2,
48 NdisMediumAtm,
49 NdisMedium802_5
50 };
51
52 #define NUM_NDIS_MEDIA (sizeof MediumArray / sizeof MediumArray[0])
53
54 ULONG NamedEventsCounter=0;
55
56 //Itoa. Replaces the buggy RtlIntegerToUnicodeString
PacketItoa(UINT n,PUCHAR buf)57 void PacketItoa(UINT n,PUCHAR buf){
58 int i;
59
60 for(i=0;i<20;i+=2){
61 buf[18-i]=(n%10)+48;
62 buf[19-i]=0;
63 n/=10;
64 }
65
66 }
67
68 /// Global start time. Used as an absolute reference for timestamp conversion.
69 struct time_conv G_Start_Time = {
70 0,
71 {0, 0},
72 };
73
74 UINT n_Opened_Instances = 0;
75
76 NDIS_SPIN_LOCK Opened_Instances_Lock;
77
78 //-------------------------------------------------------------------
79
NPF_Open(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)80 NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
81 {
82
83 PDEVICE_EXTENSION DeviceExtension;
84
85 POPEN_INSTANCE Open;
86
87 PIO_STACK_LOCATION IrpSp;
88
89 NDIS_STATUS Status;
90 NDIS_STATUS ErrorStatus;
91 UINT i;
92 PCHAR EvName;
93
94 IF_LOUD(DbgPrint("NPF: OpenAdapter\n");)
95
96 DeviceExtension = DeviceObject->DeviceExtension;
97
98 IrpSp = IoGetCurrentIrpStackLocation(Irp);
99
100 // allocate some memory for the open structure
101 Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA');
102
103 if (Open==NULL) {
104 // no memory
105 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
106 IoCompleteRequest(Irp, IO_NO_INCREMENT);
107 return STATUS_INSUFFICIENT_RESOURCES;
108 }
109
110 RtlZeroMemory(
111 Open,
112 sizeof(OPEN_INSTANCE)
113 );
114
115
116 EvName=ExAllocatePoolWithTag(NonPagedPool, sizeof(L"\\BaseNamedObjects\\SEE0000000000"), '1OWA');
117
118 if (EvName==NULL) {
119 // no memory
120 ExFreePool(Open);
121 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
122 IoCompleteRequest(Irp, IO_NO_INCREMENT);
123 return STATUS_INSUFFICIENT_RESOURCES;
124 }
125
126 // Save or open here
127 IrpSp->FileObject->FsContext=Open;
128
129 Open->DeviceExtension=DeviceExtension;
130
131
132 // Save the Irp here for the completion routine to retrieve
133 Open->OpenCloseIrp=Irp;
134
135 // Allocate a packet pool for our xmit and receive packets
136 NdisAllocatePacketPool(
137 &Status,
138 &Open->PacketPool,
139 TRANSMIT_PACKETS,
140 sizeof(PACKET_RESERVED));
141
142
143 if (Status != NDIS_STATUS_SUCCESS) {
144
145 IF_LOUD(DbgPrint("NPF: Failed to allocate packet pool\n");)
146
147 ExFreePool(Open);
148 ExFreePool(EvName);
149 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
150 IoCompleteRequest(Irp, IO_NO_INCREMENT);
151 return STATUS_INSUFFICIENT_RESOURCES;
152 }
153
154
155 RtlCopyBytes(EvName,L"\\BaseNamedObjects\\SEE0000000000",sizeof(L"\\BaseNamedObjects\\SEE0000000000"));
156
157 //Create the string containing the name of the read event
158 RtlInitUnicodeString(&Open->ReadEventName,(PCWSTR) EvName);
159
160 PacketItoa(NamedEventsCounter,(PUCHAR)(Open->ReadEventName.Buffer+21));
161
162 InterlockedIncrement(&NamedEventsCounter);
163
164 IF_LOUD(DbgPrint("\nCreated the named event for the read; name=%ws, counter=%d\n", Open->ReadEventName.Buffer,NamedEventsCounter-1);)
165
166 //allocate the event objects
167 Open->ReadEvent=IoCreateNotificationEvent(&Open->ReadEventName,&Open->ReadEventHandle);
168 if(Open->ReadEvent==NULL){
169 ExFreePool(Open);
170 ExFreePool(EvName);
171 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
172 IoCompleteRequest(Irp, IO_NO_INCREMENT);
173 return STATUS_INSUFFICIENT_RESOURCES;
174 }
175
176 KeInitializeEvent(Open->ReadEvent, NotificationEvent, FALSE);
177 KeClearEvent(Open->ReadEvent);
178 NdisInitializeEvent(&Open->WriteEvent);
179 NdisInitializeEvent(&Open->IOEvent);
180 NdisInitializeEvent(&Open->DumpEvent);
181 NdisAllocateSpinLock(&Open->MachineLock);
182 NdisAllocateSpinLock(&Open->WriteLock);
183 Open->WriteInProgress = FALSE;
184
185 // list to hold irp's want to reset the adapter
186 InitializeListHead(&Open->ResetIrpList);
187
188
189 // Initialize the request list
190 KeInitializeSpinLock(&Open->RequestSpinLock);
191 InitializeListHead(&Open->RequestList);
192
193 // Initializes the extended memory of the NPF machine
194 Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA');
195 if((Open->mem_ex.buffer) == NULL)
196 {
197 // no memory
198 ExFreePool(Open);
199 ExFreePool(EvName);
200 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
201 IoCompleteRequest(Irp, IO_NO_INCREMENT);
202 return STATUS_INSUFFICIENT_RESOURCES;
203 }
204
205 Open->mem_ex.size = DEFAULT_MEM_EX_SIZE;
206 RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE);
207
208 //
209 // Initialize the open instance
210 //
211 // Open->BufSize = 0;
212 // Open->Buffer = NULL;
213 // Open->Bhead = 0;
214 // Open->Btail = 0;
215 // (INT)Open->BLastByte = -1;
216 // Open->Dropped = 0; //reset the dropped packets counter
217 // Open->Received = 0; //reset the received packets counter
218 // Open->Accepted = 0; //reset the accepted packets counter
219 Open->bpfprogram = NULL; //reset the filter
220 Open->mode = MODE_CAPT;
221 Open->Nbytes.QuadPart = 0;
222 Open->Npackets.QuadPart = 0;
223 Open->Nwrites = 1;
224 Open->Multiple_Write_Counter = 0;
225 Open->MinToCopy = 0;
226 Open->TimeOut.QuadPart = (LONGLONG)1;
227 Open->Bound = TRUE;
228 Open->DumpFileName.Buffer = NULL;
229 Open->DumpFileHandle = NULL;
230 Open->tme.active = TME_NONE_ACTIVE;
231 Open->DumpLimitReached = FALSE;
232 Open->MaxFrameSize = 0;
233 Open->WriterSN=0;
234 Open->ReaderSN=0;
235 Open->Size=0;
236
237
238
239 //allocate the spinlock for the statistic counters
240 NdisAllocateSpinLock(&Open->CountersLock);
241
242 //allocate the spinlock for the buffer pointers
243 // NdisAllocateSpinLock(&Open->BufLock);
244
245 //
246 // link up the request stored in our open block
247 //
248 for (i=0;i<MAX_REQUESTS;i++) {
249 ExInterlockedInsertTailList(
250 &Open->RequestList,
251 &Open->Requests[i].ListElement,
252 &Open->RequestSpinLock);
253
254 }
255
256
257 IoMarkIrpPending(Irp);
258
259 //
260 // Try to open the MAC
261 //
262 IF_LOUD(DbgPrint("NPF: Opening the device %ws, BindingContext=%d\n",DeviceExtension->AdapterName.Buffer, Open);)
263
264 NdisOpenAdapter(
265 &Status,
266 &ErrorStatus,
267 &Open->AdapterHandle,
268 &Open->Medium,
269 MediumArray,
270 NUM_NDIS_MEDIA,
271 DeviceExtension->NdisProtocolHandle,
272 Open,
273 &DeviceExtension->AdapterName,
274 0,
275 NULL);
276
277 IF_LOUD(DbgPrint("NPF: Opened the device, Status=%x\n",Status);)
278
279 if (Status != NDIS_STATUS_PENDING)
280 {
281 NPF_OpenAdapterComplete(Open,Status,NDIS_STATUS_SUCCESS);
282 }
283
284 return(STATUS_PENDING);
285 }
286
287 //-------------------------------------------------------------------
288
NPF_OpenAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status,IN NDIS_STATUS OpenErrorStatus)289 VOID NPF_OpenAdapterComplete(
290 IN NDIS_HANDLE ProtocolBindingContext,
291 IN NDIS_STATUS Status,
292 IN NDIS_STATUS OpenErrorStatus)
293 {
294
295 PIRP Irp;
296 POPEN_INSTANCE Open;
297 PLIST_ENTRY RequestListEntry;
298 PINTERNAL_REQUEST MaxSizeReq;
299 NDIS_STATUS ReqStatus;
300
301
302 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete\n");)
303
304 Open= (POPEN_INSTANCE)ProtocolBindingContext;
305
306 //
307 // get the open irp
308 //
309 Irp=Open->OpenCloseIrp;
310
311 if (Status != NDIS_STATUS_SUCCESS) {
312
313 IF_LOUD(DbgPrint("NPF: OpenAdapterComplete-FAILURE\n");)
314
315 NdisFreePacketPool(Open->PacketPool);
316
317 //free mem_ex
318 Open->mem_ex.size = 0;
319 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
320
321 ExFreePool(Open->ReadEventName.Buffer);
322
323 ZwClose(Open->ReadEventHandle);
324
325
326 ExFreePool(Open);
327 }
328 else {
329 NdisAcquireSpinLock(&Opened_Instances_Lock);
330 n_Opened_Instances++;
331 NdisReleaseSpinLock(&Opened_Instances_Lock);
332
333 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
334
335 // Get the absolute value of the system boot time.
336 // This is used for timestamp conversion.
337 TIME_SYNCHRONIZE(&G_Start_Time);
338
339 // Extract a request from the list of free ones
340 RequestListEntry=ExInterlockedRemoveHeadList(&Open->RequestList, &Open->RequestSpinLock);
341
342 if (RequestListEntry == NULL)
343 {
344
345 Open->MaxFrameSize = 1600; // Assume Ethernet
346
347 Irp->IoStatus.Status = Status;
348 Irp->IoStatus.Information = 0;
349 IoCompleteRequest(Irp, IO_NO_INCREMENT);
350
351 return;
352 }
353
354 MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);
355 MaxSizeReq->Irp = Irp;
356 MaxSizeReq->Internal = TRUE;
357
358
359 MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
360 MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
361
362
363 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = &Open->MaxFrameSize;
364 MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
365
366 // submit the request
367 NdisRequest(
368 &ReqStatus,
369 Open->AdapterHandle,
370 &MaxSizeReq->Request);
371
372
373 if (ReqStatus != NDIS_STATUS_PENDING) {
374 NPF_RequestComplete(Open, &MaxSizeReq->Request, ReqStatus);
375 }
376
377 return;
378
379 }
380
381 Irp->IoStatus.Status = Status;
382 Irp->IoStatus.Information = 0;
383 IoCompleteRequest(Irp, IO_NO_INCREMENT);
384
385 return;
386
387 }
388
389 //-------------------------------------------------------------------
390
391 NTSTATUS
NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)392 NPF_Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
393 {
394
395 POPEN_INSTANCE Open;
396 NDIS_STATUS Status;
397 PIO_STACK_LOCATION IrpSp;
398 LARGE_INTEGER ThreadDelay;
399
400 IF_LOUD(DbgPrint("NPF: CloseAdapter\n");)
401
402 IrpSp = IoGetCurrentIrpStackLocation(Irp);
403
404 Open=IrpSp->FileObject->FsContext;
405
406 // Reset the buffer size. This tells the dump thread to stop.
407 // Open->BufSize = 0;
408
409 if( Open->Bound == FALSE){
410
411 NdisWaitEvent(&Open->IOEvent,10000);
412
413 // Free the filter if it's present
414 if(Open->bpfprogram != NULL)
415 ExFreePool(Open->bpfprogram);
416
417 //
418 // Jitted filters are supported on x86 (32bit) only
419 //
420 #ifdef __NPF_x86__
421 // Free the jitted filter if it's present
422 if(Open->Filter != NULL)
423 BPF_Destroy_JIT_Filter(Open->Filter);
424 #endif
425
426 //free the buffer
427 // Open->BufSize=0;
428 // if(Open->Buffer != NULL)ExFreePool(Open->Buffer);
429
430 if (Open->Size > 0)
431 ExFreePool(Open->CpuData[0].Buffer);
432
433 //free mem_ex
434 Open->mem_ex.size = 0;
435 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
436
437 NdisFreePacketPool(Open->PacketPool);
438
439 // Free the string with the name of the dump file
440 if(Open->DumpFileName.Buffer!=NULL)
441 ExFreePool(Open->DumpFileName.Buffer);
442
443 ExFreePool(Open->ReadEventName.Buffer);
444 ExFreePool(Open);
445
446 Irp->IoStatus.Information = 0;
447 Irp->IoStatus.Status = STATUS_SUCCESS;
448 IoCompleteRequest(Irp, IO_NO_INCREMENT);
449
450 return(STATUS_SUCCESS);
451 }
452
453 // Unfreeze the consumer
454 if(Open->mode & MODE_DUMP)
455 NdisSetEvent(&Open->DumpEvent);
456 else
457 KeSetEvent(Open->ReadEvent,0,FALSE);
458
459 // Save the IRP
460 Open->OpenCloseIrp = Irp;
461
462 IoMarkIrpPending(Irp);
463
464 // If this instance is in dump mode, complete the dump and close the file
465 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL){
466
467 NTSTATUS wres;
468
469 ThreadDelay.QuadPart = -50000000;
470 // Wait the completion of the thread
471 wres = KeWaitForSingleObject(Open->DumpThreadObject,
472 UserRequest,
473 KernelMode,
474 TRUE,
475 &ThreadDelay);
476
477 ObDereferenceObject(Open->DumpThreadObject);
478
479
480 // Flush and close the dump file
481 NPF_CloseDumpFile(Open);
482 }
483
484 // Destroy the read Event
485 ZwClose(Open->ReadEventHandle);
486
487 // Close the adapter
488 NdisCloseAdapter(
489 &Status,
490 Open->AdapterHandle
491 );
492
493 if (Status != NDIS_STATUS_PENDING) {
494
495 NPF_CloseAdapterComplete(
496 Open,
497 Status
498 );
499 return STATUS_SUCCESS;
500
501 }
502
503 return(STATUS_PENDING);
504 }
505
506 //-------------------------------------------------------------------
507
508 VOID
NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)509 NPF_CloseAdapterComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
510 {
511 POPEN_INSTANCE Open;
512 PIRP Irp;
513
514 IF_LOUD(DbgPrint("NPF: CloseAdapterComplete\n");)
515
516 Open= (POPEN_INSTANCE)ProtocolBindingContext;
517
518 // free the allocated structures only if the instance is still bound to the adapter
519 if(Open->Bound == TRUE){
520
521 // Free the filter if it's present
522 if(Open->bpfprogram != NULL)
523 ExFreePool(Open->bpfprogram);
524
525 //
526 // Jitted filters are supported on x86 (32bit) only
527 //
528 #ifdef __NPF_x86__
529 // Free the jitted filter if it's present
530 if(Open->Filter != NULL)
531 BPF_Destroy_JIT_Filter(Open->Filter);
532 #endif // __NPF_x86__
533
534 //free the buffer
535 // Open->BufSize = 0;
536 // if(Open->Buffer!=NULL)ExFreePool(Open->Buffer);
537
538 if (Open->Size > 0)
539 ExFreePool(Open->CpuData[0].Buffer);
540
541 //free mem_ex
542 Open->mem_ex.size = 0;
543 if(Open->mem_ex.buffer != NULL)ExFreePool(Open->mem_ex.buffer);
544
545 NdisFreePacketPool(Open->PacketPool);
546
547 Irp=Open->OpenCloseIrp;
548
549 // Free the string with the name of the dump file
550 if(Open->DumpFileName.Buffer!=NULL)
551 ExFreePool(Open->DumpFileName.Buffer);
552
553 ExFreePool(Open->ReadEventName.Buffer);
554 ExFreePool(Open);
555
556 // Complete the request only if the instance is still bound to the adapter
557 Irp->IoStatus.Status = STATUS_SUCCESS;
558 Irp->IoStatus.Information = 0;
559 IoCompleteRequest(Irp, IO_NO_INCREMENT);
560 }
561 else
562 NdisSetEvent(&Open->IOEvent);
563
564 // Decrease the counter of open instances
565 NdisAcquireSpinLock(&Opened_Instances_Lock);
566 n_Opened_Instances--;
567 NdisReleaseSpinLock(&Opened_Instances_Lock);
568
569 IF_LOUD(DbgPrint("Opened Instances:%d", n_Opened_Instances);)
570
571 if(n_Opened_Instances == 0){
572 // Force a synchronization at the next NPF_Open().
573 // This hopefully avoids the synchronization issues caused by hibernation or standby.
574 TIME_DESYNCHRONIZE(&G_Start_Time);
575 }
576
577 return;
578
579 }
580 //-------------------------------------------------------------------
581
582 #ifdef NDIS50
583 NDIS_STATUS
NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext,IN PNET_PNP_EVENT pNetPnPEvent)584 NPF_PowerChange(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnPEvent)
585 {
586 IF_LOUD(DbgPrint("NPF: PowerChange\n");)
587
588 TIME_DESYNCHRONIZE(&G_Start_Time);
589
590 TIME_SYNCHRONIZE(&G_Start_Time);
591
592 return STATUS_SUCCESS;
593 }
594 #endif
595
596 //-------------------------------------------------------------------
597
598 VOID
NPF_BindAdapter(OUT PNDIS_STATUS Status,IN NDIS_HANDLE BindContext,IN PNDIS_STRING DeviceName,IN PVOID SystemSpecific1,IN PVOID SystemSpecific2)599 NPF_BindAdapter(
600 OUT PNDIS_STATUS Status,
601 IN NDIS_HANDLE BindContext,
602 IN PNDIS_STRING DeviceName,
603 IN PVOID SystemSpecific1,
604 IN PVOID SystemSpecific2
605 )
606 {
607 IF_LOUD(DbgPrint("NPF: NPF_BindAdapter\n");)
608 }
609
610 //-------------------------------------------------------------------
611
612 VOID
NPF_UnbindAdapter(OUT PNDIS_STATUS Status,IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE UnbindContext)613 NPF_UnbindAdapter(
614 OUT PNDIS_STATUS Status,
615 IN NDIS_HANDLE ProtocolBindingContext,
616 IN NDIS_HANDLE UnbindContext
617 )
618 {
619 POPEN_INSTANCE Open =(POPEN_INSTANCE)ProtocolBindingContext;
620 NDIS_STATUS lStatus;
621
622 IF_LOUD(DbgPrint("NPF: NPF_UnbindAdapter\n");)
623
624 // Reset the buffer size. This tells the dump thread to stop.
625 // Open->BufSize=0;
626
627 NdisResetEvent(&Open->IOEvent);
628
629 // This open instance is no more bound to the adapter, set Bound to False
630 InterlockedExchange( (PLONG) &Open->Bound, FALSE );
631
632 // Awake a possible pending read on this instance
633 if(Open->mode & MODE_DUMP)
634 NdisSetEvent(&Open->DumpEvent);
635 else
636 KeSetEvent(Open->ReadEvent,0,FALSE);
637
638 // If this instance is in dump mode, complete the dump and close the file
639 if((Open->mode & MODE_DUMP) && Open->DumpFileHandle != NULL)
640 NPF_CloseDumpFile(Open);
641
642 // Destroy the read Event
643 ZwClose(Open->ReadEventHandle);
644
645 // close the adapter
646 NdisCloseAdapter(
647 &lStatus,
648 Open->AdapterHandle
649 );
650
651 if (lStatus != NDIS_STATUS_PENDING) {
652
653 NPF_CloseAdapterComplete(
654 Open,
655 lStatus
656 );
657
658 *Status = NDIS_STATUS_SUCCESS;
659 return;
660
661 }
662
663 *Status = NDIS_STATUS_SUCCESS;
664 return;
665 }
666
667 //-------------------------------------------------------------------
668
669 VOID
NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)670 NPF_ResetComplete(IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_STATUS Status)
671
672 {
673 POPEN_INSTANCE Open;
674 PIRP Irp;
675
676 PLIST_ENTRY ResetListEntry;
677
678 IF_LOUD(DbgPrint("NPF: PacketResetComplete\n");)
679
680 Open= (POPEN_INSTANCE)ProtocolBindingContext;
681
682
683 //
684 // remove the reset IRP from the list
685 //
686 ResetListEntry=ExInterlockedRemoveHeadList(
687 &Open->ResetIrpList,
688 &Open->RequestSpinLock
689 );
690
691 #if DBG
692 if (ResetListEntry == NULL) {
693 DbgBreakPoint();
694 return;
695 }
696 #endif
697
698 Irp=CONTAINING_RECORD(ResetListEntry,IRP,Tail.Overlay.ListEntry);
699
700 Irp->IoStatus.Status = STATUS_SUCCESS;
701 IoCompleteRequest(Irp, IO_NO_INCREMENT);
702
703 IF_LOUD(DbgPrint("NPF: PacketResetComplete exit\n");)
704
705 return;
706
707 }
708