Ejemplo n.º 1
0
static uint32 handle_Disconnect(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hContext;
	SCARDHANDLE hCard;
	DWORD dwDisposition = 0;

	stream_seek(irp->input, 0x20);
	stream_read_uint32(irp->input, dwDisposition);
	stream_seek(irp->input, 4);
	stream_read_uint32(irp->input, hContext);
	stream_seek(irp->input, 4);
	stream_read_uint32(irp->input, hCard);

	DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, disposition: 0x%08x)",
		(unsigned) hContext, (unsigned) hCard, (unsigned) dwDisposition);

	rv = SCardDisconnect(hCard, (DWORD) dwDisposition);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success");

	sc_output_alignment(irp, 8);

	return rv;
}
Ejemplo n.º 2
0
static uint32 handle_Connect(IRP* irp, tbool wide)
{
	LONG rv;
	SCARDCONTEXT hContext;
	char *readerName = NULL;
	DWORD dwShareMode = 0;
	DWORD dwPreferredProtocol = 0;
	DWORD dwActiveProtocol = 0;
	SCARDHANDLE hCard;

	stream_seek(irp->input, 0x1c);
	stream_read_uint32(irp->input, dwShareMode);
	stream_read_uint32(irp->input, dwPreferredProtocol);

	sc_input_reader_name(irp, &readerName, wide);

	stream_seek(irp->input, 4);
	stream_read_uint32(irp->input, hContext);

	DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")",
		(unsigned) hContext, (unsigned) dwShareMode,
		(unsigned) dwPreferredProtocol, readerName ? readerName : "NULL");

	rv = SCardConnect(hContext, readerName, (DWORD) dwShareMode,
		(DWORD) dwPreferredProtocol, &hCard, (DWORD *) &dwActiveProtocol);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s 0x%08x", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success 0x%08x", (unsigned) hCard);

	stream_write_uint32(irp->output, 0x00000000);
	stream_write_uint32(irp->output, 0x00000000);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, 0x016Cff34);
	stream_write_uint32(irp->output, dwActiveProtocol);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, hCard);
	stream_seek(irp->output, 28);

	sc_output_alignment(irp, 8);

	xfree(readerName);
	return rv;
}
Ejemplo n.º 3
0
static void sc_input_reader_name(IRP* irp, char **dest, tbool wide)
{
	uint32 dataLength;

	stream_seek(irp->input, 8);
	stream_read_uint32(irp->input, dataLength);

	DEBUG_SCARD("datalength %d", dataLength);
	sc_input_repos(irp, sc_input_string(irp, dest, dataLength, wide));
}
Ejemplo n.º 4
0
static UINT32 handle_BeginTransaction(IRP* irp)
{
	LONG status;
	SCARDCONTEXT hCard;

	stream_seek(irp->input, 0x30);
	stream_read_UINT32(irp->input, hCard);

	status = SCardBeginTransaction(hCard);

	if (status != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status);
	else
		DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard);

	smartcard_output_alignment(irp, 8);

	return status;
}
Ejemplo n.º 5
0
static UINT32 handle_Cancel(IRP *irp)
{
	LONG status;
	SCARDCONTEXT hContext;

	stream_seek(irp->input, 0x1C);
	stream_read_UINT32(irp->input, hContext);

	status = SCardCancel(hContext);

	if (status != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status);
	else
		DEBUG_SCARD("Success context: 0x%08x %s", (unsigned) hContext, pcsc_stringify_error(status));

	smartcard_output_alignment(irp, 8);

	return status;
}
Ejemplo n.º 6
0
static UINT32 handle_IsValidContext(IRP* irp)
{
	UINT32 status;
	SCARDCONTEXT hContext;

	stream_seek(irp->input, 0x1C);
	stream_read_UINT32(irp->input, hContext);

	status = SCardIsValidContext(hContext);

	if (status)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status);
	else
		DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext);

	smartcard_output_alignment(irp, 8);

	return status;
}
Ejemplo n.º 7
0
static uint32 handle_ReleaseContext(IRP* irp)
{
	uint32 len, rv;
	SCARDCONTEXT hContext = -1;

	stream_seek(irp->input, 8);
	stream_read_uint32(irp->input, len);

	stream_seek(irp->input, 0x10);
	stream_read_uint32(irp->input, hContext);

	rv = SCardReleaseContext(hContext);
	if (rv)
		DEBUG_SCARD("%s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("success 0x%08lx", hContext);

	return rv;
}
Ejemplo n.º 8
0
static uint32 handle_IsValidContext(IRP* irp)
{
	uint32 rv;
	SCARDCONTEXT hContext;

	stream_seek(irp->input, 0x1C);
	stream_read_uint32(irp->input, hContext);

	rv = SCardIsValidContext(hContext);

	if (rv)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext);

	stream_write_uint32(irp->output, rv);

	return rv;
}
Ejemplo n.º 9
0
static void smartcard_input_reader_name(IRP* irp, char** dest, BOOL wide)
{
	UINT32 dataLength;

	stream_seek(irp->input, 8);
	stream_read_UINT32(irp->input, dataLength);

	DEBUG_SCARD("datalength %d", dataLength);
	smartcard_input_repos(irp, smartcard_input_string(irp, dest, dataLength, wide));
}
Ejemplo n.º 10
0
static uint32 handle_BeginTransaction(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hCard;

	stream_seek(irp->input, 0x30);
	stream_read_uint32(irp->input, hCard);

	rv = SCardBeginTransaction(hCard);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard);

	sc_output_alignment(irp, 8);

	return rv;
}
Ejemplo n.º 11
0
static uint32 handle_Cancel(IRP *irp)
{
	LONG rv;
	SCARDCONTEXT hContext;

	stream_seek(irp->input, 0x1C);
	stream_read_uint32(irp->input, hContext);

	rv = SCardCancel(hContext);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success context: 0x%08x %s\n", (unsigned) hContext, pcsc_stringify_error(rv));

	sc_output_alignment(irp, 8);

	return rv;
}
Ejemplo n.º 12
0
static UINT32 handle_ReleaseContext(IRP* irp)
{
	UINT32 len, status;
	SCARDCONTEXT hContext = -1;

	stream_seek(irp->input, 8);
	stream_read_UINT32(irp->input, len);

	stream_seek(irp->input, 0x10);
	stream_read_UINT32(irp->input, hContext);

	status = SCardReleaseContext(hContext);

	if (status)
		DEBUG_SCARD("%s (0x%08x)", pcsc_stringify_error(status), (unsigned) status);
	else
		DEBUG_SCARD("success 0x%08lx", hContext);

	smartcard_output_alignment(irp, 8);

	return status;
}
Ejemplo n.º 13
0
static uint32 handle_Reconnect(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hContext;
	SCARDHANDLE hCard;
	DWORD dwShareMode = 0;
	DWORD dwPreferredProtocol = 0;
	DWORD dwInitialization = 0;
	DWORD dwActiveProtocol = 0;

	stream_seek(irp->input, 0x20);
	stream_read_uint32(irp->input, dwShareMode);
	stream_read_uint32(irp->input, dwPreferredProtocol);
	stream_read_uint32(irp->input, dwInitialization);

	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hContext);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hCard);

	DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, share: 0x%08x, proto: 0x%08x, init: 0x%08x)",
		(unsigned) hContext, (unsigned) hCard,
		(unsigned) dwShareMode, (unsigned) dwPreferredProtocol, (unsigned) dwInitialization);

	rv = SCardReconnect(hCard, (DWORD) dwShareMode, (DWORD) dwPreferredProtocol,
	    (DWORD) dwInitialization, (LPDWORD) &dwActiveProtocol);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol);

	sc_output_alignment(irp, 8);
	stream_write_uint32(irp->output, dwActiveProtocol); /* reversed? */

	return rv;
}
Ejemplo n.º 14
0
static DWORD handle_Status(IRP *irp, tbool wide)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD state, protocol;
	DWORD readerLen = 0;
	DWORD atrLen = 0;
	char * readerName;
	BYTE pbAtr[MAX_ATR_SIZE];
	uint32 dataLength;
	int pos, poslen1, poslen2;

