Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 41351)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 41352)
@@ -607,4 +607,5 @@
 	$(if $(VBOX_WITH_EXTPACK),src-all/ExtPackManagerImpl.cpp src-all/ExtPackUtil.cpp,) \
 	$(if $(VBOX_WITH_USB_VIDEO),src-client/UsbWebcamInterface.cpp,) \
+	$(if $(VBOX_WITH_USB_CARDREADER),src-client/UsbCardReader.cpp,) \
 	src-client/AdditionsFacilityImpl.cpp \
 	src-client/AudioSnifferInterface.cpp \
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 41351)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 41352)
@@ -36,4 +36,7 @@
 #ifdef VBOX_WITH_USB_VIDEO
 class UsbWebcamInterface;
+#endif
+#ifdef VBOX_WITH_USB_CARDREADER
+class UsbCardReader;
 #endif
 class ConsoleVRDPServer;
@@ -220,4 +223,7 @@
 #endif
     EventSource *getEventSource() { return mEventSource; }
+#ifdef VBOX_WITH_USB_CARDREADER
+    UsbCardReader *getUsbCardReader() { return mUsbCardReader; }
+#endif
 
     int VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain);
@@ -760,4 +766,7 @@
     UsbWebcamInterface * const mUsbWebcamInterface;
 #endif
+#ifdef VBOX_WITH_USB_CARDREADER
+    UsbCardReader * const mUsbCardReader;
+#endif
     BusAssignmentManager* mBusMgr;
 
Index: /trunk/src/VBox/Main/include/ConsoleVRDPServer.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 41351)
+++ /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 41352)
@@ -26,4 +26,5 @@
 #include <VBox/RemoteDesktop/VRDEImage.h>
 #include <VBox/RemoteDesktop/VRDEMousePtr.h>
+#include <VBox/RemoteDesktop/VRDESCard.h>
 
 #include <VBox/HostServices/VBoxClipboardExt.h>
@@ -142,4 +143,6 @@
     int SendVideoSreamOn(bool fFetch);
 #endif
+
+    int SCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData);
 
 private:
@@ -263,4 +266,18 @@
     /* Mouse pointer interface. */
     VRDEMOUSEPTRINTERFACE m_interfaceMousePtr;
+
+    /* Smartcard interface. */
+    VRDESCARDINTERFACE m_interfaceSCard;
+    VRDESCARDCALLBACKS m_interfaceCallbacksSCard;
+    static DECLCALLBACK(int) VRDESCardCbNotify(void *pvContext,
+                                               uint32_t u32Id,
+                                               void *pvData,
+                                               uint32_t cbData);
+    static DECLCALLBACK(int) VRDESCardCbResponse(void *pvContext,
+                                                 int rcRequest,
+                                                 void *pvUser,
+                                                 uint32_t u32Function,
+                                                 void *pvData,
+                                                 uint32_t cbData);
 };
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 41351)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 41352)
@@ -60,4 +60,7 @@
 # include "UsbWebcamInterface.h"
 #endif
+#ifdef VBOX_WITH_USB_CARDREADER
+# include "UsbCardReader.h"
+#endif
 #include "ProgressCombinedImpl.h"
 #include "ConsoleVRDPServer.h"
@@ -376,4 +379,7 @@
     , mUsbWebcamInterface(NULL)
 #endif
+#ifdef VBOX_WITH_USB_CARDREADER
+    , mUsbCardReader(NULL)
+#endif
     , mBusMgr(NULL)
     , mVMStateChangeCallbackDisabled(false)
@@ -532,4 +538,8 @@
     AssertReturn(mUsbWebcamInterface, E_FAIL);
 #endif
+#ifdef VBOX_WITH_USB_CARDREADER
+    unconst(mUsbCardReader) = new UsbCardReader(this);
+    AssertReturn(mUsbCardReader, E_FAIL);
+#endif
 
     /* VirtualBox events registration. */
@@ -624,4 +634,12 @@
         delete mUsbWebcamInterface;
         unconst(mUsbWebcamInterface) = NULL;
+    }
+#endif
+
+#ifdef VBOX_WITH_USB_CARDREADER
+    if (mUsbCardReader)
+    {
+        delete mUsbCardReader;
+        unconst(mUsbCardReader) = NULL;
     }
 #endif
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 41351)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 41352)
@@ -2343,4 +2343,8 @@
                 InsertConfigString(pLunL0,    "Driver", "DrvDirectCardReader");
                 InsertConfigNode(pLunL0,    "Config", &pCfg);
+# else
+                InsertConfigString(pLunL0,    "Driver", "UsbCardReader");
+                InsertConfigNode(pLunL0,    "Config", &pCfg);
+                InsertConfigInteger(pCfg,   "Object", (uintptr_t)mUsbCardReader);
 # endif
 #endif
Index: /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp	(revision 41351)
+++ /trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp	(revision 41352)
@@ -26,4 +26,7 @@
 #endif
 #include "VMMDev.h"
