/[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 1312 - (hide annotations)
Wed Nov 1 21:26:55 2006 UTC (17 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 70550 byte(s)
add normal rdesktop-header to smartcard-files

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     printf("[RECEIVED HCARD 0x%016lx]\n", myHCard);
814     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     printf("[myHCard = 0x%016lx]\n", myHCard);
895     #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     printf("[myHCard = 0x%016lx]\n", myHCard);
1376     #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     printf("[myHCard = 0x%016lx]\n", myHCard);
1404     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     printf("[myHCard = 0x%016lx]\n", myHCard);
1561     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     printf("[myHCard 0x%016lx]\n", myHCard);
1678     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     #ifdef WITH_PCSC120
2162     sc_nBytesReturned = nBytesReturned;
2163     myHCard = scHandleToMyPCSC(hCard);
2164     rv = SCardControl(myHCard, pInBuffer, (MYPCSC_DWORD) nInBufferSize, pOutBuffer,
2165     &sc_nBytesReturned);
2166     nBytesReturned = sc_nBytesReturned;
2167     #else
2168     sc_nBytesReturned = nBytesReturned;
2169     myHCard = scHandleToMyPCSC(hCard);
2170     rv = SCardControl(myHCard, (MYPCSC_DWORD) dwControlCode, pInBuffer,
2171     (MYPCSC_DWORD) nInBufferSize, pOutBuffer,
2172     (MYPCSC_DWORD) nOutBufferRealSize, &sc_nBytesReturned);
2173     nBytesReturned = sc_nBytesReturned;
2174     #endif
2175    
2176     #ifdef WITH_SCARD_DEBUG
2177     if (rv != SCARD_S_SUCCESS)
2178     printf("<--ERROR SCardControl Code=0x%.8x-->\n", (unsigned int) rv);
2179     else
2180     {
2181     printf("<--SUCCESS SCardControl-->\n");
2182     printf("[LENGTH %d]\n", (unsigned int) nBytesReturned);
2183     printf("+++++++++++++++++++++\n");
2184     hexdump((unsigned char *) pOutBuffer, nBytesReturned);
2185     printf("+++++++++++++++++++++\n");
2186     }
2187     #endif
2188    
2189     out_uint32_le(out, nBytesReturned);
2190     out_uint32_le(out, 0x00000004);
2191     out_uint32_le(out, nBytesReturned);
2192     if (nBytesReturned > 0)
2193     {
2194     out_uint8p(out, pOutBuffer, nBytesReturned);
2195     outRepos(out, nBytesReturned);
2196     }
2197    
2198     outForceAllignment(out, 8);
2199     SC_xfreeallmemory(&lcHandle);
2200     return rv;
2201     }
2202    
2203     static MYPCSC_DWORD
2204     TS_SCardAccessStartedEvent(STREAM in, STREAM out)
2205     {
2206     out_uint8s(out, 8);
2207     return SCARD_S_SUCCESS;
2208     }
2209    
2210    
2211     static NTSTATUS
2212     scard_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2213     {
2214     SERVER_DWORD Result = 0x00000000;
2215     unsigned char *psize, *pend, *pStatusCode;
2216     SERVER_DWORD addToEnd = 0;
2217    
2218     #ifdef WITH_SCARD_DEBUG
2219     unsigned char *pbeg = out->p;
2220     printf("--------------------------------\n");
2221     printf("[NTHANDLE %08X]\n", handle);
2222     printf("[REQUEST %08X]\n", request);
2223     printf("[INPUT DUMP]--------------------\n");
2224     hexdump(in->p, in->end - in->p);
2225     #endif
2226     /* Processing request */
2227    
2228     out_uint32_le(out, 0x00081001); /* Header lines */
2229     out_uint32_le(out, 0xCCCCCCCC);
2230     psize = out->p;
2231     out_uint32_le(out, 0x00000000); /* Size of data portion */
2232     out_uint32_le(out, 0x00000000); /* Zero bytes (may be usefull) */
2233     pStatusCode = out->p;
2234     out_uint32_le(out, 0x00000000); /* Status Code */
2235    
2236     switch (request)
2237     {
2238     /* SCardEstablishContext */
2239     case SC_ESTABLISH_CONTEXT:
2240     {
2241     #ifdef WITH_SCARD_DEBUG
2242     printf("<---SCardEstablishContext--->\n");
2243     #endif
2244     Result = (SERVER_DWORD) TS_SCardEstablishContext(in, out);
2245     break;
2246     }
2247     /* SCardReleaseContext */
2248     case SC_RELEASE_CONTEXT:
2249     {
2250     #ifdef WITH_SCARD_DEBUG
2251     printf("<---SCardReleaseContext--->\n");
2252     #endif
2253     Result = (SERVER_DWORD) TS_SCardReleaseContext(in, out);
2254     break;
2255     }
2256     /* SCardIsValidContext */
2257     case SC_IS_VALID_CONTEXT:
2258     {
2259     #ifdef WITH_SCARD_DEBUG
2260     printf("<---SCardIsValidContext--->\n");
2261     #endif
2262     Result = (SERVER_DWORD) TS_SCardIsValidContext(in, out);
2263     break;
2264     }
2265     /* SCardListReaders */
2266     case SC_LIST_READERS: /* SCardListReadersA */
2267     case SC_LIST_READERS + 4: /* SCardListReadersW */
2268     {
2269     BOOL wide = request != SC_LIST_READERS;
2270     #ifdef WITH_SCARD_DEBUG
2271     printf("<---SCardListReaders---> (%s)\n",
2272     (wide) ? ("WIDE") : ("ASCII"));
2273     #endif
2274     Result = (SERVER_DWORD) TS_SCardListReaders(in, out, wide);
2275     break;
2276     }
2277     /* ScardConnect */
2278     case SC_CONNECT: /* ScardConnectA */
2279     case SC_CONNECT + 4: /* SCardConnectW */
2280     {
2281     BOOL wide = request != SC_CONNECT;
2282     #ifdef WITH_SCARD_DEBUG
2283     printf("<---SCardConnect---> (%s)\n",
2284     (wide) ? ("WIDE") : ("ASCII"));
2285     #endif
2286     Result = (SERVER_DWORD) TS_SCardConnect(in, out, wide);
2287     break;
2288     }
2289     /* ScardReconnect */
2290     case SC_RECONNECT:
2291     {
2292     #ifdef WITH_SCARD_DEBUG
2293     printf("<---SCardReconnect--->\n");
2294     #endif
2295     Result = (SERVER_DWORD) TS_SCardReconnect(in, out);
2296     break;
2297     }
2298     /* ScardDisconnect */
2299     case SC_DISCONNECT:
2300     {
2301     #ifdef WITH_SCARD_DEBUG
2302     printf("<---SCardDisconnect--->\n");
2303     #endif
2304     Result = (SERVER_DWORD) TS_SCardDisconnect(in, out);
2305     break;
2306     }
2307     /* ScardGetStatusChange */
2308     case SC_GET_STATUS_CHANGE: /* SCardGetStatusChangeA */
2309     case SC_GET_STATUS_CHANGE + 4: /* SCardGetStatusChangeW */
2310     {
2311     BOOL wide = request != SC_GET_STATUS_CHANGE;
2312     #ifdef WITH_SCARD_DEBUG
2313     printf("<---SCardGetStatusChange---> (%s)\n",
2314     (wide) ? ("WIDE") : ("ASCII"));
2315     #endif
2316     Result = (SERVER_DWORD) TS_SCardGetStatusChange(in, out, wide);
2317     break;
2318     }
2319     /* SCardCancel */
2320     case SC_CANCEL:
2321     {
2322     #ifdef WITH_SCARD_DEBUG
2323     printf("<---SCardCancel--->\n");
2324     #endif
2325     Result = (SERVER_DWORD) TS_SCardCancel(in, out);
2326     break;
2327     }
2328     /* SCardLocateCardsByATR */
2329     case SC_LOCATE_CARDS_BY_ATR: /* SCardLocateCardsByATRA */
2330     case SC_LOCATE_CARDS_BY_ATR + 4: /* SCardLocateCardsByATRW */
2331     {
2332     BOOL wide = request != SC_LOCATE_CARDS_BY_ATR;
2333     #ifdef WITH_SCARD_DEBUG
2334     printf("<---SCardLocateCardsByATR---> (%s)\n",
2335     (wide) ? ("WIDE") : ("ASCII"));
2336     #endif
2337     Result = (SERVER_DWORD) TS_SCardLocateCardsByATR(in, out, wide);
2338     break;
2339     }
2340     /* SCardBeginTransaction */
2341     case SC_BEGIN_TRANSACTION:
2342     {
2343     #ifdef WITH_SCARD_DEBUG
2344     printf("<---SCardBeginTransaction--->\n");
2345     #endif
2346     Result = (SERVER_DWORD) TS_SCardBeginTransaction(in, out);
2347     break;
2348     }
2349     /* SCardBeginTransaction */
2350     case SC_END_TRANSACTION:
2351     {
2352     #ifdef WITH_SCARD_DEBUG
2353     printf("<---SCardEndTransaction--->\n");
2354     #endif
2355     Result = (SERVER_DWORD) TS_SCardEndTransaction(in, out);
2356     break;
2357     }
2358     /* ScardTransmit */
2359     case SC_TRANSMIT:
2360     {
2361     #ifdef WITH_SCARD_DEBUG
2362     printf("<---SCardTransmit--->\n");
2363     #endif
2364     Result = (SERVER_DWORD) TS_SCardTransmit(in, out);
2365     break;
2366     }
2367     /* SCardControl */
2368     case SC_CONTROL:
2369     {
2370     #ifdef WITH_SCARD_DEBUG
2371     printf("<---SCardControl--->\n");
2372     #endif
2373     Result = (SERVER_DWORD) TS_SCardControl(in, out);
2374     break;
2375     }
2376     /* SCardGetAttrib */
2377     #ifndef WITH_PCSC120
2378     case SC_GETATTRIB:
2379     {
2380     #ifdef WITH_SCARD_DEBUG
2381     printf("<---SCardGetAttrib--->\n");
2382     #endif
2383     Result = (SERVER_DWORD) TS_SCardGetAttrib(in, out);
2384     break;
2385     }
2386     #endif
2387     case SC_ACCESS_STARTED_EVENT:
2388     {
2389     #ifdef WITH_SCARD_DEBUG
2390     printf("<---SCardAccessStartedEvent-->\n");
2391     #endif
2392     Result = (SERVER_DWORD) TS_SCardAccessStartedEvent(in, out);
2393     break;
2394     }
2395     case SC_STATUS: /* SCardStatusA */
2396     case SC_STATUS + 4: /* SCardStatusW */
2397     {
2398     BOOL wide = request != SC_STATUS;
2399     #ifdef WITH_SCARD_DEBUG
2400     printf("<---SCardStatus---> (%s)\n", (wide) ? ("WIDE") : ("ASCII"));
2401     #endif
2402     Result = (SERVER_DWORD) TS_SCardStatus(in, out, wide);
2403     break;
2404     }
2405     case SC_STATE: /* SCardState */
2406     {
2407     #ifdef WITH_SCARD_DEBUG
2408     printf("<---SCardState--->");
2409     #endif
2410     Result = (SERVER_DWORD) TS_SCardState(in, out);
2411     break;
2412     }
2413     default:
2414     {
2415     #ifdef WITH_SCARD_DEBUG
2416     printf("<---UNSUPPORTED-FUNC--->\n");
2417     #endif
2418     Result = 0x80100014;
2419     out_uint8s(out, 256);
2420     break;
2421     }
2422     }
2423    
2424     #if 0
2425     out_uint32_le(out, 0x00000000);
2426     #endif
2427     /* Setting modified variables */
2428     pend = out->p;
2429     /* setting data size */
2430     out->p = psize;
2431     out_uint32_le(out, pend - psize - 16);
2432     /* setting status code */
2433     out->p = pStatusCode;
2434     out_uint32_le(out, Result);
2435     /* finish */
2436     out->p = pend;
2437    
2438     addToEnd = (pend - pStatusCode) % 16;
2439     if (addToEnd < 16 && addToEnd > 0)
2440     {
2441     out_uint8s(out, addToEnd);
2442     }
2443    
2444     #ifdef WITH_SCARD_DEBUG
2445     printf("[OUTPUT DUMP]-------------------\n");
2446     hexdump(pbeg, (size_t) (out->p) - (size_t) pbeg);
2447     printf("--------------------------------\n");
2448     #endif
2449     return STATUS_SUCCESS;
2450     }
2451    
2452     /* Thread functions */
2453    
2454     static STREAM
2455     duplicateStream(PMEM_HANDLE * handle, STREAM s, uint32 buffer_size, BOOL isInputStream)
2456     {
2457     STREAM d = SC_xmalloc(handle, sizeof(struct stream));
2458     if (d != NULL)
2459     {
2460     if (isInputStream)
2461     d->size = (size_t) (s->end) - (size_t) (s->data);
2462     else if (buffer_size < s->size)
2463     d->size = s->size;
2464     else
2465     d->size = buffer_size;
2466    
2467     d->data = SC_xmalloc(handle, d->size);
2468    
2469     d->end = (void *) ((size_t) (d->data) + (size_t) (s->end) - (size_t) (s->data));
2470     d->p = (void *) ((size_t) (d->data) + (size_t) (s->p) - (size_t) (s->data));
2471     d->iso_hdr =
2472     (void *) ((size_t) (d->data) + (size_t) (s->iso_hdr) - (size_t) (s->data));
2473     d->mcs_hdr =
2474     (void *) ((size_t) (d->data) + (size_t) (s->mcs_hdr) - (size_t) (s->data));
2475     d->sec_hdr =
2476     (void *) ((size_t) (d->data) + (size_t) (s->sec_hdr) - (size_t) (s->data));
2477     d->sec_hdr =
2478     (void *) ((size_t) (d->data) + (size_t) (s->sec_hdr) - (size_t) (s->data));
2479     d->rdp_hdr =
2480     (void *) ((size_t) (d->data) + (size_t) (s->rdp_hdr) - (size_t) (s->data));
2481     d->channel_hdr =
2482     (void *) ((size_t) (d->data) + (size_t) (s->channel_hdr) -
2483     (size_t) (s->data));
2484     if (isInputStream)
2485     memcpy(d->data, s->data, (size_t) (s->end) - (size_t) (s->data));
2486     else
2487     memcpy(d->data, s->data, (size_t) (s->p) - (size_t) (s->data));
2488     }
2489     return d;
2490     }
2491    
2492     static void
2493     freeStream(PMEM_HANDLE * handle, STREAM s)
2494     {
2495     if (s != NULL)
2496     {
2497     if (s->data != NULL)
2498     SC_xfree(handle, s->data);
2499     SC_xfree(handle, s);
2500     }
2501     }
2502    
2503     static PSCThreadData
2504     SC_addToQueue(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2505     {
2506     PMEM_HANDLE lcHandle = NULL;
2507     PSCThreadData data = SC_xmalloc(&lcHandle, sizeof(TSCThreadData));
2508    
2509     if (!data)
2510     return NULL;
2511     else
2512     {
2513     data->memHandle = lcHandle;
2514     data->device = curDevice;
2515     data->id = curId;
2516     data->handle = handle;
2517     data->request = request;
2518     data->in = duplicateStream(&(data->memHandle), in, 0, SC_TRUE);
2519     if (data->in == NULL)
2520     {
2521     SC_xfreeallmemory(&(data->memHandle));
2522     return NULL;
2523     }
2524     data->out =
2525     duplicateStream(&(data->memHandle), out, OUT_STREAM_SIZE + curBytesOut,
2526     SC_FALSE);
2527     if (data->out == NULL)
2528     {
2529     SC_xfreeallmemory(&(data->memHandle));
2530     return NULL;
2531     }
2532     data->next = NULL;
2533    
2534     pthread_mutex_lock(&queueAccess);
2535    
2536     if (queueLast)
2537     queueLast->next = data;
2538     queueLast = data;
2539     if (!queueFirst)
2540     queueFirst = data;
2541    
2542     pthread_mutex_unlock(&queueEmpty);
2543     pthread_mutex_unlock(&queueAccess);
2544     }
2545     return data;
2546     }
2547    
2548     static void
2549     SC_destroyThreadData(PSCThreadData data)
2550     {
2551     if (data)
2552     {
2553     PMEM_HANDLE handle = data->memHandle;
2554     SC_xfreeallmemory(&handle);
2555     }
2556     }
2557    
2558     static PSCThreadData
2559     SC_getNextInQueue()
2560     {
2561     PSCThreadData Result = NULL;
2562     pthread_mutex_lock(&queueAccess);
2563     if (queueFirst != NULL)
2564     {
2565     Result = queueFirst;
2566     queueFirst = queueFirst->next;
2567     if (!queueFirst)
2568     {
2569     queueLast = NULL;
2570     pthread_mutex_trylock(&queueEmpty);
2571     }
2572     Result->next = NULL;
2573     }
2574     pthread_mutex_unlock(&queueAccess);
2575     return Result;
2576     }
2577    
2578     static void
2579     SC_deviceControl(PSCThreadData data)
2580     {
2581     size_t buffer_len = 0;
2582     scard_device_control(data->handle, data->request, data->in, data->out);
2583     buffer_len = (size_t) data->out->p - (size_t) data->out->data;
2584     #if 0
2585     pthread_mutex_lock(&sendControl);
2586     #endif
2587     rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len);
2588     #if 0
2589     pthread_mutex_unlock(&sendControl);
2590     #endif
2591     SC_destroyThreadData(data);
2592     }
2593    
2594    
2595     static void *
2596     thread_function(PThreadListElement listElement)
2597     {
2598     #ifdef WITH_SCARD_DEBUG
2599     long sTime = 0;
2600     #endif
2601     if ((listElement != NULL) && (listElement->data != NULL))
2602     {
2603     while (1)
2604     {
2605     #ifdef WITH_SCARD_DEBUG
2606     sTime = time(NULL);
2607     #endif
2608     pthread_mutex_lock(&listElement->nodata);
2609     SC_deviceControl(listElement->data);
2610     listElement->data = NULL;
2611     #ifdef WITH_SCARD_DEBUG
2612     printf("[HANDLING TIME %d]\n", (int) (time(NULL) - sTime));
2613     #endif
2614     pthread_mutex_unlock(&listElement->busy);
2615     }
2616     }
2617     pthread_exit(NULL);
2618     return NULL;
2619     }
2620    
2621     static void
2622     SC_handleRequest(PSCThreadData data)
2623     {
2624     int Result = 0;
2625     PThreadListElement cur = threadList, last = threadList;
2626    
2627     #ifdef WITH_SCARD_DEBUG
2628     printf("[THREAD COUNT %d]\n", threadCount);
2629     #endif
2630    
2631     while (cur)
2632     {
2633     if (0 == pthread_mutex_trylock(&cur->busy))
2634     {
2635     cur->data = data;
2636     pthread_mutex_unlock(&cur->nodata);
2637     return;
2638     }
2639     else
2640     {
2641     last = cur;
2642     cur = cur->next;
2643     }
2644     }
2645    
2646     cur = SC_xmalloc(&threadListHandle, sizeof(TThreadListElement));
2647     if (!cur)
2648     return;
2649    
2650     threadCount++;
2651    
2652     cur->next = NULL;
2653     pthread_mutex_init(&cur->busy, NULL);
2654     pthread_mutex_init(&cur->nodata, NULL);
2655     pthread_mutex_trylock(&cur->busy);
2656     cur->data = data;
2657     pthread_mutex_unlock(&cur->nodata);
2658    
2659     Result = pthread_create(&cur->thread, NULL, (void *(*)(void *)) thread_function, cur);
2660     if (0 != Result)
2661     {
2662     printf("[THREAD CREATE ERROR 0x%.8x]\n", Result);
2663     SC_xfree(&threadListHandle, cur);
2664     SC_destroyThreadData(data);
2665     data = NULL;
2666     }
2667     else if (last)
2668     last->next = cur;
2669     else
2670     threadList = cur;
2671     }
2672    
2673     static void *
2674     queue_handler_function(void *data)
2675     {
2676     PSCThreadData cur_data = NULL;
2677     while (1)
2678     {
2679     cur_data = SC_getNextInQueue();
2680     if (cur_data != NULL)
2681     {
2682     switch (cur_data->request)
2683     {
2684     case SC_ESTABLISH_CONTEXT:
2685     case SC_RELEASE_CONTEXT:
2686     {
2687     SC_deviceControl(cur_data);
2688     break;
2689     }
2690     default:
2691     {
2692     SC_handleRequest(cur_data);
2693     break;
2694     }
2695     }
2696     cur_data = NULL;
2697     }
2698     else
2699     pthread_mutex_lock(&queueEmpty);
2700     }
2701     return NULL;
2702     }
2703    
2704     static NTSTATUS
2705     thread_wrapper(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
2706     {
2707     if (SC_addToQueue(handle, request, in, out))
2708     return STATUS_PENDING | 0xC0000000;
2709     else
2710     return STATUS_NO_SUCH_FILE;
2711     }
2712    
2713     DEVICE_FNS scard_fns = {
2714     scard_create,
2715     scard_close,
2716     scard_read,
2717     scard_write,
2718     thread_wrapper
2719     };
2720     #endif /* MAKE_PROTO */
2721    
2722     void
2723     scard_tcp_lock(void)
2724     {
2725     if (!tcp_sendcontrol_mutex)
2726     {
2727     tcp_sendcontrol_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
2728     pthread_mutex_init(tcp_sendcontrol_mutex, NULL);
2729     }
2730    
2731     pthread_mutex_lock(tcp_sendcontrol_mutex);
2732     }
2733    
2734     void
2735     scard_tcp_unlock(void)
2736     {
2737     pthread_mutex_unlock(tcp_sendcontrol_mutex);
2738     }
2739    
2740     STREAM
2741     scard_tcp_init(void)
2742     {
2743     STREAM result = NULL;
2744    
2745     result = &out[cur_stream_id];
2746     cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
2747    
2748     return result;
2749     }
2750    
2751     void
2752     scard_tcp_connect(void)
2753     {
2754     int i;
2755    
2756     for (i = 0; i < STREAM_COUNT; i++)
2757     {
2758     out[i].size = 4096;
2759     out[i].data = (uint8 *) xmalloc(out[i].size);
2760     }
2761     }
2762    
2763     void
2764     scard_tcp_reset_state(void)
2765     {
2766     int i;
2767     struct stream *p;
2768    
2769     for (i = 0, p = out; i < STREAM_COUNT; i++, p++)
2770     {
2771     if (p->data != NULL)
2772     xfree(p->data);
2773     p->p = NULL;
2774     p->end = NULL;
2775     p->data = NULL;
2776     p->size = 0;
2777     p->iso_hdr = NULL;
2778     p->mcs_hdr = NULL;
2779     p->sec_hdr = NULL;
2780     p->rdp_hdr = NULL;
2781     p->channel_hdr = NULL;
2782     }
2783     }

  ViewVC Help
Powered by ViewVC 1.1.26