#ifdef WITH_DEBUG_SCARD
	int i;
#endif

	stream_seek(irp->input, 0x24);
	stream_read_uint32(irp->input, readerLen);
	stream_read_uint32(irp->input, atrLen);
	stream_seek(irp->input, 0x0c);
	stream_read_uint32(irp->input, hCard);
	stream_seek(irp->input, 0x4);

	atrLen = MAX_ATR_SIZE;

#ifdef SCARD_AUTOALLOCATE
	readerLen = SCARD_AUTOALLOCATE;

	rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#else
	readerLen = 256;
	readerName = xmalloc(readerLen);

	rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol);
	DEBUG_SCARD("       Reader: \"%s\"", readerName ? readerName : "NULL");

#ifdef WITH_DEBUG_SCARD
	printf("       ATR: ");
	for (i = 0; i < atrLen; i++)
		printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':');
	printf("\n");
#endif

	state = sc_map_state(state);

	poslen1 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);
	stream_write_uint32(irp->output, 0x00020000);
	stream_write_uint32(irp->output, state);
	stream_write_uint32(irp->output, protocol);
	stream_write(irp->output, pbAtr, atrLen);

	if (atrLen < 32)
		stream_write_zero(irp->output, 32 - atrLen);
	stream_write_uint32(irp->output, atrLen);

	poslen2 = stream_get_pos(irp->output);
	stream_write_uint32(irp->output, readerLen);

	dataLength = sc_output_string(irp, readerName, wide);
	dataLength += sc_output_string(irp, "\0", wide);
	sc_output_repos(irp, dataLength);

	pos = stream_get_pos(irp->output);
	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output,dataLength);
	stream_set_pos(irp->output, pos);

	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	/* SCardFreeMemory(NULL, readerName); */
	free(readerName);
