Message d’erreur lorsque vous insérez une carte à puce dans un lecteur sur un ordinateur basé sur Windows Server 2008 R2 ou Windows 7: « logiciel de pilote de périphérique n’a pas été installée »

IMPORTANT : Cet article est issu d'une traduction automatique réalisée par un logiciel Microsoft et non par un traducteur professionnel. Cette traduction automatique a pu aussi être révisée par la communauté Microsoft grâce à la technologie Community Translation Framework (CTF). Pour en savoir plus sur cette technologie, veuillez consulter la page http://support.microsoft.com/gp/machine-translation-corrections/fr. Microsoft vous propose en effet des articles traduits par des professionnels, des articles issus de traductions automatiques et des articles issus de traductions automatiques révisées par la communauté Microsoft, de manière à ce que vous ayez accès à tous les articles de notre Base de connaissances dans votre langue. Il est important de noter que les articles issus de la traduction automatique, y compris ceux révisés par la communauté Microsoft, peuvent contenir des erreurs de vocabulaire, de syntaxe ou de grammaire. Microsoft ne pourra être tenu responsable des imprécisions, erreurs, ainsi que de tout dommage résultant d’une traduction incorrecte du contenu ou de son utilisation par les clients.

La version anglaise de cet article est la suivante: 976832
Symptômes
Lorsque vous insérez une carte à puce dans un lecteur de carte à puce, Windows essaie de télécharger et d’installer la minidrivers de carte à puce de la carte via les services Plug-and-Play. Si le pilote de la carte à puce n’est pas disponible pour les emplacements préconfigurés, tels que Windows Update, WSUS ou chemins d’accès de l’intranet, et un fournisseur de services de chiffrement personnalisé n’est pas déjà installé sur le système, le message d’erreur suivant s’affiche dans la zone de notification :
Pilote logiciel de périphérique n’a pas été installé avec succès
Pour plus d’informations, cliquez ici.
Ce message d’erreur disparaît après quelques secondes.

En outre, dans le Gestionnaire de périphériques, sous autres périphériques, le périphérique de carte à puce a le statut « Fnd » (pilote introuvable).

Cela nécessite souvent l’utilisateur obtenir un des éléments suivants à partir de l’émetteur de la carte à puce pour résoudre cette erreur :
  1. Un minipilote de carte à puce au logo Windows
  2. Un fournisseur personnalisé de services de chiffrement (CSP) pour la carte à puce.
  3. Un minipilote de carte non logoed Windows
  4. Autre middleware comme un contrôle ActiveX, logiciel de PKCS #11 ou autres logiciels personnalisés.
Toutefois, si l’utilisateur est fourni avec un seul élément 3 ou 4 de cette liste, la carte à puce continue à fonctionner sur le système. Toutefois, l’utilisateur recevra le message d’erreur qui est mentionné dans cette section chaque fois qu’ils insèrent la carte à puce.

Ce problème affecte toutes les versions de Windows 7, Windows Server 2008 R2 et dans les versions ultérieures de ces deux systèmes d’exploitation.
Cause
Toutes les cartes à puce nécessitent un logiciel supplémentaire pour fonctionner sous Windows, à moins qu'il existe un pilote dans la boîte qui permette à l'utilisateur d'utiliser la carte sans installer de logiciel supplémentaire. L'infrastructure de la carte à puce de Windows a été améliorée dans Windows 7 pour activer le téléchargement automatique de minidrivers de carte à puce à partir de Windows Update ou à partir d'autres emplacements similaires, tel qu'un serveur WSUS lorsque la carte à puce est insérée dans le lecteur. Toutes les cartes à puce qui passent avec succès les impératifs du logo, publié par le programme de Logo Windows, bénéficier de cette fonction.

