···379379 struct rb_scsi_devent_t *dev = malloc(sizeof(struct rb_scsi_devent_t));
380380 dev[0].scsi_path = NULL;
381381 dev[0].block_path = NULL;
382382+ int nr_dev = 0;
383383+ /* list logical drives */
384384+ DWORD cbStrSize = GetLogicalDriveStringsA(0, NULL);
385385+ LPSTR pszDrives = malloc(cbStrSize);
386386+ cbStrSize = GetLogicalDriveStringsA(cbStrSize, pszDrives);
387387+ /* drives are separated by a NULL character, the last drive is just a NULL one */
388388+ for(LPSTR pszDriveRoot = pszDrives; *pszDriveRoot != '\0';
389389+ pszDriveRoot += lstrlen(pszDriveRoot) + 1)
390390+ {
391391+ // each drive is of the form "X:\"
392392+ char path[3];
393393+ path[0] = pszDriveRoot[0]; // letter
394394+ path[1] = ':';
395395+ path[2] = 0;
396396+ /* open drive */
397397+ rb_scsi_device_t rdev = rb_scsi_open(path, 0, NULL, NULL);
398398+ if(rdev == NULL)
399399+ continue; // ignore device
400400+ // send an INQUIRY device to check it's actually an SCSI device and get information
401401+ uint8_t inquiry_data[36];
402402+ uint8_t cdb[6] = {0x12, 0, 0, 0, sizeof(inquiry_data), 0}; // INQUIRY
403403+404404+ struct rb_scsi_raw_cmd_t raw;
405405+ raw.dir = RB_SCSI_READ;
406406+ raw.cdb_len = sizeof(cdb);
407407+ raw.cdb = cdb;
408408+ raw.buf = inquiry_data;
409409+ raw.buf_len = sizeof(inquiry_data);
410410+ raw.sense_len = 0; // don't bother with SENSE, this command cannot possibly fail for good reasons
411411+ raw.sense = NULL;
412412+ raw.tmo = 5;
413413+ int ret = rb_scsi_raw_xfer(rdev, &raw);
414414+ rb_scsi_close(rdev);
415415+ if(ret != RB_SCSI_OK)
416416+ continue; // ignore device
417417+ if(raw.buf_len != (int)sizeof(inquiry_data))
418418+ continue; // ignore device (what kind of device would not return all the INQUIRY data?)
419419+420420+ /* fill device details */
421421+ dev = realloc(dev, (2 + nr_dev) * sizeof(struct rb_scsi_devent_t));
422422+ dev[nr_dev].scsi_path = strdup(path);
423423+ dev[nr_dev].block_path = strdup(path);
424424+ /* fill vendor/model/rev */
425425+ char info[17];
426426+ snprintf(info, sizeof(info), "%.8s", inquiry_data + 8);
427427+ dev[nr_dev].vendor = strdup(info);
428428+ snprintf(info, sizeof(info), "%.16s", inquiry_data + 16);
429429+ dev[nr_dev].model = strdup(info);
430430+ snprintf(info, sizeof(info), "%.4s", inquiry_data + 32);
431431+ dev[nr_dev].rev = strdup(info);
432432+433433+ /* sentinel */
434434+ dev[++nr_dev].scsi_path = NULL;
435435+ dev[nr_dev].block_path = NULL;
436436+ }
437437+382438 return dev;
383439}
384440/* other targets */
+2-2
utils/scsi/rbscsi.h
···9494{
9595 /* device path to the raw SCSI device, typically:
9696 * - Linux: /dev/sgX
9797- * - Windows: TODO
9797+ * - Windows: C:
9898 * This path can be used directly with scsi_rb_open(), and is guaranteed to
9999 * be valid. */
100100 char *scsi_path;
101101 /* device path to the corresponding block device, if it exists, typically:
102102 * - Linux: /dev/sdX
103103- * - Windows: TODO
103103+ * - Windows: C:
104104 * If this path is not-NULL, then it can used directly with scsi_rb_open() */
105105 char *block_path;
106106 /* various information about the device, can be NULL on error */