|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
4: All Rights Reserved
5:
6: Module Name:
7:
8: skipblk.c
9:
10: Abstract:
11:
12: Performs a forward skip of x bytes. Reverse seeks are not handled by this routine.
13:
14: Revision History:
15:
16:
17:
18:
19: --*/
20:
21: //
22: // include files
23: //
24:
25: #include <ntddk.h>
26: #include <ntddtape.h>
27: #include "common.h"
28: #include "q117.h"
29: #include "protos.h"
30:
31:
32: STATUS
33: q117SkipBlock (
34: IN OUT ULONG *HowMany,
35: IN OUT PQ117_CONTEXT Context
36: )
37:
38: /*++
39:
40: Routine Description:
41:
42: Skip forward X number of data bytes
43:
44: Arguments:
45:
46: HowMany - points to count of bytes to skip, returns with actual amount
47: skipped.
48:
49: Return Value:
50:
51: Status - NoErr, any Driver error except BadBlk, LinkRC,
52: EndOfVol, RdncUnsc.
53:
54: --*/
55:
56: {
57: STATUS ret; // Return value from other routine called.
58: SEGMENT cur_seg;
59: SEGMENT skippedSegments;
60: ULONG bytesLeft;
61:
62: if (*HowMany >= Context->CurrentOperation.BytesOnTape) {
63:
64: //
65: // Flag end of tape. This will allow for an append.
66: //
67: Context->CurrentOperation.Position = TAPE_SPACE_END_OF_DATA;
68:
69: }
70:
71: if (*HowMany > Context->CurrentOperation.BytesOnTape) {
72:
73: return(EndOfVol);
74: }
75:
76:
77: ret = NoErr;
78:
79: bytesLeft = *HowMany;
80:
81: //
82: // count number of segments to skip
83: //
84: skippedSegments = 0;
85: cur_seg = Context->CurrentOperation.LastSegmentRead;
86:
87: while (bytesLeft >= (ULONG)Context->CurrentOperation.SegmentBytesRemaining
88: && !ret) {
89:
90: bytesLeft -= Context->CurrentOperation.SegmentBytesRemaining;
91: Context->CurrentOperation.BytesOnTape -=
92: Context->CurrentOperation.SegmentBytesRemaining;
93: Context->CurrentOperation.BytesRead +=
94: Context->CurrentOperation.SegmentBytesRemaining;
95: ++skippedSegments;
96:
97: if (++cur_seg > Context->CurrentOperation.LastSegment) {
98:
99: q117ClearQueue(Context);
100: ret = EndTapeErr;
101: skippedSegments = 0;
102: cur_seg = Context->CurrentOperation.LastSegmentRead;
103:
104: } else {
105:
106: Context->CurrentOperation.SegmentBytesRemaining =
107: q117GoodDataBytes(cur_seg,Context);
108:
109: }
110: }
111:
112: if ((ULONG)skippedSegments > Context->SegmentBuffersAvailable) {
113:
114: //
115: // We skipped outside the range of buffers that we
116: // save queued up to the lower level driver, so
117: // Clear the lower level driver's requests, and
118: // start reading the segment we skipped to.
119: //
120: q117ClearQueue(Context);
121: Context->CurrentOperation.SegmentBytesRemaining = 0;
122: Context->CurrentOperation.CurrentSegment =
123: Context->CurrentOperation.LastSegmentRead + skippedSegments;
124:
125: } else {
126:
127: //
128: // The request has already been made to read the segment
129: // that we skipped to, so just de-queue all requests in
130: // front of that request and throw away the data.
131: //
132: cur_seg = Context->CurrentOperation.LastSegmentRead;
133:
134: while (skippedSegments && !ret) {
135:
136: --skippedSegments;
137:
138: if (Context->CurrentOperation.SegmentBytesRemaining =
139: q117GoodDataBytes(++cur_seg,Context)) {
140:
141: ret = q117NewTrkRC(Context);
142:
143: //
144: // Ignore Error correction failures on segments that
145: // we are skipping.
146: //
147: if (ret == RdncUnsc) {
148: ret = NoErr;
149: }
150: }
151:
152: }
153: }
154:
155: if (!ret) {
156:
157: #ifndef NO_MARKS
158: //
159: // Force the q117ReadTape code to not hit any file marks
160: //
161: Context->CurrentMark = Context->MarkArray.TotalMarks;
162: #endif
163: //
164: // Now, skip the number of bytes within the segment we skipped to
165: //
166: ret = q117ReadTape((PVOID)NULL,&bytesLeft,Context);
167:
168: if ( ret == RdncUnsc ) {
169: ret = NoErr;
170: }
171:
172: }
173:
174:
175: #ifndef NO_MARKS
176:
177: //
178: // Find our current position in the mark array.
179: //
180: Context->CurrentMark = 0;
181: while (Context->CurrentOperation.BytesRead >
182: Context->MarkArray.MarkEntry[Context->CurrentMark].Offset
183: ) {
184:
185: ++Context->CurrentMark;
186:
187: }
188: #endif
189:
190: *HowMany = 0;
191:
192: return(ret);
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.