/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1316 - (hide annotations)
Wed Nov 1 22:46:05 2006 UTC (17 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 70536 byte(s)
remove a bit code duplication

1 stargo 1312 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Smart Card support
4     Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006
5 stargo 1309
6 stargo 1312 This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 stargo 1309 #include <stdio.h>
22     #include "rdesktop.h"
23     #include <unistd.h>
24     #include <fcntl.h>
25     #include <strings.h>
26     #include <sys/types.h>
27     #include <time.h>
28     #ifndef MAKE_PROTO
29 stargo 1311 #ifdef PCSC_OSX
30     #include <PCSC/pcsclite.h>
31     #include <PCSC/winscard.h>
32     #else
33 stargo 1309 #include <pcsclite.h>
34     #include <winscard.h>
35 stargo 1311 #endif /* PCSC_OSX */
36 stargo 1309 #include "scard.h"
37    
38     /* variable segment */
39    
40     #define SCARD_MAX_MEM 102400
41     #define SCARD_AUTOALLOCATE -1
42     #define OUT_STREAM_SIZE 4096
43     #define STREAM_COUNT 8
44    
45     static struct stream out[STREAM_COUNT];
46     static int cur_stream_id = 0;
47     static pthread_mutex_t *tcp_sendcontrol_mutex = NULL;
48    
49     static uint32 curDevice = 0, curId = 0, curBytesOut = 0;
50     static PSCNameMapRec nameMapList = NULL;
51     static int nameMapCount = 0;
52    
53     static pthread_t queueHandler;
54     static pthread_mutex_t queueAccess;
55     static pthread_mutex_t queueEmpty;
56     static pthread_mutex_t hcardAccess;
57     /* static pthread_mutex_t sendControl; */
58    
59     static PMEM_HANDLE threadListHandle = NULL;
60     static PThreadListElement threadList = NULL;
61    
62    
63     static PSCThreadData queueFirst = NULL, queueLast = NULL;
64     static int threadCount = 0;
65    
66     static PSCHCardRec hcardFirst = NULL;
67    
68     static void *queue_handler_function(void *data);
69    
70     /* code segment */
71    
72     #endif /* MAKE_PROTO */
73     void
74     scardSetInfo(uint32 device, uint32 id, uint32 bytes_out)
75     {
76     curDevice = device;
77     curId = id;
78     curBytesOut = bytes_out;
79     }
80    
81     #ifndef MAKE_PROTO
82    
83     static NTSTATUS
84     scard_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
85     uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
86     {
87     return STATUS_SUCCESS;
88     }
89    
90     static NTSTATUS
91     scard_close(NTHANDLE handle)
92     {
93     return STATUS_SUCCESS;
94     }
95    
96     static NTSTATUS
97     scard_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
98     {
99     return STATUS_SUCCESS;
100     }
101    
102     static NTSTATUS
103     scard_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
104     {
105     return STATUS_SUCCESS;
106     }
107     #endif /* MAKE_PROTO */
108    
109     /* Enumeration of devices from rdesktop.c */
110     /* returns numer of units found and initialized. */
111     /* optarg looks like ':"ReaderName=ReaderAlias"' */
112     /* when it arrives to this function. */
113    
114     int
115     scard_enum_devices(uint32 * id, char *optarg)
116     {
117     char *name = optarg + 1;
118     char *alias;
119     int count = 0;
120     PSCNameMapRec tmpMap;
121    
122     MYPCSC_DWORD rv;
123     SCARDCONTEXT hContext;
124    
125     /* code segment */
126     rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
127     if (rv != SCARD_S_SUCCESS)
128     {
129     printf("[SMART CARD: PCSC service not available]\n");
130     return 0;
131     }
132     else
133     rv = SCardReleaseContext(hContext);
134    
135     count = 0;
136    
137     if (0 != pthread_mutex_init(&queueAccess, NULL))
138     {
139     printf("[SMART CARD: Can't initialize queue access mutex]\n");
140     return 0;
141     }
142    
143     if (0 != pthread_mutex_init(&queueEmpty, NULL))
144     {
145     printf("[SMART CARD: Can't initialize queue control mutex]\n");
146     return 0;
147     }
148    
149     if (0 != pthread_mutex_init(&hcardAccess, NULL))
150     {
151     printf("[SMART CARD: Can't initialize hcard list access mutex]\n");
152     return 0;
153     }
154    
155     #if 0
156     if (0 != pthread_mutex_init(&sendControl, NULL))
157     {
158     printf("[SMART CARD: Can't initialize send control mutex]\n");
159     return 0;
160     }
161     #endif
162    
163    
164     if (0 !=
165     pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL))
166     {
167     printf("[SMART CARD: Can't create queue handling Thread]\n");
168     return 0;
169     }
170    
171     strncpy(g_rdpdr_device[*id].name, "SCARD\0\0\0", 8);
172     toupper_str(g_rdpdr_device[*id].name);
173     g_rdpdr_device[*id].local_path = "/dev/scard";
174     g_rdpdr_device[*id].pdevice_data = NULL;
175     g_rdpdr_device[*id].handle = 0;
176     g_rdpdr_device[*id].device_type = DEVICE_TYPE_SCARD;
177     count++;
178     (*id)++;
179    
180     if (*optarg == ':')
181     {
182     while ((optarg = next_arg(name, ',')) && *id < RDPDR_MAX_DEVICES)
183     {
184     int len;
185     char *vendor = NULL;
186     alias = next_arg(name, '=');
187     vendor = next_arg(alias, ';');
188    
189     if (strlen(name) > 0)
190     {
191     if (!strlen(alias))
192     {
193     alias = name;
194     vendor = "\0";
195     }
196    
197     printf("Static/aliased Device:\n");
198     printf(" Lin name: [%s]\n", name);
199     printf(" Win name: [%s]\n", alias);
200     printf(" Vendor : [%s]\n", vendor);
201     nameMapCount++;
202    
203     if (nameMapList == NULL)
204     nameMapList = xmalloc(nameMapCount * sizeof(TSCNameMapRec));
205     else
206     nameMapList =
207     xrealloc(nameMapList,
208     nameMapCount * sizeof(TSCNameMapRec));
209    
210     tmpMap = nameMapList + nameMapCount - 1;
211    
212     len = strlen(alias);
213     strncpy(tmpMap->alias, alias, (len > 127) ? (127) : (len));
214     len = strlen(name);
215     strncpy(tmpMap->name, name, (len > 127) ? (127) : (len));
216    
217     if (vendor)
218     {
219     len = strlen(vendor);
220     if (len > 0)
221     {
222     memset(tmpMap->vendor, 0, 128);
223     strncpy(tmpMap->vendor, vendor,
224     (len > 127) ? (127) : (len));
225     }
226     else
227     tmpMap->vendor[0] = '\0';
228     }
229     else
230     tmpMap->vendor[0] = '\0';
231     }
232     name = optarg;
233     }
234     }
235    
236    
237     printf("******************************************************\n");
238     printf("* Smart Card support for RDesktop is initialized. *\n");
239     printf("* Copyright (C) by Alexi Volkov, alexi@myrealbox.com *\n");
240     printf("******************************************************\n");
241    
242     return count;
243     }
244    
245     #ifndef MAKE_PROTO
246     /* ---------------------------------- */
247    
248     /* These two functions depend heavily on the actual implementation of the smart
249     * card handle in PC/SC Lite 1.3.1. Here are the salient bits:
250     *
251     * From winscard.c:331, in SCardConnect:
252     * *phCard = RFCreateReaderHandle(rContext);
253     *
254     * RFCreateReaderHandle (readerfactory.c:1161) creates a random short (16-bit
255     * integer) and makes sure it's unique. Then it adds it to
256     * rContext->dwIdentity.
257     *
258     * From readerfactory.c:173, in RFAddReader:
259     * (sReadersContexts[dwContext])->dwIdentity =
260     * (dwContext + 1) << (sizeof(DWORD) / 2) * 8;
261     *
262     * dwContext must be less than PCSCLITE_MAX_READERS_CONTEXTS, which is defined
263     * to be 16 in the 1.3.1 release.
264     *
265     * The use of "(sizeof(DWORD) / 2) * 8" is what makes conversion necessary in
266     * order to use 64-bit card handles when talking to PC/SC Lite, and 32-bit card
267     * handles when talking with the server, without losing any data: a card handle
268     * made by a 32-bit PC/SC Lite looks like 0x00014d32, where the 4d32 is the
269     * random 16 bits, 01 is the reader context index + 1, and it's left-shifted by
270     * 16 bits (sizeof(DWORD) == 4, divided by 2 is 2, times 8 is 16.) But a 64-bit
271     * PC/SC Lite makes a card handle that looks like 0x0000000100004d32. The
272     * reader context index+1 is left-shifted 32 bits because sizeof(DWORD) is 8,
273     * not 4. This means the handle won't fit in 32 bits. (The multiplication by 8
274     * is because sizeofs are in bytes, but saying how many places to left-shift is
275     * speaking in bits.)
276     *
277     * So then. Maximum value of dwContext+1 is 17; we'll say this fits in a byte
278     * to be loose and have plenty of room. This is then left-shifted by
279     * sizeof(DWORD) / 2 * 8 - which in this file is sizeof(MYPCSC_DWORD) / 2 * 8.
280     *
281     * At any rate, if we take the handle as passed from PC/SC Lite, right-shift by
282     * sizeof(MYPCSC_DWORD) / 2, left-shift by sizeof(SERVER_DWORD) / 2, and add
283     * the lower two bytes of the value (the random number), we can fit all the
284     * information into 32 bits without losing any. Of course, any time we want to
285     * hand that back to PC/SC Lite, we'll have to expand it again. (And if
286     * sizeof(MYPCSC_DWORD) == sizeof(SERVER_DWORD), we're essentially doing
287     * nothing, which will not break anything.)
288     *
289     *
290     * - jared.jennings@eglin.af.mil, 2 Aug 2006
291     */
292    
293    
294     static MYPCSC_SCARDHANDLE
295     scHandleToMyPCSC(SERVER_SCARDHANDLE server)
296     {
297     return (((MYPCSC_SCARDHANDLE) server >> (sizeof(SERVER_DWORD) * 8 / 2) & 0xffff)
298     << (sizeof(MYPCSC_DWORD) * 8 / 2)) + (server & 0xffff);
299     }
300    
301     static SERVER_SCARDHANDLE
302     scHandleToServer(MYPCSC_SCARDHANDLE mypcsc)
303     {
304     return ((mypcsc >> (sizeof(MYPCSC_DWORD) * 8 / 2) & 0xffff)
305     << (sizeof(SERVER_DWORD) * 8 / 2)) + (mypcsc & 0xffff);
306     }
307    
308     /* ---------------------------------- */
309    
310     static void *
311     SC_xmalloc(PMEM_HANDLE * memHandle, unsigned int size)
312     {
313     PMEM_HANDLE handle = NULL;
314     if (size > 0 && memHandle)
315     {
316     handle = xmalloc(size + sizeof(MEM_HANDLE));
317     if (handle)
318     {
319     handle->prevHandle = NULL;
320     handle->nextHandle = NULL;
321     handle->dataSize = size;
322     if (*memHandle)
323     {
324     handle->prevHandle = *memHandle;
325     (*memHandle)->nextHandle = handle;
326     }
327     *memHandle = handle;
328     return handle + 1;
329     }
330     else
331     return NULL;
332     }
333     else
334     return NULL;
335     }
336    
337     static void
338     SC_xfree(PMEM_HANDLE * handle, void *memptr)
339     {
340     if (memptr != NULL)
341     {
342     PMEM_HANDLE lcHandle = (PMEM_HANDLE) memptr - 1;
343     if (lcHandle->dataSize > 0)
344     {
345     memset(memptr, 0, lcHandle->dataSize);
346     if (lcHandle->nextHandle)
347     lcHandle->nextHandle->prevHandle = lcHandle->prevHandle;
348     if (lcHandle->prevHandle)
349     lcHandle->prevHandle->nextHandle = lcHandle->nextHandle;
350     if (*handle == lcHandle)
351     {
352     if (lcHandle->prevHandle)
353     *handle = lcHandle->prevHandle;
354     else
355     *handle = lcHandle->nextHandle;
356     }
357     xfree(lcHandle);
358     }
359     }
360     }
361    
362     static void
363     SC_xfreeallmemory(PMEM_HANDLE * handle)
364     {
365     if (handle && (*handle))
366     {
367     if ((*handle)->prevHandle)
368     {
369     (*handle)->prevHandle->nextHandle = NULL;
370     SC_xfreeallmemory(&((*handle)->prevHandle));
371     }
372     if ((*handle)->nextHandle)
373     {
374     (*handle)->nextHandle->prevHandle = NULL;
375     SC_xfreeallmemory(&((*handle)->nextHandle));
376     }
377     memset(*handle, 0, (*handle)->dataSize + sizeof(MEM_HANDLE));
378     xfree(*handle);
379     *handle = NULL;
380     }
381     }
382    
383     /* ---------------------------------- */
384    
385     static char *
386     getName(char *alias)
387     {
388     int i;
389     PSCNameMapRec tmpMap;
390     for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)
391     {
392     if (strcmp(tmpMap->alias, alias) == 0)
393     return tmpMap->name;
394     }
395     return alias;
396     }
397    
398     static char *
399     getVendor(char *name)
400     {
401     int i;
402     PSCNameMapRec tmpMap;
403     for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)
404     {
405     if (strcmp(tmpMap->name, name) == 0)
406     return tmpMap->vendor;
407     }
408     return NULL;
409     }
410    
411    
412     static char *
413     getAlias(char *name)
414     {
415     int i;
416     PSCNameMapRec tmpMap;
417     for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)
418     {
419     if (strcmp(tmpMap->name, name) == 0)
420     return tmpMap->alias;
421     }
422     return name;
423     }
424    
425     static int
426     hasAlias(char *name)
427     {
428     int i;
429     PSCNameMapRec tmpMap;
430     for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)
431     {
432     if (strcmp(tmpMap->name, name) == 0)
433     return 1;
434     }
435     return 0;
436     }
437    
438     static void
439     inRepos(STREAM in, unsigned int read)
440     {
441     SERVER_DWORD add = 4 - read % 4;
442     if (add < 4 && add > 0)
443     {
444     in_uint8s(in, add);
445     }
446     }
447    
448     static void
449     outRepos(STREAM out, unsigned int written)
450     {
451     SERVER_DWORD add = (4 - written % 4) % 4;
452     if (add > 0)
453     {
454     out_uint8s(out, add);
455     }
456     }
457    
458    
459     static void
460     outBufferStartWithLimit(STREAM out, int length, int highLimit)
461     {
462     int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length));
463     out_uint32_le(out, header);
464     out_uint32_le(out, 0x00000001); /* Magic DWORD - any non zero */
465     }
466    
467    
468     static void
469     outBufferStart(STREAM out, int length)
470     {
471     outBufferStartWithLimit(out, length, 0x7FFFFFFF);
472     }
473    
474     static void
475     outBufferFinishWithLimit(STREAM out, char *buffer, unsigned int length, unsigned int highLimit)
476     {
477     int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length));
478     out_uint32_le(out, header);
479    
480     if (length <= 0)
481     {
482     out_uint32_le(out, 0x00000000);
483     }
484     else
485     {
486     if (header < length)
487     length = header;
488     out_uint8p(out, buffer, length);
489     outRepos(out, length);
490     }
491     }
492    
493     static void
494     outBufferFinish(STREAM out, char *buffer, unsigned int length)
495     {
496     outBufferFinishWithLimit(out, buffer, length, 0x7FFFFFFF);
497     }
498    
499     static void
500     outForceAllignment(STREAM out, unsigned int seed)
501     {
502     SERVER_DWORD add = (seed - (out->p - out->data) % seed) % seed;
503     if (add > 0)
504     {
505     out_uint8s(out, add);
506     }
507     }
508    
509     static unsigned int
510     inString(PMEM_HANDLE * handle, STREAM in, char **destination, SERVER_DWORD dataLength, BOOL wide)
511     {
512     unsigned int Result = (wide) ? (2 * dataLength) : (dataLength);
513     PMEM_HANDLE lcHandle = NULL;
514     char *buffer = SC_xmalloc(&lcHandle, Result + 2);
515     char *reader;
516    
517     /* code segment */
518    
519     if (wide)
520     {
521     int i;
522     in_uint8a(in, buffer, 2 * dataLength);
523     for (i = 0; i < dataLength; i++)
524     if ((buffer[2 * i] < 0) || (buffer[2 * i + 1] != 0))
525     buffer[i] = '?';
526     else
527     buffer[i] = buffer[2 * i];
528     }
529     else
530     {
531     in_uint8a(in, buffer, dataLength);
532     }
533    
534     buffer[dataLength] = '\0';
535     reader = getName(buffer);
536     *destination = SC_xmalloc(handle, strlen(reader) + 1);
537     strcpy(*destination, reader);
538    
539     SC_xfreeallmemory(&lcHandle);
540     return Result;
541     }
542    
543     static unsigned int
544     outString(STREAM out, char *source, BOOL wide)
545     {
546     PMEM_HANDLE lcHandle = NULL;
547     char *reader = getAlias(source);
548     unsigned int dataLength = strlen(reader) + 1;
549     unsigned int Result = (wide) ? (2 * dataLength) : (dataLength);
550    
551     /* code segment */
552    
553     if (wide)
554     {
555     int i;
556     char *buffer = SC_xmalloc(&lcHandle, Result);
557    
558     for (i = 0; i < dataLength; i++)
559     {
560     if (source[i] < 0)
561     buffer[2 * i] = '?';
562     else
563     buffer[2 * i] = reader[i];
564     buffer[2 * i + 1] = '\0';
565     }
566     out_uint8p(out, buffer, 2 * dataLength);
567     }
568     else
569     {
570     out_uint8p(out, reader, dataLength);
571     }
572    
573     SC_xfreeallmemory(&lcHandle);
574     return Result;
575     }
576    
577     static void
578     inReaderName(PMEM_HANDLE * handle, STREAM in, char **destination, BOOL wide)
579     {
580     SERVER_DWORD dataLength;
581     in->p += 0x08;
582     in_uint32_le(in, dataLength);
583     inRepos(in, inString(handle, in, destination, dataLength, wide));
584     }
585    
586     static void
587     inSkipLinked(STREAM in)
588     {
589     SERVER_DWORD len;
590     in_uint32_le(in, len);
591     if (len > 0)
592     {
593     in_uint8s(in, len);
594     inRepos(in, len);
595     }
596     }
597    
598     /* ---------------------------------- */
599     /* Smart Card processing functions: */
600     /* ---------------------------------- */
601    
602     static MYPCSC_DWORD
603     SC_returnCode(MYPCSC_DWORD rc, PMEM_HANDLE * handle, STREAM in, STREAM out)
604     {
605     SC_xfreeallmemory(handle);
606     out_uint8s(out, 256);
607     return rc;
608     }
609    
610     static MYPCSC_DWORD
611     SC_returnNoMemoryError(PMEM_HANDLE * handle, STREAM in, STREAM out)
612     {
613     return SC_returnCode(SCARD_E_NO_MEMORY, handle, in, out);
614     }
615    
616     static MYPCSC_DWORD
617     TS_SCardEstablishContext(STREAM in, STREAM out)
618     {
619     MYPCSC_DWORD rv;
620     MYPCSC_SCARDCONTEXT hContext;
621     /* code segment */
622    
623     #ifdef WITH_SCARD_DEBUG
624     printf("Establishing PC/SC Context... \n");
625     #endif
626     rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
627     #ifdef WITH_SCARD_DEBUG
628     if (rv)
629     printf("<--ERROR SCardEstablishContext Code=0x%.8x]-->\n", (unsigned int) rv);
630     else
631     printf("<--SUCCESS SCardEstablishContext-->\n");
632     #endif
633    
634     out_uint32_le(out, 0x00000004);
635     out_uint32_le(out, (SERVER_DWORD) hContext); /* must not be 0 (Seems to be pointer), don't know what is this (I use hContext as value) */
636     /* i hope it's not a pointer because i just downcasted it - jlj */
637     out_uint32_le(out, 0x00000004);
638     out_uint32_le(out, (SERVER_DWORD) hContext);
639     return rv;
640     }
641    
642     static MYPCSC_DWORD
643     TS_SCardReleaseContext(STREAM in, STREAM out)
644     {
645     MYPCSC_DWORD rv;
646     SERVER_SCARDCONTEXT hContext;
647    
648     in->p += 0x1C;
649     in_uint32_le(in, hContext);
650     #ifdef WITH_SCARD_DEBUG
651     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
652     printf("Releasing context... \n");
653     #endif
654     rv = SCardReleaseContext((MYPCSC_SCARDCONTEXT) hContext);
655     #ifdef WITH_SCARD_DEBUG
656     if (rv)
657     printf("<--ERROR SCardReleaseContext Code=0x%.8x-->\n", (unsigned int) rv);
658     else
659     printf("<--SUCCESS SCardReleaseContext-->\n");
660     #endif
661     return rv;
662     }
663    
664     static MYPCSC_DWORD
665     TS_SCardIsValidContext(STREAM in, STREAM out)
666     {
667     MYPCSC_DWORD rv;
668     SERVER_SCARDCONTEXT hContext;
669     char *readers;
670     DWORD readerCount = 1024;
671     PMEM_HANDLE lcHandle = NULL;
672    
673     in->p += 0x1C;
674     in_uint32_le(in, hContext);
675     #ifdef WITH_SCARD_DEBUG
676     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
677     printf("Checking... \n");
678     #endif
679     /* There is no realization of SCardIsValidContext in PC/SC Lite so we call SCardListReaders */
680    
681     readers = SC_xmalloc(&lcHandle, 1024);
682     if (!readers)
683     return SC_returnNoMemoryError(&lcHandle, in, out);
684    
685     rv = SCardListReaders((MYPCSC_SCARDCONTEXT) hContext, NULL, readers, &readerCount);
686     if (rv)
687     {
688     #ifdef WITH_SCARD_DEBUG
689     printf("<--ERROR SCardListReaders (no SCardIsValidContext) Code=0x%.8x-->\n",
690     (unsigned int) rv);
691     #endif
692     rv = SCARD_E_INVALID_HANDLE;
693     }
694     #ifdef WITH_SCARD_DEBUG
695     else
696     printf("<--SUCCESS SCardListReaders (no SCardIsValidContext)-->\n");
697     #endif
698     outForceAllignment(out, 8);
699     SC_xfreeallmemory(&lcHandle);
700     return rv;
701     }
702    
703    
704     static MYPCSC_DWORD
705     TS_SCardListReaders(STREAM in, STREAM out, BOOL wide)
706     {
707     #define readerArraySize 1024
708     MYPCSC_DWORD rv;
709     SERVER_SCARDCONTEXT hContext;
710     SERVER_DWORD dataLength;
711     MYPCSC_DWORD cchReaders = readerArraySize;
712     unsigned char *plen1, *plen2, *pend;
713     char *readers, *cur;
714     PMEM_HANDLE lcHandle = NULL;
715    
716     in->p += 0x2C;
717     in_uint32_le(in, hContext);
718     #ifdef WITH_SCARD_DEBUG
719     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
720     #endif
721     plen1 = out->p;
722     out_uint32_le(out, 0x00000000); /* Temp value for data length as 0x0 */
723     out_uint32_le(out, 0x01760650);
724     plen2 = out->p;
725     out_uint32_le(out, 0x00000000); /* Temp value for data length as 0x0 */
726    
727     dataLength = 0;
728     readers = SC_xmalloc(&lcHandle, readerArraySize);
729     if (!readers)
730     return SC_returnNoMemoryError(&lcHandle, in, out);
731    
732    
733     readers[0] = '\0';
734     readers[1] = '\0';
735     rv = SCardListReaders((MYPCSC_SCARDCONTEXT) hContext, NULL, readers, &cchReaders);
736     cur = readers;
737     if (!rv)
738     {
739     int i;
740     PSCNameMapRec tmpMap;
741     #ifdef WITH_SCARD_DEBUG
742     printf("[CALL RESULT of SCardListReaders 0x%.8x]\n", (unsigned int) rv);
743     hexdump((void *) readers, cchReaders);
744     #endif
745     for (i = 0, tmpMap = nameMapList; i < nameMapCount; i++, tmpMap++)
746     {
747     dataLength += outString(out, tmpMap->alias, wide);
748     }
749    
750     int lenSC = strlen(cur);
751     if (lenSC == 0)
752     dataLength += outString(out, "\0", wide);
753     else
754     while (lenSC > 0)
755     {
756     if (!hasAlias(cur))
757     dataLength += outString(out, cur, wide);
758     cur = (void *) ((unsigned char *) cur + lenSC + 1);
759     lenSC = strlen(cur);
760     }
761     }
762    
763     dataLength += outString(out, "\0", wide);
764     outRepos(out, dataLength);
765    
766     pend = out->p;
767     out->p = plen1;
768     out_uint32_le(out, dataLength);
769     out->p = plen2;
770     out_uint32_le(out, dataLength);
771     out->p = pend;
772    
773     outForceAllignment(out, 8);
774     SC_xfreeallmemory(&lcHandle);
775     return rv;
776     }
777    
778    
779     static MYPCSC_DWORD
780     TS_SCardConnect(STREAM in, STREAM out, BOOL wide)
781     {
782     MYPCSC_DWORD rv;
783     SCARDCONTEXT hContext;
784     char *szReader;
785     SERVER_DWORD dwShareMode;
786     SERVER_DWORD dwPreferredProtocol;
787     MYPCSC_SCARDHANDLE myHCard;
788     SERVER_SCARDHANDLE hCard;
789    
790     MYPCSC_DWORD dwActiveProtocol;
791     PMEM_HANDLE lcHandle = NULL;
792    
793     in->p += 0x1C;
794     in_uint32_le(in, dwShareMode);
795     in_uint32_le(in, dwPreferredProtocol);
796     #ifdef WITH_SCARD_DEBUG
797     printf("[SHARE %8x]\n", (unsigned int) dwShareMode);
798     printf("[PROTO %8x]\n", (unsigned int) dwPreferredProtocol);
799     #endif
800     inReaderName(&lcHandle, in, &szReader, wide);
801     #ifdef WITH_SCARD_DEBUG
802     printf("[CONNECT TO READER \"%s\"\n", (szReader != NULL) ? (szReader) : ("NULL"));
803     #endif
804     in->p += 0x04;
805     in_uint32_le(in, hContext);
806     #ifdef WITH_SCARD_DEBUG
807     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
808     #endif
809     rv = SCardConnect(hContext, szReader, (MYPCSC_DWORD) dwShareMode,
810     (MYPCSC_DWORD) dwPreferredProtocol, &myHCard, &dwActiveProtocol);
811     hCard = scHandleToServer(myHCard);
812     #ifdef WITH_SCARD_DEBUG
813 stargo 1313 printf("[RECEIVED HCARD 0x%016lx]\n", (unsigned long) myHCard);
814 stargo 1309 printf("[MANGLED HCARD 0x%08x]\n", hCard);
815     #endif
816     if (rv != SCARD_S_SUCCESS)
817     {
818     #ifdef WITH_SCARD_DEBUG
819     printf("<--ERROR SCardConnect Code=0x%.8x-->\n", (unsigned int) rv);
820     #endif
821     }
822     else
823     {
824     char *szVendor = getVendor(szReader);
825     #ifdef WITH_SCARD_DEBUG
826     printf("<--SUCCESS ScardConnect-->\n");
827     #endif
828     if (szVendor && (strlen(szVendor) > 0))
829     {
830     #ifdef WITH_SCARD_DEBUG
831     printf("Set Attribute ATTR_VENDOR_NAME\n");
832     #endif
833     pthread_mutex_lock(&hcardAccess);
834     PSCHCardRec hcard = xmalloc(sizeof(TSCHCardRec));
835     if (hcard)
836     {
837     hcard->hCard = hCard;
838     hcard->vendor = szVendor;
839     hcard->next = NULL;
840     hcard->prev = NULL;
841    
842     if (hcardFirst)
843     {
844     hcardFirst->prev = hcard;
845     hcard->next = hcardFirst;
846     }
847     hcardFirst = hcard;
848     }
849     pthread_mutex_unlock(&hcardAccess);
850     }
851     }
852    
853     out_uint32_le(out, 0x00000000);
854     out_uint32_le(out, 0x00000000);
855     out_uint32_le(out, 0x00000004);
856     out_uint32_le(out, 0x016Cff34);
857     /* if the active protocol > 4 billion, this is trouble. odds are low */
858     out_uint32_le(out, (SERVER_DWORD) dwActiveProtocol);
859     out_uint32_le(out, 0x00000004);
860     out_uint32_le(out, hCard);
861    
862     outForceAllignment(out, 8);
863     SC_xfreeallmemory(&lcHandle);
864     return rv;
865     }
866    
867     static MYPCSC_DWORD
868     TS_SCardReconnect(STREAM in, STREAM out)
869     {
870     MYPCSC_DWORD rv;
871     SCARDCONTEXT hContext;
872     SERVER_SCARDHANDLE hCard;
873     MYPCSC_SCARDHANDLE myHCard;
874     SERVER_DWORD dwShareMode;
875     SERVER_DWORD dwPreferredProtocol;
876     SERVER_DWORD dwInitialization;
877     MYPCSC_DWORD dwActiveProtocol;
878    
879     in->p += 0x20;
880     in_uint32_le(in, dwShareMode);
881     in_uint32_le(in, dwPreferredProtocol);
882     in_uint32_le(in, dwInitialization);
883     in->p += 0x04;
884     in_uint32_le(in, hContext);
885     in->p += 0x04;
886     in_uint32_le(in, hCard);
887     myHCard = scHandleToMyPCSC(hCard);
888     #ifdef WITH_SCARD_DEBUG
889     printf("[SHARE = 0x%.8x]\n", (unsigned int) dwShareMode);
890     printf("[PROTO = 0x%.8x]\n", (unsigned int) dwPreferredProtocol);
891     printf("[INIT = 0x%.8x]\n", (unsigned int) dwInitialization);
892     printf("[hContext = 0x%.8x]\n", (unsigned int) hContext);
893     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
894 stargo 1313 printf("[myHCard = 0x%016lx]\n", (unsigned long) myHCard);
895 stargo 1309 #endif
896     rv = SCardReconnect(myHCard, (MYPCSC_DWORD) dwShareMode, (MYPCSC_DWORD) dwPreferredProtocol,
897     (MYPCSC_DWORD) dwInitialization, &dwActiveProtocol);
898     #ifdef WITH_SCARD_DEBUG
899     if (rv != SCARD_S_SUCCESS)
900     printf("<--ERROR SCardReconnect Code=0x%.8x-->\n", (unsigned int) rv);
901     else
902     printf("<--SUCCESS SCardReconnect-->\n");
903     #endif
904    
905     outForceAllignment(out, 8);
906     out_uint32_le(out, (SERVER_DWORD) dwActiveProtocol);
907     return rv;
908     }
909    
910     static MYPCSC_DWORD
911     TS_SCardDisconnect(STREAM in, STREAM out)
912     {
913     MYPCSC_DWORD rv;
914     SERVER_SCARDCONTEXT hContext;
915     SERVER_SCARDHANDLE hCard;
916     MYPCSC_SCARDHANDLE myHCard;
917     SERVER_DWORD dwDisposition;
918    
919     in->p += 0x20;
920     in_uint32_le(in, dwDisposition);
921     in->p += 0x04;
922     in_uint32_le(in, hContext);
923     in->p += 0x04;
924     in_uint32_le(in, hCard);
925    
926     #ifdef WITH_SCARD_DEBUG
927     printf("[hContext = 0x%.8x]\n", (unsigned int) hContext);
928     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
929     printf("[dwDisposition = 0x%.8x]\n", (unsigned int) dwDisposition);
930     #endif
931    
932     pthread_mutex_lock(&hcardAccess);
933     PSCHCardRec hcard = hcardFirst;
934     while (hcard)
935     {
936     if (hcard->hCard == hCard)
937     {
938     if (hcard->prev)
939     hcard->prev->next = hcard->next;
940     if (hcard->next)
941     hcard->next->prev = hcard->prev;
942     if (hcardFirst == hcard)
943     hcardFirst = hcard->next;
944     xfree(hcard);
945     break;
946     }
947     hcard = hcard->next;
948     }
949     pthread_mutex_unlock(&hcardAccess);
950    
951     myHCard = scHandleToMyPCSC(hCard);
952     rv = SCardDisconnect(myHCard, (MYPCSC_DWORD) dwDisposition);
953    
954     #ifdef WITH_SCARD_DEBUG
955     if (rv != SCARD_S_SUCCESS)
956     printf("<--ERROR SCardDisconnect Code=0x%.8x-->\n", (unsigned int) rv);
957     else
958     printf("<--SUCCESS SCardDisconnect-->\n");
959     #endif
960     outForceAllignment(out, 8);
961     return rv;
962     }
963    
964     static int
965     needStatusRecheck(MYPCSC_DWORD rv, MYPCSC_LPSCARD_READERSTATE_A rsArray, SERVER_DWORD dwCount)
966     {
967     int i, recall = 0;
968     if (rv == SCARD_S_SUCCESS)
969     {
970     MYPCSC_LPSCARD_READERSTATE_A cur;
971     for (i = 0, cur = rsArray; i < dwCount; i++, cur++)
972     {
973     if (cur->dwEventState & SCARD_STATE_UNKNOWN)
974     {
975     cur->dwCurrentState = cur->dwEventState;
976     recall++;
977     }
978     }
979     }
980     return recall;
981     }
982    
983     static BOOL
984     mappedStatus(MYPCSC_DWORD code)
985     {
986     code >>= 16;
987     code &= 0x0000FFFF;
988     return (code % 2);
989     }
990    
991     static MYPCSC_DWORD
992     incStatus(MYPCSC_DWORD code, BOOL mapped)
993     {
994     if (mapped || (code & SCARD_STATE_CHANGED))
995     {
996     MYPCSC_DWORD count = (code >> 16) & 0x0000FFFF;
997     count++;
998     if (mapped && !(count % 2))
999     count++;
1000     return (code & 0x0000FFFF) | (count << 16);
1001     }
1002     else
1003     return code;
1004     }
1005    
1006     static void
1007     copyReaderState_MyPCSCToServer(MYPCSC_LPSCARD_READERSTATE_A src, SERVER_LPSCARD_READERSTATE_A dst,
1008     MYPCSC_DWORD readerCount)
1009     {
1010     MYPCSC_LPSCARD_READERSTATE_A srcIter;
1011     SERVER_LPSCARD_READERSTATE_A dstIter;
1012     MYPCSC_DWORD i;
1013    
1014     for (i = 0, srcIter = src, dstIter = dst; i < readerCount; i++, srcIter++, dstIter++)
1015     {
1016     dstIter->szReader = srcIter->szReader;
1017     dstIter->pvUserData = srcIter->pvUserData;
1018     dstIter->dwCurrentState = srcIter->dwCurrentState;
1019     dstIter->dwEventState = srcIter->dwEventState;
1020     dstIter->cbAtr = srcIter->cbAtr;
1021     memcpy(dstIter->rgbAtr, srcIter->rgbAtr, MAX_ATR_SIZE * sizeof(unsigned char));
1022     }
1023     }
1024    
1025     static void
1026     copyReaderState_ServerToMyPCSC(SERVER_LPSCARD_READERSTATE_A src, MYPCSC_LPSCARD_READERSTATE_A dst,
1027     SERVER_DWORD readerCount)
1028     {
1029     SERVER_LPSCARD_READERSTATE_A srcIter;
1030     MYPCSC_LPSCARD_READERSTATE_A dstIter;
1031     SERVER_DWORD i;
1032    
1033     for (i = 0, srcIter = src, dstIter = dst; i < readerCount; i++, srcIter++, dstIter++)
1034     {
1035     dstIter->szReader = srcIter->szReader;
1036     dstIter->pvUserData = srcIter->pvUserData;
1037     dstIter->dwCurrentState = srcIter->dwCurrentState;
1038     dstIter->dwEventState = srcIter->dwEventState;
1039     dstIter->cbAtr = srcIter->cbAtr;
1040     memcpy(dstIter->rgbAtr, srcIter->rgbAtr, MAX_ATR_SIZE * sizeof(unsigned char));
1041     }
1042     }
1043    
1044    
1045     static MYPCSC_DWORD
1046     TS_SCardGetStatusChange(STREAM in, STREAM out, BOOL wide)
1047     {
1048     MYPCSC_DWORD rv;
1049     SERVER_SCARDCONTEXT hContext;
1050     SERVER_DWORD dwTimeout;
1051     SERVER_DWORD dwCount;
1052     SERVER_LPSCARD_READERSTATE_A rsArray, cur;
1053     SERVER_DWORD *stateArray = NULL, *curState;
1054     MYPCSC_LPSCARD_READERSTATE_A myRsArray;
1055     long i;
1056     PMEM_HANDLE lcHandle = NULL;
1057     #if 0
1058     BOOL mapped = False;
1059     #endif
1060    
1061     in->p += 0x18;
1062     in_uint32_le(in, dwTimeout);
1063     in_uint32_le(in, dwCount);
1064     in->p += 0x08;
1065     in_uint32_le(in, hContext);
1066     in->p += 0x04;
1067     #ifdef WITH_SCARD_DEBUG
1068     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
1069     printf("[dwTimeout 0x%.8x]\n", (unsigned int) dwTimeout);
1070     printf("[COUNT %d]\n", (unsigned int) dwCount);
1071     printf("[TYPE SIZE %d]\n", (unsigned int) sizeof(SERVER_SCARD_READERSTATE_A));
1072     #endif
1073     if (dwCount > 0)
1074     {
1075     rsArray = SC_xmalloc(&lcHandle, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1076     if (!rsArray)
1077     return SC_returnNoMemoryError(&lcHandle, in, out);
1078     memset(rsArray, 0, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1079     stateArray = SC_xmalloc(&lcHandle, dwCount * sizeof(MYPCSC_DWORD));
1080     if (!stateArray)
1081     return SC_returnNoMemoryError(&lcHandle, in, out);
1082     /* skip two pointers at beginning of struct */
1083     for (i = 0, cur = (SERVER_LPSCARD_READERSTATE_A) ((unsigned char **) rsArray + 2);
1084     i < dwCount; i++, cur++)
1085     {
1086     in->p += 0x04;
1087     in_uint8a(in, cur, SERVER_SCARDSTATESIZE);
1088     }
1089     #ifdef WITH_SCARD_DEBUG
1090     printf("[READERS DUMP 1]------------------\n");
1091     hexdump((void *) rsArray, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1092     #endif
1093    
1094    
1095     for (i = 0, cur = rsArray, curState = stateArray;
1096     i < dwCount; i++, cur++, curState++)
1097     {
1098     SERVER_DWORD dataLength;
1099    
1100     /* reset Current state hign bytes; */
1101     *curState = cur->dwCurrentState;
1102     cur->dwCurrentState &= 0x0000FFFF;
1103     cur->dwEventState &= 0x0000FFFF;
1104    
1105     #if 0
1106     if (cur->dwCurrentState == (SCARD_STATE_CHANGED | SCARD_STATE_PRESENT))
1107     {
1108     cur->dwCurrentState = 0x00000000;
1109     mapped = True;
1110     }
1111    
1112     if (mappedStatus(*curState))
1113     {
1114     cur->dwCurrentState &= ~SCARD_STATE_INUSE;
1115     cur->dwEventState &= ~SCARD_STATE_INUSE;
1116    
1117     if (cur->dwCurrentState & SCARD_STATE_EMPTY)
1118     {
1119     cur->dwCurrentState &= ~SCARD_STATE_EMPTY;
1120     cur->dwCurrentState |= SCARD_STATE_UNKNOWN;
1121     }
1122     }
1123     #endif
1124    
1125     in->p += 0x08;
1126     in_uint32_le(in, dataLength);
1127     #ifdef WITH_SCARD_DEBUG
1128     printf("[%d] Data Length %d]\n", (unsigned int) i, dataLength);
1129     #endif
1130     inRepos(in,
1131     inString(&lcHandle, in, (char **) &(cur->szReader), dataLength,
1132     wide));
1133    
1134     if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0)
1135     cur->dwCurrentState |= SCARD_STATE_IGNORE;
1136     }
1137     #ifdef WITH_SCARD_DEBUG
1138     printf("[READERS DUMP 2]------------------\n");
1139     hexdump((void *) rsArray, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1140     #endif
1141     }
1142     else
1143     {
1144     rsArray = NULL;
1145     stateArray = NULL;
1146     }
1147    
1148     #ifdef WITH_SCARD_DEBUG
1149     printf("\nCalling SCardGetStatusChange...\n");
1150     #endif
1151    
1152    
1153     myRsArray = SC_xmalloc(&lcHandle, dwCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
1154     if (!rsArray)
1155     return SC_returnNoMemoryError(&lcHandle, in, out);
1156     memset(myRsArray, 0, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1157     copyReaderState_ServerToMyPCSC(rsArray, myRsArray, (SERVER_DWORD) dwCount);
1158     #ifdef WITH_SCARD_DEBUG
1159     printf("[TRANSLATION OF READERS]--------------------\n");
1160     hexdump((void *) myRsArray, dwCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
1161     #endif
1162    
1163     rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, (MYPCSC_DWORD) dwTimeout,
1164     myRsArray, (MYPCSC_DWORD) dwCount);
1165     copyReaderState_MyPCSCToServer(myRsArray, rsArray, (MYPCSC_DWORD) dwCount);
1166    
1167     #ifdef WITH_SCARD_DEBUG
1168     if (rv != SCARD_S_SUCCESS)
1169     printf("<--ERROR SCardGetStatusChange Code=0x%.8x-->\n", (unsigned int) rv);
1170     else
1171     printf("<--SUCCESS SCardGetStatusChange-->\n");
1172    
1173     if (dwCount > 0)
1174     {
1175     printf("[READERS DUMP]------------------\n");
1176     hexdump((void *) rsArray, dwCount * sizeof(SERVER_SCARD_READERSTATE_A));
1177     }
1178     #endif
1179    
1180     out_uint32_le(out, dwCount);
1181     out_uint32_le(out, 0x00084dd8);
1182     out_uint32_le(out, dwCount);
1183    
1184     for (i = 0, cur = rsArray, curState = stateArray; i < dwCount; i++, cur++, curState++)
1185     {
1186    
1187     cur->dwCurrentState = (*curState);
1188     cur->dwEventState |= (*curState) & 0xFFFF0000;
1189    
1190     #if 0
1191     if (mapped && (cur->dwCurrentState & SCARD_STATE_PRESENT)
1192     && (cur->dwCurrentState & SCARD_STATE_CHANGED)
1193     && (cur->dwEventState & SCARD_STATE_PRESENT)
1194     && (cur->dwEventState & SCARD_STATE_CHANGED))
1195     {
1196     cur->dwEventState |= SCARD_STATE_INUSE;
1197     }
1198     else if (cur->dwEventState & SCARD_STATE_UNKNOWN)
1199     {
1200     cur->dwEventState &= ~SCARD_STATE_UNKNOWN;
1201     cur->dwEventState |= SCARD_STATE_EMPTY;
1202     mapped = True;
1203     }
1204     else if ((!mapped) && (cur->dwEventState & SCARD_STATE_INUSE))
1205     {
1206     mapped = True;
1207     cur->dwEventState &= ~SCARD_STATE_INUSE;
1208     }
1209    
1210     cur->dwEventState = incStatus(cur->dwEventState, mapped);
1211     #endif
1212     cur->dwEventState = incStatus(cur->dwEventState, False);
1213    
1214     out_uint8p(out, (void *) ((unsigned char **) cur + 2),
1215     sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
1216     }
1217     outForceAllignment(out, 8);
1218     SC_xfreeallmemory(&lcHandle);
1219     return rv;
1220     }
1221    
1222     static MYPCSC_DWORD
1223     TS_SCardCancel(STREAM in, STREAM out)
1224     {
1225     MYPCSC_DWORD rv;
1226     SERVER_SCARDCONTEXT hContext;
1227    
1228     in->p += 0x1C;
1229     in_uint32_le(in, hContext);
1230     #ifdef WITH_SCARD_DEBUG
1231     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
1232     printf("Canceling... \n");
1233     #endif
1234     rv = SCardCancel((MYPCSC_SCARDCONTEXT) hContext);
1235     #ifdef WITH_SCARD_DEBUG
1236     if (rv != SCARD_S_SUCCESS)
1237     printf("<--ERROR SCardCancel Code=0x%.8x-->\n", (unsigned int) rv);
1238     else
1239     printf("<--SUCCESS SCardCancel-->\n");
1240     #endif
1241     outForceAllignment(out, 8);
1242     return rv;
1243     }
1244    
1245     static MYPCSC_DWORD
1246     TS_SCardLocateCardsByATR(STREAM in, STREAM out, BOOL wide)
1247     {
1248     int i, j, k;
1249     MYPCSC_DWORD rv;
1250     SERVER_SCARDCONTEXT hContext;
1251     /* The SCARD_ATRMASK_L struct doesn't contain any longs or DWORDs -
1252     no need to split into SERVER_ and MYPCSC_ */
1253     LPSCARD_ATRMASK_L pAtrMasks, cur;
1254     SERVER_DWORD atrMaskCount = 0;
1255     SERVER_DWORD readerCount = 0;
1256     SERVER_LPSCARD_READERSTATE_A rsArray, ResArray, rsCur;
1257     MYPCSC_LPSCARD_READERSTATE_A myRsArray;
1258     PMEM_HANDLE lcHandle = NULL;
1259    
1260     in->p += 0x2C;
1261     in_uint32_le(in, hContext);
1262     #ifdef WITH_SCARD_DEBUG
1263     printf("[CONTEXT 0x%.8x]\n", (unsigned int) hContext);
1264     #endif
1265     in_uint32_le(in, atrMaskCount);
1266     pAtrMasks = SC_xmalloc(&lcHandle, atrMaskCount * sizeof(SCARD_ATRMASK_L));
1267     if (!pAtrMasks)
1268     return SC_returnNoMemoryError(&lcHandle, in, out);
1269     in_uint8a(in, pAtrMasks, atrMaskCount * sizeof(SCARD_ATRMASK_L));
1270    
1271     in_uint32_le(in, readerCount);
1272     rsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SCARD_READERSTATE_A));
1273     if (!rsArray)
1274     return SC_returnNoMemoryError(&lcHandle, in, out);
1275     memset(rsArray, 0, readerCount * sizeof(SCARD_READERSTATE_A));
1276    
1277     for (i = 0, rsCur = (SERVER_LPSCARD_READERSTATE_A) ((unsigned char **) rsArray + 2);
1278     i < readerCount; i++, rsCur++)
1279     {
1280     in_uint8s(in, 4);
1281     in_uint8a(in, rsCur, SERVER_SCARDSTATESIZE);
1282     }
1283    
1284     ResArray = SC_xmalloc(&lcHandle, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
1285     if (!ResArray)
1286     return SC_returnNoMemoryError(&lcHandle, in, out);
1287     memcpy(ResArray, rsArray, readerCount * sizeof(SERVER_SCARD_READERSTATE_A));
1288    
1289     for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
1290     {
1291     inReaderName(&lcHandle, in, (char **) &rsCur->szReader, wide);
1292     #ifdef WITH_SCARD_DEBUG
1293     printf("[CHECK READER %s]\n", (rsCur->szReader) ? (rsCur->szReader) : ("NULL"));
1294     #endif
1295     }
1296    
1297     #ifdef WITH_SCARD_DEBUG
1298     printf("[CALL subfunction \"SCardGetStatusChange\"]\n");
1299     #endif
1300     /* FIXME segfault here. */
1301     myRsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(MYPCSC_SCARD_READERSTATE_A));
1302     if (!myRsArray)
1303     return SC_returnNoMemoryError(&lcHandle, in, out);
1304     rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, 0x00000001, myRsArray,
1305     readerCount);
1306     copyReaderState_MyPCSCToServer(myRsArray, rsArray, readerCount);
1307     if (rv != SCARD_S_SUCCESS)
1308     {
1309     #ifdef WITH_SCARD_DEBUG
1310     printf("<--ERROR SCardGetStatusChange (no SCardLocateCardsByATR) Code=0x%.8x-->\n",
1311     (unsigned int) rv);
1312     #endif
1313     }
1314     else
1315     {
1316     #ifdef WITH_SCARD_DEBUG
1317     printf("<--SUCCESS SCardGetStatusChange (no SCardLocateCardsByATR)-->\n");
1318     #endif
1319     cur = pAtrMasks;
1320     for (i = 0, cur = pAtrMasks; i < atrMaskCount; i++, cur++)
1321     {
1322     for (j = 0, rsCur = rsArray; j < readerCount; j++, rsCur++)
1323     {
1324     BOOL equal = 1;
1325     for (k = 0; k < cur->cbAtr; k++)
1326     {
1327     /* This line check if them equal */
1328     if (cur->rgbAtr[k] != rsCur->rgbAtr[k])
1329     /* Next Line was make to search with mask (some strange behavours with applications which use eToken SmartCards) */
1330     /* if((cur->rgbAtr[k]&cur->rgbMask[k])!=(rsCur->rgbAtr[k]&cur->rgbMask[k])){ */
1331     {
1332     equal = 0;
1333     break;
1334     }
1335     }
1336     if (equal)
1337     {
1338     #ifdef WITH_SCARD_DEBUG
1339     printf("[FOUND]\n");
1340     #endif
1341     rsCur->dwEventState |= 0x00000040; /* SCARD_STATE_ATRMATCH 0x00000040 */
1342     memcpy(ResArray + j, rsCur, sizeof(SCARD_READERSTATE_A));
1343     }
1344     }
1345     }
1346     }
1347    
1348     out_uint32_le(out, readerCount);
1349     out_uint32_le(out, 0x00084dd8);
1350     out_uint32_le(out, readerCount);
1351    
1352     for (i = 0, rsCur = rsArray; i < readerCount; i++, rsCur++)
1353     {
1354     out_uint8p(out, (void *) ((unsigned char **) rsCur + 2),
1355     sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *));
1356     }
1357    
1358     outForceAllignment(out, 8);
1359     SC_xfreeallmemory(&lcHandle);
1360     return rv;
1361     }
1362    
1363     static DWORD
1364     TS_SCardBeginTransaction(STREAM in, STREAM out)
1365     {
1366     MYPCSC_DWORD rv;
1367     SERVER_SCARDCONTEXT hCard;
1368     MYPCSC_SCARDCONTEXT myHCard;
1369    
1370     in->p += 0x30;
1371     in_uint32_le(in, hCard);
1372     myHCard = scHandleToMyPCSC(hCard);
1373     #ifdef WITH_SCARD_DEBUG
1374     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
1375 stargo 1313 printf("[myHCard = 0x%016lx]\n", (unsigned long) myHCard);
1376 stargo 1309 #endif
1377     rv = SCardBeginTransaction(myHCard);
1378     #ifdef WITH_SCARD_DEBUG
1379     if (rv != SCARD_S_SUCCESS)
1380     printf("<--ERROR SCardBeginTransaction Code=0x%.8x-->\n", (unsigned int) rv);
1381     else
1382     printf("<--SUCCESS SCardBeginTransaction-->\n");
1383     #endif
1384     outForceAllignment(out, 8);
1385     return rv;
1386     }
1387    
1388     static DWORD
1389     TS_SCardEndTransaction(STREAM in, STREAM out)
1390     {
1391     MYPCSC_DWORD rv;
1392     SERVER_SCARDCONTEXT hCard;
1393     MYPCSC_SCARDCONTEXT myHCard;
1394     SERVER_DWORD dwDisposition = 0;
1395    
1396     in->p += 0x20;
1397     in_uint32_le(in, dwDisposition);
1398     in->p += 0x0C;
1399     in_uint32_le(in, hCard);
1400     myHCard = scHandleToMyPCSC(hCard);
1401     #ifdef WITH_SCARD_DEBUG
1402     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
1403 stargo 1313 printf("[myHCard = 0x%016lx]\n", (unsigned long) myHCard);
1404 stargo 1309 printf("[dwDisposition = 0x%.8x]\n", (unsigned int) dwDisposition);
1405     #endif
1406     rv = SCardEndTransaction(myHCard, (MYPCSC_DWORD) dwDisposition);
1407     #ifdef WITH_SCARD_DEBUG
1408     if (rv != SCARD_S_SUCCESS)
1409     printf("<--ERROR SCardEndTransaction Code=0x%.8x-->\n", (unsigned int) rv);
1410     else
1411     printf("<--SUCCESS SCardEndTransaction-->\n");
1412     #endif
1413     outForceAllignment(out, 8);
1414     return rv;
1415     }
1416    
1417    
1418     static void
1419     copyIORequest_MyPCSCToServer(MYPCSC_LPSCARD_IO_REQUEST src, SERVER_LPSCARD_IO_REQUEST dst)
1420     {
1421     unsigned char *srcBytes, *dstBytes;
1422     size_t bytesToCopy = src->cbPciLength - sizeof(MYPCSC_SCARD_IO_REQUEST);
1423     srcBytes = ((unsigned char *) src + sizeof(MYPCSC_SCARD_IO_REQUEST));
1424     dstBytes = ((unsigned char *) dst + sizeof(SERVER_SCARD_IO_REQUEST));
1425     dst->dwProtocol = src->dwProtocol;
1426     dst->cbPciLength = src->cbPciLength
1427     - sizeof(MYPCSC_SCARD_IO_REQUEST) + sizeof(SERVER_SCARD_IO_REQUEST);
1428     memcpy(dstBytes, srcBytes, bytesToCopy);
1429     }
1430    
1431     static void
1432     copyIORequest_ServerToMyPCSC(SERVER_LPSCARD_IO_REQUEST src, MYPCSC_LPSCARD_IO_REQUEST dst)
1433     {
1434     unsigned char *srcBytes, *dstBytes;
1435     size_t bytesToCopy = src->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST);
1436     srcBytes = ((unsigned char *) src + sizeof(SERVER_SCARD_IO_REQUEST));
1437     dstBytes = ((unsigned char *) dst + sizeof(MYPCSC_SCARD_IO_REQUEST));
1438     dst->dwProtocol = src->dwProtocol;
1439     dst->cbPciLength = src->cbPciLength
1440     - sizeof(SERVER_SCARD_IO_REQUEST) + sizeof(MYPCSC_SCARD_IO_REQUEST);
1441     memcpy(dstBytes, srcBytes, bytesToCopy);
1442     }
1443    
1444    
1445     static DWORD
1446     TS_SCardTransmit(STREAM in, STREAM out)
1447     {
1448     MYPCSC_DWORD rv;
1449     SERVER_DWORD map[7], linkedLen;
1450     void *tmp;
1451     SERVER_SCARDCONTEXT hCard;
1452     MYPCSC_SCARDCONTEXT myHCard;
1453     SERVER_LPSCARD_IO_REQUEST pioSendPci, pioRecvPci;
1454     MYPCSC_LPSCARD_IO_REQUEST myPioSendPci, myPioRecvPci;
1455     unsigned char *sendBuf = NULL, *recvBuf = NULL;
1456     SERVER_DWORD cbSendLength, cbRecvLength;
1457     MYPCSC_DWORD myCbRecvLength;
1458     PMEM_HANDLE lcHandle = NULL;
1459    
1460     in->p += 0x14;
1461     in_uint32_le(in, map[0]);
1462     in->p += 0x04;
1463     in_uint32_le(in, map[1]);
1464     pioSendPci = SC_xmalloc(&lcHandle, sizeof(SERVER_SCARD_IO_REQUEST));
1465     if (!pioSendPci)
1466     return SC_returnNoMemoryError(&lcHandle, in, out);
1467     in_uint8a(in, pioSendPci, sizeof(SERVER_SCARD_IO_REQUEST));
1468     in_uint32_le(in, map[2]);
1469     in_uint32_le(in, cbSendLength);
1470     in_uint32_le(in, map[3]);
1471     in_uint32_le(in, map[4]);
1472     in_uint32_le(in, map[5]);
1473     in_uint32_le(in, cbRecvLength);
1474     if (map[0] & INPUT_LINKED)
1475     inSkipLinked(in);
1476    
1477     in->p += 0x04;
1478     in_uint32_le(in, hCard);
1479     myHCard = scHandleToMyPCSC(hCard);
1480    
1481     if (map[2] & INPUT_LINKED)
1482     {
1483     in_uint32_le(in, linkedLen);
1484     pioSendPci->cbPciLength = linkedLen + sizeof(SERVER_SCARD_IO_REQUEST);
1485     tmp = SC_xmalloc(&lcHandle, pioSendPci->cbPciLength);
1486     if (!tmp)
1487     return SC_returnNoMemoryError(&lcHandle, in, out);
1488     in_uint8a(in, (void *) ((unsigned char *) tmp + sizeof(SERVER_SCARD_IO_REQUEST)),
1489     linkedLen);
1490     memcpy(tmp, pioSendPci, sizeof(SERVER_SCARD_IO_REQUEST));
1491     SC_xfree(&lcHandle, pioSendPci);
1492     pioSendPci = tmp;
1493     tmp = NULL;
1494     }
1495     else
1496     pioSendPci->cbPciLength = sizeof(SERVER_SCARD_IO_REQUEST);
1497    
1498     if (map[3] & INPUT_LINKED)
1499     {
1500     in_uint32_le(in, linkedLen);
1501     sendBuf = SC_xmalloc(&lcHandle, linkedLen);
1502     if (!sendBuf)
1503     return SC_returnNoMemoryError(&lcHandle, in, out);
1504     in_uint8a(in, sendBuf, linkedLen);
1505     inRepos(in, linkedLen);
1506     }
1507     else
1508     sendBuf = NULL;
1509    
1510     if (cbRecvLength)
1511     {
1512     /* FIXME: handle responses with length > 448 bytes */
1513     if (cbRecvLength > 448)
1514     {
1515     #ifdef WITH_SCARD_DEBUG
1516     printf("[RECV LEN %d -> %d]\n", (unsigned int) cbRecvLength, 400);
1517     #endif
1518     cbRecvLength = 448;
1519     }
1520    
1521    
1522     recvBuf = SC_xmalloc(&lcHandle, cbRecvLength);
1523     if (!recvBuf)
1524     return SC_returnNoMemoryError(&lcHandle, in, out);
1525     }
1526    
1527     if (map[4] & INPUT_LINKED)
1528     {
1529     pioRecvPci = SC_xmalloc(&lcHandle, sizeof(SERVER_SCARD_IO_REQUEST));
1530     if (!pioRecvPci)
1531     return SC_returnNoMemoryError(&lcHandle, in, out);
1532     in_uint8a(in, pioRecvPci, sizeof(SERVER_SCARD_IO_REQUEST));
1533     in_uint32_le(in, map[6]);
1534     if (map[6] & INPUT_LINKED)
1535     {
1536     in_uint32_le(in, linkedLen);
1537     pioRecvPci->cbPciLength = linkedLen + sizeof(SERVER_SCARD_IO_REQUEST);
1538     tmp = SC_xmalloc(&lcHandle, pioRecvPci->cbPciLength);
1539     if (!tmp)
1540     return SC_returnNoMemoryError(&lcHandle, in, out);
1541     in_uint8a(in,
1542     (void *) ((unsigned char *) tmp +
1543     sizeof(SERVER_SCARD_IO_REQUEST)), linkedLen);
1544     memcpy(tmp, pioRecvPci, sizeof(SERVER_SCARD_IO_REQUEST));
1545     SC_xfree(&lcHandle, pioRecvPci);
1546     pioRecvPci = tmp;
1547     tmp = NULL;
1548     }
1549     else
1550     pioRecvPci->cbPciLength = sizeof(SERVER_SCARD_IO_REQUEST);
1551     }
1552     else
1553     pioRecvPci = NULL;
1554    
1555     #ifdef WITH_SCARD_DEBUG
1556     printf("++++++++++\n");
1557     printf("[SEND LEN = %d]\n", (unsigned int) cbSendLength);
1558     printf("[RECV LEN = %d]\n", (unsigned int) cbRecvLength);
1559     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
1560 stargo 1313 printf("[myHCard = 0x%016lx]\n", (unsigned long) myHCard);
1561 stargo 1309 printf("[pioSendPci]\n");
1562     if (pioSendPci == NULL)
1563     printf("NULL\n");
1564     else
1565     hexdump((void *) pioSendPci, pioSendPci->cbPciLength);
1566     printf("[pioRecvPci]\n");
1567     if (pioRecvPci == NULL)
1568     printf("NULL\n");
1569     else
1570     hexdump((void *) pioRecvPci, pioRecvPci->cbPciLength);
1571     printf("[sendBuf]\n");
1572     hexdump(sendBuf, cbSendLength);
1573     printf("++++++++++\n");
1574     #endif
1575    
1576     myCbRecvLength = cbRecvLength;
1577     myPioSendPci = SC_xmalloc(&lcHandle,
1578     sizeof(MYPCSC_SCARD_IO_REQUEST)
1579     + pioSendPci->cbPciLength - sizeof(SERVER_SCARD_IO_REQUEST));
1580     if (!myPioSendPci)
1581     return SC_returnNoMemoryError(&lcHandle, in, out);
1582     copyIORequest_ServerToMyPCSC(pioSendPci, myPioSendPci);
1583     /* always a send, not always a recv */
1584     if (pioRecvPci)
1585     {
1586     myPioRecvPci = SC_xmalloc(&lcHandle,
1587     sizeof(MYPCSC_SCARD_IO_REQUEST)
1588     + pioRecvPci->cbPciLength
1589     - sizeof(SERVER_SCARD_IO_REQUEST));
1590     if (!myPioRecvPci)
1591     return SC_returnNoMemoryError(&lcHandle, in, out);
1592     copyIORequest_ServerToMyPCSC(pioRecvPci, myPioRecvPci);
1593     }
1594     else
1595     {
1596     myPioRecvPci = NULL;
1597     }
1598     rv = SCardTransmit(myHCard, myPioSendPci, sendBuf, (MYPCSC_DWORD) cbSendLength,
1599     myPioRecvPci, recvBuf, &myCbRecvLength);
1600     cbRecvLength = myCbRecvLength;
1601     if (pioRecvPci)
1602     {
1603     copyIORequest_MyPCSCToServer(myPioRecvPci, pioRecvPci);
1604     }
1605    
1606     if (rv != SCARD_S_SUCCESS)
1607     {
1608     #ifdef WITH_SCARD_DEBUG
1609     printf("<--ERROR SCardTransmit Code=0x%.8x-->\n", (unsigned int) rv);
1610     #endif
1611     }
1612     else
1613     {
1614     #ifdef WITH_SCARD_DEBUG
1615     printf("<--SUCCESS SCardTransmit-->\n");
1616     printf("RESULT %d\n", (unsigned int) cbRecvLength);
1617     hexdump(recvBuf, cbRecvLength);
1618     if (myPioRecvPci)
1619     {
1620     printf("--- myPioRecvPci ---\n");
1621     hexdump((void *) myPioRecvPci, myPioRecvPci->cbPciLength);
1622     }
1623     printf("------------------\n");
1624     #endif
1625     #if 0
1626     if ((pioRecvPci != NULL) && (pioRecvPci->cbPciLength > 0))
1627     {
1628     out_uint32_le(out, (DWORD) pioRecvPci); /* if not NULL, this 4 bytes indicates that pioRecvPci is present */
1629     }
1630     else
1631     #endif
1632     out_uint32_le(out, 0); /* pioRecvPci 0x00; */
1633    
1634     outBufferStart(out, cbRecvLength); /* start of recvBuf output */
1635    
1636     #if 0
1637     if ((pioRecvPci) && (pioRecvPci->cbPciLength > 0))
1638     {
1639     out_uint32_le(out, pioRecvPci->dwProtocol);
1640     int len = pioRecvPci->cbPciLength - sizeof(pioRecvPci);
1641     outBufferStartWithLimit(out, len, 12);
1642     outBufferFinishWithLimit(out,
1643     (char *) ((DWORD) pioRecvPci + sizeof(pioRecvPci)),
1644     len, 12);
1645     }
1646     #endif
1647    
1648     outBufferFinish(out, (char *) recvBuf, cbRecvLength);
1649     }
1650     outForceAllignment(out, 8);
1651     SC_xfreeallmemory(&lcHandle);
1652     return rv;
1653     }
1654    
1655     static MYPCSC_DWORD
1656     TS_SCardStatus(STREAM in, STREAM out, BOOL wide)
1657     {
1658     MYPCSC_DWORD rv;
1659     SERVER_SCARDCONTEXT hCard;
1660     MYPCSC_SCARDCONTEXT myHCard;
1661     SERVER_DWORD dwState = 0, dwProtocol = 0, dwReaderLen, dwAtrLen;
1662     MYPCSC_DWORD state, protocol, readerLen, atrLen;
1663     SERVER_DWORD dataLength;
1664     PMEM_HANDLE lcHandle = NULL;
1665     char *readerName;
1666     unsigned char *atr;
1667    
1668     in->p += 0x24;
1669     in_uint32_le(in, dwReaderLen);
1670     in_uint32_le(in, dwAtrLen);
1671     in->p += 0x0C;
1672     in_uint32_le(in, hCard);
1673     in->p += 0x04;
1674     myHCard = scHandleToMyPCSC(hCard);
1675     #ifdef WITH_SCARD_DEBUG
1676     printf("[hCard 0x%.8x]\n", (unsigned int) hCard);
1677 stargo 1313 printf("[myHCard 0x%016lx]\n", (unsigned long) myHCard);
1678 stargo 1309 printf("[dwReaderLen %d]\n", (unsigned int) dwReaderLen);
1679     printf("[dwAtrLen %d]\n", (unsigned int) dwAtrLen);
1680     #endif
1681    
1682     if (dwReaderLen <= 0 || dwReaderLen == SCARD_AUTOALLOCATE || dwReaderLen > SCARD_MAX_MEM)
1683     dwReaderLen = SCARD_MAX_MEM;
1684     if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM)
1685     dwAtrLen = SCARD_MAX_MEM;
1686    
1687     readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2);
1688     if (!readerName)
1689     return SC_returnNoMemoryError(&lcHandle, in, out);
1690    
1691     atr = SC_xmalloc(&lcHandle, dwAtrLen + 1);
1692     if (!atr)
1693     return SC_returnNoMemoryError(&lcHandle, in, out);
1694    
1695     state = dwState;
1696     protocol = dwProtocol;
1697     readerLen = dwReaderLen;
1698     atrLen = dwAtrLen;
1699     rv = SCardStatus(myHCard, readerName, &readerLen, &state, &protocol, atr, &atrLen);
1700     dwAtrLen = atrLen;
1701     dwReaderLen = readerLen;
1702     dwProtocol = protocol;
1703     dwState = state;
1704    
1705    
1706     if (rv != SCARD_S_SUCCESS)
1707     {
1708     #ifdef WITH_SCARD_DEBUG
1709     printf("<--ERROR SCardStatus Code=0x%.8x-->\n", (unsigned int) rv);
1710     #endif
1711     return SC_returnCode(rv, &lcHandle, in, out);
1712     }
1713     else
1714     {
1715     #ifdef WITH_SCARD_DEBUG
1716     printf("<--SUCCESS SCardStatus-->\n");
1717     printf("[dwState 0x%.8x]\n", (unsigned int) dwState);
1718     printf("[dwProtocol 0x%.8x]\n", (unsigned int) dwProtocol);
1719     printf("[Reader Name]\n");
1720     hexdump((unsigned char *) readerName, dwReaderLen);
1721     printf("[Atr]\n");
1722     hexdump(atr, dwAtrLen);
1723     #endif
1724     if (dwState & (SCARD_SPECIFIC | SCARD_NEGOTIABLE))
1725     dwState = 0x00000006;
1726     else
1727     #if 0
1728     if (dwState & SCARD_SPECIFIC)
1729     dwState = 0x00000006;
1730     else if (dwState & SCARD_NEGOTIABLE)
1731     dwState = 0x00000005;
1732     else
1733     #endif
1734     if (dwState & SCARD_POWERED)
1735     dwState = 0x00000004;
1736     else if (dwState & SCARD_SWALLOWED)
1737     dwState = 0x00000003;
1738     else if (dwState & SCARD_PRESENT)
1739     dwState = 0x00000002;
1740     else if (dwState & SCARD_ABSENT)
1741     dwState = 0x00000001;
1742     else
1743     dwState = 0x00000000;
1744    
1745     void *p_len1 = out->p;
1746     out_uint32_le(out, dwReaderLen);
1747     out_uint32_le(out, 0x00020000);
1748     out_uint32_le(out, dwState);
1749     out_uint32_le(out, dwProtocol);
1750     out_uint8p(out, atr, dwAtrLen);
1751     if (dwAtrLen < 32)
1752     {
1753     out_uint8s(out, 32 - dwAtrLen);
1754     }
1755     out_uint32_le(out, dwAtrLen);
1756    
1757     void *p_len2 = out->p;
1758     out_uint32_le(out, dwReaderLen);
1759     dataLength = outString(out, readerName, wide);
1760     dataLength += outString(out, "\0", wide);
1761     outRepos(out, dataLength);
1762     void *psave = out->p;
1763     out->p = p_len1;
1764     out_uint32_le(out, dataLength);
1765     out->p = p_len2;
1766     out_uint32_le(out, dataLength);
1767     out->p = psave;
1768     }
1769     outForceAllignment(out, 8);
1770     SC_xfreeallmemory(&lcHandle);
1771     return rv;
1772     }
1773    
1774     static MYPCSC_DWORD
1775     TS_SCardState(STREAM in, STREAM out)
1776     {
1777     MYPCSC_DWORD rv;
1778     SERVER_SCARDCONTEXT hCard;
1779     MYPCSC_SCARDCONTEXT myHCard;
1780     SERVER_DWORD dwState = 0, dwProtocol = 0, dwReaderLen, dwAtrLen;
1781     MYPCSC_DWORD state, protocol, readerLen, atrLen;
1782     PMEM_HANDLE lcHandle = NULL;
1783     char *readerName;
1784     unsigned char *atr;
1785    
1786     in->p += 0x24;
1787     in_uint32_le(in, dwAtrLen);
1788     in->p += 0x0C;
1789     in_uint32_le(in, hCard);
1790     in->p += 0x04;
1791     myHCard = scHandleToMyPCSC(hCard);
1792     #ifdef WITH_SCARD_DEBUG
1793     printf("[hCard 0x%.8x]\n", (unsigned int) hCard);
1794     printf("[myHCard 0x%.8x]\n", (unsigned int) myHCard);
1795     printf("[dwAtrLen %d]\n", (unsigned int) dwAtrLen);
1796     #endif
1797    
1798    
1799     dwReaderLen = SCARD_MAX_MEM;
1800     if (dwAtrLen <= 0 || dwAtrLen == SCARD_AUTOALLOCATE || dwAtrLen > SCARD_MAX_MEM)
1801     dwAtrLen = SCARD_MAX_MEM;
1802    
1803     readerName = SC_xmalloc(&lcHandle, dwReaderLen + 2);
1804     if (!readerName)
1805     return SC_returnNoMemoryError(&lcHandle, in, out);
1806    
1807     atr = SC_xmalloc(&lcHandle, dwAtrLen + 1);
1808     if (!atr)
1809     return SC_returnNoMemoryError(&lcHandle, in, out);
1810    
1811     state = dwState;
1812     protocol = dwProtocol;
1813     readerLen = dwReaderLen;
1814     atrLen = dwAtrLen;
1815     rv = SCardStatus(myHCard, readerName, &readerLen, &state, &protocol, atr, &atrLen);
1816     dwAtrLen = atrLen;
1817     dwReaderLen = readerLen;
1818     dwProtocol = protocol;
1819     dwState = state;
1820    
1821     if (rv != SCARD_S_SUCCESS)
1822     {
1823     #ifdef WITH_SCARD_DEBUG
1824     printf("<--ERROR SCardStatus (no ScardState) Code=0x%.8x-->\n", (unsigned int) rv);
1825     #endif
1826     return SC_returnCode(rv, &lcHandle, in, out);
1827     }
1828     else
1829     {
1830     #ifdef WITH_SCARD_DEBUG
1831     printf("<--SUCCESS SCardStatus (no ScardState)-->\n");
1832     printf("[dwState 0x%.8x]\n", (unsigned int) dwState);
1833     printf("[dwProtocol 0x%.8x]\n", (unsigned int) dwProtocol);
1834     printf("[Atr]\n");
1835     hexdump(atr, dwAtrLen);
1836     #endif
1837     if (dwState & (SCARD_SPECIFIC | SCARD_NEGOTIABLE))
1838     dwState = 0x00000006;
1839     else
1840     #if 0
1841     if (dwState & SCARD_SPECIFIC)
1842     dwState = 0x00000006;
1843     else if (dwState & SCARD_NEGOTIABLE)
1844     dwState = 0x00000005;
1845     else
1846     #endif
1847     if (dwState & SCARD_POWERED)
1848     dwState = 0x00000004;
1849     else if (dwState & SCARD_SWALLOWED)
1850     dwState = 0x00000003;
1851     else if (dwState & SCARD_PRESENT)
1852     dwState = 0x00000002;
1853     else if (dwState & SCARD_ABSENT)
1854     dwState = 0x00000001;
1855     else
1856     dwState = 0x00000000;
1857    
1858     out_uint32_le(out, dwState);
1859     out_uint32_le(out, dwProtocol);
1860     out_uint32_le(out, dwAtrLen);
1861     out_uint32_le(out, 0x00000001);
1862     out_uint32_le(out, dwAtrLen);
1863     out_uint8p(out, atr, dwAtrLen);
1864     outRepos(out, dwAtrLen);
1865     }
1866     outForceAllignment(out, 8);
1867     SC_xfreeallmemory(&lcHandle);
1868     return rv;
1869     }
1870    
1871    
1872    
1873     #ifndef WITH_PCSC120
1874    
1875     static MYPCSC_DWORD
1876     TS_SCardListReaderGroups(STREAM in, STREAM out)
1877     {
1878     MYPCSC_DWORD rv;
1879     SERVER_SCARDCONTEXT hContext;
1880     SERVER_DWORD dwGroups;
1881     MYPCSC_DWORD groups;
1882     char *szGroups;
1883     PMEM_HANDLE lcHandle = NULL;
1884    
1885     in->p += 0x20;
1886     in_uint32_le(in, dwGroups);
1887     in->p += 0x04;
1888     in_uint32_le(in, hContext);
1889    
1890     if (dwGroups <= 0 || dwGroups == SCARD_AUTOALLOCATE || dwGroups > SCARD_MAX_MEM)
1891     dwGroups = SCARD_MAX_MEM;
1892    
1893     szGroups = SC_xmalloc(&lcHandle, dwGroups);
1894     if (!szGroups)
1895     return SC_returnNoMemoryError(&lcHandle, in, out);
1896    
1897     groups = dwGroups;
1898     rv = SCardListReaderGroups((MYPCSC_SCARDCONTEXT) hContext, szGroups, &groups);
1899     dwGroups = groups;
1900    
1901     if (rv)
1902     #ifdef WITH_SCARD_DEBUG
1903     {
1904     printf("<--ERROR SCardListReaderGroups Code=0x%.8x-->\n", (unsigned int) rv);
1905     #endif
1906     return SC_returnCode(rv, &lcHandle, in, out);
1907     #ifdef WITH_SCARD_DEBUG
1908     }
1909     else
1910     {
1911     printf("<--SUCCESS SCardListReaderGroups-->\n");
1912     }
1913     #endif
1914    
1915    
1916     out_uint32_le(out, dwGroups);
1917     out_uint32_le(out, 0x00200000);
1918     out_uint32_le(out, dwGroups);
1919     out_uint8a(out, szGroups, dwGroups);
1920     outRepos(out, dwGroups);
1921     out_uint32_le(out, 0x00000000);
1922    
1923     outForceAllignment(out, 8);
1924     SC_xfreeallmemory(&lcHandle);
1925     return rv;
1926     }
1927    
1928     static MYPCSC_DWORD
1929     TS_SCardGetAttrib(STREAM in, STREAM out)
1930     {
1931     MYPCSC_DWORD rv;
1932     SERVER_SCARDCONTEXT hCard;
1933     MYPCSC_SCARDCONTEXT myHCard;
1934     SERVER_DWORD dwAttrId, dwAttrLen;
1935     MYPCSC_DWORD attrLen;
1936     unsigned char *pbAttr;
1937     PMEM_HANDLE lcHandle = NULL;
1938    
1939     in->p += 0x20;
1940     in_uint32_le(in, dwAttrId);
1941     in->p += 0x04;
1942     in_uint32_le(in, dwAttrLen);
1943     in->p += 0x0C;
1944     in_uint32_le(in, hCard);
1945     myHCard = scHandleToMyPCSC(hCard);
1946    
1947     dwAttrId = dwAttrId & 0x0000FFFF;
1948    
1949     #ifdef WITH_SCARD_DEBUG
1950     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
1951     printf("[myHCard 0x%.8x]\n", (unsigned int) myHCard);
1952     printf("[dwAttrId = 0x%.8x]\n", (unsigned int) dwAttrId);
1953     printf("[dwAttrLen = 0x%.8x]\n", (unsigned int) dwAttrLen);
1954     #endif
1955    
1956     if (dwAttrLen > MAX_BUFFER_SIZE)
1957     dwAttrLen = MAX_BUFFER_SIZE;
1958    
1959    
1960     if (dwAttrLen > SCARD_AUTOALLOCATE)
1961     pbAttr = NULL;
1962     else if ((dwAttrLen < 0) || (dwAttrLen > SCARD_MAX_MEM))
1963     {
1964     dwAttrLen = SCARD_AUTOALLOCATE;
1965     pbAttr = NULL;
1966     }
1967     else
1968     {
1969     pbAttr = SC_xmalloc(&lcHandle, dwAttrLen);
1970     if (!pbAttr)
1971     return SC_returnNoMemoryError(&lcHandle, in, out);
1972     }
1973    
1974     attrLen = dwAttrLen;
1975     rv = SCardGetAttrib(myHCard, (MYPCSC_DWORD) dwAttrId, pbAttr, &attrLen);
1976     dwAttrLen = attrLen;
1977    
1978     if (dwAttrId == 0x00000100 && rv != SCARD_S_SUCCESS)
1979     {
1980     #ifdef WITH_SCARD_DEBUG
1981     printf("Get Attribute ATTR_VENDOR_NAME\n");
1982     #endif
1983     pthread_mutex_lock(&hcardAccess);
1984     PSCHCardRec hcard = hcardFirst;
1985     while (hcard)
1986     {
1987     if (hcard->hCard == hCard)
1988     {
1989     dwAttrLen = strlen(hcard->vendor);
1990     memcpy(pbAttr, hcard->vendor, dwAttrLen);
1991     rv = SCARD_S_SUCCESS;
1992     break;
1993     }
1994     hcard = hcard->next;
1995     }
1996     pthread_mutex_unlock(&hcardAccess);
1997     #ifdef WITH_SCARD_DEBUG
1998     printf("[0x%.8x]\n", (unsigned int) rv);
1999     #endif
2000     }
2001    
2002     if (rv != SCARD_S_SUCCESS)
2003     {
2004     #ifdef WITH_SCARD_DEBUG
2005     printf("<--ERROR SCardGetAttrib Code=0x%.8x-->\n", (unsigned int) rv);
2006     #endif
2007     return SC_returnCode(rv, &lcHandle, in, out);
2008     }
2009     else
2010     {
2011     #ifdef WITH_SCARD_DEBUG
2012     printf("<--SUCCESS SCardGetAttrib-->\n");
2013     printf("[LENGTH %d]\n", (unsigned int) dwAttrLen);
2014     printf("+++++++++++++++++++++\n");
2015     hexdump(pbAttr, dwAttrLen);
2016     printf("+++++++++++++++++++++\n");
2017     #endif
2018     out_uint32_le(out, dwAttrLen);
2019     out_uint32_le(out, 0x00000200);
2020     out_uint32_le(out, dwAttrLen);
2021     if (!pbAttr)
2022     {
2023     out_uint8s(out, dwAttrLen);
2024     }
2025     else
2026     {
2027     out_uint8p(out, pbAttr, dwAttrLen);
2028     }
2029     outRepos(out, dwAttrLen);
2030     out_uint32_le(out, 0x00000000);
2031     }
2032     outForceAllignment(out, 8);
2033     return rv;
2034     }
2035    
2036     static MYPCSC_DWORD
2037     TS_SCardSetAttrib(STREAM in, STREAM out)
2038     {
2039     MYPCSC_DWORD rv;
2040     SERVER_SCARDCONTEXT hCard;
2041     MYPCSC_SCARDCONTEXT myHCard;
2042     SERVER_DWORD dwAttrId;
2043     SERVER_DWORD dwAttrLen;
2044     unsigned char *pbAttr;
2045     PMEM_HANDLE lcHandle = NULL;
2046    
2047     in->p += 0x20;
2048     in_uint32_le(in, dwAttrId);
2049     in->p += 0x04;
2050     in_uint32_le(in, dwAttrLen);
2051     in->p += 0x0C;
2052     in_uint32_le(in, hCard);
2053     myHCard = scHandleToMyPCSC(hCard);
2054    
2055     dwAttrId = dwAttrId & 0x0000FFFF;
2056    
2057     #ifdef WITH_SCARD_DEBUG
2058     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
2059     printf("[myHCard 0x%.8x]\n", (unsigned int) myHCard);
2060     printf("[dwAttrId = 0x%.8x]\n", (unsigned int) dwAttrId);
2061     printf("[dwAttrLen = 0x%.8x]\n", (unsigned int) dwAttrLen);
2062     #endif
2063    
2064     if (dwAttrLen > MAX_BUFFER_SIZE)
2065     dwAttrLen = MAX_BUFFER_SIZE;
2066    
2067     pbAttr = SC_xmalloc(&lcHandle, dwAttrLen);
2068     if (!pbAttr)
2069     return SC_returnNoMemoryError(&lcHandle, in, out);
2070    
2071     in_uint8a(in, pbAttr, dwAttrLen);
2072     rv = SCardSetAttrib(myHCard, (MYPCSC_DWORD) dwAttrId, pbAttr, (MYPCSC_DWORD) dwAttrLen);
2073    
2074     #ifdef WITH_SCARD_DEBUG
2075     if (rv)
2076     printf("<--ERROR SCardSetAttrib Code=0x%.8x-->\n", (unsigned int) rv);
2077     else
2078     printf("<--SUCCESS SCardSetAttrib-->\n");
2079     #endif
2080     out_uint32_le(out, 0x00000000);
2081     out_uint32_le(out, 0x00000200);
2082     out_uint32_le(out, 0x00000000);
2083     out_uint32_le(out, 0x00000000);
2084     outForceAllignment(out, 8);
2085     SC_xfreeallmemory(&lcHandle);
2086     return rv;
2087     }
2088    
2089     #endif
2090    
2091     static MYPCSC_DWORD
2092     TS_SCardControl(STREAM in, STREAM out)
2093     {
2094     MYPCSC_DWORD rv;
2095     SERVER_SCARDCONTEXT hContext;
2096     SERVER_SCARDHANDLE hCard;
2097     MYPCSC_SCARDHANDLE myHCard;
2098     SERVER_DWORD map[3];
2099     SERVER_DWORD dwControlCode;
2100 stargo 1311 unsigned char *pInBuffer, *pOutBuffer;
2101 stargo 1309 SERVER_DWORD nInBufferSize, nOutBufferSize, nOutBufferRealSize, nBytesReturned;
2102     MYPCSC_DWORD sc_nBytesReturned;
2103     PMEM_HANDLE lcHandle = NULL;
2104    
2105     pInBuffer = NULL;
2106     pOutBuffer = NULL;
2107    
2108     in->p += 0x14;
2109     in_uint32_le(in, map[0]);
2110     in->p += 0x04;
2111     in_uint32_le(in, map[1]);
2112     in_uint32_le(in, dwControlCode);
2113     in_uint32_le(in, nInBufferSize);
2114     in_uint32_le(in, map[2]);
2115     in->p += 0x04;
2116     in_uint32_le(in, nOutBufferSize);
2117     in->p += 0x04;
2118     in_uint32_le(in, hContext);
2119     in->p += 0x04;
2120     in_uint32_le(in, hCard);
2121     if (map[2] & INPUT_LINKED)
2122     {
2123     /* read real input size */
2124     in_uint32_le(in, nInBufferSize);
2125     pInBuffer = SC_xmalloc(&lcHandle, nInBufferSize);
2126     if (!pInBuffer)
2127     return SC_returnNoMemoryError(&lcHandle, in, out);
2128     in_uint8a(in, pInBuffer, nInBufferSize);
2129     }
2130    
2131     #if 0
2132     if (nOutBufferSize > 0)
2133     {
2134     nOutBufferRealSize = nOutBufferSize;
2135     }
2136     else
2137     #endif
2138     nOutBufferRealSize = 1024;
2139    
2140     nBytesReturned = nOutBufferRealSize;
2141    
2142     nBytesReturned = nOutBufferRealSize;
2143     pOutBuffer = SC_xmalloc(&lcHandle, nOutBufferRealSize);
2144     if (!pOutBuffer)
2145     return SC_returnNoMemoryError(&lcHandle, in, out);
2146    
2147     #ifdef WITH_SCARD_DEBUG
2148     printf("[hContext = 0x%.8x]\n", (unsigned int) hContext);
2149     printf("[hCard = 0x%.8x]\n", (unsigned int) hCard);
2150     printf("[dwControlCode = 0x%.8x]\n", (unsigned int) dwControlCode);
2151     printf("[nInBufferSize = %d]\n", (unsigned int) nInBufferSize);
2152     printf("[nOutBufferSize = %d]\n", (unsigned int) nOutBufferSize);
2153     if (nInBufferSize > 0)
2154     {
2155     printf("[In buffer]\n");
2156     hexdump((unsigned char *) pInBuffer, nInBufferSize);
2157     }
2158     printf("---> Calling SCardControl\n");
2159     #endif
2160    
2161     sc_nBytesReturned = nBytesReturned;
2162     myHCard = scHandleToMyPCSC(hCard);
2163 stargo 1316 #ifdef WITH_PCSC120
2164 stargo 1309 rv = SCardControl(myHCard, pInBuffer, (MYPCSC_DWORD) nInBufferSize, pOutBuffer,
2165     &sc_nBytesReturned);
2166     #else
2167     rv = SCardControl(myHCard, (MYPCSC_DWORD) dwControlCode, pInBuffer,
2168     (MYPCSC_DWORD) nInBufferSize, pOutBuffer,
2169     (MYPCSC_DWORD) nOutBufferRealSize, &sc_nBytesReturned);
2170 stargo 1316 #endif
2171 stargo 1309 nBytesReturned = sc_nBytesReturned;
2172    
2173     #ifdef WITH_SCARD_DEBUG
2174     if (rv != SCARD_S_SUCCESS)
2175     printf("<--ERROR SCardControl Code=0x%.8x-->\n", (unsigned int) rv);
2176     else
2177     {
2178     printf("<--SUCCESS SCardControl-->\n");
2179     printf("[LENGTH %d]\n", (unsigned int) nBytesReturned);
2180     printf("+++++++++++++++++++++\n");
2181     hexdump((unsigned char *) pOutBuffer, nBytesReturned);
2182     printf("+++++++++++++++++++++\n");
2183     }
2184     #endif
2185    
2186     out_uint32_le(out, nBytesReturned);
2187     out_uint32_le(out, 0x00000004);
2188     out_uint32_le(out, nBytesReturned);
2189     if (nBytesReturned > 0)
2190     {
2191     out_uint8p(out, pOutBuffer, nBytesReturned);
2192     outRepos(out, nBytesReturned);
2193     }
2194    
2195     outForceAllignment(out, 8);
2196     SC_xfreeallmemory(&lcHandle);
2197     return rv;
2198     }
2199    
2200     static MYPCSC_DWORD
2201     TS_SCardAccessStartedEvent(STREAM in, STREAM out)
2202     {
2203     out_uint8s(out, 8);
2204     return SCARD_S_SUCCESS;
2205     }
2206    
2207    
2208     static NTSTATUS
2209     scard_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2210     {
2211     SERVER_DWORD Result = 0x00000000;
2212     unsigned char *psize, *pend, *pStatusCode;
2213     SERVER_DWORD addToEnd = 0;
2214    
2215     #ifdef WITH_SCARD_DEBUG
2216     unsigned char *pbeg = out->p;
2217     printf("--------------------------------\n");
2218     printf("[NTHANDLE %08X]\n", handle);
2219     printf("[REQUEST %08X]\n", request);
2220     printf("[INPUT DUMP]--------------------\n");
2221     hexdump(in->p, in->end - in->p);
2222     #endif
2223     /* Processing request */
2224    
2225     out_uint32_le(out, 0x00081001); /* Header lines */
2226     out_uint32_le(out, 0xCCCCCCCC);
2227     psize = out->p;
2228     out_uint32_le(out, 0x00000000); /* Size of data portion */
2229     out_uint32_le(out, 0x00000000); /* Zero bytes (may be usefull) */
2230     pStatusCode = out->p;
2231     out_uint32_le(out, 0x00000000); /* Status Code */
2232    
2233     switch (request)
2234     {
2235     /* SCardEstablishContext */
2236     case SC_ESTABLISH_CONTEXT:
2237     {
2238     #ifdef WITH_SCARD_DEBUG
2239     printf("<---SCardEstablishContext--->\n");
2240     #endif
2241     Result = (SERVER_DWORD) TS_SCardEstablishContext(in, out);
2242     break;
2243     }
2244     /* SCardReleaseContext */
2245     case SC_RELEASE_CONTEXT:
2246     {
2247     #ifdef WITH_SCARD_DEBUG
2248     printf("<---SCardReleaseContext--->\n");
2249     #endif
2250     Result = (SERVER_DWORD) TS_SCardReleaseContext(in, out);
2251     break;
2252     }
2253     /* SCardIsValidContext */
2254     case SC_IS_VALID_CONTEXT:
2255     {
2256     #ifdef WITH_SCARD_DEBUG
2257     printf("<---SCardIsValidContext--->\n");
2258     #endif
2259     Result = (SERVER_DWORD) TS_SCardIsValidContext(in, out);
2260     break;
2261     }
2262     /* SCardListReaders */
2263     case SC_LIST_READERS: /* SCardListReadersA */
2264     case SC_LIST_READERS + 4: /* SCardListReadersW */
2265     {
2266     BOOL wide = request != SC_LIST_READERS;
2267     #ifdef WITH_SCARD_DEBUG
2268     printf("<---SCardListReaders---> (%s)\n",
2269     (wide) ? ("WIDE") : ("ASCII"));
2270     #endif
2271     Result = (SERVER_DWORD) TS_SCardListReaders(in, out, wide);
2272     break;
2273     }
2274     /* ScardConnect */
2275     case SC_CONNECT: /* ScardConnectA */
2276     case SC_CONNECT + 4: /* SCardConnectW */
2277     {
2278     BOOL wide = request != SC_CONNECT;
2279     #ifdef WITH_SCARD_DEBUG
2280     printf("<---SCardConnect---> (%s)\n",
2281     (wide) ? ("WIDE") : ("ASCII"));
2282     #endif
2283     Result = (SERVER_DWORD) TS_SCardConnect(in, out, wide);
2284     break;
2285     }
2286     /* ScardReconnect */
2287     case SC_RECONNECT:
2288     {
2289     #ifdef WITH_SCARD_DEBUG
2290     printf("<---SCardReconnect--->\n");
2291     #endif
2292     Result = (SERVER_DWORD) TS_SCardReconnect(in, out);
2293     break;
2294     }
2295     /* ScardDisconnect */
2296     case SC_DISCONNECT:
2297     {
2298     #ifdef WITH_SCARD_DEBUG
2299     printf("<---SCardDisconnect--->\n");
2300     #endif
2301     Result = (SERVER_DWORD) TS_SCardDisconnect(in, out);
2302     break;
2303     }
2304     /* ScardGetStatusChange */
2305     case SC_GET_STATUS_CHANGE: /* SCardGetStatusChangeA */
2306     case SC_GET_STATUS_CHANGE + 4: /* SCardGetStatusChangeW */
2307     {
2308     BOOL wide = request != SC_GET_STATUS_CHANGE;
2309     #ifdef WITH_SCARD_DEBUG
2310     printf("<---SCardGetStatusChange---> (%s)\n",
2311     (wide) ? ("WIDE") : ("ASCII"));
2312     #endif
2313     Result = (SERVER_DWORD) TS_SCardGetStatusChange(in, out, wide);
2314     break;
2315     }
2316     /* SCardCancel */
2317     case SC_CANCEL:
2318     {
2319     #ifdef WITH_SCARD_DEBUG
2320     printf("<---SCardCancel--->\n");
2321     #endif
2322     Result = (SERVER_DWORD) TS_SCardCancel(in, out);
2323     break;
2324     }
2325     /* SCardLocateCardsByATR */
2326     case SC_LOCATE_CARDS_BY_ATR: /* SCardLocateCardsByATRA */
2327     case SC_LOCATE_CARDS_BY_ATR + 4: /* SCardLocateCardsByATRW */
2328     {
2329     BOOL wide = request != SC_LOCATE_CARDS_BY_ATR;
2330     #ifdef WITH_SCARD_DEBUG
2331     printf("<---SCardLocateCardsByATR---> (%s)\n",
2332     (wide) ? ("WIDE") : ("ASCII"));
2333     #endif
2334     Result = (SERVER_DWORD) TS_SCardLocateCardsByATR(in, out, wide);
2335     break;
2336     }
2337     /* SCardBeginTransaction */
2338     case SC_BEGIN_TRANSACTION:
2339     {
2340     #ifdef WITH_SCARD_DEBUG
2341     printf("<---SCardBeginTransaction--->\n");
2342     #endif
2343     Result = (SERVER_DWORD) TS_SCardBeginTransaction(in, out);
2344     break;
2345     }
2346     /* SCardBeginTransaction */
2347     case SC_END_TRANSACTION:
2348     {
2349     #ifdef WITH_SCARD_DEBUG
2350     printf("<---SCardEndTransaction--->\n");
2351     #endif
2352     Result = (SERVER_DWORD) TS_SCardEndTransaction(in, out);
2353     break;
2354     }
2355     /* ScardTransmit */
2356     case SC_TRANSMIT:
2357     {
2358     #ifdef WITH_SCARD_DEBUG
2359     printf("<---SCardTransmit--->\n");
2360     #endif
2361     Result = (SERVER_DWORD) TS_SCardTransmit(in, out);
2362     break;
2363     }
2364     /* SCardControl */
2365     case SC_CONTROL:
2366     {
2367     #ifdef WITH_SCARD_DEBUG
2368     printf("<---SCardControl--->\n");
2369     #endif
2370     Result = (SERVER_DWORD) TS_SCardControl(in, out);
2371     break;
2372     }
2373     /* SCardGetAttrib */
2374     #ifndef WITH_PCSC120
2375     case SC_GETATTRIB:
2376     {
2377     #ifdef WITH_SCARD_DEBUG
2378     printf("<---SCardGetAttrib--->\n");
2379     #endif
2380     Result = (SERVER_DWORD) TS_SCardGetAttrib(in, out);
2381     break;
2382     }
2383     #endif
2384     case SC_ACCESS_STARTED_EVENT:
2385     {
2386     #ifdef WITH_SCARD_DEBUG
2387     printf("<---SCardAccessStartedEvent-->\n");
2388     #endif
2389     Result = (SERVER_DWORD) TS_SCardAccessStartedEvent(in, out);
2390     break;
2391     }
2392     case SC_STATUS: /* SCardStatusA */
2393     case SC_STATUS + 4: /* SCardStatusW */
2394     {
2395     BOOL wide = request != SC_STATUS;
2396     #ifdef WITH_SCARD_DEBUG
2397     printf("<---SCardStatus---> (%s)\n", (wide) ? ("WIDE") : ("ASCII"));
2398     #endif
2399     Result = (SERVER_DWORD) TS_SCardStatus(in, out, wide);
2400     break;
2401     }
2402     case SC_STATE: /* SCardState */
2403     {
2404     #ifdef WITH_SCARD_DEBUG
2405     printf("<---SCardState--->");
2406     #endif
2407     Result = (SERVER_DWORD) TS_SCardState(in, out);
2408     break;
2409     }
2410     default:
2411     {
2412     #ifdef WITH_SCARD_DEBUG
2413     printf("<---UNSUPPORTED-FUNC--->\n");
2414     #endif
2415     Result = 0x80100014;
2416     out_uint8s(out, 256);
2417     break;
2418     }
2419     }
2420    
2421     #if 0
2422     out_uint32_le(out, 0x00000000);
2423     #endif
2424     /* Setting modified variables */
2425     pend = out->p;
2426     /* setting data size */
2427     out->p = psize;
2428     out_uint32_le(out, pend - psize - 16);
2429     /* setting status code */
2430     out->p = pStatusCode;
2431     out_uint32_le(out, Result);
2432     /* finish */
2433     out->p = pend;
2434    
2435     addToEnd = (pend - pStatusCode) % 16;
2436     if (addToEnd < 16 && addToEnd > 0)
2437     {
2438     out_uint8s(out, addToEnd);
2439     }
2440    
2441     #ifdef WITH_SCARD_DEBUG
2442     printf("[OUTPUT DUMP]-------------------\n");
2443     hexdump(pbeg, (size_t) (out->p) - (size_t) pbeg);
2444     printf("--------------------------------\n");
2445     #endif
2446     return STATUS_SUCCESS;
2447     }
2448    
2449     /* Thread functions */
2450    
2451     static STREAM
2452     duplicateStream(PMEM_HANDLE * handle, STREAM s, uint32 buffer_size, BOOL isInputStream)
2453     {
2454     STREAM d = SC_xmalloc(handle, sizeof(struct stream));
2455     if (d != NULL)
2456     {
2457     if (isInputStream)
2458     d->size = (size_t) (s->end) - (size_t) (s->data);
2459     else if (buffer_size < s->size)
2460     d->size = s->size;
2461     else
2462     d->size = buffer_size;
2463    
2464     d->data = SC_xmalloc(handle, d->size);
2465    
2466     d->end = (void *) ((size_t) (d->data) + (size_t) (s->end) - (size_t) (s->data));
2467     d->p = (void *) ((size_t) (d->data) + (size_t) (s->p) - (size_t) (s->data));
2468     d->iso_hdr =
2469     (void *) ((size_t) (d->data) + (size_t) (s->iso_hdr) - (size_t) (s->data));
2470     d->mcs_hdr =
2471     (void *) ((size_t) (d->data) + (size_t) (s->mcs_hdr) - (size_t) (s->data));
2472     d->sec_hdr =
2473     (void *) ((size_t) (d->data) + (size_t) (s->sec_hdr) - (size_t) (s->data));
2474     d->sec_hdr =
2475     (void *) ((size_t) (d->data) + (size_t) (s->sec_hdr) - (size_t) (s->data));
2476     d->rdp_hdr =
2477     (void *) ((size_t) (d->data) + (size_t) (s->rdp_hdr) - (size_t) (s->data));
2478     d->channel_hdr =
2479     (void *) ((size_t) (d->data) + (size_t) (s->channel_hdr) -
2480     (size_t) (s->data));
2481     if (isInputStream)
2482     memcpy(d->data, s->data, (size_t) (s->end) - (size_t) (s->data));
2483     else
2484     memcpy(d->data, s->data, (size_t) (s->p) - (size_t) (s->data));
2485     }
2486     return d;
2487     }
2488    
2489     static void
2490     freeStream(PMEM_HANDLE * handle, STREAM s)
2491     {
2492     if (s != NULL)
2493     {
2494     if (s->data != NULL)
2495     SC_xfree(handle, s->data);
2496     SC_xfree(handle, s);
2497     }
2498     }
2499    
2500     static PSCThreadData
2501     SC_addToQueue(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2502     {
2503     PMEM_HANDLE lcHandle = NULL;
2504     PSCThreadData data = SC_xmalloc(&lcHandle, sizeof(TSCThreadData));
2505    
2506     if (!data)
2507     return NULL;
2508     else
2509     {
2510     data->memHandle = lcHandle;
2511     data->device = curDevice;
2512     data->id = curId;
2513     data->handle = handle;
2514     data->request = request;
2515     data->in = duplicateStream(&(data->memHandle), in, 0, SC_TRUE);
2516     if (data->in == NULL)
2517     {
2518     SC_xfreeallmemory(&(data->memHandle));
2519     return NULL;
2520     }
2521     data->out =
2522     duplicateStream(&(data->memHandle), out, OUT_STREAM_SIZE + curBytesOut,
2523     SC_FALSE);
2524     if (data->out == NULL)
2525     {
2526     SC_xfreeallmemory(&(data->memHandle));
2527     return NULL;
2528     }
2529     data->next = NULL;
2530    
2531     pthread_mutex_lock(&queueAccess);
2532    
2533     if (queueLast)
2534     queueLast->next = data;
2535     queueLast = data;
2536     if (!queueFirst)
2537     queueFirst = data;
2538    
2539     pthread_mutex_unlock(&queueEmpty);
2540     pthread_mutex_unlock(&queueAccess);
2541     }
2542     return data;
2543     }
2544    
2545     static void
2546     SC_destroyThreadData(PSCThreadData data)
2547     {
2548     if (data)
2549     {
2550     PMEM_HANDLE handle = data->memHandle;
2551     SC_xfreeallmemory(&handle);
2552     }
2553     }
2554    
2555     static PSCThreadData
2556     SC_getNextInQueue()
2557     {
2558     PSCThreadData Result = NULL;
2559     pthread_mutex_lock(&queueAccess);
2560     if (queueFirst != NULL)
2561     {
2562     Result = queueFirst;
2563     queueFirst = queueFirst->next;
2564     if (!queueFirst)
2565     {
2566     queueLast = NULL;
2567     pthread_mutex_trylock(&queueEmpty);
2568     }
2569     Result->next = NULL;
2570     }
2571     pthread_mutex_unlock(&queueAccess);
2572     return Result;
2573     }
2574    
2575     static void
2576     SC_deviceControl(PSCThreadData data)
2577     {
2578     size_t buffer_len = 0;
2579     scard_device_control(data->handle, data->request, data->in, data->out);
2580     buffer_len = (size_t) data->out->p - (size_t) data->out->data;
2581     #if 0
2582     pthread_mutex_lock(&sendControl);
2583     #endif
2584     rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len);
2585     #if 0
2586     pthread_mutex_unlock(&sendControl);
2587     #endif
2588     SC_destroyThreadData(data);
2589     }
2590    
2591    
2592     static void *
2593     thread_function(PThreadListElement listElement)
2594     {
2595     #ifdef WITH_SCARD_DEBUG
2596     long sTime = 0;
2597     #endif
2598     if ((listElement != NULL) && (listElement->data != NULL))
2599     {
2600     while (1)
2601     {
2602     #ifdef WITH_SCARD_DEBUG
2603     sTime = time(NULL);
2604     #endif
2605     pthread_mutex_lock(&listElement->nodata);
2606     SC_deviceControl(listElement->data);
2607     listElement->data = NULL;
2608     #ifdef WITH_SCARD_DEBUG
2609     printf("[HANDLING TIME %d]\n", (int) (time(NULL) - sTime));
2610     #endif
2611     pthread_mutex_unlock(&listElement->busy);
2612     }
2613     }
2614     pthread_exit(NULL);
2615     return NULL;
2616     }
2617    
2618     static void
2619     SC_handleRequest(PSCThreadData data)
2620     {
2621     int Result = 0;
2622     PThreadListElement cur = threadList, last = threadList;
2623    
2624     #ifdef WITH_SCARD_DEBUG
2625     printf("[THREAD COUNT %d]\n", threadCount);
2626     #endif
2627    
2628     while (cur)
2629     {
2630     if (0 == pthread_mutex_trylock(&cur->busy))
2631     {
2632     cur->data = data;
2633     pthread_mutex_unlock(&cur->nodata);
2634     return;
2635     }
2636     else
2637     {
2638     last = cur;
2639     cur = cur->next;
2640     }
2641     }
2642    
2643     cur = SC_xmalloc(&threadListHandle, sizeof(TThreadListElement));
2644     if (!cur)
2645     return;
2646    
2647     threadCount++;
2648    
2649     cur->next = NULL;
2650     pthread_mutex_init(&cur->busy, NULL);
2651     pthread_mutex_init(&cur->nodata, NULL);
2652     pthread_mutex_trylock(&cur->busy);
2653     cur->data = data;
2654     pthread_mutex_unlock(&cur->nodata);
2655    
2656     Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);
2657     if (0 != Result)
2658     {
2659     printf("[THREAD CREATE ERROR 0x%.8x]\n", Result);
2660     SC_xfree(&threadListHandle, cur);
2661     SC_destroyThreadData(data);
2662     data = NULL;
2663     }
2664     else if (last)
2665     last->next = cur;
2666     else
2667     threadList = cur;
2668     }
2669    
2670     static void *
2671     queue_handler_function(void *data)
2672     {
2673     PSCThreadData cur_data = NULL;
2674     while (1)
2675     {
2676     cur_data = SC_getNextInQueue();
2677     if (cur_data != NULL)
2678     {
2679     switch (cur_data->request)
2680     {
2681     case SC_ESTABLISH_CONTEXT:
2682     case SC_RELEASE_CONTEXT:
2683     {
2684     SC_deviceControl(cur_data);
2685     break;
2686     }
2687     default:
2688     {
2689     SC_handleRequest(cur_data);
2690     break;
2691     }
2692     }
2693     cur_data = NULL;
2694     }
2695     else
2696     pthread_mutex_lock(&queueEmpty);
2697     }
2698     return NULL;
2699     }
2700    
2701     static NTSTATUS
2702     thread_wrapper(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2703     {
2704     if (SC_addToQueue(handle, request, in, out))
2705     return STATUS_PENDING | 0xC0000000;
2706     else
2707     return STATUS_NO_SUCH_FILE;
2708     }
2709    
2710     DEVICE_FNS scard_fns = {
2711     scard_create,
2712     scard_close,
2713     scard_read,
2714     scard_write,
2715     thread_wrapper
2716     };
2717     #endif /* MAKE_PROTO */
2718    
2719     void
2720     scard_tcp_lock(void)
2721     {
2722     if (!tcp_sendcontrol_mutex)
2723     {
2724     tcp_sendcontrol_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
2725     pthread_mutex_init(tcp_sendcontrol_mutex, NULL);
2726     }
2727    
2728     pthread_mutex_lock(tcp_sendcontrol_mutex);
2729     }
2730    
2731     void
2732     scard_tcp_unlock(void)
2733     {
2734     pthread_mutex_unlock(tcp_sendcontrol_mutex);
2735     }
2736    
2737     STREAM
2738     scard_tcp_init(void)
2739     {
2740     STREAM result = NULL;
2741    
2742     result = &out[cur_stream_id];
2743     cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
2744    
2745     return result;
2746     }
2747    
2748     void
2749     scard_tcp_connect(void)
2750     {
2751     int i;
2752    
2753     for (i = 0; i < STREAM_COUNT; i++)
2754     {
2755     out[i].size = 4096;
2756     out[i].data = (uint8 *) xmalloc(out[i].size);
2757     }
2758     }
2759    
2760     void
2761     scard_tcp_reset_state(void)
2762     {
2763     int i;
2764     struct stream *p;
2765    
2766     for (i = 0, p = out; i < STREAM_COUNT; i++, p++)
2767     {
2768     if (p->data != NULL)
2769     xfree(p->data);
2770     p->p = NULL;
2771     p->end = NULL;
2772     p->data = NULL;
2773     p->size = 0;
2774     p->iso_hdr = NULL;
2775     p->mcs_hdr = NULL;
2776     p->sec_hdr = NULL;
2777     p->rdp_hdr = NULL;
2778     p->channel_hdr = NULL;
2779     }
2780     }

  ViewVC Help
Powered by ViewVC 1.1.26