From: Konstantin Romanov incubusrk@gmail.com
based on libpcsclite rework of original code by Mounir IDRASSI to use unixlib interface
Related to Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=39113 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=37495 Also required to implement scarddlg --- dlls/winscard/Makefile.in | 7 +- dlls/winscard/unixlib.c | 315 ++++++ dlls/winscard/unixlib.h | 262 +++++ dlls/winscard/winscard.c | 1905 +++++++++++++++++++++++++++++++++-- dlls/winscard/winscard.spec | 100 +- include/winscard.h | 29 +- include/winsmcrd.h | 123 ++- 7 files changed, 2584 insertions(+), 157 deletions(-) create mode 100644 dlls/winscard/unixlib.c create mode 100644 dlls/winscard/unixlib.h
diff --git a/dlls/winscard/Makefile.in b/dlls/winscard/Makefile.in index 89449698b66..cd1f88c8907 100644 --- a/dlls/winscard/Makefile.in +++ b/dlls/winscard/Makefile.in @@ -1,8 +1,11 @@ MODULE = winscard.dll +UNIXLIB = winscard.so IMPORTLIB = winscard +IMPORTS = ntdll
C_SRCS = \ - winscard.c + winscard.c\ + unixlib.c
RC_SRCS = \ - rsrc.rc + rsrc.rc \ No newline at end of file diff --git a/dlls/winscard/unixlib.c b/dlls/winscard/unixlib.c new file mode 100644 index 00000000000..1abd0664584 --- /dev/null +++ b/dlls/winscard/unixlib.c @@ -0,0 +1,315 @@ +/* + * WinScard Unix library + * + * Copyright (C) 2023 Konstantin Romanov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <stdlib.h> +#include <stdarg.h> +#include <sys/types.h> +#include <unistd.h> +#include <dlfcn.h> + +#define __user +#include "unixlib.h" + +LONG SCardEstablishContext(DWORD_LITE dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, SCARDCONTEXT *phContext); +LONG SCardReleaseContext(SCARDCONTEXT hContext); +LONG SCardIsValidContext(SCARDCONTEXT hContext); +LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD_LITE dwShareMode, DWORD_LITE dwPreferredProtocols, + SCARDHANDLE *phCard, DWORD_LITE *pdwActiveProtocol); +LONG SCardReconnect(SCARDHANDLE hCard, DWORD_LITE dwShareMode, DWORD_LITE dwPreferredProtocols, + DWORD_LITE dwInitialization, DWORD_LITE *pdwActiveProtocol); +LONG SCardDisconnect(SCARDHANDLE hCard, DWORD_LITE dwDisposition); +LONG SCardBeginTransaction(SCARDHANDLE hCard); +LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD_LITE dwDisposition); +LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, DWORD_LITE *pcchReaderLen, DWORD_LITE *pdwState, + DWORD_LITE *pdwProtocol, LPBYTE pbAtr, DWORD_LITE *pcbAtrLen); +LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD_LITE dwTimeout, SCARD_READERSTATE_LITE *rgReaderStates, DWORD_LITE cReaders); +LONG SCardControl(SCARDHANDLE hCard, DWORD_LITE dwControlCode, LPCVOID pbSendBuffer, DWORD_LITE cbSendLength, + LPVOID pbRecvBuffer, DWORD_LITE cbRecvLength, DWORD_LITE *lpBytesReturned); +LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST_LITE *pioSendPci, LPCBYTE pbSendBuffer, DWORD_LITE cbSendLength, + SCARD_IO_REQUEST_LITE *pioRecvPci, LPBYTE pbRecvBuffer, DWORD_LITE *pcbRecvLength); +LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, DWORD_LITE *pcchGroups); +LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, DWORD_LITE *pcchReaders); +LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem); +LONG SCardCancel(SCARDCONTEXT hContext); +LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD_LITE dwAttrId, LPBYTE pbAttr, DWORD_LITE *pcbAttrLen); +LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD_LITE dwAttrId, LPCBYTE pbAttr, DWORD_LITE cbAttrLen); + +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(winscard); +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +static void* g_pcscliteHandle = NULL; + +#define MAKE_FUNCPTR(f) static typeof(f) * p##f + MAKE_FUNCPTR(SCardEstablishContext); + MAKE_FUNCPTR(SCardReleaseContext); + MAKE_FUNCPTR(SCardIsValidContext); + MAKE_FUNCPTR(SCardConnect); + MAKE_FUNCPTR(SCardReconnect); + MAKE_FUNCPTR(SCardDisconnect); + MAKE_FUNCPTR(SCardBeginTransaction); + MAKE_FUNCPTR(SCardEndTransaction); + MAKE_FUNCPTR(SCardStatus); + MAKE_FUNCPTR(SCardGetStatusChange); + MAKE_FUNCPTR(SCardControl); + MAKE_FUNCPTR(SCardTransmit); + MAKE_FUNCPTR(SCardListReaderGroups); + MAKE_FUNCPTR(SCardListReaders); + MAKE_FUNCPTR(SCardFreeMemory); + MAKE_FUNCPTR(SCardCancel); + MAKE_FUNCPTR(SCardGetAttrib); + MAKE_FUNCPTR(SCardSetAttrib); +#undef MAKE_FUNCPTR + +static BOOL load_pcsclite(void); + +static LONG pcsclite_process_attach( void *args ) +{ + if (!load_pcsclite()) return SCARD_F_INTERNAL_ERROR; + return SCARD_S_SUCCESS; +} + +static LONG pcsclite_process_detach( void *args ) +{ + if (g_pcscliteHandle) dlclose( g_pcscliteHandle ); + g_pcscliteHandle = NULL; + return SCARD_S_SUCCESS; +} + +static LONG pcsclite_SCardEstablishContext( void *args ) +{ + struct SCardEstablishContext_params *params = args; + if (!pSCardEstablishContext) return SCARD_F_INTERNAL_ERROR; + return pSCardEstablishContext( params->dwScope, params->pvReserved1, params->pvReserved2, params->phContext ); +} + +static LONG pcsclite_SCardReleaseContext( void *args ) +{ + struct SCardReleaseContext_params *params = args; + if (!pSCardReleaseContext) return SCARD_F_INTERNAL_ERROR; + return pSCardReleaseContext( params->hContext ); +} + +static LONG pcsclite_SCardIsValidContext( void *args ) +{ + struct SCardIsValidContext_params *params = args; + if (!pSCardIsValidContext) return SCARD_F_INTERNAL_ERROR; + return pSCardIsValidContext( params->hContext ); +} + +static LONG pcsclite_SCardConnect( void *args ) +{ + struct SCardConnect_params *params = args; + if (!pSCardConnect) return SCARD_F_INTERNAL_ERROR; + return pSCardConnect( params->hContext, params->szReader, params->dwShareMode, params->dwPreferredProtocols, + params->phCard, params->pdwActiveProtocol ); +} + +static LONG pcsclite_SCardReconnect( void *args ) +{ + struct SCardReconnect_params *params = args; + if (!pSCardReconnect) return SCARD_F_INTERNAL_ERROR; + return pSCardReconnect( params->hCard, params->dwShareMode, params->dwPreferredProtocols, params->dwInitialization, params->pdwActiveProtocol ); +} + +static LONG pcsclite_SCardDisconnect( void *args ) +{ + struct SCardDisconnect_params *params = args; + if (!pSCardDisconnect) return SCARD_F_INTERNAL_ERROR; + return pSCardDisconnect( params->hCard, params->dwDisposition ); +} + +static LONG pcsclite_SCardBeginTransaction( void *args ) +{ + struct SCardBeginTransaction_params *params = args; + if (!pSCardBeginTransaction) return SCARD_F_INTERNAL_ERROR; + return pSCardBeginTransaction( params->hCard ); +} + +static LONG pcsclite_SCardEndTransaction( void *args ) +{ + struct SCardEndTransaction_params *params = args; + if (!pSCardEndTransaction) return SCARD_F_INTERNAL_ERROR; + return pSCardEndTransaction( params->hCard, params->dwDisposition ); +} + +static LONG pcsclite_SCardStatus( void *args ) +{ + struct SCardStatus_params *params = args; + if (!pSCardStatus) return SCARD_F_INTERNAL_ERROR; + return pSCardStatus( params->hCard, params->mszReaderName, params->pcchReaderLen, params->pdwState, params->pdwProtocol, + params->pbAtr, params->pcbAtrLen ); +} + +static LONG pcsclite_SCardGetStatusChange( void *args ) +{ + struct SCardGetStatusChange_params *params = args; + if (!pSCardGetStatusChange) return SCARD_F_INTERNAL_ERROR; + return pSCardGetStatusChange( params->hContext, params->dwTimeout, params->rgReaderStates, params->cReaders ); +} + +static LONG pcsclite_SCardControl( void *args ) +{ + struct SCardControl_params *params = args; + if (!pSCardControl) return SCARD_F_INTERNAL_ERROR; + return pSCardControl( params->hCard, params->dwControlCode, params->pbSendBuffer, params->cbSendLength, + params->pbRecvBuffer, params->cbRecvLength, params->lpBytesReturned ); +} + +static LONG pcsclite_SCardTransmit( void *args ) +{ + struct SCardTransmit_params *params = args; + if (!pSCardTransmit) return SCARD_F_INTERNAL_ERROR; + return pSCardTransmit( params->hCard, params->pioSendPci, params->pbSendBuffer, params->cbSendLength, + params->pioRecvPci, params->pbRecvBuffer, params->pcbRecvLength ); +} + +static LONG pcsclite_SCardListReaderGroups( void *args ) +{ + struct SCardListReaderGroups_params *params = args; + if (!pSCardListReaderGroups) return SCARD_F_INTERNAL_ERROR; + return pSCardListReaderGroups( params->hContext, params->mszGroups, params->pcchGroups ); +} + +static LONG pcsclite_SCardListReaders( void *args ) +{ + struct SCardListReaders_params *params = args; + if (!pSCardListReaders) return SCARD_F_INTERNAL_ERROR; + return pSCardListReaders( params->hContext, params->mszGroups, params->mszReaders, params->pcchReaders ); +} + +static LONG pcsclite_SCardFreeMemory( void *args ) +{ + struct SCardFreeMemory_params *params = args; + if (!pSCardFreeMemory) return SCARD_F_INTERNAL_ERROR; + return pSCardFreeMemory( params->hContext, params->pvMem ); +} + +static LONG pcsclite_SCardCancel( void *args ) +{ + struct SCardCancel_params *params = args; + if (!pSCardCancel) return SCARD_F_INTERNAL_ERROR; + return pSCardCancel( params->hContext ); +} + +static LONG pcsclite_SCardGetAttrib( void *args ) +{ + struct SCardGetAttrib_params *params = args; + if (!pSCardGetAttrib) return SCARD_F_INTERNAL_ERROR; + return pSCardGetAttrib( params->hCard, params->dwAttrId, params->pbAttr, params->pcbAttrLen ); +} + +static LONG pcsclite_SCardSetAttrib( void *args ) +{ + struct SCardSetAttrib_params *params = args; + if (!pSCardSetAttrib) return SCARD_F_INTERNAL_ERROR; + return pSCardSetAttrib( params->hCard, params->dwAttrId, params->pbAttr, params->cbAttrLen ); +} + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + pcsclite_SCardEstablishContext, + pcsclite_SCardReleaseContext, + pcsclite_SCardIsValidContext, + pcsclite_SCardConnect, + pcsclite_SCardReconnect, + pcsclite_SCardDisconnect, + pcsclite_SCardBeginTransaction, + pcsclite_SCardEndTransaction, + pcsclite_SCardStatus, + pcsclite_SCardGetStatusChange, + pcsclite_SCardControl, + pcsclite_SCardTransmit, + pcsclite_SCardListReaderGroups, + pcsclite_SCardListReaders, + pcsclite_SCardFreeMemory, + pcsclite_SCardCancel, + pcsclite_SCardGetAttrib, + pcsclite_SCardSetAttrib, + pcsclite_process_attach, + pcsclite_process_detach, +}; + +static BOOL load_pcsclite(void) +{ + if(!g_pcscliteHandle) + { + /* try to load pcsc-lite */ +#ifdef __APPLE__ + g_pcscliteHandle = dlopen("/System/Library/Frameworks/PCSC.framework/PCSC",RTLD_LAZY | RTLD_GLOBAL); +#else + g_pcscliteHandle = dlopen("libpcsclite.so",RTLD_LAZY | RTLD_GLOBAL); + if(!g_pcscliteHandle) + { + /* error occured. Trying libpcsclite.so.1*/ + g_pcscliteHandle = dlopen("libpcsclite.so.1",RTLD_LAZY | RTLD_GLOBAL); + } +#endif + TRACE("g_pcscliteHandle: %p\n", g_pcscliteHandle); + if(!g_pcscliteHandle) + { + /* error occured*/ +#ifdef __APPLE__ + ERR_(winediag)( "loading PCSC framework failed, scard support will be disabled. Error: %s\n", debugstr_a(dlerror()) ); +#else + ERR_(winediag)( "failed to load libpcsclite.so, scard support will be disabled. Error: %s\n", debugstr_a(dlerror()) ); +#endif + return FALSE; + } + } + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = dlsym( g_pcscliteHandle, #f ))) \ + { \ + ERR( "failed to load %s\n", #f ); \ + goto fail; \ + } + LOAD_FUNCPTR( SCardEstablishContext) + LOAD_FUNCPTR( SCardReleaseContext) + LOAD_FUNCPTR( SCardIsValidContext) + LOAD_FUNCPTR( SCardConnect) + LOAD_FUNCPTR( SCardReconnect) + LOAD_FUNCPTR( SCardDisconnect) + LOAD_FUNCPTR( SCardBeginTransaction) + LOAD_FUNCPTR( SCardEndTransaction) + LOAD_FUNCPTR( SCardStatus) + LOAD_FUNCPTR( SCardGetStatusChange) + LOAD_FUNCPTR( SCardControl) + LOAD_FUNCPTR( SCardTransmit) + LOAD_FUNCPTR( SCardListReaderGroups) + LOAD_FUNCPTR( SCardListReaders) + LOAD_FUNCPTR( SCardFreeMemory) + LOAD_FUNCPTR( SCardCancel) + LOAD_FUNCPTR( SCardGetAttrib) + LOAD_FUNCPTR( SCardSetAttrib) +#undef LOAD_FUNCPTR + return TRUE; +fail: + dlclose( g_pcscliteHandle ); + g_pcscliteHandle = NULL; + return FALSE; +} diff --git a/dlls/winscard/unixlib.h b/dlls/winscard/unixlib.h new file mode 100644 index 00000000000..74efcb47261 --- /dev/null +++ b/dlls/winscard/unixlib.h @@ -0,0 +1,262 @@ +/* + * WinSCard Unix library + * + * Copyright (C) 2023 Konstantin Romanov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "wine/unixlib.h" + +#ifndef __unixlib_h__ +#define __unixlib_h__ + + +#ifndef LPCBYTE + typedef const BYTE *LPCBYTE; +#endif + +#define MAX_PCSCLITE_READERNAME 52 + +#ifdef WINE_UNIX_LIB + typedef ULONG_PTR SCARDCONTEXT, *PSCARDCONTEXT, *LPSCARDCONTEXT; + typedef ULONG_PTR SCARDHANDLE, *PSCARDHANDLE, *LPSCARDHANDLE; + typedef unsigned long DWORD_LITE; + typedef unsigned long* LPDWORD_LITE; +#else + #include "winscard.h" + #ifndef SCARD_READERSTATE + typedef SCARD_READERSTATEA SCARD_READERSTATE; + #endif + #ifdef __x86_64 + typedef unsigned long long DWORD_LITE; + typedef unsigned long long* LPDWORD_LITE; + #else + typedef unsigned long DWORD_LITE; + typedef unsigned long* LPDWORD_LITE; + #endif +#endif + +#ifdef __APPLE__ + +#define DWORD_LITE DWORD +#define LPDWORD_LITE LPDWORD + +#define SCARD_READERSTATE_LITE SCARD_READERSTATEA +#define LPSCARD_READERSTATE_LITE LPSCARD_READERSTATEA + + +#define SCARD_IO_REQUEST_LITE SCARD_IO_REQUEST +#define PSCARD_IO_REQUEST_LITE PSCARD_IO_REQUEST +#define LPSCARD_IO_REQUEST_LITE LPSCARD_IO_REQUEST +#define LPCSCARD_IO_REQUEST_LITE LPCSCARD_IO_REQUEST + +#else + +#undef MAX_ATR_SIZE +#define MAX_ATR_SIZE 33 /**< Maximum ATR size */ + +typedef struct +{ + const char *szReader; + void *pvUserData; + DWORD_LITE dwCurrentState; + DWORD_LITE dwEventState; + DWORD_LITE cbAtr; + unsigned char rgbAtr[MAX_ATR_SIZE]; +} +SCARD_READERSTATE_LITE; + +typedef SCARD_READERSTATE_LITE *LPSCARD_READERSTATE_LITE; + +typedef struct +{ + DWORD_LITE dwProtocol; /**< Protocol identifier */ + DWORD_LITE cbPciLength; /**< Protocol Control Inf Length */ +} +SCARD_IO_REQUEST_LITE, *PSCARD_IO_REQUEST_LITE, *LPSCARD_IO_REQUEST_LITE; + +typedef const SCARD_IO_REQUEST_LITE *LPCSCARD_IO_REQUEST_LITE; + +#endif + +enum unix_funcs +{ + unix_SCardEstablishContext, + unix_SCardReleaseContext, + unix_SCardIsValidContext, + unix_SCardConnect, + unix_SCardReconnect, + unix_SCardDisconnect, + unix_SCardBeginTransaction, + unix_SCardEndTransaction, + unix_SCardStatus, + unix_SCardGetStatusChange, + unix_SCardControl, + unix_SCardTransmit, + unix_SCardListReaderGroups, + unix_SCardListReaders, + unix_SCardFreeMemory, + unix_SCardCancel, + unix_SCardGetAttrib, + unix_SCardSetAttrib, + unix_process_attach, + unix_process_detach, +}; + +struct SCardEstablishContext_params +{ + DWORD_LITE dwScope; + LPCVOID pvReserved1; + LPCVOID pvReserved2; + LPSCARDCONTEXT phContext; +}; + +struct SCardReleaseContext_params +{ + SCARDCONTEXT hContext; +}; + +struct SCardIsValidContext_params +{ + SCARDCONTEXT hContext; +}; + +struct SCardConnect_params +{ + SCARDCONTEXT hContext; + LPCSTR szReader; + DWORD_LITE dwShareMode; + DWORD_LITE dwPreferredProtocols; + LPSCARDHANDLE phCard; + DWORD_LITE *pdwActiveProtocol; +}; + +struct SCardReconnect_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwShareMode; + DWORD_LITE dwPreferredProtocols; + DWORD_LITE dwInitialization; + DWORD_LITE *pdwActiveProtocol; +}; + +struct SCardDisconnect_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwDisposition; +}; + +struct SCardBeginTransaction_params +{ + SCARDHANDLE hCard; +}; + +struct SCardEndTransaction_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwDisposition; +}; + +struct SCardStatus_params +{ + SCARDHANDLE hCard; + LPSTR mszReaderName; + DWORD_LITE *pcchReaderLen; + DWORD_LITE *pdwState; + DWORD_LITE *pdwProtocol; + LPBYTE pbAtr; + DWORD_LITE *pcbAtrLen; +}; + +struct SCardGetStatusChange_params +{ + SCARDCONTEXT hContext; + DWORD_LITE dwTimeout; + SCARD_READERSTATE_LITE *rgReaderStates; + DWORD_LITE cReaders; +}; + +struct SCardControl_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwControlCode; + LPCVOID pbSendBuffer; + DWORD_LITE cbSendLength; + LPVOID pbRecvBuffer; + DWORD_LITE cbRecvLength; + DWORD_LITE *lpBytesReturned; +}; + +struct SCardTransmit_params +{ + SCARDHANDLE hCard; + const SCARD_IO_REQUEST_LITE *pioSendPci; + LPCBYTE pbSendBuffer; + DWORD_LITE cbSendLength; + SCARD_IO_REQUEST_LITE *pioRecvPci; + LPBYTE pbRecvBuffer; + DWORD_LITE *pcbRecvLength; +}; + +struct SCardListReaderGroups_params +{ + SCARDCONTEXT hContext; + LPSTR mszGroups; + DWORD_LITE *pcchGroups; +}; + +struct SCardListReaders_params +{ + SCARDCONTEXT hContext; + LPCSTR mszGroups; + LPSTR mszReaders; + DWORD_LITE *pcchReaders; +}; + +struct SCardFreeMemory_params +{ + SCARDCONTEXT hContext; + LPCVOID pvMem; +}; + +struct SCardCancel_params +{ + SCARDCONTEXT hContext; +}; + +struct SCardGetAttrib_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwAttrId; + LPBYTE pbAttr; + DWORD_LITE *pcbAttrLen; +}; + +struct SCardSetAttrib_params +{ + SCARDHANDLE hCard; + DWORD_LITE dwAttrId; + const LPBYTE pbAttr; + DWORD_LITE cbAttrLen; +}; + +#endif \ No newline at end of file diff --git a/dlls/winscard/winscard.c b/dlls/winscard/winscard.c index accbaf75c3d..ea2e1e2433c 100644 --- a/dlls/winscard/winscard.c +++ b/dlls/winscard/winscard.c @@ -1,5 +1,6 @@ /* - * Copyright 2007 Mounir IDRASSI (mounir.idrassi@idrix.fr, for IDRIX) + * Copyright (C) 2007 Mounir IDRASSI (mounir.idrassi@idrix.fr, for IDRIX) + * Copyright (C) 2023 Konstantin Romanov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,135 +16,1909 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ - #include <stdarg.h> #include "windef.h" #include "winbase.h" +#include "ntuser.h" +#include "wine/unixlib.h" #include "wine/debug.h" + #include "winscard.h" -#include "winternl.h" +#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(winscard);
-static HANDLE g_startedEvent = NULL; +SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 }; +SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 }; +SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 }; + +#define PCSCLITE_SCARD_PROTOCOL_RAW 0x00000004 + +static DWORD_LITE +ms_proto2lite_proto(DWORD dwProtocol) +{ + if (dwProtocol & SCARD_PROTOCOL_RAW) + { + dwProtocol ^= SCARD_PROTOCOL_RAW; + dwProtocol |= PCSCLITE_SCARD_PROTOCOL_RAW; + } + return (DWORD_LITE)dwProtocol; +} + +static DWORD +lite_proto2ms_proto(DWORD_LITE dwProtocol) +{ + if (dwProtocol & PCSCLITE_SCARD_PROTOCOL_RAW) + { + dwProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW; + dwProtocol |= SCARD_PROTOCOL_RAW; + } + return (DWORD)dwProtocol; +} + +HANDLE g_startedEvent = NULL;
-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 };
+#define WINSCARD_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params )
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved); + BOOL is_wow64=FALSE; + TRACE("%p, %#lx, %p\n", hinstDLL, fdwReason, lpvReserved); + IsWow64Process(GetCurrentProcess(), &is_wow64); + if (is_wow64) + WARN("Running in wow64 process. libpcsclite1:i386 must be installed\n");
- switch (fdwReason) - { + switch (fdwReason) { case DLL_PROCESS_ATTACH: + { DisableThreadLibraryCalls(hinstDLL); - /* FIXME: for now, we act as if the pcsc daemon is always started */ + __wine_init_unix_call(); + if(!WINSCARD_CALL( process_attach, NULL )) + WARN("Winscard loading failed."); g_startedEvent = CreateEventA(NULL,TRUE,TRUE,NULL); break; + } case DLL_PROCESS_DETACH: - if (lpvReserved) break; + { + WINSCARD_CALL( process_detach, NULL ); CloseHandle(g_startedEvent); break; + } } - return TRUE; }
-HANDLE WINAPI SCardAccessStartedEvent(void) +static LPVOID SCardAllocate(DWORD dwLength) { - return g_startedEvent; + if(!dwLength) + return NULL; + return HeapAlloc(GetProcessHeap(), 0, dwLength); }
-LONG WINAPI SCardAddReaderToGroupA(SCARDCONTEXT context, LPCSTR reader, LPCSTR group) +static void SCardFree(LPVOID ptr) { - LONG retval; - UNICODE_STRING readerW, groupW; + HeapFree(GetProcessHeap(), 0, ptr); +}
- if(reader) RtlCreateUnicodeStringFromAsciiz(&readerW,reader); - else readerW.Buffer = NULL; - if(group) RtlCreateUnicodeStringFromAsciiz(&groupW,group); - else groupW.Buffer = NULL; +/* + * Convert a wide-char multi-string to an ANSI multi-string + */ +static LONG ConvertListToANSI(LPCWSTR szListW,LPSTR* pszListA,LPDWORD pdwLength) +{ + if(!szListW) + { + *pszListA = NULL; + *pdwLength = 0; + } + else if(!*szListW) /* empty multi-string case */ + { + *pdwLength = 2; + *pszListA = (LPSTR) SCardAllocate(2); + if(!*pszListA) + return SCARD_E_NO_MEMORY; + *pszListA[0] = '\0'; + *pszListA[1] = '\0'; + } + else + { + LPSTR szStr = NULL; + int wlen = 0, alen = 0, totallen = 0; + LPCWSTR szListWPtr = szListW; + + /* compute size of wide-char multi-string */ + while (*szListWPtr) + { + wlen = lstrlenW (szListWPtr) + 1;
- retval = SCardAddReaderToGroupW(context, readerW.Buffer, groupW.Buffer); + totallen += wlen; + szListWPtr += wlen; + } + + totallen++; + + alen = WideCharToMultiByte(CP_ACP, 0, szListW, totallen, NULL, 0, NULL, NULL); + if (alen == 0) + return SCARD_F_INTERNAL_ERROR; + + /* allocate memory */ + szStr = (LPSTR) SCardAllocate (alen); + if(!szStr) + return SCARD_E_NO_MEMORY; + + /* perform the conversion */ + alen = WideCharToMultiByte(CP_ACP, 0, szListW, totallen, szStr, alen, NULL, NULL); + if (alen == 0) + { + SCardFree (szStr); + return SCARD_F_INTERNAL_ERROR; + } + + *pszListA = szStr; + *pdwLength = alen; + } + + return SCARD_S_SUCCESS; +}
- RtlFreeUnicodeString(&readerW); - RtlFreeUnicodeString(&groupW); +/* + * Convert a ANSII multi-string to a wide-char multi-string + */ +static LONG ConvertListToWideChar(LPCSTR szListA,LPWSTR* pszListW,LPDWORD pdwLength) +{ + if(!szListA) + { + *pszListW = NULL; + *pdwLength = 0; + } + else if(!*szListA) /* empty multi-string case */ + { + *pdwLength = 2; + *pszListW = (LPWSTR) SCardAllocate(2*sizeof(WCHAR)); + if(!*pszListW) + return SCARD_E_NO_MEMORY; + *pszListW[0] = '\0'; + *pszListW[1] = '\0'; + } + else + { + LPWSTR szStr = NULL; + int wlen = 0, alen = 0, totallen = 0; + LPCSTR szListAPtr = szListA; + + /* compute size of ANSI multi-string */ + while (*szListAPtr) + { + alen = lstrlenA (szListAPtr) + 1;
- return retval; + totallen += alen; + szListAPtr += alen; + } + + totallen++; + + wlen = MultiByteToWideChar(CP_ACP, 0, szListA, totallen, NULL, 0); + if (wlen == 0) + return SCARD_F_INTERNAL_ERROR; + + /* allocate memory */ + szStr = (LPWSTR) SCardAllocate (wlen * sizeof (WCHAR)); + if(!szStr) + return SCARD_E_NO_MEMORY; + + /* perform the conversion */ + wlen = MultiByteToWideChar(CP_ACP, 0, szListA, totallen, szStr, wlen); + if (wlen == 0) + { + SCardFree (szStr); + return SCARD_F_INTERNAL_ERROR; + } + + *pszListW = szStr; + *pdwLength = wlen; + } + + return SCARD_S_SUCCESS; }
-LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT context, LPCWSTR reader, LPCWSTR group) + +/* + * translate PCSC-lite errors to equivalent MS ones + * Actually, the only difference is for SCARD_W_INSERTED_CARD(0x8010006A) and + * SCARD_E_UNSUPPORTED_FEATURE (0x8010001F) + */ + +#define PCSCLITE_SCARD_W_INSERTED_CARD 0x8010006A +#define PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE 0x8010001F + +static LONG TranslateToWin32(LONG lRet) { - FIXME("%x %s %s\n", (unsigned int) context, debugstr_w(reader), debugstr_w(group)); - return SCARD_S_SUCCESS; + if(lRet == PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE) + return SCARD_E_UNSUPPORTED_FEATURE; + else if(lRet == PCSCLITE_SCARD_W_INSERTED_CARD) + return SCARD_F_UNKNOWN_ERROR; /* FIXME: is there a better WIN32 error code */ + else + return lRet; } +
-LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, - LPCVOID pvReserved2, LPSCARDCONTEXT phContext) +/* + * events functions + */ + +HANDLE WINAPI SCardAccessNewReaderEvent(void) { - FIXME("(%lx,%p,%p,%p) stub\n", dwScope, pvReserved1, pvReserved2, phContext); + FIXME("stub\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + return NULL; }
-LONG WINAPI SCardIsValidContext(SCARDCONTEXT context) +HANDLE WINAPI SCardAccessStartedEvent() { - FIXME("(%Ix) stub\n", context); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + return g_startedEvent; }
-LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguidInterfaces, DWORD cguidInterfaceCount, LPSTR mszCards, LPDWORD pcchCards) +void WINAPI SCardReleaseStartedEvent(HANDLE hStartedEventHandle) { - FIXME(": stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + /* do nothing because we don't implement yet reference couting for the event handle*/ }
-LONG WINAPI SCardReleaseContext(SCARDCONTEXT context) +LONG WINAPI SCardFreeMemory( SCARDCONTEXT hContext,LPCVOID pvMem) { - FIXME("(%Ix) stub\n", context); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + if(pvMem) + SCardFree((void*) pvMem); + return SCARD_S_SUCCESS; }
-LONG WINAPI SCardStatusA(SCARDHANDLE context, LPSTR szReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) +/* + * smart cards database functions. Almost all of them are stubs + */ + +LONG WINAPI SCardListCardsA( + SCARDCONTEXT hContext, + const BYTE* pbAtr, + LPCGUID rgquidInterfaces, + DWORD cguidInterfaceCount, + LPSTR mszCards, + LPDWORD pcchCards) { - FIXME("(%Ix) stub\n", context); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + TRACE("0x%08X, %p, %p, %#lx, %p, %p - stub\n",(unsigned int) hContext,pbAtr,rgquidInterfaces,cguidInterfaceCount,mszCards,pcchCards); + + /* we simuate the fact that no cards are enregistred on the system by returning an empty multi-string*/ + if(!pcchCards) + return SCARD_E_INVALID_PARAMETER; + else if(!mszCards) + *pcchCards = 2; + else + { + DWORD len = *pcchCards; + if(SCARD_AUTOALLOCATE == len) + { + if(!mszCards) + return SCARD_E_INVALID_PARAMETER; + else + { + /* allocate memory */ + LPSTR* pmszCards = (LPSTR*) mszCards; + LPSTR szResult = (LPSTR) SCardAllocate(2); + if(!szResult) + return SCARD_E_NO_MEMORY; + szResult[0] = '\0'; + szResult[1] = '\0'; + *pcchCards = 2; + *pmszCards = szResult; + } + } + else + { + if(len < 2) + { + *pcchCards = 2; + return SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + /* return a empty multi string */ + mszCards[0] = '\0'; + mszCards[1] = '\0'; + *pcchCards = 2; + } + } + } + + return SCARD_S_SUCCESS; }
-LONG WINAPI SCardStatusW(SCARDHANDLE context, LPWSTR szReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState,LPDWORD pdwProtocol,LPBYTE pbAtr,LPDWORD pcbArtLen) +LONG WINAPI SCardListCardsW( + SCARDCONTEXT hContext, + const BYTE* pbAtr, + LPCGUID rgquidInterfaces, + DWORD cguidInterfaceCount, + LPWSTR mszCards, + LPDWORD pcchCards) { - FIXME("(%Ix) stub\n", context); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + TRACE("0x%08X, %p, %p, %#lx, %p, %p - stub\n",(unsigned int)hContext,pbAtr,rgquidInterfaces,cguidInterfaceCount,mszCards,pcchCards); + + /* we simuate the fact that no cards are enregistred on the system by returning an empty multi-string*/ + if(!pcchCards) + return SCARD_E_INVALID_PARAMETER; + else if(!mszCards) + *pcchCards = 2; + else + { + DWORD len = *pcchCards; + if(SCARD_AUTOALLOCATE == len) + { + if(!mszCards) + return SCARD_E_INVALID_PARAMETER; + else + { + /* allocate memory */ + LPWSTR* pmszCards = (LPWSTR*) mszCards; + LPWSTR szResult = (LPWSTR) SCardAllocate(2*sizeof(WCHAR)); + if(!szResult) + return SCARD_E_NO_MEMORY; + szResult[0] = '\0'; + szResult[1] = '\0'; + *pcchCards = 2; + *pmszCards = szResult; + } + } + else + { + if(len < 2) + { + *pcchCards = 2; + return SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + /* return a empty multi string */ + mszCards[0] = '\0'; + mszCards[1] = '\0'; + *pcchCards = 2; + } + } + } + + return SCARD_S_SUCCESS; +} + +LONG WINAPI SCardListInterfacesA( + SCARDCONTEXT hContext, + LPCSTR szCard, + LPGUID pguidInterfaces, + LPDWORD pcguidInterfaces) +{ + FIXME("0x%08X %s %p %p - stub\n",(unsigned int)hContext,debugstr_a(szCard),pguidInterfaces,pcguidInterfaces); + + return SCARD_E_UNKNOWN_CARD; }
-void WINAPI SCardReleaseStartedEvent(void) +LONG WINAPI SCardListInterfacesW( + SCARDCONTEXT hContext, + LPCWSTR szCard, + LPGUID pguidInterfaces, + LPDWORD pcguidInterfaces) +{ + FIXME("0x%08X %s %p %p - stub\n",(unsigned int)hContext,debugstr_w(szCard),pguidInterfaces,pcguidInterfaces); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardGetProviderIdA( + SCARDCONTEXT hContext, + LPCSTR szCard, + LPGUID pguidProviderId) { - FIXME("stub\n"); + FIXME("0x%08X %s %p - stub\n",(unsigned int)hContext,debugstr_a(szCard),pguidProviderId); + + if(!pguidProviderId) + return SCARD_E_INVALID_PARAMETER; + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardGetProviderIdW( + SCARDCONTEXT hContext, + LPCWSTR szCard, + LPGUID pguidProviderId) +{ + FIXME("0x%08X %s %p - stub\n",(unsigned int)hContext,debugstr_w(szCard),pguidProviderId); + + if(!pguidProviderId) + return SCARD_E_INVALID_PARAMETER; + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardGetCardTypeProviderNameA( + SCARDCONTEXT hContext, + LPCSTR szCardName, + DWORD dwProviderId, + LPSTR szProvider, + LPDWORD pcchProvider) +{ + FIXME("0x%08X %s %#lx %p %p - stub\n",(unsigned int)hContext,debugstr_a(szCardName),dwProviderId,szProvider,pcchProvider); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardGetCardTypeProviderNameW( + SCARDCONTEXT hContext, + LPCWSTR szCardName, + DWORD dwProviderId, + LPWSTR szProvider, + LPDWORD pcchProvider) +{ + FIXME("0x%08X %s %#lx %p %p - stub\n",(unsigned int)hContext,debugstr_w(szCardName),dwProviderId,szProvider,pcchProvider); + + return SCARD_E_UNKNOWN_CARD; }
-LONG WINAPI SCardListReadersA(SCARDCONTEXT context, const CHAR *groups, CHAR *readers, DWORD *buflen) + +LONG WINAPI SCardIntroduceReaderGroupA( + SCARDCONTEXT hContext, + LPCSTR szGroupName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szGroupName)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardIntroduceReaderGroupW( + SCARDCONTEXT hContext, + LPCWSTR szGroupName) { - FIXME("(%Ix, %s, %p, %p) stub\n", context, debugstr_a(groups), readers, buflen); - return SCARD_E_NO_READERS_AVAILABLE; + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szGroupName)); + + return SCARD_F_UNKNOWN_ERROR; }
-LONG WINAPI SCardListReadersW(SCARDCONTEXT context, const WCHAR *groups, WCHAR *readers, DWORD *buflen) +LONG WINAPI SCardForgetReaderGroupA( + SCARDCONTEXT hContext, + LPCSTR szGroupName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szGroupName)); + + return SCARD_S_SUCCESS; +} + +LONG WINAPI SCardForgetReaderGroupW( + SCARDCONTEXT hContext, + LPCWSTR szGroupName) { - FIXME("(%Ix, %s, %p, %p) stub\n", context, debugstr_w(groups), readers, buflen); - return SCARD_E_NO_READERS_AVAILABLE; + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szGroupName)); + + return SCARD_S_SUCCESS; }
-LONG WINAPI SCardCancel(SCARDCONTEXT context) + +LONG WINAPI SCardIntroduceReaderA( + SCARDCONTEXT hContext, + LPCSTR szReaderName, + LPCSTR szDeviceName) { - FIXME("(%Ix) stub\n", context); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return SCARD_F_INTERNAL_ERROR; + FIXME("0x%08X %s %s - stub\n",(unsigned int)hContext,debugstr_a(szReaderName),debugstr_a(szDeviceName)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardIntroduceReaderW( + SCARDCONTEXT hContext, + LPCWSTR szReaderName, + LPCWSTR szDeviceName) +{ + FIXME("0x%08X %s %s - stub\n",(unsigned int)hContext,debugstr_w(szReaderName),debugstr_w(szDeviceName)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardForgetReaderA( + SCARDCONTEXT hContext, + LPCSTR szReaderName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szReaderName)); + + return SCARD_S_SUCCESS; +} + + +LONG WINAPI SCardForgetReaderW( + SCARDCONTEXT hContext, + LPCWSTR szReaderName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szReaderName)); + + return SCARD_S_SUCCESS; +} + +LONG WINAPI SCardAddReaderToGroupA( + SCARDCONTEXT hContext, + LPCSTR szReaderName, + LPCSTR szGroupName) +{ + FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_a( szReaderName), debugstr_a(szGroupName)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardAddReaderToGroupW( + SCARDCONTEXT hContext, + LPCWSTR szReaderName, + LPCWSTR szGroupName) +{ + FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_w( szReaderName), debugstr_w(szGroupName)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardRemoveReaderFromGroupA( + SCARDCONTEXT hContext, + LPCSTR szReaderName, + LPCSTR szGroupName) +{ + FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_a( szReaderName), debugstr_a(szGroupName)); + + return SCARD_S_SUCCESS; +} + +LONG WINAPI SCardRemoveReaderFromGroupW( + SCARDCONTEXT hContext, + LPCWSTR szReaderName, + LPCWSTR szGroupName) +{ + FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_w( szReaderName), debugstr_w(szGroupName)); + + return SCARD_S_SUCCESS; +} + + +LONG WINAPI SCardIntroduceCardTypeA( + SCARDCONTEXT hContext, + LPCSTR szCardName, + LPCGUID pguidPrimaryProvider, + LPCGUID rgguidInterfaces, + DWORD dwInterfaceCount, + const BYTE* pbAtr, + const BYTE* pbAtrMask, + DWORD cbAtrLen) +{ + FIXME("0x%08X %s %p %p %#lx %p %p %#lx - stub\n",(unsigned int) hContext, debugstr_a(szCardName),pguidPrimaryProvider,rgguidInterfaces,dwInterfaceCount,pbAtr,pbAtrMask,cbAtrLen); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardIntroduceCardTypeW( + SCARDCONTEXT hContext, + LPCWSTR szCardName, + LPCGUID pguidPrimaryProvider, + LPCGUID rgguidInterfaces, + DWORD dwInterfaceCount, + const BYTE* pbAtr, + const BYTE* pbAtrMask, + DWORD cbAtrLen) +{ + FIXME("0x%08X %s %p %p %#lx %p %p %#lx - stub\n",(unsigned int) hContext, debugstr_w(szCardName),pguidPrimaryProvider,rgguidInterfaces,dwInterfaceCount,pbAtr,pbAtrMask,cbAtrLen); + + return SCARD_F_UNKNOWN_ERROR; +} + + +LONG WINAPI SCardSetCardTypeProviderNameA( + SCARDCONTEXT hContext, + LPCSTR szCardName, + DWORD dwProviderId, + LPCSTR szProvider) +{ + FIXME("0x%08X %s %#lx %s - stub\n",(unsigned int) hContext, debugstr_a(szCardName),dwProviderId,debugstr_a(szProvider)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardSetCardTypeProviderNameW( + SCARDCONTEXT hContext, + LPCWSTR szCardName, + DWORD dwProviderId, + LPCWSTR szProvider) +{ + FIXME("0x%08X %s %#lx %s - stub\n",(unsigned int) hContext, debugstr_w(szCardName),dwProviderId,debugstr_w(szProvider)); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardForgetCardTypeA( + SCARDCONTEXT hContext, + LPCSTR szCardName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int) hContext, debugstr_a(szCardName)); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardForgetCardTypeW( + SCARDCONTEXT hContext, + LPCWSTR szCardName) +{ + FIXME("0x%08X %s - stub\n",(unsigned int) hContext, debugstr_w(szCardName)); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardLocateCardsA( + SCARDCONTEXT hContext, + LPCSTR mszCards, + LPSCARD_READERSTATEA rgReaderStates, + DWORD cReaders) +{ + FIXME("0x%08X %s %p %#lx - stub\n",(unsigned int) hContext, debugstr_a(mszCards),rgReaderStates,cReaders); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardLocateCardsW( + SCARDCONTEXT hContext, + LPCWSTR mszCards, + LPSCARD_READERSTATEW rgReaderStates, + DWORD cReaders) +{ + FIXME("0x%08X %s %p %#lx - stub\n",(unsigned int) hContext, debugstr_w(mszCards),rgReaderStates,cReaders); + + return SCARD_E_UNKNOWN_CARD; +} + +LONG WINAPI SCardLocateCardsByATRA( + SCARDCONTEXT hContext, + LPSCARD_ATRMASK rgAtrMasks, + DWORD cAtrs, + LPSCARD_READERSTATEA rgReaderStates, + DWORD cReaders) +{ + FIXME("0x%08X %p %#lx %p %#lx - stub\n",(unsigned int) hContext, rgAtrMasks, cAtrs, rgReaderStates, cReaders); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardLocateCardsByATRW( + SCARDCONTEXT hContext, + LPSCARD_ATRMASK rgAtrMasks, + DWORD cAtrs, + LPSCARD_READERSTATEW rgReaderStates, + DWORD cReaders) +{ + FIXME("0x%08X %p %#lx %p %#lx - stub\n",(unsigned int) hContext, rgAtrMasks, cAtrs, rgReaderStates, cReaders); + + return SCARD_F_UNKNOWN_ERROR; +} + +LONG WINAPI SCardListReaderGroupsA( + SCARDCONTEXT hContext, + LPSTR mszGroups, + LPDWORD pcchGroups) +{ + LONG lRet = SCARD_F_UNKNOWN_ERROR; + DWORD_LITE len ; + struct SCardListReaderGroups_params params; + + TRACE(" 0x%08X %s %p\n",(unsigned int) hContext,debugstr_a(mszGroups),pcchGroups); + + if(!pcchGroups) + lRet = SCARD_E_INVALID_PARAMETER; + else if(mszGroups && *pcchGroups == SCARD_AUTOALLOCATE) + { + LPSTR* pmszGroups = (LPSTR*) mszGroups; + LPSTR szList = NULL; + len = 0; + + /* ask for the length */ + params.hContext = hContext; + params.mszGroups = NULL; + params.pcchGroups = &len; + lRet = WINSCARD_CALL( SCardListReaderGroups, ¶ms ); + + if(SCARD_S_SUCCESS == lRet) + { + /* allocate memory for the list */ + szList = (LPSTR) SCardAllocate((DWORD) len); + if(!szList) + lRet = SCARD_E_NO_MEMORY; + else + { + /* fill the list */ + params.hContext = hContext; + params.mszGroups = szList; + params.pcchGroups = &len; + lRet = WINSCARD_CALL( SCardListReaderGroups, ¶ms ); + if(SCARD_S_SUCCESS != lRet) + SCardFree(szList); + else + { + *pmszGroups = szList; + *pcchGroups = (DWORD) len; + } + } + } + } + else + { + params.hContext = hContext; + params.mszGroups = mszGroups; + + if (pcchGroups) + { + len = *pcchGroups; + params.pcchGroups = &len; + } + else + params.pcchGroups = NULL; + + lRet = WINSCARD_CALL( SCardListReaderGroups, ¶ms ); + if (pcchGroups) + *pcchGroups = len; + } + + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardListReaderGroupsW( + SCARDCONTEXT hContext, + LPWSTR mszGroups, + LPDWORD pcchGroups) +{ + LONG lRet = SCARD_F_UNKNOWN_ERROR; + LPSTR szList = NULL; + LPWSTR szListW = NULL; + DWORD alen = 0,wlen = 0; + + TRACE(" 0x%08X %s %p\n",(unsigned int) hContext,debugstr_w(mszGroups),pcchGroups); + + if(!pcchGroups) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + if(!mszGroups) + { + /* asking for length only + * get the length in ANSI and multiply by sizeof(WCHAR) + */ + alen = 0; + lRet = SCardListReaderGroupsA(hContext,NULL,&alen); + if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER) + { + *pcchGroups = alen ; + } + goto end_label; + } + + /* get the ASCII list from pcsclite */ + alen = SCARD_AUTOALLOCATE; + lRet = SCardListReaderGroupsA(hContext,(LPSTR) &szList,&alen); + if(SCARD_S_SUCCESS != lRet) + goto end_label; + + /* now convert the list to a wide char list */ + lRet = ConvertListToWideChar(szList,&szListW,&wlen); + + /* free the ASCII list, we don't need it any more */ + SCardFreeMemory(hContext,(LPCVOID) szList); + + if(SCARD_S_SUCCESS != lRet) + goto end_label; + + if(SCARD_AUTOALLOCATE == *pcchGroups) + { + LPWSTR* pmszGroups = (LPWSTR*) mszGroups; + *pmszGroups = szListW; + *pcchGroups = wlen; + szListW = NULL; + lRet = SCARD_S_SUCCESS; + } + else + { + DWORD cchGroups = *pcchGroups; + if(cchGroups < wlen) + { + *pcchGroups = wlen; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + *pcchGroups = wlen; + memcpy(mszGroups,szListW,wlen*sizeof(WCHAR)); + lRet = SCARD_S_SUCCESS; + } + } + } + +end_label: + if(szListW) + SCardFree(szListW); + return TranslateToWin32(lRet); + +} + +LONG WINAPI SCardListReadersA( + SCARDCONTEXT hContext, + LPCSTR mszGroups, + LPSTR mszReaders, + LPDWORD pcchReaders) +{ + LONG lRet; + TRACE("0x%p %s %s %ld\n",(void*)hContext, debugstr_a(mszGroups), debugstr_a(mszReaders), (pcchReaders==NULL?0:*pcchReaders)); + if(!pcchReaders) + lRet = SCARD_E_INVALID_PARAMETER; + else if(mszReaders && SCARD_AUTOALLOCATE == *pcchReaders) + { + /* get list from pcsc-lite */ + LPSTR* pmszReaders = (LPSTR*) mszReaders; + LPSTR szList = NULL; + DWORD_LITE dwListLength = 0; + struct SCardListReaders_params params = { hContext, mszGroups, NULL, &dwListLength }; + lRet = WINSCARD_CALL( SCardListReaders, ¶ms ); + + if(SCARD_S_SUCCESS != lRet && lRet != SCARD_E_INSUFFICIENT_BUFFER) + goto end_label; + + szList = (LPSTR)SCardAllocate((DWORD) dwListLength); + if(!szList) + { + lRet = SCARD_E_NO_MEMORY; + goto end_label; + } + + params.hContext = hContext; + params.mszReaders = szList; + params.pcchReaders = &dwListLength; + + lRet = WINSCARD_CALL( SCardListReaders, ¶ms ); + + if(SCARD_S_SUCCESS != lRet) + SCardFree(szList); + else + { + *pmszReaders = szList; + *pcchReaders = dwListLength; + } + } + else + { + struct SCardListReaders_params params = { hContext, mszGroups, mszReaders, NULL }; + if (pcchReaders) + { + DWORD_LITE dwListLength = *pcchReaders; + params.pcchReaders = &dwListLength; + lRet = WINSCARD_CALL( SCardListReaders, ¶ms ); + *pcchReaders = dwListLength; + } + else + lRet = WINSCARD_CALL( SCardListReaders, ¶ms ); + } + +end_label: + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardListReadersW( + SCARDCONTEXT hContext, + LPCWSTR mszGroups, + LPWSTR mszReaders, + LPDWORD pcchReaders) +{ + LONG lRet; + TRACE("0x%p %s %s %p\n",(void*) hContext,debugstr_w(mszGroups),debugstr_w(mszReaders),pcchReaders); + + if(!pcchReaders) + lRet = SCARD_E_INVALID_PARAMETER; + // else if(!liteSCardListReaders) + // lRet = SCARD_F_INTERNAL_ERROR; + else + { + /* call the ANSI version */ + LPSTR mszGroupsA = NULL; + LPSTR mszReadersA = NULL; + LPWSTR szListW = NULL; + DWORD dwLength ; + if(mszGroups) + { + lRet = ConvertListToANSI(mszGroups,&mszGroupsA,&dwLength); + if(SCARD_S_SUCCESS != lRet) + goto end_label; + } + + if(!mszReaders) + { + /* asking for length only + * Assume that number of wide char is the same + * as the number f ANSI characters + */ + dwLength = 0; + lRet = SCardListReadersA(hContext,mszGroupsA,NULL,&dwLength); + if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER) + { + *pcchReaders = dwLength; + } + if(mszGroupsA) + SCardFree(mszGroupsA); + goto end_label; + } + + dwLength = SCARD_AUTOALLOCATE; + lRet = SCardListReadersA(hContext,mszGroupsA,(LPSTR) &mszReadersA,&dwLength); + + /* free the ANSI list of groups : no more needed */ + if(mszGroupsA) + SCardFree(mszGroupsA); + + if(SCARD_S_SUCCESS != lRet) + goto end_label; + + /* we now have the list in ANSI. Covert it to wide-char format*/ + lRet = ConvertListToWideChar(mszReadersA,&szListW,&dwLength); + + /* ANSI list of readers no more needed */ + SCardFreeMemory(hContext,(LPCVOID) mszReadersA); + + if(SCARD_S_SUCCESS != lRet) + goto end_label; + + if(SCARD_AUTOALLOCATE == *pcchReaders) + { + LPWSTR* pmszReaders = (LPWSTR*) mszReaders; + *pmszReaders = szListW; + szListW = NULL; + *pcchReaders = dwLength; + } + else + { + DWORD inputLength = *pcchReaders; + if(inputLength < dwLength) + lRet = SCARD_E_INSUFFICIENT_BUFFER; + else + memcpy(mszReaders,szListW,dwLength*sizeof(WCHAR)); + *pcchReaders = dwLength; + } + + if(szListW) + SCardFree(szListW); + } +end_label: + return TranslateToWin32(lRet); +} + +/* + * PCS/SC communication functions + */ +LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext) +{ + LONG lRet; + struct SCardEstablishContext_params params = { dwScope, pvReserved1, pvReserved2, phContext}; + TRACE("%#lx %p %p %p\n",dwScope,pvReserved1,pvReserved2,phContext); + + if(!phContext) + lRet = SCARD_E_INVALID_PARAMETER; + else + lRet = WINSCARD_CALL( SCardEstablishContext, ¶ms ); + + TRACE("returned %#lx hContext %p\n", lRet, (void*)*params.phContext); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardReleaseContext(SCARDCONTEXT hContext) +{ + LONG lRet; + struct SCardReleaseContext_params params = { hContext }; + TRACE("0x%p\n", (void*)hContext); + + lRet = WINSCARD_CALL( SCardReleaseContext, ¶ms ); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardIsValidContext(SCARDCONTEXT hContext) +{ + struct SCardIsValidContext_params params = { hContext }; + TRACE("0x%p\n", (void*)hContext); + + return TranslateToWin32(WINSCARD_CALL( SCardIsValidContext, ¶ms )); +} + +LONG WINAPI SCardConnectA(SCARDCONTEXT hContext, + LPCSTR szReader, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, + LPDWORD pdwActiveProtocol) +{ + LONG lRet; + struct SCardConnect_params params = { hContext, szReader, dwShareMode, dwPreferredProtocols, phCard, NULL }; + TRACE(" 0x%08X %s %#lx %#lx %p %p\n",(unsigned int) hContext,debugstr_a(szReader),dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol); + if(!szReader || !phCard || !pdwActiveProtocol) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + /* the value of SCARD_PROTOCOL_RAW is different between MS implementation and + * pcsc-lite implementation. We must change its value + */ + if(dwPreferredProtocols & SCARD_PROTOCOL_RAW) + { + dwPreferredProtocols ^= SCARD_PROTOCOL_RAW; + dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW; + params.dwPreferredProtocols = dwPreferredProtocols; + } + + if (pdwActiveProtocol) + { + DWORD_LITE dwProtocol = *pdwActiveProtocol; + params.pdwActiveProtocol = &dwProtocol; + lRet = WINSCARD_CALL( SCardConnect, ¶ms ); + *pdwActiveProtocol = (DWORD) dwProtocol; + } + else + lRet = WINSCARD_CALL( SCardConnect, ¶ms ); + if(SCARD_S_SUCCESS == lRet) + { + /* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */ + if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW) + { + *pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW; + *pdwActiveProtocol |= SCARD_PROTOCOL_RAW; + } + + } + } + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardConnectW(SCARDCONTEXT hContext, + LPCWSTR szReader, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, + LPDWORD pdwActiveProtocol) +{ + LONG lRet; + struct SCardConnect_params params = { hContext, NULL, dwShareMode, dwPreferredProtocols, phCard, NULL}; + TRACE(" 0x%08X %s %#lx %#lx %p %p\n",(unsigned int) hContext,debugstr_w(szReader),dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol); + if(!szReader || !phCard || !pdwActiveProtocol) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + LPSTR szReaderA = NULL; + int dwLen = WideCharToMultiByte(CP_ACP,0,szReader,-1,NULL,0,NULL,NULL); + if(!dwLen) + { + lRet = SCARD_F_UNKNOWN_ERROR; + goto end_label; + } + + szReaderA = (LPSTR) SCardAllocate(dwLen); + if(!szReaderA) + { + lRet = SCARD_E_NO_MEMORY; + goto end_label; + } + + dwLen = WideCharToMultiByte(CP_ACP,0,szReader,-1,szReaderA,dwLen,NULL,NULL); + if(!dwLen) + { + SCardFree(szReaderA); + lRet = SCARD_F_UNKNOWN_ERROR; + goto end_label; + } + + /* the value of SCARD_PROTOCOL_RAW is different between MS implementation and + * pcsc-lite implementation. We must change its value + */ + if(dwPreferredProtocols & SCARD_PROTOCOL_RAW) + { + dwPreferredProtocols ^= SCARD_PROTOCOL_RAW; + dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW; + params.dwPreferredProtocols = dwPreferredProtocols; + } + + params.szReader = szReaderA; + if (pdwActiveProtocol) + { + DWORD_LITE dwProtocol = *pdwActiveProtocol; + params.pdwActiveProtocol = &dwProtocol; + lRet = WINSCARD_CALL( SCardConnect, ¶ms ); + *pdwActiveProtocol = (DWORD) dwProtocol; + } + else + lRet = WINSCARD_CALL( SCardConnect, ¶ms ); + if(SCARD_S_SUCCESS == lRet) + { + /* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */ + if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW) + { + *pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW; + *pdwActiveProtocol |= SCARD_PROTOCOL_RAW; + } + } + + /* free the allocate ANSI string */ + SCardFree(szReaderA); + } +end_label: + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardReconnect(SCARDHANDLE hCard, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + DWORD dwInitialization, + LPDWORD pdwActiveProtocol) +{ + LONG lRet; + struct SCardReconnect_params params = { hCard, dwShareMode, dwPreferredProtocols, dwInitialization, NULL}; + TRACE(" 0x%08X %#lx %#lx %#lx %p\n",(unsigned int) hCard,dwShareMode,dwPreferredProtocols,dwInitialization,pdwActiveProtocol); + if(!pdwActiveProtocol) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + /* the value of SCARD_PROTOCOL_RAW is different between MS implementation and + * pcsc-lite implementation. We must change its value + */ + if(dwPreferredProtocols & SCARD_PROTOCOL_RAW) + { + dwPreferredProtocols ^= SCARD_PROTOCOL_RAW; + dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW; + params.dwPreferredProtocols = dwPreferredProtocols; + } + + if (pdwActiveProtocol) + { + DWORD_LITE dwProtocol = *pdwActiveProtocol; + params.pdwActiveProtocol = &dwProtocol; + lRet = WINSCARD_CALL( SCardReconnect, ¶ms ); + *pdwActiveProtocol = (DWORD) dwProtocol; + } + else + lRet = WINSCARD_CALL( SCardReconnect, ¶ms ); + + if(SCARD_S_SUCCESS == lRet) + { + /* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */ + if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW) + { + *pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW; + *pdwActiveProtocol |= SCARD_PROTOCOL_RAW; + } + } + } + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) +{ + LONG lRet; + struct SCardDisconnect_params params = { hCard, dwDisposition}; + TRACE(" 0x%08X %#lx\n",(unsigned int) hCard,dwDisposition); + + lRet = WINSCARD_CALL( SCardDisconnect, ¶ms ); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard) +{ + LONG lRet; + struct SCardBeginTransaction_params params = { hCard }; + TRACE(" 0x%08X\n",(unsigned int) hCard); + + lRet = WINSCARD_CALL( SCardBeginTransaction, ¶ms ); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) +{ + LONG lRet; + struct SCardEndTransaction_params params = { hCard, dwDisposition }; + TRACE(" 0x%08X %#lx\n",(unsigned int) hCard,dwDisposition); + + lRet = WINSCARD_CALL( SCardEndTransaction, ¶ms ); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardState( + SCARDHANDLE hCard, + LPDWORD pdwState, + LPDWORD pdwProtocol, + LPBYTE pbAtr, + LPDWORD pcbAtrLen) +{ + LONG lRet ; + LPSTR szName = NULL; + DWORD cchReaderLen = SCARD_AUTOALLOCATE; + TRACE(" 0x%08X %p %p %p %p\n",(unsigned int) hCard,pdwState,pdwProtocol,pbAtr,pcbAtrLen); + lRet = SCardStatusA(hCard,(LPSTR) &szName,&cchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen); + + /* free szName is allocated by SCardStatusA */ + if(szName) + SCardFree((void*) szName); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardStatusA( + SCARDHANDLE hCard, + LPSTR mszReaderNames, + LPDWORD pcchReaderLen, + LPDWORD pdwState, + LPDWORD pdwProtocol, + LPBYTE pbAtr, + LPDWORD pcbAtrLen) +{ + LONG lRet; + struct SCardStatus_params params; + TRACE(" 0x%08X %p %p %p %p %p %p\n",(unsigned int) hCard,mszReaderNames,pcchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen); + if(!pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + DWORD_LITE dwNameLen = 0,dwAtrLen=MAX_ATR_SIZE, dwState, dwProtocol = 0; + LPDWORD_LITE pdwStateLite = NULL, pdwProtocolLite = NULL, pdwNameLenLite = NULL, pdwAtrLenLite = NULL; + BYTE atr[MAX_ATR_SIZE]; + if (pdwState) + { + dwState = *pdwState; + pdwStateLite = &dwState; + } + if (pdwProtocol) + { + pdwProtocolLite = &dwProtocol; + } + + if(!mszReaderNames || !pbAtr + || (*pcchReaderLen == SCARD_AUTOALLOCATE) || (*pcbAtrLen == SCARD_AUTOALLOCATE)) + { + /* retreive the information from pcsc-lite */ + BOOL bHasAutoAllocated = FALSE; + LPSTR szNames = NULL; + + params.hCard = hCard; + params.mszReaderName = NULL; + params.pcchReaderLen = &dwNameLen; + params.pdwState = pdwStateLite; + params.pdwProtocol = pdwProtocolLite; + params.pbAtr = atr; + params.pcbAtrLen = &dwAtrLen; + + lRet = WINSCARD_CALL( SCardStatus, ¶ms ); + if (pdwState) + { + *pdwState = (DWORD) dwState; + } + if (pdwProtocol) + { + *pdwProtocol = lite_proto2ms_proto(dwProtocol); + } + if(lRet != SCARD_S_SUCCESS && lRet != SCARD_E_INSUFFICIENT_BUFFER) + goto end_label; + + /* case 1: asking for reader names length */ + if(!mszReaderNames) + { + lRet = SCARD_S_SUCCESS; + *pcchReaderLen = dwNameLen; + if(!pbAtr) + *pcbAtrLen = (DWORD) dwAtrLen; + else if(*pcbAtrLen == SCARD_AUTOALLOCATE) + { + LPBYTE* ppbAtr = (LPBYTE*) pbAtr; + *ppbAtr = (LPBYTE) SCardAllocate(dwAtrLen); + *pcbAtrLen = (DWORD) dwAtrLen; + memcpy(*ppbAtr,atr,dwAtrLen); + } + else if(*pcbAtrLen < dwAtrLen) + { + *pcbAtrLen = dwAtrLen; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + *pcbAtrLen = dwAtrLen; + memcpy(pbAtr,atr,dwAtrLen); + } + + goto end_label; + } + + /* case 2: reader names pointer provided but its length is unsufficient */ + if(*pcchReaderLen < dwNameLen) + { + *pcchReaderLen = (DWORD) dwNameLen; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + goto end_label; + } + + bHasAutoAllocated = (*pcchReaderLen == SCARD_AUTOALLOCATE)? TRUE : FALSE; + if(bHasAutoAllocated) + szNames = (LPSTR) SCardAllocate(dwNameLen); + else + szNames = mszReaderNames; + + params.hCard = hCard; + params.mszReaderName = szNames; + params.pcchReaderLen = &dwNameLen; + params.pdwState = pdwStateLite; + params.pdwProtocol = pdwProtocolLite; + params.pbAtr = atr; + params.pcbAtrLen = &dwAtrLen; + + lRet = WINSCARD_CALL( SCardStatus, ¶ms ); + if(lRet != SCARD_S_SUCCESS) + { + if(bHasAutoAllocated) + SCardFree(szNames); + goto end_label; + } + + *pcchReaderLen = (DWORD) dwNameLen; + if(bHasAutoAllocated) + { + LPSTR* pmszReaderNames = (LPSTR*) mszReaderNames; + *pmszReaderNames = szNames; + szNames = NULL; + } + + + /* now fill the ATR parameter */ + if(!pbAtr) + *pcbAtrLen = (DWORD) dwAtrLen; + else if(*pcbAtrLen == SCARD_AUTOALLOCATE) + { + LPBYTE* ppbAtr = (LPBYTE*) pbAtr; + *ppbAtr = (LPBYTE) SCardAllocate(dwAtrLen); + *pcbAtrLen = (DWORD) dwAtrLen; + memcpy(*ppbAtr,atr,dwAtrLen); + } + else if(*pcbAtrLen < dwAtrLen) + { + *pcbAtrLen = (DWORD) dwAtrLen; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + *pcbAtrLen = (DWORD) dwAtrLen; + memcpy(pbAtr,atr,dwAtrLen); + } + + if(bHasAutoAllocated && szNames) + SCardFree(szNames); + } + else + { + if (pcchReaderLen) + { + dwNameLen = *pcchReaderLen; + pdwNameLenLite = &dwNameLen; + } + else + pdwNameLenLite = NULL; + if (pcbAtrLen) + { + dwAtrLen = *pcbAtrLen; + pdwAtrLenLite = &dwAtrLen; + } + else + pdwAtrLenLite = NULL; + + params.hCard = hCard; + params.mszReaderName = mszReaderNames; + params.pcchReaderLen = pdwNameLenLite; + params.pdwState = pdwStateLite; + params.pdwProtocol = pdwProtocolLite; + params.pbAtr = pbAtr; + params.pcbAtrLen = pdwAtrLenLite; + + lRet = WINSCARD_CALL( SCardStatus, ¶ms ); + if (pdwState) + { + *pdwState = (DWORD) dwState; + } + if (pdwProtocol) + { + *pdwProtocol = lite_proto2ms_proto(dwProtocol); + } + if (pcchReaderLen) + { + *pcchReaderLen = dwNameLen; + } + if (pcbAtrLen) + { + *pcbAtrLen = dwAtrLen; + } + } + } + +end_label: + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardStatusW( + SCARDHANDLE hCard, + LPWSTR mszReaderNames, + LPDWORD pcchReaderLen, + LPDWORD pdwState, + LPDWORD pdwProtocol, + LPBYTE pbAtr, + LPDWORD pcbAtrLen) +{ + LONG lRet; + TRACE(" 0x%08X %p %p %p %p %p %p\n",(unsigned int) hCard,mszReaderNames,pcchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen); + if(!pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + /* call the ANSI version with SCARD_AUTOALLOCATE */ + LPSTR mszReaderNamesA = NULL; + DWORD dwAnsiNamesLength = SCARD_AUTOALLOCATE; + lRet = SCardStatusA(hCard,(LPSTR) &mszReaderNamesA,&dwAnsiNamesLength,pdwState,pdwProtocol,pbAtr,pcbAtrLen); + if(lRet == SCARD_S_SUCCESS) + { + /* convert mszReaderNamesA to a wide char multi-string */ + LPWSTR mszWideNamesList = NULL; + DWORD dwWideNamesLength = 0; + lRet = ConvertListToWideChar(mszReaderNamesA,&mszWideNamesList,&dwWideNamesLength); + + /* no more needed */ + if(mszReaderNamesA) + SCardFree(mszReaderNamesA); + + if(lRet == SCARD_S_SUCCESS) + { + if(!mszReaderNames) + *pcchReaderLen = dwWideNamesLength; + else if(*pcchReaderLen == SCARD_AUTOALLOCATE) + { + LPWSTR* pmszReaderNames = (LPWSTR*) mszReaderNames; + *pmszReaderNames = mszWideNamesList; + *pcchReaderLen = dwWideNamesLength; + mszWideNamesList = NULL; + } + else if(*pcchReaderLen < dwWideNamesLength) + { + *pcchReaderLen = dwWideNamesLength; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + *pcchReaderLen = dwWideNamesLength; + memcpy(mszReaderNames,mszWideNamesList,dwWideNamesLength); + } + } + + if(mszWideNamesList) + SCardFree(mszWideNamesList); + } + } + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardGetStatusChangeA( + SCARDCONTEXT hContext, + DWORD dwTimeout, + LPSCARD_READERSTATEA rgReaderStates, + DWORD cReaders) +{ + LONG lRet; + struct SCardGetStatusChange_params params; + TRACE(" 0x%08X %#lx %p %#lx\n",(unsigned int) hContext, dwTimeout,rgReaderStates,cReaders); + if(!rgReaderStates && cReaders) + lRet = SCARD_E_INVALID_PARAMETER; + else if(!cReaders) + { + lRet = SCardIsValidContext(hContext); + } + else + { + DWORD i; + LPSCARD_READERSTATE_LITE pStates = (LPSCARD_READERSTATE_LITE) SCardAllocate(cReaders * sizeof(SCARD_READERSTATE_LITE)); + memset(pStates,0,cReaders * sizeof(SCARD_READERSTATE_LITE)); + for(i=0;i<cReaders;i++) + { + pStates[i].szReader = rgReaderStates[i].szReader; + pStates[i].pvUserData = rgReaderStates[i].pvUserData; + } + + /* in pcsclite, dwTimeout = 0 is equivalent to dwTimeout = INFINITE + * In Windows, dwTimeout = 0 means return immediately + * We will simulate an immediate return + */ + if(dwTimeout == 0) + { + /* get the current state of readers and compare it with input + * Return SCARD_S_SUCCESS if a change is detected and + * SCARD_E_TIMEOUT otherwide + */ + params.hContext = hContext; + params.dwTimeout = 0; + params.rgReaderStates = pStates; + params.cReaders = cReaders; + lRet = WINSCARD_CALL( SCardGetStatusChange, ¶ms ); + if(lRet == SCARD_S_SUCCESS) + { + BOOL bStateChanges = FALSE; + for(i=0;i<cReaders;i++) + { + DWORD dwState = pStates[i].dwEventState & (~SCARD_STATE_CHANGED); + rgReaderStates[i].cbAtr = pStates[i].cbAtr; + memcpy(rgReaderStates[i].rgbAtr,pStates[i].rgbAtr,min (rgReaderStates[i].cbAtr, sizeof (rgReaderStates[i].rgbAtr))); + + if(dwState != rgReaderStates[i].dwCurrentState) + { + rgReaderStates[i].dwEventState = pStates[i].dwEventState; + bStateChanges = TRUE; + } + else + rgReaderStates[i].dwEventState = dwState; + } + + if(!bStateChanges) + lRet = SCARD_E_TIMEOUT; + } + } + else + { + for(i=0;i<cReaders;i++) + { + pStates[i].dwCurrentState = rgReaderStates[i].dwCurrentState; + pStates[i].dwEventState = rgReaderStates[i].dwEventState; + pStates[i].cbAtr = min (MAX_ATR_SIZE, rgReaderStates[i].cbAtr); + memcpy(pStates[i].rgbAtr,rgReaderStates[i].rgbAtr,pStates[i].cbAtr); + } + + params.hContext = hContext; + params.dwTimeout = dwTimeout; + params.rgReaderStates = pStates; + params.cReaders = cReaders; + lRet = WINSCARD_CALL( SCardGetStatusChange, ¶ms ); + + for(i=0;i<cReaders;i++) + { + rgReaderStates[i].dwCurrentState = pStates[i].dwCurrentState; + rgReaderStates[i].dwEventState = pStates[i].dwEventState; + rgReaderStates[i].cbAtr = pStates[i].cbAtr; + memcpy(rgReaderStates[i].rgbAtr,pStates[i].rgbAtr, MAX_ATR_SIZE); + } + } + + SCardFree(pStates); + } + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardGetStatusChangeW( + SCARDCONTEXT hContext, + DWORD dwTimeout, + LPSCARD_READERSTATEW rgReaderStates, + DWORD cReaders) +{ + LONG lRet; + TRACE(" 0x%08X %#lx %p %#lx\n",(unsigned int) hContext, dwTimeout,rgReaderStates,cReaders); + if(!rgReaderStates && cReaders) + lRet = SCARD_E_INVALID_PARAMETER; + else if(!cReaders) + { + lRet = SCardIsValidContext(hContext); + } + else + { + /* create an ANSI array of readers states* */ + DWORD i; + LPSCARD_READERSTATEA rgReaderStatesAnsi = (LPSCARD_READERSTATEA) SCardAllocate(cReaders * sizeof(SCARD_READERSTATEA)); + if(!rgReaderStatesAnsi) + return SCARD_E_NO_MEMORY; + memset(rgReaderStatesAnsi,0,cReaders * sizeof(SCARD_READERSTATEA)); + for(i=0;i<cReaders;i++) + { + int alen = WideCharToMultiByte(CP_ACP,0,rgReaderStates[i].szReader,-1,NULL,0,NULL,NULL); + if(!alen) + break; + rgReaderStatesAnsi[i].szReader = (LPSTR) SCardAllocate(alen); + WideCharToMultiByte(CP_ACP,0,rgReaderStates[i].szReader,-1,(LPSTR) rgReaderStatesAnsi[i].szReader,alen,NULL,NULL); + rgReaderStatesAnsi[i].pvUserData = rgReaderStates[i].pvUserData; + rgReaderStatesAnsi[i].dwCurrentState = rgReaderStates[i].dwCurrentState; + rgReaderStatesAnsi[i].dwEventState = rgReaderStates[i].dwEventState; + rgReaderStatesAnsi[i].cbAtr = rgReaderStates[i].cbAtr; + memcpy(rgReaderStatesAnsi[i].rgbAtr,rgReaderStates[i].rgbAtr, sizeof (rgReaderStatesAnsi[i].rgbAtr)); + } + + if(i < cReaders) + lRet = SCARD_F_UNKNOWN_ERROR; + else + { + lRet = SCardGetStatusChangeA(hContext,dwTimeout,rgReaderStatesAnsi,cReaders); + /* copy back the information */ + for(i=0;i<cReaders;i++) + { + rgReaderStates[i].dwEventState = rgReaderStatesAnsi[i].dwEventState; + rgReaderStates[i].cbAtr = rgReaderStatesAnsi[i].cbAtr; + memcpy(rgReaderStates[i].rgbAtr,rgReaderStatesAnsi[i].rgbAtr, sizeof (rgReaderStates[i].rgbAtr)); + } + } + /* free memory */ + for(i=0;i<cReaders;i++) + { + if(rgReaderStatesAnsi[i].szReader) + SCardFree((void*) rgReaderStatesAnsi[i].szReader); + } + SCardFree(rgReaderStatesAnsi); + } + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardControl( + SCARDHANDLE hCard, + DWORD dwControlCode, + LPCVOID pbSendBuffer, + DWORD cbSendLength, + LPVOID pbRecvBuffer, + DWORD cbRecvLength, + LPDWORD lpBytesReturned) +{ + struct SCardControl_params params = { hCard, dwControlCode, pbSendBuffer, cbSendLength, pbRecvBuffer, cbRecvLength, NULL }; + DWORD_LITE dwBytesReturned = 0; + LONG lRet; + if (lpBytesReturned) + { + dwBytesReturned = *lpBytesReturned; + params.lpBytesReturned = &dwBytesReturned; + } + lRet = WINSCARD_CALL( SCardControl, ¶ms ); + if (lpBytesReturned) + *lpBytesReturned = dwBytesReturned; + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardTransmit( + SCARDHANDLE hCard, + LPCSCARD_IO_REQUEST pioSendPci, + const BYTE* pbSendBuffer, + DWORD cbSendLength, + LPSCARD_IO_REQUEST pioRecvPci, + LPBYTE pbRecvBuffer, + LPDWORD pcbRecvLength) +{ + LONG lRet; + struct SCardTransmit_params params; + DWORD_LITE dwRecvLength = 0; + LPDWORD_LITE pdwRecvLengthLite = NULL; + SCARD_IO_REQUEST_LITE ioSendPci, ioRecvPci; + ioSendPci.cbPciLength = sizeof(ioSendPci); + ioRecvPci.cbPciLength = sizeof(ioRecvPci); + + if (pcbRecvLength) + { + dwRecvLength = *pcbRecvLength; + pdwRecvLengthLite = &dwRecvLength; + } + + if (pioRecvPci) { + ioRecvPci.dwProtocol = ms_proto2lite_proto(pioRecvPci->dwProtocol); + } + + if(pioSendPci) + { + ioSendPci.dwProtocol = ms_proto2lite_proto(pioSendPci->dwProtocol); + } + else + { + /* In MS PC/SC, pioSendPci can be NULL. But not in pcsc-lite */ + /* Get the protocol and set the correct value for pioSendPci*/ + DWORD protocol,dwState; + DWORD dwAtrLen,dwNameLen; + lRet = SCardStatusA(hCard,NULL,&dwNameLen,&dwState,&protocol,NULL,&dwAtrLen); + if(lRet == SCARD_S_SUCCESS) + { + ioSendPci.dwProtocol = ms_proto2lite_proto(protocol); + } + else + goto transmit_end; + } + + params.hCard = hCard; + params.pioSendPci = &ioSendPci; + params.pbSendBuffer = pbSendBuffer; + params.cbSendLength = cbSendLength; + params.pioRecvPci = pioRecvPci? &ioRecvPci : NULL; + params.pbRecvBuffer = pbRecvBuffer; + params.pcbRecvLength = pdwRecvLengthLite; + lRet = WINSCARD_CALL( SCardTransmit, ¶ms ); + + if (pcbRecvLength) + *pcbRecvLength = dwRecvLength; + +transmit_end: + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardCancel(SCARDCONTEXT hContext) +{ + LONG lRet; + struct SCardCancel_params params = { hContext }; + TRACE(" 0x%08X \n",(unsigned int) hContext); + lRet = WINSCARD_CALL( SCardCancel, ¶ms ); + + TRACE(" returned %#lx\n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardGetAttrib( + SCARDHANDLE hCard, + DWORD dwAttrId, + LPBYTE pbAttr, + LPDWORD pcbAttrLen) +{ + LONG lRet; + TRACE(" 0x%08X %#lx %p %p \n",(unsigned int) hCard, dwAttrId,pbAttr,pcbAttrLen); + if(!pcbAttrLen) + lRet = SCARD_E_INVALID_PARAMETER; + else + { + LPBYTE ptr = NULL; + DWORD_LITE dwLength = 0; + struct SCardGetAttrib_params params = {hCard, dwAttrId, NULL, &dwLength}; + lRet = WINSCARD_CALL( SCardGetAttrib, ¶ms ); + if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER) + { + if(!pbAttr) + *pcbAttrLen = (DWORD) dwLength; + else if(*pcbAttrLen < (DWORD) dwLength) + { + *pcbAttrLen = (DWORD) dwLength; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + BOOL bHasAutoAllocate = (*pcbAttrLen == SCARD_AUTOALLOCATE)? TRUE : FALSE; + if(bHasAutoAllocate) + ptr = (LPBYTE) SCardAllocate((DWORD) dwLength); + else + ptr = pbAttr; + + params.hCard = hCard; + params.dwAttrId = dwAttrId; + params.pbAttr = ptr; + params.pcbAttrLen = &dwLength; + lRet = WINSCARD_CALL( SCardGetAttrib, ¶ms ); + + if(lRet == SCARD_S_SUCCESS) + { + *pcbAttrLen = (DWORD) dwLength; + if(bHasAutoAllocate) + { + LPBYTE *ppbAttr = (LPBYTE*) pbAttr; + *ppbAttr = ptr; + ptr = NULL; + } + } + + if(bHasAutoAllocate && ptr) + SCardFree(ptr); + } + } + + if(SCARD_E_UNSUPPORTED_FEATURE == TranslateToWin32(lRet)) + { + /* in case of one of these attributes , do it our selves */ + if(SCARD_ATTR_ICC_PRESENCE == dwAttrId || SCARD_ATTR_CURRENT_PROTOCOL_TYPE == dwAttrId + || SCARD_ATTR_ATR_STRING == dwAttrId || SCARD_ATTR_DEVICE_FRIENDLY_NAME_A == dwAttrId + || SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId + || SCARD_ATTR_DEVICE_SYSTEM_NAME_A == dwAttrId + || SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId) + { + DWORD dwState; + DWORD dwProtocol; + BYTE pbAtr[MAX_ATR_SIZE]; + DWORD dwAtrLen =MAX_ATR_SIZE; + LPVOID pszReaderNames = NULL; + DWORD dwNameLength = SCARD_AUTOALLOCATE; + LONG status; + + if(SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId + || SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId) + status = SCardStatusW(hCard,(LPWSTR) &pszReaderNames, &dwNameLength, &dwState,&dwProtocol, pbAtr,&dwAtrLen); + else + status = SCardStatusA(hCard,(LPSTR) &pszReaderNames, &dwNameLength, &dwState,&dwProtocol, pbAtr,&dwAtrLen); + if(SCARD_S_SUCCESS == status) + { + BYTE pbValue[MAX_ATR_SIZE]; + DWORD dwValueLen = 0; + LPBYTE pValuePtr = &pbValue[0]; + if(SCARD_ATTR_ICC_PRESENCE == dwAttrId) + { + dwValueLen = 1; + pbValue[0] = 1; /* present by default */ + if(dwState == SCARD_ABSENT) + pbValue[0] = 0; + else if(dwState == SCARD_SWALLOWED) + pbValue[0] = 2; + } + else if(SCARD_ATTR_CURRENT_PROTOCOL_TYPE == dwAttrId) + { + dwValueLen = 4; + memcpy(pbValue,&dwProtocol,4); + } + else if(SCARD_ATTR_DEVICE_FRIENDLY_NAME_A == dwAttrId || + SCARD_ATTR_DEVICE_SYSTEM_NAME_A == dwAttrId) + { + pValuePtr = (LPBYTE) pszReaderNames; + dwValueLen = dwNameLength ; + } + else if(SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId || + SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId) + { + pValuePtr = (LPBYTE) pszReaderNames; + dwValueLen = dwNameLength * sizeof(WCHAR); + } + else /* ATR case */ + { + dwValueLen = dwAtrLen; + memcpy(pbValue,pbAtr,dwAtrLen); + } + + lRet = SCARD_S_SUCCESS; + if(!pbAttr) + *pcbAttrLen =dwValueLen; + else if(*pcbAttrLen == SCARD_AUTOALLOCATE) + { + LPBYTE *ppbAttr = (LPBYTE*) pbAttr; + *ppbAttr = (LPBYTE) SCardAllocate(dwValueLen); + memcpy(*ppbAttr,pValuePtr,dwValueLen); + *pcbAttrLen = dwValueLen; + } + else if(*pcbAttrLen < dwValueLen) + { + *pcbAttrLen = dwValueLen; + lRet = SCARD_E_INSUFFICIENT_BUFFER; + } + else + { + *pcbAttrLen = dwValueLen; + memcpy(pbAttr,pValuePtr,dwValueLen); + } + + SCardFree(pszReaderNames); + } + } + } + } + TRACE(" returned %#lx \n",lRet); + return TranslateToWin32(lRet); +} + +LONG WINAPI SCardSetAttrib( + SCARDHANDLE hCard, + DWORD dwAttrId, + const BYTE* pbAttr, + DWORD cbAttrLen) +{ + LONG lRet; + struct SCardSetAttrib_params params = {hCard, dwAttrId, pbAttr, cbAttrLen}; + TRACE(" 0x%08X %#lx %p %#lx \n",(unsigned int) hCard,dwAttrId,pbAttr,cbAttrLen); + lRet = WINSCARD_CALL( SCardGetAttrib, ¶ms ); + TRACE(" returned %#lx \n",lRet); + return TranslateToWin32(lRet); } diff --git a/dlls/winscard/winscard.spec b/dlls/winscard/winscard.spec index 037d3bef903..58c571823b2 100644 --- a/dlls/winscard/winscard.spec +++ b/dlls/winscard/winscard.spec @@ -1,63 +1,63 @@ @ stub ClassInstall32 -@ stub SCardAccessNewReaderEvent -@ stub SCardReleaseAllEvents -@ stub SCardReleaseNewReaderEvent +@ stdcall SCardAccessNewReaderEvent() +@ stub SCardReleaseAllEvents() +@ stub SCardReleaseNewReaderEvent() @ stdcall SCardAccessStartedEvent() @ stdcall SCardAddReaderToGroupA(long str str) @ stdcall SCardAddReaderToGroupW(long wstr wstr) -@ stub SCardBeginTransaction +@ stdcall SCardBeginTransaction(long) @ stdcall SCardCancel(long) -@ stub SCardConnectA -@ stub SCardConnectW -@ stub SCardControl -@ stub SCardDisconnect -@ stub SCardEndTransaction +@ stdcall SCardConnectA(long str long long ptr ptr) +@ stdcall SCardConnectW(long wstr long long ptr ptr) +@ stdcall SCardControl(long long ptr long ptr long ptr) +@ stdcall SCardDisconnect(long long) +@ stdcall SCardEndTransaction(long long) @ stdcall SCardEstablishContext(long ptr ptr ptr) -@ stub SCardForgetCardTypeA -@ stub SCardForgetCardTypeW -@ stub SCardForgetReaderA -@ stub SCardForgetReaderGroupA -@ stub SCardForgetReaderGroupW -@ stub SCardForgetReaderW -@ stub SCardFreeMemory -@ stub SCardGetAttrib -@ stub SCardGetCardTypeProviderNameA -@ stub SCardGetCardTypeProviderNameW -@ stub SCardGetProviderIdA -@ stub SCardGetProviderIdW -@ stub SCardGetStatusChangeA -@ stub SCardGetStatusChangeW -@ stub SCardIntroduceCardTypeA -@ stub SCardIntroduceCardTypeW -@ stub SCardIntroduceReaderA -@ stub SCardIntroduceReaderGroupA -@ stub SCardIntroduceReaderGroupW -@ stub SCardIntroduceReaderW +@ stdcall SCardForgetCardTypeA(long str) +@ stdcall SCardForgetCardTypeW(long wstr) +@ stdcall SCardForgetReaderA(long str) +@ stdcall SCardForgetReaderGroupA(long str) +@ stdcall SCardForgetReaderGroupW(long wstr) +@ stdcall SCardForgetReaderW(long wstr) +@ stdcall SCardFreeMemory(long ptr) +@ stdcall SCardGetAttrib(long long ptr ptr) +@ stdcall SCardGetCardTypeProviderNameA(long str long str ptr) +@ stdcall SCardGetCardTypeProviderNameW(long wstr long wstr ptr) +@ stdcall SCardGetProviderIdA(long str ptr) +@ stdcall SCardGetProviderIdW(long wstr ptr) +@ stdcall SCardGetStatusChangeA(long long ptr long) +@ stdcall SCardGetStatusChangeW(long long ptr long) +@ stdcall SCardIntroduceCardTypeA(long str ptr ptr long ptr ptr long) +@ stdcall SCardIntroduceCardTypeW(long wstr ptr ptr long ptr ptr long) +@ stdcall SCardIntroduceReaderA(long str str) +@ stdcall SCardIntroduceReaderGroupA(long str) +@ stdcall SCardIntroduceReaderGroupW(long wstr) +@ stdcall SCardIntroduceReaderW(long wstr wstr) @ stdcall SCardIsValidContext(long) @ stdcall SCardListCardsA(long ptr ptr long str ptr) -@ stub SCardListCardsW -@ stub SCardListInterfacesA -@ stub SCardListInterfacesW -@ stub SCardListReaderGroupsA -@ stub SCardListReaderGroupsW -@ stdcall SCardListReadersA(long str ptr ptr) -@ stdcall SCardListReadersW(long wstr ptr ptr) -@ stub SCardLocateCardsA -@ stub SCardLocateCardsByATRA -@ stub SCardLocateCardsByATRW -@ stub SCardLocateCardsW -@ stub SCardReconnect +@ stdcall SCardListCardsW(long ptr ptr long wstr ptr) +@ stdcall SCardListInterfacesA(long str ptr ptr) +@ stdcall SCardListInterfacesW(long wstr ptr ptr) +@ stdcall SCardListReaderGroupsA(long str ptr) +@ stdcall SCardListReaderGroupsW(long wstr ptr) +@ stdcall SCardListReadersA(long str str ptr) +@ stdcall SCardListReadersW(long wstr wstr ptr) +@ stdcall SCardLocateCardsA(long str ptr long) +@ stdcall SCardLocateCardsByATRA(long ptr long ptr long) +@ stdcall SCardLocateCardsByATRW(long ptr long ptr long) +@ stdcall SCardLocateCardsW(long wstr ptr long) +@ stdcall SCardReconnect(long long long long ptr) @ stdcall SCardReleaseContext(long) -@ stdcall SCardReleaseStartedEvent() -@ stub SCardRemoveReaderFromGroupA -@ stub SCardRemoveReaderFromGroupW -@ stub SCardSetAttrib -@ stub SCardSetCardTypeProviderNameA -@ stub SCardSetCardTypeProviderNameW -@ stub SCardState +@ stub SCardReleaseStartedEvent() +@ stdcall SCardRemoveReaderFromGroupA(long str str) +@ stdcall SCardRemoveReaderFromGroupW(long wstr wstr) +@ stdcall SCardSetAttrib(long long ptr long) +@ stdcall SCardSetCardTypeProviderNameA(long str long str) +@ stdcall SCardSetCardTypeProviderNameW(long wstr long wstr) +@ stdcall SCardState(long ptr ptr ptr ptr) @ stdcall SCardStatusA(long str ptr ptr ptr ptr ptr) @ stdcall SCardStatusW(long wstr ptr ptr ptr ptr ptr) -@ stub SCardTransmit +@ stdcall SCardTransmit(long ptr ptr long ptr ptr ptr) @ extern g_rgSCardRawPci -@ extern g_rgSCardT0Pci +@ extern g_rgSCardT0Pci @ extern g_rgSCardT1Pci diff --git a/include/winscard.h b/include/winscard.h index 5aee1b3e548..01780280c20 100644 --- a/include/winscard.h +++ b/include/winscard.h @@ -24,11 +24,6 @@ #include <winsmcrd.h> #include <scarderr.h>
-/* Valid scopes for contexts */ -#define SCARD_SCOPE_USER 0 -#define SCARD_SCOPE_TERMINAL 1 -#define SCARD_SCOPE_SYSTEM 2 - #ifndef _LPCBYTE_DEFINED #define _LPCBYTE_DEFINED typedef const BYTE *LPCBYTE; @@ -66,24 +61,6 @@ DECL_WINELIB_TYPE_AW(SCARD_READERSTATE) DECL_WINELIB_TYPE_AW(PSCARD_READERSTATE) DECL_WINELIB_TYPE_AW(LPSCARD_READERSTATE)
-#define SCARD_AUTOALLOCATE (DWORD)(-1) - -#define SCARD_SCOPE_USER 0 -#define SCARD_SCOPE_TERMINAL 1 -#define SCARD_SCOPE_SYSTEM 2 - -#define SCARD_STATE_UNAWARE 0x00000000 -#define SCARD_STATE_IGNORE 0x00000001 -#define SCARD_STATE_CHANGED 0x00000002 -#define SCARD_STATE_UNKNOWN 0x00000004 -#define SCARD_STATE_UNAVAILABLE 0x00000008 -#define SCARD_STATE_EMPTY 0x00000010 -#define SCARD_STATE_PRESENT 0x00000020 -#define SCARD_STATE_ATRMATCH 0x00000040 -#define SCARD_STATE_EXCLUSIVE 0x00000080 -#define SCARD_STATE_INUSE 0x00000100 -#define SCARD_STATE_MUTE 0x00000200 -#define SCARD_STATE_UNPOWERED 0x00000400
#ifdef __cplusplus extern "C" { @@ -138,8 +115,8 @@ LONG WINAPI SCardListCardsW(SCARDCONTEXT,LPCBYTE,LPCGUID,DWORD,LPWSTR,LPD LONG WINAPI SCardListInterfacesA(SCARDCONTEXT,LPCSTR,LPGUID,LPDWORD); LONG WINAPI SCardListInterfacesW(SCARDCONTEXT,LPCWSTR,LPGUID,LPDWORD); #define SCardListInterfaces WINELIB_NAME_AW(SCardListInterfaces) -LONG WINAPI SCardListReadersA(SCARDCONTEXT,const CHAR *,CHAR *,DWORD *); -LONG WINAPI SCardListReadersW(SCARDCONTEXT,const WCHAR *,WCHAR *,DWORD *); +LONG WINAPI SCardListReadersA(SCARDCONTEXT,LPCSTR,LPSTR,LPDWORD); +LONG WINAPI SCardListReadersW(SCARDCONTEXT,LPCWSTR,LPWSTR,LPDWORD); #define SCardListReaders WINELIB_NAME_AW(SCardListReaders) LONG WINAPI SCardListReaderGroupsA(SCARDCONTEXT,LPSTR,LPDWORD); LONG WINAPI SCardListReaderGroupsW(SCARDCONTEXT,LPWSTR,LPDWORD); @@ -152,7 +129,7 @@ LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT,LPSCARD_ATRMASK,DWORD,LPS #define SCardLocateCardsByATR WINELIB_NAME_AW(SCardLocateCardsByATR) LONG WINAPI SCardReconnect(SCARDHANDLE,DWORD,DWORD,DWORD,LPDWORD); LONG WINAPI SCardReleaseContext(SCARDCONTEXT); -void WINAPI SCardReleaseStartedEvent(void); +void WINAPI SCardReleaseStartedEvent(HANDLE hStartedEventHandle); LONG WINAPI SCardRemoveReaderFromGroupA(SCARDCONTEXT,LPCSTR,LPCSTR); LONG WINAPI SCardRemoveReaderFromGroupW(SCARDCONTEXT,LPCWSTR,LPCWSTR); #define SCardRemoveReaderFromGroup WINELIB_NAME_AW(SCardRemoveReaderFromGroup) diff --git a/include/winsmcrd.h b/include/winsmcrd.h index 60fdd3e492c..dd045b57afa 100644 --- a/include/winsmcrd.h +++ b/include/winsmcrd.h @@ -1,5 +1,5 @@ /* - * Winscard definitions + * Copyright 2007 Mounir IDRASSI (mounir.idrassi@idrix.fr, for IDRIX) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,22 +16,117 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#ifndef __WINE_WINSMCRD_H -#define __WINE_WINSMCRD_H
-#define SCARD_PROTOCOL_UNDEFINED 0x00000000 -#define SCARD_PROTOCOL_OPTIMAL 0x00000000 -#define SCARD_PROTOCOL_T0 0x00000001 -#define SCARD_PROTOCOL_T1 0x00000002 -#define SCARD_PROTOCOL_RAW 0x00010000 -#define SCARD_PROTOCOL_DEFAULT 0x80000000 -#define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) +#ifndef _WINE_WINSCMCRD_H +#define _WINE_WINSCMCRD_H
+ +#define MAX_ATR_SIZE 36 /* Maximum ATR size */ + +#ifndef SCARD_ATR_LENGTH +#define SCARD_ATR_LENGTH MAX_ATR_SIZE +#endif + +/* + * These values define the protocol used to + * communicate with the card + */ +#define SCARD_PROTOCOL_UNDEFINED 0x00000000 /* No protocol defined */ +#define SCARD_PROTOCOL_T0 0x00000001 /* T=0 protocol. */ +#define SCARD_PROTOCOL_T1 0x00000002 /* T=1 protocol */ +#define SCARD_PROTOCOL_RAW 0x00010000 /* Raw protocol, for memory card for example */ +#define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) /* Can be used in SCardConnect */ + +/* + * The following value is used as a length value + * in functions where we want the winscard dll + * to allocate memory for us + */ +#define SCARD_AUTOALLOCATE (DWORD)(-1) + +/* + * Values used by SCardEstablishContext + */ +#define SCARD_SCOPE_USER 0x0000 /* context in user scope */ +#define SCARD_SCOPE_TERMINAL 0x0001 /* context in terminal scope */ +#define SCARD_SCOPE_SYSTEM 0x0002 /* context in system scope */ + +/* + * Flags used by SCardGetStatusChange to indicate + * the reader status. + */ +#define SCARD_STATE_UNAWARE 0x0000 /* called want to know the current state */ +#define SCARD_STATE_IGNORE 0x0001 /* don't update the state for the given reader */ +#define SCARD_STATE_CHANGED 0x0002 /* reader state has not changed */ +#define SCARD_STATE_UNKNOWN 0x0004 /* reader state unknown */ +#define SCARD_STATE_UNAVAILABLE 0x0008 /* reader state unavailable */ +#define SCARD_STATE_EMPTY 0x0010 /* no card on the reader*/ +#define SCARD_STATE_PRESENT 0x0020 /* card present on the reader */ +#define SCARD_STATE_ATRMATCH 0x0040 /* card's ATR matches the given ATR */ +#define SCARD_STATE_EXCLUSIVE 0x0080 /* an exclusive connection on the card exists*/ +#define SCARD_STATE_INUSE 0x0100 /* card in use but the connection can be shared */ +#define SCARD_STATE_MUTE 0x0200 /* card is mute, doesn't answer to reset */ +#define SCARD_STATE_UNPOWERED 0x0400 /* card present but not powered */ + + +/* + * These values define how SCardConnect should + * connect to the card + */ +#define SCARD_SHARE_EXCLUSIVE 0x0001 /* connect to the card in exclusive mode (no other connection allowed) */ +#define SCARD_SHARE_SHARED 0x0002 /* connection can be shared with others */ +#define SCARD_SHARE_DIRECT 0x0003 /* access directly the reader, no other connection allowed */ + +/* + * Values used by SCardDisconnect to specify + * how the card should be treated on closing + * the connection + */ +#define SCARD_LEAVE_CARD 0x0000 /* do nothing */ +#define SCARD_RESET_CARD 0x0001 /* reset the card */ +#define SCARD_UNPOWER_CARD 0x0002 /* unpower the card */ +#define SCARD_EJECT_CARD 0x0003 /* eject the card from the reader if supported */ + +/* + * Values returned by SCardStatus indicating + * the reader's state + */ +#define SCARD_UNKNOWN 0x0001 /* state unknown */ +#define SCARD_ABSENT 0x0002 /* no card on the reader */ +#define SCARD_PRESENT 0x0004 /* card is present on the reader */ +#define SCARD_SWALLOWED 0x0008 /* card inside the reader but not powered */ +#define SCARD_POWERED 0x0010 /* card present and powered */ +#define SCARD_NEGOTIABLE 0x0020 /* card present and ready to negotiate protocol */ +#define SCARD_SPECIFIC 0x0040 /* card has ended protocol negotiation */ + +/* + * definitions used by SCardGetAttrib and SCardSetAttrib for + * requesting and setting readers attributes + * Other values maybe supported + */ +#define SCARD_ATTR_ICC_PRESENCE 0x00090300 +#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE 0x00080201 +#define SCARD_ATTR_ATR_STRING 0x00090303 +#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A 0x7FFF0003 +#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W 0x7FFF0005 +#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A 0x7FFF0004 +#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W 0x7FFF0006 + +#define SCARD_ATTR_DEVICE_FRIENDLY_NAME WINELIB_NAME_AW(SCARD_ATTR_DEVICE_FRIENDLY_NAME_) +#define SCARD_ATTR_DEVICE_SYSTEM_NAME WINELIB_NAME_AW(SCARD_ATTR_DEVICE_SYSTEM_NAME_) + + +/* + * This structure is used by SCardTransmit to communicate + * with the card + */ typedef struct _SCARD_IO_REQUEST { - DWORD dwProtocol; - DWORD cbPciLength; -} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; + unsigned long dwProtocol; /* protocol used for this request */ + unsigned long cbPciLength; /* total length of the request data, usually sizeof(SCARD_IO_REQUEST) */ +} +SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; + typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;
-#endif /* __WINE_WINSMCRD_H */ +#endif