|
|
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 kernal mode, but is not important that it does. ! 21: ! 22: Revision History: ! 23: ! 24: ! 25: --*/ ! 26: ! 27: #include <ndis.h> ! 28: #include <efilter.h> ! 29: #include <lancehrd.h> ! 30: #include <lancesft.h> ! 31: ! 32: ! 33: extern ! 34: VOID ! 35: LanceCopyFromPacketToBuffer( ! 36: IN PNDIS_PACKET Packet, ! 37: IN UINT Offset, ! 38: IN UINT BytesToCopy, ! 39: OUT PCHAR Buffer, ! 40: OUT PUINT BytesCopied ! 41: ) ! 42: ! 43: /*++ ! 44: ! 45: Routine Description: ! 46: ! 47: Copy from an ndis packet into a buffer. ! 48: ! 49: Arguments: ! 50: ! 51: Packet - The packet to copy from. ! 52: ! 53: Offset - The offset from which to start the copy. ! 54: ! 55: BytesToCopy - The number of bytes to copy from the packet. ! 56: ! 57: Buffer - The destination of the copy. ! 58: ! 59: BytesCopied - The number of bytes actually copied. Can be less then ! 60: BytesToCopy if the packet is shorter than BytesToCopy. ! 61: ! 62: Return Value: ! 63: ! 64: None ! 65: ! 66: --*/ ! 67: ! 68: { ! 69: ! 70: // ! 71: // Holds the number of ndis buffers comprising the packet. ! 72: // ! 73: UINT NdisBufferCount; ! 74: ! 75: // ! 76: // Points to the buffer from which we are extracting data. ! 77: // ! 78: PNDIS_BUFFER CurrentBuffer; ! 79: ! 80: // ! 81: // Holds the virtual address of the current buffer. ! 82: // ! 83: PVOID VirtualAddress; ! 84: ! 85: // ! 86: // Holds the length of the current buffer of the packet. ! 87: // ! 88: UINT CurrentLength; ! 89: ! 90: // ! 91: // Keep a local variable of BytesCopied so we aren't referencing ! 92: // through a pointer. ! 93: // ! 94: UINT LocalBytesCopied = 0; ! 95: ! 96: // ! 97: // Take care of boundary condition of zero length copy. ! 98: // ! 99: ! 100: *BytesCopied = 0; ! 101: if (!BytesToCopy) return; ! 102: ! 103: // ! 104: // Get the first buffer. ! 105: // ! 106: ! 107: NdisQueryPacket( ! 108: Packet, ! 109: NULL, ! 110: &NdisBufferCount, ! 111: &CurrentBuffer, ! 112: NULL ! 113: ); ! 114: ! 115: // ! 116: // Could have a null packet. ! 117: // ! 118: ! 119: if (!NdisBufferCount) return; ! 120: ! 121: NdisQueryBuffer( ! 122: CurrentBuffer, ! 123: &VirtualAddress, ! 124: &CurrentLength ! 125: ); ! 126: ! 127: while (LocalBytesCopied < BytesToCopy) { ! 128: ! 129: if (!CurrentLength) { ! 130: ! 131: NdisGetNextBuffer( ! 132: CurrentBuffer, ! 133: &CurrentBuffer ! 134: ); ! 135: ! 136: // ! 137: // We've reached the end of the packet. We return ! 138: // with what we've done so far. (Which must be shorter ! 139: // than requested. ! 140: // ! 141: ! 142: if (!CurrentBuffer) break; ! 143: ! 144: NdisQueryBuffer( ! 145: CurrentBuffer, ! 146: &VirtualAddress, ! 147: &CurrentLength ! 148: ); ! 149: continue; ! 150: ! 151: } ! 152: ! 153: // ! 154: // Try to get us up to the point to start the copy. ! 155: // ! 156: ! 157: if (Offset) { ! 158: ! 159: if (Offset > CurrentLength) { ! 160: ! 161: // ! 162: // What we want isn't in this buffer. ! 163: // ! 164: ! 165: Offset -= CurrentLength; ! 166: CurrentLength = 0; ! 167: continue; ! 168: ! 169: } else { ! 170: ! 171: VirtualAddress = (PCHAR)VirtualAddress + Offset; ! 172: CurrentLength -= Offset; ! 173: Offset = 0; ! 174: ! 175: } ! 176: ! 177: } ! 178: ! 179: // ! 180: // Copy the data. ! 181: // ! 182: ! 183: ! 184: { ! 185: ! 186: // ! 187: // Holds the amount of data to move. ! 188: // ! 189: UINT AmountToMove; ! 190: ! 191: AmountToMove = ! 192: ((CurrentLength <= (BytesToCopy - LocalBytesCopied))? ! 193: (CurrentLength):(BytesToCopy - LocalBytesCopied)); ! 194: ! 195: LANCE_MOVE_MEMORY( ! 196: Buffer, ! 197: VirtualAddress, ! 198: AmountToMove ! 199: ); ! 200: ! 201: Buffer = (PCHAR)Buffer + AmountToMove; ! 202: VirtualAddress = (PCHAR)VirtualAddress + AmountToMove; ! 203: ! 204: LocalBytesCopied += AmountToMove; ! 205: CurrentLength -= AmountToMove; ! 206: ! 207: } ! 208: ! 209: } ! 210: ! 211: *BytesCopied = LocalBytesCopied; ! 212: ! 213: } ! 214: ! 215: extern ! 216: VOID ! 217: LanceCopyFromPacketToPacket( ! 218: IN PNDIS_PACKET Destination, ! 219: IN UINT DestinationOffset, ! 220: IN UINT BytesToCopy, ! 221: IN PNDIS_PACKET Source, ! 222: IN UINT SourceOffset, ! 223: OUT PUINT BytesCopied ! 224: ) ! 225: ! 226: /*++ ! 227: ! 228: Routine Description: ! 229: ! 230: Copy from an ndis packet to an ndis packet. ! 231: ! 232: Arguments: ! 233: ! 234: Destination - The packet should be copied in to. ! 235: ! 236: DestinationOffset - The offset from the beginning of the packet ! 237: into which the data should start being placed. ! 238: ! 239: BytesToCopy - The number of bytes to copy from the source packet. ! 240: ! 241: Source - The ndis packet from which to copy data. ! 242: ! 243: SourceOffset - The offset from the start of the packet from which ! 244: to start copying data. ! 245: ! 246: BytesCopied - The number of bytes actually copied from the source ! 247: packet. This can be less than BytesToCopy if the source or destination ! 248: packet is too short. ! 249: ! 250: Return Value: ! 251: ! 252: None ! 253: ! 254: --*/ ! 255: ! 256: { ! 257: ! 258: // ! 259: // Holds the count of the number of ndis buffers comprising the ! 260: // destination packet. ! 261: // ! 262: UINT DestinationBufferCount; ! 263: ! 264: // ! 265: // Holds the count of the number of ndis buffers comprising the ! 266: // source packet. ! 267: // ! 268: UINT SourceBufferCount; ! 269: ! 270: // ! 271: // Points to the buffer into which we are putting data. ! 272: // ! 273: PNDIS_BUFFER DestinationCurrentBuffer; ! 274: ! 275: // ! 276: // Points to the buffer from which we are extracting data. ! 277: // ! 278: PNDIS_BUFFER SourceCurrentBuffer; ! 279: ! 280: // ! 281: // Holds the virtual address of the current destination buffer. ! 282: // ! 283: PVOID DestinationVirtualAddress; ! 284: ! 285: // ! 286: // Holds the virtual address of the current source buffer. ! 287: // ! 288: PVOID SourceVirtualAddress; ! 289: ! 290: // ! 291: // Holds the length of the current destination buffer. ! 292: // ! 293: UINT DestinationCurrentLength; ! 294: ! 295: // ! 296: // Holds the length of the current source buffer. ! 297: // ! 298: UINT SourceCurrentLength; ! 299: ! 300: // ! 301: // Keep a local variable of BytesCopied so we aren't referencing ! 302: // through a pointer. ! 303: // ! 304: UINT LocalBytesCopied = 0; ! 305: ! 306: // ! 307: // Take care of boundary condition of zero length copy. ! 308: // ! 309: ! 310: *BytesCopied = 0; ! 311: if (!BytesToCopy) return; ! 312: ! 313: // ! 314: // Get the first buffer of the destination. ! 315: // ! 316: ! 317: NdisQueryPacket( ! 318: Destination, ! 319: NULL, ! 320: &DestinationBufferCount, ! 321: &DestinationCurrentBuffer, ! 322: NULL ! 323: ); ! 324: ! 325: // ! 326: // Could have a null packet. ! 327: // ! 328: ! 329: if (!DestinationBufferCount) return; ! 330: ! 331: NdisQueryBuffer( ! 332: DestinationCurrentBuffer, ! 333: &DestinationVirtualAddress, ! 334: &DestinationCurrentLength ! 335: ); ! 336: ! 337: // ! 338: // Get the first buffer of the source. ! 339: // ! 340: ! 341: NdisQueryPacket( ! 342: Source, ! 343: NULL, ! 344: &SourceBufferCount, ! 345: &SourceCurrentBuffer, ! 346: NULL ! 347: ); ! 348: ! 349: // ! 350: // Could have a null packet. ! 351: // ! 352: ! 353: if (!SourceBufferCount) return; ! 354: ! 355: NdisQueryBuffer( ! 356: SourceCurrentBuffer, ! 357: &SourceVirtualAddress, ! 358: &SourceCurrentLength ! 359: ); ! 360: ! 361: while (LocalBytesCopied < BytesToCopy) { ! 362: ! 363: // ! 364: // Check to see whether we've exhausted the current destination ! 365: // buffer. If so, move onto the next one. ! 366: // ! 367: ! 368: if (!DestinationCurrentLength) { ! 369: ! 370: NdisGetNextBuffer( ! 371: DestinationCurrentBuffer, ! 372: &DestinationCurrentBuffer ! 373: ); ! 374: ! 375: if (!DestinationCurrentBuffer) { ! 376: ! 377: // ! 378: // We've reached the end of the packet. We return ! 379: // with what we've done so far. (Which must be shorter ! 380: // than requested.) ! 381: // ! 382: ! 383: break; ! 384: ! 385: } ! 386: ! 387: NdisQueryBuffer( ! 388: DestinationCurrentBuffer, ! 389: &DestinationVirtualAddress, ! 390: &DestinationCurrentLength ! 391: ); ! 392: continue; ! 393: ! 394: } ! 395: ! 396: ! 397: // ! 398: // Check to see whether we've exhausted the current source ! 399: // buffer. If so, move onto the next one. ! 400: // ! 401: ! 402: if (!SourceCurrentLength) { ! 403: ! 404: NdisGetNextBuffer( ! 405: SourceCurrentBuffer, ! 406: &SourceCurrentBuffer ! 407: ); ! 408: ! 409: if (!SourceCurrentBuffer) { ! 410: ! 411: // ! 412: // We've reached the end of the packet. We return ! 413: // with what we've done so far. (Which must be shorter ! 414: // than requested.) ! 415: // ! 416: ! 417: break; ! 418: ! 419: } ! 420: ! 421: NdisQueryBuffer( ! 422: SourceCurrentBuffer, ! 423: &SourceVirtualAddress, ! 424: &SourceCurrentLength ! 425: ); ! 426: continue; ! 427: ! 428: } ! 429: ! 430: // ! 431: // Try to get us up to the point to start the copy. ! 432: // ! 433: ! 434: if (DestinationOffset) { ! 435: ! 436: if (DestinationOffset > DestinationCurrentLength) { ! 437: ! 438: // ! 439: // What we want isn't in this buffer. ! 440: // ! 441: ! 442: DestinationOffset -= DestinationCurrentLength; ! 443: DestinationCurrentLength = 0; ! 444: continue; ! 445: ! 446: } else { ! 447: ! 448: DestinationVirtualAddress = (PCHAR)DestinationVirtualAddress ! 449: + DestinationOffset; ! 450: DestinationCurrentLength -= DestinationOffset; ! 451: DestinationOffset = 0; ! 452: ! 453: } ! 454: ! 455: } ! 456: ! 457: // ! 458: // Try to get us up to the point to start the copy. ! 459: // ! 460: ! 461: if (SourceOffset) { ! 462: ! 463: if (SourceOffset > SourceCurrentLength) { ! 464: ! 465: // ! 466: // What we want isn't in this buffer. ! 467: // ! 468: ! 469: SourceOffset -= SourceCurrentLength; ! 470: SourceCurrentLength = 0; ! 471: continue; ! 472: ! 473: } else { ! 474: ! 475: SourceVirtualAddress = (PCHAR)SourceVirtualAddress ! 476: + SourceOffset; ! 477: SourceCurrentLength -= SourceOffset; ! 478: SourceOffset = 0; ! 479: ! 480: } ! 481: ! 482: } ! 483: ! 484: // ! 485: // Copy the data. ! 486: // ! 487: ! 488: { ! 489: ! 490: // ! 491: // Holds the amount of data to move. ! 492: // ! 493: UINT AmountToMove; ! 494: ! 495: // ! 496: // Holds the amount desired remaining. ! 497: // ! 498: UINT Remaining = BytesToCopy - LocalBytesCopied; ! 499: ! 500: AmountToMove = ! 501: ((SourceCurrentLength <= DestinationCurrentLength)? ! 502: (SourceCurrentLength):(DestinationCurrentLength)); ! 503: ! 504: AmountToMove = ((Remaining < AmountToMove)? ! 505: (Remaining):(AmountToMove)); ! 506: ! 507: LANCE_MOVE_MEMORY( ! 508: DestinationVirtualAddress, ! 509: SourceVirtualAddress, ! 510: AmountToMove ! 511: ); ! 512: ! 513: DestinationVirtualAddress = ! 514: (PCHAR)DestinationVirtualAddress + AmountToMove; ! 515: SourceVirtualAddress = ! 516: (PCHAR)SourceVirtualAddress + AmountToMove; ! 517: ! 518: LocalBytesCopied += AmountToMove; ! 519: SourceCurrentLength -= AmountToMove; ! 520: DestinationCurrentLength -= AmountToMove; ! 521: ! 522: } ! 523: ! 524: } ! 525: ! 526: *BytesCopied = LocalBytesCopied; ! 527: ! 528: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.