-
Notifications
You must be signed in to change notification settings - Fork 0
/
deviceenumerator.zig
80 lines (67 loc) · 2.56 KB
/
deviceenumerator.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const std = @import("std");
const app = @import("app.zig");
const HidDevice = @import("hiddevice.zig");
const w = @import("win32.zig");
const Self = @This();
guid: w.GUID,
handle: w.HDEVINFO,
currentDeviceNr: u32,
interfaceData: w.SP_DEVICE_INTERFACE_DATA,
pub fn init() Self {
var hidguid: w.GUID = undefined;
w.HidD_GetHidGuid(&hidguid);
return Self{
.guid = hidguid,
.handle = w.SetupDiGetClassDevsW(
&hidguid,
null,
null,
w.DIGCF_DEVICEINTERFACE | w.DIGCF_PRESENT,
),
.currentDeviceNr = 0,
.interfaceData = .{ .cbSize = @sizeOf(w.SP_DEVICE_INTERFACE_DATA), .InterfaceClassGuid = undefined, .Flags = 0, .Reserved = undefined },
};
}
pub fn deinit(self: *Self) void {
_ = w.SetupDiDestroyDeviceInfoList(self.handle);
}
pub fn moveNext(self: *Self) bool {
defer self.currentDeviceNr += 1;
return w.SetupDiEnumDeviceInterfaces(self.handle, null, &self.guid, self.currentDeviceNr, &self.interfaceData) == w.TRUE;
}
pub fn getDevice(self: *Self) ?*HidDevice {
var detailDataSize: u32 = 0;
_ = w.SetupDiGetDeviceInterfaceDetailW(self.handle, &self.interfaceData, null, detailDataSize, &detailDataSize, null);
const detailDataBuf = app.allocator.alignedAlloc(u8, 8, detailDataSize) catch {
return null;
};
defer app.allocator.free(detailDataBuf);
var detailData = std.mem.bytesAsValue(w.SP_DEVICE_INTERFACE_DETAIL_DATA_W, detailDataBuf);
detailData.cbSize = w.SP_DEVICE_INTERFACE_DETAIL_DATA_W.SizeOf;
if (w.SetupDiGetDeviceInterfaceDetailW(self.handle, &self.interfaceData, detailData, detailDataSize, &detailDataSize, null) == w.FALSE) {
return null;
}
const path: [*c]u16 = @ptrCast(&detailData.DevicePath[0]);
const file = w.CreateFileW(path, w.GENERIC_READ | w.GENERIC_WRITE, w.FILE_SHARE_READ | w.FILE_SHARE_WRITE, null, w.OPEN_EXISTING, 0, null);
if (file == w.INVALID_HANDLE_VALUE) {
return null;
}
defer _ = w.CloseHandle(file);
var attributes = std.mem.zeroes(w.HIDD_ATTRIBUTES);
attributes.Size = w.HIDD_ATTRIBUTES.SizeOf;
if (w.HidD_GetAttributes(file, &attributes) == 0) {
return null;
}
var serial_buf: [128:0]u16 = undefined;
const serial: [*c]u16 = @ptrCast(&serial_buf[0]);
if (w.HidD_GetSerialNumberString(file, serial, serial_buf.len) == w.FALSE) {
serial_buf[0] = 0;
}
const d = HidDevice.init(
attributes.VendorID,
attributes.ProductID,
std.mem.span(path),
std.mem.span(serial),
) catch null;
return d;
}