VirtualBox

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

Last change on this file since 102493 was 98286, checked in by vboxsync, 23 months ago

Main/src-client: doxygen. bugref:10223

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