Esempio n. 1
0
            public SixaxisDevice(string path, Kernel32.SafeObjectHandle handle, int index) : base(path, handle, index)
            {
                DeviceType = DualShockDeviceType.DualShock3;
                //
                // Remote MAC address is encoded in path as InstanceId
                // This is a lazy approach but saves an I/O request ;)
                //
                ClientAddress = PhysicalAddress.Parse(path.Substring(path.LastIndexOf('&') + 1, 12));

                //
                // Initialize default output report native buffer
                //
                FillMemory(OutputReportBuffer, OutputReportBufferSize, 0);
                Marshal.Copy(HidOutputReport, 0, OutputReportBuffer, HidOutputReport.Length);

                //
                // Crude way to assign device index as LED number
                //
                if (index >= 0 && index < 4)
                {
                    Marshal.WriteByte(OutputReportBuffer, 11, _ledOffsets[index]);
                }

                //
                // Send the start command to remote device
                //
                var unmanagedBuffer = Marshal.AllocHGlobal(_hidEnableCommand.Length);

                Marshal.Copy(_hidEnableCommand, 0, unmanagedBuffer, _hidEnableCommand.Length);

                try
                {
                    var ret = handle.OverlappedDeviceIoControl(
                        IOCTL_BTHPS3_HID_CONTROL_WRITE,
                        unmanagedBuffer,
                        _hidEnableCommand.Length,
                        IntPtr.Zero,
                        0,
                        out _
                        );

                    if (!ret)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(unmanagedBuffer);
                }

                SendHidCommand(OutputReportBuffer, OutputReportBufferSize);
            }
Esempio n. 2
0
        private void InvertedCallSupplierWorker(object cancellationToken)
        {
            Policy.Handle <Win32Exception>().Retry(3,
                                                   (exception, i, ctx) =>
            {
                Log.Error("Inverted Call Thread died with exception {@Exception}, trying to restart...", exception);
            }).Execute(() =>
            {
                var token = (CancellationToken)cancellationToken;

                var invertedCallSize   = Marshal.SizeOf <HidGuardianGetCreateRequest>();
                var invertedCallBuffer = Marshal.AllocHGlobal(invertedCallSize);

                var authCallSize   = Marshal.SizeOf <HidGuardianSetCreateRequest>();
                var authCallBuffer = Marshal.AllocHGlobal(authCallSize);

                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        // Create random value to match request/response pair
                        var requestId = (uint)_randGen.Next();

                        // Craft inverted call packet
                        Marshal.StructureToPtr(
                            new HidGuardianGetCreateRequest
                        {
                            Size      = (uint)invertedCallSize,
                            RequestId = requestId
                        },
                            invertedCallBuffer, false);

                        // Send inverted call (this will block until the driver receives an open request)
                        var ret = _deviceHandle.OverlappedDeviceIoControl(
                            IoctlHidguardianGetCreateRequest,
                            invertedCallBuffer,
                            invertedCallSize,
                            invertedCallBuffer,
                            invertedCallSize,
                            out var _);

                        if (!ret)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Get back modified values from driver
                        var request = Marshal.PtrToStructure <HidGuardianGetCreateRequest>(invertedCallBuffer);

                        // Invoke open permission request so we know what to do next
                        var eventArgs =
                            new OpenPermissionRequestedEventArgs(ExtractHardwareIds(request), (int)request.ProcessId);
                        OpenPermissionRequested?.Invoke(this, eventArgs);

                        // Craft authentication request packet
                        Marshal.StructureToPtr(
                            new HidGuardianSetCreateRequest
                        {
                            RequestId   = request.RequestId,
                            DeviceIndex = request.DeviceIndex,
                            IsAllowed   = eventArgs.IsAllowed,
                            IsSticky    = eventArgs.IsPermanent
                        },
                            authCallBuffer, false);

                        // This request will dequeue the pending request and either complete it successfully or fail it
                        ret = _deviceHandle.OverlappedDeviceIoControl(
                            IoctlHidguardianSetCreateRequest,
                            authCallBuffer,
                            authCallSize,
                            authCallBuffer,
                            authCallSize,
                            out var _);

                        if (!ret)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(invertedCallBuffer);
                }
            });
        }