VirtualBox

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

Last change on this file since 52901 was 51612, checked in by vboxsync, 11 years ago

6813 Use of server side API wrapper code - ConsoleImpl.cpp

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