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);