#else
	xfree(readerName);
#endif

	return rv;
}
Ejemplo n.º 15
0
static uint32 handle_State(IRP* irp)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD state = 0, protocol = 0;
	DWORD readerLen;
	DWORD atrLen = MAX_ATR_SIZE;
	char * readerName;
	BYTE pbAtr[MAX_ATR_SIZE];

#ifdef WITH_DEBUG_SCARD
	int i;
#endif

	stream_seek(irp->input, 0x24);
	stream_seek_uint32(irp->input);	/* atrLen */

	stream_seek(irp->input, 0x0c);
	stream_read_uint32(irp->input, hCard);
	stream_seek(irp->input, 0x04);

#ifdef SCARD_AUTOALLOCATE
	readerLen = SCARD_AUTOALLOCATE;

	rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#else
	readerLen = 256;
	readerName = xmalloc(readerLen);

	rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen);
#endif

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)",
		(unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol);

#ifdef WITH_DEBUG_SCARD
	printf("       ATR: ");
	for (i = 0; i < atrLen; i++)
		printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':');
	printf("\n");
#endif

	state = sc_map_state(state);

	stream_write_uint32(irp->output, state);
	stream_write_uint32(irp->output, protocol);
	stream_write_uint32(irp->output, atrLen);
	stream_write_uint32(irp->output, 0x00000001);
	stream_write_uint32(irp->output, atrLen);
	stream_write(irp->output, pbAtr, atrLen);

	sc_output_repos(irp, atrLen);
	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	xfree(readerName);
#else
	xfree(readerName);
#endif

	return rv;
}
Ejemplo n.º 16
0
static uint32 handle_GetAttrib(IRP* irp)
{
	LONG rv;
	SCARDHANDLE hCard;
	DWORD dwAttrId = 0, dwAttrLen = 0;
	DWORD attrLen = 0;
	uint8* pbAttr = NULL;

	stream_seek(irp->input, 0x20);
	stream_read_uint32(irp->input, dwAttrId);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, dwAttrLen);
	stream_seek(irp->input, 0xC);
	stream_read_uint32(irp->input, hCard);

	DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)\n",
		(unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen);

#ifdef SCARD_AUTOALLOCATE
	if(dwAttrLen == 0)
	{
		attrLen = 0;
	}
	else
	{
		attrLen = SCARD_AUTOALLOCATE;
	}
