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; }
nsresult sbWinGetDevInterfaceDetail(PSP_DEVICE_INTERFACE_DETAIL_DATA* aDevIfDetailData, HDEVINFO aDevInfo, SP_DEVINFO_DATA* aDevInfoData, const GUID* aGUID) { // Validate arguments. NS_ENSURE_ARG_POINTER(aDevIfDetailData); NS_ENSURE_ARG_POINTER(aDevInfoData); NS_ENSURE_ARG_POINTER(aGUID); // Function variables. BOOL success; // Get the device interface data for the requested device and interface GUID. SP_DEVICE_INTERFACE_DATA devIfData; ZeroMemory(&devIfData, sizeof(SP_DEVICE_INTERFACE_DATA)); devIfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); success = SetupDiEnumDeviceInterfaces(aDevInfo, aDevInfoData, aGUID, 0, &devIfData); if (!success) return NS_ERROR_NOT_AVAILABLE; // Get the required size of the device interface detail data. DWORD size = 0; success = SetupDiGetDeviceInterfaceDetailW(aDevInfo, &devIfData, NULL, 0, &size, NULL); if (!success) { NS_ENSURE_TRUE(GetLastError() == ERROR_INSUFFICIENT_BUFFER, NS_ERROR_FAILURE); } NS_ENSURE_TRUE(size > 0, NS_ERROR_FAILURE); // Allocate the device interface detail data record and set it up for // auto-disposal. PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData; devIfDetailData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(NS_Alloc(size)); NS_ENSURE_TRUE(devIfDetailData, NS_ERROR_OUT_OF_MEMORY); sbAutoNSMemPtr autoDevIfDetailData(devIfDetailData); // Get the device interface details. devIfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); success = SetupDiGetDeviceInterfaceDetailW(aDevInfo, &devIfData, devIfDetailData, size, NULL, NULL); NS_ENSURE_SUCCESS(success, NS_ERROR_FAILURE); // Return results. *aDevIfDetailData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(autoDevIfDetailData.forget()); return NS_OK; }
nsresult sbWinGetDevDetail(PSP_DEVICE_INTERFACE_DETAIL_DATA* aDevIfDetailData, SP_DEVINFO_DATA* aDevInfoData, HDEVINFO aDevInfo, const GUID* aGUID, DWORD aDevIndex) { // Validate arguments. NS_ENSURE_ARG_POINTER(aDevIfDetailData); NS_ENSURE_ARG_POINTER(aDevInfoData); NS_ENSURE_ARG_POINTER(aGUID); // Function variables. BOOL success; // Set up to get the device interface detail data. If not successful, there's // no more device interfaces to enumerate. SP_DEVICE_INTERFACE_DATA devIfData; ZeroMemory(&devIfData, sizeof(SP_DEVICE_INTERFACE_DATA)); devIfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); success = SetupDiEnumDeviceInterfaces(aDevInfo, NULL, aGUID, aDevIndex, &devIfData); if (!success) return NS_ERROR_NOT_AVAILABLE; // Get the required size of the device interface detail data. DWORD size = 0; success = SetupDiGetDeviceInterfaceDetailW(aDevInfo, &devIfData, NULL, 0, &size, NULL); NS_ENSURE_TRUE(size > 0, NS_ERROR_FAILURE); // Allocate the device interface detail data record and set it up for // auto-disposal. PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(size); NS_ENSURE_TRUE(devIfDetailData, NS_ERROR_OUT_OF_MEMORY); sbAutoMemPtr<SP_DEVICE_INTERFACE_DETAIL_DATA> autoDevIfDetailData(devIfDetailData); devIfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Get the device interface details. ZeroMemory(aDevInfoData, sizeof(SP_DEVINFO_DATA)); aDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); success = SetupDiGetDeviceInterfaceDetailW(aDevInfo, &devIfData, devIfDetailData, size, NULL, aDevInfoData); NS_ENSURE_SUCCESS(success, NS_ERROR_FAILURE); // Return results. *aDevIfDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) autoDevIfDetailData.forget(); return NS_OK; }