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

mockbuffer.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 VOID XNdisGetFirstBufferFromPacket(PNDIS_PACKET Packet,
00014                    PNDIS_BUFFER *FirstBuffer,
00015                    PVOID *FirstBufferVA,
00016                    PUINT FirstBufferLength,
00017                    PUINT TotalBufferLength)
00018 {
00019     PNDIS_BUFFER _Buffer;
00020 
00021     _Buffer              = (Packet)->Private.Head;
00022     *(FirstBuffer)       = _Buffer;
00023     *(FirstBufferVA)     = MmGetMdlVirtualAddress(_Buffer);
00024     if (_Buffer != NULL) {
00025         *(FirstBufferLength) = MmGetMdlByteCount(_Buffer);
00026         _Buffer = _Buffer->Next;
00027     } else
00028         *(FirstBufferLength) = 0;
00029     *(TotalBufferLength) = *(FirstBufferLength);
00030     while (_Buffer != NULL) {
00031         *(TotalBufferLength) += MmGetMdlByteCount(_Buffer);
00032         _Buffer = _Buffer->Next;
00033     }
00034 }
00035 
00036 /*
00037  * @implemented
00038  */
00039 VOID XNdisQueryBuffer
00040 (PNDIS_BUFFER    Buffer,
00041  PVOID           *VirtualAddress,
00042  PUINT           Length)
00043 /*
00044  * FUNCTION:
00045  *     Queries an NDIS buffer for information
00046  * ARGUMENTS:
00047  *     Buffer         = Pointer to NDIS buffer to query
00048  *     VirtualAddress = Address of buffer to place virtual address
00049  *     Length         = Address of buffer to place length of buffer
00050  */
00051 {
00052     if (VirtualAddress != NULL)
00053         *(PVOID*)VirtualAddress = Buffer->MappedSystemVa;
00054 
00055     *Length = ((PMDL)Buffer)->ByteCount;
00056 }
00057 
00058 __inline INT SkipToOffset(
00059     PNDIS_BUFFER Buffer,
00060     UINT Offset,
00061     PCHAR *Data,
00062     PUINT Size)
00063 /*
00064  * FUNCTION: Skip Offset bytes into a buffer chain
00065  * ARGUMENTS:
00066  *     Buffer = Pointer to NDIS buffer
00067  *     Offset = Number of bytes to skip
00068  *     Data   = Address of a pointer that on return will contain the
00069  *              address of the offset in the buffer
00070  *     Size   = Address of a pointer that on return will contain the
00071  *              size of the destination buffer
00072  * RETURNS:
00073  *     Offset into buffer, -1 if buffer chain was smaller than Offset bytes
00074  * NOTES:
00075  *     Buffer may be NULL
00076  */
00077 {
00078     for (;;) {
00079 
00080         if (!Buffer)
00081             return -1;
00082 
00083         XNdisQueryBuffer(Buffer, (PVOID)Data, Size);
00084 
00085         if (Offset < *Size) {
00086             *Data = (PCHAR)((ULONG_PTR) *Data + Offset);
00087             *Size              -= Offset;
00088             break;
00089         }
00090 
00091         Offset -= *Size;
00092 
00093         NdisGetNextBuffer(Buffer, &Buffer);
00094     }
00095 
00096     return Offset;
00097 }
00098 
00099 
00100 UINT CopyBufferToBufferChain(
00101     PNDIS_BUFFER DstBuffer,
00102     UINT DstOffset,
00103     PCHAR SrcData,
00104     UINT Length)
00105 /*
00106  * FUNCTION: Copies data from a buffer to an NDIS buffer chain
00107  * ARGUMENTS:
00108  *     DstBuffer = Pointer to destination NDIS buffer
00109  *     DstOffset = Destination start offset
00110  *     SrcData   = Pointer to source buffer
00111  *     Length    = Number of bytes to copy
00112  * RETURNS:
00113  *     Number of bytes copied to destination buffer
00114  * NOTES:
00115  *     The number of bytes copied may be limited by the destination
00116  *     buffer size
00117  */
00118 {
00119     UINT BytesCopied, BytesToCopy, DstSize;
00120     PCHAR DstData;
00121 
00122     TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcData (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
00123 
00124     /* Skip DstOffset bytes in the destination buffer chain */
00125     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
00126         return 0;
00127 
00128     /* Start copying the data */
00129     BytesCopied = 0;
00130     for (;;) {
00131         BytesToCopy = MIN(DstSize, Length);
00132 
00133         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
00134         BytesCopied += BytesToCopy;
00135         SrcData      = (PCHAR)((ULONG_PTR)SrcData + BytesToCopy);
00136 
00137         Length -= BytesToCopy;
00138         if (Length == 0)
00139             break;
00140 
00141         DstSize -= BytesToCopy;
00142         if (DstSize == 0) {
00143             /* No more bytes in desination buffer. Proceed to
00144                the next buffer in the destination buffer chain */
00145             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00146             if (!DstBuffer)
00147                 break;
00148 
00149             XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00150         }
00151     }
00152 
00153     return BytesCopied;
00154 }
00155 
00156 
00157 UINT CopyBufferChainToBuffer(
00158     PCHAR DstData,
00159     PNDIS_BUFFER SrcBuffer,
00160     UINT SrcOffset,
00161     UINT Length)
00162 /*
00163  * FUNCTION: Copies data from an NDIS buffer chain to a buffer
00164  * ARGUMENTS:
00165  *     DstData   = Pointer to destination buffer
00166  *     SrcBuffer = Pointer to source NDIS buffer
00167  *     SrcOffset = Source start offset
00168  *     Length    = Number of bytes to copy
00169  * RETURNS:
00170  *     Number of bytes copied to destination buffer
00171  * NOTES:
00172  *     The number of bytes copied may be limited by the source
00173  *     buffer size
00174  */
00175 {
00176     UINT BytesCopied, BytesToCopy, SrcSize;
00177     PCHAR SrcData;
00178 
00179     TI_DbgPrint(DEBUG_PBUFFER, ("DstData 0x%X  SrcBuffer 0x%X  SrcOffset 0x%X  Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
00180 
00181     /* Skip SrcOffset bytes in the source buffer chain */
00182     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
00183         return 0;
00184 
00185     /* Start copying the data */
00186     BytesCopied = 0;
00187     for (;;) {
00188         BytesToCopy = MIN(SrcSize, Length);
00189 
00190         TI_DbgPrint(DEBUG_PBUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
00191 
00192         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
00193         BytesCopied += BytesToCopy;
00194         DstData      = (PCHAR)((ULONG_PTR)DstData + BytesToCopy);
00195 
00196         Length -= BytesToCopy;
00197         if (Length == 0)
00198             break;
00199 
00200         SrcSize -= BytesToCopy;
00201         if (SrcSize == 0) {
00202             /* No more bytes in source buffer. Proceed to
00203                the next buffer in the source buffer chain */
00204             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00205             if (!SrcBuffer)
00206                 break;
00207 
00208             XNdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00209         }
00210     }
00211 
00212     return BytesCopied;
00213 }
00214 
00215 
00216 UINT CopyPacketToBuffer(
00217     PCHAR DstData,
00218     PNDIS_PACKET SrcPacket,
00219     UINT SrcOffset,
00220     UINT Length)
00221 /*
00222  * FUNCTION: Copies data from an NDIS packet to a buffer
00223  * ARGUMENTS:
00224  *     DstData   = Pointer to destination buffer
00225  *     SrcPacket = Pointer to source NDIS packet
00226  *     SrcOffset = Source start offset
00227  *     Length    = Number of bytes to copy
00228  * RETURNS:
00229  *     Number of bytes copied to destination buffer
00230  * NOTES:
00231  *     The number of bytes copied may be limited by the source
00232  *     buffer size
00233  */
00234 {
00235     PNDIS_BUFFER FirstBuffer;
00236     PVOID Address;
00237     UINT FirstLength;
00238     UINT TotalLength;
00239 
00240     TI_DbgPrint(DEBUG_PBUFFER, ("DstData (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
00241 
00242     XNdisGetFirstBufferFromPacket(SrcPacket,
00243                   &FirstBuffer,
00244                   &Address,
00245                   &FirstLength,
00246                   &TotalLength);
00247 
00248     return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
00249 }
00250 
00251 
00252 UINT CopyPacketToBufferChain(
00253     PNDIS_BUFFER DstBuffer,
00254     UINT DstOffset,
00255     PNDIS_PACKET SrcPacket,
00256     UINT SrcOffset,
00257     UINT Length)
00258 /*
00259  * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
00260  * ARGUMENTS:
00261  *     DstBuffer = Pointer to destination NDIS buffer
00262  *     DstOffset = Destination start offset
00263  *     SrcPacket = Pointer to source NDIS packet
00264  *     SrcOffset = Source start offset
00265  *     Length    = Number of bytes to copy
00266  * RETURNS:
00267  *     Number of bytes copied to destination buffer
00268  * NOTES:
00269  *     The number of bytes copied may be limited by the source and
00270  *     destination buffer sizes
00271  */
00272 {
00273     PNDIS_BUFFER SrcBuffer;
00274     PCHAR DstData, SrcData;
00275     UINT DstSize, SrcSize;
00276     UINT Count, Total;
00277 
00278     TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcPacket (0x%X)  SrcOffset (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
00279 
00280     /* Skip DstOffset bytes in the destination buffer chain */
00281     XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00282     if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
00283         return 0;
00284 
00285     /* Skip SrcOffset bytes in the source packet */
00286     XNdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID *)&SrcData, &SrcSize, &Total);
00287     if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
00288         return 0;
00289 
00290     /* Copy the data */
00291     for (Total = 0;;) {
00292         /* Find out how many bytes we can copy at one time */
00293         if (Length < SrcSize)
00294             Count = Length;
00295         else
00296             Count = SrcSize;
00297         if (DstSize < Count)
00298             Count = DstSize;
00299 
00300         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
00301 
00302         Total  += Count;
00303         Length -= Count;
00304         if (Length == 0)
00305             break;
00306 
00307         DstSize -= Count;
00308         if (DstSize == 0) {
00309             /* No more bytes in destination buffer. Proceed to
00310                the next buffer in the destination buffer chain */
00311             NdisGetNextBuffer(DstBuffer, &DstBuffer);
00312             if (!DstBuffer)
00313                 break;
00314 
00315             XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
00316         }
00317 
00318         SrcSize -= Count;
00319         if (SrcSize == 0) {
00320             /* No more bytes in source buffer. Proceed to
00321                the next buffer in the source buffer chain */
00322             NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
00323             if (!SrcBuffer)
00324                 break;
00325 
00326             XNdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
00327         }
00328     }
00329 
00330     return Total;
00331 }
00332 
00333 
00334 PVOID AdjustPacket(
00335     PNDIS_PACKET Packet,
00336     UINT Available,
00337     UINT Needed)
00338 /*
00339  * FUNCTION: Adjusts the amount of unused space at the beginning of the packet
00340  * ARGUMENTS:
00341  *     Packet    = Pointer to packet
00342  *     Available = Number of bytes available at start of first buffer
00343  *     Needed    = Number of bytes needed for the header
00344  * RETURNS:
00345  *     Pointer to start of packet
00346  */
00347 {
00348     PNDIS_BUFFER NdisBuffer;
00349     INT Adjust;
00350 
00351     TI_DbgPrint(DEBUG_PBUFFER, ("Available = %d, Needed = %d.\n", Available, Needed));
00352 
00353     Adjust = Available - Needed;
00354 
00355     NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
00356 
00357     /* If Adjust is zero there is no need to adjust this packet as
00358        there is no additional space at start the of first buffer */
00359     if (Adjust != 0) {
00360         NdisBuffer->MappedSystemVa  = (PVOID) ((ULONG_PTR)(NdisBuffer->MappedSystemVa) + Adjust);
00361         NdisBuffer->ByteOffset     += Adjust;
00362         NdisBuffer->ByteCount      -= Adjust;
00363     }
00364 
00365     return NdisBuffer->MappedSystemVa;
00366 }
00367 
00368 
00369 UINT ResizePacket(
00370     PNDIS_PACKET Packet,
00371     UINT Size)
00372 /*
00373  * FUNCTION: Resizes an NDIS packet
00374  * ARGUMENTS:
00375  *     Packet = Pointer to packet
00376  *     Size   = Number of bytes in first buffer
00377  * RETURNS:
00378  *     Previous size of first buffer
00379  */
00380 {
00381     PNDIS_BUFFER NdisBuffer;
00382     UINT OldSize;
00383 
00384     NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
00385 
00386     OldSize = NdisBuffer->ByteCount;
00387 
00388     if (Size != OldSize)
00389         NdisBuffer->ByteCount = Size;
00390 
00391     return OldSize;
00392 }
00393 
00394 NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length,
00395                BOOLEAN Copy ) {
00396     PNDIS_BUFFER Buffer;
00397     NDIS_STATUS Status;
00398     PCHAR NewBuf;
00399 
00400     if( Copy ) {
00401     NewBuf = PoolAllocateBuffer( Length );
00402     if( !NewBuf ) return STATUS_NO_MEMORY;
00403     RtlCopyMemory( NewBuf, Data, Length );
00404     } else NewBuf = Data;
00405 
00406     NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, Data, Length );
00407     if( Status != NDIS_STATUS_SUCCESS ) return Status;
00408 
00409     NdisChainBufferAtFront( Packet, Buffer );
00410 
00411     return STATUS_SUCCESS;
00412 }
00413 
00414 void GetDataPtr( PNDIS_PACKET Packet,
00415          UINT Offset,
00416          PCHAR *DataOut,
00417          PUINT Size ) {
00418     PNDIS_BUFFER Buffer;
00419 
00420     NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
00421     if( !Buffer ) return;
00422     SkipToOffset( Buffer, Offset, DataOut, Size );
00423 }
00424 
00425 NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
00426                        PCHAR Data, UINT Len,
00427                        PCHAR File, UINT Line ) {
00428     PNDIS_PACKET Packet;
00429     PNDIS_BUFFER Buffer;
00430     NDIS_STATUS Status;
00431     PCHAR NewData;
00432 
00433     NewData = exAllocatePool( NonPagedPool, Len );
00434     if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX
00435 
00436     if( Data )
00437     RtlCopyMemory(NewData, Data, Len);
00438 
00439     NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
00440     if( Status != NDIS_STATUS_SUCCESS ) {
00441     exFreePool( NewData );
00442     return Status;
00443     }
00444     TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);
00445 
00446     NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
00447     if( Status != NDIS_STATUS_SUCCESS ) {
00448     exFreePool( NewData );
00449     FreeNdisPacket( Packet );
00450     }
00451     TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);
00452 
00453     NdisChainBufferAtFront( Packet, Buffer );
00454     *NdisPacket = Packet;
00455 
00456     return NDIS_STATUS_SUCCESS;
00457 }
00458 
00459 
00460 VOID FreeNdisPacketX
00461 ( PNDIS_PACKET Packet,
00462   PCHAR File,
00463   UINT Line )
00464 /*
00465  * FUNCTION: Frees an NDIS packet
00466  * ARGUMENTS:
00467  *     Packet = Pointer to NDIS packet to be freed
00468  */
00469 {
00470     PNDIS_BUFFER Buffer, NextBuffer;
00471 
00472     TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));
00473 
00474     /* Free all the buffers in the packet first */
00475     NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
00476     for (; Buffer != NULL; Buffer = NextBuffer) {
00477         PVOID Data;
00478         UINT Length;
00479 
00480         NdisGetNextBuffer(Buffer, &NextBuffer);
00481         XNdisQueryBuffer(Buffer, &Data, &Length);
00482     UntrackFL(File,Line,Buffer);
00483         NdisFreeBuffer(Buffer);
00484         exFreePool(Data);
00485     }
00486 
00487     /* Finally free the NDIS packet discriptor */
00488     UntrackFL(File,Line,Packet);
00489     NdisFreePacket(Packet);
00490 }

Generated on Mon May 28 2012 04:27:45 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.