|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: transfer.c ! 8: ! 9: Abstract: ! 10: ! 11: This module contains code to copy from ndis packets to ndis packets, ! 12: and also to copy from ndis packets to a buffer. ! 13: ! 14: Author: ! 15: ! 16: Anthony V. Ercolano (Tonye) 12-Sept-1990 ! 17: ! 18: Environment: ! 19: ! 20: Works in kernel mode, but is not important that it does. ! 21: ! 22: Revision History: ! 23: ! 24: ! 25: --*/ ! 26: ! 27: #pragma optimize("",off) ! 28: ! 29: #include <ndis.h> ! 30: ! 31: #include <tfilter.h> ! 32: #include <tokhrd.h> ! 33: #include <toksft.h> ! 34: ! 35: ! 36: extern ! 37: VOID ! 38: IbmtokCopyFromPacketToBuffer( ! 39: IN PNDIS_PACKET Packet, ! 40: IN UINT Offset, ! 41: IN UINT BytesToCopy, ! 42: OUT PCHAR Buffer, ! 43: OUT PUINT BytesCopied ! 44: ) ! 45: ! 46: /*++ ! 47: ! 48: Routine Description: ! 49: ! 50: Copy from an ndis packet into a buffer. ! 51: ! 52: Arguments: ! 53: ! 54: Packet - The packet to copy from. ! 55: ! 56: Offset - The offset from which to start the copy. ! 57: ! 58: BytesToCopy - The number of bytes to copy from the packet. ! 59: ! 60: Buffer - The destination of the copy. ! 61: ! 62: BytesCopied - The number of bytes actually copied. Can be less then ! 63: BytesToCopy if the packet is shorter than BytesToCopy. ! 64: ! 65: Return Value: ! 66: ! 67: None ! 68: ! 69: --*/ ! 70: ! 71: { ! 72: ! 73: // ! 74: // Holds the number of ndis buffers comprising the packet. ! 75: // ! 76: UINT NdisBufferCount; ! 77: ! 78: // ! 79: // Points to the buffer from which we are extracting data. ! 80: // ! 81: PNDIS_BUFFER CurrentBuffer; ! 82: ! 83: // ! 84: // Holds the virtual address of the current buffer. ! 85: // ! 86: PVOID VirtualAddress; ! 87: ! 88: // ! 89: // Holds the length of the current buffer of the packet. ! 90: // ! 91: UINT CurrentLength; ! 92: ! 93: // ! 94: // Keep a local variable of BytesCopied so we aren't referencing ! 95: // through a pointer. ! 96: // ! 97: UINT LocalBytesCopied = 0; ! 98: ! 99: // ! 100: // Take care of boundary condition of zero length copy. ! 101: // ! 102: ! 103: *BytesCopied = 0; ! 104: if (!BytesToCopy) return; ! 105: ! 106: // ! 107: // Get the first buffer. ! 108: // ! 109: ! 110: NdisQueryPacket(Packet, ! 111: NULL, ! 112: &NdisBufferCount, ! 113: &CurrentBuffer, ! 114: NULL ! 115: ); ! 116: ! 117: // ! 118: // Could have a null packet. ! 119: // ! 120: ! 121: if (!NdisBufferCount) return; ! 122: ! 123: NdisQueryBuffer(CurrentBuffer, &VirtualAddress, &CurrentLength); ! 124: ! 125: while (LocalBytesCopied < BytesToCopy) { ! 126: ! 127: if (!CurrentLength) { ! 128: ! 129: NdisGetNextBuffer( ! 130: CurrentBuffer, ! 131: &CurrentBuffer ! 132: ); ! 133: ! 134: // ! 135: // We've reached the end of the packet. We return ! 136: // with what we've done so far. (Which must be shorter ! 137: // than requested. ! 138: // ! 139: ! 140: if (CurrentBuffer == NULL) break; ! 141: ! 142: NdisQueryBuffer(CurrentBuffer, &VirtualAddress, &CurrentLength); ! 143: continue; ! 144: ! 145: } ! 146: ! 147: // ! 148: // Try to get us up to the point to start the copy. ! 149: // ! 150: ! 151: if (Offset) { ! 152: ! 153: if (Offset > CurrentLength) { ! 154: ! 155: // ! 156: // What we want isn't in this buffer. ! 157: // ! 158: ! 159: Offset -= CurrentLength; ! 160: CurrentLength = 0; ! 161: continue; ! 162: ! 163: } else { ! 164: ! 165: VirtualAddress = (PCHAR)VirtualAddress + Offset; ! 166: CurrentLength -= Offset; ! 167: Offset = 0; ! 168: ! 169: } ! 170: ! 171: } ! 172: ! 173: // ! 174: // Copy the data. ! 175: // ! 176: ! 177: ! 178: { ! 179: ! 180: // ! 181: // Holds the amount of data to move. ! 182: // ! 183: UINT AmountToMove; ! 184: ! 185: AmountToMove = ! 186: ((CurrentLength <= (BytesToCopy - LocalBytesCopied))? ! 187: (CurrentLength):(BytesToCopy - LocalBytesCopied)); ! 188: ! 189: IBMTOK_MOVE_TO_MAPPED_MEMORY( ! 190: Buffer, ! 191: VirtualAddress, ! 192: AmountToMove ! 193: ); ! 194: ! 195: Buffer = (PCHAR)Buffer + AmountToMove; ! 196: VirtualAddress = (PCHAR)VirtualAddress + AmountToMove; ! 197: ! 198: LocalBytesCopied += AmountToMove; ! 199: CurrentLength -= AmountToMove; ! 200: ! 201: } ! 202: ! 203: } ! 204: ! 205: *BytesCopied = LocalBytesCopied; ! 206: ! 207: } ! 208: ! 209: extern ! 210: VOID ! 211: IbmtokCopyFromBufferToPacket( ! 212: IN PCHAR Buffer, ! 213: IN UINT BytesToCopy, ! 214: IN PNDIS_PACKET Packet, ! 215: IN UINT Offset, ! 216: OUT PUINT BytesCopied ! 217: ) ! 218: ! 219: /*++ ! 220: ! 221: Routine Description: ! 222: ! 223: Copy from a buffer into an ndis packet. ! 224: ! 225: Arguments: ! 226: ! 227: Buffer - The packet to copy from. ! 228: ! 229: Offset - The offset from which to start the copy. ! 230: ! 231: BytesToCopy - The number of bytes to copy from the buffer. ! 232: ! 233: Packet - The destination of the copy. ! 234: ! 235: BytesCopied - The number of bytes actually copied. Will be less ! 236: than BytesToCopy if the packet is not large enough. ! 237: ! 238: Return Value: ! 239: ! 240: None ! 241: ! 242: --*/ ! 243: ! 244: { ! 245: // ! 246: // Holds the count of the number of ndis buffers comprising the ! 247: // destination packet. ! 248: // ! 249: UINT DestinationBufferCount; ! 250: ! 251: // ! 252: // Points to the buffer into which we are putting data. ! 253: // ! 254: PNDIS_BUFFER DestinationCurrentBuffer; ! 255: ! 256: // ! 257: // Points to the location in Buffer from which we are extracting data. ! 258: // ! 259: PUCHAR SourceCurrentAddress; ! 260: ! 261: // ! 262: // Holds the virtual address of the current destination buffer. ! 263: // ! 264: PVOID DestinationVirtualAddress; ! 265: ! 266: // ! 267: // Holds the length of the current destination buffer. ! 268: // ! 269: UINT DestinationCurrentLength; ! 270: ! 271: // ! 272: // Keep a local variable of BytesCopied so we aren't referencing ! 273: // through a pointer. ! 274: // ! 275: UINT LocalBytesCopied = 0; ! 276: ! 277: ! 278: // ! 279: // Take care of boundary condition of zero length copy. ! 280: // ! 281: ! 282: *BytesCopied = 0; ! 283: if (!BytesToCopy) return; ! 284: ! 285: // ! 286: // Get the first buffer of the destination. ! 287: // ! 288: ! 289: NdisQueryPacket( ! 290: Packet, ! 291: NULL, ! 292: &DestinationBufferCount, ! 293: &DestinationCurrentBuffer, ! 294: NULL ! 295: ); ! 296: ! 297: // ! 298: // Could have a null packet. ! 299: // ! 300: ! 301: if (!DestinationBufferCount) return; ! 302: ! 303: NdisQueryBuffer( ! 304: DestinationCurrentBuffer, ! 305: &DestinationVirtualAddress, ! 306: &DestinationCurrentLength ! 307: ); ! 308: ! 309: // ! 310: // Set up the source address. ! 311: // ! 312: ! 313: SourceCurrentAddress = Buffer; ! 314: ! 315: ! 316: while (LocalBytesCopied < BytesToCopy) { ! 317: ! 318: // ! 319: // Check to see whether we've exhausted the current destination ! 320: // buffer. If so, move onto the next one. ! 321: // ! 322: ! 323: if (!DestinationCurrentLength) { ! 324: ! 325: NdisGetNextBuffer( ! 326: DestinationCurrentBuffer, ! 327: &DestinationCurrentBuffer ! 328: ); ! 329: ! 330: if (DestinationCurrentBuffer == NULL) { ! 331: ! 332: // ! 333: // We've reached the end of the packet. We return ! 334: // with what we've done so far. (Which must be shorter ! 335: // than requested.) ! 336: // ! 337: ! 338: break; ! 339: ! 340: } ! 341: ! 342: NdisQueryBuffer( ! 343: DestinationCurrentBuffer, ! 344: &DestinationVirtualAddress, ! 345: &DestinationCurrentLength ! 346: ); ! 347: ! 348: continue; ! 349: ! 350: } ! 351: ! 352: // ! 353: // Try to get us up to the point to start the copy. ! 354: // ! 355: ! 356: if (Offset) { ! 357: ! 358: if (Offset > DestinationCurrentLength) { ! 359: ! 360: // ! 361: // What we want isn't in this buffer. ! 362: // ! 363: ! 364: Offset -= DestinationCurrentLength; ! 365: DestinationCurrentLength = 0; ! 366: continue; ! 367: ! 368: } else { ! 369: ! 370: DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress ! 371: + Offset; ! 372: DestinationCurrentLength -= Offset; ! 373: Offset = 0; ! 374: ! 375: } ! 376: ! 377: } ! 378: ! 379: ! 380: // ! 381: // Copy the data. ! 382: // ! 383: ! 384: { ! 385: ! 386: // ! 387: // Holds the amount of data to move. ! 388: // ! 389: UINT AmountToMove; ! 390: ! 391: // ! 392: // Holds the amount desired remaining. ! 393: // ! 394: UINT Remaining = BytesToCopy - LocalBytesCopied; ! 395: ! 396: ! 397: AmountToMove = DestinationCurrentLength; ! 398: ! 399: AmountToMove = ((Remaining < AmountToMove)? ! 400: (Remaining):(AmountToMove)); ! 401: ! 402: IBMTOK_MOVE_FROM_MAPPED_MEMORY( ! 403: DestinationVirtualAddress, ! 404: SourceCurrentAddress, ! 405: AmountToMove ! 406: ); ! 407: ! 408: SourceCurrentAddress += AmountToMove; ! 409: LocalBytesCopied += AmountToMove; ! 410: DestinationCurrentLength -= AmountToMove; ! 411: ! 412: } ! 413: ! 414: } ! 415: ! 416: *BytesCopied = LocalBytesCopied; ! 417: ! 418: ! 419: } ! 420: ! 421: extern ! 422: VOID ! 423: IbmtokCopyFromPacketToPacket( ! 424: IN PNDIS_PACKET Destination, ! 425: IN UINT DestinationOffset, ! 426: IN UINT BytesToCopy, ! 427: IN PNDIS_PACKET Source, ! 428: IN UINT SourceOffset, ! 429: OUT PUINT BytesCopied ! 430: ) ! 431: ! 432: /*++ ! 433: ! 434: Routine Description: ! 435: ! 436: Copy from an ndis packet to an ndis packet. ! 437: ! 438: Arguments: ! 439: ! 440: Destination - The packet should be copied in to. ! 441: ! 442: DestinationOffset - The offset from the beginning of the packet ! 443: into which the data should start being placed. ! 444: ! 445: BytesToCopy - The number of bytes to copy from the source packet. ! 446: ! 447: Source - The ndis packet from which to copy data. ! 448: ! 449: SourceOffset - The offset from the start of the packet from which ! 450: to start copying data. ! 451: ! 452: BytesCopied - The number of bytes actually copied from the source ! 453: packet. This can be less than BytesToCopy if the source or destination ! 454: packet is too short. ! 455: ! 456: Return Value: ! 457: ! 458: None ! 459: ! 460: --*/ ! 461: ! 462: { ! 463: ! 464: // ! 465: // Holds the count of the number of ndis buffers comprising the ! 466: // destination packet. ! 467: // ! 468: UINT DestinationBufferCount; ! 469: ! 470: // ! 471: // Holds the count of the number of ndis buffers comprising the ! 472: // source packet. ! 473: // ! 474: UINT SourceBufferCount; ! 475: ! 476: // ! 477: // Points to the buffer into which we are putting data. ! 478: // ! 479: PNDIS_BUFFER DestinationCurrentBuffer; ! 480: ! 481: // ! 482: // Points to the buffer from which we are extracting data. ! 483: // ! 484: PNDIS_BUFFER SourceCurrentBuffer; ! 485: ! 486: // ! 487: // Holds the virtual address of the current destination buffer. ! 488: // ! 489: PVOID DestinationVirtualAddress; ! 490: ! 491: // ! 492: // Holds the virtual address of the current source buffer. ! 493: // ! 494: PVOID SourceVirtualAddress; ! 495: ! 496: // ! 497: // Holds the length of the current destination buffer. ! 498: // ! 499: UINT DestinationCurrentLength; ! 500: ! 501: // ! 502: // Holds the length of the current source buffer. ! 503: // ! 504: UINT SourceCurrentLength; ! 505: ! 506: // ! 507: // Keep a local variable of BytesCopied so we aren't referencing ! 508: // through a pointer. ! 509: // ! 510: UINT LocalBytesCopied = 0; ! 511: ! 512: // ! 513: // Take care of boundary condition of zero length copy. ! 514: // ! 515: ! 516: *BytesCopied = 0; ! 517: if (!BytesToCopy) return; ! 518: ! 519: // ! 520: // Get the first buffer of the destination. ! 521: // ! 522: ! 523: NdisQueryPacket( ! 524: Destination, ! 525: NULL, ! 526: &DestinationBufferCount, ! 527: &DestinationCurrentBuffer, ! 528: NULL ! 529: ); ! 530: ! 531: // ! 532: // Could have a null packet. ! 533: // ! 534: ! 535: if (!DestinationBufferCount) return; ! 536: ! 537: NdisQueryBuffer( ! 538: DestinationCurrentBuffer, ! 539: &DestinationVirtualAddress, ! 540: &DestinationCurrentLength ! 541: ); ! 542: ! 543: // ! 544: // Get the first buffer of the source. ! 545: // ! 546: ! 547: NdisQueryPacket( ! 548: Source, ! 549: NULL, ! 550: &SourceBufferCount, ! 551: &SourceCurrentBuffer, ! 552: NULL ! 553: ); ! 554: ! 555: // ! 556: // Could have a null packet. ! 557: // ! 558: ! 559: if (!SourceBufferCount) return; ! 560: ! 561: NdisQueryBuffer( ! 562: SourceCurrentBuffer, ! 563: &SourceVirtualAddress, ! 564: &SourceCurrentLength ! 565: ); ! 566: ! 567: while (LocalBytesCopied < BytesToCopy) { ! 568: ! 569: // ! 570: // Check to see whether we've exhausted the current destination ! 571: // buffer. If so, move onto the next one. ! 572: // ! 573: ! 574: if (!DestinationCurrentLength) { ! 575: ! 576: NdisGetNextBuffer( ! 577: DestinationCurrentBuffer, ! 578: &DestinationCurrentBuffer ! 579: ); ! 580: ! 581: if (DestinationCurrentBuffer == NULL) { ! 582: ! 583: // ! 584: // We've reached the end of the packet. We return ! 585: // with what we've done so far. (Which must be shorter ! 586: // than requested.) ! 587: // ! 588: ! 589: break; ! 590: ! 591: } ! 592: ! 593: NdisQueryBuffer( ! 594: DestinationCurrentBuffer, ! 595: &DestinationVirtualAddress, ! 596: &DestinationCurrentLength ! 597: ); ! 598: continue; ! 599: ! 600: } ! 601: ! 602: ! 603: // ! 604: // Check to see whether we've exhausted the current source ! 605: // buffer. If so, move onto the next one. ! 606: // ! 607: ! 608: if (!SourceCurrentLength) { ! 609: ! 610: NdisGetNextBuffer( ! 611: SourceCurrentBuffer, ! 612: &SourceCurrentBuffer ! 613: ); ! 614: ! 615: if (SourceCurrentBuffer == NULL) { ! 616: ! 617: // ! 618: // We've reached the end of the packet. We return ! 619: // with what we've done so far. (Which must be shorter ! 620: // than requested.) ! 621: // ! 622: ! 623: break; ! 624: ! 625: } ! 626: ! 627: NdisQueryBuffer( ! 628: SourceCurrentBuffer, ! 629: &SourceVirtualAddress, ! 630: &SourceCurrentLength ! 631: ); ! 632: continue; ! 633: ! 634: } ! 635: ! 636: // ! 637: // Try to get us up to the point to start the copy. ! 638: // ! 639: ! 640: if (DestinationOffset) { ! 641: ! 642: if (DestinationOffset > DestinationCurrentLength) { ! 643: ! 644: // ! 645: // What we want isn't in this buffer. ! 646: // ! 647: ! 648: DestinationOffset -= DestinationCurrentLength; ! 649: DestinationCurrentLength = 0; ! 650: continue; ! 651: ! 652: } else { ! 653: ! 654: DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress ! 655: + DestinationOffset; ! 656: DestinationCurrentLength -= DestinationOffset; ! 657: DestinationOffset = 0; ! 658: ! 659: } ! 660: ! 661: } ! 662: ! 663: // ! 664: // Try to get us up to the point to start the copy. ! 665: // ! 666: ! 667: if (SourceOffset) { ! 668: ! 669: if (SourceOffset > SourceCurrentLength) { ! 670: ! 671: // ! 672: // What we want isn't in this buffer. ! 673: // ! 674: ! 675: SourceOffset -= SourceCurrentLength; ! 676: SourceCurrentLength = 0; ! 677: continue; ! 678: ! 679: } else { ! 680: ! 681: SourceVirtualAddress = (PCHAR)SourceVirtualAddress ! 682: + SourceOffset; ! 683: SourceCurrentLength -= SourceOffset; ! 684: SourceOffset = 0; ! 685: ! 686: } ! 687: ! 688: } ! 689: ! 690: // ! 691: // Copy the data. ! 692: // ! 693: ! 694: { ! 695: ! 696: // ! 697: // Holds the amount of data to move. ! 698: // ! 699: UINT AmountToMove; ! 700: ! 701: // ! 702: // Holds the amount desired remaining. ! 703: // ! 704: UINT Remaining = BytesToCopy - LocalBytesCopied; ! 705: ! 706: AmountToMove = ! 707: ((SourceCurrentLength <= DestinationCurrentLength)? ! 708: (SourceCurrentLength):(DestinationCurrentLength)); ! 709: ! 710: AmountToMove = ((Remaining < AmountToMove)? ! 711: (Remaining):(AmountToMove)); ! 712: ! 713: IBMTOK_MOVE_MEMORY( ! 714: DestinationVirtualAddress, ! 715: SourceVirtualAddress, ! 716: AmountToMove ! 717: ); ! 718: ! 719: DestinationVirtualAddress = ! 720: (PCHAR)DestinationVirtualAddress + AmountToMove; ! 721: SourceVirtualAddress = ! 722: (PCHAR)SourceVirtualAddress + AmountToMove; ! 723: ! 724: LocalBytesCopied += AmountToMove; ! 725: SourceCurrentLength -= AmountToMove; ! 726: DestinationCurrentLength -= AmountToMove; ! 727: ! 728: } ! 729: ! 730: } ! 731: ! 732: *BytesCopied = LocalBytesCopied; ! 733: ! 734: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.