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 TCP/IP protocol driver
00004  * FILE:        tcpip/buffer.c
00005  * PURPOSE:     Miscellaneous operations on NDIS_BUFFERs and packets.
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  * REVISIONS:
00008  *   CSH 01/08-2000 Created
00009  */
00010 
00011 #include "precomp.h"
00012 
00013 __inline INT SkipToOffset(
00014     PNDIS_BUFFER Buffer,
00015     UINT Offset,
00016     PCHAR *Data,
00017     PUINT Size)
00018 /*
00019  * FUNCTION: Skip Offset bytes into a buffer chain
00020  * ARGUMENTS:
00021  *     Buffer = Pointer to NDIS buffer
00022  *     Offset = Number of bytes to skip
00023  *     Data   = Address of a pointer that on return will contain the
00024  *              address of the offset in the buffer
00025  *     Size   = Address of a pointer that on return will contain the
00026  *              size of the destination buffer
00027  * RETURNS:
00028  *     Offset into buffer, -1 if buffer chain was smaller than Offset bytes
00029  * NOTES:
00030  *     Buffer may be NULL
00031  */
00032 {
00033     for (;;) {
00034 
00035         if (!Buffer)
00036             return -1;
00037 
00038         NdisQueryBuffer(Buffer, (PVOID)Data, Size);
00039 
00040         if (Offset < *Size) {
00041             *Data = (PCHAR)((ULONG_PTR) *Data + Offset);
00042             *Size              -= Offset;
00043             break;
00044         }
00045 
00046         Offset -= *Size;
00047 
00048         NdisGetNextBuffer(Buffer, &Buffer);
00049     }
00050 
00051     return Offset;
00052 }
00053 
00054 
00055 UINT CopyBufferToBufferChain(
00056     PNDIS_BUFFER DstBuffer,
00057     UINT DstOffset,
00058     PCHAR 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     PCHAR DstData;
00076 
00077     TI_DbgPrint(DEBUG_PBUFFER, ("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) == -1)
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      = (PCHAR)((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     PCHAR 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     PCHAR SrcData;
00133 
00134     TI_DbgPrint(DEBUG_PBUFFER, ("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) == -1)
00138         return 0;
00139 
00140     /* Start copying the data */
00141     BytesCopied = 0;
00142     for (;;) {
00143         BytesToCopy = MIN(SrcSize, Length);
00144 
00145         TI_DbgPrint(DEBUG_PBUFFER, ("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      = (PCHAR)((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     PCHAR 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     TI_DbgPrint(DEBUG_PBUFFER, ("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     PCHAR DstData, SrcData;
00230     UINT DstSize, SrcSize;
00231     UINT Count, Total;
00232 
00233     TI_DbgPrint(DEBUG_PBUFFER, ("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) == -1)
00238         return 0;
00239 
00240     /* Skip SrcOffset bytes in the source packet */
00241     NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID)&SrcData, &SrcSize, &Total);
00242     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
00243         return 0;
00244 
00245     /* Copy the data */
00246     for (Total = 0;;) {
00247         /* Find out how many bytes we can copy at one time */
00248         if (Length < SrcSize)
00249             Count = Length;
00250         else
00251             Count = SrcSize;
00252         if (DstSize < Count)
00253             Count = DstSize;
00254 
00255         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
00256 
00257         Total  += Count;
00258         Length -= Count;
00259         if (Length == 0)
00260             break;
00261 
00262         DstSize -= Count;
00263         if (DstSize == 0) {
00264             /* No more bytes in destination buffer. Proceed to
00265                the next buffer in the destination buffer chain */
00266             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00267             if (!DstBuffer)
00268                 break;
00269 
00270             NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00271         }
00272 
00273         SrcSize -= Count;
00274         if (SrcSize == 0) {
00275             /* No more bytes in source buffer. Proceed to
00276                the next buffer in the source buffer chain */
00277             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00278             if (!SrcBuffer)
00279                 break;
00280 
00281             NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00282         }
00283     }
00284 
00285     return Total;
00286 }
00287 
00288 
00289 UINT ResizePacket(
00290     PNDIS_PACKET Packet,
00291     UINT Size)
00292 /*
00293  * FUNCTION: Resizes an NDIS packet
00294  * ARGUMENTS:
00295  *     Packet = Pointer to packet
00296  *     Size   = Number of bytes in first buffer
00297  * RETURNS:
00298  *     Previous size of first buffer
00299  */
00300 {
00301     PNDIS_BUFFER NdisBuffer;
00302     UINT OldSize;
00303 
00304     NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
00305 
00306     OldSize = NdisBuffer->ByteCount;
00307 
00308     if (Size != OldSize)
00309         NdisBuffer->ByteCount = Size;
00310 
00311     return OldSize;
00312 }
00313 
00314 void GetDataPtr( PNDIS_PACKET Packet,
00315          UINT Offset,
00316          PCHAR *DataOut,
00317          PUINT Size ) {
00318     PNDIS_BUFFER Buffer;
00319 
00320     NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
00321     if( !Buffer ) return;
00322     SkipToOffset( Buffer, Offset, DataOut, Size );
00323 }
00324 
00325 NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket,
00326                       PCHAR Data, UINT Len ) {
00327     PNDIS_PACKET Packet;
00328     PNDIS_BUFFER Buffer;
00329     NDIS_STATUS Status;
00330     PCHAR NewData;
00331 
00332     NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG );
00333     if( !NewData ) return NDIS_STATUS_RESOURCES;
00334 
00335     if( Data ) RtlCopyMemory(NewData, Data, Len);
00336 
00337     NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
00338     if( Status != NDIS_STATUS_SUCCESS ) {
00339     ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
00340     return Status;
00341     }
00342 
00343     NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
00344     if( Status != NDIS_STATUS_SUCCESS ) {
00345     ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG );
00346     FreeNdisPacket( Packet );
00347     return Status;
00348     }
00349 
00350     NdisChainBufferAtFront( Packet, Buffer );
00351     *NdisPacket = Packet;
00352 
00353     return NDIS_STATUS_SUCCESS;
00354 }
00355 
00356 
00357 VOID FreeNdisPacket
00358 ( PNDIS_PACKET Packet )
00359 /*
00360  * FUNCTION: Frees an NDIS packet
00361  * ARGUMENTS:
00362  *     Packet = Pointer to NDIS packet to be freed
00363  */
00364 {
00365     PNDIS_BUFFER Buffer, NextBuffer;
00366 
00367     TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));
00368 
00369     /* Free all the buffers in the packet first */
00370     NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
00371     for (; Buffer != NULL; Buffer = NextBuffer) {
00372         PVOID Data;
00373         UINT Length;
00374 
00375         NdisGetNextBuffer(Buffer, &NextBuffer);
00376         NdisQueryBuffer(Buffer, &Data, &Length);
00377     TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer));
00378         NdisFreeBuffer(Buffer);
00379     TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data));
00380         ExFreePoolWithTag(Data, PACKET_BUFFER_TAG);
00381     }
00382 
00383     /* Finally free the NDIS packet discriptor */
00384     NdisFreePacket(Packet);
00385 }

Generated on Sat May 26 2012 04:20:07 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.