/[rdesktop]/sourceforge.net/trunk/rdesktop/scard.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/scard.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1420 by stargo, Sun Oct 28 16:49:45 2007 UTC revision 1421 by stargo, Tue Oct 30 13:09:37 2007 UTC
# Line 43  Line 43 
43  #define SCARD_AUTOALLOCATE -1  #define SCARD_AUTOALLOCATE -1
44  #define OUT_STREAM_SIZE 4096  #define OUT_STREAM_SIZE 4096
45    
46    #ifdef B_ENDIAN
47    #define swap32(x)       ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | \
48                            (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
49    
50    #define swap16(x)       ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
51    #else
52    #define swap32(x)       (x)
53    #define swap16(x)       (x)
54    #endif
55    
56  static pthread_mutex_t **scard_mutex = NULL;  static pthread_mutex_t **scard_mutex = NULL;
57    
58  static uint32 curDevice = 0, curId = 0, curBytesOut = 0;  static uint32 curDevice = 0, curId = 0, curBytesOut = 0;
# Line 51  static int nameMapCount = 0; Line 61  static int nameMapCount = 0;
61    
62  static pthread_t queueHandler;  static pthread_t queueHandler;
63  static pthread_mutex_t queueAccess;  static pthread_mutex_t queueAccess;
64  static pthread_mutex_t queueEmpty;  static pthread_cond_t queueEmpty;
65  static pthread_mutex_t hcardAccess;  static pthread_mutex_t hcardAccess;
66    
67  static PMEM_HANDLE threadListHandle = NULL;  static PMEM_HANDLE threadListHandle = NULL;
# Line 138  scard_enum_devices(uint32 * id, char *op Line 148  scard_enum_devices(uint32 * id, char *op
148                  return 0;                  return 0;
149          }          }
150    
151          if (0 != pthread_mutex_init(&queueEmpty, NULL))          if (0 != pthread_cond_init(&queueEmpty, NULL))
152          {          {
153                  error("scard_enum_devices: Can't initialize queue control mutex\n");                  error("scard_enum_devices: Can't initialize queue control cv\n");
154                  return 0;                  return 0;
155          }          }
156    
# Line 610  TS_SCardEstablishContext(STREAM in, STRE Line 620  TS_SCardEstablishContext(STREAM in, STRE
620          }          }
621          else          else
622          {          {
623                  DEBUG_SCARD(("SCARD: -> Success (context: 0x%08x)\n", (unsigned) hContext));                  DEBUG_SCARD(("SCARD: -> Success (context: 0x%08lx)\n", hContext));
624          }          }
625    
626          out_uint32_le(out, 0x00000004);          out_uint32_le(out, 0x00000004);
# Line 1053  TS_SCardGetStatusChange(STREAM in, STREA Line 1063  TS_SCardGetStatusChange(STREAM in, STREA
1063                  {                  {
1064                          SERVER_DWORD dataLength;                          SERVER_DWORD dataLength;
1065    
1066                            /* Do endian swaps... */
1067                            cur->dwCurrentState = swap32(cur->dwCurrentState);
1068                            cur->dwEventState = swap32(cur->dwEventState);
1069                            cur->cbAtr = swap32(cur->cbAtr);
1070    
1071                          /* reset Current state hign bytes; */                          /* reset Current state hign bytes; */
1072                          *curState = cur->dwCurrentState;                          *curState = cur->dwCurrentState;
1073                          cur->dwCurrentState &= 0x0000FFFF;                          cur->dwCurrentState &= 0x0000FFFF;
# Line 1160  TS_SCardGetStatusChange(STREAM in, STREA Line 1175  TS_SCardGetStatusChange(STREAM in, STREA
1175                               (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,                               (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState,
1176                               (unsigned) cur->dwEventState));                               (unsigned) cur->dwEventState));
1177    
1178                    /* Do endian swaps... */
1179                    cur->dwCurrentState = swap32(cur->dwCurrentState);
1180                    cur->dwEventState = swap32(cur->dwEventState);
1181                    cur->cbAtr = swap32(cur->cbAtr);
1182    
1183                  out_uint8p(out, (void *) ((unsigned char **) cur + 2),                  out_uint8p(out, (void *) ((unsigned char **) cur + 2),
1184                             sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));                             sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
1185          }          }
# Line 1225  TS_SCardLocateCardsByATR(STREAM in, STRE Line 1245  TS_SCardLocateCardsByATR(STREAM in, STRE
1245    
1246          for (i = 0, cur = pAtrMasks; i < atrMaskCount; i++, cur++)          for (i = 0, cur = pAtrMasks; i < atrMaskCount; i++, cur++)
1247          {          {
1248                    cur->cbAtr = swap32(cur->cbAtr);
1249    
1250                  DEBUG_SCARD(("SCARD:    ATR: "));                  DEBUG_SCARD(("SCARD:    ATR: "));
1251                  for (j = 0; j < pAtrMasks->cbAtr; j++)                  for (j = 0; j < pAtrMasks->cbAtr; j++)
1252                  {                  {
# Line 1251  TS_SCardLocateCardsByATR(STREAM in, STRE Line 1273  TS_SCardLocateCardsByATR(STREAM in, STRE
1273          ResArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));          ResArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
1274          if (!ResArray)          if (!ResArray)
1275                  return SC_returnNoMemoryError(&lcHandle, in, out);                  return SC_returnNoMemoryError(&lcHandle, in, out);
         memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));  
