Foutbericht bij het invoegen van een smartcard in lezer op een computer met Windows 7 of Windows Server 2008 R2: 'stuurprogramma is niet ge´nstalleerd'

Vertaalde artikelen Vertaalde artikelen
Artikel ID: 976832 - Bekijk de producten waarop dit artikel van toepassing is.
Alles uitklappen | Alles samenvouwen

Op deze pagina

Symptomen

Wanneer u een smartcard in een smartcardlezer plaatst, probeert Windows te downloaden en installeren van de smartcard-minidrivers voor kaart via Plug en Play-services. Als het stuurprogramma voor de smartcard niet beschikbaar op de vooraf geconfigureerde locaties zoals Windows Update, WSUS of intranet paden is en een aangepaste Crypto-provider is niet op het systeem is ge´nstalleerd, wordt het volgende foutbericht weergegeven in het systeemvak:
Stuurprogramma is niet ge´nstalleerd
Klik hier voor details.
Dit foutbericht verdwijnt na enkele seconden.

Bovendien in Apparaatbeheer onderAndere apparaten, het smartcard-apparaat heeft de status 'DNF' (stuurprogramma niet gevonden).

Vaak moet de gebruiker een van de volgende items ophalen van de verlener van de smartcard voor het oplossen:
  1. Een ministuurprogramma Windows logoed smartcard
  2. Een aangepaste cryptografieprovider (CSP) voor de smartcard.
  3. Een ministuurprogramma Windows smartcard niet logoed
  4. Andere middleware als een ActiveX-besturingselement, PKCS # 11 software of andere aangepaste software.
Echter, als de gebruiker met alleen artikel 3 of 4 van deze lijst, wordt de smartcard blijft werken op het systeem. Echter, ontvangt de gebruiker het foutbericht dat wordt vermeld in deze sectie telkens wanneer ze de smartcard plaatst.

Dit probleem geldt voor alle versies van Windows 7, Windows Server 2008 R2 en in latere versies van beide besturingssystemen.

Oorzaak

Alle smartcards vereist extra software werken in Windows, tenzij er een meegeleverd stuurprogramma waarmee de gebruiker de kaart gebruiken zonder extra software te installeren. Windows smartcard Framework is verbeterd in Windows 7 inschakelen op het automatisch downloaden van smartcard-minidrivers van Windows Update of andere soortgelijke locaties zoals een WSUS-server als de smartcard in de kaartlezer. Alle smartcards is de logovereisten, doorgeven zoals gepubliceerd door het Windows Logo Program profiteren van deze functie.

Echter, als de software die is vereist voor een smartcard gebruiken in Windows is logoed of type van een ministuurprogramma, zoals een stuurprogramma PKCS # 11, aangepaste CSP, middleware of een ActiveX-besturingselement verschilt, de optie automatisch downloaden mislukt omdat Microsoft alleen smartcard minidrivers verklaart. Als de gebruiker een kaart die een aangepaste CSP niet al is geregistreerd voegt, krijgt de gebruiker daarom een foutbericht dat aangeeft dat het stuurprogramma voor de smartcard apparaat ontbreekt, hoewel de smartcard via aanvullende software is ge´nstalleerd op de computer van de gebruiker van een aangepaste installatie kunt gebruiken.

Oplossing

Hoewel de smartcards werken ondanks het foutbericht de gebruiker blijven ziet, kunt een uitgever van smartcards, leverancier of fabrikant een van de volgende manieren oplossen.

Een ministuurprogramma smartcards implementeren

Raden kaart emittenten, leveranciers en fabrikanten smartcard minidrivers implementeren en deelnemen aan het Windows Logo Program om te profiteren van de verbeteringen die zijn ge´ntroduceerd in platform zoals smartcard Plug en Play Device Stage voor smartcards, enzovoort.

Bezoek de volgende Microsoft-website voor meer informatie over smartcard ministuurprogramma specificaties voor Windows:
http://www.Microsoft.com/whdc/Device/Input/smartcard/SC-minidriver.mspx
Bezoek de website Windows Logo-programma voor meer informatie over hoe te beginnen met het proces van het verkrijgen van een logo voor uw smartcard-minidrivers:
http://www.Microsoft.com/whdc/winlogo/default.mspx

