VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/UsbCardReader.cpp@ 85121

Last change on this file since 85121 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 66.4 KB
Line 
1/* $Id: UsbCardReader.cpp 85121 2020-07-08 19:33:26Z vboxsync $ */
2/** @file
3 * UsbCardReader - Driver Interface to USB Smart Card Reader emulation.
4 */
5
6/*
7 * Copyright (C) 2011-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_USB_CARDREADER
23#include "LoggingNew.h"
24
25#include "UsbCardReader.h"
26#include "ConsoleImpl.h"
27#include "ConsoleVRDPServer.h"
28
29#include <VBox/vmm/pdmdrv.h>
30#include <VBox/vmm/pdmcardreaderinfs.h>
31#include <VBox/err.h>
32
33#include <iprt/req.h>
34
35
36/*********************************************************************************************************************************
37* Structures and Typedefs *
38*********************************************************************************************************************************/
39typedef struct USBCARDREADER USBCARDREADER;
40typedef struct USBCARDREADER *PUSBCARDREADER;
41
42struct USBCARDREADER
43{
44 UsbCardReader *pUsbCardReader;
45
46 PPDMDRVINS pDrvIns;
47
48 PDMICARDREADERDOWN ICardReaderDown;
49 PPDMICARDREADERUP pICardReaderUp;
50
51 /* Thread handling Cmd to card reader */
52 PPDMTHREAD pThrCardReaderCmd;
53 /* Queue handling requests to cardreader */
54 RTREQQUEUE hReqQCardReaderCmd;
55};
56
57
58/*
59 * Command queue's callbacks.
60 */
61
62static DECLCALLBACK(void) drvCardReaderCmdStatusChange(PUSBCARDREADER pThis,
63 void *pvUser,
64 uint32_t u32Timeout,
65 PDMICARDREADER_READERSTATE *paReaderStats,
66 uint32_t cReaderStats)
67{
68 LogFlowFunc(("ENTER: pvUser:%p, u32Timeout:%d\n",
69 pvUser, u32Timeout));
70
71 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
72 if (!pUsbCardReader)
73 {
74 pThis->pICardReaderUp->pfnSetStatusChange(pThis->pICardReaderUp,
75 pvUser, VRDE_SCARD_E_NO_SMARTCARD,
76 paReaderStats, cReaderStats);
77 }
78 else
79 {
80 pUsbCardReader->GetStatusChange(pThis, pvUser, u32Timeout,
81 paReaderStats, cReaderStats);
82 }
83
84 LogFlowFuncLeave();
85}
86
87
88static DECLCALLBACK(void) drvCardReaderCmdEstablishContext(PUSBCARDREADER pThis)
89{
90 LogFlowFunc(("\n"));
91
92 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
93 if (!pUsbCardReader)
94 {
95 pThis->pICardReaderUp->pfnEstablishContext(pThis->pICardReaderUp,
96 VRDE_SCARD_E_NO_SMARTCARD);
97 }
98 else
99 {
100 pUsbCardReader->EstablishContext(pThis);
101 }
102
103 LogFlowFuncLeave();
104}
105
106static DECLCALLBACK(void) drvCardReaderCmdReleaseContext(PUSBCARDREADER pThis,
107 void *pvUser)
108{
109 LogFlowFunc(("ENTER: pvUser:%p\n",
110 pvUser));
111 NOREF(pvUser);
112
113 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
114 if (!pUsbCardReader)
115 {
116 /* Do nothing. */
117 }
118 else
119 {
120 pUsbCardReader->ReleaseContext(pThis);
121 }
122
123 LogFlowFuncLeave();
124}
125
126static DECLCALLBACK(void) drvCardReaderCmdStatus(PUSBCARDREADER pThis,
127 void *pvUser)
128{
129 LogFlowFunc(("ENTER: pvUser:%p\n",
130 pvUser));
131
132 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
133 if (!pUsbCardReader)
134 {
135 pThis->pICardReaderUp->pfnStatus(pThis->pICardReaderUp,
136 pvUser,
137 VRDE_SCARD_E_NO_SMARTCARD,
138 /* pszReaderName */ NULL,
139 /* cchReaderName */ 0,
140 /* u32CardState */ 0,
141 /* u32Protocol */ 0,
142 /* pu8Atr */ 0,
143 /* cbAtr */ 0);
144 }
145 else
146 {
147 pUsbCardReader->Status(pThis, pvUser);
148 }
149
150 LogFlowFuncLeave();
151}
152
153static DECLCALLBACK(void) drvCardReaderCmdConnect(PUSBCARDREADER pThis,
154 void *pvUser,
155 const char *pcszCardReaderName,
156 uint32_t u32ShareMode,
157 uint32_t u32PreferredProtocols)
158{
159 LogFlowFunc(("ENTER: pvUser:%p, pcszCardReaderName:%s, u32ShareMode:%RX32, u32PreferredProtocols:%RX32\n",
160 pvUser, pcszCardReaderName, u32ShareMode, u32PreferredProtocols));
161
162 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
163 if (!pUsbCardReader)
164 {
165 pThis->pICardReaderUp->pfnConnect(pThis->pICardReaderUp,
166 pvUser,
167 VRDE_SCARD_E_NO_SMARTCARD,
168 0);
169 }
170 else
171 {
172 pUsbCardReader->Connect(pThis, pvUser, pcszCardReaderName,
173 u32ShareMode, u32PreferredProtocols);
174 }
175
176 LogFlowFuncLeave();
177}
178
179static DECLCALLBACK(void) drvCardReaderCmdDisconnect(PUSBCARDREADER pThis,
180 void *pvUser,
181 uint32_t u32Disposition)
182{
183 LogFlowFunc(("ENTER: pvUser:%p, u32Disposition:%RX32\n",
184 pvUser, u32Disposition));
185
186 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
187 if (!pUsbCardReader)
188 {
189 pThis->pICardReaderUp->pfnDisconnect(pThis->pICardReaderUp,
190 pvUser,
191 VRDE_SCARD_E_NO_SMARTCARD);
192 }
193 else
194 {
195 pUsbCardReader->Disconnect(pThis, pvUser, u32Disposition);
196 }
197
198 LogFlowFuncLeave();
199}
200
201static DECLCALLBACK(void) drvCardReaderCmdTransmit(PUSBCARDREADER pThis,
202 void *pvUser,
203 PDMICARDREADER_IO_REQUEST *pioSendRequest,
204 uint8_t *pu8SendBuffer,
205 uint32_t cbSendBuffer,
206 uint32_t cbRecvBuffer)
207{
208 LogFlowFunc(("ENTER: pvUser:%p, pioSendRequest:%p, pu8SendBuffer:%p, cbSendBuffer:%d, cbRecvBuffer:%d\n",
209 pvUser, pioSendRequest, pu8SendBuffer, cbSendBuffer, cbRecvBuffer));
210
211 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
212 if (!pUsbCardReader)
213 {
214 pThis->pICardReaderUp->pfnTransmit(pThis->pICardReaderUp,
215 pvUser,
216 VRDE_SCARD_E_NO_SMARTCARD,
217 /* pioRecvPci */ NULL,
218 /* pu8RecvBuffer */ NULL,
219 /* cbRecvBuffer*/ 0);
220 }
221 else
222 {
223 pUsbCardReader->Transmit(pThis, pvUser, pioSendRequest,
224 pu8SendBuffer, cbSendBuffer, cbRecvBuffer);
225 }
226
227 /* Clean up buffers allocated by driver */
228 RTMemFree(pioSendRequest);
229 RTMemFree(pu8SendBuffer);
230
231 LogFlowFuncLeave();
232}
233
234static DECLCALLBACK(void) drvCardReaderCmdGetAttr(PUSBCARDREADER pThis,
235 void *pvUser,
236 uint32_t u32AttrId,
237 uint32_t cbAttrib)
238{
239 LogFlowFunc(("ENTER: pvUser:%p, u32AttrId:%RX32, cbAttrib:%d\n",
240 pvUser, u32AttrId, cbAttrib));
241
242 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
243 if (!pUsbCardReader)
244 {
245 pThis->pICardReaderUp->pfnGetAttrib(pThis->pICardReaderUp,
246 pvUser,
247 VRDE_SCARD_E_NO_SMARTCARD,
248 u32AttrId,
249 /* pvAttrib */ NULL,
250 /* cbAttrib */ 0);
251 }
252 else
253 {
254 pUsbCardReader->GetAttrib(pThis, pvUser, u32AttrId, cbAttrib);
255 }
256
257 LogFlowFuncLeave();
258}
259
260static DECLCALLBACK(void) drvCardReaderCmdSetAttr(PUSBCARDREADER pThis,
261 void *pvUser,
262 uint32_t u32AttrId,
263 void *pvAttrib,
264 uint32_t cbAttrib)
265{
266 LogFlowFunc(("ENTER: pvUser:%p, u32AttrId:%RX32, pvAttrib:%p, cbAttrib:%d\n",
267 pvUser, u32AttrId, pvAttrib, cbAttrib));
268
269 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
270 if (!pUsbCardReader)
271 {
272 pThis->pICardReaderUp->pfnSetAttrib(pThis->pICardReaderUp,
273 pvUser,
274 VRDE_SCARD_E_NO_SMARTCARD,
275 u32AttrId);
276 }
277 else
278 {
279 pUsbCardReader->SetAttrib(pThis, pvUser, u32AttrId, (uint8_t *)pvAttrib, cbAttrib);
280 }
281
282 /* Clean up buffers allocated by driver */
283 RTMemFree(pvAttrib);
284
285 LogFlowFuncLeave();
286}
287
288static DECLCALLBACK(void) drvCardReaderCmdControl(PUSBCARDREADER pThis,
289 void *pvUser,
290 uint32_t u32ControlCode,
291 void *pvInBuffer,
292 uint32_t cbInBuffer,
293 uint32_t cbOutBuffer)
294{
295 LogFlowFunc(("ENTER: pvUser:%p, u32ControlCode:%RX32, pvInBuffer:%p, cbInBuffer:%d, cbOutBuffer:%d\n",
296 pvUser, u32ControlCode, pvInBuffer, cbInBuffer, cbOutBuffer));
297
298 UsbCardReader *pUsbCardReader = pThis->pUsbCardReader;
299 if (!pUsbCardReader)
300 {
301 pThis->pICardReaderUp->pfnControl(pThis->pICardReaderUp,
302 pvUser,
303 VRDE_SCARD_E_NO_SMARTCARD,
304 u32ControlCode,
305 /* pvOutBuffer */ NULL,
306 /* cbOutBuffer */ 0);
307 }
308 else
309 {
310 pUsbCardReader->Control(pThis, pvUser, u32ControlCode,
311 (uint8_t *)pvInBuffer, cbInBuffer, cbOutBuffer);
312 }
313
314 /* Clean up buffers allocated by driver */
315 RTMemFree(pvInBuffer);
316
317 LogFlowFuncLeave();
318}
319
320
321/*
322 * PDMICARDREADERDOWN - interface
323 */
324
325static DECLCALLBACK(int) drvCardReaderDownConnect(PPDMICARDREADERDOWN pInterface,
326 void *pvUser,
327 const char *pcszCardReaderName,
328 uint32_t u32ShareMode,
329 uint32_t u32PreferredProtocols)
330{
331 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
332 LogFlowFunc(("ENTER: pcszCardReaderName:%s, pvUser:%p, u32ShareMode:%RX32, u32PreferredProtocols:%RX32\n",
333 pcszCardReaderName, pvUser, u32ShareMode, u32PreferredProtocols));
334 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
335 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
336 (PFNRT)drvCardReaderCmdConnect, 5,
337 pThis, pvUser, pcszCardReaderName, u32ShareMode, u32PreferredProtocols);
338 AssertRC(rc);
339 LogFlowFunc(("LEAVE: %Rrc\n", rc));
340 return rc;
341}
342
343static DECLCALLBACK(int) drvCardReaderDownDisconnect(PPDMICARDREADERDOWN pInterface,
344 void *pvUser,
345 uint32_t u32Disposition)
346{
347 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
348 LogFlowFunc(("ENTER: pvUser:%p, u32Disposition:%RX32\n",
349 pvUser, u32Disposition));
350 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
351 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
352 (PFNRT)drvCardReaderCmdDisconnect, 3,
353 pThis, pvUser, u32Disposition);
354 AssertRC(rc);
355 LogFlowFunc(("LEAVE: %Rrc\n", rc));
356 return rc;
357}
358
359static DECLCALLBACK(int) drvCardReaderDownEstablishContext(PPDMICARDREADERDOWN pInterface)
360{
361 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
362 LogFlowFunc(("ENTER:\n"));
363 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
364 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
365 (PFNRT)drvCardReaderCmdEstablishContext, 1,
366 pThis);
367 AssertRC(rc);
368 LogFlowFunc(("LEAVE: %Rrc\n", rc));
369 return rc;
370}
371
372static DECLCALLBACK(int) drvCardReaderDownReleaseContext(PPDMICARDREADERDOWN pInterface,
373 void *pvUser)
374{
375 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
376 LogFlowFunc(("ENTER: pvUser:%p\n",
377 pvUser));
378 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
379 /** @todo Device calls this when the driver already destroyed. */
380 if (pThis->hReqQCardReaderCmd == NIL_RTREQQUEUE)
381 {
382 LogFlowFunc(("LEAVE: device already deleted.\n"));
383 return VINF_SUCCESS;
384 }
385
386 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
387 (PFNRT)drvCardReaderCmdReleaseContext, 2,
388 pThis, pvUser);
389 AssertRC(rc);
390 LogFlowFunc(("LEAVE: %Rrc\n", rc));
391 return rc;
392}
393
394static DECLCALLBACK(int) drvCardReaderDownStatus(PPDMICARDREADERDOWN pInterface,
395 void *pvUser,
396 uint32_t cchReaderName,
397 uint32_t cbAtrLen)
398{
399 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
400 LogFlowFunc(("ENTER: pvUser:%p, cchReaderName:%d, cbAtrLen:%d\n",
401 pvUser, cchReaderName, cbAtrLen));
402 NOREF(cchReaderName);
403 NOREF(cbAtrLen);
404 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
405 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
406 (PFNRT)drvCardReaderCmdStatus, 2,
407 pThis, pvUser);
408 AssertRC(rc);
409 LogFlowFunc(("LEAVE: %Rrc\n", rc));
410 return rc;
411}
412
413static DECLCALLBACK(int) drvCardReaderDownGetStatusChange(PPDMICARDREADERDOWN pInterface,
414 void *pvUser,
415 uint32_t u32Timeout,
416 PDMICARDREADER_READERSTATE *paReaderStats,
417 uint32_t cReaderStats)
418{
419 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
420 LogFlowFunc(("ENTER: pvUser:%p, u32Timeout:%d, cReaderStats:%d\n",
421 pvUser, u32Timeout, cReaderStats));
422 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
423 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
424 (PFNRT)drvCardReaderCmdStatusChange, 5,
425 pThis, pvUser, u32Timeout, paReaderStats, cReaderStats);
426 AssertRC(rc);
427 LogFlowFunc(("LEAVE: %Rrc\n", rc));
428 return rc;
429}
430
431static DECLCALLBACK(int) drvCardReaderDownBeginTransaction(PPDMICARDREADERDOWN pInterface,
432 void *pvUser)
433{
434 RT_NOREF(pvUser);
435 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
436 LogFlowFunc(("ENTER: pvUser:%p\n",
437 pvUser));
438 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown); NOREF(pThis);
439 int rc = VERR_NOT_SUPPORTED;
440 AssertRC(rc);
441 LogFlowFunc(("LEAVE: %Rrc\n", rc));
442 return rc;
443}
444
445static DECLCALLBACK(int) drvCardReaderDownEndTransaction(PPDMICARDREADERDOWN pInterface,
446 void *pvUser,
447 uint32_t u32Disposition)
448{
449 RT_NOREF(pvUser, u32Disposition);
450 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
451 LogFlowFunc(("ENTER: pvUser:%p, u32Disposition:%RX32\n",
452 pvUser, u32Disposition));
453 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown); NOREF(pThis);
454 int rc = VERR_NOT_SUPPORTED;
455 AssertRC(rc);
456 LogFlowFunc(("LEAVE: %Rrc\n", rc));
457 return rc;
458}
459
460static DECLCALLBACK(int) drvCardReaderDownTransmit(PPDMICARDREADERDOWN pInterface,
461 void *pvUser,
462 const PDMICARDREADER_IO_REQUEST *pioSendRequest,
463 const uint8_t *pu8SendBuffer,
464 uint32_t cbSendBuffer,
465 uint32_t cbRecvBuffer)
466{
467 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
468 LogFlowFunc(("ENTER: pvUser:%p, pioSendRequest:%p, pu8SendBuffer:%p, cbSendBuffer:%d, cbRecvBuffer:%d\n",
469 pvUser, pioSendRequest, pu8SendBuffer, cbSendBuffer, cbRecvBuffer));
470 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
471 uint8_t *pu8SendBufferCopy = NULL;
472 if ( pu8SendBuffer
473 && cbSendBuffer)
474 {
475 pu8SendBufferCopy = (uint8_t *)RTMemDup(pu8SendBuffer, cbSendBuffer);
476 if (!pu8SendBufferCopy)
477 {
478 return VERR_NO_MEMORY;
479 }
480 }
481 PDMICARDREADER_IO_REQUEST *pioSendRequestCopy = NULL;
482 if (pioSendRequest)
483 {
484 pioSendRequestCopy = (PDMICARDREADER_IO_REQUEST *)RTMemDup(pioSendRequest, pioSendRequest->cbPciLength);
485 if (!pioSendRequestCopy)
486 {
487 RTMemFree(pu8SendBufferCopy);
488 return VERR_NO_MEMORY;
489 }
490 }
491 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0,RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
492 (PFNRT)drvCardReaderCmdTransmit, 6,
493 pThis, pvUser, pioSendRequestCopy, pu8SendBufferCopy, cbSendBuffer, cbRecvBuffer);
494 AssertRC(rc);
495 LogFlowFunc(("LEAVE: %Rrc\n", rc));
496 return rc;
497}
498
499static DECLCALLBACK(int) drvCardReaderDownGetAttr(PPDMICARDREADERDOWN pInterface,
500 void *pvUser,
501 uint32_t u32AttribId,
502 uint32_t cbAttrib)
503{
504 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
505 LogFlowFunc(("ENTER: pvUser:%p, u32AttribId:%RX32, cbAttrib:%d\n",
506 pvUser, u32AttribId, cbAttrib));
507 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
508 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
509 (PFNRT)drvCardReaderCmdGetAttr, 4,
510 pThis, pvUser, u32AttribId, cbAttrib);
511 AssertRC(rc);
512 LogFlowFunc(("LEAVE: %Rrc\n", rc));
513 return rc;
514}
515
516static DECLCALLBACK(int) drvCardReaderDownSetAttr(PPDMICARDREADERDOWN pInterface,
517 void *pvUser,
518 uint32_t u32AttribId,
519 const void *pvAttrib,
520 uint32_t cbAttrib)
521{
522 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
523 LogFlowFunc(("ENTER: pvUser:%p, u32AttribId:%RX32, pvAttrib:%p, cbAttrib:%d\n",
524 pvUser, u32AttribId, pvAttrib, cbAttrib));
525 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
526 void *pvAttribCopy = NULL;
527 if ( pvAttrib
528 && cbAttrib)
529 {
530 pvAttribCopy = RTMemDup(pvAttrib, cbAttrib);
531 AssertPtrReturn(pvAttribCopy, VERR_NO_MEMORY);
532 }
533 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
534 (PFNRT)drvCardReaderCmdSetAttr, 5,
535 pThis, pvUser, u32AttribId, pvAttribCopy, cbAttrib);
536 AssertRC(rc);
537 LogFlowFunc(("LEAVE: %Rrc\n", rc));
538 return rc;
539}
540
541static DECLCALLBACK(int) drvCardReaderDownControl(PPDMICARDREADERDOWN pInterface,
542 void *pvUser,
543 uint32_t u32ControlCode,
544 const void *pvInBuffer,
545 uint32_t cbInBuffer,
546 uint32_t cbOutBuffer)
547{
548 AssertPtrReturn(pInterface, VERR_INVALID_PARAMETER);
549 LogFlowFunc(("ENTER: pvUser:%p, u32ControlCode:%RX32 pvInBuffer:%p, cbInBuffer:%d, cbOutBuffer:%d\n",
550 pvUser, u32ControlCode, pvInBuffer, cbInBuffer, cbOutBuffer));
551 PUSBCARDREADER pThis = RT_FROM_MEMBER(pInterface, USBCARDREADER, ICardReaderDown);
552 void *pvInBufferCopy = NULL;
553 if ( pvInBuffer
554 && cbInBuffer)
555 {
556 pvInBufferCopy = RTMemDup(pvInBuffer, cbInBuffer);
557 AssertReturn(pvInBufferCopy, VERR_NO_MEMORY);
558 }
559 int rc = RTReqQueueCallEx(pThis->hReqQCardReaderCmd, NULL, 0, RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
560 (PFNRT)drvCardReaderCmdControl, 6,
561 pThis, pvUser, u32ControlCode, pvInBufferCopy, cbInBuffer, cbOutBuffer);
562 AssertRC(rc);
563 LogFlowFunc(("LEAVE: %Rrc\n", rc));
564 return rc;
565}
566
567
568/*
569 * Cardreader driver thread routines
570 */
571static DECLCALLBACK(int) drvCardReaderThreadCmd(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
572{
573 int rc = VINF_SUCCESS;
574 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
575
576 LogFlowFunc(("ENTER: pDrvIns:%d, state %d\n", pDrvIns->iInstance, pThread->enmState));
577
578 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
579 {
580 LogFlowFunc(("LEAVE: INITIALIZING: VINF_SUCCESS\n"));
581 return VINF_SUCCESS;
582 }
583
584 while (pThread->enmState == PDMTHREADSTATE_RUNNING)
585 {
586 rc = RTReqQueueProcess(pThis->hReqQCardReaderCmd, RT_INDEFINITE_WAIT);
587
588 AssertMsg(rc == VWRN_STATE_CHANGED,
589 ("Left RTReqProcess and error code is not VWRN_STATE_CHANGED rc=%Rrc\n",
590 rc));
591 }
592
593 LogFlowFunc(("LEAVE: %Rrc\n", rc));
594 return rc;
595}
596
597static DECLCALLBACK(int) drvCardReaderWakeupFunc(PUSBCARDREADER pThis)
598{
599 NOREF(pThis);
600 /* Returning a VINF_* will cause RTReqQueueProcess return. */
601 return VWRN_STATE_CHANGED;
602}
603
604static DECLCALLBACK(int) drvCardReaderThreadCmdWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
605{
606 RT_NOREF(pThread);
607 LogFlowFunc(("ENTER: pDrvIns:%i\n", pDrvIns->iInstance));
608 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
609
610 AssertReturn(pThis->hReqQCardReaderCmd != NIL_RTREQQUEUE, VERR_INVALID_STATE);
611
612 PRTREQ pReq;
613 int rc = RTReqQueueCall(pThis->hReqQCardReaderCmd, &pReq, 10000, (PFNRT)drvCardReaderWakeupFunc, 1, pThis);
614 AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n", rc));
615
616 if (RT_SUCCESS(rc))
617 RTReqRelease(pReq);
618 /** @todo handle VERR_TIMEOUT */
619
620 return rc;
621}
622
623
624/*
625 * USB Card reader driver implementation.
626 */
627
628UsbCardReader::UsbCardReader(Console *console)
629 :
630 mpDrv(NULL),
631 mParent(console),
632 m_pRemote(NULL)
633{
634 LogFlowFunc(("\n"));
635}
636
637UsbCardReader::~UsbCardReader()
638{
639 LogFlowFunc(("mpDrv %p\n", mpDrv));
640 if (mpDrv)
641 {
642 mpDrv->pUsbCardReader = NULL;
643 mpDrv = NULL;
644 }
645}
646
647typedef struct UCRREMOTEREADER
648{
649 bool fAvailable;
650 char szReaderName[1024];
651
652 bool fHandle;
653 VRDESCARDHANDLE hCard;
654} UCRREMOTEREADER;
655
656struct UCRREMOTE
657{
658 UsbCardReader *pUsbCardReader;
659
660 /* The remote identifiers. */
661 uint32_t u32ClientId;
662 uint32_t u32DeviceId;
663
664 bool fContext;
665 VRDESCARDCONTEXT context;
666
667 /* Possible a few readers. Currently only one. */
668 UCRREMOTEREADER reader;
669};
670
671typedef struct UCRREQCTX
672{
673 UCRREMOTE *pRemote;
674 uint32_t u32Function;
675 void *pvUser;
676 union
677 {
678 struct
679 {
680 PDMICARDREADER_READERSTATE *paReaderStats;
681 uint32_t cReaderStats;
682 } GetStatusChange;
683 struct
684 {
685 uint32_t u32AttrId;
686 } GetAttrib;
687 struct
688 {
689 uint32_t u32AttrId;
690 } SetAttrib;
691 struct
692 {
693 uint32_t u32ControlCode;
694 } Control;
695 } u;
696} UCRREQCTX;
697
698int UsbCardReader::vrdeSCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData)
699{
700 int rc = mParent->i_consoleVRDPServer()->SCardRequest(pvUser, u32Function, pvData, cbData);
701 LogFlowFunc(("%d %Rrc\n", u32Function, rc));
702 return rc;
703}
704
705int UsbCardReader::VRDENotify(uint32_t u32Id, void *pvData, uint32_t cbData)
706{
707 RT_NOREF(cbData);
708 int rc = VINF_SUCCESS;
709
710 switch (u32Id)
711 {
712 case VRDE_SCARD_NOTIFY_ATTACH:
713 {
714 VRDESCARDNOTIFYATTACH *p = (VRDESCARDNOTIFYATTACH *)pvData;
715 Assert(cbData == sizeof(VRDESCARDNOTIFYATTACH));
716
717 LogFlowFunc(("[%d,%d]\n", p->u32ClientId, p->u32DeviceId));
718
719 /* Add this remote instance, which allow access to card readers attached to the client, to the list.
720 * @todo currently only one device is allowed.
721 */
722 if (m_pRemote)
723 {
724 AssertFailed();
725 rc = VERR_NOT_SUPPORTED;
726 break;
727 }
728 UCRREMOTE *pRemote = (UCRREMOTE *)RTMemAllocZ(sizeof(UCRREMOTE));
729 if (pRemote == NULL)
730 {
731 rc = VERR_NO_MEMORY;
732 break;
733 }
734
735 pRemote->pUsbCardReader = this;
736 pRemote->u32ClientId = p->u32ClientId;
737 pRemote->u32DeviceId = p->u32DeviceId;
738
739 m_pRemote = pRemote;
740
741 /* Try to establish a context. */
742 VRDESCARDESTABLISHCONTEXTREQ req;
743 req.u32ClientId = m_pRemote->u32ClientId;
744 req.u32DeviceId = m_pRemote->u32DeviceId;
745
746 rc = vrdeSCardRequest(m_pRemote, VRDE_SCARD_FN_ESTABLISHCONTEXT, &req, sizeof(req));
747
748 LogFlowFunc(("sent ESTABLISHCONTEXT\n"));
749 } break;
750
751 case VRDE_SCARD_NOTIFY_DETACH:
752 {
753 VRDESCARDNOTIFYDETACH *p = (VRDESCARDNOTIFYDETACH *)pvData; NOREF(p);
754 Assert(cbData == sizeof(VRDESCARDNOTIFYDETACH));
755
756 /** @todo Just free. There should be no pending requests, because VRDP cancels them. */
757 RTMemFree(m_pRemote);
758 m_pRemote = NULL;
759 } break;
760
761 default:
762 rc = VERR_INVALID_PARAMETER;
763 AssertFailed();
764 break;
765 }
766
767 return rc;
768}
769
770int UsbCardReader::VRDEResponse(int rcRequest, void *pvUser, uint32_t u32Function, void *pvData, uint32_t cbData)
771{
772 RT_NOREF(cbData);
773 int rc = VINF_SUCCESS;
774
775 LogFlowFunc(("%Rrc %p %u %p %u\n",
776 rcRequest, pvUser, u32Function, pvData, cbData));
777
778 switch (u32Function)
779 {
780 case VRDE_SCARD_FN_ESTABLISHCONTEXT:
781 {
782 Assert(cbData == sizeof(VRDESCARDESTABLISHCONTEXTRSP) || RT_FAILURE(rcRequest));
783 VRDESCARDESTABLISHCONTEXTRSP *pRsp = (VRDESCARDESTABLISHCONTEXTRSP *)pvData;
784 UCRREMOTE *pRemote = (UCRREMOTE *)pvUser;
785
786 /* Check if the context was created. */
787 Assert(!pRemote->fContext);
788 if ( RT_SUCCESS(rcRequest)
789 && pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
790 {
791 pRemote->fContext = true;
792 pRemote->context = pRsp->Context;
793
794 LogFlowFunc(("ESTABLISHCONTEXT success\n"));
795
796 /* Now list readers attached to the remote client. */
797 VRDESCARDLISTREADERSREQ req;
798 req.Context = pRemote->context;
799
800 rc = vrdeSCardRequest(pRemote, VRDE_SCARD_FN_LISTREADERS, &req, sizeof(req));
801 }
802 } break;
803
804 case VRDE_SCARD_FN_LISTREADERS:
805 {
806 Assert(cbData == sizeof(VRDESCARDLISTREADERSRSP) || RT_FAILURE(rcRequest));
807 VRDESCARDLISTREADERSRSP *pRsp = (VRDESCARDLISTREADERSRSP *)pvData;
808 UCRREMOTE *pRemote = (UCRREMOTE *)pvUser;
809
810 Assert(pRemote->fContext);
811 if ( RT_SUCCESS(rcRequest)
812 && pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS
813 && pRemote->fContext)
814 {
815 LogFlowFunc(("LISTREADERS: cReaders %d\n",
816 pRsp->cReaders));
817
818 uint32_t i;
819 for (i = 0; i < pRsp->cReaders; i++)
820 {
821 LogFlowFunc(("LISTREADERS: [%d] [%s]\n",
822 i, pRsp->apszNames[i]));
823
824 /** @todo only the first reader is supported. */
825 if (i != 0)
826 {
827 continue;
828 }
829
830 RTStrCopy(pRemote->reader.szReaderName, sizeof(pRemote->reader.szReaderName), pRsp->apszNames[i]);
831 pRemote->reader.fHandle = false;
832 pRemote->reader.fAvailable = true;
833 }
834 }
835 } break;
836
837 case VRDE_SCARD_FN_RELEASECONTEXT:
838 {
839 Assert(cbData == sizeof(VRDESCARDRELEASECONTEXTRSP) || RT_FAILURE(rcRequest));
840 VRDESCARDRELEASECONTEXTRSP *pRsp = (VRDESCARDRELEASECONTEXTRSP *)pvData; NOREF(pRsp);
841 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
842
843 Assert(pCtx->u32Function == u32Function);
844
845 LogFlowFunc(("RELEASECONTEXT completed\n"));
846
847 /* No notification is expected here by the caller. */
848 Assert(!m_pRemote->fContext);
849 } break;
850
851 case VRDE_SCARD_FN_GETSTATUSCHANGE:
852 {
853 Assert(cbData == sizeof(VRDESCARDGETSTATUSCHANGERSP) || RT_FAILURE(rcRequest));
854 VRDESCARDGETSTATUSCHANGERSP *pRsp = (VRDESCARDGETSTATUSCHANGERSP *)pvData;
855 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
856
857 Assert(pCtx->u32Function == u32Function);
858
859 LogFlowFunc(("GETSTATUSCHANGE\n"));
860
861 uint32_t rcCard;
862 if (RT_FAILURE(rcRequest))
863 {
864 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
865 }
866 else
867 {
868 rcCard = pRsp->u32ReturnCode;
869
870 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
871 {
872 uint32_t i;
873 for (i = 0; i < pRsp->cReaders; i++)
874 {
875 LogFlowFunc(("GETSTATUSCHANGE: [%d] %RX32\n",
876 i, pRsp->aReaderStates[i].u32EventState));
877
878 /** @todo only the first reader is supported. */
879 if (i != 0)
880 {
881 continue;
882 }
883
884 if (i >= pCtx->u.GetStatusChange.cReaderStats)
885 {
886 continue;
887 }
888
889 pCtx->u.GetStatusChange.paReaderStats[i].u32EventState = pRsp->aReaderStates[i].u32EventState;
890 pCtx->u.GetStatusChange.paReaderStats[i].cbAtr = pRsp->aReaderStates[i].u32AtrLength > 36?
891 36:
892 pRsp->aReaderStates[i].u32AtrLength;
893 memcpy(pCtx->u.GetStatusChange.paReaderStats[i].au8Atr,
894 pRsp->aReaderStates[i].au8Atr,
895 pCtx->u.GetStatusChange.paReaderStats[i].cbAtr);
896 }
897 }
898 }
899
900 mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
901 pCtx->pvUser,
902 rcCard,
903 pCtx->u.GetStatusChange.paReaderStats,
904 pCtx->u.GetStatusChange.cReaderStats);
905
906 RTMemFree(pCtx);
907 } break;
908
909 case VRDE_SCARD_FN_CANCEL:
910 {
911 Assert(cbData == sizeof(VRDESCARDCANCELRSP) || RT_FAILURE(rcRequest));
912 VRDESCARDCANCELRSP *pRsp = (VRDESCARDCANCELRSP *)pvData; NOREF(pRsp);
913 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
914
915 Assert(pCtx->u32Function == u32Function);
916
917 LogFlowFunc(("CANCEL\n"));
918 } break;
919
920 case VRDE_SCARD_FN_CONNECT:
921 {
922 Assert(cbData == sizeof(VRDESCARDCONNECTRSP) || RT_FAILURE(rcRequest));
923 VRDESCARDCONNECTRSP *pRsp = (VRDESCARDCONNECTRSP *)pvData;
924 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
925
926 Assert(pCtx->u32Function == u32Function);
927
928 LogFlowFunc(("CONNECT\n"));
929
930 uint32_t u32ActiveProtocol = 0;
931 uint32_t rcCard;
932
933 if (RT_FAILURE(rcRequest))
934 {
935 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
936 }
937 else
938 {
939 rcCard = pRsp->u32ReturnCode;
940
941 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
942 {
943 u32ActiveProtocol = pRsp->u32ActiveProtocol;
944
945 Assert(!m_pRemote->reader.fHandle);
946 m_pRemote->reader.hCard = pRsp->hCard;
947 m_pRemote->reader.fHandle = true;
948 }
949 }
950
951 mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
952 pCtx->pvUser,
953 rcCard,
954 u32ActiveProtocol);
955
956 RTMemFree(pCtx);
957 } break;
958
959 case VRDE_SCARD_FN_RECONNECT:
960 {
961 Assert(cbData == sizeof(VRDESCARDRECONNECTRSP) || RT_FAILURE(rcRequest));
962 VRDESCARDRECONNECTRSP *pRsp = (VRDESCARDRECONNECTRSP *)pvData; NOREF(pRsp);
963 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
964
965 Assert(pCtx->u32Function == u32Function);
966
967 LogFlowFunc(("RECONNECT\n"));
968 } break;
969
970 case VRDE_SCARD_FN_DISCONNECT:
971 {
972 Assert(cbData == sizeof(VRDESCARDDISCONNECTRSP) || RT_FAILURE(rcRequest));
973 VRDESCARDDISCONNECTRSP *pRsp = (VRDESCARDDISCONNECTRSP *)pvData;
974 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
975
976 Assert(pCtx->u32Function == u32Function);
977
978 LogFlowFunc(("DISCONNECT\n"));
979
980 Assert(!pCtx->pRemote->reader.fHandle);
981
982 uint32_t rcCard;
983
984 if (RT_FAILURE(rcRequest))
985 {
986 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
987 }
988 else
989 {
990 rcCard = pRsp->u32ReturnCode;
991 }
992
993 mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
994 pCtx->pvUser,
995 rcCard);
996
997 RTMemFree(pCtx);
998 } break;
999
1000 case VRDE_SCARD_FN_BEGINTRANSACTION:
1001 {
1002 Assert(cbData == sizeof(VRDESCARDBEGINTRANSACTIONRSP) || RT_FAILURE(rcRequest));
1003 VRDESCARDBEGINTRANSACTIONRSP *pRsp = (VRDESCARDBEGINTRANSACTIONRSP *)pvData; NOREF(pRsp);
1004 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
1005
1006 Assert(pCtx->u32Function == u32Function);
1007
1008 LogFlowFunc(("BEGINTRANSACTION\n"));
1009 } break;
1010
1011 case VRDE_SCARD_FN_ENDTRANSACTION:
1012 {
1013 Assert(cbData == sizeof(VRDESCARDENDTRANSACTIONRSP) || RT_FAILURE(rcRequest));
1014 VRDESCARDENDTRANSACTIONRSP *pRsp = (VRDESCARDENDTRANSACTIONRSP *)pvData; NOREF(pRsp);
1015 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
1016
1017 Assert(pCtx->u32Function == u32Function);
1018
1019 LogFlowFunc(("ENDTRANSACTION\n"));
1020 } break;
1021
1022 case VRDE_SCARD_FN_STATE:
1023 {
1024 Assert(cbData == sizeof(VRDESCARDSTATERSP) || RT_FAILURE(rcRequest));
1025 VRDESCARDSTATERSP *pRsp = (VRDESCARDSTATERSP *)pvData; NOREF(pRsp);
1026 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
1027
1028 Assert(pCtx->u32Function == u32Function);
1029
1030 LogFlowFunc(("STATE\n"));
1031 } break;
1032
1033 case VRDE_SCARD_FN_STATUS:
1034 {
1035 Assert(cbData == sizeof(VRDESCARDSTATUSRSP) || RT_FAILURE(rcRequest));
1036 VRDESCARDSTATUSRSP *pRsp = (VRDESCARDSTATUSRSP *)pvData;
1037 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1038
1039 Assert(pCtx->u32Function == u32Function);
1040
1041 LogFlowFunc(("STATUS\n"));
1042
1043 char *pszReaderName = NULL;
1044 uint32_t cchReaderName = 0;
1045 uint32_t u32CardState = 0;
1046 uint32_t u32Protocol = 0;
1047 uint32_t u32AtrLength = 0;
1048 uint8_t *pbAtr = NULL;
1049
1050 uint32_t rcCard;
1051
1052 if (RT_FAILURE(rcRequest))
1053 {
1054 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1055 }
1056 else
1057 {
1058 rcCard = pRsp->u32ReturnCode;
1059
1060 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1061 {
1062 pszReaderName = pRsp->szReader;
1063 cchReaderName = (uint32_t)strlen(pRsp->szReader) + 1;
1064 u32CardState = pRsp->u32State;
1065 u32Protocol = pRsp->u32Protocol;
1066 u32AtrLength = pRsp->u32AtrLength;
1067 pbAtr = &pRsp->au8Atr[0];
1068 }
1069 }
1070
1071 mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1072 pCtx->pvUser,
1073 rcCard,
1074 pszReaderName,
1075 cchReaderName,
1076 u32CardState,
1077 u32Protocol,
1078 pbAtr,
1079 u32AtrLength);
1080
1081 RTMemFree(pCtx);
1082 } break;
1083
1084 case VRDE_SCARD_FN_TRANSMIT:
1085 {
1086 Assert(cbData == sizeof(VRDESCARDTRANSMITRSP) || RT_FAILURE(rcRequest));
1087 VRDESCARDTRANSMITRSP *pRsp = (VRDESCARDTRANSMITRSP *)pvData;
1088 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1089
1090 Assert(pCtx->u32Function == u32Function);
1091
1092 LogFlowFunc(("TRANSMIT\n"));
1093
1094 PDMICARDREADER_IO_REQUEST *pioRecvPci = NULL;
1095 uint8_t *pu8RecvBuffer = NULL;
1096 uint32_t cbRecvBuffer = 0;
1097
1098 uint32_t rcCard;
1099
1100 if (RT_FAILURE(rcRequest))
1101 {
1102 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1103 }
1104 else
1105 {
1106 rcCard = pRsp->u32ReturnCode;
1107
1108 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1109 {
1110 pu8RecvBuffer = pRsp->pu8RecvBuffer;
1111 cbRecvBuffer = pRsp->u32RecvLength;
1112 /** @todo pioRecvPci */
1113 }
1114 }
1115
1116 mpDrv->pICardReaderUp->pfnTransmit(mpDrv->pICardReaderUp,
1117 pCtx->pvUser,
1118 rcCard,
1119 pioRecvPci,
1120 pu8RecvBuffer,
1121 cbRecvBuffer);
1122
1123 RTMemFree(pioRecvPci);
1124
1125 RTMemFree(pCtx);
1126 } break;
1127
1128 case VRDE_SCARD_FN_CONTROL:
1129 {
1130 Assert(cbData == sizeof(VRDESCARDCONTROLRSP) || RT_FAILURE(rcRequest));
1131 VRDESCARDCONTROLRSP *pRsp = (VRDESCARDCONTROLRSP *)pvData;
1132 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1133
1134 Assert(pCtx->u32Function == u32Function);
1135
1136 LogFlowFunc(("CONTROL\n"));
1137
1138 uint8_t *pu8OutBuffer = NULL;
1139 uint32_t cbOutBuffer = 0;
1140
1141 uint32_t rcCard;
1142
1143 if (RT_FAILURE(rcRequest))
1144 {
1145 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1146 }
1147 else
1148 {
1149 rcCard = pRsp->u32ReturnCode;
1150
1151 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1152 {
1153 pu8OutBuffer = pRsp->pu8OutBuffer;
1154 cbOutBuffer = pRsp->u32OutBufferSize;
1155 }
1156 }
1157
1158 mpDrv->pICardReaderUp->pfnControl(mpDrv->pICardReaderUp,
1159 pCtx->pvUser,
1160 rcCard,
1161 pCtx->u.Control.u32ControlCode,
1162 pu8OutBuffer,
1163 cbOutBuffer);
1164
1165 RTMemFree(pCtx);
1166 } break;
1167
1168 case VRDE_SCARD_FN_GETATTRIB:
1169 {
1170 Assert(cbData == sizeof(VRDESCARDGETATTRIBRSP) || RT_FAILURE(rcRequest));
1171 VRDESCARDGETATTRIBRSP *pRsp = (VRDESCARDGETATTRIBRSP *)pvData;
1172 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1173
1174 Assert(pCtx->u32Function == u32Function);
1175
1176 LogFlowFunc(("GETATTRIB\n"));
1177
1178 uint8_t *pu8Attrib = NULL;
1179 uint32_t cbAttrib = 0;
1180
1181 uint32_t rcCard;
1182
1183 if (RT_FAILURE(rcRequest))
1184 {
1185 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1186 }
1187 else
1188 {
1189 rcCard = pRsp->u32ReturnCode;
1190
1191 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1192 {
1193 pu8Attrib = pRsp->pu8Attr;
1194 cbAttrib = pRsp->u32AttrLength;
1195 }
1196 }
1197
1198 mpDrv->pICardReaderUp->pfnGetAttrib(mpDrv->pICardReaderUp,
1199 pCtx->pvUser,
1200 rcCard,
1201 pCtx->u.GetAttrib.u32AttrId,
1202 pu8Attrib,
1203 cbAttrib);
1204
1205 RTMemFree(pCtx);
1206 } break;
1207
1208 case VRDE_SCARD_FN_SETATTRIB:
1209 {
1210 Assert(cbData == sizeof(VRDESCARDSETATTRIBRSP) || RT_FAILURE(rcRequest));
1211 VRDESCARDSETATTRIBRSP *pRsp = (VRDESCARDSETATTRIBRSP *)pvData;
1212 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1213
1214 Assert(pCtx->u32Function == u32Function);
1215
1216 LogFlowFunc(("SETATTRIB\n"));
1217
1218 uint32_t rcCard;
1219
1220 if (RT_FAILURE(rcRequest))
1221 {
1222 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1223 }
1224 else
1225 {
1226 rcCard = pRsp->u32ReturnCode;
1227 }
1228
1229 mpDrv->pICardReaderUp->pfnSetAttrib(mpDrv->pICardReaderUp,
1230 pCtx->pvUser,
1231 rcCard,
1232 pCtx->u.SetAttrib.u32AttrId);
1233
1234 RTMemFree(pCtx);
1235 } break;
1236
1237 default:
1238 AssertFailed();
1239 rc = VERR_INVALID_PARAMETER;
1240 break;
1241 }
1242
1243 return rc;
1244}
1245
1246int UsbCardReader::EstablishContext(struct USBCARDREADER *pDrv)
1247{
1248 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1249
1250 /* The context here is a not a real device context.
1251 * The device can be detached at the moment, for example the VRDP client did not connect yet.
1252 */
1253
1254 return mpDrv->pICardReaderUp->pfnEstablishContext(mpDrv->pICardReaderUp,
1255 VRDE_SCARD_S_SUCCESS);
1256}
1257
1258int UsbCardReader::ReleaseContext(struct USBCARDREADER *pDrv)
1259{
1260 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1261
1262 int rc = VINF_SUCCESS;
1263
1264 if ( !m_pRemote
1265 || !m_pRemote->fContext)
1266 {
1267 /* Do nothing. */
1268 }
1269 else
1270 {
1271 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1272 if (!pCtx)
1273 {
1274 /* Do nothing. */
1275 }
1276 else
1277 {
1278 pCtx->pRemote = m_pRemote;
1279 pCtx->u32Function = VRDE_SCARD_FN_RELEASECONTEXT;
1280 pCtx->pvUser = NULL;
1281
1282 VRDESCARDRELEASECONTEXTREQ req;
1283 req.Context = m_pRemote->context;
1284
1285 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_RELEASECONTEXT, &req, sizeof(req));
1286
1287 if (RT_FAILURE(rc))
1288 {
1289 RTMemFree(pCtx);
1290 }
1291 else
1292 {
1293 m_pRemote->fContext = false;
1294 }
1295 }
1296 }
1297
1298 return rc;
1299}
1300
1301int UsbCardReader::GetStatusChange(struct USBCARDREADER *pDrv,
1302 void *pvUser,
1303 uint32_t u32Timeout,
1304 PDMICARDREADER_READERSTATE *paReaderStats,
1305 uint32_t cReaderStats)
1306{
1307 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1308
1309 int rc = VINF_SUCCESS;
1310
1311 if ( !m_pRemote
1312 || !m_pRemote->fContext
1313 || !m_pRemote->reader.fAvailable)
1314 {
1315 rc = mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
1316 pvUser,
1317 VRDE_SCARD_E_NO_SMARTCARD,
1318 paReaderStats,
1319 cReaderStats);
1320 }
1321 else
1322 {
1323 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1324 if (!pCtx)
1325 {
1326 rc = mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
1327 pvUser,
1328 VRDE_SCARD_E_NO_MEMORY,
1329 paReaderStats,
1330 cReaderStats);
1331 }
1332 else
1333 {
1334 pCtx->pRemote = m_pRemote;
1335 pCtx->u32Function = VRDE_SCARD_FN_GETSTATUSCHANGE;
1336 pCtx->pvUser = pvUser;
1337 pCtx->u.GetStatusChange.paReaderStats = paReaderStats;
1338 pCtx->u.GetStatusChange.cReaderStats = cReaderStats;
1339
1340 VRDESCARDGETSTATUSCHANGEREQ req;
1341 req.Context = m_pRemote->context;
1342 req.u32Timeout = u32Timeout;
1343 req.cReaders = 1;
1344 req.aReaderStates[0].pszReader = &m_pRemote->reader.szReaderName[0];
1345 req.aReaderStates[0].u32CurrentState = paReaderStats[0].u32CurrentState;
1346
1347 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_GETSTATUSCHANGE, &req, sizeof(req));
1348
1349 if (RT_FAILURE(rc))
1350 {
1351 RTMemFree(pCtx);
1352 }
1353 }
1354 }
1355
1356 return rc;
1357}
1358
1359int UsbCardReader::Connect(struct USBCARDREADER *pDrv,
1360 void *pvUser,
1361 const char *pszReaderName,
1362 uint32_t u32ShareMode,
1363 uint32_t u32PreferredProtocols)
1364{
1365 RT_NOREF(pszReaderName);
1366 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1367
1368 int rc = VINF_SUCCESS;
1369
1370 if ( !m_pRemote
1371 || !m_pRemote->fContext
1372 || !m_pRemote->reader.fAvailable)
1373 {
1374 rc = mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
1375 pvUser,
1376 VRDE_SCARD_E_NO_SMARTCARD,
1377 VRDE_SCARD_PROTOCOL_T0);
1378 }
1379 else
1380 {
1381 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1382 if (!pCtx)
1383 {
1384 rc = mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
1385 pvUser,
1386 VRDE_SCARD_E_NO_MEMORY,
1387 VRDE_SCARD_PROTOCOL_T0);
1388 }
1389 else
1390 {
1391 pCtx->pRemote = m_pRemote;
1392 pCtx->u32Function = VRDE_SCARD_FN_CONNECT;
1393 pCtx->pvUser = pvUser;
1394
1395 VRDESCARDCONNECTREQ req;
1396 req.Context = m_pRemote->context;
1397 req.pszReader = &m_pRemote->reader.szReaderName[0];
1398 req.u32ShareMode = u32ShareMode;
1399 req.u32PreferredProtocols = u32PreferredProtocols;
1400
1401 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_CONNECT, &req, sizeof(req));
1402
1403 if (RT_FAILURE(rc))
1404 {
1405 RTMemFree(pCtx);
1406 }
1407 }
1408 }
1409
1410 return rc;
1411}
1412
1413int UsbCardReader::Disconnect(struct USBCARDREADER *pDrv,
1414 void *pvUser,
1415 uint32_t u32Mode)
1416{
1417 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1418
1419 int rc = VINF_SUCCESS;
1420
1421 if ( !m_pRemote
1422 || !m_pRemote->fContext
1423 || !m_pRemote->reader.fAvailable
1424 || !m_pRemote->reader.fHandle)
1425 {
1426 rc = mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
1427 pvUser,
1428 VRDE_SCARD_E_NO_SMARTCARD);
1429 }
1430 else
1431 {
1432 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1433 if (!pCtx)
1434 {
1435 rc = mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
1436 pvUser,
1437 VRDE_SCARD_E_NO_MEMORY);
1438 }
1439 else
1440 {
1441 pCtx->pRemote = m_pRemote;
1442 pCtx->u32Function = VRDE_SCARD_FN_DISCONNECT;
1443 pCtx->pvUser = pvUser;
1444
1445 VRDESCARDDISCONNECTREQ req;
1446 req.hCard = m_pRemote->reader.hCard;
1447 req.u32Disposition = u32Mode;
1448
1449 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_DISCONNECT, &req, sizeof(req));
1450
1451 if (RT_FAILURE(rc))
1452 {
1453 RTMemFree(pCtx);
1454 }
1455 else
1456 {
1457 m_pRemote->reader.fHandle = false;
1458 }
1459 }
1460 }
1461
1462 return rc;
1463}
1464
1465int UsbCardReader::Status(struct USBCARDREADER *pDrv,
1466 void *pvUser)
1467{
1468 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1469
1470 int rc = VINF_SUCCESS;
1471
1472 if ( !m_pRemote
1473 || !m_pRemote->fContext
1474 || !m_pRemote->reader.fAvailable
1475 || !m_pRemote->reader.fHandle)
1476 {
1477 rc = mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1478 pvUser,
1479 VRDE_SCARD_E_NO_SMARTCARD,
1480 /* pszReaderName */ NULL,
1481 /* cchReaderName */ 0,
1482 /* u32CardState */ 0,
1483 /* u32Protocol */ 0,
1484 /* pu8Atr */ 0,
1485 /* cbAtr */ 0);
1486 }
1487 else
1488 {
1489 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1490 if (!pCtx)
1491 {
1492 rc = mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1493 pvUser,
1494 VRDE_SCARD_E_NO_MEMORY,
1495 /* pszReaderName */ NULL,
1496 /* cchReaderName */ 0,
1497 /* u32CardState */ 0,
1498 /* u32Protocol */ 0,
1499 /* pu8Atr */ 0,
1500 /* cbAtr */ 0);
1501 }
1502 else
1503 {
1504 pCtx->pRemote = m_pRemote;
1505 pCtx->u32Function = VRDE_SCARD_FN_STATUS;
1506 pCtx->pvUser = pvUser;
1507
1508 VRDESCARDSTATUSREQ req;
1509 req.hCard = m_pRemote->reader.hCard;
1510
1511 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_STATUS, &req, sizeof(req));
1512
1513 if (RT_FAILURE(rc))
1514 {
1515 RTMemFree(pCtx);
1516 }
1517 }
1518 }
1519
1520 return rc;
1521}
1522
1523int UsbCardReader::Transmit(struct USBCARDREADER *pDrv,
1524 void *pvUser,
1525 PDMICARDREADER_IO_REQUEST *pioSendRequest,
1526 uint8_t *pu8SendBuffer,
1527 uint32_t cbSendBuffer,
1528 uint32_t cbRecvBuffer)
1529{
1530 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1531
1532 int rc = VINF_SUCCESS;
1533
1534 UCRREQCTX *pCtx = NULL;
1535 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1536
1537 if ( !m_pRemote
1538 || !m_pRemote->fContext
1539 || !m_pRemote->reader.fAvailable
1540 || !m_pRemote->reader.fHandle)
1541 {
1542 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1543 }
1544
1545 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1546 {
1547 if ( !pioSendRequest
1548 || ( pioSendRequest->cbPciLength < 2 * sizeof(uint32_t)
1549 || pioSendRequest->cbPciLength > 2 * sizeof(uint32_t) + VRDE_SCARD_MAX_PCI_DATA)
1550 )
1551 {
1552 AssertFailed();
1553 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1554 }
1555 }
1556
1557 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1558 {
1559 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1560 if (!pCtx)
1561 {
1562 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1563 }
1564 }
1565
1566 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1567 {
1568 Assert(pCtx == NULL);
1569
1570 rc = pDrv->pICardReaderUp->pfnTransmit(pDrv->pICardReaderUp,
1571 pvUser,
1572 rcSCard,
1573 /* pioRecvPci */ NULL,
1574 /* pu8RecvBuffer */ NULL,
1575 /* cbRecvBuffer*/ 0);
1576 }
1577 else
1578 {
1579 pCtx->pRemote = m_pRemote;
1580 pCtx->u32Function = VRDE_SCARD_FN_TRANSMIT;
1581 pCtx->pvUser = pvUser;
1582
1583 VRDESCARDTRANSMITREQ req;
1584 req.hCard = m_pRemote->reader.hCard;
1585
1586 req.ioSendPci.u32Protocol = pioSendRequest->u32Protocol;
1587 req.ioSendPci.u32PciLength = pioSendRequest->cbPciLength < 2 * sizeof(uint32_t)?
1588 (uint32_t)(2 * sizeof(uint32_t)):
1589 pioSendRequest->cbPciLength;
1590 Assert(pioSendRequest->cbPciLength <= VRDE_SCARD_MAX_PCI_DATA + 2 * sizeof(uint32_t));
1591 memcpy(req.ioSendPci.au8PciData,
1592 (uint8_t *)pioSendRequest + 2 * sizeof(uint32_t),
1593 req.ioSendPci.u32PciLength - 2 * sizeof(uint32_t));
1594
1595 req.u32SendLength = cbSendBuffer;
1596 req.pu8SendBuffer = pu8SendBuffer;
1597 req.u32RecvLength = cbRecvBuffer;
1598
1599 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_TRANSMIT, &req, sizeof(req));
1600
1601 if (RT_FAILURE(rc))
1602 {
1603 RTMemFree(pCtx);
1604 }
1605 }
1606
1607 return rc;
1608}
1609
1610int UsbCardReader::Control(struct USBCARDREADER *pDrv,
1611 void *pvUser,
1612 uint32_t u32ControlCode,
1613 uint8_t *pu8InBuffer,
1614 uint32_t cbInBuffer,
1615 uint32_t cbOutBuffer)
1616{
1617 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1618
1619 int rc = VINF_SUCCESS;
1620
1621 UCRREQCTX *pCtx = NULL;
1622 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1623
1624 if ( !m_pRemote
1625 || !m_pRemote->fContext
1626 || !m_pRemote->reader.fAvailable
1627 || !m_pRemote->reader.fHandle)
1628 {
1629 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1630 }
1631
1632 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1633 {
1634 if ( cbInBuffer > _128K
1635 || cbOutBuffer > _128K)
1636 {
1637 AssertFailed();
1638 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1639 }
1640 }
1641
1642 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1643 {
1644 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1645 if (!pCtx)
1646 {
1647 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1648 }
1649 }
1650
1651 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1652 {
1653 Assert(pCtx == NULL);
1654
1655 rc = pDrv->pICardReaderUp->pfnControl(pDrv->pICardReaderUp,
1656 pvUser,
1657 rcSCard,
1658 u32ControlCode,
1659 /* pvOutBuffer */ NULL,
1660 /* cbOutBuffer*/ 0);
1661 }
1662 else
1663 {
1664 pCtx->pRemote = m_pRemote;
1665 pCtx->u32Function = VRDE_SCARD_FN_CONTROL;
1666 pCtx->pvUser = pvUser;
1667 pCtx->u.Control.u32ControlCode = u32ControlCode;
1668
1669 VRDESCARDCONTROLREQ req;
1670 req.hCard = m_pRemote->reader.hCard;
1671 req.u32ControlCode = u32ControlCode;
1672 req.u32InBufferSize = cbInBuffer;
1673 req.pu8InBuffer = pu8InBuffer;
1674 req.u32OutBufferSize = cbOutBuffer;
1675
1676 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_CONTROL, &req, sizeof(req));
1677
1678 if (RT_FAILURE(rc))
1679 {
1680 RTMemFree(pCtx);
1681 }
1682 }
1683
1684 return rc;
1685}
1686
1687int UsbCardReader::GetAttrib(struct USBCARDREADER *pDrv,
1688 void *pvUser,
1689 uint32_t u32AttrId,
1690 uint32_t cbAttrib)
1691{
1692 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1693
1694 int rc = VINF_SUCCESS;
1695
1696 UCRREQCTX *pCtx = NULL;
1697 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1698
1699 if ( !m_pRemote
1700 || !m_pRemote->fContext
1701 || !m_pRemote->reader.fAvailable
1702 || !m_pRemote->reader.fHandle)
1703 {
1704 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1705 }
1706
1707 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1708 {
1709 if (cbAttrib > _128K)
1710 {
1711 AssertFailed();
1712 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1713 }
1714 }
1715
1716 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1717 {
1718 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1719 if (!pCtx)
1720 {
1721 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1722 }
1723 }
1724
1725 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1726 {
1727 Assert(pCtx == NULL);
1728
1729 pDrv->pICardReaderUp->pfnGetAttrib(pDrv->pICardReaderUp,
1730 pvUser,
1731 rcSCard,
1732 u32AttrId,
1733 /* pvAttrib */ NULL,
1734 /* cbAttrib */ 0);
1735 }
1736 else
1737 {
1738 pCtx->pRemote = m_pRemote;
1739 pCtx->u32Function = VRDE_SCARD_FN_GETATTRIB;
1740 pCtx->pvUser = pvUser;
1741 pCtx->u.GetAttrib.u32AttrId = u32AttrId;
1742
1743 VRDESCARDGETATTRIBREQ req;
1744 req.hCard = m_pRemote->reader.hCard;
1745 req.u32AttrId = u32AttrId;
1746 req.u32AttrLen = cbAttrib;
1747
1748 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_GETATTRIB, &req, sizeof(req));
1749
1750 if (RT_FAILURE(rc))
1751 {
1752 RTMemFree(pCtx);
1753 }
1754 }
1755
1756 return rc;
1757}
1758
1759int UsbCardReader::SetAttrib(struct USBCARDREADER *pDrv,
1760 void *pvUser,
1761 uint32_t u32AttrId,
1762 uint8_t *pu8Attrib,
1763 uint32_t cbAttrib)
1764{
1765 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1766
1767 int rc = VINF_SUCCESS;
1768
1769 UCRREQCTX *pCtx = NULL;
1770 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1771
1772 if ( !m_pRemote
1773 || !m_pRemote->fContext
1774 || !m_pRemote->reader.fAvailable
1775 || !m_pRemote->reader.fHandle)
1776 {
1777 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1778 }
1779
1780 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1781 {
1782 if (cbAttrib > _128K)
1783 {
1784 AssertFailed();
1785 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1786 }
1787 }
1788
1789 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1790 {
1791 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1792 if (!pCtx)
1793 {
1794 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1795 }
1796 }
1797
1798 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1799 {
1800 Assert(pCtx == NULL);
1801
1802 pDrv->pICardReaderUp->pfnSetAttrib(pDrv->pICardReaderUp,
1803 pvUser,
1804 rcSCard,
1805 u32AttrId);
1806 }
1807 else
1808 {
1809 pCtx->pRemote = m_pRemote;
1810 pCtx->u32Function = VRDE_SCARD_FN_SETATTRIB;
1811 pCtx->pvUser = pvUser;
1812 pCtx->u.SetAttrib.u32AttrId = u32AttrId;
1813
1814 VRDESCARDSETATTRIBREQ req;
1815 req.hCard = m_pRemote->reader.hCard;
1816 req.u32AttrId = u32AttrId;
1817 req.u32AttrLen = cbAttrib;
1818 req.pu8Attr = pu8Attrib;
1819
1820 rc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_SETATTRIB, &req, sizeof(req));
1821
1822 if (RT_FAILURE(rc))
1823 {
1824 RTMemFree(pCtx);
1825 }
1826 }
1827
1828 return rc;
1829}
1830
1831
1832/*
1833 * PDMDRVINS
1834 */
1835
1836/* static */ DECLCALLBACK(void *) UsbCardReader::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
1837{
1838 LogFlowFunc(("pInterface:%p, pszIID:%s\n", pInterface, pszIID));
1839 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
1840 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1841
1842 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
1843 PDMIBASE_RETURN_INTERFACE(pszIID, PDMICARDREADERDOWN, &pThis->ICardReaderDown);
1844 return NULL;
1845}
1846
1847/* static */ DECLCALLBACK(void) UsbCardReader::drvDestruct(PPDMDRVINS pDrvIns)
1848{
1849 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
1850 LogFlowFunc(("iInstance/%d\n",pDrvIns->iInstance));
1851 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1852
1853 /** @todo The driver is destroyed before the device.
1854 * So device calls ReleaseContext when there is no more driver.
1855 * Notify the device here so it can do cleanup or
1856 * do a cleanup now in the driver.
1857 */
1858 if (pThis->hReqQCardReaderCmd != NIL_RTREQQUEUE)
1859 {
1860 int rc = RTReqQueueDestroy(pThis->hReqQCardReaderCmd);
1861 AssertRC(rc);
1862 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1863 }
1864
1865 pThis->pUsbCardReader->mpDrv = NULL;
1866 pThis->pUsbCardReader = NULL;
1867 LogFlowFuncLeave();
1868}
1869
1870/* static */ DECLCALLBACK(int) UsbCardReader::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
1871{
1872 RT_NOREF(fFlags);
1873 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
1874 LogFlowFunc(("iInstance/%d, pCfg:%p, fFlags:%x\n", pDrvIns->iInstance, pCfg, fFlags));
1875 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1876
1877 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1878
1879 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
1880 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
1881 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
1882 ("Configuration error: Not possible to attach anything to this driver!\n"),
1883 VERR_PDM_DRVINS_NO_ATTACH);
1884
1885 void *pv;
1886 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
1887 AssertMsgRCReturn(rc, ("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc), rc);
1888
1889 pThis->pUsbCardReader = (UsbCardReader *)pv;
1890 pThis->pUsbCardReader->mpDrv = pThis;
1891 pThis->pDrvIns = pDrvIns;
1892
1893 pDrvIns->IBase.pfnQueryInterface = UsbCardReader::drvQueryInterface;
1894
1895 pThis->ICardReaderDown.pfnEstablishContext = drvCardReaderDownEstablishContext;
1896 pThis->ICardReaderDown.pfnReleaseContext = drvCardReaderDownReleaseContext;
1897 pThis->ICardReaderDown.pfnConnect = drvCardReaderDownConnect;
1898 pThis->ICardReaderDown.pfnDisconnect = drvCardReaderDownDisconnect;
1899 pThis->ICardReaderDown.pfnStatus = drvCardReaderDownStatus;
1900 pThis->ICardReaderDown.pfnGetStatusChange = drvCardReaderDownGetStatusChange;
1901 pThis->ICardReaderDown.pfnBeginTransaction = drvCardReaderDownBeginTransaction;
1902 pThis->ICardReaderDown.pfnEndTransaction = drvCardReaderDownEndTransaction;
1903 pThis->ICardReaderDown.pfnTransmit = drvCardReaderDownTransmit;
1904 pThis->ICardReaderDown.pfnGetAttr = drvCardReaderDownGetAttr;
1905 pThis->ICardReaderDown.pfnSetAttr = drvCardReaderDownSetAttr;
1906 pThis->ICardReaderDown.pfnControl = drvCardReaderDownControl;
1907
1908 pThis->pICardReaderUp = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMICARDREADERUP);
1909 AssertReturn(pThis->pICardReaderUp, VERR_PDM_MISSING_INTERFACE);
1910
1911 /* Command Thread Synchronization primitives */
1912 rc = RTReqQueueCreate(&pThis->hReqQCardReaderCmd);
1913 AssertLogRelRCReturn(rc, rc);
1914
1915 rc = PDMDrvHlpThreadCreate(pDrvIns,
1916 &pThis->pThrCardReaderCmd,
1917 pThis,
1918 drvCardReaderThreadCmd /* worker routine */,
1919 drvCardReaderThreadCmdWakeup /* wakeup routine */,
1920 128 * _1K, RTTHREADTYPE_IO, "UCRCMD");
1921 if (RT_FAILURE(rc))
1922 {
1923 RTReqQueueDestroy(pThis->hReqQCardReaderCmd);
1924 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1925 }
1926
1927 LogFlowFunc(("LEAVE: %Rrc\n", rc));
1928 return rc;
1929}
1930
1931/* static */ const PDMDRVREG UsbCardReader::DrvReg =
1932{
1933 /* u32Version */
1934 PDM_DRVREG_VERSION,
1935 /* szName[32] */
1936 "UsbCardReader",
1937 /* szRCMod[32] */
1938 "",
1939 /* szR0Mod[32] */
1940 "",
1941 /* pszDescription */
1942 "Main Driver communicating with VRDE",
1943 /* fFlags */
1944 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
1945 /* fClass */
1946 PDM_DRVREG_CLASS_USB,
1947 /* cMaxInstances */
1948 1,
1949 /* cbInstance */
1950 sizeof(USBCARDREADER),
1951 /* pfnConstruct */
1952 UsbCardReader::drvConstruct,
1953 /* pfnDestruct */
1954 UsbCardReader::drvDestruct,
1955 /* pfnRelocate */
1956 NULL,
1957 /* pfnIOCtl */
1958 NULL,
1959 /* pfnPowerOn */
1960 NULL,
1961 /* pfnReset */
1962 NULL,
1963 /* pfnSuspend */
1964 NULL,
1965 /* pfnResume */
1966 NULL,
1967 /* pfnAttach */
1968 NULL,
1969 /* pfnDetach */
1970 NULL,
1971 /* pfnPowerOff */
1972 NULL,
1973 /* pfnSoftReset */
1974 NULL,
1975 /* u32VersionEnd */
1976 PDM_DRVREG_VERSION
1977};
1978/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette