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