Retour à l'accueil

Désactivation de Xbox Series via GIP en C#

L'article analyse la désactivation programmatique du contrôleur Xbox Series via le protocole GIP. Du code C# est fourni pour l'accès à XboxGIP, la formation des commandes et la gestion des réponses. La solution s'intègre dans une utilitaire pour Steam Big Picture.

Protocole GIP : comment éteindre le contrôleur Xbox par programmation
Advertisement 728x90

Déconnexion logicielle des manettes Xbox Series via GIP : Plongée technique approfondie

Steam Big Picture est pratique pour jouer depuis le canapé mais présente des lacunes : il ne bascule pas la sortie audio, ne désactive pas le mode Nuit et ne déconnecte pas les manettes Xbox Series en quittant le mode. Un développeur a créé Big Picture Manager en C# pour automatiser ces tâches. L'application surveille le lancement de la fenêtre Steam Big Picture, change les périphériques audio, gère le registre Windows pour le mode Nuit et résout le problème des manettes.

Pour l'audio, un périphérique cible est défini à l'entrée, avec un retour à l'original à la sortie. Le mode Nuit est désactivé via une écriture directe dans le registre, avec restauration automatique.

Xbox Series : Connexion et tolérance aux pannes

La manette Xbox Series se connecte via Bluetooth, l'adaptateur sans fil Xbox (2,4 GHz) ou USB. Le problème de déconnexion est résolu en désactivant complètement le Bluetooth, mais ce n'est pas idéal. L'objectif est une déconnexion sélective via GIP (Game Input Protocol).

Google AdInline article slot

Microsoft a publié une documentation sur GameInput en 2024, unifiant XInput, DirectInput, Raw Input, HID et WinRT. GIP est un protocole de transport pour les périphériques de jeu. La commande Set Device State (0x04) fait passer un périphérique à l'état GIP Off.

Implémentation de l'accès à XboxGIP en C#

L'accès à l'interface s'ouvre via \\.\XboxGIP avec des permissions de lecture/écriture. Le code utilise P/Invoke pour kernel32.dll : CreateFileW, DeviceIoControl, ReadFile, WriteFile.

Exemple de code pour la réinitialisation et l'envoi de la commande de déconnexion :

Google AdInline article slot
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

public class XboxGipController
{
    private const uint GENERIC_READ = 0x80000000;
    private const uint GENERIC_WRITE = 0x40000000;
    private const uint FILE_SHARE_READ = 0x00000001;
    private const uint FILE_SHARE_WRITE = 0x00000002;
    private const uint OPEN_EXISTING = 3;
    private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;

    private const uint GIP_ADD_REENUMERATE_CALLER_CONTEXT = 0x40001CD0;

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern SafeFileHandle CreateFileW(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr lpSecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool DeviceIoControl(
        SafeFileHandle hDevice,
        uint dwIoControlCode,
        IntPtr lpInBuffer,
        uint nInBufferSize,
        IntPtr lpOutBuffer,
        uint nOutBufferSize,
        out uint lpBytesReturned,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool ReadFile(
        SafeFileHandle hFile,
        byte[] lpBuffer,
        uint nNumberOfBytesToRead,
        out uint lpNumberOfBytesRead,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool WriteFile(
        SafeFileHandle hFile,
        byte[] lpBuffer,
        uint nNumberOfBytesToWrite,
        out uint lpNumberOfBytesWritten,
        IntPtr lpOverlapped
    );

    // ... (reste du code ProcessGipMessage et ReenumerateGipControllers)
}

Séquence d'opération

  • Ouverture d'un handle vers \\.\XboxGIP.
  • Appel de DeviceIoControl avec GIP_ADD_REENUMERATE_CALLER_CONTEXT pour réinitialisation.
  • Formation du paquet de déconnexion :

- Octets 0-7 : Identifiant de la manette Xbox (0x7E 0xED 0x82 0xC6 0x8B 0xDA 0x00 0x00).

- Octet 8 : ID de commande (0x05).

- Octet 9 : Drapeaux (0x20).

Google AdInline article slot

- Octet 10 : Séquence (0x01).

- Octet 11 : Longueur de la charge utile (0x01).

- Octet 12 : Charge utile (0x04 pour Off).

  • Envoi via WriteFile.
  • Lecture de la réponse en boucle via ReadFile jusqu'à ERROR_NO_MORE_DATA (code 259).

Débogage et limitations

Le code fonctionne lorsqu'il est connecté via l'adaptateur sans fil Xbox. WriteFile peut échouer si le périphérique n'est pas prêt. ReadFile traite les messages GIP entrants pour analyse. Pour une déconnexion complète, un réglage précis des octets et une gestion d'état sont nécessaires.

  • Avantages de l'approche : Contrôle bas niveau sans bidouillage système.
  • Inconvénients : Dépendance à la documentation GIP, changements potentiels dans les mises à jour du pilote.
  • Recommandations : Tester sur Windows 10/11, surveiller Win32Exception.

Points clés à retenir

  • GameInput et GIP fournissent un accès unifié aux manettes Xbox Series.
  • La commande 0x04 dans Set Device State fait passer un périphérique à l'état Off.
  • P/Invoke en C# permet d'envoyer des paquets bruts via \\.\XboxGIP.
  • La réinitialisation via GIP_ADD_REENUMERATE_CALLER_CONTEXT est obligatoire avant les commandes.
  • L'approche n'est applicable que pour les adaptateurs sans fil, pas Bluetooth/USB.

— Editorial Team

Advertisement 728x90

Lire ensuite