Logo Search packages:      
Sourcecode: qpxtool version File versions  Download package

qpx_transport.h

//
// This is part of dvd+rw-tools by Andy Polyakov <appro@fy.chalmers.se>
//
// Use-it-on-your-own-risk, GPL bless...
//
// For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/
//

//
// edited by ShultZ to use with QPxTool  http://qpxtool.sf.net
//


#include <string.h>

#ifndef __qpx_transport_h
#define __qpx_transport_h

#if defined(__unix) || defined(__unix__)
extern long getmsecs();
#include <errno.h>
#ifndef EMEDIUMTYPE
#define EMEDIUMTYPE     EINVAL
#endif
#ifndef     ENOMEDIUM
#define     ENOMEDIUM   ENODEV
#endif

//*
#elif defined(_WIN32)

#include <windows.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define ssize_t         LONG_PTR
#define off64_t         __int64

#include "win32err.h"

#define poll(a,b,t)     Sleep(t)
#define getmsecs()      GetTickCount()

#include <locale.h>
#define ENV_LOCALE      ".OCP"
//*/
#endif

#define CREAM_ON_ERRNO_NAKED(s)                       \
    switch ((s)[12])                            \
    { case 0x04:  errno=EAGAIN;     break;            \
      case 0x20:  errno=ENODEV;     break;            \
      case 0x21:  if ((s)[13]==0)   errno=ENOSPC;     \
                  else        errno=EINVAL;     \
                  break;                        \
      case 0x30:  errno=EMEDIUMTYPE;      break;      \
      case 0x3A:  errno=ENOMEDIUM;  break;      \
    }
#define CREAM_ON_ERRNO(s)     do { CREAM_ON_ERRNO_NAKED(s) } while(0)

#define     FATAL_START(er)   (0x80|(er))
#define ERRCODE(s)      ((((s)[2]&0x0F)<<16)|((s)[12]<<8)|((s)[13]))
#define     SK(errcode) (((errcode)>>16)&0xF)
#define     ASC(errcode)      (((errcode)>>8)&0xFF)
#define ASCQ(errcode)   ((errcode)&0xFF)

extern void sperror (const char *cmd, int err); //,  Scsi_Command *scsi);

class autofree {
    private:
      unsigned char *ptr;
    public:
      autofree();
      ~autofree();
      unsigned char *operator=(unsigned char *str) { return ptr=str; }
      operator unsigned char *()          { return ptr; }
};

#if defined(__linux)

//#include <sys/ioctl.h>
#include <linux/cdrom.h>
//#include <mntent.h>
//#include <sys/wait.h>
//#include <sys/utsname.h>
#include <scsi/sg.h>
#if !defined(SG_FLAG_LUN_INHIBIT)
# if defined(SG_FLAG_UNUSED_LUN_INHIBIT)
#  define SG_FLAG_LUN_INHIBIT SG_FLAG_UNUSED_LUN_INHIBIT
# else
#  define SG_FLAG_LUN_INHIBIT 0
# endif
#endif
#ifndef CHECK_CONDITION
#define CHECK_CONDITION 0x01
#endif

typedef enum {    NONE=CGC_DATA_NONE,     // 3
            READ=CGC_DATA_READ,     // 2
            WRITE=CGC_DATA_WRITE    // 1
           } Direction;
#ifdef SG_IO

static const int Dir_xlate [4] = {  // should have been defined
                              // private in USE_SG_IO scope,
                              // but it appears to be too
            0,                // implementation-dependent...
            SG_DXFER_TO_DEV,  // 1,CGC_DATA_WRITE
            SG_DXFER_FROM_DEV,      // 2,CGC_DATA_READ
            SG_DXFER_NONE     };    // 3,CGC_DATA_NONE

class USE_SG_IO {
private:
    int     yes_or_no;
public:
    USE_SG_IO();
    ~USE_SG_IO();
    operator int()                  const { return yes_or_no; }
    int operator[] (Direction dir)  const { return Dir_xlate[dir]; }
};
#endif

static const class USE_SG_IO use_sg_io;

class Scsi_Command {
private:
//    long cmd_time;
    int fd,autoclose;
    char *filename;
    struct cdrom_generic_command cgc;
    union sense_union{
      struct request_sense    s;
      unsigned char           u[18];
    } _sense;
#ifdef SG_IO
    struct sg_io_hdr          sg_io;
#else
    struct { int cmd_len,timeout; } sg_io;
#endif
public:
    Scsi_Command();
    Scsi_Command(int f);
    Scsi_Command(void*f);
    ~Scsi_Command();
    int associate (const char *file,const struct stat *ref);
    unsigned char &operator[] (size_t i)
    { if (i==0)
      {   memset(&cgc,0,sizeof(cgc)), memset(&_sense,0,sizeof(_sense));
          cgc.quiet = 1;
          cgc.sense = &_sense.s;
#ifdef SG_IO
          if (use_sg_io)
          { memset(&sg_io,0,sizeof(sg_io));
            sg_io.interface_id= 'S';
            sg_io.mx_sb_len   = sizeof(_sense);
            sg_io.cmdp  = cgc.cmd;
            sg_io.sbp   = _sense.u;
            sg_io.flags = SG_FLAG_LUN_INHIBIT|SG_FLAG_DIRECT_IO;
          }
#endif
      }
      sg_io.cmd_len = i+1;
      return cgc.cmd[i];
    }
    unsigned char &operator()(size_t i)   { return _sense.u[i]; }
//    unsigned char *sense();
    unsigned char *sense()    { return _sense.u;    }
    void timeout(int i);
    size_t residue();
    int transport(Direction dir,void *buf,size_t sz);
    int umount(int f);
    int is_reload_needed ();
};

