リーダーは、Windows 7 ベースまたは Windows Server 2008 R2 ベースのコンピューター上では、スマート カードを挿入すると、エラー メッセージ:「デバイス ドライバー ソフトウェア インストールされていないが正常に」

文書翻訳 文書翻訳
文書番号: 976832 - 対象製品
すべて展開する | すべて折りたたむ

目次

現象

スマート カード リーダーにスマート カードを挿入すると、Windows をダウンロードして、スマート カードの minidrivers は、カードのプラグ アンド プレイ サービスをインストールしようとします。スマート カード用のドライバーに Windows の更新、WSUS、イントラネット パスなどの事前に構成された場所のいずれかがないと、カスタムの暗号化サービス プロバイダーがシステムにまだインストールされていない場合は、通知領域に、次のエラー メッセージが表示されます。
デバイス ドライバー ソフトウェアはインストールされませんでした。
詳細については、ここをクリックしてください。
このエラー メッセージ数秒後に消えます。

また、デバイス マネージャーで、] その他のデバイスは、スマート カード デバイスのステータスが"DNF"(ドライバーが見つかりません) があります。

次のいずれかのこのエラーを解決するのには、スマート カードの発行元から取得するのには、ユーザーが頻繁に必要です。
  1. Windows ロゴを取得したスマート カード ミニドライバー
  2. スマート カード用のカスタムの暗号化サービス プロバイダー (CSP)。
  3. Windows のロゴではないスマート カード ミニドライバー
  4. その他のミドルウェアは、ActiveX コントロール、PKCS #11 ソフトウェア、またはその他のカスタム ソフトウェアなど。
ただし、唯一の項目 3 または 4 をこの一覧から、ユーザーを指定した場合、スマート カードでシステムが動作する続行されます。ただし、ユーザーは、このにするたびに、スマート カードを挿入すること記載されているエラー メッセージが表示されます。

この問題は、すべてのリリースの Windows 7 は、Windows Server 2008 R2、およびそれ以降のバージョンのどちらのオペレーティング システムに適用されます。

原因

すべてのスマート カードがない限り、追加のソフトウェアをインストールしなくても、カードを使用するため、受信トレイのドライバーが Windows で動作する追加のソフトウェアが必要です。Windows スマート カード フレームワークをリーダーにスマート カードを挿入すると、自動的にスマート カードの minidrivers Windows Update または WSUS サーバーなどの他のような場所からのダウンロードを有効にするのには、Windows 7 が改良されました。すべてのスマート カードは、ロゴ プログラムの要件、Windows ロゴ プログラムでは、公開されて合格からこの機能を活用できます。

ただし、Windows でのスマート カードを使用するために必要なソフトウェア ロゴではないか、PKCS #11 ドライバー、カスタムの CSP、ミドルウェア、または、ActiveX コントロールなどは、ミニドライバーのとは異なる型の場合、自動ダウンロード オプションが失敗する Microsoft は、スマート カードの minidrivers を証明するため。したがって、ユーザーのカスタムの CSP が既に登録されていないカードを挿入する場合は、ユーザーは、ユーザーがカスタム インストールからユーザーのコンピューターにインストールされた追加のソフトウェアをスマート カードを使用することができる場合でも、ドライバー ソフトウェア、スマート カード デバイスにないことを示すエラー メッセージを受け取ります。

解決方法

スマート カードは、ユーザーが表示、エラー メッセージが引き続きが、製造元スマート カードの発行者や仕入先など、次の方法のいずれかのこのエラーを解決するのにできます。

スマート カード ミニドライバーを実装します。

カード発行者、ベンダー、および製造元スマート カードの minidrivers を実装し、スマート カード プラグ アンド プレイ デバイスのステージには、スマート カードなどのプラットフォームに導入された改善からメリットを得るには、Windows ロゴ プログラムに参加することをお勧めで。

スマート カード ミニドライバーの仕様については、Windows の詳細については、次のマイクロソフト Web サイトを参照してください。
http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
ロゴをスマート カードの minidrivers を取得するプロセスを開始する方法の詳細については、次の Windows ロゴ プログラムの Web サイトを参照してください。
http://www.microsoft.com/whdc/winlogo/default.mspx

ご使用のスマート カードの実装によって NULL ドライバー

PKCS #11 ドライバー、ActiveX コントロール、またはいくつか他のミドルウェアにカスタム ソフトウェアが windows でのスマート カードの使用を有効にするために必要ですし、スマート カード ミニドライバーは、またはカスタムの CSP の実装は、実用的な選択肢ではない場合は、カード発行会社、仕入先、または製造業者 NULL ドライバーに Windows の更新プログラムを送信することをお勧めします。NULL ドライバーが Windows Update で使用可能であることを確認するための一般的なプロセスに Winqual を通じての未分類のデバイスが正常に送信が必要です。将来がある場合は、ミニドライバーは、これらのカードの利用可能な Windows ロゴ プログラムに参加することで、新しいドライバー Windows の更新プログラムをアップロードできます。NULL ドライバーは、手動で、エンド ・ ユーザーがダウンロードすることができます。 またはすることができますに使用可能なオプションの更新プログラムを使用しています。

次の例は、NULL ドライバー用のスマート カードです。
;
; 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"
DEVICE_ID 文字列のサンプルを参照して、ハードウェア デバイスの ID を生成するのには、スマート カード ミニドライバーの仕様の指示を実行します。これを行うには、次のマイクロソフト Web サイトを参照してください。
http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx


