ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

buffer.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS NDIS library
00004  * FILE:        ndis/buffer.c
00005  * PURPOSE:     Buffer management routines
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  * REVISIONS:
00008  *   CSH 01/08-2000 Created
00009  */
00010 
00011 #include <ndissys.h>
00012 
00013 
00014 __inline ULONG SkipToOffset(
00015     IN PNDIS_BUFFER Buffer,
00016     IN UINT Offset,
00017     IN OUT PUCHAR *Data,
00018     IN OUT PUINT Size)
00019 /*
00020  * FUNCTION: Skips Offset bytes into a buffer chain
00021  * ARGUMENTS:
00022  *     Buffer = Pointer to NDIS buffer
00023  *     Offset = Number of bytes to skip
00024  *     Data   = Address of a pointer that on return will contain the
00025  *              address of the offset in the buffer
00026  *     Size   = Address of a pointer that on return will contain the
00027  *              size of the destination buffer
00028  * RETURNS:
00029  *     Offset into buffer, -1 if buffer chain was smaller than Offset bytes
00030  * NOTES:
00031  *     Buffer may be NULL
00032  */
00033 {
00034     for (;;) {
00035 
00036         if (!Buffer)
00037             return 0xFFFFFFFF;
00038 
00039         NdisQueryBuffer(Buffer, (PVOID)Data, Size);
00040 
00041         if (Offset < *Size) {
00042             *Data  = (PUCHAR) ((ULONG_PTR) *Data + Offset);
00043             *Size -= Offset;
00044             break;
00045         }
00046 
00047         Offset -= *Size;
00048 
00049         NdisGetNextBuffer(Buffer, &Buffer);
00050     }
00051 
00052     return Offset;
00053 }
00054 
00055 UINT CopyBufferToBufferChain(
00056     PNDIS_BUFFER DstBuffer,
00057     UINT DstOffset,
00058     PUCHAR SrcData,
00059     UINT Length)
00060 /*
00061  * FUNCTION: Copies data from a buffer to an NDIS buffer chain
00062  * ARGUMENTS:
00063  *     DstBuffer = Pointer to destination NDIS buffer
00064  *     DstOffset = Destination start offset
00065  *     SrcData   = Pointer to source buffer
00066  *     Length    = Number of bytes to copy
00067  * RETURNS:
00068  *     Number of bytes copied to destination buffer
00069  * NOTES:
00070  *     The number of bytes copied may be limited by the destination
00071  *     buffer size
00072  */
00073 {
00074     UINT BytesCopied, BytesToCopy, DstSize;
00075     PUCHAR DstData;
00076 
00077     NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcData (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
00078 
00079     /* Skip DstOffset bytes in the destination buffer chain */
00080     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
00081         return 0;
00082 
00083     /* Start copying the data */
00084     BytesCopied = 0;
00085     for (;;) {
00086         BytesToCopy = MIN(DstSize, Length);
00087 
00088         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
00089         BytesCopied += BytesToCopy;
00090         SrcData      = (PUCHAR) ((ULONG_PTR) SrcData + BytesToCopy);
00091 
00092         Length -= BytesToCopy;
00093         if (Length == 0)
00094             break;
00095 
00096         DstSize -= BytesToCopy;
00097         if (DstSize == 0) {
00098             /* No more bytes in desination buffer. Proceed to
00099                the next buffer in the destination buffer chain */
00100             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00101             if (!DstBuffer)
00102                 break;
00103 
00104             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00105         }
00106     }
00107 
00108     return BytesCopied;
00109 }
00110 
00111 
00112 UINT CopyBufferChainToBuffer(
00113     PUCHAR DstData,
00114     PNDIS_BUFFER SrcBuffer,
00115     UINT SrcOffset,
00116     UINT Length)
00117 /*
00118  * FUNCTION: Copies data from an NDIS buffer chain to a buffer
00119  * ARGUMENTS:
00120  *     DstData   = Pointer to destination buffer
00121  *     SrcBuffer = Pointer to source NDIS buffer
00122  *     SrcOffset = Source start offset
00123  *     Length    = Number of bytes to copy
00124  * RETURNS:
00125  *     Number of bytes copied to destination buffer
00126  * NOTES:
00127  *     The number of bytes copied may be limited by the source
00128  *     buffer size
00129  */
00130 {
00131     UINT BytesCopied, BytesToCopy, SrcSize;
00132     PUCHAR SrcData;
00133 
00134     NDIS_DbgPrint(MAX_TRACE, ("DstData 0x%X  SrcBuffer 0x%X  SrcOffset 0x%X  Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
00135 
00136     /* Skip SrcOffset bytes in the source buffer chain */
00137     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
00138         return 0;
00139 
00140     /* Start copying the data */
00141     BytesCopied = 0;
00142     for (;;) {
00143         BytesToCopy = MIN(SrcSize, Length);
00144 
00145         NDIS_DbgPrint(MAX_TRACE, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
00146 
00147         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
00148         BytesCopied += BytesToCopy;
00149         DstData      = (PUCHAR)((ULONG_PTR) DstData + BytesToCopy);
00150 
00151         Length -= BytesToCopy;
00152         if (Length == 0)
00153             break;
00154 
00155         SrcSize -= BytesToCopy;
00156         if (SrcSize == 0) {
00157             /* No more bytes in source buffer. Proceed to
00158                the next buffer in the source buffer chain */
00159             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00160             if (!SrcBuffer)
00161                 break;
00162 
00163             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00164         }
00165     }
00166 
00167     return BytesCopied;
00168 }
00169 
00170 
00171 UINT CopyPacketToBuffer(
00172     PUCHAR DstData,
00173     PNDIS_PACKET SrcPacket,
00174     UINT SrcOffset,
00175     UINT Length)
00176 /*
00177  * FUNCTION: Copies data from an NDIS packet to a buffer
00178  * ARGUMENTS:
00179  *     DstData   = Pointer to destination buffer
00180  *     SrcPacket = Pointer to source NDIS packet
00181  *     SrcOffset = Source start offset
00182  *     Length    = Number of bytes to copy
00183  * RETURNS:
00184  *     Number of bytes copied to destination buffer
00185  * NOTES:
00186  *     The number of bytes copied may be limited by the source
00187  *     buffer size
00188  */
00189 {
00190     PNDIS_BUFFER FirstBuffer;
00191     PVOID Address;
00192     UINT FirstLength;
00193     UINT TotalLength;
00194 
00195     NDIS_DbgPrint(MAX_TRACE, ("DstData (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
00196 
00197     NdisGetFirstBufferFromPacket(SrcPacket,
00198                                  &FirstBuffer,
00199                                  &Address,
00200                                  &FirstLength,
00201                                  &TotalLength);
00202 
00203     return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
00204 }
00205 
00206 
00207 UINT CopyPacketToBufferChain(
00208     PNDIS_BUFFER DstBuffer,
00209     UINT DstOffset,
00210     PNDIS_PACKET SrcPacket,
00211     UINT SrcOffset,
00212     UINT Length)
00213 /*
00214  * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
00215  * ARGUMENTS:
00216  *     DstBuffer = Pointer to destination NDIS buffer
00217  *     DstOffset = Destination start offset
00218  *     SrcPacket = Pointer to source NDIS packet
00219  *     SrcOffset = Source start offset
00220  *     Length    = Number of bytes to copy
00221  * RETURNS:
00222  *     Number of bytes copied to destination buffer
00223  * NOTES:
00224  *     The number of bytes copied may be limited by the source and
00225  *     destination buffer sizes
00226  */
00227 {
00228     PNDIS_BUFFER SrcBuffer;
00229     PUCHAR DstData, SrcData;
00230     UINT DstSize, SrcSize;
00231     UINT Count, Total;
00232 
00233     NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
00234 
00235     /* Skip DstOffset bytes in the destination buffer chain */
00236     NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00237     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
00238         return 0;
00239     /* Skip SrcOffset bytes in the source packet */
00240     NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total);
00241     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
00242         return 0;
00243     /* Copy the data */
00244     for (Total = 0;;) {
00245         /* Find out how many bytes we can copy at one time */
00246         if (Length < SrcSize)
00247             Count = Length;
00248         else
00249             Count = SrcSize;
00250         if (DstSize < Count)
00251             Count = DstSize;
00252 
00253         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
00254 
00255         Total  += Count;
00256         Length -= Count;
00257         if (Length == 0)
00258             break;
00259 
00260         DstSize -= Count;
00261         if (DstSize == 0) {
00262             /* No more bytes in destination buffer. Proceed to
00263                the next buffer in the destination buffer chain */
00264             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00265             if (!DstBuffer)
00266                 break;
00267 
00268             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00269         }
00270 
00271         SrcSize -= Count;
00272         if (SrcSize == 0) {
00273             /* No more bytes in source buffer. Proceed to
00274                the next buffer in the source buffer chain */
00275             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00276             if (!SrcBuffer)
00277                 break;
00278 
00279             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00280         }
00281     }
00282 
00283     return Total;
00284 }
00285 
00286 
00287 /*
00288  * @implemented
00289  */
00290 #undef NdisAdjustBufferLength
00291 VOID
00292 EXPORT
00293 NdisAdjustBufferLength(
00294     IN PNDIS_BUFFER Buffer,
00295     IN UINT         Length)
00296 /*
00297  * FUNCTION: Modifies the length of an NDIS buffer
00298  * ARGUMENTS:
00299  *     Buffer = Pointer to NDIS buffer descriptor
00300  *     Length = New size of buffer
00301  */
00302 {
00303     Buffer->ByteCount = Length;
00304 }
00305 
00306 
00307 /*
00308  * @implemented
00309  */
00310 #undef NDIS_BUFFER_TO_SPAN_PAGES
00311 ULONG
00312 EXPORT
00313 NDIS_BUFFER_TO_SPAN_PAGES(
00314     IN  PNDIS_BUFFER    Buffer)
00315 /*
00316  * FUNCTION: Determines how many physical pages a buffer is made of
00317  * ARGUMENTS:
00318  *     Buffer = Pointer to NDIS buffer descriptor
00319  */
00320 {
00321     if (MmGetMdlByteCount(Buffer) == 0)
00322         return 1;
00323 
00324     return ADDRESS_AND_SIZE_TO_SPAN_PAGES(
00325             MmGetMdlVirtualAddress(Buffer),
00326             MmGetMdlByteCount(Buffer));
00327 }
00328 
00329 
00330 /*
00331  * @implemented
00332  */
00333 VOID
00334 EXPORT
00335 NdisAllocateBuffer(
00336     OUT PNDIS_STATUS    Status,
00337     OUT PNDIS_BUFFER    * Buffer,
00338     IN  NDIS_HANDLE     PoolHandle,
00339     IN  PVOID           VirtualAddress,
00340     IN  UINT            Length)
00341 /*
00342  * FUNCTION: Allocates an NDIS buffer descriptor
00343  * ARGUMENTS:
00344  *     Status         = Address of buffer for status
00345  *     Buffer         = Address of buffer for NDIS buffer descriptor
00346  *     PoolHandle     = Handle returned by NdisAllocateBufferPool
00347  *     VirtualAddress = Pointer to virtual address of data buffer
00348  *     Length         = Number of bytes in data buffer
00349  */
00350 {
00351     ASSERT(VirtualAddress != NULL);
00352     ASSERT(Length > 0);
00353 
00354     *Buffer = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL);
00355     if (*Buffer != NULL) {
00356         MmBuildMdlForNonPagedPool(*Buffer);
00357         (*Buffer)->Next = NULL;
00358         *Status = NDIS_STATUS_SUCCESS;
00359     } else {
00360         NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", VirtualAddress, Length));
00361         *Status = NDIS_STATUS_FAILURE;
00362     }
00363 }
00364 
00365 
00366 /*
00367  * @implemented
00368  */
00369 VOID
00370 EXPORT
00371 NdisAllocateBufferPool(
00372     OUT PNDIS_STATUS    Status,
00373     OUT PNDIS_HANDLE    PoolHandle,
00374     IN  UINT            NumberOfDescriptors)
00375 /*
00376  * FUNCTION: Allocates storage for an NDIS buffer pool
00377  * ARGUMENTS:
00378  *     Status              = Address of buffer for status
00379  *     PoolHandle          = Address of buffer for pool handle
00380  *     NumberOfDescriptors = Size of buffer pool in number of descriptors
00381  */
00382 {
00383     *Status = NDIS_STATUS_SUCCESS;
00384     *PoolHandle = 0;
00385 }
00386 
00387 
00388 /*
00389  * @implemented
00390  */
00391 VOID
00392 EXPORT
00393 NdisAllocatePacket(
00394     OUT PNDIS_STATUS    Status,
00395     OUT PNDIS_PACKET    * Packet,
00396     IN  NDIS_HANDLE     PoolHandle)
00397 /*
00398  * FUNCTION: Allocates an NDIS packet descriptor
00399  * ARGUMENTS:
00400  *     Status     = Address of buffer for status
00401  *     Packet     = Address of buffer for packet descriptor
00402  *     PoolHandle = Handle returned by NdisAllocatePacketPool
00403  */
00404 {
00405     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
00406 
00407     KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql);
00408     NdisDprAllocatePacketNonInterlocked(Status,
00409                                         Packet,
00410                                         PoolHandle);
00411     KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql);
00412 }
00413 
00414 
00415 /*
00416  * @implemented
00417  */
00418 VOID
00419 EXPORT
00420 NdisAllocatePacketPool(
00421     OUT PNDIS_STATUS    Status,
00422     OUT PNDIS_HANDLE    PoolHandle,
00423     IN  UINT            NumberOfDescriptors,
00424     IN  UINT            ProtocolReservedLength)
00425 /*
00426  * FUNCTION: Allocates storage for an NDIS packet pool
00427  * ARGUMENTS:
00428  *     Status                 = Address of buffer for status
00429  *     PoolHandle             = Address of buffer for pool handle
00430  *     NumberOfDescriptors    = Size of packet pool in number of descriptors
00431  *     ProtocolReservedLength = Size of protocol reserved area in bytes
00432  */
00433 {
00434     NdisAllocatePacketPoolEx(
00435         Status,
00436         PoolHandle,
00437         NumberOfDescriptors,
00438         0,
00439         ProtocolReservedLength);
00440 }
00441 
00442 
00443 /*
00444  * @implemented
00445  */
00446 VOID
00447 EXPORT
00448 NdisAllocatePacketPoolEx(
00449     OUT PNDIS_STATUS    Status,
00450     OUT PNDIS_HANDLE    PoolHandle,
00451     IN  UINT            NumberOfDescriptors,
00452     IN  UINT            NumberOfOverflowDescriptors,
00453     IN  UINT            ProtocolReservedLength)
00454 /*
00455  * FUNCTION:
00456  * ARGUMENTS:
00457  * NOTES:
00458  *    NDIS 5.0
00459  */
00460 {
00461     PNDISI_PACKET_POOL Pool;
00462     UINT Size, Length, i;
00463     PNDIS_PACKET Packet, NextPacket;
00464 
00465     NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  PoolHandle (0x%X)  "
00466         "NumberOfDescriptors (%d)  ProtocolReservedLength (%d).\n",
00467         Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength));
00468 
00469     *PoolHandle = NULL;
00470 
00471     if (NumberOfDescriptors > 0xffff)
00472     {
00473         NDIS_DbgPrint(MIN_TRACE, ("Invalid number of descriptors (%lx)\n", NumberOfDescriptors))
00474         *Status = NDIS_STATUS_RESOURCES;
00475     }
00476     else
00477     {
00478         NumberOfDescriptors += NumberOfOverflowDescriptors;
00479         if (NumberOfDescriptors > 0xffff)
00480         {
00481             NDIS_DbgPrint(MIN_TRACE, ("Total number of descriptors > 0xffff (%lx)\n", NumberOfDescriptors));
00482             NumberOfDescriptors = 0xffff;
00483         }
00484 
00485         Length = sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 
00486                  sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedLength;
00487         Size   = sizeof(NDISI_PACKET_POOL) + Length * NumberOfDescriptors;
00488 
00489         Pool   = ExAllocatePool(NonPagedPool, Size);
00490         if (Pool)
00491         {
00492             KeInitializeSpinLock(&Pool->SpinLock.SpinLock);
00493             Pool->PacketLength = Length;
00494 
00495             if (NumberOfDescriptors > 0)
00496             {
00497                 Packet         = (PNDIS_PACKET)&Pool->Buffer;
00498                 Pool->FreeList = Packet;
00499 
00500                 NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
00501                 for (i = 1; i < NumberOfDescriptors; i++)
00502                 {
00503                     Packet->Reserved[0]  = (ULONG_PTR)NextPacket;
00504                     Packet               = NextPacket;
00505                     NextPacket           = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
00506                 }
00507                 Packet->Reserved[0] = 0;
00508             }
00509             else {
00510                 NDIS_DbgPrint(MIN_TRACE, ("Attempted to allocate a packet pool with 0 descriptors\n"));
00511                 Pool->FreeList = NULL;
00512             }
00513 
00514             *Status     = NDIS_STATUS_SUCCESS;
00515             *PoolHandle = (PNDIS_HANDLE)Pool;
00516         } else {
00517             *Status = NDIS_STATUS_RESOURCES;
00518         }
00519     }
00520 }
00521 
00522 
00523 /*
00524  * @implemented
00525  */
00526 #undef NdisBufferLength
00527 ULONG
00528 EXPORT
00529 NdisBufferLength(
00530     IN  PNDIS_BUFFER    Buffer)
00531 /*
00532  * FUNCTION: Modifies the length of an NDIS buffer
00533  * ARGUMENTS:
00534  *     Buffer = Pointer to NDIS buffer descriptor
00535  *     Length = New size of buffer
00536  * NOTES:
00537  *    NDIS 5.0
00538  * RETURNS:
00539  *     Length of NDIS buffer
00540  */
00541 {
00542     return MmGetMdlByteCount(Buffer);
00543 }
00544 
00545 
00546 /*
00547  * @implemented
00548  */
00549 #undef NdisBufferVirtualAddress
00550 PVOID
00551 EXPORT
00552 NdisBufferVirtualAddress(
00553     IN  PNDIS_BUFFER    Buffer)
00554 /*
00555  * FUNCTION:
00556  * ARGUMENTS:
00557  * NOTES:
00558  *    NDIS 5.0
00559  */
00560 {
00561     return MmGetSystemAddressForMdl(Buffer);
00562 }
00563 
00564 
00565 /*
00566  * @implemented
00567  */
00568 VOID
00569 EXPORT
00570 NdisCopyFromPacketToPacket(
00571     IN  PNDIS_PACKET    Destination,
00572     IN  UINT            DestinationOffset,
00573     IN  UINT            BytesToCopy,
00574     IN  PNDIS_PACKET    Source,
00575     IN  UINT            SourceOffset,
00576     OUT PUINT           BytesCopied)
00577 /*
00578  * FUNCTION: Copies data from one packet to another
00579  * ARGUMENTS:
00580  *     Destination       = Pointer to packet to copy data to
00581  *     DestinationOffset = Offset in destination packet to copy data to
00582  *     BytesToCopy       = Number of bytes to copy
00583  *     Source            = Pointer to packet descriptor to copy from
00584  *     SourceOffset      = Offset in source packet to start copying from
00585  *     BytesCopied       = Address of buffer to place number of bytes copied
00586  */
00587 {
00588     PNDIS_BUFFER SrcBuffer;
00589     PNDIS_BUFFER DstBuffer;
00590     PUCHAR DstData, SrcData;
00591     UINT DstSize, SrcSize;
00592     UINT Count, Total;
00593 
00594     *BytesCopied = 0;
00595 
00596     /* Skip DestinationOffset bytes in the destination packet */
00597     NdisGetFirstBufferFromPacket(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total);
00598     if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF)
00599         return;
00600 
00601     /* Skip SourceOffset bytes in the source packet */
00602     NdisGetFirstBufferFromPacket(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total);
00603     if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
00604         return;
00605 
00606     /* Copy the data */
00607     for (Total = 0;;) {
00608         /* Find out how many bytes we can copy at one time */
00609         if (BytesToCopy < SrcSize)
00610             Count = BytesToCopy;
00611         else
00612             Count = SrcSize;
00613         if (DstSize < Count)
00614             Count = DstSize;
00615 
00616         RtlCopyMemory(DstData, SrcData, Count);
00617 
00618         Total       += Count;
00619         BytesToCopy -= Count;
00620         if (BytesToCopy == 0)
00621             break;
00622 
00623         DstSize -= Count;
00624         if (DstSize == 0) {
00625             /* No more bytes in destination buffer. Proceed to
00626                the next buffer in the destination buffer chain */
00627             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00628             if (!DstBuffer)
00629                 break;
00630 
00631             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00632         }
00633 
00634         SrcSize -= Count;
00635         if (SrcSize == 0) {
00636             /* No more bytes in source buffer. Proceed to
00637                the next buffer in the source buffer chain */
00638             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00639             if (!SrcBuffer)
00640                 break;
00641 
00642             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00643         }
00644     }
00645 
00646     *BytesCopied = Total;
00647 }
00648 
00649 
00650 /*
00651  * @implemented
00652  */
00653 VOID
00654 EXPORT
00655 NdisDprAllocatePacket(
00656     OUT PNDIS_STATUS    Status,
00657     OUT PNDIS_PACKET    *Packet,
00658     IN  NDIS_HANDLE     PoolHandle)
00659 /*
00660  * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL
00661  * ARGUMENTS:
00662  *     Status     = Address of buffer to place status of operation
00663  *     Packet     = Address of buffer to place a pointer to a packet descriptor
00664  *     PoolHandle = Handle returned by NdisAllocatePacketPool
00665  */
00666 {
00667     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
00668 
00669     KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock);
00670     NdisDprAllocatePacketNonInterlocked(Status,
00671                                         Packet,
00672                                         PoolHandle);
00673     KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock);
00674 }
00675 
00676 
00677 /*
00678  * @implemented
00679  */
00680 VOID
00681 EXPORT
00682 NdisDprAllocatePacketNonInterlocked(
00683     OUT PNDIS_STATUS    Status,
00684     OUT PNDIS_PACKET    *Packet,
00685     IN NDIS_HANDLE      PoolHandle)
00686 /*
00687  * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
00688  * ARGUMENTS:
00689  *     Status     = Address of buffer to place status of operation
00690  *     Packet     = Address of buffer to place a pointer to a packet descriptor
00691  *     PoolHandle = Handle returned by NdisAllocatePacketPool
00692  */
00693 {
00694     PNDIS_PACKET Temp;
00695     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle;
00696 
00697     NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  Packet (0x%X)  PoolHandle (0x%X).\n",
00698         Status, Packet, PoolHandle));
00699 
00700     *Packet = NULL;
00701 
00702     if (Pool == NULL)
00703     {
00704         *Status = NDIS_STATUS_FAILURE;
00705         NDIS_DbgPrint(MIN_TRACE, ("Called passed a bad pool handle\n"));
00706         return;
00707     }
00708 
00709     if (Pool->FreeList) {
00710         Temp           = Pool->FreeList;
00711         Pool->FreeList = (PNDIS_PACKET)Temp->Reserved[0];
00712 
00713         RtlZeroMemory(Temp, Pool->PacketLength);
00714         Temp->Private.Pool = Pool;
00715         Temp->Private.ValidCounts = TRUE;
00716         Temp->Private.NdisPacketFlags = fPACKET_ALLOCATED_BY_NDIS;
00717         Temp->Private.NdisPacketOobOffset = Pool->PacketLength -
00718                                             (sizeof(NDIS_PACKET_OOB_DATA) +
00719                                              sizeof(NDIS_PACKET_EXTENSION));
00720 
00721         *Packet = Temp;
00722         *Status = NDIS_STATUS_SUCCESS;
00723     } else {
00724         NDIS_DbgPrint(MIN_TRACE, ("No more free descriptors\n"));
00725         *Status = NDIS_STATUS_RESOURCES;
00726     }
00727 }
00728 
00729 
00730 /*
00731  * @implemented
00732  */
00733 VOID
00734 EXPORT
00735 NdisDprFreePacket(
00736     IN  PNDIS_PACKET    Packet)
00737 /*
00738  * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL
00739  * ARGUMENTS:
00740  *     Packet = Pointer to packet to free
00741  */
00742 {
00743     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool;
00744 
00745     KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock);
00746     NdisDprFreePacketNonInterlocked(Packet);
00747     KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock);
00748 }
00749 
00750 
00751 /*
00752  * @implemented
00753  */
00754 VOID
00755 EXPORT
00756 NdisDprFreePacketNonInterlocked(
00757     IN  PNDIS_PACKET    Packet)
00758 /*
00759  * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization)
00760  * ARGUMENTS:
00761  *     Packet = Pointer to packet to free
00762  */
00763 {
00764     NDIS_DbgPrint(MAX_TRACE, ("Packet (0x%X).\n", Packet));
00765 
00766     Packet->Reserved[0]          = (ULONG_PTR)((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList;
00767     ((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList = Packet;
00768 }
00769 
00770 
00771 /*
00772  * @implemented
00773  */
00774 VOID
00775 EXPORT
00776 NdisFreeBufferPool(
00777     IN  NDIS_HANDLE PoolHandle)
00778 /*
00779  * FUNCTION: Frees storage allocated for an NDIS buffer pool
00780  * ARGUMENTS:
00781  *     PoolHandle = Handle returned by NdisAllocateBufferPool
00782  */
00783 {
00784 }
00785 
00786 
00787 /*
00788  * @implemented
00789  */
00790 VOID
00791 EXPORT
00792 NdisFreePacketPool(
00793     IN  NDIS_HANDLE PoolHandle)
00794 /*
00795  * FUNCTION: Frees storage allocated for an NDIS packet pool
00796  * ARGUMENTS:
00797  *     PoolHandle = Handle returned by NdisAllocatePacketPool
00798  */
00799 {
00800     ExFreePool((PVOID)PoolHandle);
00801 }
00802 
00803 
00804 /*
00805  * @implemented
00806  */
00807 #undef NdisFreeBuffer
00808 VOID
00809 EXPORT
00810 NdisFreeBuffer(
00811     IN   PNDIS_BUFFER   Buffer)
00812 /*
00813  * FUNCTION: Puts an NDIS buffer descriptor back in it's pool
00814  * ARGUMENTS:
00815  *     Buffer = Pointer to buffer descriptor
00816  */
00817 {
00818     IoFreeMdl(Buffer);
00819 }
00820 
00821 
00822 /*
00823  * @implemented
00824  */
00825 VOID
00826 EXPORT
00827 NdisFreePacket(
00828     IN   PNDIS_PACKET   Packet)
00829 /*
00830  * FUNCTION: Puts an NDIS packet descriptor back in it's pool
00831  * ARGUMENTS:
00832  *     Packet = Pointer to packet descriptor
00833  */
00834 {
00835     PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool;
00836 
00837     KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql);
00838     NdisDprFreePacketNonInterlocked(Packet);
00839     KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql);
00840 }
00841 
00842 
00843 /*
00844  * @implemented
00845  */
00846 #undef NdisGetBufferPhysicalArraySize
00847 VOID
00848 EXPORT
00849 NdisGetBufferPhysicalArraySize(
00850     IN  PNDIS_BUFFER    Buffer,
00851     OUT PUINT           ArraySize)
00852 /*
00853  * FUNCTION: Returns number of discontiguous physical blocks backing a buffer
00854  * ARGUMENTS:
00855  *     Buffer    = Pointer to buffer descriptor
00856  *     ArraySize = Address of buffer to place number of physical blocks
00857  */
00858 {
00859   ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
00860   ASSERT(Buffer && ArraySize);
00861 
00862   *ArraySize = NDIS_BUFFER_TO_SPAN_PAGES(Buffer);
00863 }
00864 
00865 
00866 /*
00867  * @implemented
00868  */
00869 #undef NdisGetFirstBufferFromPacket
00870 VOID
00871 EXPORT
00872 NdisGetFirstBufferFromPacket(
00873     IN  PNDIS_PACKET    _Packet,
00874     OUT PNDIS_BUFFER    *_FirstBuffer,
00875     OUT PVOID           *_FirstBufferVA,
00876     OUT PUINT           _FirstBufferLength,
00877     OUT PUINT           _TotalBufferLength)
00878 /*
00879  * FUNCTION: Retrieves information about an NDIS packet
00880  * ARGUMENTS:
00881  *     _Packet            = Pointer to NDIS packet
00882  *     _FirstBuffer       = Address of buffer for pointer to first NDIS buffer
00883  *     _FirstBufferVA     = Address of buffer for address of first NDIS buffer
00884  *     _FirstBufferLength = Address of buffer for length of first buffer
00885  *     _TotalBufferLength = Address of buffer for total length of packet
00886  */
00887 {
00888     PNDIS_BUFFER Buffer;
00889 
00890     Buffer          = _Packet->Private.Head;
00891     *_FirstBuffer   = Buffer;
00892 
00893     if (Buffer != NULL) {
00894         *_FirstBufferLength = MmGetMdlByteCount(Buffer);
00895         *_FirstBufferVA = MmGetSystemAddressForMdl(Buffer);
00896         Buffer = Buffer->Next;
00897     } else {
00898         NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n"));
00899         *_FirstBufferLength = 0;
00900         *_FirstBufferVA = NULL;
00901     }
00902 
00903     *_TotalBufferLength = *_FirstBufferLength;
00904 
00905     while (Buffer != NULL) {
00906         *_TotalBufferLength += MmGetMdlByteCount(Buffer);
00907         Buffer = Buffer->Next;
00908     }
00909 }
00910 
00911 #undef NdisGetFirstBufferFromPacketSafe
00912 /*
00913  * @implemented
00914  */
00915 VOID
00916 EXPORT
00917 NdisGetFirstBufferFromPacketSafe(
00918     IN  PNDIS_PACKET     _Packet,
00919     OUT PNDIS_BUFFER     *_FirstBuffer,
00920     OUT PVOID            *_FirstBufferVA,
00921     OUT PUINT            _FirstBufferLength,
00922     OUT PUINT            _TotalBufferLength,
00923     IN  MM_PAGE_PRIORITY Priority)
00924 {
00925     PNDIS_BUFFER Buffer;
00926 
00927     Buffer          = _Packet->Private.Head;
00928     *_FirstBuffer   = Buffer;
00929 
00930     if (Buffer != NULL) {
00931         *_FirstBufferLength = MmGetMdlByteCount(Buffer);
00932         *_FirstBufferVA = MmGetSystemAddressForMdlSafe(Buffer, Priority);
00933         Buffer = Buffer->Next;
00934     } else {
00935         NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n"));
00936         *_FirstBufferLength = 0;
00937         *_FirstBufferVA = NULL;
00938     }
00939 
00940     *_TotalBufferLength = *_FirstBufferLength;
00941 
00942     while (Buffer != NULL) {
00943         *_TotalBufferLength += MmGetMdlByteCount(Buffer);
00944         Buffer = Buffer->Next;
00945     }
00946 }
00947 
00948 /*
00949  * @implemented
00950  */
00951 #undef NdisQueryBuffer
00952 VOID
00953 EXPORT
00954 NdisQueryBuffer(
00955     IN  PNDIS_BUFFER    Buffer,
00956     OUT PVOID           *VirtualAddress OPTIONAL,
00957     OUT PUINT           Length)
00958 /*
00959  * FUNCTION:
00960  *     Queries an NDIS buffer for information
00961  * ARGUMENTS:
00962  *     Buffer         = Pointer to NDIS buffer to query
00963  *     VirtualAddress = Address of buffer to place virtual address
00964  *     Length         = Address of buffer to place length of buffer
00965  */
00966 {
00967     if (VirtualAddress != NULL)
00968         *(PVOID*)VirtualAddress = MmGetSystemAddressForMdl(Buffer);
00969 
00970     *Length = MmGetMdlByteCount(Buffer);
00971 }
00972 
00973 
00974 /*
00975  * @implemented
00976  */
00977 #undef NdisQueryBufferSafe
00978 VOID
00979 EXPORT
00980 NdisQueryBufferSafe(
00981     IN  PNDIS_BUFFER    Buffer,
00982     OUT PVOID           *VirtualAddress OPTIONAL,
00983     OUT PUINT           Length,
00984     IN  UINT            Priority)
00985 /*
00986  * FUNCTION:
00987  * ARGUMENTS:
00988  * NOTES:
00989  *    NDIS 5.0
00990  */
00991 {
00992     if (VirtualAddress != NULL)
00993         *VirtualAddress = MmGetSystemAddressForMdlSafe(Buffer, Priority);
00994     *Length = MmGetMdlByteCount(Buffer);
00995 }
00996 
00997 
00998 /*
00999  * @implemented
01000  */
01001 #undef NdisQueryBufferOffset
01002 VOID
01003 EXPORT
01004 NdisQueryBufferOffset(
01005     IN  PNDIS_BUFFER    Buffer,
01006     OUT PUINT           Offset,
01007     OUT PUINT           Length)
01008 {
01009     *((PUINT)Offset) = MmGetMdlByteOffset(Buffer);
01010     *((PUINT)Length) = MmGetMdlByteCount(Buffer);
01011 }
01012 
01013 
01014 /*
01015  * @implemented
01016  */
01017 VOID
01018 EXPORT
01019 NdisUnchainBufferAtBack(
01020     IN OUT  PNDIS_PACKET    Packet,
01021     OUT     PNDIS_BUFFER    *Buffer)
01022 /*
01023  * FUNCTION:
01024  *     Removes the last buffer in a packet
01025  * ARGUMENTS:
01026  *     Packet = Pointer to NDIS packet
01027  *     Buffer = Address of buffer to place pointer to removed NDIS buffer
01028  */
01029 {
01030     PNDIS_BUFFER NdisBuffer, Previous;
01031 
01032     NdisQueryPacket(Packet,
01033                     NULL,
01034                     NULL,
01035                     &NdisBuffer,
01036                     NULL);
01037     if (!NdisBuffer) {
01038         NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n"));
01039         *Buffer = NULL;
01040         return;
01041     }
01042 
01043     Previous = NULL;
01044     while (NdisBuffer->Next) {
01045         Previous   = NdisBuffer;
01046         NdisBuffer = NdisBuffer->Next;
01047     }
01048 
01049     if (Previous) {
01050         Previous->Next       = NULL;
01051         Packet->Private.Tail = Previous;
01052     } else {
01053         Packet->Private.Head = NULL;
01054         Packet->Private.Tail = NULL;
01055     }
01056 
01057     Packet->Private.ValidCounts = FALSE;
01058 
01059     *Buffer = NdisBuffer;
01060 }
01061 
01062 
01063 /*
01064  * @implemented
01065  */
01066 VOID
01067 EXPORT
01068 NdisUnchainBufferAtFront(
01069     IN OUT  PNDIS_PACKET    Packet,
01070     OUT     PNDIS_BUFFER    *Buffer)
01071 /*
01072  * FUNCTION:
01073  *     Removes the first buffer in a packet
01074  * ARGUMENTS:
01075  *     Packet = Pointer to NDIS packet
01076  *     Buffer = Address of buffer to place pointer to removed NDIS buffer
01077  */
01078 {
01079     PNDIS_BUFFER NdisBuffer;
01080 
01081     NdisQueryPacket(Packet,
01082                     NULL,
01083                     NULL,
01084                     &NdisBuffer,
01085                     NULL);
01086     if (!NdisBuffer) {
01087         NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n"));
01088         *Buffer = NULL;
01089         return;
01090     }
01091 
01092     Packet->Private.Head = NdisBuffer->Next;
01093 
01094     if (!NdisBuffer->Next)
01095         Packet->Private.Tail = NULL;
01096 
01097     NdisBuffer->Next = NULL;
01098 
01099     Packet->Private.ValidCounts = FALSE;
01100 
01101     *Buffer = NdisBuffer;
01102 }
01103 
01104 /*
01105  * @implemented
01106  */
01107 VOID
01108 EXPORT
01109 NdisCopyBuffer(
01110     OUT PNDIS_STATUS    Status,
01111     OUT PNDIS_BUFFER    *Buffer,
01112     IN  NDIS_HANDLE     PoolHandle,
01113     IN  PVOID           MemoryDescriptor,
01114     IN  UINT            Offset,
01115     IN  UINT            Length)
01116 /*
01117  * FUNCTION: Returns a new buffer descriptor for a (partial) buffer
01118  * ARGUMENTS:
01119  *     Status           = Address of a buffer to place status of operation
01120  *     Buffer           = Address of a buffer to place new buffer descriptor
01121  *     PoolHandle       = Handle returned by NdisAllocateBufferPool
01122  *     MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER)
01123  *     Offset           = Offset in buffer to start copying
01124  *     Length           = Number of bytes to copy
01125  */
01126 {
01127     PVOID CurrentVa = (PUCHAR)(MmGetMdlVirtualAddress((PNDIS_BUFFER)MemoryDescriptor)) + Offset;
01128 
01129     NDIS_DbgPrint(MAX_TRACE, ("Called\n"));
01130 
01131     *Buffer = IoAllocateMdl(CurrentVa, Length, FALSE, FALSE, NULL);
01132     if (!*Buffer)
01133     {
01134         NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", CurrentVa, Length));
01135         *Status = NDIS_STATUS_FAILURE;
01136         return;
01137     }
01138 
01139     IoBuildPartialMdl((PNDIS_BUFFER)MemoryDescriptor,
01140                       *Buffer,
01141                       CurrentVa,
01142                       Length);
01143 
01144     (*Buffer)->Next = NULL;
01145     *Status = NDIS_STATUS_SUCCESS;
01146 }
01147 
01148 /*
01149  * @implemented
01150  */
01151 NDIS_HANDLE
01152 EXPORT
01153 NdisGetPoolFromPacket(
01154     IN PNDIS_PACKET  Packet)
01155 {
01156     return Packet->Private.Pool;
01157 }
01158 
01159 /*
01160  * @implemented
01161  */
01162 UINT
01163 EXPORT
01164 NdisPacketSize(
01165     IN UINT  ProtocolReservedSize)
01166 {
01167     return sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 
01168                  sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedSize;
01169 }
01170 
01171 /*
01172  * @implemented
01173  */
01174 #undef NdisGetPacketCancelId
01175 PVOID
01176 EXPORT
01177 NdisGetPacketCancelId(
01178     IN PNDIS_PACKET  Packet)
01179 {
01180     return NDIS_GET_PACKET_CANCEL_ID(Packet);
01181 }
01182 
01183 /*
01184  * @implemented
01185  */
01186 #undef NdisSetPacketCancelId
01187 VOID
01188 EXPORT
01189 NdisSetPacketCancelId(
01190     IN PNDIS_PACKET  Packet,
01191     IN PVOID  CancelId)
01192 {
01193     NDIS_SET_PACKET_CANCEL_ID(Packet, CancelId);
01194 }
01195 
01196 /*
01197  * @implemented
01198  */
01199 VOID
01200 EXPORT
01201 NdisCopyFromPacketToPacketSafe(
01202     IN  PNDIS_PACKET     Destination,
01203     IN  UINT             DestinationOffset,
01204     IN  UINT             BytesToCopy,
01205     IN  PNDIS_PACKET     Source,
01206     IN  UINT             SourceOffset,
01207     OUT PUINT            BytesCopied,
01208     IN  MM_PAGE_PRIORITY Priority)
01209 {
01210     PNDIS_BUFFER SrcBuffer;
01211     PNDIS_BUFFER DstBuffer;
01212     PUCHAR DstData, SrcData;
01213     UINT DstSize, SrcSize;
01214     UINT Count, Total;
01215 
01216     *BytesCopied = 0;
01217 
01218     /* Skip DestinationOffset bytes in the destination packet */
01219     NdisGetFirstBufferFromPacketSafe(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total, Priority);
01220     if (!DstData || SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF)
01221         return;
01222 
01223     /* Skip SourceOffset bytes in the source packet */
01224     NdisGetFirstBufferFromPacketSafe(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total, Priority);
01225     if (!SrcData || SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
01226         return;
01227 
01228     /* Copy the data */
01229     for (Total = 0;;) {
01230         /* Find out how many bytes we can copy at one time */
01231         if (BytesToCopy < SrcSize)
01232             Count = BytesToCopy;
01233         else
01234             Count = SrcSize;
01235         if (DstSize < Count)
01236             Count = DstSize;
01237 
01238         RtlCopyMemory(DstData, SrcData, Count);
01239 
01240         Total       += Count;
01241         BytesToCopy -= Count;
01242         if (BytesToCopy == 0)
01243             break;
01244 
01245         DstSize -= Count;
01246         if (DstSize == 0) {
01247             /* No more bytes in destination buffer. Proceed to
01248                the next buffer in the destination buffer chain */
01249             NdisGetNextBuffer(DstBuffer, &DstBuffer);
01250             if (!DstBuffer)
01251                 break;
01252 
01253             NdisQueryBufferSafe(DstBuffer, (PVOID)&DstData, &DstSize, Priority);
01254             if (!DstData)
01255                 break;
01256         }
01257 
01258         SrcSize -= Count;
01259         if (SrcSize == 0) {
01260             /* No more bytes in source buffer. Proceed to
01261                the next buffer in the source buffer chain */
01262             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
01263             if (!SrcBuffer)
01264                 break;
01265 
01266             NdisQueryBufferSafe(SrcBuffer, (PVOID)&SrcData, &SrcSize, Priority);
01267             if (!SrcData)
01268                 break;
01269         }
01270     }
01271 
01272     *BytesCopied = Total;
01273 }
01274 
01275 /*
01276  * @implemented
01277  */
01278 VOID
01279 EXPORT
01280 NdisIMCopySendCompletePerPacketInfo(
01281     IN  PNDIS_PACKET    DstPacket,
01282     IN  PNDIS_PACKET    SrcPacket)
01283 /*
01284  * FUNCTION:
01285  * ARGUMENTS:
01286  * NOTES:
01287  *    NDIS 5.0
01288  */
01289 {
01290     /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and
01291      * NdisIMCopySendCompletePerPacketInfo?
01292      */
01293 
01294     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
01295 
01296     RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket),
01297                   NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket),
01298                   sizeof(NDIS_PACKET_EXTENSION));
01299 }
01300 
01301 
01302 /*
01303  * @implemented
01304  */
01305 VOID
01306 EXPORT
01307 NdisIMCopySendPerPacketInfo(
01308     IN  PNDIS_PACKET    DstPacket,
01309     IN  PNDIS_PACKET    SrcPacket)
01310 /*
01311  * FUNCTION:
01312  * ARGUMENTS:
01313  * NOTES:
01314  *    NDIS 5.0
01315  */
01316 {
01317     /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and
01318      * NdisIMCopySendCompletePerPacketInfo?
01319      */
01320 
01321     NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
01322 
01323     RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket),
01324                   NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket),
01325                   sizeof(NDIS_PACKET_EXTENSION));
01326 }
01327 
01328 /* EOF */

Generated on Sun May 27 2012 04:21:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.