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 <stdarg.h> 00023 #include "ntddk.h" 00024 #include <ntiologc.h> 00025 #include <ndis.h> 00026 #include "debug.h" 00027 #include "packet.h" 00028 #include "win_bpf.h" 00029 00030 #include "tme.h" 00031 #include "time_calls.h" 00032 00033 extern struct time_conv G_Start_Time; // from openclos.c 00034 00035 //------------------------------------------------------------------- 00036 00037 UINT GetBuffOccupation(POPEN_INSTANCE Open) 00038 { 00039 UINT Occupation; 00040 00041 NdisAcquireSpinLock( &Open->BufLock ); 00042 00043 if(Open->Btail >= Open->Bhead) Occupation = Open->Btail-Open->Bhead; 00044 else Occupation = Open->BLastByte-Open->Bhead+Open->Btail; 00045 00046 NdisReleaseSpinLock( &Open->BufLock ); 00047 00048 return Occupation; 00049 } 00050 00051 //------------------------------------------------------------------- 00052 00053 void PacketMoveMem(PVOID Destination, PVOID Source, ULONG Length, UINT *Bhead) 00054 { 00055 ULONG WordLength; 00056 UINT n,i,NBlocks; 00057 00058 WordLength=Length>>2; 00059 NBlocks=WordLength>>8; 00060 00061 for(n=0;n<NBlocks;n++){ 00062 for(i=0;i<256;i++){ 00063 *((PULONG)Destination)++=*((PULONG)Source)++; 00064 } 00065 *Bhead+=1024; 00066 } 00067 00068 n=WordLength-(NBlocks<<8); 00069 for(i=0;i<n;i++){ 00070 *((PULONG)Destination)++=*((PULONG)Source)++; 00071 } 00072 *Bhead+=n<<2; 00073 00074 n=Length-(WordLength<<2); 00075 for(i=0;i<n;i++){ 00076 *((PUCHAR)Destination)++=*((PUCHAR)Source)++; 00077 } 00078 *Bhead+=n; 00079 } 00080 00081 //------------------------------------------------------------------- 00082 00083 NTSTATUS NPF_Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) 00084 { 00085 POPEN_INSTANCE Open; 00086 PIO_STACK_LOCATION IrpSp; 00087 PUCHAR packp; 00088 UINT i; 00089 ULONG Input_Buffer_Length; 00090 UINT Thead; 00091 UINT Ttail; 00092 UINT TLastByte; 00093 PUCHAR CurrBuff; 00094 UINT cplen; 00095 UINT CpStart; 00096 LARGE_INTEGER CapTime; 00097 LARGE_INTEGER TimeFreq; 00098 struct bpf_hdr *header; 00099 KIRQL Irql; 00100 PUCHAR UserPointer; 00101 ULONG bytecopy; 00102 00103 IF_LOUD(DbgPrint("NPF: Read\n");) 00104 00105 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00106 Open=IrpSp->FileObject->FsContext; 00107 00108 if( Open->Bound == FALSE ){ 00109 // The Network adapter was removed. 00110 EXIT_FAILURE(0); 00111 } 00112 00113 if( Open->mode & MODE_DUMP && Open->DumpFileHandle == NULL ){ 00114 // this instance is in dump mode, but the dump file has still not been opened 00115 EXIT_FAILURE(0); 00116 } 00117 00118 //See if the buffer is full enough to be copied 00119 if( GetBuffOccupation(Open) <= Open->MinToCopy || Open->mode & MODE_DUMP ) 00120 { 00121 //wait until some packets arrive or the timeout expires 00122 if(Open->TimeOut.QuadPart != (LONGLONG)IMMEDIATE) 00123 KeWaitForSingleObject(Open->ReadEvent, 00124 UserRequest, 00125 KernelMode, 00126 TRUE, 00127 (Open->TimeOut.QuadPart == (LONGLONG)0)? NULL: &(Open->TimeOut)); 00128 00129 KeClearEvent(Open->ReadEvent); 00130 00131 if(Open->mode & MODE_STAT){ //this capture instance is in statistics mode 00132 CurrBuff=(PUCHAR)MmGetSystemAddressForMdl(Irp->MdlAddress); 00133 00134 //fill the bpf header for this packet 00135 header=(struct bpf_hdr*)CurrBuff; 00136 GET_TIME(&header->bh_tstamp,&G_Start_Time); 00137 00138 if(Open->mode & MODE_DUMP){ 00139 *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+16)=Open->DumpOffset.QuadPart; 00140 header->bh_caplen=24; 00141 header->bh_datalen=24; 00142 Irp->IoStatus.Information = 24 + sizeof(struct bpf_hdr); 00143 } 00144 else{ 00145 header->bh_caplen=16; 00146 header->bh_datalen=16; 00147 header->bh_hdrlen=sizeof(struct bpf_hdr); 00148 Irp->IoStatus.Information = 16 + sizeof(struct bpf_hdr); 00149 } 00150 00151 *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr))=Open->Npackets.QuadPart; 00152 *(LONGLONG*)(CurrBuff+sizeof(struct bpf_hdr)+8)=Open->Nbytes.QuadPart; 00153 00154 //reset the countetrs 00155 NdisAcquireSpinLock( &Open->CountersLock ); 00156 Open->Npackets.QuadPart=0; 00157 Open->Nbytes.QuadPart=0; 00158 NdisReleaseSpinLock( &Open->CountersLock ); 00159 00160 Irp->IoStatus.Status = STATUS_SUCCESS; 00161 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00162 00163 return STATUS_SUCCESS; 00164 } 00165 00166 if(Open->mode==MODE_MON) //this capture instance is in monitor mode 00167 { 00168 PTME_DATA data; 00169 ULONG cnt; 00170 ULONG block_size; 00171 PUCHAR tmp; 00172 00173 UserPointer=MmGetSystemAddressForMdl(Irp->MdlAddress); 00174 00175 if ((!IS_VALIDATED(Open->tme.validated_blocks,Open->tme.active_read))||(IrpSp->Parameters.Read.Length<sizeof(struct bpf_hdr))) 00176 { 00177 EXIT_FAILURE(0); 00178 } 00179 00180 header=(struct bpf_hdr*)UserPointer; 00181 00182 GET_TIME(&header->bh_tstamp,&G_Start_Time); 00183 00184 00185 header->bh_hdrlen=sizeof(struct bpf_hdr); 00186 00187 00188 //moves user memory pointer 00189 UserPointer+=sizeof(struct bpf_hdr); 00190 00191 //calculus of data to be copied 00192 //if the user buffer is smaller than data to be copied, 00193 //only some data will be copied 00194 data=&Open->tme.block_data[Open->tme.active_read]; 00195 00196 if (data->last_read.tv_sec!=0) 00197 data->last_read=header->bh_tstamp; 00198 00199 00200 bytecopy=data->block_size*data->filled_blocks; 00201 00202 if ((IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))<bytecopy) 00203 bytecopy=(IrpSp->Parameters.Read.Length-sizeof(struct bpf_hdr))/ data->block_size; 00204 else 00205 bytecopy=data->filled_blocks; 00206 00207 tmp=data->shared_memory_base_address; 00208 block_size=data->block_size; 00209 00210 for (cnt=0;cnt<bytecopy;cnt++) 00211 { 00212 NdisAcquireSpinLock(&Open->machine_lock); 00213 RtlCopyMemory(UserPointer,tmp,block_size); 00214 NdisReleaseSpinLock(&Open->machine_lock); 00215 tmp+=block_size; 00216 UserPointer+=block_size; 00217 } 00218 00219 bytecopy*=block_size; 00220 00221 header->bh_caplen=bytecopy; 00222 header->bh_datalen=header->bh_caplen; 00223 00224 EXIT_SUCCESS(bytecopy+sizeof(struct bpf_hdr)); 00225 } 00226 00227 if (Open->Bhead == Open->Btail || Open->mode & MODE_DUMP) 00228 // The timeout has expired, but the buffer is still empty (or the packets must be written to file). 00229 // We must awake the application, returning an empty buffer. 00230 { 00231 EXIT_SUCCESS(0); 00232 } 00233 00234 } 00235 00236 // 00237 // The buffer if full enough to be copied, 00238 // 00239 NdisAcquireSpinLock( &Open->BufLock ); 00240 00241 Thead = Open->Bhead; 00242 Ttail = Open->Btail; 00243 TLastByte = Open->BLastByte; 00244 00245 //get the address of the buffer 00246 CurrBuff=Open->Buffer; 00247 00248 NdisReleaseSpinLock( &Open->BufLock ); 00249 00250 Input_Buffer_Length=IrpSp->Parameters.Read.Length; 00251 packp=(PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress); 00252 00253 00254 // 00255 //fill the application buffer 00256 // 00257 if(Ttail > Thead){ //first of all see if it we can copy all the buffer in one time 00258 if((Ttail-Thead)<Input_Buffer_Length){ 00259 KeResetEvent(Open->ReadEvent); 00260 00261 PacketMoveMem(packp,CurrBuff+Thead,Ttail-Thead,&(Open->Bhead)); 00262 EXIT_SUCCESS(Ttail-Thead); 00263 } 00264 } 00265 else if((TLastByte - Thead) < Input_Buffer_Length){ 00266 PacketMoveMem(packp, CurrBuff+Thead, TLastByte - Thead, &(Open->Bhead)); 00267 00268 NdisAcquireSpinLock( &Open->BufLock ); 00269 00270 Open->BLastByte = Open->Btail; 00271 Open->Bhead = 0; 00272 00273 NdisReleaseSpinLock( &Open->BufLock ); 00274 00275 EXIT_SUCCESS(TLastByte-Thead); 00276 } 00277 00278 //the buffer must be scannned to determine the number of bytes to copy 00279 CpStart=Thead; 00280 i=0; 00281 while(TRUE){ 00282 if(Thead == Ttail)break; 00283 00284 if(Thead == TLastByte){ 00285 // Copy the portion between thead and TLastByte 00286 PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); 00287 packp+=(Thead-CpStart); 00288 00289 NdisAcquireSpinLock( &Open->BufLock ); 00290 00291 Open->BLastByte = Open->Btail; 00292 Open->Bhead = 0; 00293 00294 NdisReleaseSpinLock( &Open->BufLock ); 00295 00296 Thead=0; 00297 CpStart=0; 00298 } 00299 cplen=((struct bpf_hdr*)(CurrBuff+Thead))->bh_caplen+sizeof(struct bpf_hdr); 00300 00301 if((i+cplen > Input_Buffer_Length)){//no more space in the application's buffer 00302 PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); 00303 00304 EXIT_SUCCESS(i); 00305 } 00306 cplen=Packet_WORDALIGN(cplen); 00307 i+=cplen; 00308 Thead+=cplen; 00309 } 00310 00311 00312 KeResetEvent(Open->ReadEvent); 00313 00314 PacketMoveMem(packp,CurrBuff+CpStart,Thead-CpStart,&(Open->Bhead)); 00315 00316 Open->Bhead=Thead; 00317 00318 00319 EXIT_SUCCESS(i); 00320 } 00321 00322 //------------------------------------------------------------------- 00323 00324 NDIS_STATUS NPF_tap (IN NDIS_HANDLE ProtocolBindingContext,IN NDIS_HANDLE MacReceiveContext, 00325 IN PVOID HeaderBuffer,IN UINT HeaderBufferSize,IN PVOID LookAheadBuffer, 00326 IN UINT LookaheadBufferSize,IN UINT PacketSize) 00327 { 00328 POPEN_INSTANCE Open; 00329 PNDIS_PACKET pPacketb; 00330 ULONG SizeToTransfer; 00331 NDIS_STATUS Status; 00332 UINT BytesTransfered; 00333 ULONG BufferLength; 00334 PMDL pMdl; 00335 LARGE_INTEGER CapTime; 00336 LARGE_INTEGER TimeFreq; 00337 struct bpf_hdr *header; 00338 PUCHAR CurrBuff; 00339 UINT Thead; 00340 UINT Ttail; 00341 UINT TLastByte; 00342 UINT fres; 00343 UINT maxbufspace; 00344 USHORT NPFHdrSize; 00345 UINT BufOccupation; 00346 00347 IF_VERY_LOUD(DbgPrint("NPF: tap\n");) 00348 00349 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00350 00351 Open->Received++; // Number of packets received by filter ++ 00352 00353 BufOccupation = GetBuffOccupation(Open); // Get the full buffer space 00354 00355 if(((Open->mode&MODE_CAPT)||(Open->mode&MODE_DUMP)) && Open->BufSize - BufOccupation < PacketSize+HeaderBufferSize+sizeof(struct bpf_hdr)){ 00356 // Heuristic that drops the packet also if it possibly fits in the buffer. 00357 // It allows to avoid filtering in critical situations when CPU is very important. 00358 Open->Dropped++; 00359 return NDIS_STATUS_NOT_ACCEPTED; 00360 } 00361 00362 NdisAcquireSpinLock(&Open->machine_lock); 00363 00364 // 00365 //Check if the lookahead buffer follows the mac header. 00366 //If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is 00367 //executed on the packet. 00368 //Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or 00369 //things like this) bpf_filter_with_2_buffers() is executed. 00370 // 00371 if((UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize) 00372 fres=bpf_filter_with_2_buffers((struct bpf_insn*)(Open->bpfprogram), 00373 HeaderBuffer, 00374 LookAheadBuffer, 00375 HeaderBufferSize, 00376 PacketSize+HeaderBufferSize, 00377 LookaheadBufferSize+HeaderBufferSize, 00378 &Open->mem_ex, 00379 &Open->tme, 00380 &G_Start_Time); 00381 00382 00383 else 00384 if(Open->Filter != NULL) 00385 { 00386 if (Open->bpfprogram != NULL) 00387 { 00388 fres=Open->Filter->Function(HeaderBuffer, 00389 PacketSize+HeaderBufferSize, 00390 LookaheadBufferSize+HeaderBufferSize); 00391 00392 // Restore the stack. 00393 // I ignore the reason, but this instruction is needed only at kernel level 00394 _asm add esp,12 00395 } 00396 else 00397 fres = -1; 00398 } 00399 else 00400 fres=bpf_filter((struct bpf_insn*)(Open->bpfprogram), 00401 HeaderBuffer, 00402 PacketSize+HeaderBufferSize, 00403 LookaheadBufferSize+HeaderBufferSize, 00404 &Open->mem_ex, 00405 &Open->tme, 00406 &G_Start_Time); 00407 00408 NdisReleaseSpinLock(&Open->machine_lock); 00409 00410 if(Open->mode==MODE_MON) 00411 // we are in monitor mode 00412 { 00413 if (fres==1) 00414 KeSetEvent(Open->ReadEvent,0,FALSE); 00415 return NDIS_STATUS_NOT_ACCEPTED; 00416 00417 } 00418 00419 if(fres==0) 00420 // Packet not accepted by the filter, ignore it. 00421 return NDIS_STATUS_NOT_ACCEPTED; 00422 00423 //if the filter returns -1 the whole packet must be accepted 00424 if(fres==-1 || fres > PacketSize+HeaderBufferSize)fres=PacketSize+HeaderBufferSize; 00425 00426 if(Open->mode & MODE_STAT){ 00427 // we are in statistics mode 00428 NdisAcquireSpinLock( &Open->CountersLock ); 00429 00430 Open->Npackets.QuadPart++; 00431 00432 if(PacketSize+HeaderBufferSize<60) 00433 Open->Nbytes.QuadPart+=60; 00434 else 00435 Open->Nbytes.QuadPart+=PacketSize+HeaderBufferSize; 00436 // add preamble+SFD+FCS to the packet 00437 // these values must be considered because are not part of the packet received from NDIS 00438 Open->Nbytes.QuadPart+=12; 00439 00440 NdisReleaseSpinLock( &Open->CountersLock ); 00441 00442 if(!(Open->mode & MODE_DUMP)){ 00443 return NDIS_STATUS_NOT_ACCEPTED; 00444 } 00445 } 00446 00447 if(Open->BufSize==0)return NDIS_STATUS_NOT_ACCEPTED; 00448 00449 if(Open->mode & MODE_DUMP && Open->MaxDumpPacks && (UINT)Open->Accepted > Open->MaxDumpPacks){ 00450 // Reached the max number of packets to save in the dump file. Discard the packet and stop the dump thread. 00451 Open->DumpLimitReached = TRUE; // This stops the thread 00452 // Awake the dump thread 00453 NdisSetEvent(&Open->DumpEvent); 00454 00455 // Awake the application 00456 KeSetEvent(Open->ReadEvent,0,FALSE); 00457 00458 return NDIS_STATUS_NOT_ACCEPTED; 00459 } 00460 00461 // Calculate the correct size for the header associated with the packet 00462 NPFHdrSize=(Open->mode==MODE_CAPT)? sizeof(struct bpf_hdr): sizeof(struct sf_pkthdr); 00463 00464 NdisAcquireSpinLock( &Open->BufLock ); 00465 00466 Thead=Open->Bhead; 00467 Ttail=Open->Btail; 00468 TLastByte = Open->BLastByte; 00469 00470 NdisReleaseSpinLock( &Open->BufLock ); 00471 00472 maxbufspace=Packet_WORDALIGN(fres+NPFHdrSize); 00473 00474 if(Ttail+maxbufspace >= Open->BufSize){ 00475 if(Thead <= maxbufspace) 00476 { 00477 Open->Dropped++; 00478 return NDIS_STATUS_NOT_ACCEPTED; 00479 } 00480 else{ 00481 Ttail=0; 00482 } 00483 } 00484 00485 CurrBuff=Open->Buffer+Ttail; 00486 00487 if(LookaheadBufferSize != PacketSize || (UINT)LookAheadBuffer-(UINT)HeaderBuffer != HeaderBufferSize) 00488 { 00489 // Allocate an MDL to map the portion of the buffer following the header 00490 pMdl=IoAllocateMdl(CurrBuff+HeaderBufferSize+LookaheadBufferSize+NPFHdrSize, 00491 maxbufspace, 00492 FALSE, 00493 FALSE, 00494 NULL); 00495 00496 if (pMdl == NULL) 00497 { 00498 // Unable to map the memory: packet lost 00499 IF_LOUD(DbgPrint("NPF: Read-Failed to allocate Mdl\n");) 00500 Open->Dropped++; 00501 return NDIS_STATUS_NOT_ACCEPTED; 00502 } 00503 MmBuildMdlForNonPagedPool(pMdl); 00504 00505 //allocate the packet from NDIS 00506 NdisAllocatePacket(&Status, &pPacketb, Open->PacketPool); 00507 if (Status != NDIS_STATUS_SUCCESS) 00508 { 00509 IF_LOUD(DbgPrint("NPF: Tap - No free packets\n");) 00510 IoFreeMdl(pMdl); 00511 Open->Dropped++; 00512 return NDIS_STATUS_NOT_ACCEPTED; 00513 } 00514 //link the buffer to the packet 00515 NdisChainBufferAtFront(pPacketb,pMdl); 00516 00517 BufferLength=fres-HeaderBufferSize; 00518 //Find out how much to transfer 00519 SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength; 00520 00521 //copy the ethernet header into buffer 00522 NdisMoveMappedMemory((CurrBuff)+NPFHdrSize,HeaderBuffer,HeaderBufferSize); 00523 00524 //Copy the look ahead buffer 00525 if(LookaheadBufferSize) 00526 { 00527 NdisMoveMappedMemory((CurrBuff) + NPFHdrSize + HeaderBufferSize, 00528 LookAheadBuffer, 00529 (SizeToTransfer < LookaheadBufferSize)? SizeToTransfer : LookaheadBufferSize ); 00530 00531 SizeToTransfer = (SizeToTransfer > LookaheadBufferSize)? 00532 SizeToTransfer - LookaheadBufferSize : 0; 00533 } 00534 00535 Open->TransferMdl=pMdl; 00536 00537 if(SizeToTransfer) 00538 { 00539 //Call the Mac to transfer the packet 00540 NdisTransferData(&Status, 00541 Open->AdapterHandle, 00542 MacReceiveContext, 00543 LookaheadBufferSize, 00544 SizeToTransfer, 00545 pPacketb, 00546 &BytesTransfered); 00547 } 00548 else{ 00549 BytesTransfered = 0; 00550 } 00551 00552 } 00553 else 00554 { 00555 // The whole packet is in the lookahead buffer, we can avoid the call to NdisTransferData. 00556 // This allows us to avoid the allocation of the MDL and the NDIS packet as well 00557 RtlCopyMemory((CurrBuff) + NPFHdrSize, 00558 HeaderBuffer, 00559 HeaderBufferSize + LookaheadBufferSize); 00560 00561 Open->TransferMdl = NULL; 00562 Status = NDIS_STATUS_SUCCESS; 00563 } 00564 00565 Open->Accepted++; // Increase the accepted packets counter 00566 00567 if (Status != NDIS_STATUS_FAILURE) 00568 { 00569 00570 if( fres > (BytesTransfered+HeaderBufferSize+LookaheadBufferSize) ) 00571 fres = BytesTransfered+HeaderBufferSize+LookaheadBufferSize; 00572 00573 // 00574 // Build the header 00575 // 00576 header=(struct bpf_hdr*)CurrBuff; 00577 GET_TIME(&header->bh_tstamp,&G_Start_Time); 00578 header->bh_caplen=fres; 00579 header->bh_datalen=PacketSize+HeaderBufferSize; 00580 if(Open->mode==MODE_CAPT){ 00581 header->bh_hdrlen=NPFHdrSize; 00582 // Don't align if the packet goes to disk 00583 Ttail+=Packet_WORDALIGN(fres + NPFHdrSize); 00584 } 00585 else 00586 Ttail+=fres+NPFHdrSize; 00587 00588 //update the buffer 00589 if(Ttail > Thead)TLastByte = Ttail; 00590 00591 NdisAcquireSpinLock( &Open->BufLock ); 00592 00593 Open->Btail=Ttail; 00594 Open->BLastByte=TLastByte; 00595 00596 NdisReleaseSpinLock( &Open->BufLock ); 00597 } 00598 00599 if (Status != NDIS_STATUS_PENDING){ 00600 00601 if( Open->TransferMdl != NULL) 00602 // Complete the request and free the buffers 00603 NPF_TransferDataComplete(Open,pPacketb,Status,fres); 00604 else{ 00605 // Unfreeze the consumer 00606 if(GetBuffOccupation(Open)>Open->MinToCopy){ 00607 if(Open->mode & MODE_DUMP){ 00608 NdisSetEvent(&Open->DumpEvent); 00609 } 00610 else 00611 KeSetEvent(Open->ReadEvent,0,FALSE); 00612 } 00613 00614 } 00615 } 00616 00617 return NDIS_STATUS_SUCCESS; 00618 00619 } 00620 00621 //------------------------------------------------------------------- 00622 00623 VOID NPF_TransferDataComplete (IN NDIS_HANDLE ProtocolBindingContext,IN PNDIS_PACKET pPacket, 00624 IN NDIS_STATUS Status,IN UINT BytesTransfered) 00625 { 00626 POPEN_INSTANCE Open; 00627 00628 IF_LOUD(DbgPrint("NPF: TransferDataComplete\n");) 00629 00630 Open= (POPEN_INSTANCE)ProtocolBindingContext; 00631 00632 IoFreeMdl(Open->TransferMdl); 00633 //recylcle the packet 00634 NdisReinitializePacket(pPacket); 00635 //Put the packet on the free queue 00636 NdisFreePacket(pPacket); 00637 // Unfreeze the consumer 00638 if(GetBuffOccupation(Open)>Open->MinToCopy){ 00639 if(Open->mode & MODE_DUMP){ 00640 NdisSetEvent(&Open->DumpEvent); 00641 } 00642 else 00643 KeSetEvent(Open->ReadEvent,0,FALSE); 00644 } 00645 return; 00646 } 00647 00648 //------------------------------------------------------------------- 00649 00650 VOID NPF_ReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext) 00651 { 00652 IF_VERY_LOUD(DbgPrint("NPF: NPF_ReceiveComplete\n");) 00653 return; 00654 }
documentation. Copyright (c) 2002 Politecnico di Torino. All rights reserved.