#endif

	rv = SCardGetAttrib(hCard, dwAttrId, attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen);
	if( rv != SCARD_S_SUCCESS ) {
#ifdef SCARD_AUTOALLOCATE
		if(dwAttrLen == 0)
		{
			attrLen = 0;
		}
		else
		{
			attrLen = SCARD_AUTOALLOCATE;
		}
#endif
	}

	if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A && rv == SCARD_E_UNSUPPORTED_FEATURE)
	{
		rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
			attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen);
		if( rv != SCARD_S_SUCCESS ) {
#ifdef SCARD_AUTOALLOCATE
			if(dwAttrLen == 0)
			{
				attrLen = 0;
			}
			else
			{
				attrLen = SCARD_AUTOALLOCATE;
			}
#endif
		}
	}
	if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W && rv == SCARD_E_UNSUPPORTED_FEATURE)
	{
		rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
			attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen);
		if( rv != SCARD_S_SUCCESS ) {
#ifdef SCARD_AUTOALLOCATE
			if(dwAttrLen == 0)
			{
				attrLen = 0;
			}
			else
			{
				attrLen = SCARD_AUTOALLOCATE;
			}
#endif
		}
	}
	if(attrLen > dwAttrLen && pbAttr != NULL)
	{
		rv = SCARD_E_INSUFFICIENT_BUFFER;
	}
	dwAttrLen = attrLen;

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned int) rv);
		free(pbAttr);
		return sc_output_return(irp, rv);
	}
	else
	{
		DEBUG_SCARD("Success (%d bytes)", (int) dwAttrLen);

		stream_write_uint32(irp->output, dwAttrLen);
		stream_write_uint32(irp->output, 0x00000200);
		stream_write_uint32(irp->output, dwAttrLen);

		if (!pbAttr)
		{
			stream_write_zero(irp->output, dwAttrLen);
		}
		else
		{
			stream_write(irp->output, pbAttr, dwAttrLen);
		}
		sc_output_repos(irp, dwAttrLen);
		/* align to multiple of 4 */
		stream_write_uint32(irp->output, 0);
	}
	sc_output_alignment(irp, 8);

	xfree(pbAttr);

	return rv;
}
Ejemplo n.º 17
0
static uint32 handle_LocateCardsByATR(IRP* irp, tbool wide)
{
	LONG rv;
	int i, j, k;
	SCARDCONTEXT hContext;
	uint32 atrMaskCount = 0;
	uint32 readerCount = 0;
	SCARD_READERSTATE* cur = NULL;
	SCARD_READERSTATE* rsCur = NULL;
	SCARD_READERSTATE* readerStates = NULL;
	SERVER_SCARD_ATRMASK* curAtr = NULL;
	SERVER_SCARD_ATRMASK* pAtrMasks = NULL;

	stream_seek(irp->input, 0x2C);
	stream_read_uint32(irp->input, hContext);
	stream_read_uint32(irp->input, atrMaskCount);

	pAtrMasks = xmalloc(atrMaskCount * sizeof(SERVER_SCARD_ATRMASK));

	if (!pAtrMasks)
		return sc_output_return(irp, SCARD_E_NO_MEMORY);

	for (i = 0; i < atrMaskCount; i++)
	{
		stream_read_uint32(irp->input, pAtrMasks[i].cbAtr);
		stream_read(irp->input, pAtrMasks[i].rgbAtr, 36);
		stream_read(irp->input, pAtrMasks[i].rgbMask, 36);
	}

	stream_read_uint32(irp->input, readerCount);

	readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE));

	if (!readerStates)
		return sc_output_return(irp, SCARD_E_NO_MEMORY);

	for (i = 0; i < readerCount; i++)
	{
		cur = &readerStates[i];

		stream_seek(irp->input, 4);

		/*
		 * TODO: on-wire is little endian; need to either
		 * convert to host endian or fix the headers to
		 * request the order we want
		 */
		stream_read_uint32(irp->input, cur->dwCurrentState);
		stream_read_uint32(irp->input, cur->dwEventState);
		stream_read_uint32(irp->input, cur->cbAtr);
		stream_read(irp->input, cur->rgbAtr, 32);

		stream_seek(irp->input, 4);

		/* reset high bytes? */
		cur->dwCurrentState &= 0x0000FFFF;
		cur->dwEventState &= 0x0000FFFF;
		cur->dwEventState = 0;
	}

	for (i = 0; i < readerCount; i++)
	{
		cur = &readerStates[i];
		uint32 dataLength;

		stream_seek(irp->input, 8);
		stream_read_uint32(irp->input, dataLength);
		sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide));

		DEBUG_SCARD("   \"%s\"", cur->szReader ? cur->szReader : "NULL");
		DEBUG_SCARD("       user: 0x%08x, state: 0x%08x, event: 0x%08x",
				(unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
				(unsigned) cur->dwEventState);

		if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
			cur->dwCurrentState |= SCARD_STATE_IGNORE;
	}

	rv = SCardGetStatusChange(hContext, 0x00000001, readerStates, readerCount);
	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)",
			pcsc_stringify_error(rv), (unsigned) rv);

		return sc_output_return(irp, rv);
	}

	DEBUG_SCARD("Success");
	for (i = 0, curAtr = pAtrMasks; i < atrMaskCount; i++, curAtr++)
	{
		for (j = 0, rsCur = readerStates; j < readerCount; j++, rsCur++)
		{
			tbool equal = 1;
			for (k = 0; k < cur->cbAtr; k++)
			{
				if ((curAtr->rgbAtr[k] & curAtr->rgbMask[k]) !=
				    (rsCur->rgbAtr[k] & curAtr->rgbMask[k]))
				{
					equal = 0;
					break;
				}
			}
			if (equal)
			{
				rsCur->dwEventState |= 0x00000040;	/* SCARD_STATE_ATRMATCH 0x00000040 */
			}
		}
	}

	stream_write_uint32(irp->output, readerCount);
	stream_write_uint32(irp->output, 0x00084dd8);
	stream_write_uint32(irp->output, readerCount);

	for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++)
	{
		stream_write_uint32(irp->output, cur->dwCurrentState);
		stream_write_uint32(irp->output, cur->dwEventState);
		stream_write_uint32(irp->output, cur->cbAtr);
		stream_write(irp->output, cur->rgbAtr, 32);

		stream_write_zero(irp->output, 4);

		xfree((void*) cur->szReader);
	}

	sc_output_alignment(irp, 8);

	free(readerStates);

	return rv;
}
Ejemplo n.º 18
0
static uint32 handle_GetStatusChange(IRP* irp, tbool wide)
{
	LONG rv;
	SCARDCONTEXT hContext;
	DWORD dwTimeout = 0;
	DWORD readerCount = 0;
	SCARD_READERSTATE *readerStates, *cur;
	int i;

	stream_seek(irp->input, 0x18);
	stream_read_uint32(irp->input, dwTimeout);
	stream_read_uint32(irp->input, readerCount);

	stream_seek(irp->input, 8);

	stream_read_uint32(irp->input, hContext);

	stream_seek(irp->input, 4);

	DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d",
		     (unsigned) hContext, (unsigned) dwTimeout, (int) readerCount);
	if (readerCount > 0)
	{
		readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE));
		if (!readerStates)
			return sc_output_return(irp, SCARD_E_NO_MEMORY);


		for (i = 0; i < readerCount; i++)
		{
			cur = &readerStates[i];

			stream_seek(irp->input, 4);

			/*
			 * TODO: on-wire is little endian; need to either
			 * convert to host endian or fix the headers to
			 * request the order we want
			 */
			stream_read_uint32(irp->input, cur->dwCurrentState);
			stream_read_uint32(irp->input, cur->dwEventState);
			stream_read_uint32(irp->input, cur->cbAtr);
			stream_read(irp->input, cur->rgbAtr, 32);

			stream_seek(irp->input, 4);

			/* reset high bytes? */
			cur->dwCurrentState &= 0x0000FFFF;
			cur->dwEventState &= 0x0000FFFF;
			cur->dwEventState = 0;
		}

		for (i = 0; i < readerCount; i++)
		{
			cur = &readerStates[i];
			uint32 dataLength;

			stream_seek(irp->input, 8);
			stream_read_uint32(irp->input, dataLength);
			sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide));

			DEBUG_SCARD("   \"%s\"", cur->szReader ? cur->szReader : "NULL");
			DEBUG_SCARD("       user: 0x%08x, state: 0x%08x, event: 0x%08x",
				(unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
				(unsigned) cur->dwEventState);

			if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
				cur->dwCurrentState |= SCARD_STATE_IGNORE;
		}
	}
	else
	{
		readerStates = NULL;
	}

	rv = SCardGetStatusChange(hContext, (DWORD) dwTimeout, readerStates, (DWORD) readerCount);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success");

	stream_write_uint32(irp->output, readerCount);
	stream_write_uint32(irp->output, 0x00084dd8);
	stream_write_uint32(irp->output, readerCount);

	for (i = 0; i < readerCount; i++)
	{
		cur = &readerStates[i];

		DEBUG_SCARD("   \"%s\"", cur->szReader ? cur->szReader : "NULL");
		DEBUG_SCARD("       user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
			(unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
			(unsigned) cur->dwEventState);

		/* TODO: do byte conversions if necessary */
		stream_write_uint32(irp->output, cur->dwCurrentState);
		stream_write_uint32(irp->output, cur->dwEventState);
		stream_write_uint32(irp->output, cur->cbAtr);
		stream_write(irp->output, cur->rgbAtr, 32);

		stream_write_zero(irp->output, 4);

		xfree((void *)cur->szReader);
	}

	sc_output_alignment(irp, 8);

	xfree(readerStates);
	return rv;
}
Ejemplo n.º 19
0
static uint32 handle_Transmit(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hCard;
	uint32 map[7], linkedLen;
	SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci;
	DWORD cbSendLength = 0, cbRecvLength = 0;
	BYTE *sendBuf = NULL, *recvBuf = NULL;

	stream_seek(irp->input, 0x14);
	stream_read_uint32(irp->input, map[0]);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, map[1]);

	stream_read_uint32(irp->input, pioSendPci.dwProtocol);
	stream_read_uint32(irp->input, pioSendPci.cbPciLength);

	stream_read_uint32(irp->input, map[2]);
	stream_read_uint32(irp->input, cbSendLength);
	stream_read_uint32(irp->input, map[3]);
	stream_read_uint32(irp->input, map[4]);
	stream_read_uint32(irp->input, map[5]);
	stream_read_uint32(irp->input, cbRecvLength);

	if (map[0] & SCARD_INPUT_LINKED)
		sc_input_skip_linked(irp);

	stream_seek(irp->input, 4);
	stream_read_uint32(irp->input, hCard);

	if (map[2] & SCARD_INPUT_LINKED)
	{
		/* sendPci */
		stream_read_uint32(irp->input, linkedLen);

		stream_read_uint32(irp->input, pioSendPci.dwProtocol);
		stream_seek(irp->input, linkedLen - 4);

		sc_input_repos(irp, linkedLen);
	}
	pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST);

	if (map[3] & SCARD_INPUT_LINKED)
	{
		/* send buffer */
		stream_read_uint32(irp->input, linkedLen);

		sendBuf = xmalloc(linkedLen);
		stream_read(irp->input, sendBuf, linkedLen);
		sc_input_repos(irp, linkedLen);
	}

	if (cbRecvLength)
		recvBuf = xmalloc(cbRecvLength);

	if (map[4] & SCARD_INPUT_LINKED)
	{
		/* recvPci */
		stream_read_uint32(irp->input, linkedLen);

		stream_read_uint32(irp->input, pioRecvPci.dwProtocol);
		stream_seek(irp->input, linkedLen - 4);

		sc_input_repos(irp, linkedLen);

		stream_read_uint32(irp->input, map[6]);
		if (map[6] & SCARD_INPUT_LINKED)
		{
			/* not sure what this is */
			stream_read_uint32(irp->input, linkedLen);
			stream_seek(irp->input, linkedLen);

			sc_input_repos(irp, linkedLen);
		}
		pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST);
		pPioRecvPci = &pioRecvPci;
	}
	else
	{
		pPioRecvPci = NULL;
	}
	pPioRecvPci = NULL;

	DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)",
		(long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength);

	rv = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength,
			   pPioRecvPci, recvBuf, &cbRecvLength);

	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	}
	else
	{
		DEBUG_SCARD("Success (%d bytes)", (int) cbRecvLength);

		stream_write_uint32(irp->output, 0); 	/* pioRecvPci 0x00; */

		sc_output_buffer_start(irp, cbRecvLength);	/* start of recvBuf output */

		sc_output_buffer(irp, (char *) recvBuf, cbRecvLength);
	}

	sc_output_alignment(irp, 8);

	xfree(sendBuf);
	xfree(recvBuf);

	return rv;
}
Ejemplo n.º 20
0
static uint32 handle_Control(IRP* irp)
{
	LONG rv;
	SCARDCONTEXT hContext;
	SCARDHANDLE hCard;
	uint32 map[3];
	uint32 controlCode;
	uint32 controlFunction;
	BYTE *recvBuffer = NULL, *sendBuffer = NULL;
	uint32 recvLength;
	DWORD nBytesReturned;
	DWORD outBufferSize;

	stream_seek(irp->input, 0x14);
	stream_read_uint32(irp->input, map[0]);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, map[1]);
	stream_read_uint32(irp->input, controlCode);
	stream_read_uint32(irp->input, recvLength);
	stream_read_uint32(irp->input, map[2]);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, outBufferSize);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hContext);
	stream_seek(irp->input, 0x4);
	stream_read_uint32(irp->input, hCard);

	/* Translate Windows SCARD_CTL_CODE's to corresponding local code */
	if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD)
	{
		controlFunction = WIN_CTL_FUNCTION(controlCode);
		controlCode = SCARD_CTL_CODE(controlFunction);
	}
	DEBUG_SCARD("controlCode: 0x%08x", (unsigned) controlCode);

	if (map[2] & SCARD_INPUT_LINKED)
	{
		/* read real input size */
		stream_read_uint32(irp->input, recvLength);

		recvBuffer = xmalloc(recvLength);

		if (!recvBuffer)
			return sc_output_return(irp, SCARD_E_NO_MEMORY);

		stream_read(irp->input, recvBuffer, recvLength);
	}

	nBytesReturned = outBufferSize;
	sendBuffer = xmalloc(outBufferSize);

	if (!sendBuffer)
		return sc_output_return(irp, SCARD_E_NO_MEMORY);

	rv = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength,
		sendBuffer, (DWORD) outBufferSize, &nBytesReturned);

	if (rv != SCARD_S_SUCCESS)
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
	else
		DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned);

	stream_write_uint32(irp->output, (uint32) nBytesReturned);
	stream_write_uint32(irp->output, 0x00000004);
	stream_write_uint32(irp->output, nBytesReturned);

	if (nBytesReturned > 0)
	{
		stream_write(irp->output, sendBuffer, nBytesReturned);
		sc_output_repos(irp, nBytesReturned);
	}

	sc_output_alignment(irp, 8);

	xfree(recvBuffer);
	xfree(sendBuffer);

	return rv;
}
Ejemplo n.º 21
0
static uint32 handle_ListReaders(IRP* irp, tbool wide)
{
	uint32 len, rv;
	SCARDCONTEXT hContext;
	DWORD dwReaders;
	char *readerList = NULL, *walker;
	int elemLength, dataLength;
	int pos, poslen1, poslen2;

	stream_seek(irp->input, 8);
	stream_read_uint32(irp->input, len);

	stream_seek(irp->input, 0x1c);
	stream_read_uint32(irp->input, len);

	if (len != 4)
		return SCARD_F_INTERNAL_ERROR;

	stream_read_uint32(irp->input, hContext);

	/* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */

	rv = SCARD_S_SUCCESS;
#ifdef SCARD_AUTOALLOCATE
	dwReaders = SCARD_AUTOALLOCATE;
	rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders);