NULL ドライバーを Microsoft に送信する方法の詳細については、マイクロソフト カスタマー サポート サービスに問い合わせてください。

スマート カード プラグ アンド プレイ グループ ポリシーによって管理されているコンピューターを無効にします。

このオプションは、管理者とすべて SMS などのソフトウェア管理ツールを使用して、企業で使用されているスマート カードを使用するに必要なソフトウェアをインストールして管理するコンピューター企業の展開だけをお勧めします。

環境内のすべてのスマート カードに影響するためこの手順は以下の環境ではお勧め:
  • オンライン バンキングなどのエンドユーザーを対象広告の導入
  • 両方が含まれて環境プラグ アンド スマート カードとスマート カードのプラグ アンド プレイを無効にするグループ ポリシーを使用して非プラグ アンド プレイ スマート カード プレイします。
スマート カードのプラグ アンド プレイは、企業は、エンドユーザーのコンピューターでグループ ポリシーの機構管理され、完全に無効にできます。

非プラグ アンド プレイのスマート カード ソリューションのみを使用して展開する場合は、クライアント コンピューター上のローカル管理者がスマート カード プラグ アンド プレイを無効にできます。スマート カード プラグ アンド プレイを無効にすると、スマート カード ドライバーとも呼ばれるのスマート カードの minidrivers ダウンロードできなくなります。またスマート カードのプラグ アンド プレイ メッセージを防止します。

スマート カードのプラグ アンド プレイでローカル グループ ポリシーを無効にするのには、次の手順を実行します。
  1. クリックしてください。 スタート] gpedit.msc 続いて 検索プログラムとファイル ボックスをオンにし、ENTER キーを押します。
  2. コンソール ツリーで、[ [コンピューターの構成[ 管理用テンプレート.
  3. 詳細ペインでダブルクリックします。 Windows のコンポーネント、をダブルクリック スマート カード.
  4. 右クリックします。 スマート カードのプラグ アンド プレイ サービスを有効にします。プロパティ 編集.
  5. クリックしてください。 無効になっています。プロパティ ].

エンド ・ ユーザーのシステムを変更し、特定のカード用のスマート カード プラグ アンド プレイを無効にします。

これは最も推奨されるオプションです。のみ、カード レガシ カードですし、後でスマート カードの minidrivers を実装する予定はない場合は、このオプションを使用します。このオプションはシステムに既にインストールされている、既存のソフトウェア Windows 通知こと、エンド ・ ユーザーのシステム上にそのような CSP が存在しない場合でも、システムにインストールするカスタムの CSP があることが必要です。Windows が既にシステムにインストールされているカスタムの CSP があることを指定すると、Windows をダウンロードしてからスマート カード プラグ アンド プレイ ドライバーをインストールすることはありません。スマート カード デバイス用のデバイス ノードは、デバイス マネージャーでが表示されることがあります。このオプションで以下の変更をシステムのレジストリに表示されます。

サブキー:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\<Smart card name>
サブキーのレジストリ エントリ:
  • ATR 16 進データ = dword: カンマ区切りのスマート カードの ATR。
  • ATRMask 16 進数の DWORD =: コンマ区切りの ATR ATR での余分なバイトをマスクに適用するマスク。
  • 暗号化プロバイダーの文字列値を =: がスマート カードに関連するいくつかの文字列。
例を示します。
サブキー:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\SmartCards\Fabrikam ATM card
サブキーのレジストリ エントリ:
  • ATR DWORD の 16 進数 =: 3 b、dc、13, 00 40、3 a、49、54、47、5f、4 d、53、43, 53, 50, 5f、56、32
  • ATRMask 16 進数の DWORD =: ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff、ff
  • 暗号化プロバイダーの文字列値を =:「Fabrikam ダミー プロバイダー」
X 64 ビット システムの場合は、同じ次のサブキーの下変更します。
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Calais\SmartCards


レジストリを直接変更するのではなく、WinSCard Api システムにこれらの変更を導入することをお勧めします。スマート カードの挿入を検出し、特定のカード用のスマート カード プラグ アンド プレイ カードが存在しないプロバイダーと関連付けるレジストリ エントリを作成することでを無効にするサンプル コードの例です。

Microsoft プログラミング例としてのみ、表されるまたは暗黙の保証も提供します。これには、市場性または特定目的への適合性その他に対する暗黙的な保証についても含まれます。この資料は、例示されているプログラミング言語を作成したり、プロシージャをデバッグするために使用されるツールに精通しているユーザーを想定して作成されています。マイクロソフト サポート エンジニアは、特定のプロシージャの機能について説明することができます。ただし、機能の追加、または個別案件への対応を目的としたプロシージャ作成のためにこれらの例を修正することはありません。
//==============================================================;
//
//  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;
}

関連情報

スマート カードのプラグ アンド プレイに関する問題のトラブルシューティングの詳細については、次の TechNet の記事を参照してください。
トラブルシューティング ・ ガイド、スマート カード プラグ アンド プレイ
.aspx の http://technet.microsoft.com/en-us/library/dd979536 (WS.10)

プロパティ

文書番号: 976832 - 最終更新日: 2013年2月3日 - リビジョン: 6.0
この資料は以下の製品について記述したものです。
  • 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
キーワード:?
kbsmartcard kbcodesnippet kbtshoot kbexpertiseinter kbsurveynew kbprb kbmt KB976832 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:976832
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

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