Blame scripts/test-scard.cpp

Packit Service 5a9772
/**
Packit Service 5a9772
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit Service 5a9772
 * Smartcard API test program
Packit Service 5a9772
 *
Packit Service 5a9772
 * This simple program can be used to trigger calls for (almost) the
Packit Service 5a9772
 * entire SCARD API.
Packit Service 5a9772
 * Compile on windows, connect with FreeRDP via RDP with smartcard
Packit Service 5a9772
 * redirection enabled and run this test program on the windows
Packit Service 5a9772
 * machine.
Packit Service 5a9772
 *
Packit Service 5a9772
 * Copyright 2020 Armin Novak <armin.novak@thincast.com>
Packit Service 5a9772
 * Copyright 2020 Thincast Technologies GmbH
Packit Service 5a9772
 *
Packit Service 5a9772
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service 5a9772
 * you may not use this file except in compliance with the License.
Packit Service 5a9772
 * You may obtain a copy of the License at
Packit Service 5a9772
 *
Packit Service 5a9772
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service 5a9772
 *
Packit Service 5a9772
 * Unless required by applicable law or agreed to in writing, software
Packit Service 5a9772
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service 5a9772
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service 5a9772
 * See the License for the specific language governing permissions and
Packit Service 5a9772
 * limitations under the License.
Packit Service 5a9772
 */
Packit Service 5a9772
Packit Service 5a9772
#include <iostream>
Packit Service 5a9772
#include <string>
Packit Service 5a9772
#include <sstream>
Packit Service 5a9772
#include <locale>
Packit Service 5a9772
#include <codecvt>
Packit Service 5a9772
Packit Service 5a9772
#include <comdef.h>
Packit Service 5a9772
#include <winscard.h>
Packit Service 5a9772
Packit Service 5a9772
static const WCHAR* listW[] = { nullptr, L"SCard$AllReaders\000", L"SCard$DefaultReaders\000",
Packit Service 5a9772
	                            L"SCard$LocalReaders\000", L"SCard$SystemReaders\000" };
Packit Service 5a9772
static const char* listA[] = { nullptr, "SCard$AllReaders\000", "SCard$DefaultReaders\000",
Packit Service 5a9772
	                           "SCard$LocalReaders\000", "SCard$SystemReaders\000" };
