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