+#ifdef VBOX_WITH_USB_CARDREADER
+# include "UsbCardReader.h"
+#endif
 
 #include "Global.h"
@@ -1372,4 +1375,6 @@
     memset(&m_interfaceCallbacksImage, 0, sizeof (m_interfaceCallbacksImage));
     RT_ZERO(m_interfaceMousePtr);
+    RT_ZERO(m_interfaceSCard);
+    RT_ZERO(m_interfaceCallbacksSCard);
 }
 
@@ -1601,4 +1606,27 @@
                     }
 
+                    /* Smartcard interface. */
+                    m_interfaceSCard.header.u64Version = 1;
+                    m_interfaceSCard.header.u64Size = sizeof(m_interfaceSCard);
+
+                    m_interfaceCallbacksSCard.header.u64Version = 1;
+                    m_interfaceCallbacksSCard.header.u64Size = sizeof(m_interfaceCallbacksSCard);
+                    m_interfaceCallbacksSCard.VRDESCardCbNotify = VRDESCardCbNotify;
+                    m_interfaceCallbacksSCard.VRDESCardCbResponse = VRDESCardCbResponse;
+
+                    vrc = mpEntryPoints->VRDEGetInterface(mhServer,
+                                                          VRDE_SCARD_INTERFACE_NAME,
+                                                          &m_interfaceSCard.header,
+                                                          &m_interfaceCallbacksSCard.header,
+                                                          this);
+                    if (RT_SUCCESS(vrc))
+                    {
+                        LogRel(("VRDE: [%s]\n", VRDE_SCARD_INTERFACE_NAME));
+                    }
+                    else
+                    {
+                        RT_ZERO(m_interfaceSCard);
+                    }
+
                     /* Since these interfaces are optional, it is always a success here. */
                     vrc = VINF_SUCCESS;
@@ -1971,4 +1999,60 @@
 
     return VINF_SUCCESS;
+}
+
+/* static */ DECLCALLBACK(int) ConsoleVRDPServer::VRDESCardCbNotify(void *pvContext,
+                                                                    uint32_t u32Id,
+                                                                    void *pvData,
+                                                                    uint32_t cbData)
+{
+#ifdef VBOX_WITH_USB_CARDREADER
+    ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvContext);
+    UsbCardReader *pReader = pThis->mConsole->getUsbCardReader();
+    return pReader->VRDENotify(u32Id, pvData, cbData);
+#else
+    NOREF(pvContext);
+    NOREF(u32Id);
+    NOREF(pvData);
+    NOREF(cbData);
+    return VERR_NOT_SUPPORTED;
+#endif
+}
+
+/* static */ DECLCALLBACK(int) ConsoleVRDPServer::VRDESCardCbResponse(void *pvContext,
+                                                                      int rcRequest,
+                                                                      void *pvUser,
+                                                                      uint32_t u32Function,
+                                                                      void *pvData,
+                                                                      uint32_t cbData)
+{
+#ifdef VBOX_WITH_USB_CARDREADER
+    ConsoleVRDPServer *pThis = static_cast<ConsoleVRDPServer*>(pvContext);
+    UsbCardReader *pReader = pThis->mConsole->getUsbCardReader();
+    return pReader->VRDEResponse(rcRequest, pvUser, u32Function, pvData, cbData);
+#else
+    NOREF(pvContext);
+    NOREF(rcRequest);
+    NOREF(pvUser);
+    NOREF(u32Function);
+    NOREF(pvData);
+    NOREF(cbData);
+    return VERR_NOT_SUPPORTED;
+#endif
+}
+
+int ConsoleVRDPServer::SCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData)
+{
+    int rc = VINF_SUCCESS;
+
+    if (mhServer && mpEntryPoints && m_interfaceSCard.VRDESCardRequest)
+    {
+        rc = m_interfaceSCard.VRDESCardRequest(mhServer, pvUser, u32Function, pvData, cbData);
+    }
+    else
+    {
+        rc = VERR_NOT_SUPPORTED;
+    }
+
+    return rc;
 }
 
Index: /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp	(revision 41351)
+++ /trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp	(revision 41352)
@@ -27,4 +27,7 @@
 #ifdef VBOX_WITH_USB_VIDEO
 # include "UsbWebcamInterface.h"
+#endif
+#ifdef VBOX_WITH_USB_CARDREADER
+# include "UsbCardReader.h"
 #endif
 #include "ConsoleImpl.h"
@@ -76,4 +79,10 @@
 #endif
 
+#ifdef VBOX_WITH_USB_CARDREADER
+    rc = pCallbacks->pfnRegister(pCallbacks, &UsbCardReader::DrvReg);
+    if (RT_FAILURE(rc))
+        return rc;
+#endif
+
     rc = pCallbacks->pfnRegister(pCallbacks, &Console::DrvStatusReg);
     if (RT_FAILURE(rc))