Toutefois, si le logiciel nécessaire pour utiliser une carte à puce dans Windows n’est pas logoed ou est d’un type qui diffère d’un minipilote, par exemple un pilote PKCS #11, un fournisseur de services cryptographiques personnalisé, middleware ou un contrôle ActiveX, le téléchargement automatique option échoue parce que Microsoft ne certifie que les minidrivers de carte à puce. Par conséquent, si l’utilisateur insère une carte pour laquelle un fournisseur de services cryptographiques personnalisé n’est pas déjà inscrit, l’utilisateur reçoit un message d’erreur indiquant que le logiciel du pilote est manquant pour le périphérique de carte à puce, même si l’utilisateur peut utiliser la carte à puce par le biais des logiciels supplémentaires qui a été installé sur l’ordinateur de l’utilisateur à partir d’une installation personnalisée.
Résolution
Bien que les cartes à puce continuent de fonctionner malgré le message d’erreur que l’utilisateur voit, un émetteur de carte à puce, le fournisseur ou le fabricant peut utiliser une des méthodes suivantes pour résoudre cette erreur.

Implémenter un minipilote de carte à puce

Nous recommandons que les sociétés émettrices de cartes, les fournisseurs et les fabricants implémentent minidrivers de carte à puce et participent au programme Logo Windows pour tirer parti des améliorations introduites dans la plate-forme de carte à puce Plug-and-Play, Device Stage pour cartes à puce, et ainsi de suite.

Pour plus d’informations sur les spécifications de minipilote de carte à puce pour Windows, visitez le site Web de Microsoft à l’adresse suivante : Pour plus d’informations sur la façon de se familiariser avec le processus d’obtention d’un logo pour votre minidrivers de carte à puce, visitez le site Web Windows Logo Program :

Mettre en œuvre un pilote nul pour votre carte à puce

Si le logiciel personnalisé tel un pilote PKCS #11, un contrôle ActiveX ou certaines autre middleware est nécessaire pour permettre l’utilisation de cartes à puce sous Windows, et l’implémentation d’un minipilote de carte à puce ou d’un fournisseur de services cryptographiques personnalisé n’est pas une option pratique, nous recommandons de sociétés émettrices de cartes, des fournisseurs ou des fabricants mette envoi NULL de pilotes à Windows Update. Le processus classique pour s’assurer qu’un pilote nul est disponible sur Windows Update nécessite une soumission réussie de périphérique non classifié par Winqual. Si, à l’avenir, un minipilote est disponible pour ces cartes, le nouveau pilote peut être téléchargé pour la mise à jour de Windows en participant au programme de Logo Windows. Les pilotes NULL peuvent ensuite être téléchargés manuellement par les utilisateurs finaux ou peuvent accessibles à l’aide de mises à jour facultatives.

Voici un exemple de modèle d’un pilote nul pour une carte à puce.
;; Null Driver for Fabrikam Smartcard installation x86 and x64 package.;[Version]Signature="$Windows NT$"Class=SmartCardClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391}Provider=%ProviderName%CatalogFile=delta.catDriverVer=4/21/2006,1.0.0.0[Manufacturer]%ProviderName%=Minidriver,NTamd64,NTamd64.6.1,NTx86,NTx86.6.1[Minidriver.NTamd64];This driver has no applicability on OS versions earlier than Windows 7[Minidriver.NTx86];This driver has no applicability on OS versions earlier than Windows 7[Minidriver.NTamd64.6.1]%CardDeviceName%=Minidriver64_Install,<DEVICE_ID>;%CardDeviceName%=Minidriver64_Install,<DEVICE_ID2>;%CardDeviceName%=Minidriver64_Install,<DEVICE_ID3>;...[Minidriver.NTx86.6.1]%CardDeviceName%=Minidriver32_Install,<DEVICE_ID>;%CardDeviceName%=Minidriver32_Install,<DEVICE_ID2>;%CardDeviceName%=Minidriver32_Install,<DEVICE_ID3>;...;Leave the following sections blank[DefaultInstall][DefaultInstall.ntamd64][DefaultInstall.NTx86][DefaultInstall.ntamd64.6.1][DefaultInstall.NTx86.6.1][Minidriver64_Install.NT][Minidriver64_61_Install.NT][Minidriver32_Install.NT][Minidriver32_61_Install.NT][Minidriver64_61_Install.NT.Services]AddService = ,2[Minidriver32_61_Install.NT.Services]AddService = ,2; =================== Generic ==================================[Strings]ProviderName ="Microsoft"CardDeviceName="Fabrikam Generic Smart card"
Pour générer l’ID de périphérique matériel qui est référencé par la chaîne DEVICE_ID dans l’exemple, suivez les instructions fournies dans la spécification de la carte à puce du minipilote. Pour ce faire, visitez le site Web de Microsoft à l'adresse suivante :