Een NULL-stuurprogramma voor uw smartcard implementeren

Als aangepaste software PKCS # 11 stuurprogramma, een ActiveX-besturingselement of bepaalde middleware vereist het gebruik van smartcards voor Windows en uitvoering van een ministuurprogramma smartcard of een aangepaste CSP een praktische optie is, raadzaam dat emittenten kaart, leveranciers of fabrikanten overwegen NULL-stuurprogramma's aan Windows Update verzenden. De typische proces ervoor zorgen dat een NULL-stuurprogramma is beschikbaar op Windows Update vereist een succesvolle niet geclassificeerd apparaat indienen via Winqual. Als in de toekomst er een ministuurprogramma beschikbaar voor deze kaarten is, kunt nieuwe stuurprogramma uploaden naar Windows Update door deelname aan het Windows Logo Program. De NULL-stuurprogramma's kunnen vervolgens handmatig gedownload door de eindgebruikers of kunnen met optionele updates beschikbaar gesteld.

Hier volgt een voorbeeldsjabloon voor een NULL-stuurprogramma voor een smartcard.
;
; Null Driver for Fabrikam Smartcard installation x86 and x64 package.
;

[Version]
Signature="$Windows NT$"
Class=SmartCard
ClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391}
Provider=%ProviderName%
CatalogFile=delta.cat
DriverVer=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"
Volg de instructies in de smartcard ministuurprogramma specificatie voor het genereren van de hardware-apparaat-ID waarnaar wordt verwezen door de tekenreeks DEVICE_ID in het monster. Ga hiervoor naar de volgende Microsoft-website:
http://www.Microsoft.com/whdc/Device/Input/smartcard/SC-minidriver.mspx


Neem contact op met Microsoft Customer Support Services voor gedetailleerde informatie over het indienen van een NULL-stuurprogramma van Microsoft.

Smartcard Plug en Play via Groepsbeleid voor beheerde computers uitschakelen

Deze optie wordt alleen aanbevolen voor implementaties waar computers worden beheerd door beheerders en alle benodigde software werken met smartcards die worden gebruikt in de onderneming is ge´nstalleerd met hulpprogramma's voor software zoals SMS.

Deze procedure is in de volgende omgevingen sterk afgeraden omdat dit van invloed op de smartcards in uw omgeving:
  • CommerciŰle implementaties die eindgebruikers, zoals on line bankieren
  • Omgevingen die beide Play Plug en-smartcards en niet-Plug en Play-smartcards Groepsbeleid gebruiken om Plug en Play voor smartcards uitschakelen
Smartcard Plug en Play kan volledig worden uitgeschakeld in ondernemingen waar de computer van de eindgebruiker wordt beheerd door mechanismen zoals Groepsbeleid.

Als uw implementatie alleen niet-Plug en Play-smartcard oplossingen gebruikt, kan smartcard Plug en Play worden uitgeschakeld door een lokale beheerder op een clientcomputer. Smartcard Plug en Play uitschakelen voorkomt smartcard stuurprogramma's, ook bekend als smartcard minidrivers downloaden. Ook verhindert u dat Plug en Play-prompts smartcard.

Smartcard Plug en Play in lokaal groepsbeleid uitschakelen, als volgt:
  1. Klik opStart, typgpedit.mscin deZoeken naar programma's en bestandenhet vak en druk op ENTER.
  2. In de consolestructuur onderComputerconfiguratie, klik opBeheersjablonen.
  3. Dubbelklik in het detailvensterWindows-onderdelen, en dubbelklik vervolgens opSmartcard.
  4. Klik met de rechtermuisknopSmartcard Plug en Play-service inschakelen, en klik vervolgens opBewerken.
  5. Klik opUitgeschakeld, en klik vervolgens opOK.

Wijzigen van de eindgebruiker en smartcard Plug en Play voor specifieke kaarten uitschakelen

