00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00022 #include "config.h"
00023 #include <time.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026
00027 #include "pcsclite.h"
00028 #include "winscard.h"
00029 #include "debuglog.h"
00030 #include "winscard_msg.h"
00031 #include "winscard_svc.h"
00032 #include "sys_generic.h"
00033 #include "thread_generic.h"
00034
00040 static struct _psContext
00041 {
00042 SCARDCONTEXT hContext;
00043 SCARDHANDLE hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00044 DWORD dwClientID;
00045 PCSCLITE_THREAD_T pthThread;
00046 sharedSegmentMsg msgStruct;
00047 int protocol_major, protocol_minor;
00048 } psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
00049
00050 LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
00051 LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD);
00052 LONG MSGAddContext(SCARDCONTEXT, DWORD);
00053 LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
00054 LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
00055 LONG MSGRemoveHandle(SCARDHANDLE, DWORD);
00056 LONG MSGCleanupClient(DWORD);
00057
00058 static void ContextThread(LPVOID pdwIndex);
00059
00060 LONG ContextsInitialize(void)
00061 {
00062 memset(psContext, 0, sizeof(struct _psContext)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
00063 return 1;
00064 }
00065
00076 LONG CreateContextThread(PDWORD pdwClientID)
00077 {
00078 int i;
00079
00080 for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
00081 {
00082 if (psContext[i].dwClientID == 0)
00083 {
00084 psContext[i].dwClientID = *pdwClientID;
00085 *pdwClientID = 0;
00086 break;
00087 }
00088 }
00089
00090 if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS)
00091 {
00092 SYS_CloseFile(psContext[i].dwClientID);
00093 psContext[i].dwClientID = 0;
00094 return SCARD_F_INTERNAL_ERROR;
00095 }
00096
00097 if (SYS_ThreadCreate(&psContext[i].pthThread, THREAD_ATTR_DETACHED,
00098 (PCSCLITE_THREAD_FUNCTION( )) ContextThread,
00099 (LPVOID) i) != 1)
00100 {
00101 SYS_CloseFile(psContext[i].dwClientID);
00102 psContext[i].dwClientID = 0;
00103 return SCARD_E_NO_MEMORY;
00104 }
00105
00106 return SCARD_S_SUCCESS;
00107 }
00108
00109
00110
00111
00112
00113
00122 static void ContextThread(LPVOID dwIndex)
00123 {
00124 LONG rv;
00125 sharedSegmentMsg msgStruct;
00126 DWORD dwContextIndex = (DWORD)dwIndex;
00127
00128 Log2(PCSC_LOG_DEBUG, "Thread is started: %d",
00129 psContext[dwContextIndex].dwClientID);
00130
00131 while (1)
00132 {
00133 switch (rv = SHMProcessEventsContext(&psContext[dwContextIndex].dwClientID, &msgStruct, 0))
00134 {
00135 case 0:
00136 if (msgStruct.mtype == CMD_CLIENT_DIED)
00137 {
00138
00139
00140
00141 Log2(PCSC_LOG_DEBUG, "Client die: %d",
00142 psContext[dwContextIndex].dwClientID);
00143 MSGCleanupClient(dwContextIndex);
00144 SYS_ThreadExit((LPVOID) NULL);
00145 }
00146 break;
00147
00148 case 1:
00149 if (msgStruct.mtype == CMD_FUNCTION)
00150 {
00151
00152
00153
00154 MSGFunctionDemarshall(&msgStruct, dwContextIndex);
00155 rv = SHMMessageSend(&msgStruct, psContext[dwContextIndex].dwClientID,
00156 PCSCLITE_SERVER_ATTEMPTS);
00157 }
00158 else
00159
00160 if (msgStruct.mtype == CMD_VERSION)
00161 {
00162 version_struct *veStr;
00163 veStr = (version_struct *) msgStruct.data;
00164
00165
00166 psContext[dwContextIndex].protocol_major = veStr->major;
00167 psContext[dwContextIndex].protocol_minor = veStr->minor;
00168
00169 Log3(PCSC_LOG_DEBUG,
00170 "Client is protocol version %d:%d",
00171 veStr->major, veStr->minor);
00172
00173
00174 veStr->major = PROTOCOL_VERSION_MAJOR;
00175 veStr->minor = PROTOCOL_VERSION_MINOR;
00176 veStr->rv = SCARD_S_SUCCESS;
00177
00178
00179 rv = SHMMessageSend(&msgStruct,
00180 psContext[dwContextIndex].dwClientID,
00181 PCSCLITE_SERVER_ATTEMPTS);
00182 }
00183 else
00184 continue;
00185
00186 break;
00187
00188 case 2:
00189
00190
00191
00192
00193
00194 break;
00195
00196 case -1:
00197 Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsContext");
00198 break;
00199
00200 default:
00201 Log2(PCSC_LOG_ERROR,
00202 "SHMProcessEventsContext unknown retval: %d", rv);
00203 break;
00204 }
00205 }
00206 }
00207
00223 LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct, DWORD dwContextIndex)
00224 {
00225 LONG rv;
00226 establish_struct *esStr;
00227 release_struct *reStr;
00228 connect_struct *coStr;
00229 reconnect_struct *rcStr;
00230 disconnect_struct *diStr;
00231 begin_struct *beStr;
00232 cancel_struct *caStr;
00233 end_struct *enStr;
00234 status_struct *stStr;
00235 transmit_struct *trStr;
00236 control_struct *ctStr;
00237 getset_struct *gsStr;
00238
00239
00240
00241
00242 rv = 0;
00243 switch (msgStruct->command)
00244 {
00245
00246 case SCARD_ESTABLISH_CONTEXT:
00247 esStr = ((establish_struct *) msgStruct->data);
00248 esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0,
00249 &esStr->phContext);
00250
00251 if (esStr->rv == SCARD_S_SUCCESS)
00252 esStr->rv =
00253 MSGAddContext(esStr->phContext, dwContextIndex);
00254 break;
00255
00256 case SCARD_RELEASE_CONTEXT:
00257 reStr = ((release_struct *) msgStruct->data);
00258 reStr->rv = SCardReleaseContext(reStr->hContext);
00259
00260 if (reStr->rv == SCARD_S_SUCCESS)
00261 reStr->rv =
00262 MSGRemoveContext(reStr->hContext, dwContextIndex);
00263
00264 break;
00265
00266 case SCARD_CONNECT:
00267 coStr = ((connect_struct *) msgStruct->data);
00268 coStr->rv = SCardConnect(coStr->hContext, coStr->szReader,
00269 coStr->dwShareMode, coStr->dwPreferredProtocols,
00270 &coStr->phCard, &coStr->pdwActiveProtocol);
00271
00272 if (coStr->rv == SCARD_S_SUCCESS)
00273 coStr->rv =
00274 MSGAddHandle(coStr->hContext, coStr->phCard, dwContextIndex);
00275
00276 break;
00277
00278 case SCARD_RECONNECT:
00279 rcStr = ((reconnect_struct *) msgStruct->data);
00280 rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
00281 if (rv != 0) return rv;
00282
00283 rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
00284 rcStr->dwPreferredProtocols,
00285 rcStr->dwInitialization, &rcStr->pdwActiveProtocol);
00286 break;
00287
00288 case SCARD_DISCONNECT:
00289 diStr = ((disconnect_struct *) msgStruct->data);
00290 rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex);
00291 if (rv != 0) return rv;
00292 diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition);
00293
00294 if (diStr->rv == SCARD_S_SUCCESS)
00295 diStr->rv =
00296 MSGRemoveHandle(diStr->hCard, dwContextIndex);
00297 break;
00298
00299 case SCARD_BEGIN_TRANSACTION:
00300 beStr = ((begin_struct *) msgStruct->data);
00301 rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex);
00302 if (rv != 0) return rv;
00303 beStr->rv = SCardBeginTransaction(beStr->hCard);
00304 break;
00305
00306 case SCARD_END_TRANSACTION:
00307 enStr = ((end_struct *) msgStruct->data);
00308 rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex);
00309 if (rv != 0) return rv;
00310 enStr->rv =
00311 SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
00312 break;
00313
00314 case SCARD_CANCEL_TRANSACTION:
00315 caStr = ((cancel_struct *) msgStruct->data);
00316 rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex);
00317 if (rv != 0) return rv;
00318 caStr->rv = SCardCancelTransaction(caStr->hCard);
00319 break;
00320
00321 case SCARD_STATUS:
00322 stStr = ((status_struct *) msgStruct->data);
00323 rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex);
00324 if (rv != 0) return rv;
00325 stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
00326 &stStr->pcchReaderLen, &stStr->pdwState,
00327 &stStr->pdwProtocol, stStr->pbAtr, &stStr->pcbAtrLen);
00328 break;
00329
00330 case SCARD_TRANSMIT:
00331 trStr = ((transmit_struct *) msgStruct->data);
00332 rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
00333 if (rv != 0) return rv;
00334 trStr->rv = SCardTransmit(trStr->hCard, &trStr->pioSendPci,
00335 trStr->pbSendBuffer, trStr->cbSendLength,
00336 &trStr->pioRecvPci, trStr->pbRecvBuffer,
00337 &trStr->pcbRecvLength);
00338 break;
00339
00340 case SCARD_CONTROL:
00341 ctStr = ((control_struct *) msgStruct->data);
00342 rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
00343 if (rv != 0) return rv;
00344 ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
00345 ctStr->pbSendBuffer, ctStr->cbSendLength,
00346 ctStr->pbRecvBuffer, ctStr->cbRecvLength,
00347 &ctStr->dwBytesReturned);
00348 break;
00349
00350 case SCARD_GET_ATTRIB:
00351 gsStr = ((getset_struct *) msgStruct->data);
00352 rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
00353 if (rv != 0) return rv;
00354 gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId,
00355 gsStr->pbAttr, &gsStr->cbAttrLen);
00356 break;
00357
00358 case SCARD_SET_ATTRIB:
00359 gsStr = ((getset_struct *) msgStruct->data);
00360 rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
00361 if (rv != 0) return rv;
00362 gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId,
00363 gsStr->pbAttr, gsStr->cbAttrLen);
00364 break;
00365
00366 default:
00367 return -1;
00368 }
00369
00370 return 0;
00371 }
00372
00373 LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
00374 {
00375 psContext[dwContextIndex].hContext = hContext;
00376 return SCARD_S_SUCCESS;
00377 }
00378
00379 LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
00380 {
00381 int i;
00382 LONG rv;
00383
00384 if (psContext[dwContextIndex].hContext == hContext)
00385 {
00386
00387 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00388 {
00389
00390
00391
00392
00393 if (psContext[dwContextIndex].hCard[i] != 0)
00394 {
00395
00396
00397
00398
00399
00400
00401
00402 rv = SCardStatus(psContext[dwContextIndex].hCard[i], 0, 0, 0, 0, 0, 0);
00403
00404 if (rv == SCARD_W_RESET_CARD
00405 || rv == SCARD_W_REMOVED_CARD)
00406 {
00407 SCardDisconnect(psContext[dwContextIndex].hCard[i], SCARD_LEAVE_CARD);
00408 } else
00409 {
00410 SCardDisconnect(psContext[dwContextIndex].hCard[i], SCARD_RESET_CARD);
00411 }
00412
00413 psContext[dwContextIndex].hCard[i] = 0;
00414 }
00415
00416 }
00417
00418 psContext[dwContextIndex].hContext = 0;
00419 return SCARD_S_SUCCESS;
00420 }
00421
00422 return SCARD_E_INVALID_VALUE;
00423 }
00424
00425 LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard, DWORD dwContextIndex)
00426 {
00427 int i;
00428
00429 if (psContext[dwContextIndex].hContext == hContext)
00430 {
00431
00432
00433
00434
00435 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00436 {
00437 if (psContext[dwContextIndex].hCard[i] == 0)
00438 {
00439 psContext[dwContextIndex].hCard[i] = hCard;
00440 break;
00441 }
00442 }
00443
00444 if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
00445 {
00446 return SCARD_F_INTERNAL_ERROR;
00447 } else
00448 {
00449 return SCARD_S_SUCCESS;
00450 }
00451
00452 }
00453
00454 return SCARD_E_INVALID_VALUE;
00455 }
00456
00457 LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex)
00458 {
00459 int i;
00460
00461 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00462 {
00463 if (psContext[dwContextIndex].hCard[i] == hCard)
00464 {
00465 psContext[dwContextIndex].hCard[i] = 0;
00466 return SCARD_S_SUCCESS;
00467 }
00468 }
00469
00470 return SCARD_E_INVALID_VALUE;
00471 }
00472
00473
00474 LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex)
00475 {
00476 int i;
00477
00478 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00479 {
00480 if (psContext[dwContextIndex].hCard[i] == hCard)
00481 {
00482 return 0;
00483 }
00484 }
00485
00486
00487 Log1(PCSC_LOG_ERROR, "Client failed to authenticate");
00488 SYS_Sleep(2);
00489
00490 return -1;
00491 }
00492
00493 LONG MSGCleanupClient(DWORD dwContextIndex)
00494 {
00495 if (psContext[dwContextIndex].hContext != 0)
00496 {
00497 SCardReleaseContext(psContext[dwContextIndex].hContext);
00498 MSGRemoveContext(psContext[dwContextIndex].hContext, dwContextIndex);
00499 }
00500
00501 psContext[dwContextIndex].dwClientID = 0;
00502 psContext[dwContextIndex].protocol_major = 0;
00503 psContext[dwContextIndex].protocol_minor = 0;
00504
00505 return 0;
00506 }