Skip to content

Commit

Permalink
Remove elevated rights and device enabling-disabling
Browse files Browse the repository at this point in the history
  • Loading branch information
dancol90 committed Aug 22, 2021
1 parent 1634d10 commit ed6e9ae
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 120 deletions.
5 changes: 0 additions & 5 deletions Source/HidLibrary/HidDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,6 @@ public bool WriteFeatureData(byte[] data)
return success;
}

public bool SetState(bool enabled)
{
return HidDevices.SetDeviceState(_devicePath, enabled);
}

protected static void EndRead(IAsyncResult ar)
{
var hidAsyncState = (HidAsyncState)ar.AsyncState;
Expand Down
71 changes: 7 additions & 64 deletions Source/HidLibrary/HidDevices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,69 +47,13 @@ public static IEnumerable<HidDevice> Enumerate(int vendorId)
return EnumerateDevices().Select(x => new HidDevice(x.Path, x.Description)).Where(x => x.Attributes.VendorId == vendorId);
}

public static bool SetDeviceState(string interfacePath, bool state)
{
var iface = EnumerateDevicesInterfaces(false)
.Where(ei =>
{
var devicePath = GetDevicePath(ei.DeviceInfoSet, ei.DeviceInterfaceData);
return devicePath.ToLower() == interfacePath.ToLower();
})
.FirstOrDefault();

if (iface == null)
return false;

var header = new NativeMethods.SP_CLASSINSTALL_HEADER();
header.cbSize = (int)Marshal.SizeOf(header);
header.InstallFunction = NativeMethods.DIF_PROPERTYCHANGE;

var propchangeparams = new NativeMethods.SP_PROPCHANGE_PARAMS
{
ClassInstallHeader = header,
StateChange = state ? NativeMethods.DICS_ENABLE : NativeMethods.DICS_DISABLE,
Scope = NativeMethods.DICS_FLAG_GLOBAL,
HwProfile = 0
};

NativeMethods.SetupDiSetClassInstallParams(iface.DeviceInfoSet, ref iface.DeviceInfoData, ref propchangeparams, (UInt32)Marshal.SizeOf(propchangeparams));

if (Marshal.GetLastWin32Error() != 0)
return false;

NativeMethods.SetupDiChangeState(iface.DeviceInfoSet, ref iface.DeviceInfoData);

if (Marshal.GetLastWin32Error() != 0)
return false;

return true;
}

public class DeviceInfo { public string Path { get; set; } public string Description { get; set; } }

internal class DeviceInterfaceInfo
{
internal IntPtr DeviceInfoSet;
internal NativeMethods.SP_DEVINFO_DATA DeviceInfoData;
internal NativeMethods.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
internal int DeviceInterfaceIndex;
}

public static IEnumerable<DeviceInfo> EnumerateDevices()
{
return EnumerateDevicesInterfaces().Select(ei => {
var devicePath = GetDevicePath(ei.DeviceInfoSet, ei.DeviceInterfaceData);
var description = GetBusReportedDeviceDescription(ei.DeviceInfoSet, ref ei.DeviceInfoData) ??
GetDeviceDescription(ei.DeviceInfoSet, ref ei.DeviceInfoData);
return new DeviceInfo { Path = devicePath, Description = description };
});
}

internal static IEnumerable<DeviceInterfaceInfo> EnumerateDevicesInterfaces(bool presentOnly = true)
{
var devices = new List<DeviceInfo>();
var hidClass = HidClassGuid;
var flags = NativeMethods.DIGCF_DEVICEINTERFACE | (presentOnly ? NativeMethods.DIGCF_PRESENT : 0);
var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref hidClass, null, 0, flags);
var deviceInfoSet = NativeMethods.SetupDiGetClassDevs(ref hidClass, null, 0, NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE);

