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 NDIS library 00004 * FILE: ndis/buffer.c 00005 * PURPOSE: Buffer management routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 01/08-2000 Created 00009 */ 00010 00011 #include <ndissys.h> 00012 00013 00014 __inline ULONG SkipToOffset( 00015 IN PNDIS_BUFFER Buffer, 00016 IN UINT Offset, 00017 IN OUT PUCHAR *Data, 00018 IN OUT PUINT Size) 00019 /* 00020 * FUNCTION: Skips Offset bytes into a buffer chain 00021 * ARGUMENTS: 00022 * Buffer = Pointer to NDIS buffer 00023 * Offset = Number of bytes to skip 00024 * Data = Address of a pointer that on return will contain the 00025 * address of the offset in the buffer 00026 * Size = Address of a pointer that on return will contain the 00027 * size of the destination buffer 00028 * RETURNS: 00029 * Offset into buffer, -1 if buffer chain was smaller than Offset bytes 00030 * NOTES: 00031 * Buffer may be NULL 00032 */ 00033 { 00034 for (;;) { 00035 00036 if (!Buffer) 00037 return 0xFFFFFFFF; 00038 00039 NdisQueryBuffer(Buffer, (PVOID)Data, Size); 00040 00041 if (Offset < *Size) { 00042 *Data = (PUCHAR) ((ULONG_PTR) *Data + Offset); 00043 *Size -= Offset; 00044 break; 00045 } 00046 00047 Offset -= *Size; 00048 00049 NdisGetNextBuffer(Buffer, &Buffer); 00050 } 00051 00052 return Offset; 00053 } 00054 00055 UINT CopyBufferToBufferChain( 00056 PNDIS_BUFFER DstBuffer, 00057 UINT DstOffset, 00058 PUCHAR 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 PUCHAR DstData; 00076 00077 NDIS_DbgPrint(MAX_TRACE, ("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) == 0xFFFFFFFF) 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 = (PUCHAR) ((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 PUCHAR 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 PUCHAR SrcData; 00133 00134 NDIS_DbgPrint(MAX_TRACE, ("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) == 0xFFFFFFFF) 00138 return 0; 00139 00140 /* Start copying the data */ 00141 BytesCopied = 0; 00142 for (;;) { 00143 BytesToCopy = MIN(SrcSize, Length); 00144 00145 NDIS_DbgPrint(MAX_TRACE, ("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 = (PUCHAR)((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 PUCHAR 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 NDIS_DbgPrint(MAX_TRACE, ("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 PUCHAR DstData, SrcData; 00230 UINT DstSize, SrcSize; 00231 UINT Count, Total; 00232 00233 NDIS_DbgPrint(MAX_TRACE, ("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) == 0xFFFFFFFF) 00238 return 0; 00239 /* Skip SrcOffset bytes in the source packet */ 00240 NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total); 00241 if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 00242 return 0; 00243 /* Copy the data */ 00244 for (Total = 0;;) { 00245 /* Find out how many bytes we can copy at one time */ 00246 if (Length < SrcSize) 00247 Count = Length; 00248 else 00249 Count = SrcSize; 00250 if (DstSize < Count) 00251 Count = DstSize; 00252 00253 RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count); 00254 00255 Total += Count; 00256 Length -= Count; 00257 if (Length == 0) 00258 break; 00259 00260 DstSize -= Count; 00261 if (DstSize == 0) { 00262 /* No more bytes in destination buffer. Proceed to 00263 the next buffer in the destination buffer chain */ 00264 NdisGetNextBuffer(DstBuffer, &DstBuffer); 00265 if (!DstBuffer) 00266 break; 00267 00268 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 00269 } 00270 00271 SrcSize -= Count; 00272 if (SrcSize == 0) { 00273 /* No more bytes in source buffer. Proceed to 00274 the next buffer in the source buffer chain */ 00275 NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 00276 if (!SrcBuffer) 00277 break; 00278 00279 NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize); 00280 } 00281 } 00282 00283 return Total; 00284 } 00285 00286 00287 /* 00288 * @implemented 00289 */ 00290 #undef NdisAdjustBufferLength 00291 VOID 00292 EXPORT 00293 NdisAdjustBufferLength( 00294 IN PNDIS_BUFFER Buffer, 00295 IN UINT Length) 00296 /* 00297 * FUNCTION: Modifies the length of an NDIS buffer 00298 * ARGUMENTS: 00299 * Buffer = Pointer to NDIS buffer descriptor 00300 * Length = New size of buffer 00301 */ 00302 { 00303 Buffer->ByteCount = Length; 00304 } 00305 00306 00307 /* 00308 * @implemented 00309 */ 00310 #undef NDIS_BUFFER_TO_SPAN_PAGES 00311 ULONG 00312 EXPORT 00313 NDIS_BUFFER_TO_SPAN_PAGES( 00314 IN PNDIS_BUFFER Buffer) 00315 /* 00316 * FUNCTION: Determines how many physical pages a buffer is made of 00317 * ARGUMENTS: 00318 * Buffer = Pointer to NDIS buffer descriptor 00319 */ 00320 { 00321 if (MmGetMdlByteCount(Buffer) == 0) 00322 return 1; 00323 00324 return ADDRESS_AND_SIZE_TO_SPAN_PAGES( 00325 MmGetMdlVirtualAddress(Buffer), 00326 MmGetMdlByteCount(Buffer)); 00327 } 00328 00329 00330 /* 00331 * @implemented 00332 */ 00333 VOID 00334 EXPORT 00335 NdisAllocateBuffer( 00336 OUT PNDIS_STATUS Status, 00337 OUT PNDIS_BUFFER * Buffer, 00338 IN NDIS_HANDLE PoolHandle, 00339 IN PVOID VirtualAddress, 00340 IN UINT Length) 00341 /* 00342 * FUNCTION: Allocates an NDIS buffer descriptor 00343 * ARGUMENTS: 00344 * Status = Address of buffer for status 00345 * Buffer = Address of buffer for NDIS buffer descriptor 00346 * PoolHandle = Handle returned by NdisAllocateBufferPool 00347 * VirtualAddress = Pointer to virtual address of data buffer 00348 * Length = Number of bytes in data buffer 00349 */ 00350 { 00351 ASSERT(VirtualAddress != NULL); 00352 ASSERT(Length > 0); 00353 00354 *Buffer = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL); 00355 if (*Buffer != NULL) { 00356 MmBuildMdlForNonPagedPool(*Buffer); 00357 (*Buffer)->Next = NULL; 00358 *Status = NDIS_STATUS_SUCCESS; 00359 } else { 00360 NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", VirtualAddress, Length)); 00361 *Status = NDIS_STATUS_FAILURE; 00362 } 00363 } 00364 00365 00366 /* 00367 * @implemented 00368 */ 00369 VOID 00370 EXPORT 00371 NdisAllocateBufferPool( 00372 OUT PNDIS_STATUS Status, 00373 OUT PNDIS_HANDLE PoolHandle, 00374 IN UINT NumberOfDescriptors) 00375 /* 00376 * FUNCTION: Allocates storage for an NDIS buffer pool 00377 * ARGUMENTS: 00378 * Status = Address of buffer for status 00379 * PoolHandle = Address of buffer for pool handle 00380 * NumberOfDescriptors = Size of buffer pool in number of descriptors 00381 */ 00382 { 00383 *Status = NDIS_STATUS_SUCCESS; 00384 *PoolHandle = 0; 00385 } 00386 00387 00388 /* 00389 * @implemented 00390 */ 00391 VOID 00392 EXPORT 00393 NdisAllocatePacket( 00394 OUT PNDIS_STATUS Status, 00395 OUT PNDIS_PACKET * Packet, 00396 IN NDIS_HANDLE PoolHandle) 00397 /* 00398 * FUNCTION: Allocates an NDIS packet descriptor 00399 * ARGUMENTS: 00400 * Status = Address of buffer for status 00401 * Packet = Address of buffer for packet descriptor 00402 * PoolHandle = Handle returned by NdisAllocatePacketPool 00403 */ 00404 { 00405 PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 00406 00407 KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql); 00408 NdisDprAllocatePacketNonInterlocked(Status, 00409 Packet, 00410 PoolHandle); 00411 KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql); 00412 } 00413 00414 00415 /* 00416 * @implemented 00417 */ 00418 VOID 00419 EXPORT 00420 NdisAllocatePacketPool( 00421 OUT PNDIS_STATUS Status, 00422 OUT PNDIS_HANDLE PoolHandle, 00423 IN UINT NumberOfDescriptors, 00424 IN UINT ProtocolReservedLength) 00425 /* 00426 * FUNCTION: Allocates storage for an NDIS packet pool 00427 * ARGUMENTS: 00428 * Status = Address of buffer for status 00429 * PoolHandle = Address of buffer for pool handle 00430 * NumberOfDescriptors = Size of packet pool in number of descriptors 00431 * ProtocolReservedLength = Size of protocol reserved area in bytes 00432 */ 00433 { 00434 NdisAllocatePacketPoolEx( 00435 Status, 00436 PoolHandle, 00437 NumberOfDescriptors, 00438 0, 00439 ProtocolReservedLength); 00440 } 00441 00442 00443 /* 00444 * @implemented 00445 */ 00446 VOID 00447 EXPORT 00448 NdisAllocatePacketPoolEx( 00449 OUT PNDIS_STATUS Status, 00450 OUT PNDIS_HANDLE PoolHandle, 00451 IN UINT NumberOfDescriptors, 00452 IN UINT NumberOfOverflowDescriptors, 00453 IN UINT ProtocolReservedLength) 00454 /* 00455 * FUNCTION: 00456 * ARGUMENTS: 00457 * NOTES: 00458 * NDIS 5.0 00459 */ 00460 { 00461 PNDISI_PACKET_POOL Pool; 00462 UINT Size, Length, i; 00463 PNDIS_PACKET Packet, NextPacket; 00464 00465 NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) PoolHandle (0x%X) " 00466 "NumberOfDescriptors (%d) ProtocolReservedLength (%d).\n", 00467 Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength)); 00468 00469 *PoolHandle = NULL; 00470 00471 if (NumberOfDescriptors > 0xffff) 00472 { 00473 NDIS_DbgPrint(MIN_TRACE, ("Invalid number of descriptors (%lx)\n", NumberOfDescriptors)) 00474 *Status = NDIS_STATUS_RESOURCES; 00475 } 00476 else 00477 { 00478 NumberOfDescriptors += NumberOfOverflowDescriptors; 00479 if (NumberOfDescriptors > 0xffff) 00480 { 00481 NDIS_DbgPrint(MIN_TRACE, ("Total number of descriptors > 0xffff (%lx)\n", NumberOfDescriptors)); 00482 NumberOfDescriptors = 0xffff; 00483 } 00484 00485 Length = sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 00486 sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedLength; 00487 Size = sizeof(NDISI_PACKET_POOL) + Length * NumberOfDescriptors; 00488 00489 Pool = ExAllocatePool(NonPagedPool, Size); 00490 if (Pool) 00491 { 00492 KeInitializeSpinLock(&Pool->SpinLock.SpinLock); 00493 Pool->PacketLength = Length; 00494 00495 if (NumberOfDescriptors > 0) 00496 { 00497 Packet = (PNDIS_PACKET)&Pool->Buffer; 00498 Pool->FreeList = Packet; 00499 00500 NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length); 00501 for (i = 1; i < NumberOfDescriptors; i++) 00502 { 00503 Packet->Reserved[0] = (ULONG_PTR)NextPacket; 00504 Packet = NextPacket; 00505 NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length); 00506 } 00507 Packet->Reserved[0] = 0; 00508 } 00509 else { 00510 NDIS_DbgPrint(MIN_TRACE, ("Attempted to allocate a packet pool with 0 descriptors\n")); 00511 Pool->FreeList = NULL; 00512 } 00513 00514 *Status = NDIS_STATUS_SUCCESS; 00515 *PoolHandle = (PNDIS_HANDLE)Pool; 00516 } else { 00517 *Status = NDIS_STATUS_RESOURCES; 00518 } 00519 } 00520 } 00521 00522 00523 /* 00524 * @implemented 00525 */ 00526 #undef NdisBufferLength 00527 ULONG 00528 EXPORT 00529 NdisBufferLength( 00530 IN PNDIS_BUFFER Buffer) 00531 /* 00532 * FUNCTION: Modifies the length of an NDIS buffer 00533 * ARGUMENTS: 00534 * Buffer = Pointer to NDIS buffer descriptor 00535 * Length = New size of buffer 00536 * NOTES: 00537 * NDIS 5.0 00538 * RETURNS: 00539 * Length of NDIS buffer 00540 */ 00541 { 00542 return MmGetMdlByteCount(Buffer); 00543 } 00544 00545 00546 /* 00547 * @implemented 00548 */ 00549 #undef NdisBufferVirtualAddress 00550 PVOID 00551 EXPORT 00552 NdisBufferVirtualAddress( 00553 IN PNDIS_BUFFER Buffer) 00554 /* 00555 * FUNCTION: 00556 * ARGUMENTS: 00557 * NOTES: 00558 * NDIS 5.0 00559 */ 00560 { 00561 return MmGetSystemAddressForMdl(Buffer); 00562 } 00563 00564 00565 /* 00566 * @implemented 00567 */ 00568 VOID 00569 EXPORT 00570 NdisCopyFromPacketToPacket( 00571 IN PNDIS_PACKET Destination, 00572 IN UINT DestinationOffset, 00573 IN UINT BytesToCopy, 00574 IN PNDIS_PACKET Source, 00575 IN UINT SourceOffset, 00576 OUT PUINT BytesCopied) 00577 /* 00578 * FUNCTION: Copies data from one packet to another 00579 * ARGUMENTS: 00580 * Destination = Pointer to packet to copy data to 00581 * DestinationOffset = Offset in destination packet to copy data to 00582 * BytesToCopy = Number of bytes to copy 00583 * Source = Pointer to packet descriptor to copy from 00584 * SourceOffset = Offset in source packet to start copying from 00585 * BytesCopied = Address of buffer to place number of bytes copied 00586 */ 00587 { 00588 PNDIS_BUFFER SrcBuffer; 00589 PNDIS_BUFFER DstBuffer; 00590 PUCHAR DstData, SrcData; 00591 UINT DstSize, SrcSize; 00592 UINT Count, Total; 00593 00594 *BytesCopied = 0; 00595 00596 /* Skip DestinationOffset bytes in the destination packet */ 00597 NdisGetFirstBufferFromPacket(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total); 00598 if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF) 00599 return; 00600 00601 /* Skip SourceOffset bytes in the source packet */ 00602 NdisGetFirstBufferFromPacket(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total); 00603 if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 00604 return; 00605 00606 /* Copy the data */ 00607 for (Total = 0;;) { 00608 /* Find out how many bytes we can copy at one time */ 00609 if (BytesToCopy < SrcSize) 00610 Count = BytesToCopy; 00611 else 00612 Count = SrcSize; 00613 if (DstSize < Count) 00614 Count = DstSize; 00615 00616 RtlCopyMemory(DstData, SrcData, Count); 00617 00618 Total += Count; 00619 BytesToCopy -= Count; 00620 if (BytesToCopy == 0) 00621 break; 00622 00623 DstSize -= Count; 00624 if (DstSize == 0) { 00625 /* No more bytes in destination buffer. Proceed to 00626 the next buffer in the destination buffer chain */ 00627 NdisGetNextBuffer(DstBuffer, &DstBuffer); 00628 if (!DstBuffer) 00629 break; 00630 00631 NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize); 00632 } 00633 00634 SrcSize -= Count; 00635 if (SrcSize == 0) { 00636 /* No more bytes in source buffer. Proceed to 00637 the next buffer in the source buffer chain */ 00638 NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 00639 if (!SrcBuffer) 00640 break; 00641 00642 NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize); 00643 } 00644 } 00645 00646 *BytesCopied = Total; 00647 } 00648 00649 00650 /* 00651 * @implemented 00652 */ 00653 VOID 00654 EXPORT 00655 NdisDprAllocatePacket( 00656 OUT PNDIS_STATUS Status, 00657 OUT PNDIS_PACKET *Packet, 00658 IN NDIS_HANDLE PoolHandle) 00659 /* 00660 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL 00661 * ARGUMENTS: 00662 * Status = Address of buffer to place status of operation 00663 * Packet = Address of buffer to place a pointer to a packet descriptor 00664 * PoolHandle = Handle returned by NdisAllocatePacketPool 00665 */ 00666 { 00667 PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 00668 00669 KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock); 00670 NdisDprAllocatePacketNonInterlocked(Status, 00671 Packet, 00672 PoolHandle); 00673 KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock); 00674 } 00675 00676 00677 /* 00678 * @implemented 00679 */ 00680 VOID 00681 EXPORT 00682 NdisDprAllocatePacketNonInterlocked( 00683 OUT PNDIS_STATUS Status, 00684 OUT PNDIS_PACKET *Packet, 00685 IN NDIS_HANDLE PoolHandle) 00686 /* 00687 * FUNCTION: Allocates a packet at IRQL DISPATCH_LEVEL (w/o synchronization) 00688 * ARGUMENTS: 00689 * Status = Address of buffer to place status of operation 00690 * Packet = Address of buffer to place a pointer to a packet descriptor 00691 * PoolHandle = Handle returned by NdisAllocatePacketPool 00692 */ 00693 { 00694 PNDIS_PACKET Temp; 00695 PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)PoolHandle; 00696 00697 NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n", 00698 Status, Packet, PoolHandle)); 00699 00700 *Packet = NULL; 00701 00702 if (Pool == NULL) 00703 { 00704 *Status = NDIS_STATUS_FAILURE; 00705 NDIS_DbgPrint(MIN_TRACE, ("Called passed a bad pool handle\n")); 00706 return; 00707 } 00708 00709 if (Pool->FreeList) { 00710 Temp = Pool->FreeList; 00711 Pool->FreeList = (PNDIS_PACKET)Temp->Reserved[0]; 00712 00713 RtlZeroMemory(Temp, Pool->PacketLength); 00714 Temp->Private.Pool = Pool; 00715 Temp->Private.ValidCounts = TRUE; 00716 Temp->Private.NdisPacketFlags = fPACKET_ALLOCATED_BY_NDIS; 00717 Temp->Private.NdisPacketOobOffset = Pool->PacketLength - 00718 (sizeof(NDIS_PACKET_OOB_DATA) + 00719 sizeof(NDIS_PACKET_EXTENSION)); 00720 00721 *Packet = Temp; 00722 *Status = NDIS_STATUS_SUCCESS; 00723 } else { 00724 NDIS_DbgPrint(MIN_TRACE, ("No more free descriptors\n")); 00725 *Status = NDIS_STATUS_RESOURCES; 00726 } 00727 } 00728 00729 00730 /* 00731 * @implemented 00732 */ 00733 VOID 00734 EXPORT 00735 NdisDprFreePacket( 00736 IN PNDIS_PACKET Packet) 00737 /* 00738 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL 00739 * ARGUMENTS: 00740 * Packet = Pointer to packet to free 00741 */ 00742 { 00743 PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool; 00744 00745 KeAcquireSpinLockAtDpcLevel(&Pool->SpinLock.SpinLock); 00746 NdisDprFreePacketNonInterlocked(Packet); 00747 KeReleaseSpinLockFromDpcLevel(&Pool->SpinLock.SpinLock); 00748 } 00749 00750 00751 /* 00752 * @implemented 00753 */ 00754 VOID 00755 EXPORT 00756 NdisDprFreePacketNonInterlocked( 00757 IN PNDIS_PACKET Packet) 00758 /* 00759 * FUNCTION: Frees a packet at IRQL DISPATCH_LEVEL (w/o synchronization) 00760 * ARGUMENTS: 00761 * Packet = Pointer to packet to free 00762 */ 00763 { 00764 NDIS_DbgPrint(MAX_TRACE, ("Packet (0x%X).\n", Packet)); 00765 00766 Packet->Reserved[0] = (ULONG_PTR)((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList; 00767 ((NDISI_PACKET_POOL*)Packet->Private.Pool)->FreeList = Packet; 00768 } 00769 00770 00771 /* 00772 * @implemented 00773 */ 00774 VOID 00775 EXPORT 00776 NdisFreeBufferPool( 00777 IN NDIS_HANDLE PoolHandle) 00778 /* 00779 * FUNCTION: Frees storage allocated for an NDIS buffer pool 00780 * ARGUMENTS: 00781 * PoolHandle = Handle returned by NdisAllocateBufferPool 00782 */ 00783 { 00784 } 00785 00786 00787 /* 00788 * @implemented 00789 */ 00790 VOID 00791 EXPORT 00792 NdisFreePacketPool( 00793 IN NDIS_HANDLE PoolHandle) 00794 /* 00795 * FUNCTION: Frees storage allocated for an NDIS packet pool 00796 * ARGUMENTS: 00797 * PoolHandle = Handle returned by NdisAllocatePacketPool 00798 */ 00799 { 00800 ExFreePool((PVOID)PoolHandle); 00801 } 00802 00803 00804 /* 00805 * @implemented 00806 */ 00807 #undef NdisFreeBuffer 00808 VOID 00809 EXPORT 00810 NdisFreeBuffer( 00811 IN PNDIS_BUFFER Buffer) 00812 /* 00813 * FUNCTION: Puts an NDIS buffer descriptor back in it's pool 00814 * ARGUMENTS: 00815 * Buffer = Pointer to buffer descriptor 00816 */ 00817 { 00818 IoFreeMdl(Buffer); 00819 } 00820 00821 00822 /* 00823 * @implemented 00824 */ 00825 VOID 00826 EXPORT 00827 NdisFreePacket( 00828 IN PNDIS_PACKET Packet) 00829 /* 00830 * FUNCTION: Puts an NDIS packet descriptor back in it's pool 00831 * ARGUMENTS: 00832 * Packet = Pointer to packet descriptor 00833 */ 00834 { 00835 PNDISI_PACKET_POOL Pool = (PNDISI_PACKET_POOL)Packet->Private.Pool; 00836 00837 KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &Pool->SpinLock.OldIrql); 00838 NdisDprFreePacketNonInterlocked(Packet); 00839 KeReleaseSpinLock(&Pool->SpinLock.SpinLock, Pool->SpinLock.OldIrql); 00840 } 00841 00842 00843 /* 00844 * @implemented 00845 */ 00846 #undef NdisGetBufferPhysicalArraySize 00847 VOID 00848 EXPORT 00849 NdisGetBufferPhysicalArraySize( 00850 IN PNDIS_BUFFER Buffer, 00851 OUT PUINT ArraySize) 00852 /* 00853 * FUNCTION: Returns number of discontiguous physical blocks backing a buffer 00854 * ARGUMENTS: 00855 * Buffer = Pointer to buffer descriptor 00856 * ArraySize = Address of buffer to place number of physical blocks 00857 */ 00858 { 00859 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00860 ASSERT(Buffer && ArraySize); 00861 00862 *ArraySize = NDIS_BUFFER_TO_SPAN_PAGES(Buffer); 00863 } 00864 00865 00866 /* 00867 * @implemented 00868 */ 00869 #undef NdisGetFirstBufferFromPacket 00870 VOID 00871 EXPORT 00872 NdisGetFirstBufferFromPacket( 00873 IN PNDIS_PACKET _Packet, 00874 OUT PNDIS_BUFFER *_FirstBuffer, 00875 OUT PVOID *_FirstBufferVA, 00876 OUT PUINT _FirstBufferLength, 00877 OUT PUINT _TotalBufferLength) 00878 /* 00879 * FUNCTION: Retrieves information about an NDIS packet 00880 * ARGUMENTS: 00881 * _Packet = Pointer to NDIS packet 00882 * _FirstBuffer = Address of buffer for pointer to first NDIS buffer 00883 * _FirstBufferVA = Address of buffer for address of first NDIS buffer 00884 * _FirstBufferLength = Address of buffer for length of first buffer 00885 * _TotalBufferLength = Address of buffer for total length of packet 00886 */ 00887 { 00888 PNDIS_BUFFER Buffer; 00889 00890 Buffer = _Packet->Private.Head; 00891 *_FirstBuffer = Buffer; 00892 00893 if (Buffer != NULL) { 00894 *_FirstBufferLength = MmGetMdlByteCount(Buffer); 00895 *_FirstBufferVA = MmGetSystemAddressForMdl(Buffer); 00896 Buffer = Buffer->Next; 00897 } else { 00898 NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n")); 00899 *_FirstBufferLength = 0; 00900 *_FirstBufferVA = NULL; 00901 } 00902 00903 *_TotalBufferLength = *_FirstBufferLength; 00904 00905 while (Buffer != NULL) { 00906 *_TotalBufferLength += MmGetMdlByteCount(Buffer); 00907 Buffer = Buffer->Next; 00908 } 00909 } 00910 00911 #undef NdisGetFirstBufferFromPacketSafe 00912 /* 00913 * @implemented 00914 */ 00915 VOID 00916 EXPORT 00917 NdisGetFirstBufferFromPacketSafe( 00918 IN PNDIS_PACKET _Packet, 00919 OUT PNDIS_BUFFER *_FirstBuffer, 00920 OUT PVOID *_FirstBufferVA, 00921 OUT PUINT _FirstBufferLength, 00922 OUT PUINT _TotalBufferLength, 00923 IN MM_PAGE_PRIORITY Priority) 00924 { 00925 PNDIS_BUFFER Buffer; 00926 00927 Buffer = _Packet->Private.Head; 00928 *_FirstBuffer = Buffer; 00929 00930 if (Buffer != NULL) { 00931 *_FirstBufferLength = MmGetMdlByteCount(Buffer); 00932 *_FirstBufferVA = MmGetSystemAddressForMdlSafe(Buffer, Priority); 00933 Buffer = Buffer->Next; 00934 } else { 00935 NDIS_DbgPrint(MID_TRACE, ("No buffers linked to this packet\n")); 00936 *_FirstBufferLength = 0; 00937 *_FirstBufferVA = NULL; 00938 } 00939 00940 *_TotalBufferLength = *_FirstBufferLength; 00941 00942 while (Buffer != NULL) { 00943 *_TotalBufferLength += MmGetMdlByteCount(Buffer); 00944 Buffer = Buffer->Next; 00945 } 00946 } 00947 00948 /* 00949 * @implemented 00950 */ 00951 #undef NdisQueryBuffer 00952 VOID 00953 EXPORT 00954 NdisQueryBuffer( 00955 IN PNDIS_BUFFER Buffer, 00956 OUT PVOID *VirtualAddress OPTIONAL, 00957 OUT PUINT Length) 00958 /* 00959 * FUNCTION: 00960 * Queries an NDIS buffer for information 00961 * ARGUMENTS: 00962 * Buffer = Pointer to NDIS buffer to query 00963 * VirtualAddress = Address of buffer to place virtual address 00964 * Length = Address of buffer to place length of buffer 00965 */ 00966 { 00967 if (VirtualAddress != NULL) 00968 *(PVOID*)VirtualAddress = MmGetSystemAddressForMdl(Buffer); 00969 00970 *Length = MmGetMdlByteCount(Buffer); 00971 } 00972 00973 00974 /* 00975 * @implemented 00976 */ 00977 #undef NdisQueryBufferSafe 00978 VOID 00979 EXPORT 00980 NdisQueryBufferSafe( 00981 IN PNDIS_BUFFER Buffer, 00982 OUT PVOID *VirtualAddress OPTIONAL, 00983 OUT PUINT Length, 00984 IN UINT Priority) 00985 /* 00986 * FUNCTION: 00987 * ARGUMENTS: 00988 * NOTES: 00989 * NDIS 5.0 00990 */ 00991 { 00992 if (VirtualAddress != NULL) 00993 *VirtualAddress = MmGetSystemAddressForMdlSafe(Buffer, Priority); 00994 *Length = MmGetMdlByteCount(Buffer); 00995 } 00996 00997 00998 /* 00999 * @implemented 01000 */ 01001 #undef NdisQueryBufferOffset 01002 VOID 01003 EXPORT 01004 NdisQueryBufferOffset( 01005 IN PNDIS_BUFFER Buffer, 01006 OUT PUINT Offset, 01007 OUT PUINT Length) 01008 { 01009 *((PUINT)Offset) = MmGetMdlByteOffset(Buffer); 01010 *((PUINT)Length) = MmGetMdlByteCount(Buffer); 01011 } 01012 01013 01014 /* 01015 * @implemented 01016 */ 01017 VOID 01018 EXPORT 01019 NdisUnchainBufferAtBack( 01020 IN OUT PNDIS_PACKET Packet, 01021 OUT PNDIS_BUFFER *Buffer) 01022 /* 01023 * FUNCTION: 01024 * Removes the last buffer in a packet 01025 * ARGUMENTS: 01026 * Packet = Pointer to NDIS packet 01027 * Buffer = Address of buffer to place pointer to removed NDIS buffer 01028 */ 01029 { 01030 PNDIS_BUFFER NdisBuffer, Previous; 01031 01032 NdisQueryPacket(Packet, 01033 NULL, 01034 NULL, 01035 &NdisBuffer, 01036 NULL); 01037 if (!NdisBuffer) { 01038 NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n")); 01039 *Buffer = NULL; 01040 return; 01041 } 01042 01043 Previous = NULL; 01044 while (NdisBuffer->Next) { 01045 Previous = NdisBuffer; 01046 NdisBuffer = NdisBuffer->Next; 01047 } 01048 01049 if (Previous) { 01050 Previous->Next = NULL; 01051 Packet->Private.Tail = Previous; 01052 } else { 01053 Packet->Private.Head = NULL; 01054 Packet->Private.Tail = NULL; 01055 } 01056 01057 Packet->Private.ValidCounts = FALSE; 01058 01059 *Buffer = NdisBuffer; 01060 } 01061 01062 01063 /* 01064 * @implemented 01065 */ 01066 VOID 01067 EXPORT 01068 NdisUnchainBufferAtFront( 01069 IN OUT PNDIS_PACKET Packet, 01070 OUT PNDIS_BUFFER *Buffer) 01071 /* 01072 * FUNCTION: 01073 * Removes the first buffer in a packet 01074 * ARGUMENTS: 01075 * Packet = Pointer to NDIS packet 01076 * Buffer = Address of buffer to place pointer to removed NDIS buffer 01077 */ 01078 { 01079 PNDIS_BUFFER NdisBuffer; 01080 01081 NdisQueryPacket(Packet, 01082 NULL, 01083 NULL, 01084 &NdisBuffer, 01085 NULL); 01086 if (!NdisBuffer) { 01087 NDIS_DbgPrint(MID_TRACE, ("No buffer to unchain\n")); 01088 *Buffer = NULL; 01089 return; 01090 } 01091 01092 Packet->Private.Head = NdisBuffer->Next; 01093 01094 if (!NdisBuffer->Next) 01095 Packet->Private.Tail = NULL; 01096 01097 NdisBuffer->Next = NULL; 01098 01099 Packet->Private.ValidCounts = FALSE; 01100 01101 *Buffer = NdisBuffer; 01102 } 01103 01104 /* 01105 * @implemented 01106 */ 01107 VOID 01108 EXPORT 01109 NdisCopyBuffer( 01110 OUT PNDIS_STATUS Status, 01111 OUT PNDIS_BUFFER *Buffer, 01112 IN NDIS_HANDLE PoolHandle, 01113 IN PVOID MemoryDescriptor, 01114 IN UINT Offset, 01115 IN UINT Length) 01116 /* 01117 * FUNCTION: Returns a new buffer descriptor for a (partial) buffer 01118 * ARGUMENTS: 01119 * Status = Address of a buffer to place status of operation 01120 * Buffer = Address of a buffer to place new buffer descriptor 01121 * PoolHandle = Handle returned by NdisAllocateBufferPool 01122 * MemoryDescriptor = Pointer to a memory descriptor (possibly NDIS_BUFFER) 01123 * Offset = Offset in buffer to start copying 01124 * Length = Number of bytes to copy 01125 */ 01126 { 01127 PVOID CurrentVa = (PUCHAR)(MmGetMdlVirtualAddress((PNDIS_BUFFER)MemoryDescriptor)) + Offset; 01128 01129 NDIS_DbgPrint(MAX_TRACE, ("Called\n")); 01130 01131 *Buffer = IoAllocateMdl(CurrentVa, Length, FALSE, FALSE, NULL); 01132 if (!*Buffer) 01133 { 01134 NDIS_DbgPrint(MIN_TRACE, ("IoAllocateMdl failed (%x, %lx)\n", CurrentVa, Length)); 01135 *Status = NDIS_STATUS_FAILURE; 01136 return; 01137 } 01138 01139 IoBuildPartialMdl((PNDIS_BUFFER)MemoryDescriptor, 01140 *Buffer, 01141 CurrentVa, 01142 Length); 01143 01144 (*Buffer)->Next = NULL; 01145 *Status = NDIS_STATUS_SUCCESS; 01146 } 01147 01148 /* 01149 * @implemented 01150 */ 01151 NDIS_HANDLE 01152 EXPORT 01153 NdisGetPoolFromPacket( 01154 IN PNDIS_PACKET Packet) 01155 { 01156 return Packet->Private.Pool; 01157 } 01158 01159 /* 01160 * @implemented 01161 */ 01162 UINT 01163 EXPORT 01164 NdisPacketSize( 01165 IN UINT ProtocolReservedSize) 01166 { 01167 return sizeof(NDIS_PACKET) + sizeof(NDIS_PACKET_OOB_DATA) + 01168 sizeof(NDIS_PACKET_EXTENSION) + ProtocolReservedSize; 01169 } 01170 01171 /* 01172 * @implemented 01173 */ 01174 #undef NdisGetPacketCancelId 01175 PVOID 01176 EXPORT 01177 NdisGetPacketCancelId( 01178 IN PNDIS_PACKET Packet) 01179 { 01180 return NDIS_GET_PACKET_CANCEL_ID(Packet); 01181 } 01182 01183 /* 01184 * @implemented 01185 */ 01186 #undef NdisSetPacketCancelId 01187 VOID 01188 EXPORT 01189 NdisSetPacketCancelId( 01190 IN PNDIS_PACKET Packet, 01191 IN PVOID CancelId) 01192 { 01193 NDIS_SET_PACKET_CANCEL_ID(Packet, CancelId); 01194 } 01195 01196 /* 01197 * @implemented 01198 */ 01199 VOID 01200 EXPORT 01201 NdisCopyFromPacketToPacketSafe( 01202 IN PNDIS_PACKET Destination, 01203 IN UINT DestinationOffset, 01204 IN UINT BytesToCopy, 01205 IN PNDIS_PACKET Source, 01206 IN UINT SourceOffset, 01207 OUT PUINT BytesCopied, 01208 IN MM_PAGE_PRIORITY Priority) 01209 { 01210 PNDIS_BUFFER SrcBuffer; 01211 PNDIS_BUFFER DstBuffer; 01212 PUCHAR DstData, SrcData; 01213 UINT DstSize, SrcSize; 01214 UINT Count, Total; 01215 01216 *BytesCopied = 0; 01217 01218 /* Skip DestinationOffset bytes in the destination packet */ 01219 NdisGetFirstBufferFromPacketSafe(Destination, &DstBuffer, (PVOID*)&DstData, &DstSize, &Total, Priority); 01220 if (!DstData || SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF) 01221 return; 01222 01223 /* Skip SourceOffset bytes in the source packet */ 01224 NdisGetFirstBufferFromPacketSafe(Source, &SrcBuffer, (PVOID*)&SrcData, &SrcSize, &Total, Priority); 01225 if (!SrcData || SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF) 01226 return; 01227 01228 /* Copy the data */ 01229 for (Total = 0;;) { 01230 /* Find out how many bytes we can copy at one time */ 01231 if (BytesToCopy < SrcSize) 01232 Count = BytesToCopy; 01233 else 01234 Count = SrcSize; 01235 if (DstSize < Count) 01236 Count = DstSize; 01237 01238 RtlCopyMemory(DstData, SrcData, Count); 01239 01240 Total += Count; 01241 BytesToCopy -= Count; 01242 if (BytesToCopy == 0) 01243 break; 01244 01245 DstSize -= Count; 01246 if (DstSize == 0) { 01247 /* No more bytes in destination buffer. Proceed to 01248 the next buffer in the destination buffer chain */ 01249 NdisGetNextBuffer(DstBuffer, &DstBuffer); 01250 if (!DstBuffer) 01251 break; 01252 01253 NdisQueryBufferSafe(DstBuffer, (PVOID)&DstData, &DstSize, Priority); 01254 if (!DstData) 01255 break; 01256 } 01257 01258 SrcSize -= Count; 01259 if (SrcSize == 0) { 01260 /* No more bytes in source buffer. Proceed to 01261 the next buffer in the source buffer chain */ 01262 NdisGetNextBuffer(SrcBuffer, &SrcBuffer); 01263 if (!SrcBuffer) 01264 break; 01265 01266 NdisQueryBufferSafe(SrcBuffer, (PVOID)&SrcData, &SrcSize, Priority); 01267 if (!SrcData) 01268 break; 01269 } 01270 } 01271 01272 *BytesCopied = Total; 01273 } 01274 01275 /* 01276 * @implemented 01277 */ 01278 VOID 01279 EXPORT 01280 NdisIMCopySendCompletePerPacketInfo( 01281 IN PNDIS_PACKET DstPacket, 01282 IN PNDIS_PACKET SrcPacket) 01283 /* 01284 * FUNCTION: 01285 * ARGUMENTS: 01286 * NOTES: 01287 * NDIS 5.0 01288 */ 01289 { 01290 /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and 01291 * NdisIMCopySendCompletePerPacketInfo? 01292 */ 01293 01294 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 01295 01296 RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket), 01297 NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket), 01298 sizeof(NDIS_PACKET_EXTENSION)); 01299 } 01300 01301 01302 /* 01303 * @implemented 01304 */ 01305 VOID 01306 EXPORT 01307 NdisIMCopySendPerPacketInfo( 01308 IN PNDIS_PACKET DstPacket, 01309 IN PNDIS_PACKET SrcPacket) 01310 /* 01311 * FUNCTION: 01312 * ARGUMENTS: 01313 * NOTES: 01314 * NDIS 5.0 01315 */ 01316 { 01317 /* FIXME: What is the difference between NdisIMCopySendPerPacketInfo and 01318 * NdisIMCopySendCompletePerPacketInfo? 01319 */ 01320 01321 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 01322 01323 RtlCopyMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(DstPacket), 01324 NDIS_PACKET_EXTENSION_FROM_PACKET(SrcPacket), 01325 sizeof(NDIS_PACKET_EXTENSION)); 01326 } 01327 01328 /* EOF */ Generated on Sun May 27 2012 04:21:35 for ReactOS by
1.7.6.1
|