MORE INFORMATION
To determine if a tape drive can support variable block size, the
GetTapeParameters function must be called. Specifying the
GET_TAPE_DRIVE_INFORMATION operation will yield a TAPE_GET_DRIVE_PARAMETERS
structure. The dwFeaturesLow member of this structure is a flag that will
have the TAPE_DRIVE_VARIABLE_BLOCK bit set if the drive can support
variable block size. The following sample code shows how to use the
function:
BOOL DriveSupportsVariableBlockSize()
{
TAPE_GET_DRIVE_PARAMETERS DriveParms;
DWORD dwBufferSize;
DWORD dwErrorCode;
dwBufferSize = sizeof(DriveParms);
dwErrorCode = GetTapeParameters( ghTape,
GET_TAPE_DRIVE_INFORMATION,
&dwBufferSize,
&DriveParms );
if (dwErrorCode != NO_ERROR) {
// An error occurred calling the function.
// The error should be handled by some error handling function.
return FALSE;
}
if (DriveParms.dwFeaturesLow & TAPE_DRIVE_VARIABLE_BLOCK)
return TRUE;
else
return FALSE;
}
If the drive reports that it is not capable of supporting variable block
size, then variable block size cannot be used. Tapes that use variable
block size will not be usable with the tape drive.
If, on the other hand, the tape drive indicates that it is capable of
supporting variable block size, then the next step is to set the tape media
parameters to variable block size. The SetTapeParameters function must be
called specifying the SET_TAPE_MEDIA_INFORMATION operation. The function
requires the use of a TAPE_SET_MEDIA_PARAMETERS structure. The BlockSize
member of the structure must be set to the desired block size. A block size
of 0 indicates variable block size. Any other value sets the media
parameters to fixed block size. The following sample code demonstrates how
to use the function:
BOOL SetTapeBlockSize(DWORD dwNewBlockSize)
{
TAPE_SET_MEDIA_PARAMETERS MediaParms;
DWORD dwErrorCode;
MediaParms.BlockSize = dwNewBlockSize;
dwErrorCode = SetTapeParameters( ghTape,
SET_TAPE_MEDIA_INFORMATION,
&MediaParms );
if (dwErrorCode != NO_ERROR) {
// An error occurred calling the function.
// The error should be handled by some error handling function.
return FALSE;
}
return TRUE;
}
When writing to a tape using variable block size, each write operation
creates a new data block on the tape. The size of the block is the size of
the write operation. There is an exception to this when a single write may
create more than one block. For additional information on this exception,
please see the following article in the Microsoft Knowledge Base:
152518
PRB: Tape Variable Blocksize Limited to 64K Bytes
Reading a tape containing variable sized blocks can be accomplished even
without knowing what size the blocks are. If a buffer is large enough to
read the data in a block, then the data will be read without any errors. If
the buffer is larger than a block, then only data in a single block will be
read and the tape will be advanced to the next block. The size of the block
is returned by the read operation in the &dwBytesRead parameter.
If, on the other hand, a data buffer is too small to contain all of the
data in a block, then a couple of things occur. First, the data buffer will
contain data from the tape, but the read operation will fail and
GetLastError will return ERROR_MORE_DATA. This error value indicates that
there is more data in the block to be read. Second, the tape is advanced to
the next block. To re-read the previous block, the tape must be
repositioned to the desired block and a larger buffer must be specified. It
is best to specify as large a buffer as possible so that this does not
occur.
If a tape has fixed size blocks, but the tape media parameters are set to
variable block size, then no assumptions are made regarding the size of the
blocks on the tape. Each read operation behaves as described above. The
size of the blocks on the tape are treated as variable, but happen to be
the same size.
If a tape has variable size blocks, but the tape media parameters are set
to fixed block size, then the size of all blocks on the tape are expected
to be the same fixed size. Reading a block of a tape in this situation will
fail and GetLastError will return ERROR_INVALID_BLOCK_LENGTH. The only
exception to this is if the block size in the media parameters is the same
as the size of the variable block and the size of the read buffer happens
to be a multiple of the size of the variable block.