Dit is de minst aanbevolen optie. Gebruik deze optie alleen als de kaarten oudere kaarten en er geen plannen zijn om in toekomstige minidrivers smartcards implementeren. Deze optie is vereist dat de bestaande software al ge´nstalleerd op het systeem waarschuwen Windows is er een aangepaste CSP op het systeem is ge´nstalleerd, zelfs als geen dergelijke CSP op het systeem van de eindgebruiker bestaat. Als Windows vaststelt dat er een aangepaste CSP al op het systeem is ge´nstalleerd, probeert Windows niet te downloaden en installeren van een stuurprogramma via smartcard Plug en Play. Geen apparaatknooppunt voor de smartcard apparaat gemaakt dat wordt weergegeven in Apparaatbeheer. Deze optie resulteert in de volgende wijzigingen aan het register:

De subsleutel:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\<smart card="" name=""></smart>
Subsleutel registervermeldingen:
  • ATR hexadecimale DWORD =: komma ATR van de smartcard.
  • ATRMask = hexadecimale DWORD: komma masker toepassen ATR te verwaarlozen bytes in de ATR maskeren.
  • Cryptografieprovider = tekenreekswaarde: sommige tekenreeks die relevant zijn voor uw smartcard.
Bijvoorbeeld:
De subsleutel:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\Fabrikam ATM-kaart
Subsleutel registervermeldingen:
  • ATR hexadecimale DWORD =: 3b, dc, 13, 00, 40, 3.a, 49, 54, 47 5f 4 d, 53, 43, 53, 50, 5f, 56, 32
  • ATRMask = hexadecimale DWORD: ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff
  • Cryptografieprovider = tekenreeks: "fabrikam ATM Dummy Provider"
Voor x 64-bits systemen identieke wijzigingen moeten worden aangebracht onder de volgende subsleutel:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards


Het is raadzaam, in plaats van het register rechtstreeks wijzigen, WinSCard-API's te gebruiken introduceren van wijzigingen aan het systeem. Hier is sample codevoorbeeld detecteert smartcard invoeren en smartcard Plug en Play voor bepaalde kaart uitgeschakeld door een registervermelding de kaart aan een niet-bestaande provider koppelt maken.

Microsoft biedt programming voorbeelden ter illustratie, zonder expliciete of impliciete garantie. Dit omvat, maar is niet beperkt tot impliciete garanties van verkoopbaarheid of geschiktheid voor een bepaald doel. In dit artikel wordt ervan uitgegaan dat u bekend bent met de programmeertaal wordt aangetoond en de hulpmiddelen maken en procedures voor foutopsporing worden gebruikt. Ondersteuningstechnici van Microsoft kunt de functionaliteit van een bepaalde procedure uitgelegd. Zij zal deze voorbeelden om extra functionaliteit of procedures uw specifieke behoeften te bouwen echter niet wijzigen.
//==============================================================;
//
//  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         36

LONG 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;
}

Referenties

Zie de volgende TechNet-artikel voor meer informatie over het oplossen van problemen met Plug en Play smartcard:
Smartcard Plug en Play Troubleshooting Guide
http://technet.Microsoft.com/en-us/library/dd979536 (WS.10) .aspx

Eigenschappen

Artikel ID: 976832 - Laatste beoordeling: zaterdag 19 maart 2011 - Wijziging: 2.0
De informatie in dit artikel is van toepassing op:
Trefwoorden:á
kbsmartcard kbcodesnippet kbtshoot kbexpertiseinter kbsurveynew kbprb kbmt KB976832 KbMtnl
Automatisch vertaald artikel
BELANGRIJK: Dit artikel is vertaald door de vertaalmachine software van Microsoft in plaats van door een professionele vertaler. Microsoft biedt u professioneel vertaalde artikelen en artikelen vertaald door de vertaalmachine, zodat u toegang heeft tot al onze knowledge base artikelen in uw eigen taal. Artikelen vertaald door de vertaalmachine zijn niet altijd perfect vertaald. Deze artikelen kunnen fouten bevatten in de vocabulaire, zinsopbouw en grammatica en kunnen lijken op hoe een anderstalige de taal spreekt en schrijft. Microsoft is niet verantwoordelijk voor onnauwkeurigheden, fouten en schade ontstaan door een incorrecte vertaling van de content of het gebruik ervan door onze klanten. Microsoft past continue de kwaliteit van de vertaalmachine software aan door deze te updaten.
De Engelstalige versie van dit artikel is de volgende:976832

Geef ons feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com