ScsiIf-win.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:9k
- /* cdrdao - write audio CD-Rs in disc-at-once mode
- *
- * Copyright (C) 1998 Andreas Mueller <mueller@daneb.ping.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*
- * $Log$
- */
- static char rcsid[] = "$Id$";
- #include "config.h"
- #include <windows.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <string.h>
- #include <assert.h>
- #include "winaspi.h"
- #include "ScsiIf.h"
- #include "util.h"
- #include "decodeSense.cc"
- typedef DWORD (*GETSUPPORTINFO) (void);
- typedef DWORD (*GETDLLVERSION) (void);
- typedef DWORD (*SENDCOMMAND) (char *);
- #define BUF_SIZE (32*1024)
- class ScsiIfImpl
- {
- public:
- char *dev_;
-
- int maxSendLen_;
- SRB_ExecSCSICmd6 cmd6_;
- SRB_ExecSCSICmd10 cmd10_;
- SRB_ExecSCSICmd12 cmd12_;
- unsigned char senseBuffer_[SENSE_LEN];
- char haid_;
- char lun_;
- char scsi_id_;
- HINSTANCE hinstlib;
- SENDCOMMAND Sendcommand;
- };
- ScsiIf::ScsiIf(const char *dev)
- {
- char *p, *q;
-
- impl_ = new ScsiIfImpl;
- impl_->dev_ = strdupCC(dev);
- maxDataLen_ = BUF_SIZE;
- impl_->haid_ = 0;
- impl_->lun_ = 0;
- impl_->scsi_id_ = 0;
- if (p = strchr (impl_->dev_, ':'))
- {
- *p = 0;
- impl_->haid_ = atoi (impl_->dev_);
- q = ++p;
- if (p = strchr (q, ':'))
- {
- *p = 0;
- impl_->lun_ = atoi (q);
- q = ++p;
- impl_->scsi_id_ = atoi (q);
- }
- }
- impl_->hinstlib = 0;
- vendor_[0] = 0;
- product_[0] = 0;
- revision_[0] = 0;
- }
- ScsiIf::~ScsiIf()
- {
- delete[] impl_->dev_;
- impl_->dev_ = NULL;
- if (impl_->hinstlib)
- FreeLibrary (impl_->hinstlib);
- delete impl_;
- }
- // opens and flushes scsi device
- // return: 0: OK
- // 1: device could not be opened
- // 2: inquiry failed
- int ScsiIf::init()
- {
- impl_->hinstlib = LoadLibrary ("WNASPI32.DLL");
- if (!impl_->hinstlib)
- {
- message (-2, "Can't load WNASPI32.DLL");
- return 1;
- }
- else {
- impl_->Sendcommand = (SENDCOMMAND)GetProcAddress (impl_->hinstlib, "SendASPI32Command");
- }
- if (inquiry() != 0)
- return 2;
- return 0;
- }
- // Sets given timeout value in seconds and returns old timeout.
- // return: old timeout
- int ScsiIf::timeout (int t)
- {
- return 0;
- }
- // sends a scsi command and receives data
- // return 0: OK
- // 1: scsi command failed (os level, no sense data available)
- // 2: scsi command failed (sense data available)
- int ScsiIf::sendCmd (const unsigned char *cmd, int cmdLen,
- const unsigned char *dataOut, int dataOutLen,
- unsigned char *dataIn, int dataInLen,
- int showMessage)
- {
- int status, i = 10;
- switch (cmdLen)
- {
- case 6: memset (&impl_->cmd6_, 0, sizeof (SRB_ExecSCSICmd6));
- memcpy (impl_->cmd6_.CDBByte, cmd, 6);
- impl_->cmd6_.SRB_Cmd = SC_EXEC_SCSI_CMD;
- impl_->cmd6_.SRB_HaId = impl_->haid_;
- impl_->cmd6_.SRB_Target = impl_->scsi_id_;
- impl_->cmd6_.SRB_Lun = impl_->lun_;
- impl_->cmd6_.SRB_SenseLen = SENSE_LEN;
- impl_->cmd6_.SRB_CDBLen = 6;
- if (dataOut && dataOutLen)
- {
- impl_->cmd6_.SRB_Flags = SRBF_WRITE;
- impl_->cmd6_.SRB_BufPointer = dataOut;
- impl_->cmd6_.SRB_BufLen = dataOutLen;
- }
- else
- {
- impl_->cmd6_.SRB_Flags = SRBF_READ;
- impl_->cmd6_.SRB_BufPointer = dataIn;
- impl_->cmd6_.SRB_BufLen = dataInLen;
- }
- (impl_->Sendcommand) ((char *) &impl_->cmd6_);
- while (i-- && impl_->cmd6_.SRB_Status != SS_COMP)
- {
- while (!impl_->cmd6_.SRB_Status)
- Sleep (10);
- }
- // AM: Try to get sense data
- if (impl_->cmd6_.SRB_Status == SS_ERR &&
- impl_->cmd6_.SRB_TargStat == STATUS_CHKCOND) {
- memcpy(impl_->senseBuffer_, impl_->cmd6_.SenseArea, SENSE_LEN);
- if (showMessage)
- printError();
- return 2;
- }
- if (impl_->cmd6_.SRB_Status != SS_COMP)
- return (1);
- break;
- case 10: memset (&impl_->cmd10_, 0, sizeof (SRB_ExecSCSICmd10));
- memcpy (impl_->cmd10_.CDBByte, cmd, 10);
- impl_->cmd10_.SRB_Cmd = SC_EXEC_SCSI_CMD;
- impl_->cmd10_.SRB_HaId = impl_->haid_;
- impl_->cmd10_.SRB_Target = impl_->scsi_id_;
- impl_->cmd10_.SRB_Lun = impl_->lun_;
- impl_->cmd10_.SRB_SenseLen = SENSE_LEN;
- impl_->cmd10_.SRB_CDBLen = 10;
- if (dataOut && dataOutLen)
- {
- impl_->cmd10_.SRB_Flags = SRBF_WRITE;
- impl_->cmd10_.SRB_BufPointer = dataOut;
- impl_->cmd10_.SRB_BufLen = dataOutLen;
- }
- else
- {
- impl_->cmd10_.SRB_Flags = SRBF_READ;
- impl_->cmd10_.SRB_BufPointer = dataIn;
- impl_->cmd10_.SRB_BufLen = dataInLen;
- }
-
- (impl_->Sendcommand) ((char *) &impl_->cmd10_);
- while (i-- && impl_->cmd10_.SRB_Status != SS_COMP)
- {
- while (!impl_->cmd10_.SRB_Status)
- Sleep (10);
- }
- // AM: Try to get sense data
- if (impl_->cmd10_.SRB_Status == SS_ERR &&
- impl_->cmd10_.SRB_TargStat == STATUS_CHKCOND) {
- memcpy(impl_->senseBuffer_, impl_->cmd10_.SenseArea10,
- SENSE_LEN);
- if (showMessage)
- printError();
- return 2;
- }
- if (impl_->cmd10_.SRB_Status != SS_COMP)
- return (1);
- break;
- case 12: memset (&impl_->cmd12_, 0, sizeof (SRB_ExecSCSICmd12));
- memcpy (impl_->cmd12_.CDBByte, cmd, 12);
- impl_->cmd12_.SRB_Cmd = SC_EXEC_SCSI_CMD;
- impl_->cmd12_.SRB_HaId = impl_->haid_;
- impl_->cmd12_.SRB_Target = impl_->scsi_id_;
- impl_->cmd12_.SRB_Lun = impl_->lun_;
- impl_->cmd12_.SRB_SenseLen = SENSE_LEN;
- impl_->cmd12_.SRB_CDBLen = 12;
- if (dataOut && dataOutLen)
- {
- impl_->cmd12_.SRB_Flags = SRBF_WRITE;
- impl_->cmd12_.SRB_BufPointer = dataOut;
- impl_->cmd12_.SRB_BufLen = dataOutLen;
- }
- else
- {
- impl_->cmd12_.SRB_Flags = SRBF_READ;
- impl_->cmd12_.SRB_BufPointer = dataIn;
- impl_->cmd12_.SRB_BufLen = dataInLen;
- }
-
- (impl_->Sendcommand) ((char *) &impl_->cmd12_);
- while (i-- && impl_->cmd12_.SRB_Status != SS_COMP)
- {
- while (!impl_->cmd12_.SRB_Status)
- Sleep (10);
- }
- // AM: Try to get sense data
- if (impl_->cmd12_.SRB_Status == SS_ERR &&
- impl_->cmd12_.SRB_TargStat == STATUS_CHKCOND) {
- memcpy(impl_->senseBuffer_, impl_->cmd12_.SenseArea12,
- SENSE_LEN);
- if (showMessage)
- printError();
- return 2;
- }
- if (impl_->cmd12_.SRB_Status != SS_COMP)
- return (1);
- break;
- }
- return 0;
- }
- const unsigned char *ScsiIf::getSense(int &len) const
- {
- len = SENSE_LEN;
- return impl_->senseBuffer_;
- }
- void ScsiIf::printError()
- {
- decodeSense(impl_->senseBuffer_, SENSE_LEN);
- }
- int ScsiIf::inquiry()
- {
- unsigned char cmd[6];
- unsigned char result[0x2c];
- int i;
- cmd[0] = 0x12; // INQUIRY
- cmd[1] = cmd[2] = cmd[3] = 0;
- cmd[4] = 0x2c;
- cmd[5] = 0;
- if (sendCmd (cmd, 6, NULL, 0, result, 0x2c, 1) != 0) {
- message (-2, "Inquiry command failed on '%s': ", impl_->dev_);
- return 1;
- }
- strncpy(vendor_, (char *)(result + 0x08), 8);
- vendor_[8] = 0;
- strncpy(product_, (char *)(result + 0x10), 16);
- product_[16] = 0;
- strncpy(revision_, (char *)(result + 0x20), 4);
- revision_[4] = 0;
- for (i = 7; i >= 0 && vendor_[i] == ' '; i--)
- {
- vendor_[i] = 0;
- }
- for (i = 15; i >= 0 && product_[i] == ' '; i--)
- {
- product_[i] = 0;
- }
- for (i = 3; i >= 0 && revision_[i] == ' '; i--)
- {
- revision_[i] = 0;
- }
- return 0;
- }