VirtualBox

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

Last change on this file since 43053 was 42433, checked in by vboxsync, 12 years ago

Main/UsbCardReader: fixes.

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