Chybová zpráva při vložení karty smart card do čtecího zařízení v počítači se systémem Windows 7 nebo systémem Windows Server 2008 R2: "softwarový ovladač zařízení nebyl úspěšně nainstalován".

Překlady článku Překlady článku
ID článku: 976832 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Příznaky

Při vložení karty smart card do čtecího zařízení karty smart card, systém Windows se pokusí stáhnout a nainstalovat minidrivers karty smart card prostřednictvím služby Plug and Play. Pokud kdykoli předem místech, jako je například Windows Update, služby WSUS nebo cesty k intranetu, není k dispozici ovladač pro kartu smart card a vlastní šifrovací poskytovatel metadat již není v systému nainstalována, zobrazí se následující chybová zpráva v oznamovací oblast:
Software ovladače zařízení nebyl úspěšně nainstalován.
Klepnutím sem zobrazíte podrobnosti.
Tato chybová zpráva zmizí po několika sekundách.

Navíc ve Správci zařízení pod Další zařízení, zařízení karty Smart Card má stav "DNF" (ovladač nebyl nalezen).

To často vyžaduje, aby uživatel se vydavatel karet smart card k vyřešení této chyby získat jednu z následujících položek:
  1. Miniovladač logoed karty smart card systému Windows
  2. Vlastní poskytovatel metadat kryptografických (CSP) pro kartu Smart card.
  3. Miniovladač-logoed karty smart card systému Windows
  4. Ostatní middleware jako ovládací prvek ActiveX, PKCS # 11 nebo jiný vlastní software.
Však v případě, že uživatel je součástí pouze položky 3 nebo 4 z tohoto seznamu, karty smart card nadále pracovat v systému. Však uživatel obdrží chybovou zprávu, která je uvedena v této části při každém vložení karty smart card.

Tento problém se týká všechna vydání systému Windows Server 2008 R2, Windows 7 a novější obou operačních systémů.

Příčina

Všechny karty smart card vyžadují další software pro práci v systému Windows, pokud je ovladač Doručená pošta, který umožňuje uživateli používat karty bez instalace dalšího softwaru. V systému Windows 7 povolit automatické stahování karty smart card minidrivers z webu Windows Update nebo z jiných podobných umístění, jako je například WSUS server při vložení karty smart card do čtecího zařízení bylo lepší Windows Framework karty Smart Card. Čipové karty, které úspěšně projdou požadavky logo zveřejněné programu Windows Logo těžit z této funkce.

Však v případě, že software, který je vyžadován při použití karty smart card v systému Windows je logoed nebo typ, který se liší od miniovladač, jako je například ovladač PKCS # 11, vlastní zprostředkovatele kryptografických služeb, middleware nebo ovládací prvek ActiveX, na možnost automatické stažení se nezdaří, protože Microsoft potvrzuje pouze minidrivers karty smart card. Proto pokud uživatel vloží karty, jejíž vlastní zprostředkovatel kryptografických služeb není již registrován, uživatel obdrží chybovou zprávu, která uvádí, že je software ovladače pro zařízení karty smart card nebyl nalezen i přesto, že uživatel může použít kartu smart card pomocí dalšího softwaru, který byl nainstalován v počítači uživatele z vlastní instalace.

Řešení

Ačkoli karet smart card pokračovat v práci i přes chybovou zprávu, která se zobrazí uživateli, vydavatel karet smart card, prodejce nebo výrobce můžete použít jednu z následujících metod k vyřešení této chyby.

Implementovat miniovladač karty smart card

Doporučujeme karty emitentů, dodavatelů a výrobců implementovat minidrivers karty smart card a účastnit se programu Windows Logo prospěch ze zlepšení, které jsou dovezeny v platformu, jako jsou například karty Smart Card typu Plug and Play, fázi zařízení karet Smart Card, atd.

