Поделиться через


Создание команды APDU ISO7816-4

Чтобы добавить функциональные возможности к поставщику услуг, необходимо знать, как в библиотеках DLL базового поставщика служб создается единица данных протокола приложения (APDU) ISO7816-4. В следующей процедуре представлен краткий обзор процесса сборки.

Примечание

Приведенный здесь пример не обязательно является полным; Дополнительные сведения см. в примерах приложений и библиотек DLL.

 

Создание команды APDU ISO7816-4

  1. Создайте объекты ISCardCmd и ISCardISO7816 .

    //  Create an ISCardCmd object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardCmd,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardCmd,
                               (LPVOID*) &g_pISCardCmd);
    //  Create an ISCardISO7816 object.
    HRESULT hresult = CoCreateInstance(CLSID_CSCardISO7816,
                               NULL,
                               CLSCTX_ALL,
                               IID_ISCardISO7816,
                               (LPVOID*) &g_pISCardISO7816);
    

    Интерфейс ISCardCmd содержит два буфера IByteBuffer . Один буфер содержит фактическую командную строку APDU (а также любые данные для отправки с помощью команды ). Второй содержит все ответные сведения, возвращаемые карта после выполнения команды.

  2. С помощью этих объектов создайте допустимую команду ISO7816-4 следующим образом:

    //  Do challenge.
    HRESULT hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                             &g_pISCardCmd);
    

    Ниже приведен код, используемый в методе GetChallenge :

    #include <windows.h>
    
    STDMETHODIMP CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                                IN OUT LPSCARDCMD *ppCmd)
    {
        //  Locals.
        HRESULT hr = S_OK;
    
        try
        {
            //  Is the ISCardCmd object okay?
            hr = IsSCardCmdValid(ppCmd);
            if (FAILED(hr))
                throw (hr);
    
            //  Do it.
            hr = (*ppCmd)->BuildCmd(m_byClassId,
                                    (BYTE) INS_GET_CHALLENGE,
                                    (BYTE) INS_NULL,  // P1 = 0x00
                                    (BYTE) INS_NULL,  // P2 = 0x00
                                    NULL,
                                    &dwBytesExpected);
            if (FAILED(hr))
                throw (hr);
        }
    }
    

    Метод ISCardISO7816::GetChallenge использует метод ISCardCmd::BuildCmd для сборки запрошенного APDU. Это делается путем записи соответствующих сведений в буфер APDU ISCardCmd в следующей инструкции:

    hr = (*ppCmd)->BuildCmd;
    
  3. Используя встроенный объект ISCardCmd, выполните транзакцию с карта, интерпретировать результаты и продолжить.

Расширение за пределами ISO7816-4

Рекомендуемый способ расширить процесс сборки и выполнения поставщика услуг, описанный выше, — создать новый COM-объект. Этот COM-объект должен поддерживать новый интерфейс, который позволяет создавать команды, отличные от ISO7816-4, и должен агрегировать интерфейс ISCardISO7816 .

Пример создания команды APDU ISO7816-4

В следующем примере показан код, используемый в процедуре выше.

//  Create an ISCardCmd object.
hresult = CoCreateInstance(CLSID_CSCardCmd,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardCmd,
                           (LPVOID*) &g_pISCardCmd);
//  Create an ISCardISO7816 object.
hresult = CoCreateInstance(CLSID_CSCardISO7816,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardISO7816,
                           (LPVOID*) &g_pISCardISO7816);
//  Do challenge.
hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                         &g_pISCardCmd);

STDMETHODIMP
CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                            IN OUT LPSCARDCMD *ppCmd)
{
    //  Locals.
    HRESULT hr = S_OK;
    
    try
    {
        //  Is the ISCardCmd object okay?
        hr = IsSCardCmdValid(ppCmd);
        if (FAILED(hr))
            throw (hr);

        //  Do it.
        hr = (*ppCmd)->BuildCmd(m_byClassId,
                                (BYTE) INS_GET_CHALLENGE,
                                (BYTE) INS_NULL,  // P1 = 0x00
                                (BYTE) INS_NULL,  // P2 = 0x00
                                NULL,
                                &dwBytesExpected);
        if (FAILED(hr))
            throw (hr);
    }
}