/* static */ int getDriveInfoFromDev(DriveInfoList *pList, bool isDVD, bool *pfSuccess) { AssertPtrReturn(pList, VERR_INVALID_POINTER); AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); LogFlowFunc(("pList=%p, isDVD=%d, pfSuccess=%p\n", pList, isDVD, pfSuccess)); int rc = VINF_SUCCESS; bool success = false; char szPath[RTPATH_MAX] = "/dev"; deviceNodeArray aDevices; RT_ZERO(aDevices); devFindDeviceRecursive(szPath, sizeof(szPath), aDevices, isDVD); try { for (unsigned i = 0; i < MAX_DEVICE_NODES; ++i) { if (aDevices[i].Device) { pList->push_back(DriveInfo(aDevices[i].szPath, aDevices[i].szUdi, aDevices[i].szDesc)); success = true; } } if (pfSuccess != NULL) *pfSuccess = success; } catch(std::bad_alloc &e) { rc = VERR_NO_MEMORY; } LogFlowFunc (("rc=%Rrc, success=%d\n", rc, success)); return rc; }
void Device::Open(QString path, bool close) { this->path = path; problemReported = false; if(close) Close(); // skip opening device pointing to result file if(path.length() == 0) return; // open device file fd = open(path.toUtf8(), O_RDONLY | O_LARGEFILE | O_SYNC); if(fd < 0) { ReportWarning(); } DropCaches(); // get drive size device_size = lseek64(fd, 0, SEEK_END); // set pos to begin of device SetPos(0); DriveInfo(); }
void TSessionTest::testDriveInfo() // // Test the drive info. // { test.Start(_L("The drive info")); TDriveList list; TInt r=iFs.DriveList(list); test_KErrNone(r); for (TInt i=0;i<KMaxDrives;i++) { TInt att=list[i]; if (att) { TDriveInfo d; r=iFs.Drive(d,i); test_KErrNone(r); printDriveInfo(i,d); test.Printf(_L("\n")); DriveInfo(i,d); } } test.End(); }
/* static */ int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, bool *pfSuccess) { AssertPtrReturn(pList, VERR_INVALID_POINTER); AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */ LogFlowFunc (("pList=%p, isDVD=%u, pfSuccess=%p\n", pList, (unsigned) isDVD, pfSuccess)); RTDIR hDir; int rc; bool fSuccess = false; unsigned cFound = 0; if (!RTPathExists("/sys")) return VINF_SUCCESS; rc = RTDirOpen(&hDir, "/sys/block"); /* This might mean that sysfs semantics have changed */ AssertReturn(rc != VERR_FILE_NOT_FOUND, VINF_SUCCESS); fSuccess = true; if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY entry; rc = RTDirRead(hDir, &entry, NULL); Assert(rc != VERR_BUFFER_OVERFLOW); /* Should never happen... */ if (RT_FAILURE(rc)) /* Including overflow and no more files */ break; if (entry.szName[0] == '.') continue; sysfsBlockDev dev(entry.szName, isDVD); /* This might mean that sysfs semantics have changed */ AssertBreakStmt(dev.isConsistent(), fSuccess = false); if (!dev.isValid()) continue; try { pList->push_back(DriveInfo(dev.getNode(), dev.getUdi(), dev.getDesc())); } catch(std::bad_alloc &e) { rc = VERR_NO_MEMORY; break; } ++cFound; } RTDirClose(hDir); } if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; if (RT_FAILURE(rc)) /* Clean up again */ for (unsigned i = 0; i < cFound; ++i) pList->pop_back(); if (pfSuccess) *pfSuccess = fSuccess; LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned) fSuccess)); return rc; }
/* static */ int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) { AssertPtrReturn(pcszVar, VERR_INVALID_POINTER); AssertPtrReturn(pList, VERR_INVALID_POINTER); AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, pList, isDVD, pfSuccess)); int rc = VINF_SUCCESS; bool success = false; char *pszFreeMe = RTEnvDupEx(RTENV_DEFAULT, pcszVar); try { const char *pcszCurrent = pszFreeMe; while (pcszCurrent && *pcszCurrent != '\0') { const char *pcszNext = strchr(pcszCurrent, ':'); char szPath[RTPATH_MAX], szReal[RTPATH_MAX]; char szDesc[256], szUdi[256]; if (pcszNext) RTStrPrintf(szPath, sizeof(szPath), "%.*s", pcszNext - pcszCurrent - 1, pcszCurrent); else RTStrPrintf(szPath, sizeof(szPath), "%s", pcszCurrent); if ( RT_SUCCESS(RTPathReal(szPath, szReal, sizeof(szReal))) && devValidateDevice(szReal, isDVD, NULL, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi))) { pList->push_back(DriveInfo(szReal, szUdi, szDesc)); success = true; } pcszCurrent = pcszNext ? pcszNext + 1 : NULL; } if (pfSuccess != NULL) *pfSuccess = success; } catch(std::bad_alloc &e) { rc = VERR_NO_MEMORY; } RTStrFree(pszFreeMe); LogFlowFunc(("rc=%Rrc, success=%d\n", rc, success)); return rc; }
/** * Search for available CD/DVD drives using the CAM layer. * * @returns iprt status code * @param pList the list to append the drives found to * @param pfSuccess this will be set to true if we found at least one drive * and to false otherwise. Optional. */ static int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess) { int rc = VINF_SUCCESS; RTFILE FileXpt; rc = RTFileOpen(&FileXpt, "/dev/xpt0", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_SUCCESS(rc)) { union ccb DeviceCCB; struct dev_match_pattern DeviceMatchPattern; struct dev_match_result *paMatches = NULL; RT_ZERO(DeviceCCB); RT_ZERO(DeviceMatchPattern); /* We want to get all devices. */ DeviceCCB.ccb_h.func_code = XPT_DEV_MATCH; DeviceCCB.ccb_h.path_id = CAM_XPT_PATH_ID; DeviceCCB.ccb_h.target_id = CAM_TARGET_WILDCARD; DeviceCCB.ccb_h.target_lun = CAM_LUN_WILDCARD; /* Setup the pattern */ DeviceMatchPattern.type = DEV_MATCH_DEVICE; DeviceMatchPattern.pattern.device_pattern.path_id = CAM_XPT_PATH_ID; DeviceMatchPattern.pattern.device_pattern.target_id = CAM_TARGET_WILDCARD; DeviceMatchPattern.pattern.device_pattern.target_lun = CAM_LUN_WILDCARD; DeviceMatchPattern.pattern.device_pattern.flags = DEV_MATCH_INQUIRY; #if __FreeBSD_version >= 900000 # define INQ_PAT data.inq_pat #else #define INQ_PAT inq_pat #endif DeviceMatchPattern.pattern.device_pattern.INQ_PAT.type = T_CDROM; DeviceMatchPattern.pattern.device_pattern.INQ_PAT.media_type = SIP_MEDIA_REMOVABLE | SIP_MEDIA_FIXED; DeviceMatchPattern.pattern.device_pattern.INQ_PAT.vendor[0] = '*'; /* Matches anything */ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.product[0] = '*'; /* Matches anything */ DeviceMatchPattern.pattern.device_pattern.INQ_PAT.revision[0] = '*'; /* Matches anything */ #undef INQ_PAT DeviceCCB.cdm.num_patterns = 1; DeviceCCB.cdm.pattern_buf_len = sizeof(struct dev_match_result); DeviceCCB.cdm.patterns = &DeviceMatchPattern; /* * Allocate the buffer holding the matches. * We will allocate for 10 results and call * CAM multiple times if we have more results. */ paMatches = (struct dev_match_result *)RTMemAllocZ(10 * sizeof(struct dev_match_result)); if (paMatches) { DeviceCCB.cdm.num_matches = 0; DeviceCCB.cdm.match_buf_len = 10 * sizeof(struct dev_match_result); DeviceCCB.cdm.matches = paMatches; do { rc = RTFileIoCtl(FileXpt, CAMIOCOMMAND, &DeviceCCB, sizeof(union ccb), NULL); if (RT_FAILURE(rc)) { Log(("Error while querying available CD/DVD devices rc=%Rrc\n", rc)); break; } for (unsigned i = 0; i < DeviceCCB.cdm.num_matches; i++) { if (paMatches[i].type == DEV_MATCH_DEVICE) { /* We have the drive now but need the appropriate device node */ struct device_match_result *pDevResult = &paMatches[i].result.device_result; union ccb PeriphCCB; struct dev_match_pattern PeriphMatchPattern; struct dev_match_result aPeriphMatches[2]; struct periph_match_result *pPeriphResult = NULL; unsigned iPeriphMatch = 0; RT_ZERO(PeriphCCB); RT_ZERO(PeriphMatchPattern); RT_ZERO(aPeriphMatches); /* This time we only want the specific nodes for the device. */ PeriphCCB.ccb_h.func_code = XPT_DEV_MATCH; PeriphCCB.ccb_h.path_id = paMatches[i].result.device_result.path_id; PeriphCCB.ccb_h.target_id = paMatches[i].result.device_result.target_id; PeriphCCB.ccb_h.target_lun = paMatches[i].result.device_result.target_lun; /* Setup the pattern */ PeriphMatchPattern.type = DEV_MATCH_PERIPH; PeriphMatchPattern.pattern.periph_pattern.path_id = paMatches[i].result.device_result.path_id; PeriphMatchPattern.pattern.periph_pattern.target_id = paMatches[i].result.device_result.target_id; PeriphMatchPattern.pattern.periph_pattern.target_lun = paMatches[i].result.device_result.target_lun; PeriphMatchPattern.pattern.periph_pattern.flags = PERIPH_MATCH_PATH | PERIPH_MATCH_TARGET | PERIPH_MATCH_LUN; PeriphCCB.cdm.num_patterns = 1; PeriphCCB.cdm.pattern_buf_len = sizeof(struct dev_match_result); PeriphCCB.cdm.patterns = &PeriphMatchPattern; PeriphCCB.cdm.num_matches = 0; PeriphCCB.cdm.match_buf_len = sizeof(aPeriphMatches); PeriphCCB.cdm.matches = aPeriphMatches; do { rc = RTFileIoCtl(FileXpt, CAMIOCOMMAND, &PeriphCCB, sizeof(union ccb), NULL); if (RT_FAILURE(rc)) { Log(("Error while querying available periph devices rc=%Rrc\n", rc)); break; } for (iPeriphMatch = 0; iPeriphMatch < PeriphCCB.cdm.num_matches; iPeriphMatch++) { if ( (aPeriphMatches[iPeriphMatch].type == DEV_MATCH_PERIPH) && (!strcmp(aPeriphMatches[iPeriphMatch].result.periph_result.periph_name, "cd"))) { pPeriphResult = &aPeriphMatches[iPeriphMatch].result.periph_result; break; /* We found the periph device */ } } if (iPeriphMatch < PeriphCCB.cdm.num_matches) break; } while ( (DeviceCCB.ccb_h.status == CAM_REQ_CMP) && (DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE)); if (pPeriphResult) { char szPath[RTPATH_MAX]; char szDesc[256]; RTStrPrintf(szPath, sizeof(szPath), "/dev/%s%d", pPeriphResult->periph_name, pPeriphResult->unit_number); /* Remove trailing white space. */ strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.vendor, sizeof(pDevResult->inq_data.vendor)); strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.product, sizeof(pDevResult->inq_data.product)); dvdCreateDeviceString(pDevResult->inq_data.vendor, pDevResult->inq_data.product, szDesc, sizeof(szDesc)); pList->push_back(DriveInfo(szPath, "", szDesc)); if (pfSuccess) *pfSuccess = true; } } } } while ( (DeviceCCB.ccb_h.status == CAM_REQ_CMP) && (DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE)); RTMemFree(paMatches); } else rc = VERR_NO_MEMORY; RTFileClose(FileXpt); } return rc; }