18
18
*
19
19
*/
20
20
21
+ /**
22
+ * @file sesman/chansrv/smartcard.c
23
+ *
24
+ * smartcard redirection support
25
+ *
26
+ * This file implements some of the PDUs detailed in [MS-RDPESC].
27
+ *
28
+ * The PDUs use DCE IDL structs. These are required to be re-interpreted
29
+ * in DCE NDR (Netword Data Representation)
30
+ *
31
+ * For more information on this subject see DCE publication C706
32
+ * "DCE 1.1: Remote Procedure Call" 1997. In particular:-
33
+ * Section 4.2 : Describes the IDL
34
+ * Section 14 : Describes the NDR
35
+ */
36
+
21
37
/*
22
38
* smartcard redirection support
23
39
*/
@@ -1085,13 +1101,51 @@ static void
1085
1101
scard_send_ListReaders (IRP * irp , char * context , int context_bytes ,
1086
1102
char * groups , int cchReaders , int wide )
1087
1103
{
1088
- /* see [MS-RDPESC] 2.2.2.4 */
1104
+ /* see [MS-RDPESC] 2.2.2.4
1105
+ *
1106
+ * IDL:-
1107
+ *
1108
+ * typedef struct _REDIR_SCARDCONTEXT {
1109
+ * [range(0,16)] unsigned long cbContext;
1110
+ * [unique] [size_is(cbContext)] byte *pbContext;
1111
+ * } REDIR_SCARDCONTEXT;
1112
+ *
1113
+ * struct _ListReaders_Call {
1114
+ * REDIR_SCARDCONTEXT Context;
1115
+ * [range(0, 65536)] unsigned long cBytes;
1116
+ * [unique] [size_is(cBytes)] const byte *mszGroups;
1117
+ * long fmszReadersIsNULL;
1118
+ * unsigned long cchReaders;
1119
+ * } ListReaders_Call;
1120
+ *
1121
+ * Type summary:-
1122
+ *
1123
+ * Context.cbContext Unsigned 32-bit word
1124
+ * Context.pbContext Embedded full pointer to conformant array of bytes
1125
+ * cBytes Unsigned 32-bit word
1126
+ * mszGroups Embedded full pointer to conformant array of bytes
1127
+ * fmszReaders 32-bit word
1128
+ * cchReaders Unsigned 32-bit word
1129
+ *
1130
+ * NDL:-
1131
+ *
1132
+ * Offset Decription
1133
+ * 0 Context.cbContext
1134
+ * 4 Referent Identifier for pbContext
1135
+ * 8 cBytes
1136
+ * 12 Referent Identifier for mszGroups (or NULL)
1137
+ * 16 fmszReadersIsNULL
1138
+ * 20 cchReaders
1139
+ * 24 Conformant Array pointed to by pbContext
1140
+ * ?? Conformant Array pointed to by mszGroups
1141
+ *
1142
+ */
1089
1143
1090
1144
SMARTCARD * sc ;
1091
1145
struct stream * s ;
1092
1146
int bytes ;
1093
- int bytes_groups ;
1094
- int val ;
1147
+ int bytes_groups ; // Length of NDR for groups + 2 terminators
1148
+ int val ; // Referent Id for mszGroups (assume NULL)
1095
1149
int index ;
1096
1150
int num_chars ;
1097
1151
tui32 ioctl ;
@@ -1129,17 +1183,25 @@ scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
1129
1183
1130
1184
s_push_layer (s , mcs_hdr , 4 ); /* bytes, set later */
1131
1185
out_uint32_le (s , 0x00000000 );
1186
+ // REDIR_SCARDCONTEXT Context;
1132
1187
out_uint32_le (s , context_bytes );
1133
1188
out_uint32_le (s , 0x00020000 );
1189
+ // [range(0, 65536)] unsigned long cBytes;
1134
1190
out_uint32_le (s , bytes_groups );
1191
+ // [unique] [size_is(cBytes)] const byte *mszGroups; (pointer)
1135
1192
out_uint32_le (s , val );
1193
+ // long fmszReadersIsNULL;
1136
1194
out_uint32_le (s , 0x00000000 );
1195
+ // unsigned long cchReaders;
1137
1196
out_uint32_le (s , cchReaders );
1138
1197
1139
- /* insert context */
1198
+ // At the end of the struct come the pointed-to structures
1199
+
1200
+ // Context field pbContext is a Uni-dimensional conformant array
1140
1201
out_uint32_le (s , context_bytes );
1141
1202
out_uint8a (s , context , context_bytes );
1142
1203
1204
+ // mszGroups is also a Uni-dimensional conformant array of bytes
1143
1205
if (bytes_groups > 0 )
1144
1206
{
1145
1207
if (wide )
@@ -1215,8 +1277,69 @@ scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
1215
1277
int wide , tui32 timeout ,
1216
1278
tui32 num_readers , READER_STATE * rsa )
1217
1279
{
1218
- /* see [MS-RDPESC] 2.2.2.11 for ASCII */
1219
- /* see [MS-RDPESC] 2.2.2.12 for Wide char */
1280
+ /* see [MS-RDPESC] 2.2.2.11 for ASCII
1281
+ * see [MS-RDPESC] 2.2.2.12 for Wide char
1282
+ *
1283
+ * Here is a breakdown of the Wide-char variant
1284
+ *
1285
+ * IDL:-
1286
+ *
1287
+ * typedef struct _REDIR_SCARDCONTEXT {
1288
+ * [range(0,16)] unsigned long cbContext;
1289
+ * [unique] [size_is(cbContext)] byte *pbContext;
1290
+ * } REDIR_SCARDCONTEXT;
1291
+ *
1292
+ * typedef struct _ReaderState_Common_Call {
1293
+ * unsigned long dwCurrentState;
1294
+ * unsigned long dwEventState;
1295
+ * [range(0,36)] unsigned long cbAtr;
1296
+ * byte rgbAtr[36];
1297
+ * } ReaderState_Common_Call;
1298
+ *
1299
+ * typedef struct _ReaderStateW {
1300
+ * [string] const wchar_t* szReader;
1301
+ * ReaderState_Common_Call Common;
1302
+ * } ReaderStateW;
1303
+ *
1304
+ * struct _GetStatusChangeW_Call {
1305
+ * REDIR_SCARDCONTEXT Context;
1306
+ * unsigned long dwTimeOut;
1307
+ * [range(0,11)] unsigned long cReaders;
1308
+ * [size_is(cReaders)] ReaderStateW* rgReaderStates;
1309
+ * } GetStatusChangeW_Call;
1310
+ *
1311
+ * Type summary:-
1312
+ *
1313
+ * Context.cbContext Unsigned 32-bit word
1314
+ * Context.pbContext Embedded full pointer to conformant array of bytes
1315
+ * dwTimeOut Unsigned 32-bit word
1316
+ * cReaders Unsigned 32-bit word
1317
+ * rgReaderStates
1318
+ * Embedded full pointer to array of rgReaderStates
1319
+ * rgReaderStates.szReader
1320
+ * Embedded full pointer to conformant and varying
1321
+ * string of [Windows] wchar_t
1322
+ * rgReaderStates.Common.dwCurrentState
1323
+ * Unsigned 32-bit word
1324
+ * rgReaderStates.Common.dwEventState
1325
+ * Unsigned 32-bit word
1326
+ * rgReaderStates.Common.cbAtr
1327
+ * Unsigned 32-bit word
1328
+ * rgReaderStates.Common.rgbAtr[36]
1329
+ * Uni-dimensional fixed array
1330
+ *
1331
+ * NDL:-
1332
+ * Offset Decription
1333
+ * 0 Context.cbContext
1334
+ * 4 Referent Identifier for pbContext
1335
+ * 8 dwTimeOut;
1336
+ * 12 cReaders;
1337
+ * 16 Referent Identifier for rgReaderStates
1338
+ * 20 Conformant Array pointed to by pbContext
1339
+ * ?? Conformant Array pointed to by rgReaderStates. Each element
1340
+ * of this array has a pointer to a string for the name
1341
+ * ?? String names pointed to in the above array.
1342
+ */
1220
1343
1221
1344
SMARTCARD * sc ;
1222
1345
READER_STATE * rs ;
@@ -1245,27 +1368,40 @@ scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
1245
1368
1246
1369
s_push_layer (s , mcs_hdr , 4 ); /* bytes, set later */
1247
1370
out_uint32_le (s , 0x00000000 );
1371
+ // REDIR_SCARDCONTEXT Context;
1248
1372
out_uint32_le (s , context_bytes );
1249
1373
out_uint32_le (s , 0x00020000 );
1250
1374
1375
+ // unsigned long dwTimeOut;
1251
1376
out_uint32_le (s , timeout );
1377
+ // [range(0,11)] unsigned long cReaders;
1252
1378
out_uint32_le (s , num_readers );
1253
- out_uint32_le (s , 0x00020004 ); /* ? */
1379
+ // [size_is(cReaders)] ReaderStateW* rgReaderStates;
1380
+ out_uint32_le (s , 0x00020004 );
1254
1381
1255
- /* insert context */
1382
+ // At the end of the struct come the pointed-to structures
1383
+
1384
+ // Context field pbContext is a Uni-dimensional conformant array
1256
1385
out_uint32_le (s , context_bytes );
1257
1386
out_uint8a (s , context , context_bytes );
1258
1387
1388
+ // rgReaderState is a Uni-dimensional conformant array
1259
1389
out_uint32_le (s , num_readers );
1260
1390
1261
1391
/* insert card reader state */
1262
1392
for (i = 0 ; i < num_readers ; i ++ )
1263
1393
{
1264
1394
rs = & rsa [i ];
1265
- out_uint32_le (s , 0x00020008 ); /* ? */
1395
+ // [string] const wchar_t* szReader (wide)
1396
+ // [string] const char_t* szReader (ASCII)
1397
+ out_uint32_le (s , 0x00020008 + (i * 4 ));
1398
+ // unsigned long dwCurrentState;
1266
1399
out_uint32_le (s , rs -> current_state );
1400
+ // unsigned long dwEventState;
1267
1401
out_uint32_le (s , rs -> event_state );
1402
+ // [range(0,36)] unsigned long cbAtr;
1268
1403
out_uint32_le (s , rs -> atr_len );
1404
+ // byte rgbAtr[36];
1269
1405
out_uint8p (s , rs -> atr , 33 );
1270
1406
out_uint8s (s , 3 );
1271
1407
}
@@ -1342,8 +1478,53 @@ static void
1342
1478
scard_send_Connect (IRP * irp , char * context , int context_bytes ,
1343
1479
int wide , READER_STATE * rs )
1344
1480
{
1345
- /* see [MS-RDPESC] 2.2.2.13 for ASCII */
1346
- /* see [MS-RDPESC] 2.2.2.14 for Wide char */
1481
+ /* see [MS-RDPESC] 2.2.2.13 for ASCII
1482
+ * see [MS-RDPESC] 2.2.2.14 for Wide char
1483
+ *
1484
+ * Here is a breakdown of the Wide-char variant
1485
+ *
1486
+ * IDL:-
1487
+ *
1488
+ * typedef struct _REDIR_SCARDCONTEXT {
1489
+ * [range(0,16)] unsigned long cbContext;
1490
+ * [unique] [size_is(cbContext)] byte *pbContext;
1491
+ * } REDIR_SCARDCONTEXT;
1492
+ *
1493
+ * typedef struct _Connect_Common {
1494
+ * REDIR_SCARDCONTEXT Context;
1495
+ * unsigned long dwShareMode;
1496
+ * unsigned long dwPreferredProtocols;
1497
+ * } Connect_Common;
1498
+ *
1499
+ * typedef struct _ConnectW_Call {
1500
+ * [string] const wchar_t* szReader;
1501
+ * Connect_Common Common;
1502
+ * } ConnectW_Call;
1503
+ *
1504
+ * Type summary:-
1505
+ *
1506
+ * szReader Embedded full pointer to conformant and varying
1507
+ * string of [Windows] wchar_t
1508
+ * Common.Context.cbContext
1509
+ * Unsigned 32-bit word
1510
+ * Common.Context.pbContext
1511
+ * Embedded full pointer to conformant array of bytes
1512
+ * Common.dwShareMode Unsigned 32-bit word
1513
+ * Common.dwPreferredProtocols
1514
+ * Unsigned 32-bit word
1515
+ *
1516
+ * NDL:-
1517
+ *
1518
+ * Offset Decription
1519
+ * 0 Referent Identifier for szReader
1520
+ * 4 Context.cbContext
1521
+ * 8 Referent Identifier for pbContext
1522
+ * 12 dwShareMode
1523
+ * 16 dwPreferredProtocols
1524
+ * 20 Conformant Array pointed to by szReader
1525
+ * ?? Conformant Array pointed to by pbContext
1526
+ *
1527
+ */
1347
1528
1348
1529
SMARTCARD * sc ;
1349
1530
struct stream * s ;
@@ -1370,11 +1551,19 @@ scard_send_Connect(IRP *irp, char *context, int context_bytes,
1370
1551
1371
1552
s_push_layer (s , mcs_hdr , 4 ); /* bytes, set later */
1372
1553
out_uint32_le (s , 0x00000000 );
1554
+ // [string] const wchar_t* szReader;
1373
1555
out_uint32_le (s , 0x00020000 );
1556
+
1557
+ // REDIR_SCARDCONTEXT Context;
1374
1558
out_uint32_le (s , context_bytes );
1375
1559
out_uint32_le (s , 0x00020004 );
1560
+
1561
+ // unsigned long dwShareMode;
1376
1562
out_uint32_le (s , rs -> dwShareMode );
1563
+ // unsigned long dwPreferredProtocols;
1377
1564
out_uint32_le (s , rs -> dwPreferredProtocols );
1565
+
1566
+ /* insert card reader name */
1378
1567
num_chars = g_mbstowcs (w_reader_name , rs -> reader_name , 99 );
1379
1568
out_uint32_le (s , num_chars + 2 );
1380
1569
out_uint32_le (s , 0x00000000 );
0 commit comments