You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

hidapi

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hidapi - cargo Package Compare versions

Comparing version
1.1.1
to
1.2.0
+1
-1
build.rs

@@ -45,3 +45,3 @@ // **************************************************************************

let avail_backends: [(&'static str, Box<Fn()>); 4] = [
let avail_backends: [(&'static str, Box<dyn Fn()>); 4] = [
(

@@ -48,0 +48,0 @@ "LINUX_STATIC_HIDRAW",

@@ -5,3 +5,3 @@ # This file is automatically @generated by Cargo.

name = "cc"
version = "1.0.36"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -11,7 +11,7 @@

name = "hidapi"
version = "1.1.1"
version = "1.2.0"
dependencies = [
"cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]

@@ -21,3 +21,3 @@

name = "libc"
version = "0.2.54"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"

@@ -27,8 +27,8 @@

name = "pkg-config"
version = "0.3.14"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a0c56216487bb80eec9c4516337b2588a4f2a2290d72a1416d930e4dcdb0c90d"
"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"

@@ -15,3 +15,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "hidapi"
version = "1.1.1"
version = "1.2.0"
authors = ["Roland Ruckerbauer <roland.rucky@gmail.com>", "Osspial <osspial@gmail.com>", "Artyom Pavlov <newpavlov@gmail.com>", "mberndt123", "niklasad1"]

@@ -18,0 +18,0 @@ build = "build.rs"

@@ -18,4 +18,16 @@ /****************************************************************************

Ok(api) => {
for device in api.devices() {
println!("{:#?}", device);
for device in api.device_list() {
println!(
"VID: {:04x}, PID: {:04x}, Serial: {}, Product name: {}",
device.vendor_id(),
device.product_id(),
match device.serial_number() {
Some(s) => s,
_ => "<COULD NOT FETCH>",
},
match device.product_string() {
Some(s) => s,
_ => "<COULD NOT FETCH>",
}
);
}

@@ -22,0 +34,0 @@ }

@@ -19,4 +19,3 @@ /****************************************************************************

let device_info = hidapi
.devices()
.iter()
.device_list()
.next()

@@ -26,3 +25,3 @@ .expect("No devices are available!")

println!("Opening device:\n {:#?}\n", device_info);
println!("Opening device:\n VID: {:04x}, PID: {:04x}\n", device_info.vendor_id(), device_info.product_id());

@@ -29,0 +28,0 @@ let device = device_info.open_device(&hidapi)?;

@@ -26,12 +26,10 @@ /****************************************************************************

let devices = api.devices();
let mut devices = api.device_list();
let dev_info = devices
.get(0)
.nth(0)
.expect("There is not a single hid device available");
println!("{:#?}", dev_info);
let dev = Rc::new(
api.open(dev_info.vendor_id, dev_info.product_id)
api.open(dev_info.vendor_id(), dev_info.product_id())
.expect("Can not open device"),

@@ -38,0 +36,0 @@ );

+210
-29

@@ -38,2 +38,5 @@ // **************************************************************************

// Allow use of deprecated items, we defined ourselfes...
#![allow(deprecated)]
extern crate libc;

@@ -94,3 +97,4 @@

pub struct HidApi {
devices: Vec<HidDeviceInfo>,
devices: Vec<HidDeviceInfo>, /* Deprecated */
device_list: Vec<DeviceInfo>,
_lock: Arc<HidApiLock>,

@@ -108,4 +112,7 @@ }

let device_list = unsafe { HidApi::get_hid_device_info_vector()? };
Ok(HidApi {
devices: unsafe { HidApi::get_hid_device_info_vector()? },
device_list: device_list.clone(),
devices: device_list.into_iter().map(|d| d.into()).collect(),
_lock: Arc::new(lock),

@@ -116,9 +123,11 @@ })

/// Refresh devices list and information about them (to access them use
/// `devices()` method)
/// `device_list()` method)
pub fn refresh_devices(&mut self) -> HidResult<()> {
self.devices = unsafe { HidApi::get_hid_device_info_vector()? };
let device_list = unsafe { HidApi::get_hid_device_info_vector()? };
self.device_list = device_list.clone();
self.devices = device_list.into_iter().map(|d| d.into()).collect();
Ok(())
}
unsafe fn get_hid_device_info_vector() -> HidResult<Vec<HidDeviceInfo>> {
unsafe fn get_hid_device_info_vector() -> HidResult<Vec<DeviceInfo>> {
let mut device_vector = Vec::with_capacity(8);

@@ -143,3 +152,6 @@

/// Returns list of objects containing information about connected devices
/// Returns vec of objects containing information about connected devices
///
/// Deprecated. Use `HidApi::device_list()` instead.
#[deprecated]
pub fn devices(&self) -> &Vec<HidDeviceInfo> {

@@ -149,2 +161,7 @@ &self.devices

/// Returns iterator containing information about attached HID devices.
pub fn device_list(&self) -> impl Iterator<Item = &DeviceInfo> {
self.device_list.iter()
}
/// Open a HID device using a Vendor ID (VID) and Product ID (PID).

@@ -201,10 +218,12 @@ ///

/// Converts a pointer to a `wchar_t` to a optional string
unsafe fn wchar_to_string(wstr: *const wchar_t) -> HidResult<Option<String>> {
/// Converts a pointer to a `*const wchar_t` to a WcharString.
unsafe fn wchar_to_string(wstr: *const wchar_t) -> WcharString {
if wstr.is_null() {
return Ok(None);
return WcharString::None;
}
let mut char_vector: Vec<char> = Vec::with_capacity(8);
let mut raw_vector: Vec<wchar_t> = Vec::with_capacity(8);
let mut index: isize = 0;
let mut invalid_char = false;

@@ -215,25 +234,33 @@ let o = |i| *wstr.offset(i);

use std::char;
char_vector.push(match char::from_u32(o(index) as u32) {
Some(ch) => ch,
None => Err(HidError::FromWideCharError {
wide_char: o(index),
})?,
});
raw_vector.push(*wstr.offset(index));
if !invalid_char {
if let Some(c) = char::from_u32(o(index) as u32) {
char_vector.push(c);
} else {
invalid_char = true;
}
}
index += 1;
}
Ok(Some(char_vector.into_iter().collect()))
if !invalid_char {
WcharString::String(char_vector.into_iter().collect())
} else {
WcharString::Raw(raw_vector)
}
}
/// Convert the CFFI `HidDeviceInfo` struct to a native `HidDeviceInfo` struct
unsafe fn conv_hid_device_info(src: *mut ffi::HidDeviceInfo) -> HidResult<HidDeviceInfo> {
Ok(HidDeviceInfo {
unsafe fn conv_hid_device_info(src: *mut ffi::HidDeviceInfo) -> HidResult<DeviceInfo> {
Ok(DeviceInfo {
path: CStr::from_ptr((*src).path).to_owned(),
vendor_id: (*src).vendor_id,
product_id: (*src).product_id,
serial_number: wchar_to_string((*src).serial_number)?,
serial_number: wchar_to_string((*src).serial_number),
release_number: (*src).release_number,
manufacturer_string: wchar_to_string((*src).manufacturer_string)?,
product_string: wchar_to_string((*src).product_string)?,
manufacturer_string: wchar_to_string((*src).manufacturer_string),
product_string: wchar_to_string((*src).product_string),
usage_page: (*src).usage_page,

@@ -245,4 +272,23 @@ usage: (*src).usage,

#[derive(Clone)]
enum WcharString {
String(String),
Raw(Vec<wchar_t>),
None,
}
impl Into<Option<String>> for WcharString {
fn into(self) -> Option<String> {
match self {
WcharString::String(s) => Some(s),
_ => None,
}
}
}
/// Storage for device related information
///
/// Deprecated. Use `HidApi::device_list()` instead.
#[derive(Debug, Clone)]
/// Storage for device related information
#[deprecated]
pub struct HidDeviceInfo {

@@ -261,2 +307,136 @@ pub path: CString,

/// Device information. Use accessors to extract information about Hid devices.
///
/// Note: Methods like `serial_number()` may return None, if the conversion to a
/// String failed internally. You can however access the raw hid representation of the
/// string by calling `serial_number_raw()`
#[derive(Clone)]
pub struct DeviceInfo {
path: CString,
vendor_id: u16,
product_id: u16,
serial_number: WcharString,
release_number: u16,
manufacturer_string: WcharString,
product_string: WcharString,
usage_page: u16,
usage: u16,
interface_number: i32,
}
impl DeviceInfo {
pub fn path(&self) -> &CStr {
&self.path
}
pub fn vendor_id(&self) -> u16 {
self.vendor_id
}
pub fn product_id(&self) -> u16 {
self.product_id
}
/// Try to call `serial_number_raw()`, if None is returned.
pub fn serial_number(&self) -> Option<&str> {
match self.serial_number {
WcharString::String(ref s) => Some(s),
_ => None,
}
}
pub fn serial_number_raw(&self) -> Option<&[wchar_t]> {
match self.serial_number {
WcharString::Raw(ref s) => Some(s),
_ => None,
}
}
pub fn release_number(&self) -> u16 {
self.release_number
}
/// Try to call `manufacturer_string_raw()`, if None is returned.
pub fn manufacturer_string(&self) -> Option<&str> {
match self.manufacturer_string {
WcharString::String(ref s) => Some(s),
_ => None,
}
}
pub fn manufacturer_string_raw(&self) -> Option<&[wchar_t]> {
match self.manufacturer_string {
WcharString::Raw(ref s) => Some(s),
_ => None,
}
}
/// Try to call `product_string_raw()`, if None is returned.
pub fn product_string(&self) -> Option<&str> {
match self.product_string {
WcharString::String(ref s) => Some(s),
_ => None,
}
}
pub fn product_string_raw(&self) -> Option<&[wchar_t]> {
match self.product_string {
WcharString::Raw(ref s) => Some(s),
_ => None,
}
}
pub fn usage_page(&self) -> u16 {
self.usage_page
}
pub fn usage(&self) -> u16 {
self.usage
}
pub fn interface_number(&self) -> i32 {
self.interface_number
}
/// Use the information contained in `DeviceInfo` to open
/// and return a handle to a [HidDevice](struct.HidDevice.html).
///
/// By default the device path is used to open the device.
/// When no path is available, then vid, pid and serial number are used.
/// If both path and serial number are not available, then this function will
/// fail with [HidError::OpenHidDeviceWithDeviceInfoError](enum.HidError.html#variant.OpenHidDeviceWithDeviceInfoError).
///
/// Note, that opening a device could still be done using [HidApi::open()](struct.HidApi.html#method.open) directly.
pub fn open_device(&self, hidapi: &HidApi) -> HidResult<HidDevice> {
if self.path.as_bytes().len() != 0 {
hidapi.open_path(self.path.as_c_str())
} else if let Some(ref sn) = self.serial_number() {
hidapi.open_serial(self.vendor_id, self.product_id, sn)
} else {
Err(HidError::OpenHidDeviceWithDeviceInfoError {
device_info: Box::new(self.clone().into()),
})
}
}
}
impl Into<HidDeviceInfo> for DeviceInfo {
fn into(self) -> HidDeviceInfo {
HidDeviceInfo {
path: self.path,
vendor_id: self.vendor_id,
product_id: self.product_id,
serial_number: match self.serial_number {
WcharString::String(s) => Some(s),
_ => None,
},
release_number: self.release_number,
manufacturer_string: match self.manufacturer_string {
WcharString::String(s) => Some(s),
_ => None,
},
product_string: match self.product_string {
WcharString::String(s) => Some(s),
_ => None,
},
usage_page: self.usage_page,
usage: self.usage,
interface_number: self.interface_number,
}
}
}
impl HidDeviceInfo {

@@ -327,5 +507,6 @@ /// Use the information contained in `HidDeviceInfo` to open

message: unsafe {
wchar_to_string(ffi::hid_error(self._hid_device))
.map_err(|e| HidError::HidApiErrorEmptyWithCause { cause: Box::new(e) })?
.ok_or(HidError::HidApiErrorEmpty)?
match wchar_to_string(ffi::hid_error(self._hid_device)) {
WcharString::String(s) => s,
_ => return Err(HidError::HidApiErrorEmpty),
}
},

@@ -450,3 +631,3 @@ })

let res = self.check_size(res)?;
unsafe { wchar_to_string(buf[..res].as_ptr()) }
unsafe { Ok(wchar_to_string(buf[..res].as_ptr()).into()) }
}

@@ -465,3 +646,3 @@

let res = self.check_size(res)?;
unsafe { wchar_to_string(buf[..res].as_ptr()) }
unsafe { Ok(wchar_to_string(buf[..res].as_ptr()).into()) }
}

@@ -480,3 +661,3 @@

let res = self.check_size(res)?;
unsafe { wchar_to_string(buf[..res].as_ptr()) }
unsafe { Ok(wchar_to_string(buf[..res].as_ptr()).into()) }
}

@@ -496,4 +677,4 @@

let res = self.check_size(res)?;
unsafe { wchar_to_string(buf[..res].as_ptr()) }
unsafe { Ok(wchar_to_string(buf[..res].as_ptr()).into()) }
}
}

Sorry, the diff of this file is not supported yet