Packit Service 5a9772
Packit Service 5a9772
static std::string scope2str(DWORD scope)
Packit Service 5a9772
{
Packit Service 5a9772
	switch (scope)
Packit Service 5a9772
	{
Packit Service 5a9772
		case SCARD_SCOPE_USER:
Packit Service 5a9772
			return "SCARD_SCOPE_USER";
Packit Service 5a9772
		case SCARD_SCOPE_TERMINAL:
Packit Service 5a9772
			return "SCARD_SCOPE_TERMINAL";
Packit Service 5a9772
		case SCARD_SCOPE_SYSTEM:
Packit Service 5a9772
			return "SCARD_SCOPE_SYSTEM";
Packit Service 5a9772
		default:
Packit Service 5a9772
			return "UNKNOWN";
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static std::string err2str(LONG code)
Packit Service 5a9772
{
Packit Service 5a9772
	switch (code)
Packit Service 5a9772
	{
Packit Service 5a9772
		case ERROR_BROKEN_PIPE:
Packit Service 5a9772
			return "ERROR_BROKEN_PIPE";
Packit Service 5a9772
		case SCARD_E_BAD_SEEK:
Packit Service 5a9772
			return "SCARD_E_BAD_SEEK";
Packit Service 5a9772
		case SCARD_E_CANCELLED:
Packit Service 5a9772
			return "SCARD_E_CANCELLED";
Packit Service 5a9772
		case SCARD_E_CANT_DISPOSE:
Packit Service 5a9772
			return "SCARD_E_CANT_DISPOSE";
Packit Service 5a9772
		case SCARD_E_CARD_UNSUPPORTED:
Packit Service 5a9772
			return "SCARD_E_CARD_UNSUPPORTED";
Packit Service 5a9772
		case SCARD_E_CERTIFICATE_UNAVAILABLE:
Packit Service 5a9772
			return "SCARD_E_CERTIFICATE_UNAVAILABLE";
Packit Service 5a9772
		case SCARD_E_COMM_DATA_LOST:
Packit Service 5a9772
			return "SCARD_E_COMM_DATA_LOST";
Packit Service 5a9772
		case SCARD_E_DIR_NOT_FOUND:
Packit Service 5a9772
			return "SCARD_E_DIR_NOT_FOUND";
Packit Service 5a9772
		case SCARD_E_DUPLICATE_READER:
Packit Service 5a9772
			return "SCARD_E_DUPLICATE_READER";
Packit Service 5a9772
		case SCARD_E_FILE_NOT_FOUND:
Packit Service 5a9772
			return "SCARD_E_FILE_NOT_FOUND";
Packit Service 5a9772
		case SCARD_E_ICC_CREATEORDER:
Packit Service 5a9772
			return "SCARD_E_ICC_CREATEORDER";
Packit Service 5a9772
		case SCARD_E_ICC_INSTALLATION:
Packit Service 5a9772
			return "SCARD_E_ICC_INSTALLATION";
Packit Service 5a9772
		case SCARD_E_INSUFFICIENT_BUFFER:
Packit Service 5a9772
			return "SCARD_E_INSUFFICIENT_BUFFER";
Packit Service 5a9772
		case SCARD_E_INVALID_ATR:
Packit Service 5a9772
			return "SCARD_E_INVALID_ATR";
Packit Service 5a9772
		case SCARD_E_INVALID_CHV:
Packit Service 5a9772
			return "SCARD_E_INVALID_CHV";
Packit Service 5a9772
		case SCARD_E_INVALID_HANDLE:
Packit Service 5a9772
			return "SCARD_E_INVALID_HANDLE";
Packit Service 5a9772
		case SCARD_E_INVALID_PARAMETER:
Packit Service 5a9772
			return "SCARD_E_INVALID_PARAMETER";
Packit Service 5a9772
		case SCARD_E_INVALID_TARGET:
Packit Service 5a9772
			return "SCARD_E_INVALID_TARGET";
Packit Service 5a9772
		case SCARD_E_INVALID_VALUE:
Packit Service 5a9772
			return "SCARD_E_INVALID_VALUE";
Packit Service 5a9772
		case SCARD_E_NO_ACCESS:
Packit Service 5a9772
			return "SCARD_E_NO_ACCESS";
Packit Service 5a9772
		case SCARD_E_NO_DIR:
Packit Service 5a9772
			return "SCARD_E_NO_DIR";
Packit Service 5a9772
		case SCARD_E_NO_FILE:
Packit Service 5a9772
			return "SCARD_E_NO_FILE";
Packit Service 5a9772
		case SCARD_E_NO_KEY_CONTAINER:
Packit Service 5a9772
			return "SCARD_E_NO_KEY_CONTAINER";
Packit Service 5a9772
		case SCARD_E_NO_MEMORY:
Packit Service 5a9772
			return "SCARD_E_NO_MEMORY";
Packit Service 5a9772
		case SCARD_E_NO_PIN_CACHE:
Packit Service 5a9772
			return "SCARD_E_NO_PIN_CACHE";
Packit Service 5a9772
		case SCARD_E_NO_READERS_AVAILABLE:
Packit Service 5a9772
			return "SCARD_E_NO_READERS_AVAILABLE";
Packit Service 5a9772
		case SCARD_E_NO_SERVICE:
Packit Service 5a9772
			return "SCARD_E_NO_SERVICE";
Packit Service 5a9772
		case SCARD_E_NO_SMARTCARD:
Packit Service 5a9772
			return "SCARD_E_NO_SMARTCARD";
Packit Service 5a9772
		case SCARD_E_NO_SUCH_CERTIFICATE:
Packit Service 5a9772
			return "SCARD_E_NO_SUCH_CERTIFICATE";
Packit Service 5a9772
		case SCARD_E_NOT_READY:
Packit Service 5a9772
			return "SCARD_E_NOT_READY";
Packit Service 5a9772
		case SCARD_E_NOT_TRANSACTED:
Packit Service 5a9772
			return "SCARD_E_NOT_TRANSACTED";
Packit Service 5a9772
		case SCARD_E_PCI_TOO_SMALL:
Packit Service 5a9772
			return "SCARD_E_PCI_TOO_SMALL";
Packit Service 5a9772
		case SCARD_E_PIN_CACHE_EXPIRED:
Packit Service 5a9772
			return "SCARD_E_PIN_CACHE_EXPIRED";
Packit Service 5a9772
		case SCARD_E_PROTO_MISMATCH:
Packit Service 5a9772
			return "SCARD_E_PROTO_MISMATCH";
Packit Service 5a9772
		case SCARD_E_READ_ONLY_CARD:
Packit Service 5a9772
			return "SCARD_E_READ_ONLY_CARD";
Packit Service 5a9772
		case SCARD_E_READER_UNAVAILABLE:
Packit Service 5a9772
			return "SCARD_E_READER_UNAVAILABLE";
Packit Service 5a9772
		case SCARD_E_READER_UNSUPPORTED:
Packit Service 5a9772
			return "SCARD_E_READER_UNSUPPORTED";
Packit Service 5a9772
		case SCARD_E_SERVER_TOO_BUSY:
Packit Service 5a9772
			return "SCARD_E_SERVER_TOO_BUSY";
Packit Service 5a9772
		case SCARD_E_SERVICE_STOPPED:
Packit Service 5a9772
			return "SCARD_E_SERVICE_STOPPED";
Packit Service 5a9772
		case SCARD_E_SHARING_VIOLATION:
Packit Service 5a9772
			return "SCARD_E_SHARING_VIOLATION";
Packit Service 5a9772
		case SCARD_E_SYSTEM_CANCELLED:
Packit Service 5a9772
			return "SCARD_E_SYSTEM_CANCELLED";
Packit Service 5a9772
		case SCARD_E_TIMEOUT:
Packit Service 5a9772
			return "SCARD_E_TIMEOUT";
Packit Service 5a9772
		case SCARD_E_UNEXPECTED:
Packit Service 5a9772
			return "SCARD_E_UNEXPECTED";
Packit Service 5a9772
		case SCARD_E_UNKNOWN_CARD:
Packit Service 5a9772
			return "SCARD_E_UNKNOWN_CARD";
Packit Service 5a9772
		case SCARD_E_UNKNOWN_READER:
Packit Service 5a9772
			return "SCARD_E_UNKNOWN_READER";
Packit Service 5a9772
		case SCARD_E_UNKNOWN_RES_MNG:
Packit Service 5a9772
			return "SCARD_E_UNKNOWN_RES_MNG";
Packit Service 5a9772
		case SCARD_E_UNSUPPORTED_FEATURE:
Packit Service 5a9772
			return "SCARD_E_UNSUPPORTED_FEATURE";
Packit Service 5a9772
		case SCARD_E_WRITE_TOO_MANY:
Packit Service 5a9772
			return "SCARD_E_WRITE_TOO_MANY";
Packit Service 5a9772
		case SCARD_F_COMM_ERROR:
Packit Service 5a9772
			return "SCARD_F_COMM_ERROR";
Packit Service 5a9772
		case SCARD_F_INTERNAL_ERROR:
Packit Service 5a9772
			return "SCARD_F_INTERNAL_ERROR";
Packit Service 5a9772
		case SCARD_F_UNKNOWN_ERROR:
Packit Service 5a9772
			return "SCARD_F_UNKNOWN_ERROR";
Packit Service 5a9772
		case SCARD_F_WAITED_TOO_LONG:
Packit Service 5a9772
			return "SCARD_F_WAITED_TOO_LONG";
Packit Service 5a9772
		case SCARD_P_SHUTDOWN:
Packit Service 5a9772
			return "SCARD_P_SHUTDOWN";
Packit Service 5a9772
		case SCARD_S_SUCCESS:
Packit Service 5a9772
			return "SCARD_S_SUCCESS";
Packit Service 5a9772
		case SCARD_W_CANCELLED_BY_USER:
Packit Service 5a9772
			return "SCARD_W_CANCELLED_BY_USER";
Packit Service 5a9772
		case SCARD_W_CACHE_ITEM_NOT_FOUND:
Packit Service 5a9772
			return "SCARD_W_CACHE_ITEM_NOT_FOUND";
Packit Service 5a9772
		case SCARD_W_CACHE_ITEM_STALE:
Packit Service 5a9772
			return "SCARD_W_CACHE_ITEM_STALE";
Packit Service 5a9772
		case SCARD_W_CACHE_ITEM_TOO_BIG:
Packit Service 5a9772
			return "SCARD_W_CACHE_ITEM_TOO_BIG";
Packit Service 5a9772
		case SCARD_W_CARD_NOT_AUTHENTICATED:
Packit Service 5a9772
			return "SCARD_W_CARD_NOT_AUTHENTICATED";
Packit Service 5a9772
		case SCARD_W_CHV_BLOCKED:
Packit Service 5a9772
			return "SCARD_W_CHV_BLOCKED";
Packit Service 5a9772
		case SCARD_W_EOF:
Packit Service 5a9772
			return "SCARD_W_EOF";
Packit Service 5a9772
		case SCARD_W_REMOVED_CARD:
Packit Service 5a9772
			return "SCARD_W_REMOVED_CARD";
Packit Service 5a9772
		case SCARD_W_RESET_CARD:
Packit Service 5a9772
			return "SCARD_W_RESET_CARD";
Packit Service 5a9772
		case SCARD_W_SECURITY_VIOLATION:
Packit Service 5a9772
			return "SCARD_W_SECURITY_VIOLATION";
Packit Service 5a9772
		case SCARD_W_UNPOWERED_CARD:
Packit Service 5a9772
			return "SCARD_W_UNPOWERED_CARD";
Packit Service 5a9772
		case SCARD_W_UNRESPONSIVE_CARD:
Packit Service 5a9772
			return "SCARD_W_UNRESPONSIVE_CARD";
Packit Service 5a9772
		case SCARD_W_UNSUPPORTED_CARD:
Packit Service 5a9772
			return "SCARD_W_UNSUPPORTED_CARD";
Packit Service 5a9772
		case SCARD_W_WRONG_CHV:
Packit Service 5a9772
			return "SCARD_W_WRONG_CHV";
Packit Service 5a9772
		default:
Packit Service 5a9772
			return "UNKNOWN";
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static std::wstring err2wstr(LONG code)
Packit Service 5a9772
{
Packit Service 5a9772
	auto str = err2str(code);
Packit Service 5a9772
	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
Packit Service 5a9772
	return converter.from_bytes(str);
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
#if 0
Packit Service 5a9772
static bool test_listreadergroups(SCARDCONTEXT hContext) {
Packit Service 5a9772
    auto rc = SCardListReaderGroupsA(hContext, &groups, &foobar);
Packit Service 5a9772
    rc = SCardListReaderGroupsW(hContext, &groups, &foobar);
Packit Service 5a9772
}
Packit Service 5a9772
#endif
Packit Service 5a9772
Packit Service 5a9772
static bool test_valid(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	auto rc = SCardIsValidContext(context);
Packit Service 5a9772
	if (rc)
Packit Service 5a9772
		std::cerr << "SCardIsValidContext failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_readers_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	for (auto cur : listA)
Packit Service 5a9772
	{
Packit Service 5a9772
		LPSTR mszReaders = nullptr;
Packit Service 5a9772
		DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
		auto rc = SCardListReadersA(context, cur, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
		if (!cur)
Packit Service 5a9772
		{
Packit Service 5a9772
			cur = "NULL";
Packit Service 5a9772
		}
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cerr << "SCardListReadersA [" << cur << "] failed with " << err2str(rc)
Packit Service 5a9772
			          << std::endl;
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			auto start = mszReaders;
Packit Service 5a9772
			auto end = &mszReaders[chReaders];
Packit Service 5a9772
Packit Service 5a9772
			std::cout << "SCardListReadersA [" << cur << "] " << chReaders << " [";
Packit Service 5a9772
			while (start < end)
Packit Service 5a9772
			{
Packit Service 5a9772
				std::cout << start << ", ";
Packit Service 5a9772
				start += strnlen(start, chReaders) + 2;
Packit Service 5a9772
			}
Packit Service 5a9772
			std::cout << "]" << std::endl;
Packit Service 5a9772
		}
Packit Service 5a9772
		SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_readers_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	for (auto cur : listW)
Packit Service 5a9772
	{
Packit Service 5a9772
		LPWSTR mszReaders = nullptr;
Packit Service 5a9772
		DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
		auto rc =
Packit Service 5a9772
		    SCardListReadersW(context, cur, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
		if (!cur)
Packit Service 5a9772
		{
Packit Service 5a9772
			cur = L"NULL";
Packit Service 5a9772
		}
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::wcerr << L"SCardListReadersW [" << cur << L"] failed with " << err2wstr(rc)
Packit Service 5a9772
			           << std::endl;
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			auto start = mszReaders;
Packit Service 5a9772
			auto end = &mszReaders[chReaders];
Packit Service 5a9772
Packit Service 5a9772
			std::wcout << L"SCardListReadersW [" << cur << L"] " << chReaders << L" [";
Packit Service 5a9772
			while (start < end)
Packit Service 5a9772
			{
Packit Service 5a9772
				std::wcout << start << L", ";
Packit Service 5a9772
				start += wcsnlen(start, chReaders) + 2;
Packit Service 5a9772
			}
Packit Service 5a9772
			std::wcout << L"]" << std::endl;
Packit Service 5a9772
		}
Packit Service 5a9772
		SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_reader_groups_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPSTR mszReaders = nullptr;
Packit Service 5a9772
	DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	auto rc = SCardListReaderGroupsA(context, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardListReaderGroupsA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		auto start = mszReaders;
Packit Service 5a9772
		auto end = &mszReaders[chReaders];
Packit Service 5a9772
Packit Service 5a9772
		std::cout << "SCardListReaderGroupsA " << chReaders << " [";
Packit Service 5a9772
		while (start < end)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cout << start << ", ";
Packit Service 5a9772
			start += strnlen(start, chReaders) + 2;
Packit Service 5a9772
		}
Packit Service 5a9772
		std::cout << "]" << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_reader_groups_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPWSTR mszReaders = nullptr;
Packit Service 5a9772
	DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	auto rc = SCardListReaderGroupsW(context, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::wcerr << L"SCardListReaderGroupsW failed with " << err2wstr(rc) << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		auto start = mszReaders;
Packit Service 5a9772
		auto end = &mszReaders[chReaders];
Packit Service 5a9772
Packit Service 5a9772
		std::wcout << L"SCardListReaderGroupsW " << chReaders << L" [";
Packit Service 5a9772
		while (start < end)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::wcout << start << L", ";
Packit Service 5a9772
			start += wcsnlen(start, chReaders) + 2;
Packit Service 5a9772
		}
Packit Service 5a9772
		std::wcout << L"]" << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_introduce_forget_reader_groups_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPSTR group = "somefancygroup";
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardIntroduceReaderGroupA(context, group);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardIntroduceReaderGroupA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		rc = SCardForgetReaderGroupA(context, group);
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cerr << "SCardForgetReaderGroupA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
			return false;
Packit Service 5a9772
		}
Packit Service 5a9772
		return true;
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_introduce_forget_reader_groups_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPWSTR group = L"somefancygroup";
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardIntroduceReaderGroupW(context, group);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardIntroduceReaderGroupW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		rc = SCardForgetReaderGroupW(context, group);
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cerr << "SCardForgetReaderGroupW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
			return false;
Packit Service 5a9772
		}
Packit Service 5a9772
		return true;
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_introduce_forget_reader_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPSTR reader = "somefancygroup";
Packit Service 5a9772
	LPSTR device = "otherfancy";
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardIntroduceReaderA(context, reader, device);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardIntroduceReaderA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		rc = SCardForgetReaderA(context, reader);
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cerr << "SCardForgetReaderA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
			return false;
Packit Service 5a9772
		}
Packit Service 5a9772
		return true;
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_introduce_forget_reader_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPWSTR reader = L"somefancygroup";
Packit Service 5a9772
	LPWSTR device = L"otherfancy";
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardIntroduceReaderW(context, reader, device);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardIntroduceReaderW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		rc = SCardForgetReaderW(context, reader);
Packit Service 5a9772
		if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cerr << "SCardForgetReaderW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
			return false;
Packit Service 5a9772
		}
Packit Service 5a9772
		return true;
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_cards_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	DWORD chCards = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	LPSTR mszCards = nullptr;
Packit Service 5a9772
	auto rc =
Packit Service 5a9772
	    SCardListCardsA(context, nullptr, nullptr, 0, reinterpret_cast<LPSTR>(&mszCards), &chCards);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardListCardsA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		auto start = mszCards;
Packit Service 5a9772
		auto end = &mszCards[chCards];
Packit Service 5a9772
		std::cout << "SCardListCardsA " << chCards << " [";
Packit Service 5a9772
		while (start < end)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::cout << start << ", ";
Packit Service 5a9772
			start += strnlen(start, chCards) + 2;
Packit Service 5a9772
		}
Packit Service 5a9772
		std::cout << "]" << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_list_cards_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	DWORD chCards = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	LPWSTR mszCards = nullptr;
Packit Service 5a9772
	auto rc = SCardListCardsW(context, nullptr, nullptr, 0, reinterpret_cast<LPWSTR>(&mszCards),
Packit Service 5a9772
	                          &chCards);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardListCardsW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		auto start = mszCards;
Packit Service 5a9772
		auto end = &mszCards[chCards];
Packit Service 5a9772
		std::cout << "SCardListCardsW " << chCards << " [";
Packit Service 5a9772
		while (start < end)
Packit Service 5a9772
		{
Packit Service 5a9772
			std::wcout << start << L", ";
Packit Service 5a9772
			start += wcsnlen(start, chCards) + 2;
Packit Service 5a9772
		}
Packit Service 5a9772
		std::cout << "]" << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_cache_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Packit Service 5a9772
	const DWORD wdatalen = sizeof(wdata);
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	DWORD datalen = sizeof(data);
Packit Service 5a9772
	LPSTR name = "testdata";
Packit Service 5a9772
	UUID id = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardWriteCacheA(context, &id, 0, name, wdata, wdatalen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardWriteCacheA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	rc = SCardReadCacheA(context, &id, 0, name, data, &datalen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardReadCacheA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (wdatalen != datalen)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardWriteCacheA wrote " << wdatalen << "bytes, SCardReadCacheA read "
Packit Service 5a9772
		          << datalen << "bytes" << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (memcmp(wdata, data, wdatalen) != 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardWriteCacheA / SCardReadCacheA data corruption detected" << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_cache_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Packit Service 5a9772
	const DWORD wdatalen = sizeof(wdata);
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	DWORD datalen = sizeof(data);
Packit Service 5a9772
	LPWSTR name = L"testdata";
Packit Service 5a9772
	UUID id = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardWriteCacheW(context, &id, 0, name, wdata, wdatalen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardWriteCacheW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	rc = SCardReadCacheW(context, &id, 0, name, data, &datalen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardReadCacheW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (wdatalen != datalen)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardReadCacheW wrote " << wdatalen << "bytes, SCardReadCacheW read "
Packit Service 5a9772
		          << datalen << "bytes" << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (memcmp(wdata, data, wdatalen) != 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardReadCacheW / SCardReadCacheW data corruption detected" << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_reader_icon_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
Packit Service 5a9772
	LPBYTE pbIcon = nullptr;
Packit Service 5a9772
	DWORD cbIcon = SCARD_AUTOALLOCATE;
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardGetReaderIconA(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
Packit Service 5a9772
	SCardFreeMemory(context, pbIcon);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetReaderIconA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_reader_icon_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
Packit Service 5a9772
	LPBYTE pbIcon = nullptr;
Packit Service 5a9772
	DWORD cbIcon = SCARD_AUTOALLOCATE;
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardGetReaderIconW(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
Packit Service 5a9772
	SCardFreeMemory(context, pbIcon);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetReaderIconW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_locate_cards_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
Packit Service 5a9772
	SCARD_READERSTATEA rgReaderStates[16] = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardLocateCardsA(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardLocateCardsA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_locate_cards_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
Packit Service 5a9772
	SCARD_READERSTATEW rgReaderStates[16] = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardLocateCardsW(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardLocateCardsW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_locate_cards_by_atr_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	SCARD_READERSTATEA rgReaderStates[16] = {};
Packit Service 5a9772
	SCARD_ATRMASK rgAtrMasks[16] = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardLocateCardsByATRA(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
Packit Service 5a9772
	                                 ARRAYSIZE(rgReaderStates));
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardLocateCardsByATRA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_locate_cards_by_atr_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	SCARD_READERSTATEW rgReaderStates[16] = {};
Packit Service 5a9772
	SCARD_ATRMASK rgAtrMasks[16] = {};
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardLocateCardsByATRW(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
Packit Service 5a9772
	                                 ARRAYSIZE(rgReaderStates));
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardLocateCardsByATRW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_devicetype_id_a(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	LPSTR name = "testdata";
Packit Service 5a9772
	DWORD type;
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardGetDeviceTypeIdA(context, name, &type);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetDeviceTypeIdA failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_devicetype_id_w(SCARDCONTEXT context)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	LPWSTR name = L"testdata";
Packit Service 5a9772
	DWORD type;
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardGetDeviceTypeIdW(context, name, &type);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_transmitcount(SCARDHANDLE handle)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	LPWSTR name = L"testdata";
Packit Service 5a9772
	DWORD count;
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardGetTransmitCount(handle, &count);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetTransmitCount failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	std::cout << "SCardGetTransmitCount() " << count << std::endl;
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_status_a(SCARDHANDLE handle)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	LPWSTR name = L"testdata";
Packit Service 5a9772
	DWORD count;
Packit Service 5a9772
	/*
Packit Service 5a9772
	    auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
Packit Service 5a9772
	    if (rc != SCARD_S_SUCCESS) {
Packit Service 5a9772
	        std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	        return false;
Packit Service 5a9772
	    }
Packit Service 5a9772
	*/
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_status_w(SCARDHANDLE handle)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE data[32] = {};
Packit Service 5a9772
	LPWSTR name = L"testdata";
Packit Service 5a9772
	DWORD count;
Packit Service 5a9772
	/*
Packit Service 5a9772
	auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS) {
Packit Service 5a9772
	    std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
	    return false;
Packit Service 5a9772
	}
Packit Service 5a9772
*/
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_get_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
Packit Service 5a9772
{
Packit Service 5a9772
	DWORD attrlen = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	LPBYTE attr = nullptr;
Packit Service 5a9772
Packit Service 5a9772
	auto rc =
Packit Service 5a9772
	    SCardGetAttrib(handle, SCARD_ATTR_ATR_STRING, reinterpret_cast<LPBYTE>(&attr), &attrlen);
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardGetAttrib failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	std::cout << "SCardGetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
Packit Service 5a9772
	SCardFreeMemory(context, attr);
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static bool test_set_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
Packit Service 5a9772
{
Packit Service 5a9772
	DWORD attrlen = SCARD_AUTOALLOCATE;
Packit Service 5a9772
	BYTE attr[] = "0123456789";
Packit Service 5a9772
Packit Service 5a9772
	auto rc = SCardSetAttrib(handle, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST, attr, ARRAYSIZE(attr));
Packit Service 5a9772
	if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "SCardSetAttrib failed with " << err2str(rc) << std::endl;
Packit Service 5a9772
		return false;
Packit Service 5a9772
	}
Packit Service 5a9772
	std::cout << "SCardSetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
Packit Service 5a9772
	SCardFreeMemory(context, attr);
Packit Service 5a9772
Packit Service 5a9772
	return true;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
int main()
Packit Service 5a9772
{
Packit Service 5a9772
	std::cout << "Hello World!" << std::endl;
Packit Service 5a9772
	try
Packit Service 5a9772
	{
Packit Service 5a9772
		auto scopes = { SCARD_SCOPE_USER, SCARD_SCOPE_SYSTEM };
Packit Service 5a9772
		for (auto scope : scopes)
Packit Service 5a9772
		{
Packit Service 5a9772
			SCARDCONTEXT context;
Packit Service 5a9772
			auto rc = SCardEstablishContext(scope, nullptr, nullptr, &context);
Packit Service 5a9772
			if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
			{
Packit Service 5a9772
				std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] failed with "
Packit Service 5a9772
				          << err2str(rc) << std::endl;
Packit Service 5a9772
			}
Packit Service 5a9772
			else
Packit Service 5a9772
			{
Packit Service 5a9772
				std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] success"
Packit Service 5a9772
				          << std::endl;
Packit Service 5a9772
Packit Service 5a9772
				test_valid(context);
Packit Service 5a9772
Packit Service 5a9772
				test_list_reader_groups_a(context);
Packit Service 5a9772
				test_list_reader_groups_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_list_readers_a(context);
Packit Service 5a9772
				test_list_readers_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_list_cards_a(context);
Packit Service 5a9772
				test_list_cards_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_introduce_forget_reader_groups_a(context);
Packit Service 5a9772
				test_introduce_forget_reader_groups_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_introduce_forget_reader_a(context);
Packit Service 5a9772
				test_introduce_forget_reader_w(context);
Packit Service 5a9772
Packit Service 5a9772
				// TODO: Introduce/Remove reader to group
Packit Service 5a9772
				test_locate_cards_a(context);
Packit Service 5a9772
				test_locate_cards_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_locate_cards_by_atr_a(context);
Packit Service 5a9772
				test_locate_cards_by_atr_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_cache_a(context);
Packit Service 5a9772
				test_cache_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_reader_icon_a(context);
Packit Service 5a9772
				test_reader_icon_w(context);
Packit Service 5a9772
Packit Service 5a9772
				test_devicetype_id_a(context);
Packit Service 5a9772
				test_devicetype_id_w(context);
Packit Service 5a9772
Packit Service 5a9772
				// TODO: statuschange
Packit Service 5a9772
				// TODO: begin/end transaction
Packit Service 5a9772
				// TODO: state
Packit Service 5a9772
				// TODO: transmit
Packit Service 5a9772
				// TODO: control
Packit Service 5a9772
Packit Service 5a9772
				{
Packit Service 5a9772
					DWORD protocol;
Packit Service 5a9772
					SCARDHANDLE handle = 0;
Packit Service 5a9772
					LPSTR mszReaders;
Packit Service 5a9772
					DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
Packit Service 5a9772
					LONG status = SCardListReadersA(
Packit Service 5a9772
					    context, nullptr, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
					if (status == SCARD_S_SUCCESS)
Packit Service 5a9772
						status = SCardConnectA(context, mszReaders, SCARD_SHARE_SHARED,
Packit Service 5a9772
						                       SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
Packit Service 5a9772
						                           SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
Packit Service 5a9772
						                       &handle, &protocol);
Packit Service 5a9772
					SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
					if (status != SCARD_S_SUCCESS)
Packit Service 5a9772
					{
Packit Service 5a9772
						std::cerr << "SCardConnectA ["
Packit Service 5a9772
						          << "] failed with " << err2str(status) << std::endl;
Packit Service 5a9772
					}
Packit Service 5a9772
					else
Packit Service 5a9772
					{
Packit Service 5a9772
						test_status_a(handle);
Packit Service 5a9772
						test_status_w(handle);
Packit Service 5a9772
						test_get_attrib(context, handle);
Packit Service 5a9772
						test_set_attrib(context, handle);
Packit Service 5a9772
						test_transmitcount(handle);
Packit Service 5a9772
Packit Service 5a9772
						status = SCardDisconnect(handle, 0);
Packit Service 5a9772
						if (status)
Packit Service 5a9772
						{
Packit Service 5a9772
							std::cerr << "SCardDisconnect ["
Packit Service 5a9772
							          << "] failed with " << err2str(status) << std::endl;
Packit Service 5a9772
						}
Packit Service 5a9772
					}
Packit Service 5a9772
				}
Packit Service 5a9772
				{
Packit Service 5a9772
					DWORD protocol;
Packit Service 5a9772
					SCARDHANDLE handle = 0;
Packit Service 5a9772
					LPWSTR mszReaders;
Packit Service 5a9772
					DWORD chReaders = SCARD_AUTOALLOCATE;
Packit Service 5a9772
Packit Service 5a9772
					LONG status = SCardListReadersW(
Packit Service 5a9772
					    context, nullptr, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
Packit Service 5a9772
					if (status == SCARD_S_SUCCESS)
Packit Service 5a9772
						status = SCardConnectW(context, mszReaders, SCARD_SHARE_SHARED,
Packit Service 5a9772
						                       SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
Packit Service 5a9772
						                           SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
Packit Service 5a9772
						                       &handle, &protocol);
Packit Service 5a9772
					SCardFreeMemory(context, mszReaders);
Packit Service 5a9772
Packit Service 5a9772
					if (status != SCARD_S_SUCCESS)
Packit Service 5a9772
					{
Packit Service 5a9772
						std::cerr << "SCardConnectW ["
Packit Service 5a9772
						          << "] failed with " << err2str(status) << std::endl;
Packit Service 5a9772
					}
Packit Service 5a9772
					else
Packit Service 5a9772
					{
Packit Service 5a9772
						test_status_a(handle);
Packit Service 5a9772
						test_status_w(handle);
Packit Service 5a9772
						test_get_attrib(context, handle);
Packit Service 5a9772
						test_set_attrib(context, handle);
Packit Service 5a9772
						test_transmitcount(handle);
Packit Service 5a9772
Packit Service 5a9772
						status = SCardDisconnect(handle, 0);
Packit Service 5a9772
						if (status)
Packit Service 5a9772
						{
Packit Service 5a9772
							std::cerr << "SCardDisconnect ["
Packit Service 5a9772
							          << "] failed with " << err2str(status) << std::endl;
Packit Service 5a9772
						}
Packit Service 5a9772
					}
Packit Service 5a9772
				}
Packit Service 5a9772
Packit Service 5a9772
				rc = SCardReleaseContext(context);
Packit Service 5a9772
				if (rc != SCARD_S_SUCCESS)
Packit Service 5a9772
				{
Packit Service 5a9772
					std::cerr << "SCardReleaseContext [" << scope2str(scope) << "] failed with "
Packit Service 5a9772
					          << err2str(rc) << std::endl;
Packit Service 5a9772
				}
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit Service 5a9772
	}
Packit Service 5a9772
	catch (...)
Packit Service 5a9772
	{
Packit Service 5a9772
		std::cerr << "exception!!!!" << std::endl;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return 0;
Packit Service 5a9772
}