[Cc: to the dvd+rw-tools maintainer to let him know of the patches] Hello developers, I know we already got libscg up and running on all three operating systems that are our main target. But the original libscg by Joerg Schilling has the disadvantage that it is centered around the Solaris way of addressing SCSI devices by bus/dev/lun, which does not fit the model on windows, and also in uncomfortable to deal with on Linux. On Linux, libscg thankfully supports "open by devname" which avoids the abstraction into bus/dev/lun we don't need if we are just interested in the Hi-MD stuff, while on Windows, "open by devname" is not supported. libusal (the fork by Debain people around Eduard Bloch) adds support for opening by device name, but hacks it into the present infrastructure in a not exactly clean way - and for example still scans all drives to assign bus numbers. I found that dvd+rwtools contains a refreshingly simple GPLed (without any restrictions like "you need to modify author name" and so on) SCSI abstraction layer that covers the following operating systems: Linux, OpenBSD/NetBSD, Solaris (license for distribution maybe questionable), FreeBSD, HP-UX, IRIX, Win32, Mac OS X. (see: http://fy.chalmers.se/~appro/linux/DVD+RW/ search for "run Linux") The nice thing is that this library does not even think about adding some abstraction on device naming, so "/dev/sdb" works out-of-the-box on Linux while "E:" works out-of-the-box on Windows. I don't have a MacOS to test here. Sources for dvd+rw-tools can be obtained from here: http://fy.chalmers.se/~appro/linux/DVD+RW/tools/ Patches (one for a bug in the Linux header, one to suppress lots of warnings to compile with MinGW, one to lift the restriction of only being able to work on CD/DVD drives) are attached to this mail, as well as a simple test program that sends an "INQUIRY" SCSI command (reads vendor/model/revision). I would like to have it tested on MacOS X, too, if someone cares. It looks like a device node name is expected in the MacOS case too, just as in Linux. To use the SCSI layer, you just need transport.hxx, win32err.h and asctable.h from the dvd+rw-tools package. The only small drawback of this code compared to libscg is that this code is in C++, but as it in fact does not really make use of C++ except for making Scsi_Command a class, it integrates quite well even into C projects. I wouldn't have problems to add this small amount of C++ to libhimd. Regards, Michael Karcher
--- ../dvd+rw-tools-7.1/win32err.h.orig 2010-12-03 02:57:54.000000000 +0100 +++ win32err.h 2010-12-03 02:59:05.000000000 +0100 @@ -1,16 +1,5 @@ -# define EINVAL ERROR_BAD_ARGUMENTS -# define ENOMEM ERROR_OUTOFMEMORY # define EMEDIUMTYPE ERROR_MEDIA_INCOMPATIBLE # define ENOMEDIUM ERROR_MEDIA_OFFLINE -# define ENODEV ERROR_BAD_COMMAND -# define EAGAIN ERROR_NOT_READY -# define ENOSPC ERROR_DISK_FULL -# define EIO ERROR_NOT_SUPPORTED -# define ENXIO ERROR_GEN_FAILURE -# define EBUSY ERROR_SHARING_VIOLATION -# define ENOENT ERROR_FILE_NOT_FOUND -# define ENOTDIR ERROR_NO_VOLUME_LABEL -# define EINTR ERROR_OPERATION_ABORTED # define FATAL_START(e) (0x10000|(e)) # define FATAL_MASK 0x0FFFF
--- ../dvd+rw-tools-7.1/transport.hxx.orig 2010-12-03 02:43:34.000000000 +0100 +++ transport.hxx 2010-12-03 02:58:57.000000000 +0100 @@ -1297,14 +1297,21 @@ int associate (const char *file,const struct stat *ref=NULL) { char dev[32]; sprintf(dev,"%.*s\\",sizeof(dev)-2,file); - if (GetDriveType(dev)!=DRIVE_CDROM) - return errno=EINVAL,0; sprintf(dev,"\\\\.\\%.*s",sizeof(dev)-5,file); fd=CreateFile (dev,GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL); if (fd!=INVALID_HANDLE_VALUE) - filename=strdup(dev); + { /* test that SCSI Passthrough is supported by sending test unit ready */ + for(int i = 0;i < 8;++i) + this->operator[](0) = 0; + if(transport() == -1) + { CloseHandle(fd); + fd = INVALID_HANDLE_VALUE; + errno = EINVAL; + } else + filename=strdup(dev); + } return fd!=INVALID_HANDLE_VALUE; } unsigned char &operator[] (size_t i)
--- ../dvd+rw-tools-7.1/transport.hxx.orig 2010-12-03 02:43:34.000000000 +0100 +++ transport.hxx 2010-12-03 02:58:57.000000000 +0100 @@ -139,6 +139,7 @@ #if defined(__linux) +#include <limits.h> #include <sys/ioctl.h> #include <linux/cdrom.h> #include <mntent.h>
#include <string> #include <climits> #include <iostream> #include <ostream> #include "transport.hxx" int main(int argc, char ** argv) { using std::cerr; using std::cout; using std::endl; Scsi_Command cmd; char response[96]; if(!cmd.associate(argv[1])) { cerr << "Can't associate"; return 1; } cmd[0] = 0x12; cmd[1] = 0; cmd[2] = 0; /* page code */ cmd[3] = 0; cmd[4] = 96; cmd[5] = 0; if(cmd.transport(READ,response,96)) { cerr << "Can't execute"; return 1; } cout << "Vendor: " << std::string(response+8,8) << "; Model: " << std::string(response+16,16) << "; Revision " << std::string(response+32,4) << endl; return 0; }