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