19 |
*/ |
*/ |
20 |
|
|
21 |
#include <stdio.h> |
#include <stdio.h> |
|
#include "rdesktop.h" |
|
22 |
#include <unistd.h> |
#include <unistd.h> |
23 |
#include <fcntl.h> |
#include <fcntl.h> |
24 |
#include <strings.h> |
#include <strings.h> |
26 |
#include <time.h> |
#include <time.h> |
27 |
#ifndef MAKE_PROTO |
#ifndef MAKE_PROTO |
28 |
#ifdef PCSC_OSX |
#ifdef PCSC_OSX |
29 |
|
#include <PCSC/wintypes.h> |
30 |
#include <PCSC/pcsclite.h> |
#include <PCSC/pcsclite.h> |
31 |
#include <PCSC/winscard.h> |
#include <PCSC/winscard.h> |
32 |
#else |
#else |
33 |
|
#include <wintypes.h> |
34 |
#include <pcsclite.h> |
#include <pcsclite.h> |
35 |
#include <winscard.h> |
#include <winscard.h> |
36 |
#endif /* PCSC_OSX */ |
#endif /* PCSC_OSX */ |
37 |
|
#include "rdesktop.h" |
38 |
#include "scard.h" |
#include "scard.h" |
39 |
|
|
40 |
/* variable segment */ |
/* variable segment */ |
42 |
#define SCARD_MAX_MEM 102400 |
#define SCARD_MAX_MEM 102400 |
43 |
#define SCARD_AUTOALLOCATE -1 |
#define SCARD_AUTOALLOCATE -1 |
44 |
#define OUT_STREAM_SIZE 4096 |
#define OUT_STREAM_SIZE 4096 |
|
#define STREAM_COUNT 8 |
|
45 |
|
|
46 |
static struct stream out[STREAM_COUNT]; |
static pthread_mutex_t **scard_mutex = NULL; |
|
static int cur_stream_id = 0; |
|
|
static pthread_mutex_t *tcp_sendcontrol_mutex = NULL; |
|
47 |
|
|
48 |
static uint32 curDevice = 0, curId = 0, curBytesOut = 0; |
static uint32 curDevice = 0, curId = 0, curBytesOut = 0; |
49 |
static PSCNameMapRec nameMapList = NULL; |
static PSCNameMapRec nameMapList = NULL; |
53 |
static pthread_mutex_t queueAccess; |
static pthread_mutex_t queueAccess; |
54 |
static pthread_mutex_t queueEmpty; |
static pthread_mutex_t queueEmpty; |
55 |
static pthread_mutex_t hcardAccess; |
static pthread_mutex_t hcardAccess; |
|
/* static pthread_mutex_t sendControl; */ |
|
56 |
|
|
57 |
static PMEM_HANDLE threadListHandle = NULL; |
static PMEM_HANDLE threadListHandle = NULL; |
58 |
static PThreadListElement threadList = NULL; |
static PThreadListElement threadList = NULL; |
78 |
|
|
79 |
#ifndef MAKE_PROTO |
#ifndef MAKE_PROTO |
80 |
|
|
81 |
static NTSTATUS |
static RD_NTSTATUS |
82 |
scard_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, |
scard_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, |
83 |
uint32 flags_and_attributes, char *filename, NTHANDLE * phandle) |
uint32 flags_and_attributes, char *filename, RD_NTHANDLE * phandle) |
84 |
{ |
{ |
85 |
return STATUS_SUCCESS; |
return RD_STATUS_SUCCESS; |
86 |
} |
} |
87 |
|
|
88 |
static NTSTATUS |
static RD_NTSTATUS |
89 |
scard_close(NTHANDLE handle) |
scard_close(RD_NTHANDLE handle) |
90 |
{ |
{ |
91 |
return STATUS_SUCCESS; |
return RD_STATUS_SUCCESS; |
92 |
} |
} |
93 |
|
|
94 |
static NTSTATUS |
static RD_NTSTATUS |
95 |
scard_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) |
scard_read(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) |
96 |
{ |
{ |
97 |
return STATUS_SUCCESS; |
return RD_STATUS_SUCCESS; |
98 |
} |
} |
99 |
|
|
100 |
static NTSTATUS |
static RD_NTSTATUS |
101 |
scard_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) |
scard_write(RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) |
102 |
{ |
{ |
103 |
return STATUS_SUCCESS; |
return RD_STATUS_SUCCESS; |
104 |
} |
} |
105 |
#endif /* MAKE_PROTO */ |
#endif /* MAKE_PROTO */ |
106 |
|
|
150 |
return 0; |
return 0; |
151 |
} |
} |
152 |
|
|
|
#if 0 |
|
|
if (0 != pthread_mutex_init(&sendControl, NULL)) |
|
|
{ |
|
|
error("[SMART CARD: Can't initialize send control mutex]\n"); |
|
|
return 0; |
|
|
} |
|
|
#endif |
|
|
|
|
|
|
|
153 |
if (0 != |
if (0 != |
154 |
pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL)) |
pthread_create(&queueHandler, NULL, (void *(*)(void *)) queue_handler_function, NULL)) |
155 |
{ |
{ |
222 |
} |
} |
223 |
} |
} |
224 |
|
|
|
|
|
|
printf("******************************************************\n"); |
|
|
printf("* Smart Card support for RDesktop is initialized. *\n"); |
|
|
printf("* Copyright (C) by Alexi Volkov, alexi@myrealbox.com *\n"); |
|
|
printf("******************************************************\n"); |
|
|
|
|
225 |
return count; |
return count; |
226 |
} |
} |
227 |
|
|
480 |
} |
} |
481 |
|
|
482 |
static void |
static void |
483 |
outForceAllignment(STREAM out, unsigned int seed) |
outForceAlignment(STREAM out, unsigned int seed) |
484 |
{ |
{ |
485 |
SERVER_DWORD add = (seed - (out->p - out->data) % seed) % seed; |
SERVER_DWORD add = (seed - (out->p - out->data) % seed) % seed; |
486 |
if (add > 0) |
if (add > 0) |
|
{ |
|
487 |
out_uint8s(out, add); |
out_uint8s(out, add); |
|
} |
|
488 |
} |
} |
489 |
|
|
490 |
static unsigned int |
static unsigned int |
491 |
inString(PMEM_HANDLE * handle, STREAM in, char **destination, SERVER_DWORD dataLength, BOOL wide) |
inString(PMEM_HANDLE * handle, STREAM in, char **destination, SERVER_DWORD dataLength, RD_BOOL wide) |
492 |
{ |
{ |
493 |
unsigned int Result = (wide) ? (2 * dataLength) : (dataLength); |
unsigned int Result = (wide) ? (2 * dataLength) : (dataLength); |
494 |
PMEM_HANDLE lcHandle = NULL; |
PMEM_HANDLE lcHandle = NULL; |
522 |
} |
} |
523 |
|
|
524 |
static unsigned int |
static unsigned int |
525 |
outString(STREAM out, char *source, BOOL wide) |
outString(STREAM out, char *source, RD_BOOL wide) |
526 |
{ |
{ |
527 |
PMEM_HANDLE lcHandle = NULL; |
PMEM_HANDLE lcHandle = NULL; |
528 |
char *reader = getAlias(source); |
char *reader = getAlias(source); |
556 |
} |
} |
557 |
|
|
558 |
static void |
static void |
559 |
inReaderName(PMEM_HANDLE * handle, STREAM in, char **destination, BOOL wide) |
inReaderName(PMEM_HANDLE * handle, STREAM in, char **destination, RD_BOOL wide) |
560 |
{ |
{ |
561 |
SERVER_DWORD dataLength; |
SERVER_DWORD dataLength; |
562 |
in->p += 0x08; |
in->p += 0x08; |
605 |
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); |
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); |
606 |
if (rv) |
if (rv) |
607 |
{ |
{ |
608 |
DEBUG_SCARD(("<--ERROR SCardEstablishContext Code=0x%.8x]-->\n", |
DEBUG_SCARD(("<--ERROR SCardEstablishContext Code=0x%.8x, %s]-->\n", |
609 |
(unsigned int) rv)); |
(unsigned int) rv, pcsc_stringify_error(rv))); |
610 |
} |
} |
611 |
else |
else |
612 |
{ |
{ |
635 |
|
|
636 |
if (rv) |
if (rv) |
637 |
{ |
{ |
638 |
DEBUG_SCARD(("<--ERROR SCardReleaseContext Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardReleaseContext Code=0x%.8x, %s-->\n", (unsigned int) rv, |
639 |
|
pcsc_stringify_error(rv))); |
640 |
} |
} |
641 |
else |
else |
642 |
{ |
{ |
669 |
|
|
670 |
if (rv) |
if (rv) |
671 |
{ |
{ |
672 |
DEBUG_SCARD(("<--ERROR SCardListReaders (no SCardIsValidContext) Code=0x%.8x-->\n", |
DEBUG_SCARD(("<--ERROR SCardListReaders (no SCardIsValidContext) Code=0x%.8x, %s-->\n", (unsigned int) rv, pcsc_stringify_error(rv))); |
|
(unsigned int) rv)); |
|
673 |
rv = SCARD_E_INVALID_HANDLE; |
rv = SCARD_E_INVALID_HANDLE; |
674 |
} |
} |
675 |
else |
else |
677 |
DEBUG_SCARD(("<--SUCCESS SCardListReaders (no SCardIsValidContext)-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardListReaders (no SCardIsValidContext)-->\n")); |
678 |
} |
} |
679 |
|
|
680 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
681 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
682 |
return rv; |
return rv; |
683 |
} |
} |
684 |
|
|
685 |
|
|
686 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
687 |
TS_SCardListReaders(STREAM in, STREAM out, BOOL wide) |
TS_SCardListReaders(STREAM in, STREAM out, RD_BOOL wide) |
688 |
{ |
{ |
689 |
#define readerArraySize 1024 |
#define readerArraySize 1024 |
690 |
MYPCSC_DWORD rv; |
MYPCSC_DWORD rv; |
750 |
out_uint32_le(out, dataLength); |
out_uint32_le(out, dataLength); |
751 |
out->p = pend; |
out->p = pend; |
752 |
|
|
753 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
754 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
755 |
return rv; |
return rv; |
756 |
} |
} |
757 |
|
|
758 |
|
|
759 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
760 |
TS_SCardConnect(STREAM in, STREAM out, BOOL wide) |
TS_SCardConnect(STREAM in, STREAM out, RD_BOOL wide) |
761 |
{ |
{ |
762 |
MYPCSC_DWORD rv; |
MYPCSC_DWORD rv; |
763 |
SCARDCONTEXT hContext; |
SCARDCONTEXT hContext; |
787 |
DEBUG_SCARD(("[MANGLED HCARD 0x%08x]\n", hCard)); |
DEBUG_SCARD(("[MANGLED HCARD 0x%08x]\n", hCard)); |
788 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
789 |
{ |
{ |
790 |
DEBUG_SCARD(("<--ERROR SCardConnect Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardConnect Code=0x%.8x, %s-->\n", (unsigned int) rv, |
791 |
|
pcsc_stringify_error(rv))); |
792 |
} |
} |
793 |
else |
else |
794 |
{ |
{ |
826 |
out_uint32_le(out, 0x00000004); |
out_uint32_le(out, 0x00000004); |
827 |
out_uint32_le(out, hCard); |
out_uint32_le(out, hCard); |
828 |
|
|
829 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
830 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
831 |
return rv; |
return rv; |
832 |
} |
} |
862 |
(MYPCSC_DWORD) dwInitialization, &dwActiveProtocol); |
(MYPCSC_DWORD) dwInitialization, &dwActiveProtocol); |
863 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
864 |
{ |
{ |
865 |
DEBUG_SCARD(("<--ERROR SCardReconnect Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardReconnect Code=0x%.8x, %s-->\n", (unsigned int) rv, |
866 |
|
pcsc_stringify_error(rv))); |
867 |
} |
} |
868 |
else |
else |
869 |
{ |
{ |
870 |
DEBUG_SCARD(("<--SUCCESS SCardReconnect-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardReconnect-->\n")); |
871 |
} |
} |
872 |
|
|
873 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
874 |
out_uint32_le(out, (SERVER_DWORD) dwActiveProtocol); |
out_uint32_le(out, (SERVER_DWORD) dwActiveProtocol); |
875 |
return rv; |
return rv; |
876 |
} |
} |
919 |
|
|
920 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
921 |
{ |
{ |
922 |
DEBUG_SCARD(("<--ERROR SCardDisconnect Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardDisconnect Code=0x%.8x, %s-->\n", (unsigned int) rv, |
923 |
|
pcsc_stringify_error(rv))); |
924 |
} |
} |
925 |
else |
else |
926 |
{ |
{ |
927 |
DEBUG_SCARD(("<--SUCCESS SCardDisconnect-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardDisconnect-->\n")); |
928 |
} |
} |
929 |
|
|
930 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
931 |
return rv; |
return rv; |
932 |
} |
} |
933 |
|
|
950 |
return recall; |
return recall; |
951 |
} |
} |
952 |
|
|
953 |
static BOOL |
static RD_BOOL |
954 |
mappedStatus(MYPCSC_DWORD code) |
mappedStatus(MYPCSC_DWORD code) |
955 |
{ |
{ |
956 |
code >>= 16; |
code >>= 16; |
959 |
} |
} |
960 |
|
|
961 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
962 |
incStatus(MYPCSC_DWORD code, BOOL mapped) |
incStatus(MYPCSC_DWORD code, RD_BOOL mapped) |
963 |
{ |
{ |
964 |
if (mapped || (code & SCARD_STATE_CHANGED)) |
if (mapped || (code & SCARD_STATE_CHANGED)) |
965 |
{ |
{ |
1013 |
|
|
1014 |
|
|
1015 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
1016 |
TS_SCardGetStatusChange(STREAM in, STREAM out, BOOL wide) |
TS_SCardGetStatusChange(STREAM in, STREAM out, RD_BOOL wide) |
1017 |
{ |
{ |
1018 |
MYPCSC_DWORD rv; |
MYPCSC_DWORD rv; |
1019 |
SERVER_SCARDCONTEXT hContext; |
SERVER_SCARDCONTEXT hContext; |
1025 |
long i; |
long i; |
1026 |
PMEM_HANDLE lcHandle = NULL; |
PMEM_HANDLE lcHandle = NULL; |
1027 |
#if 0 |
#if 0 |
1028 |
BOOL mapped = False; |
RD_BOOL mapped = False; |
1029 |
#endif |
#endif |
1030 |
|
|
1031 |
in->p += 0x18; |
in->p += 0x18; |
1132 |
|
|
1133 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1134 |
{ |
{ |
1135 |
DEBUG_SCARD(("<--ERROR SCardGetStatusChange Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardGetStatusChange Code=0x%.8x, %s-->\n", |
1136 |
|
(unsigned int) rv, pcsc_stringify_error(rv))); |
1137 |
} |
} |
1138 |
else |
else |
1139 |
{ |
{ |
1185 |
out_uint8p(out, (void *) ((unsigned char **) cur + 2), |
out_uint8p(out, (void *) ((unsigned char **) cur + 2), |
1186 |
sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *)); |
sizeof(SERVER_SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *)); |
1187 |
} |
} |
1188 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1189 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1190 |
return rv; |
return rv; |
1191 |
} |
} |
1203 |
rv = SCardCancel((MYPCSC_SCARDCONTEXT) hContext); |
rv = SCardCancel((MYPCSC_SCARDCONTEXT) hContext); |
1204 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1205 |
{ |
{ |
1206 |
DEBUG_SCARD(("<--ERROR SCardCancel Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardCancel Code=0x%.8x, %s-->\n", (unsigned int) rv, |
1207 |
|
pcsc_stringify_error(rv))); |
1208 |
} |
} |
1209 |
else |
else |
1210 |
{ |
{ |
1211 |
DEBUG_SCARD(("<--SUCCESS SCardCancel-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardCancel-->\n")); |
1212 |
} |
} |
1213 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1214 |
return rv; |
return rv; |
1215 |
} |
} |
1216 |
|
|
1217 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
1218 |
TS_SCardLocateCardsByATR(STREAM in, STREAM out, BOOL wide) |
TS_SCardLocateCardsByATR(STREAM in, STREAM out, RD_BOOL wide) |
1219 |
{ |
{ |
1220 |
int i, j, k; |
int i, j, k; |
1221 |
MYPCSC_DWORD rv; |
MYPCSC_DWORD rv; |
1268 |
myRsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(MYPCSC_SCARD_READERSTATE_A)); |
myRsArray = SC_xmalloc(&lcHandle, readerCount * sizeof(MYPCSC_SCARD_READERSTATE_A)); |
1269 |
if (!myRsArray) |
if (!myRsArray) |
1270 |
return SC_returnNoMemoryError(&lcHandle, in, out); |
return SC_returnNoMemoryError(&lcHandle, in, out); |
1271 |
|
copyReaderState_ServerToMyPCSC(rsArray, myRsArray, readerCount); |
1272 |
rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, 0x00000001, myRsArray, |
rv = SCardGetStatusChange((MYPCSC_SCARDCONTEXT) hContext, 0x00000001, myRsArray, |
1273 |
readerCount); |
readerCount); |
1274 |
copyReaderState_MyPCSCToServer(myRsArray, rsArray, readerCount); |
copyReaderState_MyPCSCToServer(myRsArray, rsArray, readerCount); |
1275 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1276 |
{ |
{ |
1277 |
DEBUG_SCARD(("<--ERROR SCardGetStatusChange (no SCardLocateCardsByATR) Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardGetStatusChange (no SCardLocateCardsByATR) Code=0x%.8x, %s-->\n", (unsigned int) rv, pcsc_stringify_error(rv))); |
1278 |
} |
} |
1279 |
else |
else |
1280 |
{ |
{ |
1284 |
{ |
{ |
1285 |
for (j = 0, rsCur = rsArray; j < readerCount; j++, rsCur++) |
for (j = 0, rsCur = rsArray; j < readerCount; j++, rsCur++) |
1286 |
{ |
{ |
1287 |
BOOL equal = 1; |
RD_BOOL equal = 1; |
1288 |
for (k = 0; k < cur->cbAtr; k++) |
for (k = 0; k < cur->cbAtr; k++) |
1289 |
{ |
{ |
1290 |
/* This line check if them equal */ |
/* This line check if them equal */ |
1316 |
sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *)); |
sizeof(SCARD_READERSTATE_A) - 2 * sizeof(unsigned char *)); |
1317 |
} |
} |
1318 |
|
|
1319 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1320 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1321 |
return rv; |
return rv; |
1322 |
} |
} |
1336 |
rv = SCardBeginTransaction(myHCard); |
rv = SCardBeginTransaction(myHCard); |
1337 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1338 |
{ |
{ |
1339 |
DEBUG_SCARD(("<--ERROR SCardBeginTransaction Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardBeginTransaction Code=0x%.8x, %s-->\n", |
1340 |
|
(unsigned int) rv, pcsc_stringify_error(rv))); |
1341 |
} |
} |
1342 |
else |
else |
1343 |
{ |
{ |
1344 |
DEBUG_SCARD(("<--SUCCESS SCardBeginTransaction-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardBeginTransaction-->\n")); |
1345 |
} |
} |
1346 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1347 |
return rv; |
return rv; |
1348 |
} |
} |
1349 |
|
|
1368 |
rv = SCardEndTransaction(myHCard, (MYPCSC_DWORD) dwDisposition); |
rv = SCardEndTransaction(myHCard, (MYPCSC_DWORD) dwDisposition); |
1369 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1370 |
{ |
{ |
1371 |
DEBUG_SCARD(("<--ERROR SCardEndTransaction Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardEndTransaction Code=0x%.8x, %s-->\n", (unsigned int) rv, |
1372 |
|
pcsc_stringify_error(rv))); |
1373 |
} |
} |
1374 |
else |
else |
1375 |
{ |
{ |
1376 |
DEBUG_SCARD(("<--SUCCESS SCardEndTransaction-->\n")); |
DEBUG_SCARD(("<--SUCCESS SCardEndTransaction-->\n")); |
1377 |
} |
} |
1378 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1379 |
return rv; |
return rv; |
1380 |
} |
} |
1381 |
|
|
1573 |
|
|
1574 |
if (pioRecvPci) |
if (pioRecvPci) |
1575 |
{ |
{ |
1576 |
copyIORequest_MyPCSCToServer(myPioRecvPci, pioRecvPci); |
/* |
1577 |
|
* pscs-lite mishandles this structure in some cases. |
1578 |
|
* make sure we only copy it if it is valid. |
1579 |
|
*/ |
1580 |
|
if (myPioRecvPci->cbPciLength >= sizeof(MYPCSC_SCARD_IO_REQUEST)) |
1581 |
|
copyIORequest_MyPCSCToServer(myPioRecvPci, pioRecvPci); |
1582 |
} |
} |
1583 |
|
|
1584 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1585 |
{ |
{ |
1586 |
DEBUG_SCARD(("<--ERROR SCardTransmit Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardTransmit Code=0x%.8x, %s-->\n", (unsigned int) rv, |
1587 |
|
pcsc_stringify_error(rv))); |
1588 |
} |
} |
1589 |
else |
else |
1590 |
{ |
{ |
1624 |
|
|
1625 |
outBufferFinish(out, (char *) recvBuf, cbRecvLength); |
outBufferFinish(out, (char *) recvBuf, cbRecvLength); |
1626 |
} |
} |
1627 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1628 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1629 |
return rv; |
return rv; |
1630 |
} |
} |
1631 |
|
|
1632 |
static MYPCSC_DWORD |
static MYPCSC_DWORD |
1633 |
TS_SCardStatus(STREAM in, STREAM out, BOOL wide) |
TS_SCardStatus(STREAM in, STREAM out, RD_BOOL wide) |
1634 |
{ |
{ |
1635 |
MYPCSC_DWORD rv; |
MYPCSC_DWORD rv; |
1636 |
SERVER_SCARDCONTEXT hCard; |
SERVER_SCARDCONTEXT hCard; |
1681 |
|
|
1682 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1683 |
{ |
{ |
1684 |
DEBUG_SCARD(("<--ERROR SCardStatus Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardStatus Code=0x%.8x, %s-->\n", (unsigned int) rv, |
1685 |
|
pcsc_stringify_error(rv))); |
1686 |
return SC_returnCode(rv, &lcHandle, in, out); |
return SC_returnCode(rv, &lcHandle, in, out); |
1687 |
} |
} |
1688 |
else |
else |
1741 |
out_uint32_le(out, dataLength); |
out_uint32_le(out, dataLength); |
1742 |
out->p = psave; |
out->p = psave; |
1743 |
} |
} |
1744 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1745 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1746 |
return rv; |
return rv; |
1747 |
} |
} |
1793 |
|
|
1794 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1795 |
{ |
{ |
1796 |
DEBUG_SCARD(("<--ERROR SCardStatus (no ScardState) Code=0x%.8x-->\n", |
DEBUG_SCARD(("<--ERROR SCardStatus (no ScardState) Code=0x%.8x, %s-->\n", |
1797 |
(unsigned int) rv)); |
(unsigned int) rv, pcsc_stringify_error(rv))); |
1798 |
return SC_returnCode(rv, &lcHandle, in, out); |
return SC_returnCode(rv, &lcHandle, in, out); |
1799 |
} |
} |
1800 |
else |
else |
1835 |
out_uint8p(out, atr, dwAtrLen); |
out_uint8p(out, atr, dwAtrLen); |
1836 |
outRepos(out, dwAtrLen); |
outRepos(out, dwAtrLen); |
1837 |
} |
} |
1838 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1839 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1840 |
return rv; |
return rv; |
1841 |
} |
} |
1872 |
|
|
1873 |
if (rv) |
if (rv) |
1874 |
{ |
{ |
1875 |
DEBUG_SCARD(("<--ERROR SCardListReaderGroups Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardListReaderGroups Code=0x%.8x, %s-->\n", |
1876 |
|
(unsigned int) rv, pcsc_stringify_error(rv))); |
1877 |
return SC_returnCode(rv, &lcHandle, in, out); |
return SC_returnCode(rv, &lcHandle, in, out); |
1878 |
} |
} |
1879 |
else |
else |
1889 |
outRepos(out, dwGroups); |
outRepos(out, dwGroups); |
1890 |
out_uint32_le(out, 0x00000000); |
out_uint32_le(out, 0x00000000); |
1891 |
|
|
1892 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1893 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
1894 |
return rv; |
return rv; |
1895 |
} |
} |
1964 |
|
|
1965 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
1966 |
{ |
{ |
1967 |
DEBUG_SCARD(("<--ERROR SCardGetAttrib Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardGetAttrib Code=0x%.8x, %s-->\n", (unsigned int) rv, |
1968 |
|
pcsc_stringify_error(rv))); |
1969 |
return SC_returnCode(rv, &lcHandle, in, out); |
return SC_returnCode(rv, &lcHandle, in, out); |
1970 |
} |
} |
1971 |
else |
else |
1991 |
outRepos(out, dwAttrLen); |
outRepos(out, dwAttrLen); |
1992 |
out_uint32_le(out, 0x00000000); |
out_uint32_le(out, 0x00000000); |
1993 |
} |
} |
1994 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
1995 |
return rv; |
return rv; |
1996 |
} |
} |
1997 |
|
|
2033 |
|
|
2034 |
if (rv) |
if (rv) |
2035 |
{ |
{ |
2036 |
DEBUG_SCARD(("<--ERROR SCardSetAttrib Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardSetAttrib Code=0x%.8x, %s-->\n", (unsigned int) rv, |
2037 |
|
pcsc_stringify_error(rv))); |
2038 |
} |
} |
2039 |
else |
else |
2040 |
{ |
{ |
2045 |
out_uint32_le(out, 0x00000200); |
out_uint32_le(out, 0x00000200); |
2046 |
out_uint32_le(out, 0x00000000); |
out_uint32_le(out, 0x00000000); |
2047 |
out_uint32_le(out, 0x00000000); |
out_uint32_le(out, 0x00000000); |
2048 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
2049 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
2050 |
return rv; |
return rv; |
2051 |
} |
} |
2137 |
#ifdef WITH_DEBUG_SCARD |
#ifdef WITH_DEBUG_SCARD |
2138 |
if (rv != SCARD_S_SUCCESS) |
if (rv != SCARD_S_SUCCESS) |
2139 |
{ |
{ |
2140 |
DEBUG_SCARD(("<--ERROR SCardControl Code=0x%.8x-->\n", (unsigned int) rv)); |
DEBUG_SCARD(("<--ERROR SCardControl Code=0x%.8x, %s-->\n", (unsigned int) rv, |
2141 |
|
pcsc_stringify_error(rv))); |
2142 |
} |
} |
2143 |
else |
else |
2144 |
{ |
{ |
2159 |
outRepos(out, nBytesReturned); |
outRepos(out, nBytesReturned); |
2160 |
} |
} |
2161 |
|
|
2162 |
outForceAllignment(out, 8); |
outForceAlignment(out, 8); |
2163 |
SC_xfreeallmemory(&lcHandle); |
SC_xfreeallmemory(&lcHandle); |
2164 |
return rv; |
return rv; |
2165 |
} |
} |
2172 |
} |
} |
2173 |
|
|
2174 |
|
|
2175 |
static NTSTATUS |
static RD_NTSTATUS |
2176 |
scard_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
scard_device_control(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
2177 |
{ |
{ |
2178 |
SERVER_DWORD Result = 0x00000000; |
SERVER_DWORD Result = 0x00000000; |
2179 |
unsigned char *psize, *pend, *pStatusCode; |
unsigned char *psize, *pend, *pStatusCode; |
2224 |
case SC_LIST_READERS: /* SCardListReadersA */ |
case SC_LIST_READERS: /* SCardListReadersA */ |
2225 |
case SC_LIST_READERS + 4: /* SCardListReadersW */ |
case SC_LIST_READERS + 4: /* SCardListReadersW */ |
2226 |
{ |
{ |
2227 |
BOOL wide = request != SC_LIST_READERS; |
RD_BOOL wide = request != SC_LIST_READERS; |
2228 |
DEBUG_SCARD(("<---SCardListReaders---> (%s)\n", |
DEBUG_SCARD(("<---SCardListReaders---> (%s)\n", |
2229 |
(wide) ? ("WIDE") : ("ASCII"))); |
(wide) ? ("WIDE") : ("ASCII"))); |
2230 |
Result = (SERVER_DWORD) TS_SCardListReaders(in, out, wide); |
Result = (SERVER_DWORD) TS_SCardListReaders(in, out, wide); |
2234 |
case SC_CONNECT: /* ScardConnectA */ |
case SC_CONNECT: /* ScardConnectA */ |
2235 |
case SC_CONNECT + 4: /* SCardConnectW */ |
case SC_CONNECT + 4: /* SCardConnectW */ |
2236 |
{ |
{ |
2237 |
BOOL wide = request != SC_CONNECT; |
RD_BOOL wide = request != SC_CONNECT; |
2238 |
DEBUG_SCARD(("<---SCardConnect---> (%s)\n", |
DEBUG_SCARD(("<---SCardConnect---> (%s)\n", |
2239 |
(wide) ? ("WIDE") : ("ASCII"))); |
(wide) ? ("WIDE") : ("ASCII"))); |
2240 |
Result = (SERVER_DWORD) TS_SCardConnect(in, out, wide); |
Result = (SERVER_DWORD) TS_SCardConnect(in, out, wide); |
2258 |
case SC_GET_STATUS_CHANGE: /* SCardGetStatusChangeA */ |
case SC_GET_STATUS_CHANGE: /* SCardGetStatusChangeA */ |
2259 |
case SC_GET_STATUS_CHANGE + 4: /* SCardGetStatusChangeW */ |
case SC_GET_STATUS_CHANGE + 4: /* SCardGetStatusChangeW */ |
2260 |
{ |
{ |
2261 |
BOOL wide = request != SC_GET_STATUS_CHANGE; |
RD_BOOL wide = request != SC_GET_STATUS_CHANGE; |
2262 |
DEBUG_SCARD(("<---SCardGetStatusChange---> (%s)\n", |
DEBUG_SCARD(("<---SCardGetStatusChange---> (%s)\n", |
2263 |
(wide) ? ("WIDE") : ("ASCII"))); |
(wide) ? ("WIDE") : ("ASCII"))); |
2264 |
Result = (SERVER_DWORD) TS_SCardGetStatusChange(in, out, wide); |
Result = (SERVER_DWORD) TS_SCardGetStatusChange(in, out, wide); |
2275 |
case SC_LOCATE_CARDS_BY_ATR: /* SCardLocateCardsByATRA */ |
case SC_LOCATE_CARDS_BY_ATR: /* SCardLocateCardsByATRA */ |
2276 |
case SC_LOCATE_CARDS_BY_ATR + 4: /* SCardLocateCardsByATRW */ |
case SC_LOCATE_CARDS_BY_ATR + 4: /* SCardLocateCardsByATRW */ |
2277 |
{ |
{ |
2278 |
BOOL wide = request != SC_LOCATE_CARDS_BY_ATR; |
RD_BOOL wide = request != SC_LOCATE_CARDS_BY_ATR; |
2279 |
DEBUG_SCARD(("<---SCardLocateCardsByATR---> (%s)\n", |
DEBUG_SCARD(("<---SCardLocateCardsByATR---> (%s)\n", |
2280 |
(wide) ? ("WIDE") : ("ASCII"))); |
(wide) ? ("WIDE") : ("ASCII"))); |
2281 |
Result = (SERVER_DWORD) TS_SCardLocateCardsByATR(in, out, wide); |
Result = (SERVER_DWORD) TS_SCardLocateCardsByATR(in, out, wide); |
2327 |
case SC_STATUS: /* SCardStatusA */ |
case SC_STATUS: /* SCardStatusA */ |
2328 |
case SC_STATUS + 4: /* SCardStatusW */ |
case SC_STATUS + 4: /* SCardStatusW */ |
2329 |
{ |
{ |
2330 |
BOOL wide = request != SC_STATUS; |
RD_BOOL wide = request != SC_STATUS; |
2331 |
DEBUG_SCARD(("<---SCardStatus---> (%s)\n", |
DEBUG_SCARD(("<---SCardStatus---> (%s)\n", |
2332 |
(wide) ? ("WIDE") : ("ASCII"))); |
(wide) ? ("WIDE") : ("ASCII"))); |
2333 |
Result = (SERVER_DWORD) TS_SCardStatus(in, out, wide); |
Result = (SERVER_DWORD) TS_SCardStatus(in, out, wide); |
2373 |
hexdump(pbeg, (size_t) (out->p) - (size_t) pbeg); |
hexdump(pbeg, (size_t) (out->p) - (size_t) pbeg); |
2374 |
DEBUG_SCARD(("--------------------------------\n")); |
DEBUG_SCARD(("--------------------------------\n")); |
2375 |
#endif |
#endif |
2376 |
return STATUS_SUCCESS; |
return RD_STATUS_SUCCESS; |
2377 |
} |
} |
2378 |
|
|
2379 |
/* Thread functions */ |
/* Thread functions */ |
2380 |
|
|
2381 |
static STREAM |
static STREAM |
2382 |
duplicateStream(PMEM_HANDLE * handle, STREAM s, uint32 buffer_size, BOOL isInputStream) |
duplicateStream(PMEM_HANDLE * handle, STREAM s, uint32 buffer_size, RD_BOOL isInputStream) |
2383 |
{ |
{ |
2384 |
STREAM d = SC_xmalloc(handle, sizeof(struct stream)); |
STREAM d = SC_xmalloc(handle, sizeof(struct stream)); |
2385 |
if (d != NULL) |
if (d != NULL) |
2428 |
} |
} |
2429 |
|
|
2430 |
static PSCThreadData |
static PSCThreadData |
2431 |
SC_addToQueue(NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
SC_addToQueue(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
2432 |
{ |
{ |
2433 |
PMEM_HANDLE lcHandle = NULL; |
PMEM_HANDLE lcHandle = NULL; |
2434 |
PSCThreadData data = SC_xmalloc(&lcHandle, sizeof(TSCThreadData)); |
PSCThreadData data = SC_xmalloc(&lcHandle, sizeof(TSCThreadData)); |
2508 |
size_t buffer_len = 0; |
size_t buffer_len = 0; |
2509 |
scard_device_control(data->handle, data->request, data->in, data->out); |
scard_device_control(data->handle, data->request, data->in, data->out); |
2510 |
buffer_len = (size_t) data->out->p - (size_t) data->out->data; |
buffer_len = (size_t) data->out->p - (size_t) data->out->data; |
|
#if 0 |
|
|
pthread_mutex_lock(&sendControl); |
|
|
#endif |
|
2511 |
rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len); |
rdpdr_send_completion(data->device, data->id, 0, buffer_len, data->out->data, buffer_len); |
|
#if 0 |
|
|
pthread_mutex_unlock(&sendControl); |
|
|
#endif |
|
2512 |
SC_destroyThreadData(data); |
SC_destroyThreadData(data); |
2513 |
} |
} |
2514 |
|
|
2618 |
return NULL; |
return NULL; |
2619 |
} |
} |
2620 |
|
|
2621 |
static NTSTATUS |
static RD_NTSTATUS |
2622 |
thread_wrapper(NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
thread_wrapper(RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out) |
2623 |
{ |
{ |
2624 |
if (SC_addToQueue(handle, request, in, out)) |
if (SC_addToQueue(handle, request, in, out)) |
2625 |
return STATUS_PENDING | 0xC0000000; |
return RD_STATUS_PENDING | 0xC0000000; |
2626 |
else |
else |
2627 |
return STATUS_NO_SUCH_FILE; |
return RD_STATUS_NO_SUCH_FILE; |
2628 |
} |
} |
2629 |
|
|
2630 |
DEVICE_FNS scard_fns = { |
DEVICE_FNS scard_fns = { |
2637 |
#endif /* MAKE_PROTO */ |
#endif /* MAKE_PROTO */ |
2638 |
|
|
2639 |
void |
void |
2640 |
scard_tcp_lock(void) |
scard_lock(int lock) |
2641 |
{ |
{ |
2642 |
if (!tcp_sendcontrol_mutex) |
if (!scard_mutex) |
2643 |
{ |
{ |
2644 |
tcp_sendcontrol_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); |
int i; |
|
pthread_mutex_init(tcp_sendcontrol_mutex, NULL); |
|
|
} |
|
|
|
|
|
pthread_mutex_lock(tcp_sendcontrol_mutex); |
|
|
} |
|
|
|
|
|
void |
|
|
scard_tcp_unlock(void) |
|
|
{ |
|
|
pthread_mutex_unlock(tcp_sendcontrol_mutex); |
|
|
} |
|
|
|
|
|
STREAM |
|
|
scard_tcp_init(void) |
|
|
{ |
|
|
STREAM result = NULL; |
|
2645 |
|
|
2646 |
result = &out[cur_stream_id]; |
scard_mutex = |
2647 |
cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT; |
(pthread_mutex_t **) xmalloc(sizeof(pthread_mutex_t *) * SCARD_LOCK_LAST); |
2648 |
|
|
2649 |
return result; |
for (i = 0; i < SCARD_LOCK_LAST; i++) |
2650 |
} |
{ |
2651 |
|
scard_mutex[i] = NULL; |
2652 |
void |
} |
2653 |
scard_tcp_connect(void) |
} |
|
{ |
|
|
int i; |
|
2654 |
|
|
2655 |
for (i = 0; i < STREAM_COUNT; i++) |
if (!scard_mutex[lock]) |
2656 |
{ |
{ |
2657 |
out[i].size = 4096; |
scard_mutex[lock] = (pthread_mutex_t *) xmalloc(sizeof(pthread_mutex_t)); |
2658 |
out[i].data = (uint8 *) xmalloc(out[i].size); |
pthread_mutex_init(scard_mutex[lock], NULL); |
2659 |
} |
} |
2660 |
|
|
2661 |
|
pthread_mutex_lock(scard_mutex[lock]); |
2662 |
} |
} |
2663 |
|
|
2664 |
void |
void |
2665 |
scard_tcp_reset_state(void) |
scard_unlock(int lock) |
2666 |
{ |
{ |
2667 |
int i; |
pthread_mutex_unlock(scard_mutex[lock]); |
|
struct stream *p; |
|
|
|
|
|
for (i = 0, p = out; i < STREAM_COUNT; i++, p++) |
|
|
{ |
|
|
if (p->data != NULL) |
|
|
xfree(p->data); |
|
|
p->p = NULL; |
|
|
p->end = NULL; |
|
|
p->data = NULL; |
|
|
p->size = 0; |
|
|
p->iso_hdr = NULL; |
|
|
p->mcs_hdr = NULL; |
|
|
p->sec_hdr = NULL; |
|
|
p->rdp_hdr = NULL; |
|
|
p->channel_hdr = NULL; |
|
|
} |
|
2668 |
} |
} |