Dela via


Skapa ett ISO7816-4 APDU-kommando

Om du vill lägga till funktioner i en tjänstleverantör måste du veta hur en ISO7816-4 application protocol data unit (APDU) skapas inom bastjänstleverantörens DLL:er. Följande procedur ger en kort översikt över byggprocessen.

Anteckning

Exemplet som ingår här är inte nödvändigtvis fullständigt. Mer information finns i exempelprogram och DLL:er.

 

Skapa ett ISO7816-4 APDU-kommando

  1. Skapa ett ISCardCmd--objekt och ett ISCardISO7816--objekt.

    //  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);
    

    Gränssnittet ISCardCmd innehåller två IByteBuffer- buffertar. En buffert innehåller den faktiska APDU-kommandosträngen (plus alla data som ska skickas med kommandot). Den andra innehåller svarsinformation som returneras av kortet efter att kommandot har körts.

  2. Använd dessa objekt och skapa ett giltigt ISO7816-4-kommando på följande sätt:

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

    Här är koden som används i metoden 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);
        }
    }
    

    Metoden ISCardISO7816::GetChallenge använder metoden ISCardCmd::BuildCmd för att skapa den begärda APDU:n. Detta görs genom att skriva lämplig information till ISCardCmd APDU-bufferten i följande instruktion:

    hr = (*ppCmd)->BuildCmd;
    
  3. Med hjälp av det inbyggda ISCardCmd--objektet gör du en transaktion med kortet, tolkar resultatet och fortsätter.

Att utvidga utöver ISO7816-4

Det rekommenderade sättet att expandera processen för att skapa/köra tjänstprovidern som beskrivs ovan är att skapa ett nytt COM-objekt. Det här COM-objektet bör ha stöd för ett nytt gränssnitt som gör det möjligt att skapa icke-ISO7816-4-kommandon och sammanställa ISCardISO7816--gränssnittet.

Exempel på att skapa ett ISO7816-4 APDU-kommando

I följande exempel visas den kod som används i proceduren ovan.

//  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);
    }
}