From 62b8e1e6d80ae657f72559801bab4eacf7193fde Mon Sep 17 00:00:00 2001 From: Johannes Findeisen Date: Mon, 22 Feb 2021 04:21:28 +0100 Subject: [PATCH] Added scard_begin_transaction and scard_end_transaction; SEGFAULTS when using it --- docs/examples/simple.php | 22 ++++++++++++++ package.xml | 2 +- pcsc.c | 42 +++++++++++++++++++++++++++ pcsc.stub.php | 12 ++++++++ pcsc_arginfo.h | 62 +++++++++++++++++++++++----------------- pcsc_legacy_arginfo.h | 60 ++++++++++++++++++++++---------------- php_pcsc.h | 4 ++- 7 files changed, 151 insertions(+), 53 deletions(-) diff --git a/docs/examples/simple.php b/docs/examples/simple.php index 87c0c5a..04504e3 100644 --- a/docs/examples/simple.php +++ b/docs/examples/simple.php @@ -48,6 +48,17 @@ $errstr = scard_errstr($errno); var_dump($errstr); echo "\n"; +# Begin Transaction +echo ">> Begin Transaction\n"; +$begin= scard_begin_transaction($connection); +var_dump($begin); + +$errno = scard_last_errno(); +var_dump($errno); +$errstr = scard_errstr($errno); +var_dump($errstr); +echo "\n"; + # Select Applet APDU echo ">> Select Applet\n"; $CMD = "00a4040c0cD2760001354B414E4D30310000"; @@ -73,6 +84,17 @@ $errstr = scard_errstr($errno); var_dump($errstr); echo "\n"; +# End Transaction +echo ">> End Transaction\n"; +$begin= scard_end_transaction($connection); +var_dump($connection); + +$errno = scard_last_errno(); +var_dump($errno); +$errstr = scard_errstr($errno); +var_dump($errstr); +echo "\n"; + # Show Status echo ">> Show Status\n"; $status = scard_status($connection); diff --git a/package.xml b/package.xml index 26b7da0..5b762eb 100644 --- a/package.xml +++ b/package.xml @@ -23,7 +23,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> 2021-02-21 - 0.5.1 + 0.6.0 0.3.1 diff --git a/pcsc.c b/pcsc.c index 23ec66d..c833121 100644 --- a/pcsc.c +++ b/pcsc.c @@ -636,6 +636,48 @@ PHP_FUNCTION(scard_disconnect) } /* }}} */ +/* {{{ proto boolean scard_begin_transaction(resource card_handle) + Begin transaction on a card connection obtained with scard_connect */ +PHP_FUNCTION(scard_begin_transaction) +{ + LONG rc; + zval* conn_res; + SCARDHANDLE hCard; + + ZEND_FETCH_RESOURCE(hCard, SCARDHANDLE, &conn_res, -1, PHP_PCSC_CONN_RES_NAME, le_pcsc_conn_res); + + rc = SCardBeginTransaction(hCard); + if (rc != SCARD_S_SUCCESS) { + PCSC_G(last_errno) = rc; + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto boolean scard_end_transaction(resource card_handle, [long disposition = SCARD_LEAVE_CARD]) + End a previously begun transaction invoked by scard_begin_transaction on a card connection obtained with scard_connect; If no transaction began, do nothing. */ +PHP_FUNCTION(scard_end_transaction) +{ + zend_long dwDisposition = SCARD_LEAVE_CARD; + LONG rc; + zval* conn_res; + SCARDHANDLE hCard; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &conn_res, &dwDisposition) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(hCard, SCARDHANDLE, &conn_res, -1, PHP_PCSC_CONN_RES_NAME, le_pcsc_conn_res); + + rc = SCardEndTransaction(hCard, (DWORD)dwDisposition); + if (rc != SCARD_S_SUCCESS) { + PCSC_G(last_errno) = rc; + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + /* {{{ proto string scard_transmit(resource card_handle, string send_command) Transmit (and receive) data to (and from) the card */ PHP_FUNCTION(scard_transmit) diff --git a/pcsc.stub.php b/pcsc.stub.php index 1a973c3..c295f40 100644 --- a/pcsc.stub.php +++ b/pcsc.stub.php @@ -37,6 +37,18 @@ function scard_connect($context, string $reader_name, int $preferred_protocol=SC */ function scard_disconnect($card, int $disposition=SCARD_EJECT_CARD): bool {} +/** + * @param resource $card + * @return resource|false + */ +function scard_begin_transaction($card): bool {} + +/** + * @param resource $card + * @return resource|false + */ +function scard_end_transaction($card, int $disposition=SCARD_LEAVE_CARD): bool {} + /** * @param resource $card * @return resource|false diff --git a/pcsc_arginfo.h b/pcsc_arginfo.h index 80b4481..6ecb3e8 100644 --- a/pcsc_arginfo.h +++ b/pcsc_arginfo.h @@ -1,45 +1,51 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3e1df1d509b6416c1eb997f61295c26d9ad0fd03 */ - ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_establish_context, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_scard_release_context, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO(0, context) ZEND_END_ARG_INFO() #define arginfo_scard_is_valid_context arginfo_scard_release_context ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_scard_list_readers, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO(0, context) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_scard_connect, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, context) - ZEND_ARG_TYPE_INFO(0, reader_name, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, preferred_protocol, IS_LONG, 0, "SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(1, current_protocol, IS_LONG, 0, "NULL") + ZEND_ARG_INFO(0, context) + ZEND_ARG_TYPE_INFO(0, reader_name, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, preferred_protocol, IS_LONG, 0, "SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(1, current_protocol, IS_LONG, 0, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_scard_disconnect, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, card) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, disposition, IS_LONG, 0, "SCARD_EJECT_CARD") + ZEND_ARG_INFO(0, card) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, disposition, IS_LONG, 0, "SCARD_EJECT_CARD") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_begin_transaction, 0, 1, _IS_BOOL, 0) + ZEND_ARG_INFO(0, card) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_end_transaction, 0, 1, _IS_BOOL, 0) + ZEND_ARG_INFO(0, card) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, disposition, IS_LONG, 0, "SCARD_LEAVE_CARD") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_scard_transmit, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, card) - ZEND_ARG_TYPE_INFO(0, command, IS_STRING, 0) + ZEND_ARG_INFO(0, card) + ZEND_ARG_TYPE_INFO(0, command, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_scard_status, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, card) + ZEND_ARG_INFO(0, card) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_scard_last_errno, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_scard_errstr, 0, 1, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, errno, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, errno, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -49,6 +55,8 @@ ZEND_FUNCTION(scard_is_valid_context); ZEND_FUNCTION(scard_list_readers); ZEND_FUNCTION(scard_connect); ZEND_FUNCTION(scard_disconnect); +ZEND_FUNCTION(scard_begin_transaction); +ZEND_FUNCTION(scard_end_transaction); ZEND_FUNCTION(scard_transmit); ZEND_FUNCTION(scard_status); ZEND_FUNCTION(scard_last_errno); @@ -56,15 +64,17 @@ ZEND_FUNCTION(scard_errstr); static const zend_function_entry ext_functions[] = { - ZEND_FE(scard_establish_context, arginfo_scard_establish_context) - ZEND_FE(scard_release_context, arginfo_scard_release_context) - ZEND_FE(scard_is_valid_context, arginfo_scard_is_valid_context) - ZEND_FE(scard_list_readers, arginfo_scard_list_readers) - ZEND_FE(scard_connect, arginfo_scard_connect) - ZEND_FE(scard_disconnect, arginfo_scard_disconnect) - ZEND_FE(scard_transmit, arginfo_scard_transmit) - ZEND_FE(scard_status, arginfo_scard_status) - ZEND_FE(scard_last_errno, arginfo_scard_last_errno) - ZEND_FE(scard_errstr, arginfo_scard_errstr) - ZEND_FE_END + ZEND_FE(scard_establish_context, arginfo_scard_establish_context) + ZEND_FE(scard_release_context, arginfo_scard_release_context) + ZEND_FE(scard_is_valid_context, arginfo_scard_is_valid_context) + ZEND_FE(scard_list_readers, arginfo_scard_list_readers) + ZEND_FE(scard_connect, arginfo_scard_connect) + ZEND_FE(scard_disconnect, arginfo_scard_disconnect) + ZEND_FE(scard_begin_transaction, arginfo_scard_begin_transaction) + ZEND_FE(scard_end_transaction, arginfo_scard_end_transaction) + ZEND_FE(scard_transmit, arginfo_scard_transmit) + ZEND_FE(scard_status, arginfo_scard_status) + ZEND_FE(scard_last_errno, arginfo_scard_last_errno) + ZEND_FE(scard_errstr, arginfo_scard_errstr) + ZEND_FE_END }; diff --git a/pcsc_legacy_arginfo.h b/pcsc_legacy_arginfo.h index c56c076..17975db 100644 --- a/pcsc_legacy_arginfo.h +++ b/pcsc_legacy_arginfo.h @@ -1,11 +1,8 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3e1df1d509b6416c1eb997f61295c26d9ad0fd03 */ - ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_establish_context, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_release_context, 0, 0, 1) - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO(0, context) ZEND_END_ARG_INFO() #define arginfo_scard_is_valid_context arginfo_scard_release_context @@ -13,30 +10,39 @@ ZEND_END_ARG_INFO() #define arginfo_scard_list_readers arginfo_scard_release_context ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_connect, 0, 0, 2) - ZEND_ARG_INFO(0, context) - ZEND_ARG_INFO(0, reader_name) - ZEND_ARG_INFO(0, preferred_protocol) - ZEND_ARG_INFO(1, current_protocol) + ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO(0, reader_name) + ZEND_ARG_INFO(0, preferred_protocol) + ZEND_ARG_INFO(1, current_protocol) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_disconnect, 0, 0, 1) - ZEND_ARG_INFO(0, card) - ZEND_ARG_INFO(0, disposition) + ZEND_ARG_INFO(0, card) + ZEND_ARG_INFO(0, disposition) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_begin_transaction, 0, 0, 1) + ZEND_ARG_INFO(0, card) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_end_transaction, 0, 0, 1) + ZEND_ARG_INFO(0, card) + ZEND_ARG_INFO(0, disposition) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_transmit, 0, 0, 2) - ZEND_ARG_INFO(0, card) - ZEND_ARG_INFO(0, command) + ZEND_ARG_INFO(0, card) + ZEND_ARG_INFO(0, command) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_status, 0, 0, 1) - ZEND_ARG_INFO(0, card) + ZEND_ARG_INFO(0, card) ZEND_END_ARG_INFO() #define arginfo_scard_last_errno arginfo_scard_establish_context ZEND_BEGIN_ARG_INFO_EX(arginfo_scard_errstr, 0, 0, 1) - ZEND_ARG_INFO(0, errno) + ZEND_ARG_INFO(0, errno) ZEND_END_ARG_INFO() @@ -46,6 +52,8 @@ ZEND_FUNCTION(scard_is_valid_context); ZEND_FUNCTION(scard_list_readers); ZEND_FUNCTION(scard_connect); ZEND_FUNCTION(scard_disconnect); +ZEND_FUNCTION(scard_begin_transaction); +ZEND_FUNCTION(scard_end_transaction); ZEND_FUNCTION(scard_transmit); ZEND_FUNCTION(scard_status); ZEND_FUNCTION(scard_last_errno); @@ -53,15 +61,17 @@ ZEND_FUNCTION(scard_errstr); static const zend_function_entry ext_functions[] = { - ZEND_FE(scard_establish_context, arginfo_scard_establish_context) - ZEND_FE(scard_release_context, arginfo_scard_release_context) - ZEND_FE(scard_is_valid_context, arginfo_scard_is_valid_context) - ZEND_FE(scard_list_readers, arginfo_scard_list_readers) - ZEND_FE(scard_connect, arginfo_scard_connect) - ZEND_FE(scard_disconnect, arginfo_scard_disconnect) - ZEND_FE(scard_transmit, arginfo_scard_transmit) - ZEND_FE(scard_status, arginfo_scard_status) - ZEND_FE(scard_last_errno, arginfo_scard_last_errno) - ZEND_FE(scard_errstr, arginfo_scard_errstr) - ZEND_FE_END + ZEND_FE(scard_establish_context, arginfo_scard_establish_context) + ZEND_FE(scard_release_context, arginfo_scard_release_context) + ZEND_FE(scard_is_valid_context, arginfo_scard_is_valid_context) + ZEND_FE(scard_list_readers, arginfo_scard_list_readers) + ZEND_FE(scard_connect, arginfo_scard_connect) + ZEND_FE(scard_disconnect, arginfo_scard_disconnect) + ZEND_FE(scard_begin_transaction, arginfo_scard_begin_transaction) + ZEND_FE(scard_end_transaction, arginfo_scard_end_transaction) + ZEND_FE(scard_transmit, arginfo_scard_transmit) + ZEND_FE(scard_status, arginfo_scard_status) + ZEND_FE(scard_last_errno, arginfo_scard_last_errno) + ZEND_FE(scard_errstr, arginfo_scard_errstr) + ZEND_FE_END }; diff --git a/php_pcsc.h b/php_pcsc.h index e91ff4e..e4f3811 100644 --- a/php_pcsc.h +++ b/php_pcsc.h @@ -4,7 +4,7 @@ extern zend_module_entry pcsc_module_entry; #define phpext_pcsc_ptr &pcsc_module_entry -#define PHP_PCSC_VERSION "0.5.1" +#define PHP_PCSC_VERSION "0.6.0" #ifdef PHP_WIN32 #define PHP_PCSC_API __declspec(dllexport) @@ -32,6 +32,8 @@ PHP_FUNCTION(scard_list_readers); PHP_FUNCTION(scard_connect); //PHP_FUNCTION(scard_reconnect); PHP_FUNCTION(scard_disconnect); +PHP_FUNCTION(scard_begin_transaction); +PHP_FUNCTION(scard_end_transaction); PHP_FUNCTION(scard_status); //PHP_FUNCTION(scard_get_status_change); PHP_FUNCTION(scard_transmit);