|
|
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.