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