Blame examples/PCSCv2part10.c

Packit 9f0df5
/*
Packit 9f0df5
    PCSCv2part10.c: helper functions for PC/SC v2 part 10 services
Packit 9f0df5
    Copyright (C) 2012   Ludovic Rousseau
Packit 9f0df5
Packit 9f0df5
    This library is free software; you can redistribute it and/or
Packit 9f0df5
    modify it under the terms of the GNU Lesser General Public
Packit 9f0df5
    License as published by the Free Software Foundation; either
Packit 9f0df5
    version 2.1 of the License, or (at your option) any later version.
Packit 9f0df5
Packit 9f0df5
    This library is distributed in the hope that it will be useful,
Packit 9f0df5
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 9f0df5
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 9f0df5
    Lesser General Public License for more details.
Packit 9f0df5
Packit 9f0df5
    You should have received a copy of the GNU Lesser General Public
Packit 9f0df5
    License along with this library; if not, write to the Free Software
Packit 9f0df5
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 9f0df5
*/
Packit 9f0df5
Packit 9f0df5
#include <stdio.h>
Packit 9f0df5
#include <arpa/inet.h>
Packit 9f0df5
Packit 9f0df5
#ifdef __APPLE__
Packit 9f0df5
#include <PCSC/winscard.h>
Packit 9f0df5
#include <PCSC/wintypes.h>
Packit 9f0df5
#else
Packit 9f0df5
#include <winscard.h>
Packit 9f0df5
#endif
Packit 9f0df5
Packit 9f0df5
#include "PCSCv2part10.h"
Packit 9f0df5
Packit 9f0df5
int PCSCv2Part10_find_TLV_property_by_tag_from_buffer(
Packit 9f0df5
	unsigned char *buffer, int length, int property, int * value_int)
Packit 9f0df5
{
Packit 9f0df5
	unsigned char *p;
Packit 9f0df5
	int found = 0, len;
Packit 9f0df5
	int value = -1;
Packit 9f0df5
	int ret = -1;	/* not found by default */
Packit 9f0df5
Packit 9f0df5
	p = buffer;
Packit 9f0df5
	while (p-buffer < length)
Packit 9f0df5
	{
Packit 9f0df5
		if (*p++ == property)
Packit 9f0df5
		{
Packit 9f0df5
			found = 1;
Packit 9f0df5
			break;
Packit 9f0df5
		}
Packit 9f0df5
Packit 9f0df5
		/* go to next tag */
Packit 9f0df5
		len = *p++;
Packit 9f0df5
		p += len;
Packit 9f0df5
	}
Packit 9f0df5
Packit 9f0df5
	if (found)
Packit 9f0df5
	{
Packit 9f0df5
		len = *p++;
Packit 9f0df5
		ret = 0;
Packit 9f0df5
Packit 9f0df5
		switch(len)
Packit 9f0df5
		{
Packit 9f0df5
			case 1:
Packit 9f0df5
				value = *p;
Packit 9f0df5
				break;
Packit 9f0df5
			case 2:
Packit 9f0df5
				value = *p + (*(p+1)<<8);
Packit 9f0df5
				break;
Packit 9f0df5
			case 4:
Packit 9f0df5
				value = *p + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24);
Packit 9f0df5
				break;
Packit 9f0df5
			default:
Packit 9f0df5
				/* wrong length for an integer */
Packit 9f0df5
				ret = -2;
Packit 9f0df5
		}
Packit 9f0df5
	}
Packit 9f0df5
Packit 9f0df5
	if (value_int)
Packit 9f0df5
		*value_int = value;
Packit 9f0df5
Packit 9f0df5
	return ret;
Packit 9f0df5
} /* PCSCv2Part10_find_TLV_property_by_tag_from_buffer */
Packit 9f0df5
Packit 9f0df5
int PCSCv2Part10_find_TLV_property_by_tag_from_hcard(SCARDHANDLE hCard,
Packit 9f0df5
	int property, int * value)
Packit 9f0df5
{
Packit 9f0df5
	unsigned char buffer[MAX_BUFFER_SIZE];
Packit 9f0df5
	LONG rv;
Packit 9f0df5
	DWORD length;
Packit 9f0df5
	unsigned int i;
Packit 9f0df5
	PCSC_TLV_STRUCTURE *pcsc_tlv;
Packit 9f0df5
	DWORD properties_in_tlv_ioctl;
Packit 9f0df5
	int found;
Packit 9f0df5
Packit 9f0df5
	rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
Packit 9f0df5
		buffer, sizeof buffer, &length);
Packit 9f0df5
	if (rv != SCARD_S_SUCCESS)
Packit 9f0df5
		return -1;
Packit 9f0df5
Packit 9f0df5
	/* get the number of elements instead of the complete size */
Packit 9f0df5
	length /= sizeof(PCSC_TLV_STRUCTURE);
Packit 9f0df5
Packit 9f0df5
	pcsc_tlv = (PCSC_TLV_STRUCTURE *)buffer;
Packit 9f0df5
	found = 0;
Packit 9f0df5
	for (i = 0; i < length; i++)
Packit 9f0df5
	{
Packit 9f0df5
		if (FEATURE_GET_TLV_PROPERTIES == pcsc_tlv[i].tag)
Packit 9f0df5
		{
Packit 9f0df5
			properties_in_tlv_ioctl = ntohl(pcsc_tlv[i].value);
Packit 9f0df5
			found = 1;
Packit 9f0df5
		}
Packit 9f0df5
	}
Packit 9f0df5
Packit 9f0df5
	if (! found)
Packit 9f0df5
		return -3;
Packit 9f0df5
Packit 9f0df5
	rv= SCardControl(hCard, properties_in_tlv_ioctl, NULL, 0,
Packit 9f0df5
		buffer, sizeof buffer, &length);
Packit 9f0df5
	if (rv != SCARD_S_SUCCESS)
Packit 9f0df5
		return -1;
Packit 9f0df5
Packit 9f0df5
	return PCSCv2Part10_find_TLV_property_by_tag_from_buffer(buffer,
Packit 9f0df5
		length, property, value);
Packit 9f0df5
}
Packit 9f0df5