|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 - Colorado Memory Systems, Inc. ! 4: All Rights Reserved ! 5: ! 6: Module Name: ! 7: ! 8: gttpinfo.c ! 9: ! 10: Abstract: ! 11: ! 12: Gets volume information (end of data, number of volumes, etc). ! 13: ! 14: Revision History: ! 15: ! 16: ! 17: ! 18: --*/ ! 19: ! 20: // ! 21: // include files ! 22: // ! 23: ! 24: #include <ntddk.h> ! 25: #include <ntddtape.h> ! 26: #include "common.h" ! 27: #include "q117.h" ! 28: #include "protos.h" ! 29: ! 30: ! 31: STATUS ! 32: q117ReadVolumeEntry( ! 33: PVOLUME_TABLE_ENTRY VolumeEntry, ! 34: PQ117_CONTEXT Context ! 35: ) ! 36: ! 37: /*++ ! 38: ! 39: Routine Description: ! 40: ! 41: Transfers the VolDir structure to the given location and defines ! 42: CurrentOperation.EndOfUsedTape if called for the VolDir structure that has 0 for its ! 43: startblock. ! 44: ! 45: This routine will also define 'CurrentOperation.EndOfUsedTape' provided it is called for ! 46: all the entries that are on the Tape Directory. (This is determined ! 47: when the 'startblock' field of the VolDir is 0. ! 48: ! 49: Arguments: ! 50: ! 51: TheVolumeTable - ! 52: ! 53: Context - ! 54: ! 55: Return Value: ! 56: ! 57: NoErr, any Driver error except BadBlk, RdncUnsc, ! 58: <LinkRC>, EndOfVol (if caller exceeds block of 256th VolDir entry). ! 59: ! 60: --*/ ! 61: ! 62: { ! 63: STATUS ret; ! 64: ULONG size; ! 65: ! 66: // ! 67: // Read in a volume entry ! 68: // ! 69: size = sizeof(*VolumeEntry); ! 70: ! 71: ret = q117ReadTape(VolumeEntry, &size, Context); ! 72: ! 73: if (Context->CurrentOperation.EndOfUsedTape != 0) { ! 74: ! 75: // ! 76: // This is an extraneous read by a command line. ! 77: // ! 78: ! 79: return(ret); ! 80: ! 81: } ! 82: ! 83: if (ret==RdncUnsc) { ! 84: ! 85: // ! 86: // Assume that there was a valid entry here. This assumption affects StartBack(). ! 87: // ! 88: ! 89: Context->ActiveVolumeNumber++; ! 90: ! 91: // ! 92: // Will not define the 'CurrentTape.LastUsedSegment' unless we look at a good block. ! 93: // ! 94: ! 95: Context->CurrentTape.LastUsedSegment=0; ! 96: ! 97: } else { ! 98: ! 99: if (ret==NoErr) { ! 100: ! 101: if (VolumeEntry->Signature != VolumeTableSig) { ! 102: ! 103: Context->CurrentOperation.EndOfUsedTape = Context->CurrentTape.LastUsedSegment; ! 104: ret = EndOfVol; ! 105: ! 106: } else { ! 107: ! 108: Context->CurrentTape.LastUsedSegment = VolumeEntry->EndingSegment; ! 109: Context->ActiveVolumeNumber++; ! 110: ! 111: // ! 112: // A certain vendor who shall remain anonymous, but whose ! 113: // initials are S.C.O, puts into its volume headers a starting ! 114: // and ending segment, but not a data size. If we detect this ! 115: // condition, we will attempt to fake it by adding up the ! 116: // valid sectors & and stuffing the result into DataSize. ! 117: // ! 118: ! 119: if (!VolumeEntry->DataSize) { ! 120: ! 121: q117FakeDataSize(VolumeEntry, Context); ! 122: ! 123: } ! 124: ! 125: } ! 126: ! 127: } else { ! 128: ! 129: if (ret == EndOfVol) { ! 130: ! 131: Context->CurrentOperation.EndOfUsedTape = Context->CurrentTape.LastUsedSegment; ! 132: ! 133: } ! 134: } ! 135: } ! 136: ! 137: // ! 138: // if we have read the last volume entry then set the tape statistics ! 139: // ! 140: ! 141: if (Context->CurrentOperation.EndOfUsedTape) { ! 142: ! 143: q117SetTpSt(Context); ! 144: ! 145: } ! 146: return(ret); ! 147: } ! 148: ! 149: ! 150: VOID ! 151: q117FakeDataSize( ! 152: IN OUT PVOLUME_TABLE_ENTRY TheVolumeTable, ! 153: IN PQ117_CONTEXT Context ! 154: ) ! 155: ! 156: /*++ ! 157: ! 158: Routine Description: ! 159: ! 160: This routine will fake the volume's data size by calculating the total ! 161: amount of data contained in the segments between (inclusive) the starting ! 162: and ending segments as given in the volume table entry. ! 163: It assumes that the bad sector map is accurate. ! 164: Called from q117ReadVolumeEntry() only. ! 165: ! 166: Arguments: ! 167: ! 168: TheVolumeTable - ! 169: ! 170: Context - ! 171: ! 172: Return Value: ! 173: ! 174: None ! 175: ! 176: --*/ ! 177: ! 178: { ! 179: SEGMENT segment; // Segment we are looking at ! 180: ULONG datasize = (LONG)0; // accumulator ! 181: ! 182: for(segment = TheVolumeTable->StartSegment; ! 183: segment <= TheVolumeTable->EndingSegment ; ++segment) { ! 184: ! 185: // ! 186: // count good data in each segment. ! 187: // ! 188: ! 189: datasize += (ULONG)q117GoodDataBytes(segment,Context); ! 190: ! 191: } ! 192: ! 193: // ! 194: // give back the results ! 195: // ! 196: ! 197: TheVolumeTable->DataSize = datasize; ! 198: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.