IOCTL_READ_TAPE_POSITION
This command returns Position data in either the short, long, or extended form. The type of data to return is specified by setting the data_format field to either RP_SHORT_FORM, RP_LONG_FORM, or RP_EXTENDED_FORM.
The data structures that are used with this IOCTL are
#define IOCTL_READ_TAPE_POSITION CTL_CODE(IOCTL_TAPE_BASE, 0x0829,
METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
#define RP_SHORT_FORM 0x00
#define RP_LONG_FORM 0x06
#define RP_EXTENDED_FORM 0x08
typedef struct _SHORT_DATA_FORMAT {
UCHAR bop:1, /* beginning of partition */
eop:1, /* end of partition */
locu:1, /* 1 means num_buffer_logical_obj field is unknown */
bycu:1, /* 1 means the num_buffer_bytes field is unknown */
rsvd :1,
lolu:1, /* 1 means the first and last logical obj position fields
are unknown */
perr: 1, /* 1 means the position fields have overflowed and
cannot be reported */
bpew :1; /* beyond programmable early warning */
UCHAR active_partition; /* current active partition */
UCHAR reserved[2];
UCHAR first_logical_obj_position[4]; /* current logical object position */
UCHAR last_logical_obj_position[4]; /* next logical object to be
transferred to tape */
UCHAR num_buffer_logical_obj[4]; /* number of logical objects in buffer */
UCHAR num_buffer_bytes[4]; /* number of bytes in buffer */
UCHAR reserved1; /* instead of the commented reserved1 */
} SHORT_DATA_FORMAT, *PSHORT_DATA_FORMAT;
typedef struct _LONG_DATA_FORMAT {
UCHAR bop:1, /* beginning of partition */
eop:1, /* end of partition */
rsvd1:2,
mpu:1, /* 1 means the logical file id field in unknown */
lonu:1,/* 1 means either the partition number or logical obj number field
are unknown */
rsvd2:1,
bpew :1;/* beyond programmable early warning */
CHAR reserved[6];
UCHAR active_partition; /* current active partition */
UCHAR logical_obj_number[8];/* current logical object position */
UCHAR logical_file_id[8]; /* number of filemarks from bop and
current logical position */
UCHAR obsolete[8];
}LONG_DATA_FORMAT, *PLONG_DATA_FORMAT;
typedef struct _EXTENDED_DATA_FORMAT {
UCHAR bop:1, /* beginning of partition */
eop:1, /* end of partition */
locu:1, /* 1 means num_buffer_logical_obj field is unknown */
bycu:1, /* 1 means the num_buffer_bytes field is unknown */
rsvd :1,
lolu:1, /* 1 means the first and last logical obj position fields
are unknown */
perr: 1,/* 1 means the position fields have overflowed and
can not be reported */
bpew :1;/* beyond programmable early warning */
UCHAR active_partition; /* current active partition */
UCHAR additional_length[2];
UCHAR num_buffer_logical_obj[4]; /* number of logical objects in buffer */
UCHAR first_logical_obj_position[8];/* current logical object position */
UCHAR last_logical_obj_position[8]; /* next logical object to be
transferred to tape */
UCHAR num_buffer_bytes[8]; /* number of bytes in buffer */
UCHAR reserved;
} EXTENDED_DATA_FORMAT, *PEXTENDED_DATA_FORMAT;
typedef struct READ_TAPE_POSITION{
UCHAR data_format; /* Specifies the return data format either
short, long or extended*/
union
{
SHORT_DATA_FORMAT rp_short;
LONG_DATA_FORMAT rp_long;
EXTENDED_DATA_FORMAT rp_extended;
UCHAR reserved[64];
} rp_data;
} READ_TAPE_POSITION, *PREAD_TAPE_POSITION;
An example of the READ_TAPE_POSITION command
is
DWORD cb;
READ_TAPE_POSITION tapePosition;
*rc_ptr = DeviceIoControl(gp->ddHandle0,
IOCTL_READ_TAPE_POSITION,
&tapePosition,
(long)sizeof(READ_TAPE_POSITION),
&tapePosition,
(long)sizeof(READ_TAPE_POSITION),
&cb,
(LPOVERLAPPED) NULL);