VirtualBox

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

Last change on this file since 65173 was 63563, checked in by vboxsync, 8 years ago

scm: cleaning up todos

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