#elif defined(__OpenBSD__) || defined(__NetBSD__)

#include <sys/ioctl.h>
#include <sys/scsiio.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/mount.h>

typedef off_t off64_t;
#define stat64   stat
#define fstat64  fstat
#define open64   open
#define pread64    pread
#define pwrite64 pwrite
#define lseek64  lseek

typedef enum {    NONE=0,
            READ=SCCMD_READ,
            WRITE=SCCMD_WRITE
           } Direction;

class Scsi_Command {
private:
    int fd,autoclose;
    char *filename;
    scsireq_t req;
public:
    Scsi_Command();
    Scsi_Command(int f);
    Scsi_Command(void*f);
    ~Scsi_Command();
    int associate (const char *file,const struct stat *ref);
    unsigned char &operator[] (size_t i)
    { if (i==0)
      {   memset(&req,0,sizeof(req));
          req.flags = SCCMD_ESCAPE;
          req.timeout = 30000;
          req.senselen = 18; //sizeof(req.sense);
      }
      req.cmdlen = i+1;
      return req.cmd[i];
    }
    unsigned char &operator()(size_t i)   { return req.sense[i]; }
    unsigned char *sense()          { return req.sense;    }
    void timeout(int i);
    size_t residue();
    int transport(Direction dir,void *buf,size_t sz);
    int umount(int f);
    int is_reload_needed ();
};

#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)

#include <sys/ioctl.h>
#include <stdio.h>
#include <camlib.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <dirent.h>

typedef off_t off64_t;
#define stat64   stat
#define fstat64  fstat
#define open64   open
#define pread64  pread
#define pwrite64 pwrite
#define lseek64  lseek

#define ioctl_fd (((struct cam_device *)ioctl_handle)->fd)

typedef enum {    NONE=CAM_DIR_NONE,
            READ=CAM_DIR_IN,
            WRITE=CAM_DIR_OUT
           } Direction;

class Scsi_Command {
private:
    int fd,autoclose;
    char *filename;
    struct cam_device  *cam;
    union ccb           ccb;
public:
    Scsi_Command();
    Scsi_Command(int f);
    Scsi_Command(void *f);
    ~Scsi_Command();

    int associate (const char *file,const struct stat *ref);
    unsigned char &operator[] (size_t i)
    { if (i==0)
      {   memset(&ccb,0,sizeof(ccb));
          ccb.ccb_h.path_id    = cam->path_id;
          ccb.ccb_h.target_id  = cam->target_id;
          ccb.ccb_h.target_lun = cam->target_lun;
          cam_fill_csio (&(ccb.csio),
                  1,                      // retries
                  NULL,                   // cbfncp
                  CAM_DEV_QFRZDIS,        // flags
                  MSG_SIMPLE_Q_TAG,       // tag_action
                  NULL,                   // data_ptr
                  0,                      // dxfer_len
                  sizeof(ccb.csio.sense_data),  // sense_len
                  0,                      // cdb_len
                  30*1000);               // timeout
      }
      ccb.csio.cdb_len = i+1;
      return ccb.csio.cdb_io.cdb_bytes[i];
    }
    unsigned char &operator()(size_t i) 
      { return ((unsigned char *)&ccb.csio.sense_data)[i]; }
      unsigned char *sense()  { return (unsigned char*)&ccb.csio.sense_data;    }
      void timeout(int i);
      size_t residue();
      int transport(Direction dir,void *buf,size_t sz);
      int umount(int f);
#define RELOAD_NEVER_NEEDED   // according to Matthew Dillon
      int is_reload_needed ();
};

//*
#elif defined(_WIN32)

#if defined(__MINGW32__)
#include <ddk/ntddscsi.h>
#define FSCTL_LOCK_VOLUME     CTL_CODE(FILE_DEVICE_FILE_SYSTEM,6,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_UNLOCK_VOLUME   CTL_CODE(FILE_DEVICE_FILE_SYSTEM,7,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM,8,METHOD_BUFFERED,FILE_ANY_ACCESS)
#else
#include <winioctl.h>
#include <ntddscsi.h>
#endif

typedef enum {    NONE=SCSI_IOCTL_DATA_UNSPECIFIED,
            READ=SCSI_IOCTL_DATA_IN,
            WRITE=SCSI_IOCTL_DATA_OUT
           } Direction;

typedef struct {
    SCSI_PASS_THROUGH_DIRECT  spt;
    unsigned char       sense[18];
} SPKG;

class Scsi_Command {
private:
    HANDLE fd;
    int    autoclose;
    char  *filename;
    SPKG   p;
public:
    Scsi_Command();
    Scsi_Command(void*f);
    ~Scsi_Command();
    int associate (const char *file,const struct stat *ref=NULL);
    unsigned char &operator[] (size_t i)
    { if (i==0)
      {   memset(&p,0,sizeof(p));
          p.spt.Length = sizeof(p.spt);
          p.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
          p.spt.TimeOutValue = 30;
          p.spt.SenseInfoLength = sizeof(p.sense);
          p.spt.SenseInfoOffset = offsetof(SPKG,sense);
      }
      p.spt.CdbLength = i+1;
      return p.spt.Cdb[i];
    }
    unsigned char &operator()(size_t i)   { return p.sense[i]; }
    unsigned char *sense();
    void timeout(int i);
    size_t residue();
    int transport(Direction dir=NONE,void *buf=NULL,size_t sz=0);
    int umount (int f=-1);

#define RELOAD_NEVER_NEEDED
    int is_reload_needed ();
};
//*/

#else
#error "Unsupported OS"
#endif

#undef ERRCODE
#undef CREAM_ON_ERRNO
#undef CREAM_ON_ERRNO_NAKED

#endif

Generated by  Doxygen 1.6.0   Back to index