Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbuffer.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
1.7.6.1
|