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