Další informace o čipových karet miniovladač specifikací pro systém Windows navštivte následující Web společnosti Microsoft:
http://www.microsoft.com/whdc/device/Input/SmartCard/sc-minidriver.mspx
Další informace o tom, jak začít pracovat s proces získání loga vaší karty smart card minidrivers navštivte následující web Windows Logo Program:
http://www.microsoft.com/whdc/winlogo/default.mspx

Implementovat PRÁZDNÉHO ovladače karty smart card

Je-li vlastní software PKCS # 11 ovladač, ovládací prvek ActiveX nebo některé jiné middleware je nutné povolit použití karet smart card v systému Windows a implementaci miniovladač karty smart card nebo vlastní zprostředkovatele kryptografických služeb není vhodným řešením, doporučujeme karty emitentů, dodavateli nebo výrobci zvážit odesílání NULL ovladače systému Windows Update. Typický proces pro zajištění, že ovladač NULL je k dispozici na webu Windows Update vyžaduje odeslání úspěšné Nezatříděné zařízení prostřednictvím Winqual. Je-li v budoucnu, je miniovladač k dispozici pro tyto karty, lze uložit nový ovladač systému Windows Update účastí v programu Windows Logo. Ovladače NULL mohou potom ručně stáhnout koncoví uživatelé, nebo můžete pomocí volitelné aktualizace k dispozici.

Následuje ukázkové šablony pro PRÁZDNÉHO ovladače karty smart card.
;
; 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"
Chcete-li generovat ID hardwaru zařízení, který odkazuje řetězec DEVICE_ID ve vzorku, postupujte podle pokynů karty smart card miniovladač specifikace. Chcete-li to provést, navštivte následující Web společnosti Microsoft:
http://www.microsoft.com/whdc/device/Input/SmartCard/sc-minidriver.mspx


Podrobné informace o tom, jak odeslat NULL ovladač společnosti Microsoft obraťte se na technickou podporu společnosti.

Zakázat čipové karty Plug and Play pomocí Zásady skupiny pro spravované počítače

Tato možnost je doporučena pouze pro podnikové nasazení, kde jsou počítače spravovány správci a veškerý potřebný software pro práci s kartami smart card, použité v rozlehlé síti je nainstalována pomocí nástroje pro správu softwaru jako například server SMS.

Tento postup nedoporučujeme v následujících prostředích protože ovlivní všechny karty smart card v prostředí:
  • Komerční nasazení, které cílové koncové uživatele, jako je například bankovnictví online
  • Prostředí, které obsahují obě technologie Plug and Play, karty smart card a čipových karet typu Plug and Play, které Zásady skupiny použít k zakázání technologie Plug and Play pro čipové karty
Čipové karty typu Plug and Play je možné úplně zakázat v podnicích, kde koncového uživatele počítače spravovány mechanismů, jako je například Zásady skupiny.

Používá-li zavedení pouze řešení čipové karty typu Plug and Play, může místní správce v klientském počítači zakázat čipové karty typu Plug and Play. Zakázání čipové karty typu Plug and Play zabrání stahování ovladače karty smart card, také známé jako minidrivers karty smart card. Zabraňuje také výzvy čipové karty typu Plug and Play.

Chcete-li zakázat čipové karty typu Plug and Play v místní Zásady skupiny, postupujte takto:
  1. Klepněte na tlačítko Spustit, typ gpedit.msc v Prohledat programy a soubory pole a stiskněte klávesu ENTER.
  2. Ve stromu konzoly pod Konfigurace počítače, klepněte na tlačítko Šablony pro správu.
  3. V podokně podrobností poklepejte na položku Součásti systému Windowsa potom poklepejte na Karta Smart Card.
  4. Klepněte pravým tlačítkem myši Zapnout službu čipové karty typu Plug and Playa klepněte na tlačítko Upravit.
  5. Klepněte na tlačítko Zakázánoa klepněte na tlačítko OK.

Změna systému koncového uživatele a zakázat čipové karty typu Plug and Play pro konkrétní karty

