diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2020-01-29 13:27:18 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2020-01-29 13:27:18 +0100 |
commit | 05a40ab07c3f7784e62fc2651d49bb0ff735c2f3 (patch) | |
tree | 54532c723b0d5f3e97d9fc29115a0a4c04b68586 | |
parent | 392db31d905c6d893c8b2bd42c03fd49332aeb3c (diff) | |
download | rockbox-05a40ab07c3f7784e62fc2651d49bb0ff735c2f3.tar.gz rockbox-05a40ab07c3f7784e62fc2651d49bb0ff735c2f3.zip |
scsi: add support for listing devices on Windows
Change-Id: I963028c6017796152a201791c078f672bf84a40a
-rw-r--r-- | utils/scsi/rbscsi.c | 56 | ||||
-rw-r--r-- | utils/scsi/rbscsi.h | 4 |
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 */ |