1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3*c2c66affSColin Finck * PROJECT: ReactOS NDIS library 4*c2c66affSColin Finck * FILE: ndis/buffer.c 5*c2c66affSColin Finck * PURPOSE: Buffer management routines 6*c2c66affSColin Finck * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 7*c2c66affSColin Finck * REVISIONS: 8*c2c66affSColin Finck * CSH 01/08-2000 Created 9*c2c66affSColin Finck */ 10*c2c66affSColin Finck 11*c2c66affSColin Finck #include <ndissys.h> 12*c2c66affSColin Finck 13*c2c66affSColin Finck __inline ULONG SkipToOffset( 14*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 15*c2c66affSColin Finck IN UINT Offset, 16*c2c66affSColin Finck IN OUT PUCHAR *Data, 17*c2c66affSColin Finck IN OUT PUINT Size) 18*c2c66affSColin Finck /* 19*c2c66affSColin Finck * FUNCTION: Skips Offset bytes into a buffer chain 20*c2c66affSColin Finck * ARGUMENTS: 21*c2c66affSColin Finck * Buffer = Pointer to NDIS buffer 22*c2c66affSColin Finck * Offset = Number of bytes to skip 23*c2c66affSColin Finck * Data = Address of a pointer that on return will contain the 24*c2c66affSColin Finck * address of the offset in the buffer 25*c2c66affSColin Finck * Size = Address of a pointer that on return will contain the 26*c2c66affSColin Finck * size of the destination buffer 27*c2c66affSColin Finck * RETURNS: 28*c2c66affSColin Finck * Offset into buffer, -1 if buffer chain was smaller than Offset bytes 29*c2c66affSColin Finck * NOTES: 30*c2c66affSColin Finck * Buffer may be NULL 31*c2c66affSColin Finck */ 32*c2c66affSColin Finck { 33*c2c66affSColin Finck for (;;) { 34*c2c66affSColin Finck 35*c2c66affSColin Finck if (!Buffer) 36*c2c66affSColin Finck return 0xFFFFFFFF; 37*c2c66affSColin Finck 38*c2c66affSColin Finck NdisQueryBuffer(Buffer, (PVOID)Data, Size); 39*c2c66affSColin Finck 40*c2c66affSColin Finck if (Offset < *Size) { 41*c2c66affSColin Finck *Data = (PUCHAR) ((ULONG_PTR) *Data + Offset); 42*c2c66affSColin Finck *Size -= Offset; 43*c2c66affSColin Finck break; 44*c2c66affSColin Finck } 45*c2c66affSColin Finck 46*c2c66affSColin Finck Offset -= *Size; 47*c2c66affSColin Finck 48*c2c66affSColin Finck NdisGetNextBuffer(Buffer, &Buffer); 49*c2c66affSColin Finck } 50*c2c66affSColin Finck 51*c2c66affSColin Finck return Offset; 52*c2c66affSColin Finck } 53*c2c66affSColin Finck 54*c2c66affSColin Finck UINT CopyBufferToBufferChain( 55*c2c66affSColin Finck PNDIS_BUFFER DstBuffer, 56*c2c66affSColin Finck UINT DstOffset, 57*c2c66affSColin Finck PUCHAR SrcData, 58*c2c66affSColin Finck UINT Length) 59*c2c66affSColin Finck /* 60*c2c66affSColin Finck * FUNCTION: Copies data from a buffer to an NDIS buffer chain 61*c2c66affSColin Finck * ARGUMENTS: 62*c2c66affSColin Finck * DstBuffer = Pointer to destination NDIS buffer 63*c2c66affSColin Finck * DstOffset = Destination start offset 64*c2c66affSColin Finck * SrcData = Pointer to source buffer 65*c2c66affSColin Finck * Length = Number of bytes to copy 66*c2c66affSColin Finck * RETURNS: 67*c2c66affSColin Finck * Number of bytes copied to destination buffer 68*c2c66affSColin Finck * NOTES: 69*c2c66affSColin Finck * The number of bytes copied may be limited by the destination 70*c2c66affSColin Finck * buffer size 71*c2c66affSColin Finck */ 72*c2c66affSColin Finck { 73*c2c66affSColin Finck UINT BytesCopied, BytesToCopy, DstSize; 74*c2c66affSColin Finck PUCHAR DstData; 75*c2c66affSColin Finck 76*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length)); 77*c2c66affSColin Finck 78*c2c66affSColin Finck /* Skip DstOffset bytes in the destination buffer chain */ 79*c2c66affSColin Finck if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF) 80*c2c66affSColin Finck return 0; 81*c2c66affSColin Finck 82*c2c66affSColin Finck /* Start copying the data */ 83*c2c66affSColin Finck BytesCopied = 0; 84*c2c66affSColin Finck for (;;) { 85*c2c66affSColin Finck BytesToCopy = MIN(DstSize, Length); 86*c2c66affSColin Finck 87*c2c66affSColin Finck RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy); 88*c2c66affSColin Finck BytesCopied += BytesToCopy; 89*c2c66affSColin Finck SrcData = (PUCHAR) ((ULONG_PTR) SrcData + BytesToCopy); 90*c2c66affSColin Finck 91*c2c66affSColin Finck Length -= BytesToCopy; 92*c2c66affSColin Finck if (Length == 0) 93*c2c66affSColin Finck break; 94*c2c66affSColin Finck 95*c2c66affSColin Finck DstSize -= BytesToCopy; 96*c2c66affSColin Finck if (DstSize == 0) { 97*c2c66affSColin Finck /* No more bytes in destination buffer. Proceed to 98*c2c66affSColin Finck the next buffer in the destination buffer chain */ 99*c2c66affSColin Finck NdisGetNextBuffer(DstBuffer, &DstBuffer); 100*c2c66affSColin Finck if (!DstBuffer) 101*c2c66affSColin Finck break; 102*c2c66affSColin Finck 103*c2c66affSColin Finck NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 104*c2c66affSColin Finck } 105*c2c66affSColin Finck } 106*c2c66affSColin Finck 107*c2c66affSColin Finck return BytesCopied; 108*c2c66affSColin Finck } 109*c2c66affSColin Finck 110*c2c66affSColin Finck 111*c2c66affSColin Finck UINT CopyBufferChainToBuffer( 112*c2c66affSColin Finck PUCHAR DstData, 113*c2c66affSColin Finck PNDIS_BUFFER SrcBuffer, 114*c2c66affSColin Finck UINT SrcOffset, 115*c2c66affSColin Finck UINT Length) 116*c2c66affSColin Finck /* 117*c2c66affSColin Finck * FUNCTION: Copies data from an NDIS buffer chain to a buffer 118*c2c66affSColin Finck * ARGUMENTS: 119*c2c66affSColin Finck * DstData = Pointer to destination buffer 120*c2c66affSColin Finck * SrcBuffer = Pointer to source NDIS buffer 121*c2c66affSColin Finck * SrcOffset = Source start offset 122*c2c66affSColin Finck * Length = Number of bytes to copy 123*c2c66affSColin Finck * RETURNS: 124*c2c66affSColin Finck * Number of bytes copied to destination buffer 125*c2c66affSColin Finck * NOTES: 126*c2c66affSColin Finck * The number of bytes copied may be limited by the source 127*c2c66affSColin Finck * buffer size 128*c2c66affSColin Finck */ 129*c2c66affSColin Finck { 130*c2c66affSColin Finck UINT BytesCopied, BytesToCopy, SrcSize; 131*c2c66affSColin Finck PUCHAR SrcData; 132*c2c66affSColin Finck 133*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length)); 134*c2c66affSColin Finck 135*c2c66affSColin Finck /* Skip SrcOffset bytes in the source buffer chain */ 136*c2c66affSColin Finck if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 137*c2c66affSColin Finck return 0; 138*c2c66affSColin Finck 139*c2c66affSColin Finck /* Start copying the data */ 140*c2c66affSColin Finck BytesCopied = 0; 141*c2c66affSColin Finck for (;;) { 142*c2c66affSColin Finck BytesToCopy = MIN(SrcSize, Length); 143*c2c66affSColin Finck 144*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData)); 145*c2c66affSColin Finck 146*c2c66affSColin Finck RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy); 147*c2c66affSColin Finck BytesCopied += BytesToCopy; 148*c2c66affSColin Finck DstData = (PUCHAR)((ULONG_PTR) DstData + BytesToCopy); 149*c2c66affSColin Finck 150*c2c66affSColin Finck Length -= BytesToCopy; 151*c2c66affSColin Finck if (Length == 0) 152*c2c66affSColin Finck break; 153*c2c66affSColin Finck 154*c2c66affSColin Finck SrcSize -= BytesToCopy; 155*c2c66affSColin Finck if (SrcSize == 0) { 156*c2c66affSColin Finck /* No more bytes in source buffer. Proceed to 157*c2c66affSColin Finck the next buffer in the source buffer chain */ 158*c2c66affSColin Finck NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 159*c2c66affSColin Finck if (!SrcBuffer) 160*c2c66affSColin Finck break; 161*c2c66affSColin Finck 162*c2c66affSColin Finck NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize); 163*c2c66affSColin Finck } 164*c2c66affSColin Finck } 165*c2c66affSColin Finck 166*c2c66affSColin Finck return BytesCopied; 167*c2c66affSColin Finck } 168*c2c66affSColin Finck 169*c2c66affSColin Finck 170*c2c66affSColin Finck UINT CopyPacketToBuffer( 171*c2c66affSColin Finck PUCHAR DstData, 172*c2c66affSColin Finck PNDIS_PACKET SrcPacket, 173*c2c66affSColin Finck UINT SrcOffset, 174*c2c66affSColin Finck UINT Length) 175*c2c66affSColin Finck /* 176*c2c66affSColin Finck * FUNCTION: Copies data from an NDIS packet to a buffer 177*c2c66affSColin Finck * ARGUMENTS: 178*c2c66affSColin Finck * DstData = Pointer to destination buffer 179*c2c66affSColin Finck * SrcPacket = Pointer to source NDIS packet 180*c2c66affSColin Finck * SrcOffset = Source start offset 181*c2c66affSColin Finck * Length = Number of bytes to copy 182*c2c66affSColin Finck * RETURNS: 183*c2c66affSColin Finck * Number of bytes copied to destination buffer 184*c2c66affSColin Finck * NOTES: 185*c2c66affSColin Finck * The number of bytes copied may be limited by the source 186*c2c66affSColin Finck * buffer size 187*c2c66affSColin Finck */ 188*c2c66affSColin Finck { 189*c2c66affSColin Finck PNDIS_BUFFER FirstBuffer; 190*c2c66affSColin Finck PVOID Address; 191*c2c66affSColin Finck UINT FirstLength; 192*c2c66affSColin Finck UINT TotalLength; 193*c2c66affSColin Finck 194*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length)); 195*c2c66affSColin Finck 196*c2c66affSColin Finck NdisGetFirstBufferFromPacket(SrcPacket, 197*c2c66affSColin Finck &FirstBuffer, 198*c2c66affSColin Finck &Address, 199*c2c66affSColin Finck &FirstLength, 200*c2c66affSColin Finck &TotalLength); 201*c2c66affSColin Finck 202*c2c66affSColin Finck return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length); 203*c2c66affSColin Finck } 204*c2c66affSColin Finck 205*c2c66affSColin Finck 206*c2c66affSColin Finck UINT CopyPacketToBufferChain( 207*c2c66affSColin Finck PNDIS_BUFFER DstBuffer, 208*c2c66affSColin Finck UINT DstOffset, 209*c2c66affSColin Finck PNDIS_PACKET SrcPacket, 210*c2c66affSColin Finck UINT SrcOffset, 211*c2c66affSColin Finck UINT Length) 212*c2c66affSColin Finck /* 213*c2c66affSColin Finck * FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain 214*c2c66affSColin Finck * ARGUMENTS: 215*c2c66affSColin Finck * DstBuffer = Pointer to destination NDIS buffer 216*c2c66affSColin Finck * DstOffset = Destination start offset 217*c2c66affSColin Finck * SrcPacket = Pointer to source NDIS packet 218*c2c66affSColin Finck * SrcOffset = Source start offset 219*c2c66affSColin Finck * Length = Number of bytes to copy 220*c2c66affSColin Finck * RETURNS: 221*c2c66affSColin Finck * Number of bytes copied to destination buffer 222*c2c66affSColin Finck * NOTES: 223*c2c66affSColin Finck * The number of bytes copied may be limited by the source and 224*c2c66affSColin Finck * destination buffer sizes 225*c2c66affSColin Finck */ 226*c2c66affSColin Finck { 227*c2c66affSColin Finck PNDIS_BUFFER SrcBuffer; 228*c2c66affSColin Finck PUCHAR DstData, SrcData; 229*c2c66affSColin Finck UINT DstSize, SrcSize; 230*c2c66affSColin Finck UINT Count, Total; 231*c2c66affSColin Finck 232*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length)); 233*c2c66affSColin Finck 234*c2c66affSColin Finck /* Skip DstOffset bytes in the destination buffer chain */ 235*c2c66affSColin Finck NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 236*c2c66affSColin Finck if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF) 237*c2c66affSColin Finck return 0; 238*c2c66affSColin Finck /* Skip SrcOffset bytes in the source packet */ 239*c2c66affSColin Finck NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total); 240*c2c66affSColin Finck if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 241*c2c66affSColin Finck return 0; 242*c2c66affSColin Finck /* Copy the data */ 243*c2c66affSColin Finck for (Total = 0;;) { 244*c2c66affSColin Finck /* Find out how many bytes we can copy at one time */ 245*c2c66affSColin Finck if (Length < SrcSize) 246*c2c66affSColin Finck Count = Length; 247*c2c66affSColin Finck else 248*c2c66affSColin Finck Count = SrcSize; 249*c2c66affSColin Finck if (DstSize < Count) 250*c2c66affSColin Finck Count = DstSize; 251*c2c66affSColin Finck 252*c2c66affSColin Finck RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count); 253*c2c66affSColin Finck 254*c2c66affSColin Finck Total += Count; 255*c2c66affSColin Finck Length -= Count; 256*c2c66affSColin Finck if (Length == 0) 257*c2c66affSColin Finck break; 258*c2c66affSColin Finck 259*c2c66affSColin Finck DstSize -= Count; 260*c2c66affSColin Finck if (DstSize == 0) { 261*c2c66affSColin Finck /* No more bytes in destination buffer. Proceed to 262*c2c66affSColin Finck the next buffer in the destination buffer chain */ 263*c2c66affSColin Finck NdisGetNextBuffer(DstBuffer, &DstBuffer); 264*c2c66affSColin Finck if (!DstBuffer) 265*c2c66affSColin Finck break; 266*c2c66affSColin Finck 267*c2c66affSColin Finck NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 268*c2c66affSColin Finck } 269*c2c66affSColin Finck 270*c2c66affSColin Finck SrcSize -= Count; 271*c2c66affSColin Finck if (SrcSize == 0) { 272*c2c66affSColin Finck /* No more bytes in source buffer. Proceed to 273*c2c66affSColin Finck the next buffer in the source buffer chain */ 274*c2c66affSColin Finck NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 275*c2c66affSColin Finck if (!SrcBuffer) 276*c2c66affSColin Finck break; 277*c2c66affSColin Finck 278*c2c66affSColin Finck NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize); 279*c2c66affSColin Finck } 280*c2c66affSColin Finck } 281*c2c66affSColin Finck 282*c2c66affSColin Finck return Total; 283*c2c66affSColin Finck } 284*c2c66affSColin Finck 285*c2c66affSColin Finck 286*c2c66affSColin Finck /* 287*c2c66affSColin Finck * @implemented 288*c2c66affSColin Finck */ 289*c2c66affSColin Finck #undef NdisAdjustBufferLength 290*c2c66affSColin Finck VOID 291*c2c66affSColin Finck EXPORT 292*c2c66affSColin Finck NdisAdjustBufferLength( 293*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 294*c2c66affSColin Finck IN UINT Length) 295*c2c66affSColin Finck /* 296*c2c66affSColin Finck * FUNCTION: Modifies the length of an NDIS buffer 297*c2c66affSColin Finck * ARGUMENTS: 298*c2c66affSColin Finck * Buffer = Pointer to NDIS buffer descriptor 299*c2c66affSColin Finck * Length = New size of buffer 300*c2c66affSColin Finck */ 301*c2c66affSColin Finck { 302*c2c66affSColin Finck Buffer->ByteCount = Length; 303*c2c66affSColin Finck } 304*c2c66affSColin Finck 305*c2c66affSColin Finck 306*c2c66affSColin Finck /* 307*c2c66affSColin Finck * @implemented 308*c2c66affSColin Finck */ 309*c2c66affSColin Finck #undef NDIS_BUFFER_TO_SPAN_PAGES 310*c2c66affSColin Finck ULONG 311*c2c66affSColin Finck EXPORT 312*c2c66affSColin Finck NDIS_BUFFER_TO_SPAN_PAGES( 313*c2c66affSColin Finck IN PNDIS_BUFFER Buffer) 314*c2c66affSColin Finck /* 315*c2c66affSColin Finck * FUNCTION: Determines how many physical pages a buffer is made of 316*c2c66affSColin Finck * ARGUMENTS: 317*c2c66affSColin Finck * Buffer = Pointer to NDIS buffer descriptor 318*c2c66affSColin Finck */ 319*c2c66affSColin Finck { 320*c2c66affSColin Finck if (MmGetMdlByteCount(Buffer) == 0) 321*c2c66affSColin Finck return 1; 322*c2c66affSColin Finck 323*c2c66affSColin Finck return ADDRESS_AND_SIZE_TO_SPAN_PAGES( 324*c2c66affSColin Finck MmGetMdlVirtualAddress(Buffer), 325*c2c66affSColin Finck MmGetMdlByteCount(Buffer)); 326*c2c66affSColin Finck } 327*c2c66affSColin Finck 328*c2c66affSColin Finck 329*c2c66affSColin Finck /* 330*c2c66affSColin Finck * @implemented 331*c2c66affSColin Finck */ 332*c2c66affSColin Finck VOID 333*c2c66affSColin Finck EXPORT 334*c2c66affSColin Finck NdisAllocateBuffer( 335*c2c66affSColin Finck OUT PNDIS_STATUS Status, 336*c2c66affSColin Finck OUT PNDIS_BUFFER * Buffer, 337*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle, 338*c2c66affSColin Finck IN PVOID VirtualAddress, 339*c2c66affSColin Finck IN UINT Length) 340*c2c66affSColin Finck /* 341*c2c66affSColin Finck * FUNCTION: Allocates an NDIS buffer descriptor 342*c2c66affSColin Finck * ARGUMENTS: 343*c2c66affSColin Finck * Status = Address of buffer for status 344*c2c66affSColin Finck * Buffer = Address of buffer for NDIS buffer descriptor 345*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocateBufferPool 346*c2c66affSColin Finck * VirtualAddress = Pointer to virtual address of data buffer 347*c2c66affSColin Finck * Length = Number of bytes in data buffer 348*c2c66affSColin Finck */ 349*c2c66affSColin Finck { 350*c2c66affSColin Finck ASSERT(VirtualAddress != NULL); 351*c2c66affSColin Finck ASSERT(Length > 0); 352*c2c66affSColin Finck 353*c2c66affSColin Finck *Buffer = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL); 354*c2c66affSColin Finck if (*Buffer != NULL) { 355*c2c66affSColin Finck MmBuildMdlForNonPagedPool(*Buffer); 356*c2c66affSColin Finck (*Buffer)->Next = NULL; 357*c2c66affSColin Finck *Status = NDIS_STATUS_SUCCESS; 358*c2c66affSColin Finck } else { 359*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", VirtualAddress, Length)); 360*c2c66affSColin Finck *Status = NDIS_STATUS_FAILURE; 361*c2c66affSColin Finck } 362*c2c66affSColin Finck } 363*c2c66affSColin Finck 364*c2c66affSColin Finck 365*c2c66affSColin Finck /* 366*c2c66affSColin Finck * @implemented 367*c2c66affSColin Finck */ 368*c2c66affSColin Finck VOID 369*c2c66affSColin Finck EXPORT 370*c2c66affSColin Finck NdisAllocateBufferPool( 371*c2c66affSColin Finck OUT PNDIS_STATUS Status, 372*c2c66affSColin Finck OUT PNDIS_HANDLE PoolHandle, 373*c2c66affSColin Finck IN UINT NumberOfDescriptors) 374*c2c66affSColin Finck /* 375*c2c66affSColin Finck * FUNCTION: Allocates storage for an NDIS buffer pool 376*c2c66affSColin Finck * ARGUMENTS: 377*c2c66affSColin Finck * Status = Address of buffer for status 378*c2c66affSColin Finck * PoolHandle = Address of buffer for pool handle 379*c2c66affSColin Finck * NumberOfDescriptors = Size of buffer pool in number of descriptors 380*c2c66affSColin Finck */ 381*c2c66affSColin Finck { 382*c2c66affSColin Finck *Status = NDIS_STATUS_SUCCESS; 383*c2c66affSColin Finck *PoolHandle = 0; 384*c2c66affSColin Finck } 385*c2c66affSColin Finck 386*c2c66affSColin Finck 387*c2c66affSColin Finck /* 388*c2c66affSColin Finck * @implemented 389*c2c66affSColin Finck */ 390*c2c66affSColin Finck VOID 391*c2c66affSColin Finck EXPORT 392*c2c66affSColin Finck NdisAllocatePacket( 393*c2c66affSColin Finck OUT PNDIS_STATUS Status, 394*c2c66affSColin Finck OUT PNDIS_PACKET * Packet, 395*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle) 396*c2c66affSColin Finck /* 397*c2c66affSColin Finck * FUNCTION: Allocates an NDIS packet descriptor 398*c2c66affSColin Finck * ARGUMENTS: 399*c2c66affSColin Finck * Status = Address of buffer for status 400*c2c66affSColin Finck * Packet = Address of buffer for packet descriptor 401*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocatePacketPool 402*c2c66affSColin Finck */ 403*c2c66affSColin Finck { 404*c2c66affSColin Finck PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 405*c2c66affSColin Finck 406*c2c66affSColin Finck KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql); 407*c2c66affSColin Finck NdisDprAllocatePacketNonInterlocked(Status, 408*c2c66affSColin Finck Packet, 409*c2c66affSColin Finck PoolHandle); 410*c2c66affSColin Finck KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql); 411*c2c66affSColin Finck } 412*c2c66affSColin Finck 413*c2c66affSColin Finck 414*c2c66affSColin Finck /* 415*c2c66affSColin Finck * @implemented 416*c2c66affSColin Finck */ 417*c2c66affSColin Finck VOID 418*c2c66affSColin Finck EXPORT 419*c2c66affSColin Finck NdisAllocatePacketPool( 420*c2c66affSColin Finck OUT PNDIS_STATUS Status, 421*c2c66affSColin Finck OUT PNDIS_HANDLE PoolHandle, 422*c2c66affSColin Finck IN UINT NumberOfDescriptors, 423*c2c66affSColin Finck IN UINT ProtocolReservedLength) 424*c2c66affSColin Finck /* 425*c2c66affSColin Finck * FUNCTION: Allocates storage for an NDIS packet pool 426*c2c66affSColin Finck * ARGUMENTS: 427*c2c66affSColin Finck * Status = Address of buffer for status 428*c2c66affSColin Finck * PoolHandle = Address of buffer for pool handle 429*c2c66affSColin Finck * NumberOfDescriptors = Size of packet pool in number of descriptors 430*c2c66affSColin Finck * ProtocolReservedLength = Size of protocol reserved area in bytes 431*c2c66affSColin Finck */ 432*c2c66affSColin Finck { 433*c2c66affSColin Finck NdisAllocatePacketPoolEx( 434*c2c66affSColin Finck Status, 435*c2c66affSColin Finck PoolHandle, 436*c2c66affSColin Finck NumberOfDescriptors, 437*c2c66affSColin Finck 0, 438*c2c66affSColin Finck ProtocolReservedLength); 439*c2c66affSColin Finck } 440*c2c66affSColin Finck 441*c2c66affSColin Finck 442*c2c66affSColin Finck /* 443*c2c66affSColin Finck * @implemented 444*c2c66affSColin Finck */ 445*c2c66affSColin Finck VOID 446*c2c66affSColin Finck EXPORT 447*c2c66affSColin Finck NdisAllocatePacketPoolEx( 448*c2c66affSColin Finck OUT PNDIS_STATUS Status, 449*c2c66affSColin Finck OUT PNDIS_HANDLE PoolHandle, 450*c2c66affSColin Finck IN UINT NumberOfDescriptors, 451*c2c66affSColin Finck IN UINT NumberOfOverflowDescriptors, 452*c2c66affSColin Finck IN UINT ProtocolReservedLength) 453*c2c66affSColin Finck /* 454*c2c66affSColin Finck * FUNCTION: 455*c2c66affSColin Finck * ARGUMENTS: 456*c2c66affSColin Finck * NOTES: 457*c2c66affSColin Finck * NDIS 5.0 458*c2c66affSColin Finck */ 459*c2c66affSColin Finck { 460*c2c66affSColin Finck PNDISI_PACKET_POOL Pool; 461*c2c66affSColin Finck UINT Size, Length, i; 462*c2c66affSColin Finck PNDIS_PACKET Packet, NextPacket; 463*c2c66affSColin Finck 464*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) PoolHandle (0x%X) " 465*c2c66affSColin Finck "NumberOfDescriptors (%d) ProtocolReservedLength (%d).\n", 466*c2c66affSColin Finck Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength)); 467*c2c66affSColin Finck 468*c2c66affSColin Finck *PoolHandle = NULL; 469*c2c66affSColin Finck 470*c2c66affSColin Finck if (NumberOfDescriptors > 0xffff) 471*c2c66affSColin Finck { 472*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("Invalid number of descriptors (%lx)\n", NumberOfDescriptors)) 473*c2c66affSColin Finck *Status = NDIS_STATUS_RESOURCES; 474*c2c66affSColin Finck } 475*c2c66affSColin Finck else 476*c2c66affSColin Finck { 477*c2c66affSColin Finck NumberOfDescriptors += NumberOfOverflowDescriptors; 478*c2c66affSColin Finck if (NumberOfDescriptors > 0xffff) 479*c2c66affSColin Finck { 480*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("Total number of descriptors > 0xffff (%lx)\n", NumberOfDescriptors)); 481*c2c66affSColin Finck NumberOfDescriptors = 0xffff; 482*c2c66affSColin Finck } 483*c2c66affSColin Finck 484*c2c66affSColin Finck Length = sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 485*c2c66affSColin Finck sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedLength; 486*c2c66affSColin Finck Size = sizeof(NDISI_PACKET_POOL) + Length * NumberOfDescriptors; 487*c2c66affSColin Finck 488*c2c66affSColin Finck Pool = ExAllocatePool(NonPagedPool, Size); 489*c2c66affSColin Finck if (Pool) 490*c2c66affSColin Finck { 491*c2c66affSColin Finck KeInitializeSpinLock(&Pool->SpinLock.SpinLock); 492*c2c66affSColin Finck Pool->PacketLength = Length; 493*c2c66affSColin Finck 494*c2c66affSColin Finck if (NumberOfDescriptors > 0) 495*c2c66affSColin Finck { 496*c2c66affSColin Finck Packet = (PNDIS_PACKET)&Pool->Buffer; 497*c2c66affSColin Finck Pool->FreeList = Packet; 498*c2c66affSColin Finck 499*c2c66affSColin Finck NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length); 500*c2c66affSColin Finck for (i = 1; i < NumberOfDescriptors; i++) 501*c2c66affSColin Finck { 502*c2c66affSColin Finck Packet->Reserved[0] = (ULONG_PTR)NextPacket; 503*c2c66affSColin Finck Packet = NextPacket; 504*c2c66affSColin Finck NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length); 505*c2c66affSColin Finck } 506*c2c66affSColin Finck Packet->Reserved[0] = 0; 507*c2c66affSColin Finck } 508*c2c66affSColin Finck else { 509*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("Attempted to allocate a packet pool with 0 descriptors\n")); 510*c2c66affSColin Finck Pool->FreeList = NULL; 511*c2c66affSColin Finck } 512*c2c66affSColin Finck 513*c2c66affSColin Finck *Status = NDIS_STATUS_SUCCESS; 514*c2c66affSColin Finck *PoolHandle = (PNDIS_HANDLE)Pool; 515*c2c66affSColin Finck } else { 516*c2c66affSColin Finck *Status = NDIS_STATUS_RESOURCES; 517*c2c66affSColin Finck } 518*c2c66affSColin Finck } 519*c2c66affSColin Finck } 520*c2c66affSColin Finck 521*c2c66affSColin Finck 522*c2c66affSColin Finck /* 523*c2c66affSColin Finck * @implemented 524*c2c66affSColin Finck */ 525*c2c66affSColin Finck #undef NdisBufferLength 526*c2c66affSColin Finck ULONG 527*c2c66affSColin Finck EXPORT 528*c2c66affSColin Finck NdisBufferLength( 529*c2c66affSColin Finck IN PNDIS_BUFFER Buffer) 530*c2c66affSColin Finck /* 531*c2c66affSColin Finck * FUNCTION: Modifies the length of an NDIS buffer 532*c2c66affSColin Finck * ARGUMENTS: 533*c2c66affSColin Finck * Buffer = Pointer to NDIS buffer descriptor 534*c2c66affSColin Finck * Length = New size of buffer 535*c2c66affSColin Finck * NOTES: 536*c2c66affSColin Finck * NDIS 5.0 537*c2c66affSColin Finck * RETURNS: 538*c2c66affSColin Finck * Length of NDIS buffer 539*c2c66affSColin Finck */ 540*c2c66affSColin Finck { 541*c2c66affSColin Finck return MmGetMdlByteCount(Buffer); 542*c2c66affSColin Finck } 543*c2c66affSColin Finck 544*c2c66affSColin Finck 545*c2c66affSColin Finck /* 546*c2c66affSColin Finck * @implemented 547*c2c66affSColin Finck */ 548*c2c66affSColin Finck #undef NdisBufferVirtualAddress 549*c2c66affSColin Finck PVOID 550*c2c66affSColin Finck EXPORT 551*c2c66affSColin Finck NdisBufferVirtualAddress( 552*c2c66affSColin Finck IN PNDIS_BUFFER Buffer) 553*c2c66affSColin Finck /* 554*c2c66affSColin Finck * FUNCTION: 555*c2c66affSColin Finck * ARGUMENTS: 556*c2c66affSColin Finck * NOTES: 557*c2c66affSColin Finck * NDIS 5.0 558*c2c66affSColin Finck */ 559*c2c66affSColin Finck { 560*c2c66affSColin Finck return MmGetSystemAddressForMdl(Buffer); 561*c2c66affSColin Finck } 562*c2c66affSColin Finck 563*c2c66affSColin Finck 564*c2c66affSColin Finck /* 565*c2c66affSColin Finck * @implemented 566*c2c66affSColin Finck */ 567*c2c66affSColin Finck VOID 568*c2c66affSColin Finck EXPORT 569*c2c66affSColin Finck NdisCopyFromPacketToPacket( 570*c2c66affSColin Finck IN PNDIS_PACKET Destination, 571*c2c66affSColin Finck IN UINT DestinationOffset, 572*c2c66affSColin Finck IN UINT BytesToCopy, 573*c2c66affSColin Finck IN PNDIS_PACKET Source, 574*c2c66affSColin Finck IN UINT SourceOffset, 575*c2c66affSColin Finck OUT PUINT BytesCopied) 576*c2c66affSColin Finck /* 577*c2c66affSColin Finck * FUNCTION: Copies data from one packet to another 578*c2c66affSColin Finck * ARGUMENTS: 579*c2c66affSColin Finck * Destination = Pointer to packet to copy data to 580*c2c66affSColin Finck * DestinationOffset = Offset in destination packet to copy data to 581*c2c66affSColin Finck * BytesToCopy = Number of bytes to copy 582*c2c66affSColin Finck * Source = Pointer to packet descriptor to copy from 583*c2c66affSColin Finck * SourceOffset = Offset in source packet to start copying from 584*c2c66affSColin Finck * BytesCopied = Address of buffer to place number of bytes copied 585*c2c66affSColin Finck */ 586*c2c66affSColin Finck { 587*c2c66affSColin Finck PNDIS_BUFFER SrcBuffer; 588*c2c66affSColin Finck PNDIS_BUFFER DstBuffer; 589*c2c66affSColin Finck PUCHAR DstData, SrcData; 590*c2c66affSColin Finck UINT DstSize, SrcSize; 591*c2c66affSColin Finck UINT Count, Total; 592*c2c66affSColin Finck 593*c2c66affSColin Finck *BytesCopied = 0; 594*c2c66affSColin Finck 595*c2c66affSColin Finck /* Skip DestinationOffset bytes in the destination packet */ 596*c2c66affSColin Finck NdisGetFirstBufferFromPacket(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total); 597*c2c66affSColin Finck if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF) 598*c2c66affSColin Finck return; 599*c2c66affSColin Finck 600*c2c66affSColin Finck /* Skip SourceOffset bytes in the source packet */ 601*c2c66affSColin Finck NdisGetFirstBufferFromPacket(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total); 602*c2c66affSColin Finck if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 603*c2c66affSColin Finck return; 604*c2c66affSColin Finck 605*c2c66affSColin Finck /* Copy the data */ 606*c2c66affSColin Finck for (Total = 0;;) { 607*c2c66affSColin Finck /* Find out how many bytes we can copy at one time */ 608*c2c66affSColin Finck if (BytesToCopy < SrcSize) 609*c2c66affSColin Finck Count = BytesToCopy; 610*c2c66affSColin Finck else 611*c2c66affSColin Finck Count = SrcSize; 612*c2c66affSColin Finck if (DstSize < Count) 613*c2c66affSColin Finck Count = DstSize; 614*c2c66affSColin Finck 615*c2c66affSColin Finck RtlCopyMemory(DstData, SrcData, Count); 616*c2c66affSColin Finck 617*c2c66affSColin Finck Total += Count; 618*c2c66affSColin Finck BytesToCopy -= Count; 619*c2c66affSColin Finck if (BytesToCopy == 0) 620*c2c66affSColin Finck break; 621*c2c66affSColin Finck 622*c2c66affSColin Finck DstSize -= Count; 623*c2c66affSColin Finck if (DstSize == 0) { 624*c2c66affSColin Finck /* No more bytes in destination buffer. Proceed to 625*c2c66affSColin Finck the next buffer in the destination buffer chain */ 626*c2c66affSColin Finck NdisGetNextBuffer(DstBuffer, &DstBuffer); 627*c2c66affSColin Finck if (!DstBuffer) 628*c2c66affSColin Finck break; 629*c2c66affSColin Finck 630*c2c66affSColin Finck NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 631*c2c66affSColin Finck } 632*c2c66affSColin Finck 633*c2c66affSColin Finck SrcSize -= Count; 634*c2c66affSColin Finck if (SrcSize == 0) { 635*c2c66affSColin Finck /* No more bytes in source buffer. Proceed to 636*c2c66affSColin Finck the next buffer in the source buffer chain */ 637*c2c66affSColin Finck NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 638*c2c66affSColin Finck if (!SrcBuffer) 639*c2c66affSColin Finck break; 640*c2c66affSColin Finck 641*c2c66affSColin Finck NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize); 642*c2c66affSColin Finck } 643*c2c66affSColin Finck } 644*c2c66affSColin Finck 645*c2c66affSColin Finck *BytesCopied = Total; 646*c2c66affSColin Finck } 647*c2c66affSColin Finck 648*c2c66affSColin Finck 649*c2c66affSColin Finck /* 650*c2c66affSColin Finck * @implemented 651*c2c66affSColin Finck */ 652*c2c66affSColin Finck VOID 653*c2c66affSColin Finck EXPORT 654*c2c66affSColin Finck NdisDprAllocatePacket( 655*c2c66affSColin Finck OUT PNDIS_STATUS Status, 656*c2c66affSColin Finck OUT PNDIS_PACKET *Packet, 657*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle) 658*c2c66affSColin Finck /* 659*c2c66affSColin Finck * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL 660*c2c66affSColin Finck * ARGUMENTS: 661*c2c66affSColin Finck * Status = Address of buffer to place status of operation 662*c2c66affSColin Finck * Packet = Address of buffer to place a pointer to a packet descriptor 663*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocatePacketPool 664*c2c66affSColin Finck */ 665*c2c66affSColin Finck { 666*c2c66affSColin Finck PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 667*c2c66affSColin Finck 668*c2c66affSColin Finck KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock); 669*c2c66affSColin Finck NdisDprAllocatePacketNonInterlocked(Status, 670*c2c66affSColin Finck Packet, 671*c2c66affSColin Finck PoolHandle); 672*c2c66affSColin Finck KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock); 673*c2c66affSColin Finck } 674*c2c66affSColin Finck 675*c2c66affSColin Finck 676*c2c66affSColin Finck /* 677*c2c66affSColin Finck * @implemented 678*c2c66affSColin Finck */ 679*c2c66affSColin Finck VOID 680*c2c66affSColin Finck EXPORT 681*c2c66affSColin Finck NdisDprAllocatePacketNonInterlocked( 682*c2c66affSColin Finck OUT PNDIS_STATUS Status, 683*c2c66affSColin Finck OUT PNDIS_PACKET *Packet, 684*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle) 685*c2c66affSColin Finck /* 686*c2c66affSColin Finck * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization) 687*c2c66affSColin Finck * ARGUMENTS: 688*c2c66affSColin Finck * Status = Address of buffer to place status of operation 689*c2c66affSColin Finck * Packet = Address of buffer to place a pointer to a packet descriptor 690*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocatePacketPool 691*c2c66affSColin Finck */ 692*c2c66affSColin Finck { 693*c2c66affSColin Finck PNDIS_PACKET Temp; 694*c2c66affSColin Finck PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 695*c2c66affSColin Finck 696*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n", 697*c2c66affSColin Finck Status, Packet, PoolHandle)); 698*c2c66affSColin Finck 699*c2c66affSColin Finck *Packet = NULL; 700*c2c66affSColin Finck 701*c2c66affSColin Finck if (Pool == NULL) 702*c2c66affSColin Finck { 703*c2c66affSColin Finck *Status = NDIS_STATUS_FAILURE; 704*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("Called passed a bad pool handle\n")); 705*c2c66affSColin Finck return; 706*c2c66affSColin Finck } 707*c2c66affSColin Finck 708*c2c66affSColin Finck if (Pool->FreeList) { 709*c2c66affSColin Finck Temp = Pool->FreeList; 710*c2c66affSColin Finck Pool->FreeList = (PNDIS_PACKET)Temp->Reserved[0]; 711*c2c66affSColin Finck 712*c2c66affSColin Finck RtlZeroMemory(Temp, Pool->PacketLength); 713*c2c66affSColin Finck Temp->Private.Pool = Pool; 714*c2c66affSColin Finck Temp->Private.ValidCounts = TRUE; 715*c2c66affSColin Finck Temp->Private.NdisPacketFlags = fPACKET_ALLOCATED_BY_NDIS; 716*c2c66affSColin Finck Temp->Private.NdisPacketOobOffset = Pool->PacketLength - 717*c2c66affSColin Finck (sizeof(NDIS_PACKET_OOB_DATA) + 718*c2c66affSColin Finck sizeof(NDIS_PACKET_EXTENSION)); 719*c2c66affSColin Finck 720*c2c66affSColin Finck *Packet = Temp; 721*c2c66affSColin Finck *Status = NDIS_STATUS_SUCCESS; 722*c2c66affSColin Finck } else { 723*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("No more free descriptors\n")); 724*c2c66affSColin Finck *Status = NDIS_STATUS_RESOURCES; 725*c2c66affSColin Finck } 726*c2c66affSColin Finck } 727*c2c66affSColin Finck 728*c2c66affSColin Finck 729*c2c66affSColin Finck /* 730*c2c66affSColin Finck * @implemented 731*c2c66affSColin Finck */ 732*c2c66affSColin Finck VOID 733*c2c66affSColin Finck EXPORT 734*c2c66affSColin Finck NdisDprFreePacket( 735*c2c66affSColin Finck IN PNDIS_PACKET Packet) 736*c2c66affSColin Finck /* 737*c2c66affSColin Finck * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL 738*c2c66affSColin Finck * ARGUMENTS: 739*c2c66affSColin Finck * Packet = Pointer to packet to free 740*c2c66affSColin Finck */ 741*c2c66affSColin Finck { 742*c2c66affSColin Finck PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool; 743*c2c66affSColin Finck 744*c2c66affSColin Finck KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock); 745*c2c66affSColin Finck NdisDprFreePacketNonInterlocked(Packet); 746*c2c66affSColin Finck KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock); 747*c2c66affSColin Finck } 748*c2c66affSColin Finck 749*c2c66affSColin Finck 750*c2c66affSColin Finck /* 751*c2c66affSColin Finck * @implemented 752*c2c66affSColin Finck */ 753*c2c66affSColin Finck VOID 754*c2c66affSColin Finck EXPORT 755*c2c66affSColin Finck NdisDprFreePacketNonInterlocked( 756*c2c66affSColin Finck IN PNDIS_PACKET Packet) 757*c2c66affSColin Finck /* 758*c2c66affSColin Finck * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization) 759*c2c66affSColin Finck * ARGUMENTS: 760*c2c66affSColin Finck * Packet = Pointer to packet to free 761*c2c66affSColin Finck */ 762*c2c66affSColin Finck { 763*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Packet (0x%X).\n", Packet)); 764*c2c66affSColin Finck 765*c2c66affSColin Finck Packet->Reserved[0] = (ULONG_PTR)((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList; 766*c2c66affSColin Finck ((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList = Packet; 767*c2c66affSColin Finck } 768*c2c66affSColin Finck 769*c2c66affSColin Finck 770*c2c66affSColin Finck /* 771*c2c66affSColin Finck * @implemented 772*c2c66affSColin Finck */ 773*c2c66affSColin Finck VOID 774*c2c66affSColin Finck EXPORT 775*c2c66affSColin Finck NdisFreeBufferPool( 776*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle) 777*c2c66affSColin Finck /* 778*c2c66affSColin Finck * FUNCTION: Frees storage allocated for an NDIS buffer pool 779*c2c66affSColin Finck * ARGUMENTS: 780*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocateBufferPool 781*c2c66affSColin Finck */ 782*c2c66affSColin Finck { 783*c2c66affSColin Finck } 784*c2c66affSColin Finck 785*c2c66affSColin Finck 786*c2c66affSColin Finck /* 787*c2c66affSColin Finck * @implemented 788*c2c66affSColin Finck */ 789*c2c66affSColin Finck VOID 790*c2c66affSColin Finck EXPORT 791*c2c66affSColin Finck NdisFreePacketPool( 792*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle) 793*c2c66affSColin Finck /* 794*c2c66affSColin Finck * FUNCTION: Frees storage allocated for an NDIS packet pool 795*c2c66affSColin Finck * ARGUMENTS: 796*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocatePacketPool 797*c2c66affSColin Finck */ 798*c2c66affSColin Finck { 799*c2c66affSColin Finck ExFreePool((PVOID)PoolHandle); 800*c2c66affSColin Finck } 801*c2c66affSColin Finck 802*c2c66affSColin Finck 803*c2c66affSColin Finck /* 804*c2c66affSColin Finck * @implemented 805*c2c66affSColin Finck */ 806*c2c66affSColin Finck #undef NdisFreeBuffer 807*c2c66affSColin Finck VOID 808*c2c66affSColin Finck EXPORT 809*c2c66affSColin Finck NdisFreeBuffer( 810*c2c66affSColin Finck IN PNDIS_BUFFER Buffer) 811*c2c66affSColin Finck /* 812*c2c66affSColin Finck * FUNCTION: Puts an NDIS buffer descriptor back in it's pool 813*c2c66affSColin Finck * ARGUMENTS: 814*c2c66affSColin Finck * Buffer = Pointer to buffer descriptor 815*c2c66affSColin Finck */ 816*c2c66affSColin Finck { 817*c2c66affSColin Finck IoFreeMdl(Buffer); 818*c2c66affSColin Finck } 819*c2c66affSColin Finck 820*c2c66affSColin Finck 821*c2c66affSColin Finck /* 822*c2c66affSColin Finck * @implemented 823*c2c66affSColin Finck */ 824*c2c66affSColin Finck VOID 825*c2c66affSColin Finck EXPORT 826*c2c66affSColin Finck NdisFreePacket( 827*c2c66affSColin Finck IN PNDIS_PACKET Packet) 828*c2c66affSColin Finck /* 829*c2c66affSColin Finck * FUNCTION: Puts an NDIS packet descriptor back in it's pool 830*c2c66affSColin Finck * ARGUMENTS: 831*c2c66affSColin Finck * Packet = Pointer to packet descriptor 832*c2c66affSColin Finck */ 833*c2c66affSColin Finck { 834*c2c66affSColin Finck PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool; 835*c2c66affSColin Finck 836*c2c66affSColin Finck KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql); 837*c2c66affSColin Finck NdisDprFreePacketNonInterlocked(Packet); 838*c2c66affSColin Finck KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql); 839*c2c66affSColin Finck } 840*c2c66affSColin Finck 841*c2c66affSColin Finck 842*c2c66affSColin Finck /* 843*c2c66affSColin Finck * @implemented 844*c2c66affSColin Finck */ 845*c2c66affSColin Finck #undef NdisGetBufferPhysicalArraySize 846*c2c66affSColin Finck VOID 847*c2c66affSColin Finck EXPORT 848*c2c66affSColin Finck NdisGetBufferPhysicalArraySize( 849*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 850*c2c66affSColin Finck OUT PUINT ArraySize) 851*c2c66affSColin Finck /* 852*c2c66affSColin Finck * FUNCTION: Returns number of discontiguous physical blocks backing a buffer 853*c2c66affSColin Finck * ARGUMENTS: 854*c2c66affSColin Finck * Buffer = Pointer to buffer descriptor 855*c2c66affSColin Finck * ArraySize = Address of buffer to place number of physical blocks 856*c2c66affSColin Finck */ 857*c2c66affSColin Finck { 858*c2c66affSColin Finck ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 859*c2c66affSColin Finck ASSERT(Buffer && ArraySize); 860*c2c66affSColin Finck 861*c2c66affSColin Finck *ArraySize = NDIS_BUFFER_TO_SPAN_PAGES(Buffer); 862*c2c66affSColin Finck } 863*c2c66affSColin Finck 864*c2c66affSColin Finck 865*c2c66affSColin Finck /* 866*c2c66affSColin Finck * @implemented 867*c2c66affSColin Finck */ 868*c2c66affSColin Finck #undef NdisGetFirstBufferFromPacket 869*c2c66affSColin Finck VOID 870*c2c66affSColin Finck EXPORT 871*c2c66affSColin Finck NdisGetFirstBufferFromPacket( 872*c2c66affSColin Finck IN PNDIS_PACKET _Packet, 873*c2c66affSColin Finck OUT PNDIS_BUFFER *_FirstBuffer, 874*c2c66affSColin Finck OUT PVOID *_FirstBufferVA, 875*c2c66affSColin Finck OUT PUINT _FirstBufferLength, 876*c2c66affSColin Finck OUT PUINT _TotalBufferLength) 877*c2c66affSColin Finck /* 878*c2c66affSColin Finck * FUNCTION: Retrieves information about an NDIS packet 879*c2c66affSColin Finck * ARGUMENTS: 880*c2c66affSColin Finck * _Packet = Pointer to NDIS packet 881*c2c66affSColin Finck * _FirstBuffer = Address of buffer for pointer to first NDIS buffer 882*c2c66affSColin Finck * _FirstBufferVA = Address of buffer for address of first NDIS buffer 883*c2c66affSColin Finck * _FirstBufferLength = Address of buffer for length of first buffer 884*c2c66affSColin Finck * _TotalBufferLength = Address of buffer for total length of packet 885*c2c66affSColin Finck */ 886*c2c66affSColin Finck { 887*c2c66affSColin Finck PNDIS_BUFFER Buffer; 888*c2c66affSColin Finck 889*c2c66affSColin Finck Buffer = _Packet->Private.Head; 890*c2c66affSColin Finck *_FirstBuffer = Buffer; 891*c2c66affSColin Finck 892*c2c66affSColin Finck if (Buffer != NULL) { 893*c2c66affSColin Finck *_FirstBufferLength = MmGetMdlByteCount(Buffer); 894*c2c66affSColin Finck *_FirstBufferVA = MmGetSystemAddressForMdl(Buffer); 895*c2c66affSColin Finck Buffer = Buffer->Next; 896*c2c66affSColin Finck } else { 897*c2c66affSColin Finck NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n")); 898*c2c66affSColin Finck *_FirstBufferLength = 0; 899*c2c66affSColin Finck *_FirstBufferVA = NULL; 900*c2c66affSColin Finck } 901*c2c66affSColin Finck 902*c2c66affSColin Finck *_TotalBufferLength = *_FirstBufferLength; 903*c2c66affSColin Finck 904*c2c66affSColin Finck while (Buffer != NULL) { 905*c2c66affSColin Finck *_TotalBufferLength += MmGetMdlByteCount(Buffer); 906*c2c66affSColin Finck Buffer = Buffer->Next; 907*c2c66affSColin Finck } 908*c2c66affSColin Finck } 909*c2c66affSColin Finck 910*c2c66affSColin Finck #undef NdisGetFirstBufferFromPacketSafe 911*c2c66affSColin Finck /* 912*c2c66affSColin Finck * @implemented 913*c2c66affSColin Finck */ 914*c2c66affSColin Finck VOID 915*c2c66affSColin Finck EXPORT 916*c2c66affSColin Finck NdisGetFirstBufferFromPacketSafe( 917*c2c66affSColin Finck IN PNDIS_PACKET _Packet, 918*c2c66affSColin Finck OUT PNDIS_BUFFER *_FirstBuffer, 919*c2c66affSColin Finck OUT PVOID *_FirstBufferVA, 920*c2c66affSColin Finck OUT PUINT _FirstBufferLength, 921*c2c66affSColin Finck OUT PUINT _TotalBufferLength, 922*c2c66affSColin Finck IN MM_PAGE_PRIORITY Priority) 923*c2c66affSColin Finck { 924*c2c66affSColin Finck PNDIS_BUFFER Buffer; 925*c2c66affSColin Finck 926*c2c66affSColin Finck Buffer = _Packet->Private.Head; 927*c2c66affSColin Finck *_FirstBuffer = Buffer; 928*c2c66affSColin Finck 929*c2c66affSColin Finck if (Buffer != NULL) { 930*c2c66affSColin Finck *_FirstBufferLength = MmGetMdlByteCount(Buffer); 931*c2c66affSColin Finck *_FirstBufferVA = MmGetSystemAddressForMdlSafe(Buffer, Priority); 932*c2c66affSColin Finck Buffer = Buffer->Next; 933*c2c66affSColin Finck } else { 934*c2c66affSColin Finck NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n")); 935*c2c66affSColin Finck *_FirstBufferLength = 0; 936*c2c66affSColin Finck *_FirstBufferVA = NULL; 937*c2c66affSColin Finck } 938*c2c66affSColin Finck 939*c2c66affSColin Finck *_TotalBufferLength = *_FirstBufferLength; 940*c2c66affSColin Finck 941*c2c66affSColin Finck while (Buffer != NULL) { 942*c2c66affSColin Finck *_TotalBufferLength += MmGetMdlByteCount(Buffer); 943*c2c66affSColin Finck Buffer = Buffer->Next; 944*c2c66affSColin Finck } 945*c2c66affSColin Finck } 946*c2c66affSColin Finck 947*c2c66affSColin Finck /* 948*c2c66affSColin Finck * @implemented 949*c2c66affSColin Finck */ 950*c2c66affSColin Finck #undef NdisQueryBuffer 951*c2c66affSColin Finck VOID 952*c2c66affSColin Finck EXPORT 953*c2c66affSColin Finck NdisQueryBuffer( 954*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 955*c2c66affSColin Finck OUT PVOID *VirtualAddress OPTIONAL, 956*c2c66affSColin Finck OUT PUINT Length) 957*c2c66affSColin Finck /* 958*c2c66affSColin Finck * FUNCTION: 959*c2c66affSColin Finck * Queries an NDIS buffer for information 960*c2c66affSColin Finck * ARGUMENTS: 961*c2c66affSColin Finck * Buffer = Pointer to NDIS buffer to query 962*c2c66affSColin Finck * VirtualAddress = Address of buffer to place virtual address 963*c2c66affSColin Finck * Length = Address of buffer to place length of buffer 964*c2c66affSColin Finck */ 965*c2c66affSColin Finck { 966*c2c66affSColin Finck if (VirtualAddress != NULL) 967*c2c66affSColin Finck *(PVOID*)VirtualAddress = MmGetSystemAddressForMdl(Buffer); 968*c2c66affSColin Finck 969*c2c66affSColin Finck *Length = MmGetMdlByteCount(Buffer); 970*c2c66affSColin Finck } 971*c2c66affSColin Finck 972*c2c66affSColin Finck 973*c2c66affSColin Finck /* 974*c2c66affSColin Finck * @implemented 975*c2c66affSColin Finck */ 976*c2c66affSColin Finck #undef NdisQueryBufferSafe 977*c2c66affSColin Finck VOID 978*c2c66affSColin Finck EXPORT 979*c2c66affSColin Finck NdisQueryBufferSafe( 980*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 981*c2c66affSColin Finck OUT PVOID *VirtualAddress OPTIONAL, 982*c2c66affSColin Finck OUT PUINT Length, 983*c2c66affSColin Finck IN UINT Priority) 984*c2c66affSColin Finck /* 985*c2c66affSColin Finck * FUNCTION: 986*c2c66affSColin Finck * ARGUMENTS: 987*c2c66affSColin Finck * NOTES: 988*c2c66affSColin Finck * NDIS 5.0 989*c2c66affSColin Finck */ 990*c2c66affSColin Finck { 991*c2c66affSColin Finck if (VirtualAddress != NULL) 992*c2c66affSColin Finck *VirtualAddress = MmGetSystemAddressForMdlSafe(Buffer, Priority); 993*c2c66affSColin Finck *Length = MmGetMdlByteCount(Buffer); 994*c2c66affSColin Finck } 995*c2c66affSColin Finck 996*c2c66affSColin Finck 997*c2c66affSColin Finck /* 998*c2c66affSColin Finck * @implemented 999*c2c66affSColin Finck */ 1000*c2c66affSColin Finck #undef NdisQueryBufferOffset 1001*c2c66affSColin Finck VOID 1002*c2c66affSColin Finck EXPORT 1003*c2c66affSColin Finck NdisQueryBufferOffset( 1004*c2c66affSColin Finck IN PNDIS_BUFFER Buffer, 1005*c2c66affSColin Finck OUT PUINT Offset, 1006*c2c66affSColin Finck OUT PUINT Length) 1007*c2c66affSColin Finck { 1008*c2c66affSColin Finck *((PUINT)Offset) = MmGetMdlByteOffset(Buffer); 1009*c2c66affSColin Finck *((PUINT)Length) = MmGetMdlByteCount(Buffer); 1010*c2c66affSColin Finck } 1011*c2c66affSColin Finck 1012*c2c66affSColin Finck 1013*c2c66affSColin Finck /* 1014*c2c66affSColin Finck * @implemented 1015*c2c66affSColin Finck */ 1016*c2c66affSColin Finck VOID 1017*c2c66affSColin Finck EXPORT 1018*c2c66affSColin Finck NdisUnchainBufferAtBack( 1019*c2c66affSColin Finck IN OUT PNDIS_PACKET Packet, 1020*c2c66affSColin Finck OUT PNDIS_BUFFER *Buffer) 1021*c2c66affSColin Finck /* 1022*c2c66affSColin Finck * FUNCTION: 1023*c2c66affSColin Finck * Removes the last buffer in a packet 1024*c2c66affSColin Finck * ARGUMENTS: 1025*c2c66affSColin Finck * Packet = Pointer to NDIS packet 1026*c2c66affSColin Finck * Buffer = Address of buffer to place pointer to removed NDIS buffer 1027*c2c66affSColin Finck */ 1028*c2c66affSColin Finck { 1029*c2c66affSColin Finck PNDIS_BUFFER NdisBuffer, Previous; 1030*c2c66affSColin Finck 1031*c2c66affSColin Finck NdisQueryPacket(Packet, 1032*c2c66affSColin Finck NULL, 1033*c2c66affSColin Finck NULL, 1034*c2c66affSColin Finck &NdisBuffer, 1035*c2c66affSColin Finck NULL); 1036*c2c66affSColin Finck if (!NdisBuffer) { 1037*c2c66affSColin Finck NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n")); 1038*c2c66affSColin Finck *Buffer = NULL; 1039*c2c66affSColin Finck return; 1040*c2c66affSColin Finck } 1041*c2c66affSColin Finck 1042*c2c66affSColin Finck Previous = NULL; 1043*c2c66affSColin Finck while (NdisBuffer->Next) { 1044*c2c66affSColin Finck Previous = NdisBuffer; 1045*c2c66affSColin Finck NdisBuffer = NdisBuffer->Next; 1046*c2c66affSColin Finck } 1047*c2c66affSColin Finck 1048*c2c66affSColin Finck if (Previous) { 1049*c2c66affSColin Finck Previous->Next = NULL; 1050*c2c66affSColin Finck Packet->Private.Tail = Previous; 1051*c2c66affSColin Finck } else { 1052*c2c66affSColin Finck Packet->Private.Head = NULL; 1053*c2c66affSColin Finck Packet->Private.Tail = NULL; 1054*c2c66affSColin Finck } 1055*c2c66affSColin Finck 1056*c2c66affSColin Finck Packet->Private.ValidCounts = FALSE; 1057*c2c66affSColin Finck 1058*c2c66affSColin Finck *Buffer = NdisBuffer; 1059*c2c66affSColin Finck } 1060*c2c66affSColin Finck 1061*c2c66affSColin Finck 1062*c2c66affSColin Finck /* 1063*c2c66affSColin Finck * @implemented 1064*c2c66affSColin Finck */ 1065*c2c66affSColin Finck VOID 1066*c2c66affSColin Finck EXPORT 1067*c2c66affSColin Finck NdisUnchainBufferAtFront( 1068*c2c66affSColin Finck IN OUT PNDIS_PACKET Packet, 1069*c2c66affSColin Finck OUT PNDIS_BUFFER *Buffer) 1070*c2c66affSColin Finck /* 1071*c2c66affSColin Finck * FUNCTION: 1072*c2c66affSColin Finck * Removes the first buffer in a packet 1073*c2c66affSColin Finck * ARGUMENTS: 1074*c2c66affSColin Finck * Packet = Pointer to NDIS packet 1075*c2c66affSColin Finck * Buffer = Address of buffer to place pointer to removed NDIS buffer 1076*c2c66affSColin Finck */ 1077*c2c66affSColin Finck { 1078*c2c66affSColin Finck PNDIS_BUFFER NdisBuffer; 1079*c2c66affSColin Finck 1080*c2c66affSColin Finck NdisQueryPacket(Packet, 1081*c2c66affSColin Finck NULL, 1082*c2c66affSColin Finck NULL, 1083*c2c66affSColin Finck &NdisBuffer, 1084*c2c66affSColin Finck NULL); 1085*c2c66affSColin Finck if (!NdisBuffer) { 1086*c2c66affSColin Finck NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n")); 1087*c2c66affSColin Finck *Buffer = NULL; 1088*c2c66affSColin Finck return; 1089*c2c66affSColin Finck } 1090*c2c66affSColin Finck 1091*c2c66affSColin Finck Packet->Private.Head = NdisBuffer->Next; 1092*c2c66affSColin Finck 1093*c2c66affSColin Finck if (!NdisBuffer->Next) 1094*c2c66affSColin Finck Packet->Private.Tail = NULL; 1095*c2c66affSColin Finck 1096*c2c66affSColin Finck NdisBuffer->Next = NULL; 1097*c2c66affSColin Finck 1098*c2c66affSColin Finck Packet->Private.ValidCounts = FALSE; 1099*c2c66affSColin Finck 1100*c2c66affSColin Finck *Buffer = NdisBuffer; 1101*c2c66affSColin Finck } 1102*c2c66affSColin Finck 1103*c2c66affSColin Finck /* 1104*c2c66affSColin Finck * @implemented 1105*c2c66affSColin Finck */ 1106*c2c66affSColin Finck VOID 1107*c2c66affSColin Finck EXPORT 1108*c2c66affSColin Finck NdisCopyBuffer( 1109*c2c66affSColin Finck OUT PNDIS_STATUS Status, 1110*c2c66affSColin Finck OUT PNDIS_BUFFER *Buffer, 1111*c2c66affSColin Finck IN NDIS_HANDLE PoolHandle, 1112*c2c66affSColin Finck IN PVOID MemoryDescriptor, 1113*c2c66affSColin Finck IN UINT Offset, 1114*c2c66affSColin Finck IN UINT Length) 1115*c2c66affSColin Finck /* 1116*c2c66affSColin Finck * FUNCTION: Returns a new buffer descriptor for a (partial) buffer 1117*c2c66affSColin Finck * ARGUMENTS: 1118*c2c66affSColin Finck * Status = Address of a buffer to place status of operation 1119*c2c66affSColin Finck * Buffer = Address of a buffer to place new buffer descriptor 1120*c2c66affSColin Finck * PoolHandle = Handle returned by NdisAllocateBufferPool 1121*c2c66affSColin Finck * MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER) 1122*c2c66affSColin Finck * Offset = Offset in buffer to start copying 1123*c2c66affSColin Finck * Length = Number of bytes to copy 1124*c2c66affSColin Finck */ 1125*c2c66affSColin Finck { 1126*c2c66affSColin Finck PVOID CurrentVa = (PUCHAR)(MmGetMdlVirtualAddress((PNDIS_BUFFER)MemoryDescriptor)) + Offset; 1127*c2c66affSColin Finck 1128*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Called\n")); 1129*c2c66affSColin Finck 1130*c2c66affSColin Finck *Buffer = IoAllocateMdl(CurrentVa, Length, FALSE, FALSE, NULL); 1131*c2c66affSColin Finck if (!*Buffer) 1132*c2c66affSColin Finck { 1133*c2c66affSColin Finck NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", CurrentVa, Length)); 1134*c2c66affSColin Finck *Status = NDIS_STATUS_FAILURE; 1135*c2c66affSColin Finck return; 1136*c2c66affSColin Finck } 1137*c2c66affSColin Finck 1138*c2c66affSColin Finck IoBuildPartialMdl((PNDIS_BUFFER)MemoryDescriptor, 1139*c2c66affSColin Finck *Buffer, 1140*c2c66affSColin Finck CurrentVa, 1141*c2c66affSColin Finck Length); 1142*c2c66affSColin Finck 1143*c2c66affSColin Finck (*Buffer)->Next = NULL; 1144*c2c66affSColin Finck *Status = NDIS_STATUS_SUCCESS; 1145*c2c66affSColin Finck } 1146*c2c66affSColin Finck 1147*c2c66affSColin Finck /* 1148*c2c66affSColin Finck * @implemented 1149*c2c66affSColin Finck */ 1150*c2c66affSColin Finck NDIS_HANDLE 1151*c2c66affSColin Finck EXPORT 1152*c2c66affSColin Finck NdisGetPoolFromPacket( 1153*c2c66affSColin Finck IN PNDIS_PACKET Packet) 1154*c2c66affSColin Finck { 1155*c2c66affSColin Finck return Packet->Private.Pool; 1156*c2c66affSColin Finck } 1157*c2c66affSColin Finck 1158*c2c66affSColin Finck /* 1159*c2c66affSColin Finck * @implemented 1160*c2c66affSColin Finck */ 1161*c2c66affSColin Finck UINT 1162*c2c66affSColin Finck EXPORT 1163*c2c66affSColin Finck NdisPacketSize( 1164*c2c66affSColin Finck IN UINT ProtocolReservedSize) 1165*c2c66affSColin Finck { 1166*c2c66affSColin Finck return sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 1167*c2c66affSColin Finck sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedSize; 1168*c2c66affSColin Finck } 1169*c2c66affSColin Finck 1170*c2c66affSColin Finck /* 1171*c2c66affSColin Finck * @implemented 1172*c2c66affSColin Finck */ 1173*c2c66affSColin Finck #undef NdisGetPacketCancelId 1174*c2c66affSColin Finck PVOID 1175*c2c66affSColin Finck EXPORT 1176*c2c66affSColin Finck NdisGetPacketCancelId( 1177*c2c66affSColin Finck IN PNDIS_PACKET Packet) 1178*c2c66affSColin Finck { 1179*c2c66affSColin Finck return NDIS_GET_PACKET_CANCEL_ID(Packet); 1180*c2c66affSColin Finck } 1181*c2c66affSColin Finck 1182*c2c66affSColin Finck /* 1183*c2c66affSColin Finck * @implemented 1184*c2c66affSColin Finck */ 1185*c2c66affSColin Finck #undef NdisSetPacketCancelId 1186*c2c66affSColin Finck VOID 1187*c2c66affSColin Finck EXPORT 1188*c2c66affSColin Finck NdisSetPacketCancelId( 1189*c2c66affSColin Finck IN PNDIS_PACKET Packet, 1190*c2c66affSColin Finck IN PVOID CancelId) 1191*c2c66affSColin Finck { 1192*c2c66affSColin Finck NDIS_SET_PACKET_CANCEL_ID(Packet, CancelId); 1193*c2c66affSColin Finck } 1194*c2c66affSColin Finck 1195*c2c66affSColin Finck /* 1196*c2c66affSColin Finck * @implemented 1197*c2c66affSColin Finck */ 1198*c2c66affSColin Finck VOID 1199*c2c66affSColin Finck EXPORT 1200*c2c66affSColin Finck NdisCopyFromPacketToPacketSafe( 1201*c2c66affSColin Finck IN PNDIS_PACKET Destination, 1202*c2c66affSColin Finck IN UINT DestinationOffset, 1203*c2c66affSColin Finck IN UINT BytesToCopy, 1204*c2c66affSColin Finck IN PNDIS_PACKET Source, 1205*c2c66affSColin Finck IN UINT SourceOffset, 1206*c2c66affSColin Finck OUT PUINT BytesCopied, 1207*c2c66affSColin Finck IN MM_PAGE_PRIORITY Priority) 1208*c2c66affSColin Finck { 1209*c2c66affSColin Finck PNDIS_BUFFER SrcBuffer; 1210*c2c66affSColin Finck PNDIS_BUFFER DstBuffer; 1211*c2c66affSColin Finck PUCHAR DstData, SrcData; 1212*c2c66affSColin Finck UINT DstSize, SrcSize; 1213*c2c66affSColin Finck UINT Count, Total; 1214*c2c66affSColin Finck 1215*c2c66affSColin Finck *BytesCopied = 0; 1216*c2c66affSColin Finck 1217*c2c66affSColin Finck /* Skip DestinationOffset bytes in the destination packet */ 1218*c2c66affSColin Finck NdisGetFirstBufferFromPacketSafe(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total, Priority); 1219*c2c66affSColin Finck if (!DstData || SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF) 1220*c2c66affSColin Finck return; 1221*c2c66affSColin Finck 1222*c2c66affSColin Finck /* Skip SourceOffset bytes in the source packet */ 1223*c2c66affSColin Finck NdisGetFirstBufferFromPacketSafe(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total, Priority); 1224*c2c66affSColin Finck if (!SrcData || SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 1225*c2c66affSColin Finck return; 1226*c2c66affSColin Finck 1227*c2c66affSColin Finck /* Copy the data */ 1228*c2c66affSColin Finck for (Total = 0;;) { 1229*c2c66affSColin Finck /* Find out how many bytes we can copy at one time */ 1230*c2c66affSColin Finck if (BytesToCopy < SrcSize) 1231*c2c66affSColin Finck Count = BytesToCopy; 1232*c2c66affSColin Finck else 1233*c2c66affSColin Finck Count = SrcSize; 1234*c2c66affSColin Finck if (DstSize < Count) 1235*c2c66affSColin Finck Count = DstSize; 1236*c2c66affSColin Finck 1237*c2c66affSColin Finck RtlCopyMemory(DstData, SrcData, Count); 1238*c2c66affSColin Finck 1239*c2c66affSColin Finck Total += Count; 1240*c2c66affSColin Finck BytesToCopy -= Count; 1241*c2c66affSColin Finck if (BytesToCopy == 0) 1242*c2c66affSColin Finck break; 1243*c2c66affSColin Finck 1244*c2c66affSColin Finck DstSize -= Count; 1245*c2c66affSColin Finck if (DstSize == 0) { 1246*c2c66affSColin Finck /* No more bytes in destination buffer. Proceed to 1247*c2c66affSColin Finck the next buffer in the destination buffer chain */ 1248*c2c66affSColin Finck NdisGetNextBuffer(DstBuffer, &DstBuffer); 1249*c2c66affSColin Finck if (!DstBuffer) 1250*c2c66affSColin Finck break; 1251*c2c66affSColin Finck 1252*c2c66affSColin Finck NdisQueryBufferSafe(DstBuffer, (PVOID)&DstData, &DstSize, Priority); 1253*c2c66affSColin Finck if (!DstData) 1254*c2c66affSColin Finck break; 1255*c2c66affSColin Finck } 1256*c2c66affSColin Finck 1257*c2c66affSColin Finck SrcSize -= Count; 1258*c2c66affSColin Finck if (SrcSize == 0) { 1259*c2c66affSColin Finck /* No more bytes in source buffer. Proceed to 1260*c2c66affSColin Finck the next buffer in the source buffer chain */ 1261*c2c66affSColin Finck NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 1262*c2c66affSColin Finck if (!SrcBuffer) 1263*c2c66affSColin Finck break; 1264*c2c66affSColin Finck 1265*c2c66affSColin Finck NdisQueryBufferSafe(SrcBuffer, (PVOID)&SrcData, &SrcSize, Priority); 1266*c2c66affSColin Finck if (!SrcData) 1267*c2c66affSColin Finck break; 1268*c2c66affSColin Finck } 1269*c2c66affSColin Finck } 1270*c2c66affSColin Finck 1271*c2c66affSColin Finck *BytesCopied = Total; 1272*c2c66affSColin Finck } 1273*c2c66affSColin Finck 1274*c2c66affSColin Finck /* 1275*c2c66affSColin Finck * @implemented 1276*c2c66affSColin Finck */ 1277*c2c66affSColin Finck VOID 1278*c2c66affSColin Finck EXPORT 1279*c2c66affSColin Finck NdisIMCopySendCompletePerPacketInfo( 1280*c2c66affSColin Finck IN PNDIS_PACKET DstPacket, 1281*c2c66affSColin Finck IN PNDIS_PACKET SrcPacket) 1282*c2c66affSColin Finck /* 1283*c2c66affSColin Finck * FUNCTION: 1284*c2c66affSColin Finck * ARGUMENTS: 1285*c2c66affSColin Finck * NOTES: 1286*c2c66affSColin Finck * NDIS 5.0 1287*c2c66affSColin Finck */ 1288*c2c66affSColin Finck { 1289*c2c66affSColin Finck /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and 1290*c2c66affSColin Finck * NdisIMCopySendCompletePerPacketInfo? 1291*c2c66affSColin Finck */ 1292*c2c66affSColin Finck 1293*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 1294*c2c66affSColin Finck 1295*c2c66affSColin Finck RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket), 1296*c2c66affSColin Finck NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket), 1297*c2c66affSColin Finck sizeof(NDIS_PACKET_EXTENSION)); 1298*c2c66affSColin Finck } 1299*c2c66affSColin Finck 1300*c2c66affSColin Finck 1301*c2c66affSColin Finck /* 1302*c2c66affSColin Finck * @implemented 1303*c2c66affSColin Finck */ 1304*c2c66affSColin Finck VOID 1305*c2c66affSColin Finck EXPORT 1306*c2c66affSColin Finck NdisIMCopySendPerPacketInfo( 1307*c2c66affSColin Finck IN PNDIS_PACKET DstPacket, 1308*c2c66affSColin Finck IN PNDIS_PACKET SrcPacket) 1309*c2c66affSColin Finck /* 1310*c2c66affSColin Finck * FUNCTION: 1311*c2c66affSColin Finck * ARGUMENTS: 1312*c2c66affSColin Finck * NOTES: 1313*c2c66affSColin Finck * NDIS 5.0 1314*c2c66affSColin Finck */ 1315*c2c66affSColin Finck { 1316*c2c66affSColin Finck /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and 1317*c2c66affSColin Finck * NdisIMCopySendCompletePerPacketInfo? 1318*c2c66affSColin Finck */ 1319*c2c66affSColin Finck 1320*c2c66affSColin Finck NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 1321*c2c66affSColin Finck 1322*c2c66affSColin Finck RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket), 1323*c2c66affSColin Finck NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket), 1324*c2c66affSColin Finck sizeof(NDIS_PACKET_EXTENSION)); 1325*c2c66affSColin Finck } 1326*c2c66affSColin Finck 1327*c2c66affSColin Finck /* EOF */ 1328