VirtualBox

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

Last change on this file since 103415 was 102499, checked in by vboxsync, 12 months ago

Main/UsbCardReader: Don't try to copy the reader name if it is NULL (which happens with the Apple Silicon variant of Microsoft Remote Desktop app), ticketref:21820

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 66.5 KB
Line 
1/* $Id: UsbCardReader.cpp 102499 2023-12-06 11:06:46Z vboxsync $ */
2/** @file
3 * UsbCardReader - Driver Interface to USB Smart Card Reader emulation.
4 */
5
6/*
7 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_USB_CARDREADER
33#include "LoggingNew.h"
34
35#include "UsbCardReader.h"
36#include "ConsoleImpl.h"
37#include "ConsoleVRDPServer.h"
38
39#include <VBox/vmm/pdmdrv.h>
40#include <VBox/vmm/pdmcardreaderinfs.h>
41#include <VBox/err.h>
42
43#include <iprt/req.h>
44
45
46/*********************************************************************************************************************************
47* Structures and Typedefs *
48*********************************************************************************************************************************/
49typedef struct USBCARDREADER USBCARDREADER;
50typedef struct USBCARDREADER *PUSBCARDREADER;
51
52struct USBCARDREADER
53{
54 UsbCardReader *pUsbCardReader;
55
56 PPDMDRVINS pDrvIns;
57
58 PDMICARDREADERDOWN ICardReaderDown;
59 PPDMICARDREADERUP pICardReaderUp;
60
61 /* Thread handling Cmd to card reader */
62 PPDMTHREAD pThrCardReaderCmd;
63 /* Queue handling requests to cardreader */
64 RTREQQUEUE hReqQCardReaderCmd;
65};
66
67
68/*
69 * Command queue's callbacks.
70 */
71
72static DECLCALLBACK(void) drvCardReaderCmdStatusChange(PUSBCARDREADER pThis,
73 void *pvUser,
74 uint32_t u32Timeout,
75 PDMICARDREADER_READERSTATE *paReaderStats,
76 uint32_t cReaderStats)
77{
78 LogFlowFunc(("ENTER: pvUser:%p, u32Timeout:%d\n", 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 if (pRsp->apszNames[i])
795 RTStrCopy(pRemote->reader.szReaderName, sizeof(pRemote->reader.szReaderName), pRsp->apszNames[i]);
796 else
797 RT_ZERO(pRemote->reader.szReaderName);
798 pRemote->reader.fHandle = false;
799 pRemote->reader.fAvailable = true;
800 }
801 }
802 } break;
803
804 case VRDE_SCARD_FN_RELEASECONTEXT:
805 {
806 Assert(cbData == sizeof(VRDESCARDRELEASECONTEXTRSP) || RT_FAILURE(rcRequest));
807 VRDESCARDRELEASECONTEXTRSP *pRsp = (VRDESCARDRELEASECONTEXTRSP *)pvData; NOREF(pRsp);
808 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
809
810 Assert(pCtx->u32Function == u32Function);
811
812 LogFlowFunc(("RELEASECONTEXT completed\n"));
813
814 /* No notification is expected here by the caller. */
815 Assert(!m_pRemote->fContext);
816 } break;
817
818 case VRDE_SCARD_FN_GETSTATUSCHANGE:
819 {
820 Assert(cbData == sizeof(VRDESCARDGETSTATUSCHANGERSP) || RT_FAILURE(rcRequest));
821 VRDESCARDGETSTATUSCHANGERSP *pRsp = (VRDESCARDGETSTATUSCHANGERSP *)pvData;
822 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
823
824 Assert(pCtx->u32Function == u32Function);
825
826 LogFlowFunc(("GETSTATUSCHANGE\n"));
827
828 uint32_t rcCard;
829 if (RT_FAILURE(rcRequest))
830 {
831 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
832 }
833 else
834 {
835 rcCard = pRsp->u32ReturnCode;
836
837 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
838 {
839 uint32_t i;
840 for (i = 0; i < pRsp->cReaders; i++)
841 {
842 LogFlowFunc(("GETSTATUSCHANGE: [%d] %RX32\n",
843 i, pRsp->aReaderStates[i].u32EventState));
844
845 /** @todo only the first reader is supported. */
846 if (i != 0)
847 {
848 continue;
849 }
850
851 if (i >= pCtx->u.GetStatusChange.cReaderStats)
852 {
853 continue;
854 }
855
856 pCtx->u.GetStatusChange.paReaderStats[i].u32EventState = pRsp->aReaderStates[i].u32EventState;
857 pCtx->u.GetStatusChange.paReaderStats[i].cbAtr = pRsp->aReaderStates[i].u32AtrLength > 36?
858 36:
859 pRsp->aReaderStates[i].u32AtrLength;
860 memcpy(pCtx->u.GetStatusChange.paReaderStats[i].au8Atr,
861 pRsp->aReaderStates[i].au8Atr,
862 pCtx->u.GetStatusChange.paReaderStats[i].cbAtr);
863 }
864 }
865 }
866
867 mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
868 pCtx->pvUser,
869 rcCard,
870 pCtx->u.GetStatusChange.paReaderStats,
871 pCtx->u.GetStatusChange.cReaderStats);
872
873 RTMemFree(pCtx);
874 } break;
875
876 case VRDE_SCARD_FN_CANCEL:
877 {
878 Assert(cbData == sizeof(VRDESCARDCANCELRSP) || RT_FAILURE(rcRequest));
879 VRDESCARDCANCELRSP *pRsp = (VRDESCARDCANCELRSP *)pvData; NOREF(pRsp);
880 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
881
882 Assert(pCtx->u32Function == u32Function);
883
884 LogFlowFunc(("CANCEL\n"));
885 } break;
886
887 case VRDE_SCARD_FN_CONNECT:
888 {
889 Assert(cbData == sizeof(VRDESCARDCONNECTRSP) || RT_FAILURE(rcRequest));
890 VRDESCARDCONNECTRSP *pRsp = (VRDESCARDCONNECTRSP *)pvData;
891 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
892
893 Assert(pCtx->u32Function == u32Function);
894
895 LogFlowFunc(("CONNECT\n"));
896
897 uint32_t u32ActiveProtocol = 0;
898 uint32_t rcCard;
899
900 if (RT_FAILURE(rcRequest))
901 {
902 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
903 }
904 else
905 {
906 rcCard = pRsp->u32ReturnCode;
907
908 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
909 {
910 u32ActiveProtocol = pRsp->u32ActiveProtocol;
911
912 Assert(!m_pRemote->reader.fHandle);
913 m_pRemote->reader.hCard = pRsp->hCard;
914 m_pRemote->reader.fHandle = true;
915 }
916 }
917
918 mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
919 pCtx->pvUser,
920 rcCard,
921 u32ActiveProtocol);
922
923 RTMemFree(pCtx);
924 } break;
925
926 case VRDE_SCARD_FN_RECONNECT:
927 {
928 Assert(cbData == sizeof(VRDESCARDRECONNECTRSP) || RT_FAILURE(rcRequest));
929 VRDESCARDRECONNECTRSP *pRsp = (VRDESCARDRECONNECTRSP *)pvData; NOREF(pRsp);
930 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
931
932 Assert(pCtx->u32Function == u32Function);
933
934 LogFlowFunc(("RECONNECT\n"));
935 } break;
936
937 case VRDE_SCARD_FN_DISCONNECT:
938 {
939 Assert(cbData == sizeof(VRDESCARDDISCONNECTRSP) || RT_FAILURE(rcRequest));
940 VRDESCARDDISCONNECTRSP *pRsp = (VRDESCARDDISCONNECTRSP *)pvData;
941 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
942
943 Assert(pCtx->u32Function == u32Function);
944
945 LogFlowFunc(("DISCONNECT\n"));
946
947 Assert(!pCtx->pRemote->reader.fHandle);
948
949 uint32_t rcCard;
950
951 if (RT_FAILURE(rcRequest))
952 {
953 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
954 }
955 else
956 {
957 rcCard = pRsp->u32ReturnCode;
958 }
959
960 mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
961 pCtx->pvUser,
962 rcCard);
963
964 RTMemFree(pCtx);
965 } break;
966
967 case VRDE_SCARD_FN_BEGINTRANSACTION:
968 {
969 Assert(cbData == sizeof(VRDESCARDBEGINTRANSACTIONRSP) || RT_FAILURE(rcRequest));
970 VRDESCARDBEGINTRANSACTIONRSP *pRsp = (VRDESCARDBEGINTRANSACTIONRSP *)pvData; NOREF(pRsp);
971 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
972
973 Assert(pCtx->u32Function == u32Function);
974
975 LogFlowFunc(("BEGINTRANSACTION\n"));
976 } break;
977
978 case VRDE_SCARD_FN_ENDTRANSACTION:
979 {
980 Assert(cbData == sizeof(VRDESCARDENDTRANSACTIONRSP) || RT_FAILURE(rcRequest));
981 VRDESCARDENDTRANSACTIONRSP *pRsp = (VRDESCARDENDTRANSACTIONRSP *)pvData; NOREF(pRsp);
982 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
983
984 Assert(pCtx->u32Function == u32Function);
985
986 LogFlowFunc(("ENDTRANSACTION\n"));
987 } break;
988
989 case VRDE_SCARD_FN_STATE:
990 {
991 Assert(cbData == sizeof(VRDESCARDSTATERSP) || RT_FAILURE(rcRequest));
992 VRDESCARDSTATERSP *pRsp = (VRDESCARDSTATERSP *)pvData; NOREF(pRsp);
993 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser; NOREF(pCtx);
994
995 Assert(pCtx->u32Function == u32Function);
996
997 LogFlowFunc(("STATE\n"));
998 } break;
999
1000 case VRDE_SCARD_FN_STATUS:
1001 {
1002 Assert(cbData == sizeof(VRDESCARDSTATUSRSP) || RT_FAILURE(rcRequest));
1003 VRDESCARDSTATUSRSP *pRsp = (VRDESCARDSTATUSRSP *)pvData;
1004 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1005
1006 Assert(pCtx->u32Function == u32Function);
1007
1008 LogFlowFunc(("STATUS\n"));
1009
1010 char *pszReaderName = NULL;
1011 uint32_t cchReaderName = 0;
1012 uint32_t u32CardState = 0;
1013 uint32_t u32Protocol = 0;
1014 uint32_t u32AtrLength = 0;
1015 uint8_t *pbAtr = NULL;
1016
1017 uint32_t rcCard;
1018
1019 if (RT_FAILURE(rcRequest))
1020 {
1021 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1022 }
1023 else
1024 {
1025 rcCard = pRsp->u32ReturnCode;
1026
1027 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1028 {
1029 pszReaderName = pRsp->szReader;
1030 cchReaderName = (uint32_t)strlen(pRsp->szReader) + 1;
1031 u32CardState = pRsp->u32State;
1032 u32Protocol = pRsp->u32Protocol;
1033 u32AtrLength = pRsp->u32AtrLength;
1034 pbAtr = &pRsp->au8Atr[0];
1035 }
1036 }
1037
1038 mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1039 pCtx->pvUser,
1040 rcCard,
1041 pszReaderName,
1042 cchReaderName,
1043 u32CardState,
1044 u32Protocol,
1045 pbAtr,
1046 u32AtrLength);
1047
1048 RTMemFree(pCtx);
1049 } break;
1050
1051 case VRDE_SCARD_FN_TRANSMIT:
1052 {
1053 Assert(cbData == sizeof(VRDESCARDTRANSMITRSP) || RT_FAILURE(rcRequest));
1054 VRDESCARDTRANSMITRSP *pRsp = (VRDESCARDTRANSMITRSP *)pvData;
1055 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1056
1057 Assert(pCtx->u32Function == u32Function);
1058
1059 LogFlowFunc(("TRANSMIT\n"));
1060
1061 PDMICARDREADER_IO_REQUEST *pioRecvPci = NULL;
1062 uint8_t *pu8RecvBuffer = NULL;
1063 uint32_t cbRecvBuffer = 0;
1064
1065 uint32_t rcCard;
1066
1067 if (RT_FAILURE(rcRequest))
1068 {
1069 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1070 }
1071 else
1072 {
1073 rcCard = pRsp->u32ReturnCode;
1074
1075 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1076 {
1077 pu8RecvBuffer = pRsp->pu8RecvBuffer;
1078 cbRecvBuffer = pRsp->u32RecvLength;
1079 /** @todo pioRecvPci */
1080 }
1081 }
1082
1083 mpDrv->pICardReaderUp->pfnTransmit(mpDrv->pICardReaderUp,
1084 pCtx->pvUser,
1085 rcCard,
1086 pioRecvPci,
1087 pu8RecvBuffer,
1088 cbRecvBuffer);
1089
1090 RTMemFree(pioRecvPci);
1091
1092 RTMemFree(pCtx);
1093 } break;
1094
1095 case VRDE_SCARD_FN_CONTROL:
1096 {
1097 Assert(cbData == sizeof(VRDESCARDCONTROLRSP) || RT_FAILURE(rcRequest));
1098 VRDESCARDCONTROLRSP *pRsp = (VRDESCARDCONTROLRSP *)pvData;
1099 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1100
1101 Assert(pCtx->u32Function == u32Function);
1102
1103 LogFlowFunc(("CONTROL\n"));
1104
1105 uint8_t *pu8OutBuffer = NULL;
1106 uint32_t cbOutBuffer = 0;
1107
1108 uint32_t rcCard;
1109
1110 if (RT_FAILURE(rcRequest))
1111 {
1112 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1113 }
1114 else
1115 {
1116 rcCard = pRsp->u32ReturnCode;
1117
1118 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1119 {
1120 pu8OutBuffer = pRsp->pu8OutBuffer;
1121 cbOutBuffer = pRsp->u32OutBufferSize;
1122 }
1123 }
1124
1125 mpDrv->pICardReaderUp->pfnControl(mpDrv->pICardReaderUp,
1126 pCtx->pvUser,
1127 rcCard,
1128 pCtx->u.Control.u32ControlCode,
1129 pu8OutBuffer,
1130 cbOutBuffer);
1131
1132 RTMemFree(pCtx);
1133 } break;
1134
1135 case VRDE_SCARD_FN_GETATTRIB:
1136 {
1137 Assert(cbData == sizeof(VRDESCARDGETATTRIBRSP) || RT_FAILURE(rcRequest));
1138 VRDESCARDGETATTRIBRSP *pRsp = (VRDESCARDGETATTRIBRSP *)pvData;
1139 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1140
1141 Assert(pCtx->u32Function == u32Function);
1142
1143 LogFlowFunc(("GETATTRIB\n"));
1144
1145 uint8_t *pu8Attrib = NULL;
1146 uint32_t cbAttrib = 0;
1147
1148 uint32_t rcCard;
1149
1150 if (RT_FAILURE(rcRequest))
1151 {
1152 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1153 }
1154 else
1155 {
1156 rcCard = pRsp->u32ReturnCode;
1157
1158 if (pRsp->u32ReturnCode == VRDE_SCARD_S_SUCCESS)
1159 {
1160 pu8Attrib = pRsp->pu8Attr;
1161 cbAttrib = pRsp->u32AttrLength;
1162 }
1163 }
1164
1165 mpDrv->pICardReaderUp->pfnGetAttrib(mpDrv->pICardReaderUp,
1166 pCtx->pvUser,
1167 rcCard,
1168 pCtx->u.GetAttrib.u32AttrId,
1169 pu8Attrib,
1170 cbAttrib);
1171
1172 RTMemFree(pCtx);
1173 } break;
1174
1175 case VRDE_SCARD_FN_SETATTRIB:
1176 {
1177 Assert(cbData == sizeof(VRDESCARDSETATTRIBRSP) || RT_FAILURE(rcRequest));
1178 VRDESCARDSETATTRIBRSP *pRsp = (VRDESCARDSETATTRIBRSP *)pvData;
1179 UCRREQCTX *pCtx = (UCRREQCTX *)pvUser;
1180
1181 Assert(pCtx->u32Function == u32Function);
1182
1183 LogFlowFunc(("SETATTRIB\n"));
1184
1185 uint32_t rcCard;
1186
1187 if (RT_FAILURE(rcRequest))
1188 {
1189 rcCard = VRDE_SCARD_E_NO_SMARTCARD;
1190 }
1191 else
1192 {
1193 rcCard = pRsp->u32ReturnCode;
1194 }
1195
1196 mpDrv->pICardReaderUp->pfnSetAttrib(mpDrv->pICardReaderUp,
1197 pCtx->pvUser,
1198 rcCard,
1199 pCtx->u.SetAttrib.u32AttrId);
1200
1201 RTMemFree(pCtx);
1202 } break;
1203
1204 default:
1205 AssertFailed();
1206 vrc = VERR_INVALID_PARAMETER;
1207 break;
1208 }
1209
1210 return vrc;
1211}
1212
1213int UsbCardReader::EstablishContext(struct USBCARDREADER *pDrv)
1214{
1215 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1216
1217 /* The context here is a not a real device context.
1218 * The device can be detached at the moment, for example the VRDP client did not connect yet.
1219 */
1220
1221 return mpDrv->pICardReaderUp->pfnEstablishContext(mpDrv->pICardReaderUp,
1222 VRDE_SCARD_S_SUCCESS);
1223}
1224
1225int UsbCardReader::ReleaseContext(struct USBCARDREADER *pDrv)
1226{
1227 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1228
1229 int vrc = VINF_SUCCESS;
1230
1231 if ( !m_pRemote
1232 || !m_pRemote->fContext)
1233 {
1234 /* Do nothing. */
1235 }
1236 else
1237 {
1238 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1239 if (!pCtx)
1240 {
1241 /* Do nothing. */
1242 }
1243 else
1244 {
1245 pCtx->pRemote = m_pRemote;
1246 pCtx->u32Function = VRDE_SCARD_FN_RELEASECONTEXT;
1247 pCtx->pvUser = NULL;
1248
1249 VRDESCARDRELEASECONTEXTREQ req;
1250 req.Context = m_pRemote->context;
1251
1252 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_RELEASECONTEXT, &req, sizeof(req));
1253 if (RT_FAILURE(vrc))
1254 RTMemFree(pCtx);
1255 else
1256 m_pRemote->fContext = false;
1257 }
1258 }
1259
1260 return vrc;
1261}
1262
1263int UsbCardReader::GetStatusChange(struct USBCARDREADER *pDrv,
1264 void *pvUser,
1265 uint32_t u32Timeout,
1266 PDMICARDREADER_READERSTATE *paReaderStats,
1267 uint32_t cReaderStats)
1268{
1269 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1270
1271 int vrc;
1272 if ( !m_pRemote
1273 || !m_pRemote->fContext
1274 || !m_pRemote->reader.fAvailable)
1275 vrc = mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
1276 pvUser,
1277 VRDE_SCARD_E_NO_SMARTCARD,
1278 paReaderStats,
1279 cReaderStats);
1280 else
1281 {
1282 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1283 if (!pCtx)
1284 vrc = mpDrv->pICardReaderUp->pfnSetStatusChange(mpDrv->pICardReaderUp,
1285 pvUser,
1286 VRDE_SCARD_E_NO_MEMORY,
1287 paReaderStats,
1288 cReaderStats);
1289 else
1290 {
1291 pCtx->pRemote = m_pRemote;
1292 pCtx->u32Function = VRDE_SCARD_FN_GETSTATUSCHANGE;
1293 pCtx->pvUser = pvUser;
1294 pCtx->u.GetStatusChange.paReaderStats = paReaderStats;
1295 pCtx->u.GetStatusChange.cReaderStats = cReaderStats;
1296
1297 VRDESCARDGETSTATUSCHANGEREQ req;
1298 req.Context = m_pRemote->context;
1299 req.u32Timeout = u32Timeout;
1300 req.cReaders = 1;
1301 req.aReaderStates[0].pszReader = &m_pRemote->reader.szReaderName[0];
1302 req.aReaderStates[0].u32CurrentState = paReaderStats[0].u32CurrentState;
1303
1304 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_GETSTATUSCHANGE, &req, sizeof(req));
1305 if (RT_FAILURE(vrc))
1306 RTMemFree(pCtx);
1307 }
1308 }
1309
1310 return vrc;
1311}
1312
1313int UsbCardReader::Connect(struct USBCARDREADER *pDrv,
1314 void *pvUser,
1315 const char *pszReaderName,
1316 uint32_t u32ShareMode,
1317 uint32_t u32PreferredProtocols)
1318{
1319 RT_NOREF(pszReaderName);
1320 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1321
1322 int vrc;
1323 if ( !m_pRemote
1324 || !m_pRemote->fContext
1325 || !m_pRemote->reader.fAvailable)
1326 vrc = mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
1327 pvUser,
1328 VRDE_SCARD_E_NO_SMARTCARD,
1329 VRDE_SCARD_PROTOCOL_T0);
1330 else
1331 {
1332 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1333 if (!pCtx)
1334 vrc = mpDrv->pICardReaderUp->pfnConnect(mpDrv->pICardReaderUp,
1335 pvUser,
1336 VRDE_SCARD_E_NO_MEMORY,
1337 VRDE_SCARD_PROTOCOL_T0);
1338 else
1339 {
1340 pCtx->pRemote = m_pRemote;
1341 pCtx->u32Function = VRDE_SCARD_FN_CONNECT;
1342 pCtx->pvUser = pvUser;
1343
1344 VRDESCARDCONNECTREQ req;
1345 req.Context = m_pRemote->context;
1346 req.pszReader = &m_pRemote->reader.szReaderName[0];
1347 req.u32ShareMode = u32ShareMode;
1348 req.u32PreferredProtocols = u32PreferredProtocols;
1349
1350 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_CONNECT, &req, sizeof(req));
1351 if (RT_FAILURE(vrc))
1352 RTMemFree(pCtx);
1353 }
1354 }
1355
1356 return vrc;
1357}
1358
1359int UsbCardReader::Disconnect(struct USBCARDREADER *pDrv,
1360 void *pvUser,
1361 uint32_t u32Mode)
1362{
1363 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1364
1365 int vrc;
1366 if ( !m_pRemote
1367 || !m_pRemote->fContext
1368 || !m_pRemote->reader.fAvailable
1369 || !m_pRemote->reader.fHandle)
1370 vrc = mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
1371 pvUser,
1372 VRDE_SCARD_E_NO_SMARTCARD);
1373 else
1374 {
1375 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1376 if (!pCtx)
1377 vrc = mpDrv->pICardReaderUp->pfnDisconnect(mpDrv->pICardReaderUp,
1378 pvUser,
1379 VRDE_SCARD_E_NO_MEMORY);
1380 else
1381 {
1382 pCtx->pRemote = m_pRemote;
1383 pCtx->u32Function = VRDE_SCARD_FN_DISCONNECT;
1384 pCtx->pvUser = pvUser;
1385
1386 VRDESCARDDISCONNECTREQ req;
1387 req.hCard = m_pRemote->reader.hCard;
1388 req.u32Disposition = u32Mode;
1389
1390 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_DISCONNECT, &req, sizeof(req));
1391 if (RT_FAILURE(vrc))
1392 RTMemFree(pCtx);
1393 else
1394 m_pRemote->reader.fHandle = false;
1395 }
1396 }
1397
1398 return vrc;
1399}
1400
1401int UsbCardReader::Status(struct USBCARDREADER *pDrv,
1402 void *pvUser)
1403{
1404 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1405
1406 int vrc;
1407 if ( !m_pRemote
1408 || !m_pRemote->fContext
1409 || !m_pRemote->reader.fAvailable
1410 || !m_pRemote->reader.fHandle)
1411 vrc = mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1412 pvUser,
1413 VRDE_SCARD_E_NO_SMARTCARD,
1414 /* pszReaderName */ NULL,
1415 /* cchReaderName */ 0,
1416 /* u32CardState */ 0,
1417 /* u32Protocol */ 0,
1418 /* pu8Atr */ 0,
1419 /* cbAtr */ 0);
1420 else
1421 {
1422 UCRREQCTX *pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1423 if (!pCtx)
1424 vrc = mpDrv->pICardReaderUp->pfnStatus(mpDrv->pICardReaderUp,
1425 pvUser,
1426 VRDE_SCARD_E_NO_MEMORY,
1427 /* pszReaderName */ NULL,
1428 /* cchReaderName */ 0,
1429 /* u32CardState */ 0,
1430 /* u32Protocol */ 0,
1431 /* pu8Atr */ 0,
1432 /* cbAtr */ 0);
1433 else
1434 {
1435 pCtx->pRemote = m_pRemote;
1436 pCtx->u32Function = VRDE_SCARD_FN_STATUS;
1437 pCtx->pvUser = pvUser;
1438
1439 VRDESCARDSTATUSREQ req;
1440 req.hCard = m_pRemote->reader.hCard;
1441
1442 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_STATUS, &req, sizeof(req));
1443 if (RT_FAILURE(vrc))
1444 RTMemFree(pCtx);
1445 }
1446 }
1447
1448 return vrc;
1449}
1450
1451int UsbCardReader::Transmit(struct USBCARDREADER *pDrv,
1452 void *pvUser,
1453 PDMICARDREADER_IO_REQUEST *pIoSendRequest,
1454 uint8_t *pbSendBuffer,
1455 uint32_t cbSendBuffer,
1456 uint32_t cbRecvBuffer)
1457{
1458 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1459
1460 int vrc = VINF_SUCCESS;
1461
1462 UCRREQCTX *pCtx = NULL;
1463 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1464
1465 if ( !m_pRemote
1466 || !m_pRemote->fContext
1467 || !m_pRemote->reader.fAvailable
1468 || !m_pRemote->reader.fHandle)
1469 {
1470 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1471 }
1472
1473 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1474 {
1475 if ( !pIoSendRequest
1476 || ( pIoSendRequest->cbPciLength < 2 * sizeof(uint32_t)
1477 || pIoSendRequest->cbPciLength > 2 * sizeof(uint32_t) + VRDE_SCARD_MAX_PCI_DATA)
1478 )
1479 {
1480 AssertFailed();
1481 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1482 }
1483 }
1484
1485 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1486 {
1487 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1488 if (!pCtx)
1489 {
1490 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1491 }
1492 }
1493
1494 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1495 {
1496 Assert(pCtx == NULL);
1497
1498 vrc = pDrv->pICardReaderUp->pfnTransmit(pDrv->pICardReaderUp,
1499 pvUser,
1500 rcSCard,
1501 /* pioRecvPci */ NULL,
1502 /* pu8RecvBuffer */ NULL,
1503 /* cbRecvBuffer*/ 0);
1504 }
1505 else
1506 {
1507 pCtx->pRemote = m_pRemote;
1508 pCtx->u32Function = VRDE_SCARD_FN_TRANSMIT;
1509 pCtx->pvUser = pvUser;
1510
1511 VRDESCARDTRANSMITREQ req;
1512 req.hCard = m_pRemote->reader.hCard;
1513
1514 req.ioSendPci.u32Protocol = pIoSendRequest->u32Protocol;
1515 req.ioSendPci.u32PciLength = pIoSendRequest->cbPciLength < 2 * sizeof(uint32_t)?
1516 (uint32_t)(2 * sizeof(uint32_t)):
1517 pIoSendRequest->cbPciLength;
1518 Assert(pIoSendRequest->cbPciLength <= VRDE_SCARD_MAX_PCI_DATA + 2 * sizeof(uint32_t));
1519 memcpy(req.ioSendPci.au8PciData,
1520 (uint8_t *)pIoSendRequest + 2 * sizeof(uint32_t),
1521 req.ioSendPci.u32PciLength - 2 * sizeof(uint32_t));
1522
1523 req.u32SendLength = cbSendBuffer;
1524 req.pu8SendBuffer = pbSendBuffer;
1525 req.u32RecvLength = cbRecvBuffer;
1526
1527 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_TRANSMIT, &req, sizeof(req));
1528 if (RT_FAILURE(vrc))
1529 RTMemFree(pCtx);
1530 }
1531
1532 return vrc;
1533}
1534
1535int UsbCardReader::Control(struct USBCARDREADER *pDrv,
1536 void *pvUser,
1537 uint32_t u32ControlCode,
1538 uint8_t *pu8InBuffer,
1539 uint32_t cbInBuffer,
1540 uint32_t cbOutBuffer)
1541{
1542 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1543
1544 int vrc = VINF_SUCCESS;
1545
1546 UCRREQCTX *pCtx = NULL;
1547 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1548
1549 if ( !m_pRemote
1550 || !m_pRemote->fContext
1551 || !m_pRemote->reader.fAvailable
1552 || !m_pRemote->reader.fHandle)
1553 {
1554 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1555 }
1556
1557 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1558 {
1559 if ( cbInBuffer > _128K
1560 || cbOutBuffer > _128K)
1561 {
1562 AssertFailed();
1563 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1564 }
1565 }
1566
1567 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1568 {
1569 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1570 if (!pCtx)
1571 {
1572 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1573 }
1574 }
1575
1576 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1577 {
1578 Assert(pCtx == NULL);
1579
1580 vrc = pDrv->pICardReaderUp->pfnControl(pDrv->pICardReaderUp,
1581 pvUser,
1582 rcSCard,
1583 u32ControlCode,
1584 /* pvOutBuffer */ NULL,
1585 /* cbOutBuffer*/ 0);
1586 }
1587 else
1588 {
1589 pCtx->pRemote = m_pRemote;
1590 pCtx->u32Function = VRDE_SCARD_FN_CONTROL;
1591 pCtx->pvUser = pvUser;
1592 pCtx->u.Control.u32ControlCode = u32ControlCode;
1593
1594 VRDESCARDCONTROLREQ req;
1595 req.hCard = m_pRemote->reader.hCard;
1596 req.u32ControlCode = u32ControlCode;
1597 req.u32InBufferSize = cbInBuffer;
1598 req.pu8InBuffer = pu8InBuffer;
1599 req.u32OutBufferSize = cbOutBuffer;
1600
1601 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_CONTROL, &req, sizeof(req));
1602 if (RT_FAILURE(vrc))
1603 RTMemFree(pCtx);
1604 }
1605
1606 return vrc;
1607}
1608
1609int UsbCardReader::GetAttrib(struct USBCARDREADER *pDrv,
1610 void *pvUser,
1611 uint32_t u32AttrId,
1612 uint32_t cbAttrib)
1613{
1614 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1615
1616 int vrc = VINF_SUCCESS;
1617
1618 UCRREQCTX *pCtx = NULL;
1619 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1620
1621 if ( !m_pRemote
1622 || !m_pRemote->fContext
1623 || !m_pRemote->reader.fAvailable
1624 || !m_pRemote->reader.fHandle)
1625 {
1626 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1627 }
1628
1629 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1630 {
1631 if (cbAttrib > _128K)
1632 {
1633 AssertFailed();
1634 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1635 }
1636 }
1637
1638 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1639 {
1640 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1641 if (!pCtx)
1642 {
1643 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1644 }
1645 }
1646
1647 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1648 {
1649 Assert(pCtx == NULL);
1650
1651 pDrv->pICardReaderUp->pfnGetAttrib(pDrv->pICardReaderUp,
1652 pvUser,
1653 rcSCard,
1654 u32AttrId,
1655 /* pvAttrib */ NULL,
1656 /* cbAttrib */ 0);
1657 }
1658 else
1659 {
1660 pCtx->pRemote = m_pRemote;
1661 pCtx->u32Function = VRDE_SCARD_FN_GETATTRIB;
1662 pCtx->pvUser = pvUser;
1663 pCtx->u.GetAttrib.u32AttrId = u32AttrId;
1664
1665 VRDESCARDGETATTRIBREQ req;
1666 req.hCard = m_pRemote->reader.hCard;
1667 req.u32AttrId = u32AttrId;
1668 req.u32AttrLen = cbAttrib;
1669
1670 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_GETATTRIB, &req, sizeof(req));
1671 if (RT_FAILURE(vrc))
1672 RTMemFree(pCtx);
1673 }
1674
1675 return vrc;
1676}
1677
1678int UsbCardReader::SetAttrib(struct USBCARDREADER *pDrv,
1679 void *pvUser,
1680 uint32_t u32AttrId,
1681 uint8_t *pu8Attrib,
1682 uint32_t cbAttrib)
1683{
1684 AssertReturn(pDrv == mpDrv, VERR_NOT_SUPPORTED);
1685
1686 int vrc = VINF_SUCCESS;
1687
1688 UCRREQCTX *pCtx = NULL;
1689 uint32_t rcSCard = VRDE_SCARD_S_SUCCESS;
1690
1691 if ( !m_pRemote
1692 || !m_pRemote->fContext
1693 || !m_pRemote->reader.fAvailable
1694 || !m_pRemote->reader.fHandle)
1695 {
1696 rcSCard = VRDE_SCARD_E_NO_SMARTCARD;
1697 }
1698
1699 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1700 {
1701 if (cbAttrib > _128K)
1702 {
1703 AssertFailed();
1704 rcSCard = VRDE_SCARD_E_INVALID_PARAMETER;
1705 }
1706 }
1707
1708 if (rcSCard == VRDE_SCARD_S_SUCCESS)
1709 {
1710 pCtx = (UCRREQCTX *)RTMemAlloc(sizeof(UCRREQCTX));
1711 if (!pCtx)
1712 {
1713 rcSCard = VRDE_SCARD_E_NO_MEMORY;
1714 }
1715 }
1716
1717 if (rcSCard != VRDE_SCARD_S_SUCCESS)
1718 {
1719 Assert(pCtx == NULL);
1720
1721 pDrv->pICardReaderUp->pfnSetAttrib(pDrv->pICardReaderUp,
1722 pvUser,
1723 rcSCard,
1724 u32AttrId);
1725 }
1726 else
1727 {
1728 pCtx->pRemote = m_pRemote;
1729 pCtx->u32Function = VRDE_SCARD_FN_SETATTRIB;
1730 pCtx->pvUser = pvUser;
1731 pCtx->u.SetAttrib.u32AttrId = u32AttrId;
1732
1733 VRDESCARDSETATTRIBREQ req;
1734 req.hCard = m_pRemote->reader.hCard;
1735 req.u32AttrId = u32AttrId;
1736 req.u32AttrLen = cbAttrib;
1737 req.pu8Attr = pu8Attrib;
1738
1739 vrc = vrdeSCardRequest(pCtx, VRDE_SCARD_FN_SETATTRIB, &req, sizeof(req));
1740 if (RT_FAILURE(vrc))
1741 RTMemFree(pCtx);
1742 }
1743
1744 return vrc;
1745}
1746
1747
1748/*
1749 * PDMDRVINS
1750 */
1751
1752/* static */ DECLCALLBACK(void *) UsbCardReader::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
1753{
1754 LogFlowFunc(("pInterface:%p, pszIID:%s\n", pInterface, pszIID));
1755 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
1756 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1757
1758 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
1759 PDMIBASE_RETURN_INTERFACE(pszIID, PDMICARDREADERDOWN, &pThis->ICardReaderDown);
1760 return NULL;
1761}
1762
1763/* static */ DECLCALLBACK(void) UsbCardReader::drvDestruct(PPDMDRVINS pDrvIns)
1764{
1765 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
1766 LogFlowFunc(("iInstance/%d\n",pDrvIns->iInstance));
1767 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1768
1769 /** @todo The driver is destroyed before the device.
1770 * So device calls ReleaseContext when there is no more driver.
1771 * Notify the device here so it can do cleanup or
1772 * do a cleanup now in the driver.
1773 */
1774 if (pThis->hReqQCardReaderCmd != NIL_RTREQQUEUE)
1775 {
1776 int vrc = RTReqQueueDestroy(pThis->hReqQCardReaderCmd);
1777 AssertRC(vrc);
1778 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1779 }
1780
1781 pThis->pUsbCardReader->mpDrv = NULL;
1782 pThis->pUsbCardReader = NULL;
1783 LogFlowFuncLeave();
1784}
1785
1786/* static */ DECLCALLBACK(int) UsbCardReader::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
1787{
1788 RT_NOREF(fFlags, pCfg);
1789 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
1790 LogFlowFunc(("iInstance/%d, pCfg:%p, fFlags:%x\n", pDrvIns->iInstance, pCfg, fFlags));
1791 PUSBCARDREADER pThis = PDMINS_2_DATA(pDrvIns, PUSBCARDREADER);
1792
1793 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1794
1795 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "", "");
1796 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
1797 ("Configuration error: Not possible to attach anything to this driver!\n"),
1798 VERR_PDM_DRVINS_NO_ATTACH);
1799
1800 com::Guid uuid(USBCARDREADER_OID);
1801 pThis->pUsbCardReader = (UsbCardReader *)PDMDrvHlpQueryGenericUserObject(pDrvIns, uuid.raw());
1802 AssertMsgReturn(RT_VALID_PTR(pThis->pUsbCardReader), ("Configuration error: No/bad USB card reader object value!\n"), VERR_NOT_FOUND);
1803
1804 pThis->pUsbCardReader->mpDrv = pThis;
1805 pThis->pDrvIns = pDrvIns;
1806
1807 pDrvIns->IBase.pfnQueryInterface = UsbCardReader::drvQueryInterface;
1808
1809 pThis->ICardReaderDown.pfnEstablishContext = drvCardReaderDownEstablishContext;
1810 pThis->ICardReaderDown.pfnReleaseContext = drvCardReaderDownReleaseContext;
1811 pThis->ICardReaderDown.pfnConnect = drvCardReaderDownConnect;
1812 pThis->ICardReaderDown.pfnDisconnect = drvCardReaderDownDisconnect;
1813 pThis->ICardReaderDown.pfnStatus = drvCardReaderDownStatus;
1814 pThis->ICardReaderDown.pfnGetStatusChange = drvCardReaderDownGetStatusChange;
1815 pThis->ICardReaderDown.pfnBeginTransaction = drvCardReaderDownBeginTransaction;
1816 pThis->ICardReaderDown.pfnEndTransaction = drvCardReaderDownEndTransaction;
1817 pThis->ICardReaderDown.pfnTransmit = drvCardReaderDownTransmit;
1818 pThis->ICardReaderDown.pfnGetAttr = drvCardReaderDownGetAttr;
1819 pThis->ICardReaderDown.pfnSetAttr = drvCardReaderDownSetAttr;
1820 pThis->ICardReaderDown.pfnControl = drvCardReaderDownControl;
1821
1822 pThis->pICardReaderUp = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMICARDREADERUP);
1823 AssertReturn(pThis->pICardReaderUp, VERR_PDM_MISSING_INTERFACE);
1824
1825 /* Command Thread Synchronization primitives */
1826 int vrc = RTReqQueueCreate(&pThis->hReqQCardReaderCmd);
1827 AssertLogRelRCReturn(vrc, vrc);
1828
1829 vrc = PDMDrvHlpThreadCreate(pDrvIns,
1830 &pThis->pThrCardReaderCmd,
1831 pThis,
1832 drvCardReaderThreadCmd /* worker routine */,
1833 drvCardReaderThreadCmdWakeup /* wakeup routine */,
1834 128 * _1K, RTTHREADTYPE_IO, "UCRCMD");
1835 if (RT_FAILURE(vrc))
1836 {
1837 RTReqQueueDestroy(pThis->hReqQCardReaderCmd);
1838 pThis->hReqQCardReaderCmd = NIL_RTREQQUEUE;
1839 }
1840
1841 LogFlowFunc(("LEAVE: %Rrc\n", vrc));
1842 return vrc;
1843}
1844
1845/* static */ const PDMDRVREG UsbCardReader::DrvReg =
1846{
1847 /* u32Version */
1848 PDM_DRVREG_VERSION,
1849 /* szName[32] */
1850 "UsbCardReader",
1851 /* szRCMod[32] */
1852 "",
1853 /* szR0Mod[32] */
1854 "",
1855 /* pszDescription */
1856 "Main Driver communicating with VRDE",
1857 /* fFlags */
1858 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
1859 /* fClass */
1860 PDM_DRVREG_CLASS_USB,
1861 /* cMaxInstances */
1862 1,
1863 /* cbInstance */
1864 sizeof(USBCARDREADER),
1865 /* pfnConstruct */
1866 UsbCardReader::drvConstruct,
1867 /* pfnDestruct */
1868 UsbCardReader::drvDestruct,
1869 /* pfnRelocate */
1870 NULL,
1871 /* pfnIOCtl */
1872 NULL,
1873 /* pfnPowerOn */
1874 NULL,
1875 /* pfnReset */
1876 NULL,
1877 /* pfnSuspend */
1878 NULL,
1879 /* pfnResume */
1880 NULL,
1881 /* pfnAttach */
1882 NULL,
1883 /* pfnDetach */
1884 NULL,
1885 /* pfnPowerOff */
1886 NULL,
1887 /* pfnSoftReset */
1888 NULL,
1889 /* u32VersionEnd */
1890 PDM_DRVREG_VERSION
1891};
1892/* 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