From b5cc36d9e8c60ad4f9bcf99b1e951520a3ca412b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 Apr 2010 23:08:59 +0200 Subject: [PATCH] added himd format feature (windows only) --- libhimd/himd_scsi.c | 88 +++++++++++++++++++++++++++++++++++ libhimd/himd_scsi.h | 25 ++++++++++ libhimd/libhimd.pro | 6 +- qhimdtransfer/qhimddetection.h | 1 + qhimdtransfer/qhimdformatdialog.cpp | 51 ++++++++++++++++++++ qhimdtransfer/qhimdformatdialog.h | 5 ++ qhimdtransfer/qhimdmainwindow.cpp | 16 +++++- qhimdtransfer/qhimdwindetection.cpp | 3 +- 8 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 libhimd/himd_scsi.c create mode 100644 libhimd/himd_scsi.h diff --git a/libhimd/himd_scsi.c b/libhimd/himd_scsi.c new file mode 100644 index 0000000..4152669 --- /dev/null +++ b/libhimd/himd_scsi.c @@ -0,0 +1,88 @@ +#include "himd.h" +#include "himd_scsi.h" +#include + +#include +#include + +int himdscsi_open_device(char * device) +{ + return scsi_pt_open_device(device, 0 ,0); +} + +int himdscsi_send_format_cmd(int open_device, struct scsi_error * error) +{ + int success = -1; + struct sg_pt_base *ptvp = NULL; + unsigned char command[12]; + unsigned char sense_buffer[32]; + + ptvp = construct_scsi_pt_obj(); + if (ptvp == NULL) + { + error->error_msg = "Cannot send scsi command, out of memory"; + goto clean; + } + + memset(command,0,12); + command[0] = 0xC2; /* sony special commands */ + command[4] = 3; /* subcommand: format */ + + set_scsi_pt_cdb(ptvp, command, sizeof(command)); + set_scsi_pt_sense(ptvp, sense_buffer, sizeof(sense_buffer)); + + if(do_scsi_pt(ptvp, open_device, SCSI_TIMEOUT, 0) != 0) + { + error->error_msg = "Error sending scsi command"; + goto clean; + } + + if(get_scsi_pt_result_category(ptvp) == SCSI_PT_RESULT_GOOD) + { + success = 0; + goto clean; + } + else if(get_scsi_pt_result_category(ptvp) == SCSI_PT_RESULT_SENSE) + { + error->error_msg = "scsi device returns an error"; + sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp), sizeof(error->status), error->status); + sg_get_sense_str(NULL, sense_buffer, sizeof(sense_buffer), 0, sizeof(error->sense), error->sense); + } +clean: + if (ptvp) + destruct_scsi_pt_obj(ptvp); + + return success; +} + +void himdscsi_wait_for_unit_ready(int open_device) +{ + int status; + unsigned char command[12]; + struct sg_pt_base *ptvp = NULL; + + memset(command,0,12); + do + { + if (ptvp) + destruct_scsi_pt_obj(ptvp); + ptvp = construct_scsi_pt_obj(); + set_scsi_pt_cdb(ptvp, command, sizeof(command)); + status = do_scsi_pt(ptvp, open_device, SCSI_TIMEOUT, 0); + } + while(get_scsi_pt_result_category(ptvp) != SCSI_PT_RESULT_GOOD); + + if (ptvp) + destruct_scsi_pt_obj(ptvp); +} + +void himdscsi_close_device(int open_device) +{ + if (open_device >= 0) + scsi_pt_close_device(open_device); +} + + + + + diff --git a/libhimd/himd_scsi.h b/libhimd/himd_scsi.h new file mode 100644 index 0000000..f1398c2 --- /dev/null +++ b/libhimd/himd_scsi.h @@ -0,0 +1,25 @@ +#ifndef INCLUDED_LIBHIMD_SCSI_H +#define INCLUDED_LIBHIMD_SCSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct scsi_error { + char * error_msg; + char status[128]; + char sense[1024]; +}; + +#define SCSI_TIMEOUT 20 + +int himdscsi_open_device(char * device); +int himdscsi_send_format_cmd(int open_device, struct scsi_error * error); +void himdscsi_wait_for_unit_ready(int open_device); +void himdscsi_close_device(int open_device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libhimd/libhimd.pro b/libhimd/libhimd.pro index 45390d0..35e0488 100644 --- a/libhimd/libhimd.pro +++ b/libhimd/libhimd.pro @@ -17,6 +17,6 @@ else: !build_pass: message(You disabled mcrypt: No PCM and ATRAC transfer will b else: !build_pass: message(You disabled mad: MP3 transfer will be limited) PKGCONFIG += glib-2.0 -HEADERS += himd.h himd_private.h sony_oma.h -SOURCES += encryption.c himd.c mdstream.c trackindex.c sony_oma.c frag.c -LIBS += -lmad -lmcrypt +HEADERS += himd.h himd_private.h sony_oma.h himd_scsi.h +SOURCES += encryption.c himd.c mdstream.c trackindex.c sony_oma.c frag.c himd_scsi.c +LIBS += -lmad -lmcrypt -lsgutils2 diff --git a/qhimdtransfer/qhimddetection.h b/qhimdtransfer/qhimddetection.h index 5c30be9..5a417a6 100644 --- a/qhimdtransfer/qhimddetection.h +++ b/qhimdtransfer/qhimddetection.h @@ -24,6 +24,7 @@ struct himd_device { QString path; bool md_inserted; QString recorder_name; + QString scsi_device; virtual ~himd_device(){} /* for polymorphic delete */ }; diff --git a/qhimdtransfer/qhimdformatdialog.cpp b/qhimdtransfer/qhimdformatdialog.cpp index f3e0452..47efcc5 100644 --- a/qhimdtransfer/qhimdformatdialog.cpp +++ b/qhimdtransfer/qhimdformatdialog.cpp @@ -1,5 +1,9 @@ #include "qhimdformatdialog.h" #include "ui_qhimdformatdialog.h" +#include +#include + +#include QHiMDFormatDialog::QHiMDFormatDialog(QWidget *parent) : QDialog(parent), @@ -23,3 +27,50 @@ void QHiMDFormatDialog::changeEvent(QEvent *e) break; } } + +void QHiMDFormatDialog::on_buttonBox_accepted() +{ + int sg_open = -1; + struct scsi_error error; + QString errmsg; + QMessageBox formatStatus; + + if(device == NULL) + { + errmsg = tr("himd device is not present"); + goto clean; + } + + if(device->scsi_device.isEmpty()) + { + errmsg = tr("No scsi device information available"); + goto clean; + } + + sg_open = himdscsi_open_device(device->scsi_device.toLatin1().data()); + if (sg_open < 0) + { + errmsg = tr("Error opening scsi port for device: ") + device->scsi_device; + goto clean; + } + + if(himdscsi_send_format_cmd(sg_open, &error) < 0) + { + errmsg = error.error_msg + tr("\nDevice Status: ") + error.status + tr("\nSense: ") + error.sense; + goto clean; + } + +clean: + if(!errmsg.isEmpty()) + formatStatus.setText(tr("Error formatting HiMD:\n") + errmsg); + else + { + himdscsi_wait_for_unit_ready(sg_open); + formatStatus.setText(tr("HiMD successfully formatted")); + } + + himdscsi_close_device(sg_open); + formatStatus.exec(); + device = NULL; +} + diff --git a/qhimdtransfer/qhimdformatdialog.h b/qhimdtransfer/qhimdformatdialog.h index 5b92c8a..d3588c5 100644 --- a/qhimdtransfer/qhimdformatdialog.h +++ b/qhimdtransfer/qhimdformatdialog.h @@ -2,6 +2,7 @@ #define QHIMDFORMATDIALOG_H #include +#include namespace Ui { class QHiMDFormatDialog; @@ -13,12 +14,16 @@ class QHiMDFormatDialog : public QDialog { public: explicit QHiMDFormatDialog(QWidget *parent = 0); virtual ~QHiMDFormatDialog(); + himd_device * device; protected: virtual void changeEvent(QEvent *e); private: Ui::QHiMDFormatDialog *m_ui; + +private slots: + void on_buttonBox_accepted(); }; #endif // QHIMDFORMATDIALOG_H diff --git a/qhimdtransfer/qhimdmainwindow.cpp b/qhimdtransfer/qhimdmainwindow.cpp index 359c91e..a2c238f 100644 --- a/qhimdtransfer/qhimdmainwindow.cpp +++ b/qhimdtransfer/qhimdmainwindow.cpp @@ -154,7 +154,7 @@ QString QHiMDMainWindow::dumppcm(const QHiMDTrack & track, QString file) while(himd_nonmp3stream_read_block(&str, &data, &len, NULL, &status) >= 0) { - + for(i = 0; i < len/4; i++) { left = data[i*4]*256+data[i*4+1]; @@ -309,7 +309,7 @@ void QHiMDMainWindow::upload_to(const QString & UploadDirectory) allblocks += tracks[i].blockcount(); uploadDialog->init(tracks.length(), allblocks); - + for(int i = 0;i < tracks.length(); i++) { QString filename, errmsg; @@ -360,7 +360,7 @@ void QHiMDMainWindow::upload_to(const QString & UploadDirectory) QHiMDMainWindow::QHiMDMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::QHiMDMainWindowClass) -{ +{ aboutDialog = new QHiMDAboutDialog; formatDialog = new QHiMDFormatDialog; uploadDialog = new QHiMDUploadDialog; @@ -423,6 +423,15 @@ void QHiMDMainWindow::on_action_About_triggered() void QHiMDMainWindow::on_action_Format_triggered() { + QMessageBox formatError; + + formatDialog->device = detect->find_by_path(ui->himd_devices->currentText()); + if(formatDialog->device == NULL) + { + formatError.setText(tr("Format command is not supported on mounted images")); + formatError.exec(); + return; + } formatDialog->show(); } @@ -527,6 +536,7 @@ void QHiMDMainWindow::himd_removed(QString HiMDPath) ui->himd_devices->hide(); ui->himdpath->show(); } + formatDialog->device = NULL; } void QHiMDMainWindow::on_himd_devices_activated(QString device) diff --git a/qhimdtransfer/qhimdwindetection.cpp b/qhimdtransfer/qhimdwindetection.cpp index 1dc437a..d65cf43 100644 --- a/qhimdtransfer/qhimdwindetection.cpp +++ b/qhimdtransfer/qhimdwindetection.cpp @@ -58,7 +58,7 @@ QHiMDDetection * createDetection(QObject * parent) return new QHiMDWinDetection(parent); } -QHiMDWinDetection::QHiMDWinDetection(QObject * parent) +QHiMDWinDetection::QHiMDWinDetection(QObject * parent) : QHiMDDetection(parent), QWidget(0) { // ask for Window ID to have Qt create the window. @@ -222,6 +222,7 @@ void QHiMDWinDetection::add_himddevice(QString path, QString name) new_device->is_busy = false; new_device->path = path; new_device->recorder_name = name; + new_device->scsi_device = "PD" + QString::number(sdn.DeviceNumber); file[0] = path.at(0).toAscii(); if(OpenFile(file, &OFfile, OF_EXIST) != HFILE_ERROR) -- 1.6.4.msysgit.0