VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use