Module: wine Branch: master Commit: c53a2044e0bc0d8833b33351fb4b1f4a4175b4c7 URL: https://gitlab.winehq.org/wine/wine/-/commit/c53a2044e0bc0d8833b33351fb4b1f4...
Author: Hans Leidekker hans@codeweavers.com Date: Thu Feb 16 13:07:41 2023 +0100
winscard: Implement SCardControl().
---
dlls/winscard/unixlib.c | 9 +++++++++ dlls/winscard/unixlib.h | 12 ++++++++++++ dlls/winscard/winscard.c | 25 +++++++++++++++++++++++++ dlls/winscard/winscard.spec | 2 +- 4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/dlls/winscard/unixlib.c b/dlls/winscard/unixlib.c index 50f6e348e97..b9ca68e40b9 100644 --- a/dlls/winscard/unixlib.c +++ b/dlls/winscard/unixlib.c @@ -45,6 +45,7 @@ LONG SCardReconnect( UINT64, UINT64, UINT64, UINT64, UINT64 * ); LONG SCardBeginTransaction( UINT64 ); LONG SCardEndTransaction( UINT64, UINT64 ); LONG SCardTransmit( UINT64, const struct io_request *, const BYTE *, UINT64, struct io_request *, BYTE *, UINT64 * ); +LONG SCardControl( UINT64, UINT64, const void *, UINT64, void *, UINT64, UINT64 * );
static NTSTATUS scard_establish_context( void *args ) { @@ -134,6 +135,13 @@ static NTSTATUS scard_transmit( void *args ) params->recv_buf, params->recv_buflen ); }
+static NTSTATUS scard_control( void *args ) +{ + struct scard_control_params *params = args; + return SCardControl( params->handle, params->code, params->in_buf, params->in_buflen, params->out_buf, + params->out_buflen, params->ret_len ); +} + const unixlib_entry_t __wine_unix_call_funcs[] = { scard_establish_context, @@ -150,4 +158,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] = scard_begin_transaction, scard_end_transaction, scard_transmit, + scard_control, }; diff --git a/dlls/winscard/unixlib.h b/dlls/winscard/unixlib.h index 33b1d295509..cdc7efe1b05 100644 --- a/dlls/winscard/unixlib.h +++ b/dlls/winscard/unixlib.h @@ -138,6 +138,17 @@ struct scard_transmit_params UINT64 *recv_buflen; };
+struct scard_control_params +{ + UINT64 handle; + UINT64 code; + const void *in_buf; + UINT64 in_buflen; + void *out_buf; + UINT64 out_buflen; + UINT64 *ret_len; +}; + enum winscard_funcs { unix_scard_establish_context, @@ -154,4 +165,5 @@ enum winscard_funcs unix_scard_begin_transaction, unix_scard_end_transaction, unix_scard_transmit, + unix_scard_control, }; diff --git a/dlls/winscard/winscard.c b/dlls/winscard/winscard.c index 7ef0a3fc9ba..09b5734c802 100644 --- a/dlls/winscard/winscard.c +++ b/dlls/winscard/winscard.c @@ -822,6 +822,31 @@ LONG WINAPI SCardTransmit( SCARDHANDLE connect, const SCARD_IO_REQUEST *send, co return ret; }
+LONG WINAPI SCardControl( SCARDHANDLE connect, DWORD code, const void *in_buf, DWORD in_buflen, void *out_buf, + DWORD out_buflen, DWORD *ret_len ) +{ + struct handle *handle = (struct handle *)connect; + struct scard_control_params params; + UINT64 ret_len64; + LONG ret; + + TRACE( "%Ix, %#lx, %p, %lu, %p, %lu, %p\n", connect, code, in_buf, in_buflen, out_buf, out_buflen, ret_len ); + + if (!handle || handle->magic != CONNECT_MAGIC) return ERROR_INVALID_HANDLE; + if (!ret_len) return SCARD_E_INVALID_PARAMETER; + + params.handle = handle->unix_handle; + params.code = code; + params.in_buf = in_buf; + params.in_buflen = in_buflen; + params.out_buf = out_buf; + params.out_buflen = out_buflen; + params.ret_len = &ret_len64; + if (!(ret = UNIX_CALL( scard_control, ¶ms ))) *ret_len = ret_len64; + TRACE( "returning %#lx\n", ret ); + return ret; +} + BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved ) { switch (reason) diff --git a/dlls/winscard/winscard.spec b/dlls/winscard/winscard.spec index 6de6c9036dd..bc9b0fd40da 100644 --- a/dlls/winscard/winscard.spec +++ b/dlls/winscard/winscard.spec @@ -9,7 +9,7 @@ @ stdcall SCardCancel(long) @ stdcall SCardConnectA(long str long long ptr ptr) @ stdcall SCardConnectW(long wstr long long ptr ptr) -@ stub SCardControl +@ stdcall SCardControl(long long ptr long ptr long ptr) @ stdcall SCardDisconnect(long long) @ stdcall SCardEndTransaction(long long) @ stdcall SCardEstablishContext(long ptr ptr ptr)