if (deviceInfoSet.ToInt64() != NativeMethods.INVALID_HANDLE_VALUE)
{
Expand All @@ -127,16 +71,15 @@ internal static IEnumerable<DeviceInterfaceInfo> EnumerateDevicesInterfaces(bool
while (NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, ref deviceInfoData, ref hidClass, deviceInterfaceIndex, ref deviceInterfaceData))
{
deviceInterfaceIndex++;
yield return new DeviceInterfaceInfo {
DeviceInfoSet = deviceInfoSet,
DeviceInfoData = deviceInfoData,
DeviceInterfaceData = deviceInterfaceData,
DeviceInterfaceIndex = deviceInterfaceIndex
};
var devicePath = GetDevicePath(deviceInfoSet, deviceInterfaceData);
var description = GetBusReportedDeviceDescription(deviceInfoSet, ref deviceInfoData) ??
GetDeviceDescription(deviceInfoSet, ref deviceInfoData);
devices.Add(new DeviceInfo { Path = devicePath, Description = description });
}
}
NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
return devices;
}

private static NativeMethods.SP_DEVINFO_DATA CreateDeviceInfoData()
Expand Down
37 changes: 2 additions & 35 deletions Source/HidLibrary/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@ internal struct SECURITY_ATTRIBUTES
internal const short DIGCF_DEVICEINTERFACE = 0x10;
internal const int DIGCF_ALLCLASSES = 0x4;

internal const int DIF_PROPERTYCHANGE = 0x12;
internal const int DICS_ENABLE = 1;
internal const int DICS_DISABLE = 2; // disable device
internal const int DICS_FLAG_GLOBAL = 1; // not profile-specific

internal const int MAX_DEV_LEN = 1000;
internal const int MAX_DEV_LEN = 1000;
internal const int SPDRP_ADDRESS = 0x1c;
internal const int SPDRP_BUSNUMBER = 0x15;
internal const int SPDRP_BUSTYPEGUID = 0x13;
Expand Down Expand Up @@ -190,22 +185,6 @@ internal struct DEVPROPKEY
public ulong pid;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SP_CLASSINSTALL_HEADER
{
public int cbSize;
public int InstallFunction;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SP_PROPCHANGE_PARAMS
{
public SP_CLASSINSTALL_HEADER ClassInstallHeader;
public int StateChange;
public int Scope;
public int HwProfile;
}

internal static DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc =
new DEVPROPKEY { fmtid = new Guid(0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2), pid = 4 };

Expand Down Expand Up @@ -239,19 +218,7 @@ internal struct SP_PROPCHANGE_PARAMS
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static internal extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, IntPtr deviceInfoData);

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiSetClassInstallParams(
IntPtr deviceInfoSet,
[In] ref SP_DEVINFO_DATA deviceInfoData,
[In] ref SP_PROPCHANGE_PARAMS classInstallParams,
UInt32 ClassInstallParamsSize);

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetupDiChangeState(
IntPtr deviceInfoSet,
[In] ref SP_DEVINFO_DATA deviceInfoData);

[DllImport("user32.dll")]
[DllImport("user32.dll")]
static internal extern bool UnregisterDeviceNotification(IntPtr handle);

internal const short HIDP_INPUT = 0;
Expand Down
15 changes: 0 additions & 15 deletions Source/mi-360/MiGamepad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,10 @@ public void Stop()
_InputThread.Join();
}

public void DisableReEnableDevice()
{
_Logger.Information("Disabling gamepad {Device}", _Device);
if (!_Device.SetState(false))
_Logger.Error("Cannot disable device {Device}", _Device);

_Logger.Information("Enabling gamepad {Device}", _Device);
if (!_Device.SetState(true))
_Logger.Error("Cannot enable device {Device}", _Device);
}

private void DeviceWorker()
{
_Logger.Information("Starting worker thread for {Device}", _Device);

DisableReEnableDevice();

// Open HID device to read input from the gamepad
_Logger.Information("Opening HID device {Device}", _Device);
_Device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.Exclusive);
Expand Down Expand Up @@ -268,8 +255,6 @@ [19] MI button
_Logger.Information("Closing HID device {Device}", _Device);
_Device.CloseDevice();

DisableReEnableDevice();

_Logger.Information("Exiting worker thread for {0}", _Device.ToString());
Ended?.Invoke(this, EventArgs.Empty);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/mi-360/app.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
Rimuovere questo elemento se l'applicazione richiede questa virtualizzazione per
compatibilità con le versioni precedenti.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<!--<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />-->
</requestedPrivileges>
</security>
</trustInfo>
Expand Down

0 comments on commit ed6e9ae

Please sign in to comment.