nsresult sbWinDeviceHasInterface(DEVINST aDevInst, const GUID* aGUID, bool* aHasInterface) { // Validate arguments. NS_ENSURE_ARG_POINTER(aGUID); NS_ENSURE_ARG_POINTER(aHasInterface); // Function variables. nsresult rv; // Set default result. *aHasInterface = PR_FALSE; // Get the device info set and set it up for auto-disposal. nsAutoString deviceInstanceID; rv = sbWinGetDeviceInstanceID(aDevInst, deviceInstanceID); NS_ENSURE_SUCCESS(rv, rv); HDEVINFO devInfo = SetupDiGetClassDevsW(aGUID, deviceInstanceID.get(), NULL, DIGCF_DEVICEINTERFACE); NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE); sbAutoHDEVINFO autoDevInfo(devInfo); // Get the device info for the device instance. Device does not have the // interface if it does not have a device info data record. SP_DEVINFO_DATA devInfoData; rv = sbWinGetDevInfoData(aDevInst, devInfo, &devInfoData); if (NS_FAILED(rv)) return NS_OK; // Get the device interface detail. Device does not have the interface if it // does not have the interface detail. PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData; rv = sbWinGetDevInterfaceDetail(&devIfDetailData, devInfo, &devInfoData, aGUID); if (NS_FAILED(rv)) return NS_OK; sbAutoNSMemPtr autoDevIfDetailData(devIfDetailData); // Device has the interface. *aHasInterface = PR_TRUE; return NS_OK; }
nsresult sbWinGetDevicePath(DEVINST aDevInst, const GUID* aGUID, nsAString& aDevicePath) { // Validate arguments. NS_ENSURE_ARG_POINTER(aGUID); // Function variables. nsresult rv; // Get the device info set and set it up for auto-disposal. nsAutoString deviceInstanceID; rv = sbWinGetDeviceInstanceID(aDevInst, deviceInstanceID); NS_ENSURE_SUCCESS(rv, rv); HDEVINFO devInfo = SetupDiGetClassDevsW(aGUID, deviceInstanceID.get(), NULL, DIGCF_DEVICEINTERFACE); NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE); sbAutoHDEVINFO autoDevInfo(devInfo); // Get the device info for the device instance. SP_DEVINFO_DATA devInfoData; rv = sbWinGetDevInfoData(aDevInst, devInfo, &devInfoData); NS_ENSURE_SUCCESS(rv, rv); // Get the device interface detail data for the device instance. PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData; rv = sbWinGetDevInterfaceDetail(&devIfDetailData, devInfo, &devInfoData, aGUID); NS_ENSURE_SUCCESS(rv, rv); sbAutoNSMemPtr autoDevIfDetailData(devIfDetailData); // Return results. aDevicePath.Assign(devIfDetailData->DevicePath); return NS_OK; }
nsresult sbWinFindDevicesByStorageDevNum(STORAGE_DEVICE_NUMBER* aStorageDevNum, PRBool aMatchPartitionNumber, const GUID* aGUID, nsTArray<DEVINST>& aDevInstList) { // Validate arguments. NS_ENSURE_ARG_POINTER(aStorageDevNum); NS_ENSURE_ARG_POINTER(aGUID); // Function variables. nsresult rv; // Get the interface device class info and set up for auto-disposal. HDEVINFO devInfo = SetupDiGetClassDevsW(aGUID, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE); sbAutoHDEVINFO autoDevInfo(devInfo); // Search for device instances with a matching storage device number. aDevInstList.Clear(); DWORD devIndex = 0; while (1) { // Get the next device detail data and set it up for auto-disposal. PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData; SP_DEVINFO_DATA devInfoData; rv = sbWinGetDevDetail(&devIfDetailData, &devInfoData, devInfo, aGUID, devIndex++); if (rv == NS_ERROR_NOT_AVAILABLE) break; NS_ENSURE_SUCCESS(rv, rv); sbAutoMemPtr<SP_DEVICE_INTERFACE_DETAIL_DATA> autoDevIfDetailData(devIfDetailData); // Get the next storage device number. STORAGE_DEVICE_NUMBER storageDevNum; rv = sbWinGetStorageDevNum(devIfDetailData->DevicePath, &storageDevNum); if (NS_FAILED(rv)) continue; // Skip device instance if it doesn't match the target storage device // number. if (storageDevNum.DeviceType != aStorageDevNum->DeviceType) continue; if (storageDevNum.DeviceNumber != aStorageDevNum->DeviceNumber) continue; if (aMatchPartitionNumber && (storageDevNum.PartitionNumber != aStorageDevNum->PartitionNumber)) { continue; } // Add device instance to list. NS_ENSURE_TRUE(aDevInstList.AppendElement(devInfoData.DevInst), NS_ERROR_OUT_OF_MEMORY); } return NS_OK; }