VirtualBox

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

Last change on this file since 105978 was 105353, checked in by vboxsync, 5 months ago

iprt/req.h,*: Adjustments of the RTReqQueue API to fit darwin/arm64 restrictions. bugref:10725

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