VirtualBox

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

Last change on this file since 70030 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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