Pour obtenir des informations détaillées sur l’envoi d’un pilote nul pour Microsoft, veuillez contacter le Support technique de Microsoft.

Désactiver la carte à puce Plug-and-Play via la stratégie de groupe pour les ordinateurs gérés

Cette option est recommandée uniquement pour les déploiements d’entreprise où les ordinateurs sont gérés par les administrateurs et tous les logiciels nécessaires pour travailler avec les cartes à puce qui sont utilisés dans l’entreprise sont installé à l’aide des outils de gestion de logiciels tels que SMS.

Cette procédure est vivement déconseillée dans les environnements suivants car cela affectera toutes les cartes à puce dans votre environnement :
  • Déploiements commerciales qui ciblent les utilisateurs finaux, tels que des services bancaires en ligne
  • Les environnements qui incluent les deux Plug and Play, cartes à puce et les cartes à puce non Plug-and-Play qui utilisent la stratégie de groupe pour désactiver le Plug-and-Play pour les cartes à puce
Carte à puce Plug-and-Play peut être complètement désactivé dans les entreprises où l’ordinateur de l’utilisateur final est gérée par les mécanismes de stratégie de groupe.

Si votre déploiement utilise uniquement des solutions de carte à puce de non-Plug-and-Play, carte à puce Plug-and-Play peut être désactivé par un administrateur local sur un ordinateur client. Désactivation de la carte à puce Plug-and-Play empêche le téléchargement des pilotes de la carte à puce, également connu sous le nom minidrivers de carte à puce. Il empêche également invites de carte à puce Plug-and-Play.

Pour désactiver la carte à puce Plug and Play dans la stratégie de groupe local, procédez comme suit :
  1. Cliquez sur Démarrer, type gpedit.msc dans la zone Rechercher les programmes et fichiers , puis appuyez sur ENTRÉE.
  2. Dans l'arborescence de la console, sous Configuration ordinateur, cliquez sur Modèles d'administration.
  3. Dans le volet de détails, double-cliquez sur Composants Windows, puis double-cliquez sur carte à puce.
  4. Cliquez sur Activer le service de carte à puce Plug-and-Play, puis cliquez sur Modifier.
  5. Cliquez sur désactivé, puis cliquez sur OK.

Modifier le système de l’utilisateur final et de désactiver la carte à puce Plug and Play pour les cartes spécifiques

Cette option est la moins recommandée. Vous devez utiliser cette option uniquement si les cartes sont hérités et ne sont pas prévu d’implémenter minidrivers de carte à puce à l’avenir. Cette option nécessite que le logiciel existant qui est déjà installé sur le système de notification Windows qu’il y a un fournisseur de services cryptographiques personnalisé installé sur le système, même si aucun CSP de ce type n’existe sur le système de l’utilisateur final. Dès que Windows détermine qu’il y a un fournisseur de services cryptographiques personnalisé déjà installé sur le système, Windows ne tente pas de télécharger et d’installer un pilote par le biais de cartes à puce Plug-and-Play. Aucun nœud de périphérique pour le périphérique de carte à puce n’est visible dans le Gestionnaire de périphériques est créé. Cette option entraîne les modifications suivantes au Registre système :

Sous-clé :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\<Smart card name>
Entrées de la sous-clé de Registre :
  • ATR = DWORD hexadécimale : délimitée par des virgules ATR de la carte à puce.
  • ATRMask = DWORD hexadécimale : masque à appliquer à la RAR permet de masquer des octets non significatifs de la RAR de délimitée par des virgules.
  • Fournisseur de chiffrement = valeur de chaîne : une chaîne à votre carte à puce.
Par exemple :
Sous-clé :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\Fabrikam ATM card
Entrées de la sous-clé de Registre :
  • ATR = DWORD hexadécimale: 3 b, dc, 13, 00, 40, 3 a, 49, 54, 47, 5f, 4D, 53, 43, 53, 50, 5f, 56, 32
  • ATRMask = DWORD hexadécimale: ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff
  • Fournisseur de chiffrement = valeur de la chaîne: « Fournisseur de Fabrikam ATM factice »
Pour les systèmes de x64 bits, identiques doivent être modifiés sous la sous-clé suivante :
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards


Nous recommandons que, au lieu de modifier directement le Registre du système, vous utilisez WinSCard APIs d’introduire ces modifications au système. Voici un exemple de code qui détecte l’insertion de la carte à puce et puis désactive la carte à puce Plug and Play de la carte spécifique en créant une entrée de Registre qui associe la fiche d’un fournisseur non existant.

