|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
4: All Rights Reserved
5:
6: Module Name:
7:
8: readtape.c
9:
10: Abstract:
11:
12: Reads data as a byte stream from the selected volume.
13:
14: Revision History:
15:
16:
17:
18:
19: --*/
20:
21: //
22: // Includes
23: //
24:
25: #include <ntddk.h>
26: #include <ntddtape.h> // tape device driver I/O control codes
27: #include "common.h"
28: #include "q117.h"
29: #include "protos.h"
30:
31:
32: STATUS
33: q117ReadTape (
34: OUT PVOID ToWhere,
35: IN OUT ULONG *HowMany,
36: IN OUT PQ117_CONTEXT Context
37: )
38:
39: /*++
40:
41: Routine Description:
42:
43: Coeleates data from multiple segment buffers to reconstruct
44: the original data stream.
45:
46: Arguments:
47:
48:
49: Return Value:
50:
51: NoErr, any driver error except BadBlk, LinkRC, RdncUnsc.
52:
53: --*/
54:
55: {
56: USHORT left;
57: UCHAR *ptr;
58: STATUS ret,readret;
59: ULONG leftToRead;
60: ULONG bytesToRead;
61: #ifndef NO_MARKS
62: ULONG leftTillMark;
63: ULONG bytesToSkip;
64: #endif
65:
66:
67: bytesToRead = *HowMany;
68: *HowMany = 0;
69:
70: readret = Context->CurrentOperation.SegmentStatus;
71:
72: #ifndef NO_MARKS
73:
74: leftTillMark = Context->MarkArray.MarkEntry[Context->CurrentMark].Offset -
75: Context->CurrentOperation.BytesRead;
76:
77: bytesToSkip = 0;
78:
79: if (bytesToRead > leftTillMark) {
80:
81: bytesToRead = leftTillMark;
82:
83: switch(Context->MarkArray.MarkEntry[Context->CurrentMark].Type) {
84:
85: case TAPE_SETMARKS:
86: readret = SetMark;
87: break;
88:
89: case TAPE_FILEMARKS:
90: readret = FileMark;
91: break;
92:
93: case TAPE_SHORT_FILEMARKS:
94: readret = ShortFileMark;
95: break;
96:
97: case TAPE_LONG_FILEMARKS:
98: readret = LongFileMark;
99: break;
100:
101: default:
102: return FCodeErr;
103:
104: }
105: bytesToSkip = BLOCK_SIZE;
106: ++Context->CurrentMark;
107: }
108:
109: #endif
110:
111: if (bytesToRead > Context->CurrentOperation.BytesOnTape) {
112:
113: bytesToRead = Context->CurrentOperation.BytesOnTape;
114:
115: readret = EndOfVol;
116: }
117:
118: if (bytesToRead == Context->CurrentOperation.BytesOnTape) {
119:
120: //
121: // Flag end of tape. This will allow for an append
122: //
123: Context->CurrentOperation.Position = TAPE_SPACE_END_OF_DATA;
124: }
125:
126: leftToRead = bytesToRead;
127:
128: #ifndef NO_MARKS
129: while (leftToRead+bytesToSkip > 0) {
130: #else
131: while (leftToRead > 0) {
132: #endif
133:
134: if (Context->CurrentOperation.SegmentBytesRemaining == 0) {
135: //
136: // get CurrentOperation.SegmentPointer and CurrentOperation.SegmentBytesRemaining for new segment
137: //
138: if (ret = q117NewTrkRC(Context)) {
139: //
140: // return error (unless error correction failed)
141: //
142: if (ret != RdncUnsc) {
143: return(ret);
144: }
145: }
146: //
147: // set return value for all accesses to this segment
148: // if no error then set to error return by newtrkrc
149: //
150: if (readret == NoErr) {
151: readret = ret;
152: }
153: }
154:
155: ptr = Context->CurrentOperation.SegmentPointer;
156: left = Context->CurrentOperation.SegmentBytesRemaining;
157:
158: #ifndef NO_MARKS
159: //
160: // set up to skip the file mark
161: //
162: if ( leftToRead == 0 ) {
163: leftToRead = bytesToSkip;
164: ToWhere = 0;
165: bytesToSkip = 0;
166: }
167: #endif
168:
169: if ( leftToRead > (ULONG)left ) {
170:
171: if (ToWhere) {
172:
173: RtlMoveMemory(ToWhere,ptr,left);
174: (PUCHAR)ToWhere += left;
175:
176: }
177:
178: leftToRead -= left;
179: Context->CurrentOperation.BytesOnTape -= left;
180: Context->CurrentOperation.BytesRead += left;
181: left = 0;
182:
183: } else {
184:
185: if (ToWhere) {
186:
187: RtlMoveMemory(ToWhere,ptr,leftToRead);
188:
189: }
190:
191: left -= (USHORT)leftToRead;
192: ptr += leftToRead;
193: Context->CurrentOperation.BytesOnTape -= leftToRead;
194: Context->CurrentOperation.BytesRead += leftToRead;
195: leftToRead = 0;
196:
197: }
198:
199: Context->CurrentOperation.SegmentPointer = ptr;
200: Context->CurrentOperation.SegmentBytesRemaining = left;
201:
202: }
203:
204: //
205: // Return number of bytes read
206:
207: *HowMany = bytesToRead-leftToRead;
208:
209: return readret;
210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.