NT4/private/ntos/dd/qic117/gttpinfo.c
2020-09-30 17:12:29 +02:00

198 lines
3.9 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1993 - Colorado Memory Systems, Inc.
All Rights Reserved
Module Name:
gttpinfo.c
Abstract:
Gets volume information (end of data, number of volumes, etc).
Revision History:
--*/
//
// include files
//
#include <ntddk.h>
#include <ntddtape.h>
#include "common.h"
#include "q117.h"
#include "protos.h"
#define FCT_ID 0x010a
dStatus
q117ReadVolumeEntry(
PVOLUME_TABLE_ENTRY VolumeEntry,
PQ117_CONTEXT Context
)
/*++
Routine Description:
Transfers the VolDir structure to the given location and defines
CurrentOperation.EndOfUsedTape if called for the VolDir structure that has 0 for its
startblock.
This routine will also define 'CurrentOperation.EndOfUsedTape' provided it is called for
all the entries that are on the Tape Directory. (This is determined
when the 'startblock' field of the VolDir is 0.
Arguments:
TheVolumeTable -
Context -
Return Value:
--*/
{
dStatus ret;
ULONG size;
//
// Read in a volume entry
//
size = sizeof(*VolumeEntry);
ret = q117ReadTape(VolumeEntry, &size, Context);
if (Context->CurrentOperation.EndOfUsedTape != 0) {
//
// This is an extraneous read by a command line.
//
return(ret);
}
if (ERROR_DECODE(ret)==ERR_ECC_FAILED) {
//
// Assume that there was a valid entry here. This assumption affects StartBack().
//
Context->ActiveVolumeNumber++;
//
// Will not define the 'CurrentTape.LastUsedSegment' unless we look at a good block.
//
Context->CurrentTape.LastUsedSegment=0;
} else {
if (ret==ERR_NO_ERR) {
if (VolumeEntry->Signature != VolumeTableSig) {
Context->CurrentOperation.EndOfUsedTape = Context->CurrentTape.LastUsedSegment;
ret = ERROR_ENCODE(ERR_END_OF_VOLUME, FCT_ID, 1);
} else {
Context->CurrentTape.LastUsedSegment = VolumeEntry->EndingSegment;
Context->ActiveVolumeNumber++;
//
// A certain vendor who shall remain anonymous, but whose
// initials are S.C.O, puts into its volume headers a starting
// and ending segment, but not a data size. If we detect this
// condition, we will attempt to fake it by adding up the
// valid sectors & and stuffing the result into DataSize.
//
if (!VolumeEntry->DataSize) {
q117FakeDataSize(VolumeEntry, Context);
}
}
} else {
if (ERROR_DECODE(ret) == ERR_END_OF_VOLUME) {
Context->CurrentOperation.EndOfUsedTape = Context->CurrentTape.LastUsedSegment;
}
}
}
//
// if we have read the last volume entry then set the tape statistics
//
if (Context->CurrentOperation.EndOfUsedTape) {
q117SetTpSt(Context);
}
return(ret);
}
VOID
q117FakeDataSize(
IN OUT PVOLUME_TABLE_ENTRY TheVolumeTable,
IN PQ117_CONTEXT Context
)
/*++
Routine Description:
This routine will fake the volume's data size by calculating the total
amount of data contained in the segments between (inclusive) the starting
and ending segments as given in the volume table entry.
It assumes that the bad sector map is accurate.
Called from q117ReadVolumeEntry() only.
Arguments:
TheVolumeTable -
Context -
Return Value:
None
--*/
{
SEGMENT segment; // Segment we are looking at
ULONG datasize = (LONG)0; // accumulator
for(segment = TheVolumeTable->StartSegment;
segment <= TheVolumeTable->EndingSegment ; ++segment) {
//
// count good data in each segment.
//
datasize += (ULONG)q117GoodDataBytes(segment,Context);
}
//
// give back the results
//
TheVolumeTable->DataSize = datasize;
}