Toto je doporučeno alespoň možnost. Tuto možnost byste měli použít pouze v případě, že karty jsou starší karty a není plánováno v budoucnu provádět minidrivers karty smart card. Tato možnost vyžaduje, že stávající software, který je již v systému nainstalován oznámí Windows, že je vlastní zprostředkovatele kryptografických služeb v systému nainstalován, přestože neexistuje žádný takový zprostředkovatel kryptografických služeb v systému koncovým uživatelem. Jakmile systém Windows určí, že je vlastní zprostředkovatel kryptografických služeb nainstalován v systému, systém Windows nepokouší stáhněte a nainstalujte ovladač pomocí čipové karty typu Plug and Play. Je vytvořen žádný uzel zařízení pro zařízení karty smart card, který je viditelný ve Správci zařízení. Tato možnost způsobí v systémovém registru následující změny:

Podklíč:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\<smart card="" name=""></smart>
Podklíč registru položky:
  • ATR = šestnáctkové DWORD: oddělený ATR karty smart card.
  • ATRMask = šestnáctkové DWORD: oddělený masky pro zamaskujte nevýznamné bajtů v ATR ATR.
  • Zprostředkovatel kryptografických služeb = hodnota řetězce: některé řetězce, které jsou relevantní pro čipové karty.
Například:
Podklíč:
Karty HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\Fabrikam ATM
Podklíč registru položky:
  • ATR = šestnáctkové DWORD: 3b, dc, 13, 00, 40, 3a, 49, 54, 47, 5f, 4 d, 53, 43, 53, 50, 5f, 56, 32
  • ATRMask = šestnáctkové DWORD: ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff
  • Zprostředkovatel kryptografických služeb = hodnota řetězce: "Zprostředkovatele figuríny ATM Fabrikam"
X 64bitové systémy stejné změny musí provést v následujícím podklíči:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards


Doporučujeme, namísto změny přímo v systémovém registru, můžete použít rozhraní API WinSCard zavést tyto změny v systému. Zde je příklad kódu vzorku, který rozpozná vložení karty smart card a zakáže čipové karty Plug and Play pro určitou kartu vytvořením položky registru, který je přidružen zprostředkovatel neexistující karty.

Společnost Microsoft poskytuje ukázky programování pouze pro ilustraci bez žádné záruky výslovně uvedené nebo předpokládané. To zahrnuje, ale není omezen pouze na předpokládaných záruk obchodovatelnosti nebo vhodnosti pro určitý účel. Tento článek předpokládá, že jste obeznámeni s programovacím jazykem, který je předmětem ukázky a s nástroji, které slouží k vytvoření a ladění skriptu. Pracovníci podpory společnosti Microsoft mohou vysvětlit funkce určitého postupu. Však nemohou tyto příklady rozšířit o další funkce nebo konstrukce podle konkrétních požadavků.
//==============================================================;
//
//  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;
}

Odkazy

Další informace o řešení potíží pomocí karty smart card typu Plug and Play naleznete v následujícím článku na webu TechNet:
Čipové karty typu Plug and Play, Průvodce odstraňováním potíží
http://technet.microsoft.com/en-us/library/dd979536 (WS.10) .aspx

Vlastnosti

ID článku: 976832 - Poslední aktualizace: 24. května 2011 - Revize: 4.0
Informace v tomto článku jsou určeny pro produkt:
  • Windows Server 2008 R2 Datacenter
  • Windows Server 2008 R2 Enterprise
  • Windows Server 2008 R2 Standard
  • Windows 7 Enterprise
  • Windows 7 Home Basic
  • Windows 7 Home Premium
  • Windows 7 Professional
  • Windows 7 Starter
  • Windows 7 Ultimate
Klíčová slova: 
kbsmartcard kbcodesnippet kbtshoot kbexpertiseinter kbsurveynew kbprb kbmt KB976832 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:976832

Dejte nám zpětnou vazbu

 

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