From 3a428b87dfa68422a900a98df1cf06352d88bf01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Moreau?= Date: Tue, 8 Apr 2014 01:26:28 -0400 Subject: [PATCH] libwinpr-smartcard: add option to build statically against specialized pcsclite build --- CMakeLists.txt | 2 + cmake/FindPCSC.cmake | 12 +- cmake/FindPCSCWinPR.cmake | 15 +++ winpr/libwinpr/smartcard/CMakeLists.txt | 9 ++ winpr/libwinpr/smartcard/smartcard_link.c | 142 ++++++++++++++++++++++ winpr/libwinpr/smartcard/smartcard_pcsc.c | 33 ++++- 6 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 cmake/FindPCSCWinPR.cmake create mode 100644 winpr/libwinpr/smartcard/smartcard_link.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f3253a69e..2d65fece2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -341,6 +341,8 @@ else() set(X11_FEATURE_TYPE "DISABLED") endif() +find_package(PCSCWinPR) + set(X11_FEATURE_PURPOSE "X11") set(X11_FEATURE_DESCRIPTION "X11 client and server") diff --git a/cmake/FindPCSC.cmake b/cmake/FindPCSC.cmake index 8097010b8..16a59e8e3 100644 --- a/cmake/FindPCSC.cmake +++ b/cmake/FindPCSC.cmake @@ -5,16 +5,17 @@ # PCSC_LIBRARIES - libraries needed for linking include(FindPkgConfig) -if (PKG_CONFIG_FOUND) - pkg_check_modules(PC_PCSC QUIET libpcsclite) + +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_PCSC QUIET libpcsclite) endif() find_path(PCSC_INCLUDE_DIR pcsclite.h WinSCard.h - HINTS ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS} - PATH_SUFFIXES PCSC) + HINTS ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS} + PATH_SUFFIXES PCSC) find_library(PCSC_LIBRARY NAMES PCSC WinSCard pcsclite - HINTS ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS}) + HINTS ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PCSC DEFAULT_MSG PCSC_LIBRARY PCSC_INCLUDE_DIR) @@ -24,3 +25,4 @@ set(PCSC_INCLUDE_DIRS ${PCSC_INCLUDE_DIR}) mark_as_advanced(PCSC_INCLUDE_DIR PCSC_LIBRARY) + diff --git a/cmake/FindPCSCWinPR.cmake b/cmake/FindPCSCWinPR.cmake new file mode 100644 index 000000000..70a53d1fd --- /dev/null +++ b/cmake/FindPCSCWinPR.cmake @@ -0,0 +1,15 @@ + +find_library(PCSC_WINPR_LIBRARY + NAMES libpcsc-winpr.a + PATHS + /opt/lib + /usr/lib + /usr/local/lib + ) + +if(NOT ${PCSC_WINPR_LIBRARY} MATCHES ".*-NOTFOUND") + set(PCSC_WINPR_FOUND 1) + message(STATUS "Found PCSC-WinPR: ${PCSC_WINPR_LIBRARY}") +endif() + +mark_as_advanced(PCSC_WINPR_LIBRARY) diff --git a/winpr/libwinpr/smartcard/CMakeLists.txt b/winpr/libwinpr/smartcard/CMakeLists.txt index 7f6c82e10..ae77ef74f 100644 --- a/winpr/libwinpr/smartcard/CMakeLists.txt +++ b/winpr/libwinpr/smartcard/CMakeLists.txt @@ -18,9 +18,14 @@ set(MODULE_NAME "winpr-smartcard") set(MODULE_PREFIX "WINPR_SMARTCARD") +if(PCSC_WINPR_FOUND) + add_definitions(-DWITH_WINPR_PCSC) +endif() + set(${MODULE_PREFIX}_SRCS smartcard.c smartcard.h + smartcard_link.c smartcard_pcsc.c smartcard_pcsc.h smartcard_winscard.c @@ -41,6 +46,10 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MODULE winpr MODULES winpr-crt winpr-library) +if(PCSC_WINPR_FOUND) + list(APPEND ${MODULE_PREFIX}_LIBS ${PCSC_WINPR_LIBRARY}) +endif() + if(MONOLITHIC_BUILD) set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) else() diff --git a/winpr/libwinpr/smartcard/smartcard_link.c b/winpr/libwinpr/smartcard/smartcard_link.c new file mode 100644 index 000000000..e23460748 --- /dev/null +++ b/winpr/libwinpr/smartcard/smartcard_link.c @@ -0,0 +1,142 @@ +/** + * WinPR: Windows Portable Runtime + * Smart Card API + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +/** + * libpcsc-winpr.a: + * + * Add the WinPR_PCSC_* definitions + * to pcsc-lite/src/PCSC/winscard.h + * + * Configure project as static in a local prefix: + * ./configure --enable-static --prefix=/usr/local + * + * Install, and then rename + * libpcsclite.a to libpcsc-winpr.a + * + * This static library will contain a non-conflicting ABI + * so we can safely link to it with and import its functions. + */ + +#if 0 +#define WinPR_PCSC +#define SCardEstablishContext WinPR_PCSC_SCardEstablishContext +#define SCardReleaseContext WinPR_PCSC_SCardReleaseContext +#define SCardIsValidContext WinPR_PCSC_SCardIsValidContext +#define SCardConnect WinPR_PCSC_SCardConnect +#define SCardReconnect WinPR_PCSC_SCardReconnect +#define SCardDisconnect WinPR_PCSC_SCardDisconnect +#define SCardBeginTransaction WinPR_PCSC_SCardBeginTransaction +#define SCardEndTransaction WinPR_PCSC_SCardEndTransaction +#define SCardStatus WinPR_PCSC_SCardStatus +#define SCardGetStatusChange WinPR_PCSC_SCardGetStatusChange +#define SCardControl WinPR_PCSC_SCardControl +#define SCardTransmit WinPR_PCSC_SCardTransmit +#define SCardListReaderGroups WinPR_PCSC_SCardListReaderGroups +#define SCardListReaders WinPR_PCSC_SCardListReaders +#define SCardFreeMemory WinPR_PCSC_SCardFreeMemory +#define SCardCancel WinPR_PCSC_SCardCancel +#define SCardGetAttrib WinPR_PCSC_SCardGetAttrib +#define SCardSetAttrib WinPR_PCSC_SCardSetAttrib +#define list_size WinPR_PCSC_list_size /* src/simclist.h */ +#endif + +#ifdef WITH_WINPR_PCSC +extern void* WinPR_PCSC_SCardEstablishContext(); +extern void* WinPR_PCSC_SCardReleaseContext(); +extern void* WinPR_PCSC_SCardIsValidContext(); +extern void* WinPR_PCSC_SCardConnect(); +extern void* WinPR_PCSC_SCardReconnect(); +extern void* WinPR_PCSC_SCardDisconnect(); +extern void* WinPR_PCSC_SCardBeginTransaction(); +extern void* WinPR_PCSC_SCardEndTransaction(); +extern void* WinPR_PCSC_SCardStatus(); +extern void* WinPR_PCSC_SCardGetStatusChange(); +extern void* WinPR_PCSC_SCardControl(); +extern void* WinPR_PCSC_SCardTransmit(); +extern void* WinPR_PCSC_SCardListReaderGroups(); +extern void* WinPR_PCSC_SCardListReaders(); +extern void* WinPR_PCSC_SCardFreeMemory(); +extern void* WinPR_PCSC_SCardCancel(); +extern void* WinPR_PCSC_SCardGetAttrib(); +extern void* WinPR_PCSC_SCardSetAttrib(); +#endif + +struct _PCSCFunctionTable +{ + void* pfnSCardEstablishContext; + void* pfnSCardReleaseContext; + void* pfnSCardIsValidContext; + void* pfnSCardConnect; + void* pfnSCardReconnect; + void* pfnSCardDisconnect; + void* pfnSCardBeginTransaction; + void* pfnSCardEndTransaction; + void* pfnSCardStatus; + void* pfnSCardGetStatusChange; + void* pfnSCardControl; + void* pfnSCardTransmit; + void* pfnSCardListReaderGroups; + void* pfnSCardListReaders; + void* pfnSCardFreeMemory; + void* pfnSCardCancel; + void* pfnSCardGetAttrib; + void* pfnSCardSetAttrib; +}; +typedef struct _PCSCFunctionTable PCSCFunctionTable; + +PCSCFunctionTable g_PCSC_Link = { 0 }; + +int PCSC_InitializeSCardApi_Link(void) +{ + int status = -1; + +#ifdef WITH_WINPR_PCSC + g_PCSC_Link.pfnSCardEstablishContext = (void*) WinPR_PCSC_SCardEstablishContext; + g_PCSC_Link.pfnSCardReleaseContext = (void*) WinPR_PCSC_SCardReleaseContext; + g_PCSC_Link.pfnSCardIsValidContext = (void*) WinPR_PCSC_SCardIsValidContext; + g_PCSC_Link.pfnSCardConnect = (void*) WinPR_PCSC_SCardConnect; + g_PCSC_Link.pfnSCardReconnect = (void*) WinPR_PCSC_SCardReconnect; + g_PCSC_Link.pfnSCardDisconnect = (void*) WinPR_PCSC_SCardDisconnect; + g_PCSC_Link.pfnSCardBeginTransaction = (void*) WinPR_PCSC_SCardBeginTransaction; + g_PCSC_Link.pfnSCardEndTransaction = (void*) WinPR_PCSC_SCardEndTransaction; + g_PCSC_Link.pfnSCardStatus = (void*) WinPR_PCSC_SCardStatus; + g_PCSC_Link.pfnSCardGetStatusChange = (void*) WinPR_PCSC_SCardGetStatusChange; + g_PCSC_Link.pfnSCardControl = (void*) WinPR_PCSC_SCardControl; + g_PCSC_Link.pfnSCardTransmit = (void*) WinPR_PCSC_SCardTransmit; + g_PCSC_Link.pfnSCardListReaderGroups = (void*) WinPR_PCSC_SCardListReaderGroups; + g_PCSC_Link.pfnSCardListReaders = (void*) WinPR_PCSC_SCardListReaders; + //g_PCSC_Link.pfnSCardFreeMemory = (void*) WinPR_PCSC_SCardFreeMemory; + g_PCSC_Link.pfnSCardFreeMemory = (void*) NULL; + g_PCSC_Link.pfnSCardCancel = (void*) WinPR_PCSC_SCardCancel; + g_PCSC_Link.pfnSCardGetAttrib = (void*) WinPR_PCSC_SCardGetAttrib; + g_PCSC_Link.pfnSCardSetAttrib = (void*) WinPR_PCSC_SCardSetAttrib; + + status = 1; +#endif + + return status; +} diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index fac25e5cb..7c5d1605c 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -985,10 +985,37 @@ PSCardApiFunctionTable PCSC_GetSCardApiFunctionTable(void) return &PCSC_SCardApiFunctionTable; } -int PCSC_InitializeSCardApi(void) -{ - g_PCSCModule = LoadLibraryA("libpcsclite.so"); +extern PCSCFunctionTable g_PCSC_Link; +extern int PCSC_InitializeSCardApi_Link(void); +int PCSC_InitializeSCardApi(void) +{ + if (PCSC_InitializeSCardApi_Link() >= 0) + { + g_PCSC.pfnSCardEstablishContext = g_PCSC_Link.pfnSCardEstablishContext; + g_PCSC.pfnSCardReleaseContext = g_PCSC_Link.pfnSCardReleaseContext; + g_PCSC.pfnSCardIsValidContext = g_PCSC_Link.pfnSCardIsValidContext; + g_PCSC.pfnSCardConnect = g_PCSC_Link.pfnSCardConnect; + g_PCSC.pfnSCardReconnect = g_PCSC_Link.pfnSCardReconnect; + g_PCSC.pfnSCardDisconnect = g_PCSC_Link.pfnSCardDisconnect; + g_PCSC.pfnSCardBeginTransaction = g_PCSC_Link.pfnSCardBeginTransaction; + g_PCSC.pfnSCardEndTransaction = g_PCSC_Link.pfnSCardEndTransaction; + g_PCSC.pfnSCardStatus = g_PCSC_Link.pfnSCardStatus; + g_PCSC.pfnSCardGetStatusChange = g_PCSC_Link.pfnSCardGetStatusChange; + g_PCSC.pfnSCardControl = g_PCSC_Link.pfnSCardControl; + g_PCSC.pfnSCardTransmit = g_PCSC_Link.pfnSCardTransmit; + g_PCSC.pfnSCardListReaderGroups = g_PCSC_Link.pfnSCardListReaderGroups; + g_PCSC.pfnSCardListReaders = g_PCSC_Link.pfnSCardListReaders; + g_PCSC.pfnSCardFreeMemory = g_PCSC_Link.pfnSCardFreeMemory; + g_PCSC.pfnSCardCancel = g_PCSC_Link.pfnSCardCancel; + g_PCSC.pfnSCardGetAttrib = g_PCSC_Link.pfnSCardGetAttrib; + g_PCSC.pfnSCardSetAttrib = g_PCSC_Link.pfnSCardSetAttrib; + + return 1; + } + + g_PCSCModule = LoadLibraryA("libpcsclite.so"); + if (!g_PCSCModule) return -1;