1276    
1277          for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)          for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
1278          {          {
1279                    /* Do endian swaps... */
1280                    rsCur->dwCurrentState = swap32(rsCur->dwCurrentState);
1281                    rsCur->dwEventState = swap32(rsCur->dwEventState);
1282                    rsCur->cbAtr = swap32(rsCur->cbAtr);
1283    
1284                  inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);                  inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);
1285                  DEBUG_SCARD(("SCARD:    \"%s\"\n", rsCur->szReader ? rsCur->szReader : "NULL"));                  DEBUG_SCARD(("SCARD:    \"%s\"\n", rsCur->szReader ? rsCur->szReader : "NULL"));
1286                  DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",                  DEBUG_SCARD(("SCARD:        user: 0x%08x, state: 0x%08x, event: 0x%08x\n",
1287                               (unsigned) rsCur->pvUserData, (unsigned) rsCur->dwCurrentState,                               (unsigned) rsCur->pvUserData, (unsigned) rsCur->dwCurrentState,
1288                               (unsigned) rsCur->dwEventState));                               (unsigned) rsCur->dwEventState));
1289          }          }
1290            memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
1291    
1292          /* FIXME segfault here. */          /* FIXME segfault here. */
1293          myRsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(MYPCSC_SCARD_READERSTATE_A));          myRsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
# Line 1309  TS_SCardLocateCardsByATR(STREAM in, STRE Line 1336  TS_SCardLocateCardsByATR(STREAM in, STRE
1336          out_uint32_le(out, 0x00084dd8);          out_uint32_le(out, 0x00084dd8);
1337          out_uint32_le(out, readerCount);          out_uint32_le(out, readerCount);
1338    
1339          for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)          for (i = 0, rsCur = ResArray; i < readerCount; i++, rsCur++)
1340          {          {
1341                    /* Do endian swaps... */
1342                    rsCur->dwCurrentState = swap32(rsCur->dwCurrentState);
1343                    rsCur->dwEventState = swap32(rsCur->dwEventState);
1344                    rsCur->cbAtr = swap32(rsCur->cbAtr);
1345    
1346                  out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),                  out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),
1347                             sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));                             sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
1348          }          }
# Line 1388  copyIORequest_MyPCSCToServer(MYPCSC_LPSC Line 1420  copyIORequest_MyPCSCToServer(MYPCSC_LPSC
1420          size_t bytesToCopy = src->cbPciLength - sizeof(MYPCSC_SCARD_IO_REQUEST);          size_t bytesToCopy = src->cbPciLength - sizeof(MYPCSC_SCARD_IO_REQUEST);
1421          srcBytes = ((unsigned char *) src + sizeof(MYPCSC_SCARD_IO_REQUEST));          srcBytes = ((unsigned char *) src + sizeof(MYPCSC_SCARD_IO_REQUEST));
1422          dstBytes = ((unsigned char *) dst + sizeof(SERVER_SCARD_IO_REQUEST));          dstBytes = ((unsigned char *) dst + sizeof(SERVER_SCARD_IO_REQUEST));
1423          dst->dwProtocol = src->dwProtocol;          dst->dwProtocol = swap32((uint32_t)src->dwProtocol);
1424          dst->cbPciLength = src->cbPciLength          dst->cbPciLength = swap32((uint32_t)src->cbPciLength
1425                  - sizeof(MYPCSC_SCARD_IO_REQUEST) + sizeof(SERVER_SCARD_IO_REQUEST);                  - sizeof(MYPCSC_SCARD_IO_REQUEST) + sizeof(SERVER_SCARD_IO_REQUEST));
1426          memcpy(dstBytes, srcBytes, bytesToCopy);          memcpy(dstBytes, srcBytes, bytesToCopy);
1427  }  }
1428    
# Line 1401  copyIORequest_ServerToMyPCSC(SERVER_LPSC Line 1433  copyIORequest_ServerToMyPCSC(SERVER_LPSC
1433          size_t bytesToCopy = src->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST);          size_t bytesToCopy = src->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST);
1434          srcBytes = ((unsigned char *) src + sizeof(SERVER_SCARD_IO_REQUEST));          srcBytes = ((unsigned char *) src + sizeof(SERVER_SCARD_IO_REQUEST));
1435          dstBytes = ((unsigned char *) dst + sizeof(MYPCSC_SCARD_IO_REQUEST));          dstBytes = ((unsigned char *) dst + sizeof(MYPCSC_SCARD_IO_REQUEST));
1436          dst->dwProtocol = src->dwProtocol;          dst->dwProtocol = swap32(src->dwProtocol);
1437          dst->cbPciLength = src->cbPciLength          dst->cbPciLength = src->cbPciLength     /* already correct endian */
1438                  - sizeof(SERVER_SCARD_IO_REQUEST) + sizeof(MYPCSC_SCARD_IO_REQUEST);                  - sizeof(SERVER_SCARD_IO_REQUEST) + sizeof(MYPCSC_SCARD_IO_REQUEST);
1439          memcpy(dstBytes, srcBytes, bytesToCopy);          memcpy(dstBytes, srcBytes, bytesToCopy);
1440  }  }
# Line 1563  TS_SCardTransmit(STREAM in, STREAM out) Line 1595  TS_SCardTransmit(STREAM in, STREAM out)
1595          {          {
1596                  DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) cbRecvLength));                  DEBUG_SCARD(("SCARD: -> Success (%d bytes)\n", (int) cbRecvLength));
1597  #if 0  #if 0
1598                  if ((pioRecvPci != NULL) && (pioRecvPci->cbPciLength > 0))                  if ((pioRecvPci != NULL) && (mypioRecvPci->cbPciLength > 0))
1599                  {                  {
1600                          out_uint32_le(out, (DWORD) pioRecvPci); /* if not NULL, this 4 bytes indicates that pioRecvPci is present */                          out_uint32_le(out, (DWORD) pioRecvPci); /* if not NULL, this 4 bytes indicates that pioRecvPci is present */
1601                  }                  }
# Line 1574  TS_SCardTransmit(STREAM in, STREAM out) Line 1606  TS_SCardTransmit(STREAM in, STREAM out)
1606                  outBufferStart(out, cbRecvLength);      /* start of recvBuf output */                  outBufferStart(out, cbRecvLength);      /* start of recvBuf output */
1607    
1608  #if 0  #if 0
1609                  if ((pioRecvPci) && (pioRecvPci->cbPciLength > 0))                  if ((pioRecvPci) && (mypioRecvPci->cbPciLength > 0))
1610                  {                  {
1611                          out_uint32_le(out, pioRecvPci->dwProtocol);                          out_uint32_le(out, mypioRecvPci->dwProtocol);
1612                          int len = pioRecvPci->cbPciLength - sizeof(pioRecvPci);                          int len = mypioRecvPci->cbPciLength - sizeof(mypioRecvPci);
1613                          outBufferStartWithLimit(out, len, 12);                          outBufferStartWithLimit(out, len, 12);
1614                          outBufferFinishWithLimit(out,                          outBufferFinishWithLimit(out,
1615                                                   (char *) ((DWORD) pioRecvPci + sizeof(pioRecvPci)),                                                   (char *) ((DWORD) pioRecvPci + sizeof(pioRecvPci)),
# Line 1620  TS_SCardStatus(STREAM in, STREAM out, RD Line 1652  TS_SCardStatus(STREAM in, STREAM out, RD
1652          if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM)          if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM)
1653                  dwAtrLen = SCARD_MAX_MEM;                  dwAtrLen = SCARD_MAX_MEM;
1654    
1655    #if 1
1656            /*
1657             * Active client sometimes sends a readerlen *just* big enough
1658             * SCardStatus doesn't seem to like this. This is a workaround,
1659             * aka hack!
1660             */
1661            dwReaderLen = 200;
1662    #endif
1663    
1664          readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2);          readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2);
1665          if (!readerName)          if (!readerName)
1666                  return SC_returnNoMemoryError(&lcHandle, in, out);                  return SC_returnNoMemoryError(&lcHandle, in, out);
# Line 2382  SC_addToQueue(RD_NTHANDLE handle, uint32 Line 2423  SC_addToQueue(RD_NTHANDLE handle, uint32
2423                  if (!queueFirst)                  if (!queueFirst)
2424                          queueFirst = data;                          queueFirst = data;
2425    
2426                  pthread_mutex_unlock(&queueEmpty);                  pthread_cond_broadcast(&queueEmpty);
2427                  pthread_mutex_unlock(&queueAccess);                  pthread_mutex_unlock(&queueAccess);
2428          }          }
2429          return data;          return data;
# Line 2402  static PSCThreadData Line 2443  static PSCThreadData
2443  SC_getNextInQueue()  SC_getNextInQueue()
2444  {  {
2445          PSCThreadData Result = NULL;          PSCThreadData Result = NULL;
2446    
2447          pthread_mutex_lock(&queueAccess);          pthread_mutex_lock(&queueAccess);
2448          if (queueFirst != NULL)  
2449            while (queueFirst == NULL)
2450                    pthread_cond_wait(&queueEmpty, &queueAccess);
2451    
2452            Result = queueFirst;
2453            queueFirst = queueFirst->next;
2454            if (!queueFirst)
2455          {          {
2456                  Result = queueFirst;                  queueLast = NULL;
                 queueFirst = queueFirst->next;  
                 if (!queueFirst)  
                 {  
                         queueLast = NULL;  
                         pthread_mutex_trylock(&queueEmpty);  
                 }  
                 Result->next = NULL;  
2457          }          }
2458            Result->next = NULL;
2459    
2460          pthread_mutex_unlock(&queueAccess);          pthread_mutex_unlock(&queueAccess);
2461    
2462          return Result;          return Result;
2463  }  }
2464    
# Line 2432  SC_deviceControl(PSCThreadData data) Line 2476  SC_deviceControl(PSCThreadData data)
2476  static void *  static void *
2477  thread_function(PThreadListElement listElement)  thread_function(PThreadListElement listElement)
2478  {  {
2479          if ((listElement != NULL) && (listElement->data != NULL))          pthread_mutex_lock(&listElement->busy);
2480            while (1)
2481          {          {
2482                  while (1)                  while (listElement->data == NULL)
2483                  {                          pthread_cond_wait(&listElement->nodata,
2484                          pthread_mutex_lock(&listElement->nodata);                              &listElement->busy);
2485                          SC_deviceControl(listElement->data);  
2486                          listElement->data = NULL;                  SC_deviceControl(listElement->data);
2487                          pthread_mutex_unlock(&listElement->busy);                  listElement->data = NULL;
                 }  
2488          }          }
2489            pthread_mutex_unlock(&listElement->busy);
2490    
2491          pthread_exit(NULL);          pthread_exit(NULL);
2492          return NULL;          return NULL;
2493  }  }
# Line 2450  static void Line 2496  static void
2496  SC_handleRequest(PSCThreadData data)  SC_handleRequest(PSCThreadData data)
2497  {  {
2498          int Result = 0;          int Result = 0;
2499          PThreadListElement cur = threadList, last = threadList;          PThreadListElement cur;
2500    
2501          while (cur)          for (cur = threadList; cur != NULL; cur = cur->next) {
2502          {                  if (cur->data == NULL) {
2503                  if (0 == pthread_mutex_trylock(&cur->busy))                          pthread_mutex_lock(&cur->busy);
2504                  {                          /* double check with lock held.... */
2505                            if (cur->data != NULL) {
2506                                    pthread_mutex_unlock(&cur->busy);
2507                                    continue;
2508                            }
2509                            
2510                            /* Wake up thread */
2511                          cur->data = data;                          cur->data = data;
2512                          pthread_mutex_unlock(&cur->nodata);                          pthread_cond_broadcast(&cur->nodata);
2513                            pthread_mutex_unlock(&cur->busy);
2514                          return;                          return;
2515                  }                  }
                 else  
                 {  
                         last = cur;  
                         cur = cur->next;  
                 }  
2516          }          }
2517    
2518          cur = SC_xmalloc(&threadListHandle, sizeof(TThreadListElement));          cur = SC_xmalloc(&threadListHandle, sizeof(TThreadListElement));
# Line 2473  SC_handleRequest(PSCThreadData data) Line 2521  SC_handleRequest(PSCThreadData data)
2521    
2522          threadCount++;          threadCount++;
2523    
         cur->next = NULL;  
2524          pthread_mutex_init(&cur->busy, NULL);          pthread_mutex_init(&cur->busy, NULL);
2525          pthread_mutex_init(&cur->nodata, NULL);          pthread_cond_init(&cur->nodata, NULL);
         pthread_mutex_trylock(&cur->busy);  
2526          cur->data = data;          cur->data = data;
         pthread_mutex_unlock(&cur->nodata);  
2527    
2528          Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);          Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);
2529          if (0 != Result)          if (0 != Result)
# Line 2488  SC_handleRequest(PSCThreadData data) Line 2533  SC_handleRequest(PSCThreadData data)
2533                  SC_destroyThreadData(data);                  SC_destroyThreadData(data);
2534                  data = NULL;                  data = NULL;
2535          }          }
2536          else if (last)          cur->next = threadList;
2537                  last->next = cur;          threadList = cur;
         else  
                 threadList = cur;  
