summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-01-05 16:21:55 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-07 15:52:33 +0100
commit456a3fc952d34a3e8781ca100851e6253c537109 (patch)
tree8406a3e38eb8a399a0bb155314be0ddc2d31e5a1
parent950f4bdc027cb8c83fd2145590549fdcf5522078 (diff)
downloadrockbox-456a3fc.tar.gz
rockbox-456a3fc.zip
imxtools: various fixes for Windows
Don't use colors since the terminal doesn't support it. Also packing is broken on MinGW so use #pragma pack when compiling for windows, this is also supported by MSCV. Change-Id: I635649d52ed5f2e0af46cb9ca2ec325955b2ddb2
-rw-r--r--utils/imxtools/scsitools/misc.c5
-rw-r--r--utils/imxtools/scsitools/stmp_scsi.c8
-rw-r--r--utils/imxtools/scsitools/stmp_scsi.h41
-rw-r--r--utils/nwztools/scsitools/misc.c5
-rw-r--r--utils/scsi/rbscsi.c22
-rw-r--r--utils/scsi/rbscsi.h15
6 files changed, 81 insertions, 15 deletions
diff --git a/utils/imxtools/scsitools/misc.c b/utils/imxtools/scsitools/misc.c
index 108235e7fd..36eae198e5 100644
--- a/utils/imxtools/scsitools/misc.c
+++ b/utils/imxtools/scsitools/misc.c
@@ -32,7 +32,12 @@ char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
+#if defined(_WIN32) || defined(__WIN32__)
+/* disable colors on Windows */
+static bool g_color_enable = false;
+#else
static bool g_color_enable = true;
+#endif
void *xmalloc(size_t s)
{
diff --git a/utils/imxtools/scsitools/stmp_scsi.c b/utils/imxtools/scsitools/stmp_scsi.c
index e1d0dc4c77..8daeb8a532 100644
--- a/utils/imxtools/scsitools/stmp_scsi.c
+++ b/utils/imxtools/scsitools/stmp_scsi.c
@@ -245,14 +245,22 @@ int stmp_get_logical_media_table(stmp_device_t dev, struct stmp_logical_media_ta
int len = sizeof(header);
int ret = stmp_scsi_get_logical_table(dev, 0, &header, &len);
if(ret || len != sizeof(header))
+ {
+ stmp_debugf(dev, "Device returned the wrong size for logical media header: "
+ "%d bytes but expected %d\n", len, sizeof(header));
return -1;
+ }
header.count = stmp_fix_endian16be(header.count);
int sz = sizeof(header) + header.count * sizeof(struct scsi_stmp_logical_table_entry_t);
len = sz;
*table = malloc(sz);
ret = stmp_scsi_get_logical_table(dev, header.count, &(*table)->header, &len);
if(ret || len != sz)
+ {
+ stmp_debugf(dev, "Device returned the wrong size for logical media table: "
+ "%d bytes but expected %d (%d entries)\n", len, sz, header.count);
return -1;
+ }
(*table)->header.count = stmp_fix_endian16be((*table)->header.count);
for(unsigned i = 0; i < (*table)->header.count; i++)
(*table)->entry[i].size = stmp_fix_endian64be((*table)->entry[i].size);
diff --git a/utils/imxtools/scsitools/stmp_scsi.h b/utils/imxtools/scsitools/stmp_scsi.h
index 56068b5d4c..e85122041f 100644
--- a/utils/imxtools/scsitools/stmp_scsi.h
+++ b/utils/imxtools/scsitools/stmp_scsi.h
@@ -25,6 +25,17 @@
#include <stdbool.h>
#include "rbscsi.h"
+#if defined(_WIN32) || defined(__WIN32__)
+/* Mingw has a curious behaviour: it packs only the last field, see
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 */
+#pragma pack(push)
+#pragma pack(1)
+#define RB_POP_PACK
+#define RB_PACKED
+#else
+#define RB_PACKED __attribute__((packed))
+#endif
+
/**
* Low-Level SCSI stuff
*/
@@ -57,17 +68,17 @@ struct scsi_stmp_protocol_version_t
{
uint8_t major;
uint8_t minor;
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_rom_rev_id_t
{
uint16_t rev; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_chip_major_rev_id_t
{
uint16_t rev; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_table_entry_t
{
@@ -75,7 +86,7 @@ struct scsi_stmp_logical_table_entry_t
uint8_t type;
uint8_t tag;
uint64_t size; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
#define SCSI_STMP_DRIVE_TYPE_USER 0
#define SCSI_STMP_DRIVE_TYPE_SYSTEM 1
@@ -87,7 +98,7 @@ struct scsi_stmp_logical_table_entry_t
struct scsi_stmp_logical_table_header_t
{
uint16_t count; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
#define SCSI_STMP_MEDIA_INFO_NR_DRIVES 0 /** Number of drives (obsolete) */
#define SCSI_STMP_MEDIA_INFO_SIZE 1 /** Total size (bytes) */
@@ -127,12 +138,12 @@ struct scsi_stmp_logical_table_header_t
struct scsi_stmp_logical_media_info_type_t
{
uint8_t type;
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_media_info_manufacturer_t
{
uint32_t type; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
#define SCSI_STMP_DRIVE_INFO_SECTOR_SIZE 0 /** Sector Size (bytes) */
#define SCSI_STMP_DRIVE_INFO_ERASE_SIZE 1 /** Erase Size (bytes) */
@@ -170,29 +181,29 @@ struct scsi_stmp_logical_media_info_manufacturer_t
struct scsi_stmp_logical_drive_info_sector_t
{
uint32_t size; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_drive_info_count_t
{
uint64_t count; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_drive_info_size_t
{
uint64_t size; /* big-endian */
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_drive_info_type_t
{
uint8_t type;
-} __attribute__((packed));
+} RB_PACKED;
struct scsi_stmp_logical_drive_info_version_t
{
uint16_t major;
uint16_t minor;
uint16_t revision;
-} __attribute__((packed));
+} RB_PACKED;
struct stmp_device_t;
typedef struct stmp_device_t *stmp_device_t;
@@ -253,7 +264,11 @@ struct stmp_logical_media_table_t
{
struct scsi_stmp_logical_table_header_t header;
struct scsi_stmp_logical_table_entry_t entry[];
-}__attribute__((packed)) table;
+}RB_PACKED table;
+
+#ifdef RB_POP_PACK
+#pragma pack(pop)
+#endif
struct stmp_logical_media_info_t
{
diff --git a/utils/nwztools/scsitools/misc.c b/utils/nwztools/scsitools/misc.c
index 108235e7fd..36eae198e5 100644
--- a/utils/nwztools/scsitools/misc.c
+++ b/utils/nwztools/scsitools/misc.c
@@ -32,7 +32,12 @@ char GREEN[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '2', 0x6d, '\0' };
char YELLOW[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '3', 0x6d, '\0' };
char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
+#if defined(_WIN32) || defined(__WIN32__)
+/* disable colors on Windows */
+static bool g_color_enable = false;
+#else
static bool g_color_enable = true;
+#endif
void *xmalloc(size_t s)
{
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 */