summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2020-01-29 13:27:18 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2020-01-29 13:27:18 +0100
commit05a40ab07c3f7784e62fc2651d49bb0ff735c2f3 (patch)
tree54532c723b0d5f3e97d9fc29115a0a4c04b68586
parent392db31d905c6d893c8b2bd42c03fd49332aeb3c (diff)
downloadrockbox-05a40ab07c3f7784e62fc2651d49bb0ff735c2f3.tar.gz
rockbox-05a40ab07c3f7784e62fc2651d49bb0ff735c2f3.zip
scsi: add support for listing devices on Windows
Change-Id: I963028c6017796152a201791c078f672bf84a40a
-rw-r--r--utils/scsi/rbscsi.c56
-rw-r--r--utils/scsi/rbscsi.h4
2 files changed, 58 insertions, 2 deletions
diff --git a/utils/scsi/rbscsi.c b/utils/scsi/rbscsi.c
index adfecd8d0a..b44203152f 100644
--- a/utils/scsi/rbscsi.c
+++ b/utils/scsi/rbscsi.c
@@ -379,6 +379,62 @@ struct rb_scsi_devent_t *rb_scsi_list(void)
379 struct rb_scsi_devent_t *dev = malloc(sizeof(struct rb_scsi_devent_t)); 379 struct rb_scsi_devent_t *dev = malloc(sizeof(struct rb_scsi_devent_t));
380 dev[0].scsi_path = NULL; 380 dev[0].scsi_path = NULL;
381 dev[0].block_path = NULL; 381 dev[0].block_path = NULL;
382 int nr_dev = 0;
383 /* list logical drives */
384 DWORD cbStrSize = GetLogicalDriveStringsA(0, NULL);
385 LPSTR pszDrives = malloc(cbStrSize);
386 cbStrSize = GetLogicalDriveStringsA(cbStrSize, pszDrives);
387 /* drives are separated by a NULL character, the last drive is just a NULL one */
388 for(LPSTR pszDriveRoot = pszDrives; *pszDriveRoot != '\0';
389 pszDriveRoot += lstrlen(pszDriveRoot) + 1)
390 {
391 // each drive is of the form "X:\"
392 char path[3];
393 path[0] = pszDriveRoot[0]; // letter
394 path[1] = ':';
395 path[2] = 0;
396 /* open drive */
397 rb_scsi_device_t rdev = rb_scsi_open(path, 0, NULL, NULL);
398 if(rdev == NULL)
399 continue; // ignore device
400 // send an INQUIRY device to check it's actually an SCSI device and get information
401 uint8_t inquiry_data[36];
402 uint8_t cdb[6] = {0x12, 0, 0, 0, sizeof(inquiry_data), 0}; // INQUIRY
403
404 struct rb_scsi_raw_cmd_t raw;
405 raw.dir = RB_SCSI_READ;
406 raw.cdb_len = sizeof(cdb);
407 raw.cdb = cdb;
408 raw.buf = inquiry_data;
409 raw.buf_len = sizeof(inquiry_data);
410 raw.sense_len = 0; // don't bother with SENSE, this command cannot possibly fail for good reasons
411 raw.sense = NULL;
412 raw.tmo = 5;
413 int ret = rb_scsi_raw_xfer(rdev, &raw);
414 rb_scsi_close(rdev);
415 if(ret != RB_SCSI_OK)
416 continue; // ignore device
417 if(raw.buf_len != (int)sizeof(inquiry_data))
418 continue; // ignore device (what kind of device would not return all the INQUIRY data?)
419
420 /* fill device details */
421 dev = realloc(dev, (2 + nr_dev) * sizeof(struct rb_scsi_devent_t));
422 dev[nr_dev].scsi_path = strdup(path);
423 dev[nr_dev].block_path = strdup(path);
424 /* fill vendor/model/rev */
425 char info[17];
426 snprintf(info, sizeof(info), "%.8s", inquiry_data + 8);
427 dev[nr_dev].vendor = strdup(info);
428 snprintf(info, sizeof(info), "%.16s", inquiry_data + 16);
429 dev[nr_dev].model = strdup(info);
430 snprintf(info, sizeof(info), "%.4s", inquiry_data + 32);
431 dev[nr_dev].rev = strdup(info);
432
433 /* sentinel */
434 dev[++nr_dev].scsi_path = NULL;
435 dev[nr_dev].block_path = NULL;
436 }
437
382 return dev; 438 return dev;
383} 439}
384/* other targets */ 440/* other targets */
diff --git a/utils/scsi/rbscsi.h b/utils/scsi/rbscsi.h
index 322d94ec53..d2b4b71edb 100644
--- a/utils/scsi/rbscsi.h
+++ b/utils/scsi/rbscsi.h
@@ -94,13 +94,13 @@ struct rb_scsi_devent_t
94{ 94{
95 /* device path to the raw SCSI device, typically: 95 /* device path to the raw SCSI device, typically:
96 * - Linux: /dev/sgX 96 * - Linux: /dev/sgX
97 * - Windows: TODO 97 * - Windows: C:
98 * This path can be used directly with scsi_rb_open(), and is guaranteed to 98 * This path can be used directly with scsi_rb_open(), and is guaranteed to
99 * be valid. */ 99 * be valid. */
100 char *scsi_path; 100 char *scsi_path;
101 /* device path to the corresponding block device, if it exists, typically: 101 /* device path to the corresponding block device, if it exists, typically:
102 * - Linux: /dev/sdX 102 * - Linux: /dev/sdX
103 * - Windows: TODO 103 * - Windows: C:
104 * If this path is not-NULL, then it can used directly with scsi_rb_open() */ 104 * If this path is not-NULL, then it can used directly with scsi_rb_open() */
105 char *block_path; 105 char *block_path;
106 /* various information about the device, can be NULL on error */ 106 /* various information about the device, can be NULL on error */