summaryrefslogtreecommitdiffstats
path: root/utils/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'utils/scsi')
-rw-r--r--utils/scsi/rbscsi.c22
-rw-r--r--utils/scsi/rbscsi.h15
2 files changed, 35 insertions, 2 deletions
diff --git a/utils/scsi/rbscsi.c b/utils/scsi/rbscsi.c
index aa62ba0118..8a263f29e6 100644
--- a/utils/scsi/rbscsi.c
+++ b/utils/scsi/rbscsi.c
@@ -151,13 +151,33 @@ void rb_scsi_close(rb_scsi_device_t dev)
/* Windpws */
#elif defined(RB_SCSI_WINDOWS)
+/* return either path or something allocated with malloc() */
+static const char *map_to_physical_drive(const char *path, unsigned flags, void *user,
+ rb_scsi_printf_t printf)
+{
+ /* don't do anything if path starts with '\' */
+ if(path[0] == '\\')
+ return path;
+ /* Convert to UNC path (C: -> \\.\C:) otherwise it won't work) */
+ char *unc_path = malloc(strlen(path) + 5);
+ sprintf(unc_path, "\\\\.\\%s", path);
+ if(flags & RB_SCSI_DEBUG)
+ printf(user, "rb_scsi: map to UNC path: %s\n", unc_path);
+ return unc_path;
+}
+
rb_scsi_device_t rb_scsi_open(const char *path, unsigned flags, void *user,
rb_scsi_printf_t printf)
{
if(printf == NULL)
printf = misc_std_printf;
- HANDLE h = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ /* magic to auto-detect physical drive */
+ const char *open_path = map_to_physical_drive(path, flags, user, printf);
+ HANDLE h = CreateFileA(open_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
+ /* free path if it was allocated */
+ if(open_path != path)
+ free((char *)open_path);
if(h == INVALID_HANDLE_VALUE)
{
if(flags & RB_SCSI_DEBUG)
diff --git a/utils/scsi/rbscsi.h b/utils/scsi/rbscsi.h
index 2b56aabad2..c7345a6cdf 100644
--- a/utils/scsi/rbscsi.h
+++ b/utils/scsi/rbscsi.h
@@ -66,7 +66,20 @@ struct rb_scsi_raw_cmd_t
};
/* open a device, returns a handle or NULL on error
- * the caller can optionally provide an error printing function */
+ * the caller can optionally provide an error printing function
+ *
+ * Linux:
+ * Path must be the block device, typically /dev/sdX and the program
+ * must have the permission to open it in read/write mode.
+ *
+ * Windows:
+ * If the path starts with '\', it will be use as-is. This allows to use
+ * paths such as \\.\PhysicalDriveX or \\.\ScsiX
+ * Alternatively, the code will try to map a logical drive (such as 'C:') to
+ * the correspoding physical drive.
+ * In any case, on recent windows, the program needs to be started with
+ * Administrator privileges.
+ */
rb_scsi_device_t rb_scsi_open(const char *path, unsigned flags, void *user,
rb_scsi_printf_t printf);
/* performs a raw transfer, returns !=0 on error */