mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 02:38:21 +00:00
winscard: Implement SCardGetStatusChangeA/W().
This commit is contained in:
parent
9d40ac4635
commit
3f325721c3
|
@ -34,6 +34,7 @@
|
|||
LONG SCardEstablishContext( UINT64, const void *, const void *, UINT64 * );
|
||||
LONG SCardReleaseContext( UINT64 );
|
||||
LONG SCardIsValidContext( UINT64 );
|
||||
LONG SCardGetStatusChange( UINT64, UINT64, struct reader_state *, UINT64 );
|
||||
|
||||
static NTSTATUS scard_establish_context( void *args )
|
||||
{
|
||||
|
@ -53,9 +54,16 @@ static NTSTATUS scard_is_valid_context( void *args )
|
|||
return SCardIsValidContext( params->handle );
|
||||
}
|
||||
|
||||
static NTSTATUS scard_get_status_change( void *args )
|
||||
{
|
||||
struct scard_get_status_change_params *params = args;
|
||||
return SCardGetStatusChange( params->handle, params->timeout, params->states, params->count );
|
||||
}
|
||||
|
||||
const unixlib_entry_t __wine_unix_call_funcs[] =
|
||||
{
|
||||
scard_establish_context,
|
||||
scard_release_context,
|
||||
scard_is_valid_context,
|
||||
scard_get_status_change,
|
||||
};
|
||||
|
|
|
@ -35,9 +35,29 @@ struct scard_is_valid_context_params
|
|||
UINT64 handle;
|
||||
};
|
||||
|
||||
#define MAX_ATR_SIZE 33
|
||||
struct reader_state
|
||||
{
|
||||
UINT64 reader;
|
||||
UINT64 userdata;
|
||||
UINT64 current_state;
|
||||
UINT64 event_state;
|
||||
UINT64 atr_size;
|
||||
unsigned char atr[MAX_ATR_SIZE];
|
||||
};
|
||||
|
||||
struct scard_get_status_change_params
|
||||
{
|
||||
UINT64 handle;
|
||||
UINT64 timeout;
|
||||
struct reader_state *states;
|
||||
UINT64 count;
|
||||
};
|
||||
|
||||
enum winscard_funcs
|
||||
{
|
||||
unix_scard_establish_context,
|
||||
unix_scard_release_context,
|
||||
unix_scard_is_valid_context,
|
||||
unix_scard_get_status_change,
|
||||
};
|
||||
|
|
|
@ -37,6 +37,40 @@ const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
|
|||
const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
|
||||
const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
|
||||
|
||||
static inline char *utf16_to_utf8( const WCHAR *src )
|
||||
{
|
||||
char *dst = NULL;
|
||||
if (src)
|
||||
{
|
||||
int len = WideCharToMultiByte( CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL );
|
||||
if ((dst = malloc( len ))) WideCharToMultiByte( CP_UTF8, 0, src, -1, dst, len, NULL, NULL );
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline WCHAR *ansi_to_utf16( const char *src )
|
||||
{
|
||||
WCHAR *dst = NULL;
|
||||
if (src)
|
||||
{
|
||||
int len = MultiByteToWideChar( CP_ACP, 0, src, -1, NULL, 0 );
|
||||
if ((dst = malloc( len * sizeof(WCHAR) ))) MultiByteToWideChar( CP_ACP, 0, src, -1, dst, len );
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline char *ansi_to_utf8( const char *src )
|
||||
{
|
||||
char *dst = NULL;
|
||||
if (src)
|
||||
{
|
||||
WCHAR *tmp;
|
||||
if ((tmp = ansi_to_utf16( src ))) dst = utf16_to_utf8( tmp );
|
||||
free( tmp );
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
HANDLE WINAPI SCardAccessStartedEvent(void)
|
||||
{
|
||||
return g_startedEvent;
|
||||
|
@ -174,6 +208,119 @@ LONG WINAPI SCardCancel(SCARDCONTEXT context)
|
|||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
static LONG map_states_inA( const SCARD_READERSTATEA *src, struct reader_state *dst, DWORD count )
|
||||
{
|
||||
DWORD i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (src[i].szReader && !(dst[i].reader = (UINT64)(ULONG_PTR)ansi_to_utf8( src[i].szReader )))
|
||||
return SCARD_E_NO_MEMORY;
|
||||
dst[i].current_state = src[i].dwCurrentState;
|
||||
dst[i].event_state = src[i].dwEventState;
|
||||
dst[i].atr_size = src[i].cbAtr;
|
||||
memcpy( dst[i].atr, src[i].rgbAtr, src[i].cbAtr );
|
||||
}
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
static void map_states_out( const struct reader_state *src, SCARD_READERSTATEA *dst, DWORD count )
|
||||
{
|
||||
DWORD i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
dst[i].dwCurrentState = src[i].current_state;
|
||||
dst[i].dwEventState = src[i].event_state;
|
||||
dst[i].cbAtr = src[i].atr_size;
|
||||
memcpy( dst[i].rgbAtr, src[i].atr, src[i].atr_size );
|
||||
}
|
||||
}
|
||||
|
||||
static void free_states( struct reader_state *states, DWORD count )
|
||||
{
|
||||
DWORD i;
|
||||
for (i = 0; i < count; i++) free( (void *)(ULONG_PTR)states[i].reader );
|
||||
free( states );
|
||||
}
|
||||
|
||||
LONG WINAPI SCardGetStatusChangeA( SCARDCONTEXT context, DWORD timeout, SCARD_READERSTATEA *states, DWORD count )
|
||||
{
|
||||
struct handle *handle = (struct handle *)context;
|
||||
struct scard_get_status_change_params params;
|
||||
struct reader_state *states_utf8 = NULL;
|
||||
LONG ret;
|
||||
|
||||
TRACE( "%Ix, %lu, %p, %lu\n", context, timeout, states, count );
|
||||
|
||||
if (!handle || handle->magic != CONTEXT_MAGIC) return ERROR_INVALID_HANDLE;
|
||||
|
||||
if (!(states_utf8 = calloc( count, sizeof(*states_utf8) ))) return SCARD_E_NO_MEMORY;
|
||||
if ((ret = map_states_inA( states, states_utf8, count )))
|
||||
{
|
||||
free_states( states_utf8, count );
|
||||
return ret;
|
||||
}
|
||||
|
||||
params.handle = handle->unix_handle;
|
||||
params.timeout = timeout;
|
||||
params.states = states_utf8;
|
||||
params.count = count;
|
||||
if (!(ret = UNIX_CALL( scard_get_status_change, ¶ms )) && states)
|
||||
{
|
||||
map_states_out( states_utf8, states, count );
|
||||
}
|
||||
|
||||
free_states( states_utf8, count );
|
||||
TRACE( "returning %#lx\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LONG map_states_inW( SCARD_READERSTATEW *src, struct reader_state *dst, DWORD count )
|
||||
{
|
||||
DWORD i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (src[i].szReader && !(dst[i].reader = (UINT64)(ULONG_PTR)utf16_to_utf8( src[i].szReader )))
|
||||
return SCARD_E_NO_MEMORY;
|
||||
dst[i].current_state = src[i].dwCurrentState;
|
||||
dst[i].event_state = src[i].dwEventState;
|
||||
dst[i].atr_size = src[i].cbAtr;
|
||||
memcpy( dst[i].atr, src[i].rgbAtr, src[i].cbAtr );
|
||||
}
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
LONG WINAPI SCardGetStatusChangeW( SCARDCONTEXT context, DWORD timeout, SCARD_READERSTATEW *states, DWORD count )
|
||||
{
|
||||
struct handle *handle = (struct handle *)context;
|
||||
struct scard_get_status_change_params params;
|
||||
struct reader_state *states_utf8;
|
||||
LONG ret;
|
||||
|
||||
TRACE( "%Ix, %lu, %p, %lu\n", context, timeout, states, count );
|
||||
|
||||
if (!handle || handle->magic != CONTEXT_MAGIC) return ERROR_INVALID_HANDLE;
|
||||
|
||||
if (!(states_utf8 = calloc( count, sizeof(*states_utf8) ))) return SCARD_E_NO_MEMORY;
|
||||
if ((ret = map_states_inW( states, states_utf8, count )))
|
||||
{
|
||||
free_states( states_utf8, count );
|
||||
return ret;
|
||||
}
|
||||
|
||||
params.handle = handle->unix_handle;
|
||||
params.timeout = timeout;
|
||||
params.states = states_utf8;
|
||||
params.count = count;
|
||||
if (!(ret = UNIX_CALL( scard_get_status_change, ¶ms )))
|
||||
{
|
||||
map_states_out( states_utf8, (SCARD_READERSTATEA *)states, count );
|
||||
}
|
||||
|
||||
free_states( states_utf8, count );
|
||||
TRACE( "returning %#lx\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved )
|
||||
{
|
||||
switch (reason)
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
@ stub SCardGetCardTypeProviderNameW
|
||||
@ stub SCardGetProviderIdA
|
||||
@ stub SCardGetProviderIdW
|
||||
@ stub SCardGetStatusChangeA
|
||||
@ stub SCardGetStatusChangeW
|
||||
@ stdcall SCardGetStatusChangeA(long long ptr long)
|
||||
@ stdcall SCardGetStatusChangeW(long long ptr long)
|
||||
@ stub SCardIntroduceCardTypeA
|
||||
@ stub SCardIntroduceCardTypeW
|
||||
@ stub SCardIntroduceReaderA
|
||||
|
|
Loading…
Reference in a new issue