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
This commit is contained in:
Amaury Pouly 2017-01-05 16:21:55 +01:00
parent 950f4bdc02
commit 456a3fc952
6 changed files with 81 additions and 15 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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
{

View file

@ -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)
{

View file

@ -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)

View file

@ -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 */