/[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 1326 - (hide annotations)
Fri Nov 3 18:57:09 2006 UTC (17 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 69400 byte(s)
reset padding to 8, as it did not fix the disconnects
enable sendControl mutex, as the rest of rdesktop is not threadsafe and
parallel access to rdpdr_send_completion might very likely result in
these disconnects

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

  ViewVC Help
Powered by ViewVC 1.1.26