From a577d28a8b8176636b1dec9b95d0aaf2be2a6fb4 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 28 Jul 2023 10:07:56 +0200 Subject: [PATCH] winscard: Handle different type sizes on macOS. --- dlls/winscard/unixlib.c | 187 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 182 insertions(+), 5 deletions(-) diff --git a/dlls/winscard/unixlib.c b/dlls/winscard/unixlib.c index cd55e6352a8..d332b404a58 100644 --- a/dlls/winscard/unixlib.c +++ b/dlls/winscard/unixlib.c @@ -21,20 +21,39 @@ #endif #include +#include #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" #include "winbase.h" -#include "wine/debug.h" #include "wine/unixlib.h" #include "unixlib.h" +#ifdef __APPLE__ +LONG SCardEstablishContext( UINT32, const void *, const void *, UINT32 * ); +LONG SCardReleaseContext( UINT32 ); +LONG SCardIsValidContext( UINT32 ); +LONG SCardGetStatusChange( UINT32, UINT32, void *, UINT32 ); +LONG SCardCancel( UINT32 ); +LONG SCardListReaders( UINT32, const char *, char *, UINT32 * ); +LONG SCardListReaderGroups( UINT32, char *, UINT32 * ); +LONG SCardConnect( UINT32, const char *, UINT32, UINT32, UINT32 *, UINT32 * ); +LONG SCardStatus( UINT32, char *, UINT32 *, UINT32 *, UINT32 *, BYTE *, UINT32 * ); +LONG SCardDisconnect( UINT32, UINT32 ); +LONG SCardReconnect( UINT32, UINT32, UINT32, UINT32, UINT32 * ); +LONG SCardBeginTransaction( UINT32 ); +LONG SCardEndTransaction( UINT32, UINT32 ); +LONG SCardTransmit( UINT32, const void *, const BYTE *, UINT32, void *, BYTE *, UINT32 * ); +LONG SCardControl132( UINT32, UINT32, const void *, UINT32, void *, UINT32, UINT32 * ); +LONG SCardGetAttrib( UINT32, UINT32, BYTE *, UINT32 * ); +LONG SCardSetAttrib( UINT32, UINT32, const BYTE *, UINT32 ); +#else LONG SCardEstablishContext( UINT64, const void *, const void *, UINT64 * ); LONG SCardReleaseContext( UINT64 ); LONG SCardIsValidContext( UINT64 ); -LONG SCardGetStatusChange( UINT64, UINT64, struct reader_state *, UINT64 ); +LONG SCardGetStatusChange( UINT64, UINT64, void *, UINT64 ); LONG SCardCancel( UINT64 ); LONG SCardListReaders( UINT64, const char *, char *, UINT64 * ); LONG SCardListReaderGroups( UINT64, char *, UINT64 * ); @@ -44,15 +63,23 @@ LONG SCardDisconnect( UINT64, UINT64 ); 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 SCardTransmit( UINT64, const void *, const BYTE *, UINT64, void *, BYTE *, UINT64 * ); LONG SCardControl( UINT64, UINT64, const void *, UINT64, void *, UINT64, UINT64 * ); LONG SCardGetAttrib( UINT64, UINT64, BYTE *, UINT64 * ); LONG SCardSetAttrib( UINT64, UINT64, const BYTE *, UINT64 ); +#endif static NTSTATUS scard_establish_context( void *args ) { struct scard_establish_context_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 handle; + if (!(status = SCardEstablishContext( params->scope, NULL, NULL, &handle ))) *params->handle = handle; + return status; +#else return SCardEstablishContext( params->scope, NULL, NULL, params->handle ); +#endif } static NTSTATUS scard_release_context( void *args ) @@ -67,10 +94,63 @@ static NTSTATUS scard_is_valid_context( void *args ) return SCardIsValidContext( params->handle ); } +#ifdef __APPLE__ +struct reader_state_macos +{ + UINT64 reader; + UINT64 userdata; + UINT32 current_state; + UINT32 event_state; + UINT32 atr_size; + unsigned char atr[MAX_ATR_SIZE]; +}; + +static struct reader_state_macos *map_states_in( const struct reader_state *state, unsigned int count ) +{ + struct reader_state_macos *ret; + unsigned int i; + + if (!(ret = malloc( sizeof(*ret) * count ))) return NULL; + for (i = 0; i < count; i++) + { + ret[i].reader = state[i].reader; + ret[i].userdata = state[i].userdata; + ret[i].current_state = state[i].current_state; + ret[i].event_state = state[i].event_state; + memcpy( ret[i].atr, state[i].atr, state[i].atr_size ); + ret[i].atr_size = state[i].atr_size; + } + return ret; +} + +static void map_states_out( const struct reader_state_macos *state_macos, struct reader_state *state, unsigned int count ) +{ + unsigned int i; + for (i = 0; i < count; i++) + { + state[i].current_state = state_macos[i].current_state; + state[i].event_state = state_macos[i].event_state; + memcpy( state[i].atr, state_macos[i].atr, state_macos[i].atr_size ); + state[i].atr_size = state_macos[i].atr_size; + } +} +#endif + static NTSTATUS scard_get_status_change( void *args ) { struct scard_get_status_change_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + struct reader_state_macos *states = map_states_in( params->states, params->count ); + + if (!states) return STATUS_NO_MEMORY; + if (!(status = SCardGetStatusChange( params->handle, params->timeout, states, params->count ))) + map_states_out( states, params->states, params->count ); + free( states ); + return status; +#else return SCardGetStatusChange( params->handle, params->timeout, params->states, params->count ); +#endif } static NTSTATUS scard_cancel( void *args ) @@ -82,34 +162,86 @@ static NTSTATUS scard_cancel( void *args ) static NTSTATUS scard_list_readers( void *args ) { struct scard_list_readers_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 len = *params->readers_len; + if (!(status = SCardListReaders( params->handle, params->groups, params->readers, &len ))) *params->readers_len = len; + return status; +#else return SCardListReaders( params->handle, params->groups, params->readers, params->readers_len ); +#endif } static NTSTATUS scard_list_reader_groups( void *args ) { struct scard_list_reader_groups_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 len = *params->groups_len; + if (!(status = SCardListReaderGroups( params->handle, params->groups, &len ))) *params->groups_len = len; + return status; +#else return SCardListReaderGroups( params->handle, params->groups, params->groups_len ); +#endif } static NTSTATUS scard_connect( void *args ) { struct scard_connect_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 handle, protocol; + if (!(status = SCardConnect( params->context_handle, params->reader, params->share_mode, + params->preferred_protocols, &handle, &protocol ))) + { + *params->connect_handle = handle; + *params->protocol = protocol; + } + return status; +#else return SCardConnect( params->context_handle, params->reader, params->share_mode, params->preferred_protocols, params->connect_handle, params->protocol ); +#endif } static NTSTATUS scard_status( void *args ) { struct scard_status_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 names_len = params->names_len ? *params->names_len : 0; + UINT32 atr_len = params->atr_len ? *params->atr_len : 0; + UINT32 state, protocol; + + if (!(status = SCardStatus( params->handle, params->names, params->names_len ? &names_len : NULL, + params->state ? &state : NULL, params->protocol ? &protocol : NULL, params->atr, + params->atr_len ? &atr_len : NULL ))) + { + if (params->names_len) *params->names_len = names_len; + if (params->state) *params->state = state; + if (params->protocol) *params->protocol = protocol; + if (params->atr_len) *params->atr_len = atr_len; + } + return status; +#else return SCardStatus( params->handle, params->names, params->names_len, params->state, params->protocol, params->atr, params->atr_len ); +#endif } static NTSTATUS scard_reconnect( void *args ) { struct scard_reconnect_params *params = args; - return SCardReconnect( params->handle, params->share_mode, params->preferred_protocols, - params->initialization, params->protocol ); +#ifdef __APPLE__ + NTSTATUS status; + UINT32 protocol; + if (!(status = SCardReconnect( params->handle, params->share_mode, params->preferred_protocols, + params->initialization, &protocol ))) *params->protocol = protocol; + return status; +#else + return SCardReconnect( params->handle, params->share_mode, params->preferred_protocols, params->initialization, + params->protocol ); +#endif } static NTSTATUS scard_disconnect( void *args ) @@ -133,21 +265,66 @@ static NTSTATUS scard_end_transaction( void *args ) static NTSTATUS scard_transmit( void *args ) { struct scard_transmit_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 len = *params->recv_buflen; + struct + { + UINT32 protocol; + UINT32 pci_len; + } send, recv; + + send.protocol = params->send->protocol; + send.pci_len = params->send->pci_len; + if (params->recv) + { + recv.protocol = params->recv->protocol; + recv.pci_len = params->recv->pci_len; + } + if (!(status = SCardTransmit( params->handle, &send, params->send_buf, params->send_buflen, &recv, + params->recv_buf, &len ))) + { + if (params->recv) + { + params->recv->protocol = recv.protocol; + params->recv->pci_len = recv.pci_len; + } + *params->recv_buflen = len; + } + return status; +#else return SCardTransmit( params->handle, params->send, params->send_buf, params->send_buflen, params->recv, params->recv_buf, params->recv_buflen ); +#endif } static NTSTATUS scard_control( void *args ) { struct scard_control_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 len; + if (!(status = SCardControl132( params->handle, params->code, params->in_buf, params->in_buflen, params->out_buf, + params->out_buflen, &len ))) + *params->ret_len = len; + return status; +#else return SCardControl( params->handle, params->code, params->in_buf, params->in_buflen, params->out_buf, params->out_buflen, params->ret_len ); +#endif } static NTSTATUS scard_get_attrib( void *args ) { struct scard_get_attrib_params *params = args; +#ifdef __APPLE__ + NTSTATUS status; + UINT32 len = *params->attr_len; + if (!(status = SCardGetAttrib( params->handle, params->id, params->attr, &len ))) *params->attr_len = len; + return status; +#else return SCardGetAttrib( params->handle, params->id, params->attr, params->attr_len ); +#endif } static NTSTATUS scard_set_attrib( void *args )