#else
	rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);

	readerList = xmalloc(dwReaders);
	rv = SCardListReaders(hContext, NULL, readerList, &dwReaders);
#endif
	if (rv != SCARD_S_SUCCESS)
	{
		DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv);
		return rv;
	}

/*	DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/

	poslen1 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	stream_write_uint32(irp->output, 0x01760650);

	poslen2 = stream_get_pos(irp->output);
	stream_seek_uint32(irp->output);

	walker = readerList;
	dataLength = 0;

	while (1)
	{
		elemLength = strlen(walker);
		if (elemLength == 0)
			break;

		dataLength += sc_output_string(irp, walker, wide);
		walker += elemLength + 1;
		elemLength = strlen(walker);
	}

	dataLength += sc_output_string(irp, "\0", wide);

	pos = stream_get_pos(irp->output);

	stream_set_pos(irp->output, poslen1);
	stream_write_uint32(irp->output, dataLength);
	stream_set_pos(irp->output, poslen2);
	stream_write_uint32(irp->output, dataLength);

	stream_set_pos(irp->output, pos);

	sc_output_repos(irp, dataLength);
	sc_output_alignment(irp, 8);

#ifdef SCARD_AUTOALLOCATE
	SCardFreeMemory(hContext, readerList);
#else
	xfree(readerList);
#endif

	return rv;
}