Partager via


Les services Win32 interagissent avec les appareils

Un service Win32 idéal installé via INF AddService qui interagit avec les appareils se comporte de la même manière qu’un pilote interagit avec les appareils. Un pilote est chargé et déchargé en fonction de la présence d’un appareil, et un service Win32 qui interagit avec les appareils doit suivre ce même modèle de démarrage et d’arrêt en fonction de la présence d’un appareil.

Les services doivent démarrer uniquement lorsqu’une interface d’appareil est présente et activée pour interagir avec et s’arrêter lorsque l’interface de l’appareil n’est plus activée. Ce modèle de conception garantit un service robuste qui réduit le comportement non souhaité et non défini. Nous allons découvrir comment un service doit être conçu pour suivre ce modèle.

Installation du service

Pour installer le service, utilisez la directive AddService INF . Cela vous permettra de créer et de démarrer le service.

Ajoutez le paramètre qui permet au service de démarrer la demande. Pour ce faire, définissez StartType=0x3 qui permet au déclencheur de service de démarrer.

La dernière étape de cette section consiste à utiliser la directive AddTrigger pour que le service démarre à l’arrivée d’une interface d’appareil (voir AddService pour plus d’informations sur AddTrigger). Voici un exemple de la façon dont AddTrigger doit être utilisé :

[UserSvc_Install]
ServiceType   = 0x10 ; SERVICE_WIN32_OWN_PROCESS
StartType     = 3    ; SERVICE_DEMAND_START
ErrorControl  = 0    ; SERVICE_ERROR_IGNORE
ServiceBinary = %13%\oemsvc.exe
AddTrigger    = UserSvc_AddTrigger

[UserSvc_AddTrigger]
TriggerType = 1                           ; SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL
Action      = 1                           ; SERVICE_TRIGGER_ACTION_SERVICE_START
SubType     = %GUID_DEVINTERFACE_OSRFX2%  ; Interface class GUID
DataItem    = 2, "USB\VID_0547&PID_1002"  ; SERVICE_TRIGGER_DATA_TYPE_STRING

Notez que le HardwareId spécifié dans DataItem est facultatif et généralement nécessaire uniquement lors de l’utilisation d’une interface de classe générique pour étendre le déclencheur à un appareil plus spécifique.

Runtime du service

Du point de vue du runtime, la première étape de votre service doit consister à s’inscrire aux notifications d’interface d’appareil. Vous trouverez des conseils prescriptifs sur la façon d’y parvenir sur cette page : Inscription pour notification de l’arrivée de l’interface d’appareil et de suppression d’appareil.

En particulier, vous devez utiliser CM_Register_Notification avec l’indicateur CM_NOTIFY_FILTERY_TYPE_DEVICEINTERFACE pour effectuer l’inscription appropriée des notifications d’interface d’appareil.

Notes

Lorsqu’un service démarre, vous ne pouvez pas compter sur le fait que vous recevrez des notifications d’interface de l’appareil, car la notification d’arrivée est peut-être déjà passée, en particulier si une arrivée d’interface d’appareil est à l’origine du démarrage du service. Au lieu de cela, vous devez obtenir la liste des interfaces d’appareil à case activée s’il existe déjà des interfaces.

Une fois que vous vous êtes inscrit pour recevoir des notifications pour les interfaces d’appareil, vous serez informé de l’activation de nouvelles interfaces d’appareil ou de la désactivation des interfaces d’appareil existantes. Vous pouvez découvrir le chemin d’interface de l’appareil à partir du rappel de notification. Pour interroger la liste des interfaces d’appareil existantes afin d’examiner les interfaces d’appareil qui existaient avant le début du service et inscrites pour les notifications, vous pouvez obtenir une liste d’interfaces d’appareil via des API telles que CM_Get_Device_Interface_List.

Notes

Il est possible que l’interface de l’appareil arrive entre l’inscription aux notifications et la récupération d’une liste d’interfaces d’appareil déjà sur le système. Dans ce cas, l’interface de l’appareil est répertoriée à la fois dans le rappel de notification et dans la liste des interfaces d’appareil.

Si vous souhaitez interagir avec l’interface de l’appareil avec les API d’E/S, une fois que vous avez trouvé l’interface de l’appareil souhaitée, ouvrez un handle à l’interface via CreateFile.

L’étape suivante consiste à s’inscrire aux notifications secondaires par handle pour être averti des modifications d’état apportées à l’appareil, telles que les tentatives de suppression de l’appareil ou la suppression de l’appareil. Pour ce faire, utilisez CM_Register_Notification avec l’indicateur CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE . En suivant les instructions de l’inscription à la notification de l’arrivée et de la suppression de l’interface d’appareil, vous serez sûr que lorsqu’un appareil disparaît, le handle peut être libéré en conséquence.

Les arrivées et suppressions de l’interface d’appareil doivent être suivies afin que la suppression de la dernière interface d’appareil avec laquelle le service peut vouloir interagir signifie que le service peut être arrêté. Une fois la dernière interface supprimée, arrêtez votre service (vous trouverez des informations détaillées sur cette page). Pour ce faire, procédez comme suit :

  1. Publier l’état SERVICE_STOP_PENDING sur SCM pour indiquer que le service est en panne

  2. Annuler/propre-up tout ce que le service utilisait

  3. Publier l’état SERVICE_STOP sur SCM pour terminer l’opération d’arrêt

Si le service est arrêté, veillez à case activée pour et à parcourir tous les handles ouverts existants sur les interfaces d’appareil (il n’y en a peut-être aucun) et propre-les.

L’interface de l’appareil peut revenir lors de l’installation de l’appareil, de l’activation/désactivation de l’appareil, de la réinsentation de l’appareil, du redémarrage du système ou pendant d’autres scénarios non répertoriés. Lorsque l’interface de l’appareil revient, le service est déclenché en fonction de son inscription au démarrage du déclencheur.

Ce flux garantit que le service démarre à l’arrivée d’une interface d’appareil et s’arrête lorsque la dernière interface d’appareil n’est plus présente.

Il existe un exemple sur GitHub qui explique comment un service peut tirer parti de ce flux d’événements. L’exemple se trouve ici : Exemple de service Win32.

En outre, vous trouverez une documentation utile sur AddTrigger sur la page AddService .