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