2538  }  }
2539    
2540  static void *  static void *
# Line 2501  queue_handler_function(void *data) Line 2544  queue_handler_function(void *data)
2544          while (1)          while (1)
2545          {          {
2546                  cur_data = SC_getNextInQueue();                  cur_data = SC_getNextInQueue();
2547                  if (cur_data != NULL)                  switch (cur_data->request)
2548                  {                  {
2549                          switch (cur_data->request)                          case SC_ESTABLISH_CONTEXT:
2550                          {                          case SC_RELEASE_CONTEXT:
2551                                  case SC_ESTABLISH_CONTEXT:                                  {
2552                                  case SC_RELEASE_CONTEXT:                                          SC_deviceControl(cur_data);
2553                                          {                                          break;
2554                                                  SC_deviceControl(cur_data);                                  }
2555                                                  break;                          default:
2556                                          }                                  {
2557                                  default:                                          SC_handleRequest(cur_data);
2558                                          {                                          break;
2559                                                  SC_handleRequest(cur_data);                                  }
                                                 break;  
                                         }  
                         }  
                         cur_data = NULL;  
2560                  }                  }
                 else  
                         pthread_mutex_lock(&queueEmpty);  
2561          }          }
2562          return NULL;          return NULL;
2563  }  }

Legend:
Removed from v.1420  
changed lines
  Added in v.1421

  ViewVC Help
Powered by ViewVC 1.1.26