Microsoft fournit des exemples de programmation à titre d'illustration uniquement, sans garantie expresse ou implicite. Ceci inclut, mais n'est pas limité à, les garanties implicites de qualité marchande ou d'adéquation à un usage particulier. Cet article suppose que vous êtes familiarisé avec le langage de programmation présenté et les outils utilisés pour créer et déboguer des procédures. Les ingénieurs du support technique Microsoft peuvent aider à expliquer la fonctionnalité d'une procédure particulière. Toutefois, ils ne modifieront pas ces exemples pour fournir des fonctionnalités supplémentaires ou créer des procédures répondant à vos besoins spécifiques.
//==============================================================;////  Disable Smart card Plug and Play for specific cards////  Abstract://      This is an example of how to create a new//      Smart Card Database entry when a smart card is inserted//      into the computer.////  This source code is only intended as a supplement to existing Microsoft//  documentation.////  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY//  KIND, EITHER EXPRESSED OR IMPLIED. THIS INCLUDES BUT NOT LIMITED TO THE//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR//  PURPOSE.////  Copyright (C) Microsoft Corporation.  All Rights Reserved.////==============================================================;// This code must be compiled with UNICODE support to work correctly#ifndef UNICODE#define UNICODE#endif#include <windows.h>#include <winscard.h>#include <stdio.h>#include <strsafe.h>#include <rpc.h>// Change this prefix to specify what the beginning of the// introduced card name in the registry will be. This is// be prepended to a GUID value.#define CARD_NAME_PREFIX    L"MyCustomCard"// This is the name that will be provided as the CSP for // the card when introduced to the system. This is provided// in order to disable Smart Card Plug and Play for this// card.#define CARD_CSP            L"$DisableSCPnP$"// This special reader name is used to be notified when// a reader is added to or removed from the system through// SCardGetStatusChange.#define PNP_READER_NAME     L"\\\\?PnP?\\Notification"// Maximum ATR length plus alignment bytes. This value is// used in the SCARD_READERSTATE structure#define MAX_ATR_LEN         36LONG GenerateCardName(    __deref_out LPWSTR  *ppwszCardName){    LONG        lReturn = NO_ERROR;    HRESULT     hr = S_OK;    DWORD       cchFinalString = 0;    WCHAR       wszCardNamePrefix[] = CARD_NAME_PREFIX;    LPWSTR      pwszFinalString = NULL;    UUID        uuidCardGuid = {0};    RPC_WSTR    pwszCardGuid = NULL;    RPC_STATUS  rpcStatus = RPC_S_OK;    // Parameter check    if (NULL == ppwszCardName)    {        wprintf(L"Invalid parameter in GenerateCardName.\n");        return ERROR_INVALID_PARAMETER;    }    // Generate GUID    rpcStatus = UuidCreate(&uuidCardGuid);    if (RPC_S_OK != rpcStatus)    {        wprintf(L"Failed to create new GUID with error 0x%x.\n");        lReturn = (DWORD)rpcStatus;    }    else    {        // Convert GUID to string        rpcStatus = UuidToString(&uuidCardGuid, &pwszCardGuid);        if (RPC_S_OK != rpcStatus)        {            wprintf(L"Failed to convert new GUID to string with error 0x%x.\n", rpcStatus);            lReturn = (DWORD)rpcStatus;        }        else        {            // Allocate memory for final string            // Template is <prefix>-<guid>            cchFinalString = (DWORD)(wcslen(wszCardNamePrefix) + 1 + wcslen((LPWSTR)pwszCardGuid) + 1);            pwszFinalString = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cchFinalString * sizeof(WCHAR));            if (NULL == pwszFinalString)            {                wprintf(L"Out of memory.\n");                lReturn = ERROR_OUTOFMEMORY;            }            else            {                // Create final string                hr = StringCchPrintf(                            pwszFinalString,                            cchFinalString,                            L"%s-%s",                            wszCardNamePrefix,                            pwszCardGuid);                if (FAILED(hr))                {                    wprintf(L"Failed to create card name with error 0x%x.\n", hr);                    lReturn = (DWORD)hr;                }                else                {                    // Set output params                    *ppwszCardName = pwszFinalString;                    pwszFinalString = NULL;                }            }        }    }    if (NULL != pwszCardGuid)    {        RpcStringFree(&pwszCardGuid);    }    if (NULL != pwszFinalString)    {        HeapFree(GetProcessHeap(), 0, pwszFinalString);    }    return lReturn;}LONG IntroduceCardATR(    __in SCARDCONTEXT   hSC,    __in LPBYTE         pbAtr,    __in DWORD          cbAtr){    LONG    lReturn = NO_ERROR;    LPWSTR  pwszCardName = NULL;        // Parameter checks    if (NULL == hSC || NULL == pbAtr || 0 == cbAtr)    {        wprintf(L"Invalid parameter in IntroduceCardATR.\n");        return ERROR_INVALID_PARAMETER;    }    // Generate a name for the card    lReturn = GenerateCardName(&pwszCardName);    if (NO_ERROR != lReturn)    {        wprintf(L"Failed to generate card name with error 0x%x.\n", lReturn);    }    else    {        // Introduce the card to the system        lReturn = SCardIntroduceCardType(                                hSC,                                pwszCardName,                                NULL,                                NULL,                                0,                                pbAtr,                                NULL,                                cbAtr);        if (SCARD_S_SUCCESS != lReturn)        {            wprintf(L"Failed to introduce card '%s' to system with error 0x%x.\n", pwszCardName, lReturn);        }        else        {            // Set the provider name            lReturn = SCardSetCardTypeProviderName(                                        hSC,                                        pwszCardName,                                        SCARD_PROVIDER_CSP,                                        CARD_CSP);            if (SCARD_S_SUCCESS != lReturn)            {                wprintf(L"Failed to set CSP for card '%s' with error 0x%x.\n", pwszCardName, lReturn);            }            else            {                wprintf(L"Card '%s' has been successfully introduced to the system and has had Plug and Play disabled.\n", pwszCardName);            }        }    }    if (NULL != pwszCardName)    {        HeapFree(GetProcessHeap(), 0, pwszCardName);    }    return lReturn;}LONG ProcessCard(    __in SCARDCONTEXT           hSC,    __in LPSCARD_READERSTATE    pRdr){    LONG        lReturn = NO_ERROR;    DWORD       dwActiveProtocol = 0;    DWORD       cbAtr = MAX_ATR_LEN;    DWORD       dwIndex = 0;    DWORD       cchCards = SCARD_AUTOALLOCATE;    LPWSTR      pmszCards = NULL;    BYTE        rgbAtr[MAX_ATR_LEN] = {0};    SCARDHANDLE hSCard = NULL;    // Parameter checks    if (NULL == hSC || NULL == pRdr)    {        wprintf(L"Invalid parameter in ProcessCard.\n");        return ERROR_INVALID_PARAMETER;    }    // Connect to the card in the provided reader in shared mode    lReturn = SCardConnect(                    hSC,                    pRdr->szReader,                    SCARD_SHARE_SHARED,                    SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,                    &hSCard,                    &dwActiveProtocol);    if (SCARD_S_SUCCESS != lReturn)    {        wprintf(L"Failed to connect to card in reader '%s' with error 0x%x.\n", pRdr->szReader, lReturn);    }    else    {        wprintf(L"Connected to card in reader '%s'.\n", pRdr->szReader);        /*         * In this spot, put any necessary calls needed to identify that this         * is the type of card you are looking for. Usually this is done via         * SCardTransmit calls. For this example, we will grab the ATR of every         * inserted card.         */        // Obtain the ATR of the inserted card        lReturn = SCardGetAttrib(                            hSCard,                            SCARD_ATTR_ATR_STRING,                            rgbAtr,                            &cbAtr);        if (SCARD_S_SUCCESS != lReturn)        {            wprintf(L"Failed to obtain ATR of card in reader '%s' with error 0x%x.\n", pRdr->szReader, lReturn);        }        else        {            // Output the ATR            wprintf(L"ATR of card in reader '%s':", pRdr->szReader);            for (dwIndex = 0; dwIndex < cbAtr; dwIndex++)            {                wprintf(L" %02x", rgbAtr[dwIndex]);            }            wprintf(L"\n");            // Determine if the ATR is already in the Smart Card Database            lReturn = SCardListCards(                                hSC,                                rgbAtr,                                NULL,                                0,                                (LPWSTR)&pmszCards,                                &cchCards);            if (SCARD_S_SUCCESS != lReturn)            {                wprintf(L"Failed to determine if card in reader '%s' is currently recognized by the system with error 0x%x. Skipping.\n", pRdr->szReader, lReturn);            }            else if (NULL == pmszCards || 0 == *pmszCards)            {                // Card not found. We need to add it.                wprintf(L"Card in reader '%s' is not currently recognized by the system. Adding ATR.\n", pRdr->szReader);                lReturn = IntroduceCardATR(                                    hSC,                                     rgbAtr,                                     cbAtr);                // If an error occurs here, we will continue so we can try the next time                // the card is inserted as well as examine other readers.            }            else            {                wprintf(L"Card in reader '%s' is already known by the system. Not adding ATR.\n", pRdr->szReader);            }        }    }    // Disconnect from the card. We do not need to reset it.    if (NULL != hSCard)    {        SCardDisconnect(hSCard, SCARD_LEAVE_CARD);    }    // Free resources    if (NULL != pmszCards)    {        SCardFreeMemory(hSC, pmszCards);    }    return lReturn;}LONG MonitorReaders(        __in SCARDCONTEXT hSC){    LPWSTR              pwszReaders = NULL;    LPWSTR              pwszOldReaders = NULL;    LPWSTR              pwszRdr = NULL;    DWORD               dwRet = ERROR_SUCCESS;    DWORD               cchReaders = SCARD_AUTOALLOCATE;    DWORD               dwRdrCount = 0;    DWORD               dwOldRdrCount = 0;    DWORD               dwIndex = 0;    LONG                lReturn = NO_ERROR;    BOOL                fDone = FALSE;    SCARD_READERSTATE   rgscState[MAXIMUM_SMARTCARD_READERS+1] = {0};    SCARD_READERSTATE   rgscOldState[MAXIMUM_SMARTCARD_READERS+1] = {0};    LPSCARD_READERSTATE pRdr = NULL;    // Parameter check    if (NULL == hSC)    {        wprintf(L"Invalid parameter in MonitorReaders.\n");        return ERROR_INVALID_PARAMETER;    }    // One of the entries for monitoring will be to detect new readers    // The first time through the loop will be to detect whether    // the system has any readers.    rgscState[0].szReader = PNP_READER_NAME;    rgscState[0].dwCurrentState = SCARD_STATE_UNAWARE;    dwRdrCount = 1;    while (!fDone)    {        while (!fDone)        {            // Wait for status changes to occur            wprintf(L"Monitoring for changes.\n");            lReturn = SCardGetStatusChange(                                    hSC,                                    INFINITE,                                    rgscState,                                    dwRdrCount);            switch (lReturn)            {                case SCARD_S_SUCCESS:                    // Success                    break;                case SCARD_E_CANCELLED:                    // Monitoring is being cancelled                    wprintf(L"Monitoring cancelled. Exiting.\n");                    fDone = TRUE;                    break;                default:                    // Error occurred                    wprintf(L"Error 0x%x occurred while monitoring reader states.\n", lReturn);                    fDone = TRUE;                    break;            }            if (!fDone)            {                // Examine the status change for each reader, skipping the PnP notification reader                for (dwIndex = 1; dwIndex < dwRdrCount; dwIndex++)                {                    pRdr = &rgscState[dwIndex];                    // Determine if a card is now present in the reader and                    // it can be communicated with.                    if ((pRdr->dwCurrentState & SCARD_STATE_EMPTY ||                         SCARD_STATE_UNAWARE == pRdr->dwCurrentState) &&                        pRdr->dwEventState & SCARD_STATE_PRESENT &&                        !(pRdr->dwEventState & SCARD_STATE_MUTE))                    {                        // A card has been inserted and is available.                        // Grab its ATR for addition to the database.                        wprintf(L"A card has been inserted into reader '%s'. Grabbing its ATR.\n", pRdr->szReader);                        lReturn = ProcessCard(hSC, pRdr);                        // If an error occurs here, we will continue so we can try the next time                        // the card is inserted as well as examine other readers.                    }                    // Save off the new state of the reader                    pRdr->dwCurrentState = pRdr->dwEventState;                }                // Now see if the number of readers in the system has changed.                // Save its new state as the current state for the next loop.                pRdr = &rgscState[0];                pRdr->dwCurrentState = pRdr->dwEventState;                if (pRdr->dwEventState & SCARD_STATE_CHANGED)                {                    wprintf(L"Reader change detected.\n");                    break;                }            }           }        if (!fDone)        {            // Clean up previous loop            if (NULL != pwszOldReaders)            {                SCardFreeMemory(hSC, pwszOldReaders);                pwszOldReaders = NULL;            }            pwszReaders = NULL;            cchReaders = SCARD_AUTOALLOCATE;                        // Save off PnP notification reader state and and list of readers previously found in the system            memcpy_s(&rgscOldState[0], sizeof(SCARD_READERSTATE), &rgscState[0], sizeof(SCARD_READERSTATE));            memset(rgscState, 0, sizeof(rgscState));            dwOldRdrCount = dwRdrCount;            pwszOldReaders = pwszReaders;                        // Obtain a list of all readers in the system            wprintf(L"Building reader list.\n");            lReturn = SCardListReaders(                                hSC,                                NULL,                                (LPWSTR)&pwszReaders,                                &cchReaders);            switch (lReturn)            {                case SCARD_S_SUCCESS:                    // Success                    break;                case SCARD_E_NO_READERS_AVAILABLE:                    // No readers in the system. This is OK.                    lReturn = SCARD_S_SUCCESS;                    break;                default:                    // Error occurred                    wprintf(L"Failed to obtain list of readers with error 0x%x.\n", lReturn);                    fDone = TRUE;                    break;            }            // Build the reader list for monitoring - NULL indicates end-of-list            // First entry is the PnP Notification entry.            pRdr = rgscState;            memcpy_s(&rgscState[0], sizeof(SCARD_READERSTATE), &rgscOldState[0], sizeof(SCARD_READERSTATE));            pRdr++;            pwszRdr = pwszReaders;            while ((NULL != pwszRdr) && (0 != *pwszRdr))            {                BOOL fFound = FALSE;                dwRdrCount++;                // Look for an existing reader state from a previous loop                for (dwIndex = 1; dwIndex < dwOldRdrCount; dwIndex++)                {                    if ((lstrlen(pwszRdr) == lstrlen(rgscOldState[dwIndex].szReader)) &&                        (0 == lstrcmpi(pwszRdr, rgscOldState[dwIndex].szReader)))                    {                        // Found a match. Copy it.                        memcpy_s(pRdr, sizeof(SCARD_READERSTATE), &rgscOldState[dwIndex], sizeof(SCARD_READERSTATE));                        fFound = TRUE;                        break;                    }                }                if (!fFound)                {                    // New reader                    pRdr->szReader = pwszRdr;                    pRdr->dwCurrentState = SCARD_STATE_UNAWARE;                }                // Increment reader indices                pRdr++;                pwszRdr += lstrlen(pwszRdr)+1;            }        }    }    // Clean up resources    if (NULL != pwszReaders)    {        SCardFreeMemory(hSC, pwszReaders);    }    if (NULL != pwszOldReaders)    {        SCardFreeMemory(hSC, pwszOldReaders);    }    return lReturn;}LONG __cdecl main(        VOID){    DWORD               dwRet = ERROR_SUCCESS;    SCARDCONTEXT        hSC = NULL;    LONG                lReturn = NO_ERROR;    HANDLE              hStartedEvent = NULL;    // Get handle to event that will be signaled when the Smart Card Service is available    hStartedEvent = SCardAccessStartedEvent();    // Wait for the Smart Card Service to become available    dwRet = WaitForSingleObject(hStartedEvent, INFINITE);    if (WAIT_OBJECT_0 != dwRet)    {        wprintf(L"Wait for Smart Card Service failed with error 0x%x.\n", dwRet);        lReturn = dwRet;    }    else    {        // Establish a system-level context with the Smart Card Service        lReturn = SCardEstablishContext(                                SCARD_SCOPE_SYSTEM,                                NULL,                                NULL,                                &hSC);        if (SCARD_S_SUCCESS != lReturn)        {            wprintf(L"Failed to establish context with the Smart Card Service with error 0x%x.\n", lReturn);        }        else        {            // Begin monitoring the readers in the system            // This routine could be done in a separate thread so it can be cancelled via SCardCancel().            lReturn = MonitorReaders(hSC);        }    }       // Cleanup resources    if (NULL != hSC)    {        SCardReleaseContext(hSC);    }    if (NULL != hStartedEvent)    {        SCardReleaseStartedEvent();    }    wprintf(L"Done.\n");    return lReturn;}
Références
Pour plus d’informations sur la résolution des problèmes de carte à puce Plug-and-Play, consultez l’article TechNet suivant :
Guide de dépannage de carte à puce Plug and Play
http://technet.Microsoft.com/en-us/library/dd979536 (ws.10).aspx
Carte à puce du win2008R2 plugnplay PnP win7

Avertissement : Cet article a été traduit automatiquement.

Propriétés

ID d'article : 976832 - Dernière mise à jour : 06/11/2016 08:23:00 - Révision : 8.0

Windows Server 2008 R2 Datacenter, Windows Server 2008 R2 Enterprise, Windows Server 2008 R2 Standard, Windows 7 Entreprise, Windows 7 Édition Familiale Basique, Windows 7 Édition Familiale Premium, Windows 7 Professionnel, Windows 7 Édition Starter, Windows 7 Édition Integrale

  • kbsmartcard kbcodesnippet kbtshoot kbexpertiseinter kbsurveynew kbprb kbmt KB976832 KbMtfr
Commentaires