diff --git a/Makefile.objs b/Makefile.objs
index f513ffa..1fe1146 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -355,7 +355,7 @@ endif
 ######################################################################
 # smartcard
 
-libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o
+libcacard-y = cac.o event.o passthru.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/libcacard/passthru.c b/libcacard/passthru.c
new file mode 100644
index 0000000..d78e2db
--- /dev/null
+++ b/libcacard/passthru.c
@@ -0,0 +1,609 @@
+/*
+ * implement the applets for the CAC card.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifdef USE_PASSTHRU
+#include <stdlib.h>
+#include <string.h>
+
+#include <pcsclite.h>
+
+#include "qemu-thread.h"
+
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "card_7816.h"
+#include "vreader.h"
+#include "vcard_emul.h"
+#include "passthru.h"
+
+/*
+ * Passthru applet private data
+ */
+struct VCardAppletPrivateStruct {
+    char *reader_name;
+    /* pcsc-lite parameters */
+    SCARDHANDLE hCard;
+    uint32_t hProtocol;
+    SCARD_IO_REQUEST *send_io;
+    unsigned char atr[MAX_ATR_SIZE];
+    int atr_len;
+};
+
+static SCARDCONTEXT global_context;
+
+#define MAX_RESPONSE_LENGTH 261 /*65537 */
+/*
+ * handle all the APDU's that are common to all CAC applets
+ */
+static VCardStatus
+passthru_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
+{
+    LONG rv;
+    unsigned char buf[MAX_RESPONSE_LENGTH];
+    uint32_t len = MAX_RESPONSE_LENGTH;
+    VCardAppletPrivate *applet_private = NULL;
+    SCARD_IO_REQUEST receive_io;
+
+    applet_private = vcard_get_current_applet_private(card, 0);
+    if (applet_private == NULL) {
+        *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR);
+        return VCARD_DONE;
+    }
+
+    rv = SCardTransmit(applet_private->hCard, applet_private->send_io,
+                       apdu->a_data, apdu->a_len, &receive_io, buf, &len);
+    if (rv != SCARD_S_SUCCESS) {
+        *response = vcard_make_response(VCARD7816_STATUS_EXC_ERROR);
+        return VCARD_DONE;
+    }
+
+    *response = vcard_response_new_data(buf, len);
+    if (*response == NULL) {
+        *response =
+            vcard_make_response(VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
+    } else {
+        (*response)->b_total_len = (*response)->b_len;
+    }
+    return VCARD_DONE;
+}
+
+static void
+passthru_card_set_atr(VCard *card, unsigned char *atr, int atr_len)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    applet_private = vcard_get_current_applet_private(card, 0);
+    if (applet_private == NULL) {
+        return;
+    }
+    applet_private->atr_len = MIN(atr_len, sizeof(applet_private->atr));
+    memcpy(applet_private->atr, atr, applet_private->atr_len);
+}
+
+static void passthru_card_get_atr(VCard *card, unsigned char *atr, int *atr_len)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    SCARD_READERSTATE *state;
+
+    applet_private = vcard_get_current_applet_private(card, 0);
+    if ((applet_private == NULL) || (applet_private->atr_len == 0)) {
+        vcard_emul_get_atr(card, atr, atr_len);
+        return;
+    }
+    *atr_len = MIN(applet_private->atr_len, *atr_len);
+    memcpy(atr, applet_private->atr, *atr_len);
+    return;
+}
+
+/*
+ *  reset the inter call state between applet selects
+ */
+static VCardStatus
+passthru_reset(VCard *card, int channel)
+{
+    return VCARD_DONE;
+}
+
+static VCardStatus
+passthru_pcsc_lite_init()
+{
+    LONG rv;
+    if (global_context != 0) {
+        return VCARD_DONE;
+    }
+    rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &global_context);
+    if (rv != SCARD_S_SUCCESS) {
+        return VCARD_FAIL;
+    }
+    return VCARD_DONE;
+}
+
+/*
+ *  match if s1 is completely contained in s2
+ */
+static int
+string_match(const char *s1, const char *s2)
+{
+    int len = strlen(s1);
+    const char *start;
+
+    for (start = strchr(s2, *s1); start; start = strchr(start+1, *s1)) {
+        if (strncmp(start, s1, len) == 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
+/*
+ *  Look for the reader that best matches the name for VReader
+ */
+static char *
+passthru_get_reader_name(VReader *reader)
+{
+    const char *reader_name = vreader_get_name(reader);
+    char *reader_list = NULL;
+    char *reader_entry = NULL;
+    char *reader_match = NULL;
+    uint32_t reader_string_length;
+    VCardStatus status;
+    LONG rv;
+
+    if (reader_name == NULL) {
+        return NULL;
+    }
+
+    status = passthru_pcsc_lite_init();
+    if (status != VCARD_DONE) {
+        return NULL;
+    }
+
+
+    /* find the existing reader names */
+    rv = SCardListReaders(global_context, NULL, NULL, &reader_string_length);
+    if (rv !=  SCARD_S_SUCCESS) {
+        return NULL;
+    }
+    reader_list = (char *)qemu_malloc(reader_string_length);
+    rv = SCardListReaders(global_context, NULL, reader_list,
+                          &reader_string_length);
+    if (rv !=  SCARD_S_SUCCESS) {
+        goto cleanup;
+    }
+
+    /* match that name */
+    for (reader_entry = reader_list; *reader_entry;
+                                   reader_entry += strlen(reader_entry)+1) {
+        if (string_match(reader_entry, reader_name)) {
+            reader_match = strdup(reader_entry);
+            break;
+        }
+    }
+cleanup:
+    if (reader_list) {
+        qemu_free(reader_list);
+    }
+    return reader_match;
+}
+
+
+/*
+ * utilities for creating and destroying the private applet data
+ */
+static void
+passthru_delete_applet_private(VCardAppletPrivate *applet_private)
+{
+    if (applet_private == NULL) {
+        return;
+    }
+    if (applet_private->hCard) {
+        SCardDisconnect(applet_private->hCard, SCARD_LEAVE_CARD);
+    }
+    if (applet_private->reader_name != NULL) {
+        qemu_free(applet_private->reader_name);
+    }
+    qemu_free(applet_private);
+}
+
+static VCardAppletPrivate *
+passthru_new_applet_private(VReader *reader)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    LONG rv;
+
+    applet_private = (VCardAppletPrivate *)qemu_malloc(sizeof(VCardAppletPrivate));
+
+    applet_private->hCard = 0;
+    applet_private->reader_name = NULL;
+
+    applet_private->reader_name = passthru_get_reader_name(reader);
+    if (applet_private->reader_name == NULL) {
+        goto fail;
+    }
+
+    rv = SCardConnect(global_context, applet_private->reader_name,
+        SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,
+        &applet_private->hCard,
+        &applet_private->hProtocol);
+    if (rv !=  SCARD_S_SUCCESS) {
+        goto fail;
+    }
+
+    if (applet_private->hProtocol == SCARD_PROTOCOL_T0) {
+        applet_private->send_io = SCARD_PCI_T0;
+    } else {
+        applet_private->send_io = SCARD_PCI_T1;
+    }
+    applet_private->atr_len = 0;
+    return applet_private;
+
+fail:
+    if (applet_private) {
+        passthru_delete_applet_private(applet_private);
+    }
+    return NULL;
+}
+
+
+/*
+ * create a new applet which links to our override function.
+ */
+static VCardApplet *
+passthru_new_applet(VReader *reader)
+{
+    VCardAppletPrivate *applet_private = NULL;
+    VCardApplet *applet = NULL;
+    unsigned char passthru_aid[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+    int passthru_aid_len = sizeof(passthru_aid);
+
+    applet_private = passthru_new_applet_private(reader);
+    if (applet_private == NULL) {
+        goto failure;
+    }
+    applet = vcard_new_applet(passthru_process_apdu, passthru_reset,
+                              passthru_aid, passthru_aid_len);
+    if (applet == NULL) {
+        goto failure;
+    }
+    vcard_set_applet_private(applet, applet_private,
+                          passthru_delete_applet_private);
+    applet_private = NULL;
+
+    return applet;
+
+failure:
+    if (applet_private != NULL) {
+        passthru_delete_applet_private(applet_private);
+    }
+    return NULL;
+}
+
+
+
+/*
+ * Initialize the card. This is the only 'card type emulator' portion of this
+ * the rest are connected through function pointers.
+ */
+VCardStatus
+passthru_card_init(VReader *vreader, VCard *card,
+                const char *flags,
+                unsigned char * const *cert,
+                int cert_len[],
+                VCardKey *key[] /* adopt the keys*/,
+                int cert_count)
+{
+    int i;
+    VCardApplet *applet;
+
+    /* Don't do soft emulation of the 7816, pass everything to the card */
+    vcard_set_type(card, VCARD_DIRECT);
+
+    applet = passthru_new_applet(vreader);
+    if (applet == NULL) {
+        goto failure;
+    }
+
+    vcard_add_applet(card, applet);
+
+    /* we are adopting the keys, so free them now (since we don't use them) */
+    for (i = 0; i < cert_count; i++) {
+        vcard_emul_delete_key(key[i]);
+    }
+
+    return VCARD_DONE;
+
+failure:
+    return VCARD_FAIL;
+}
+
+/*
+ *  Begin passthru_emul code. This emulator only works with the passthru card
+ *  type.
+ *
+ */
+
+/*
+ *  Get the state entry that matches this reader. If none found, return NULL
+ */
+static SCARD_READERSTATE_A *
+passthru_get_reader_state(SCARD_READERSTATE_A *reader_states,
+                          int reader_count, char *name)
+{
+    int i;
+
+    for (i = 0; i < reader_count; i++) {
+        if (name == NULL && reader_states[i].szReader == NULL) {
+            /* looking for a blank slot to return */
+            return &reader_states[i];
+        }
+        if (name == NULL || reader_states[i].szReader == NULL) {
+            continue;
+        }
+        if (strcmp(name, reader_states[i].szReader) == 0) {
+            return &reader_states[i];
+        }
+    }
+    return NULL;
+}
+
+/*
+ * find a card slot that has been cleared out
+ */
+static SCARD_READERSTATE_A *
+passthru_get_blank_reader(SCARD_READERSTATE_A *reader_states, int reader_count)
+{
+    return passthru_get_reader_state(reader_states,  reader_count, NULL);
+}
+
+
+/*
+ *  This is the main work of the emulator, handling the thread that looks for
+ *  changes in the readers and the cards.
+ */
+static void *
+passthru_emul_event_thread(void *args)
+{
+    char *reader_list = NULL;
+    int reader_list_len = 0;
+    SCARD_READERSTATE_A *reader_states = NULL;
+    int reader_count = 0;     /* number of active readers */
+    int max_reader_count = 0; /* size of the reader_state array (including
+                                 inactive readers) */
+    LONG rv;
+    int timeout = 1000;
+    int i;
+
+    do {
+        /* variables to hold on to our new values until we are ready to replace
+         * our old values */
+        char *new_reader_list = NULL;
+        int new_reader_list_len = 0;
+        int new_reader_count = 0;
+
+        /* other temps */
+        char *reader_entry;
+        VReader *reader;
+
+        /*
+         * First check to see if the reader list has changed
+         */
+        rv = SCardListReaders(global_context, NULL, NULL, &new_reader_list_len);
+        if (rv !=  SCARD_S_SUCCESS) {
+            goto next;
+        }
+        /*
+         * If the names have changed, we need to update our list and states.
+         * This is where we detect reader insertions and removals.
+         */
+        if (new_reader_list_len != reader_list_len) {
+            /* update the list */
+            new_reader_list = (char *)qemu_malloc(new_reader_list_len);
+            rv = SCardListReaders(global_context, NULL, new_reader_list,
+                                  &new_reader_list_len);
+            if (rv !=  SCARD_S_SUCCESS) {
+                qemu_free(new_reader_list);
+                goto next;
+            }
+            /* clear out our event state */
+            for (i = 0; i < reader_count; i++) {
+                    reader_states[i].dwEventState = 0;
+            }
+            /* count the readers and mark the ones that are still with us */
+            for (reader_entry = new_reader_list; *reader_entry;
+                 reader_entry += strlen(reader_entry)+1) {
+                SCARD_READERSTATE_A *this_state;
+                new_reader_count++;
+                /* if the reader is still on the list, mark it present */
+                this_state = passthru_get_reader_state(reader_states,
+                                                       reader_count,
+                                                       reader_entry);
+                if (this_state) {
+                    this_state->dwEventState = SCARD_STATE_PRESENT;
+                }
+            }
+            /* eject any removed readers */
+            for (i = 0; i < reader_count; i++) {
+                if (reader_states[i].dwEventState == SCARD_STATE_PRESENT) {
+                    reader_states[i].dwEventState = 0;
+                    continue;
+                }
+                reader = vreader_get_reader_by_name(reader_states[i].szReader);
+                vreader_remove_reader(reader);
+                vreader_free(reader);
+                reader_states[i].szReader = NULL;
+            }
+            /* handle the shrinking list */
+            if (new_reader_count < reader_count) {
+                /* fold all the valid entries at the end of our reader_states
+                 * array up into those locations vacated by ejected readers. */
+                for (i = reader_count - 1; i < (new_reader_count - 1); i--) {
+                    if (reader_states[i].szReader) {
+                        SCARD_READERSTATE_A *blank_reader;
+                        blank_reader =
+                            passthru_get_blank_reader(reader_states,
+                                                      new_reader_count);
+                        assert(blank_reader);
+                        *blank_reader = reader_states[i];
+                        reader_states[i].szReader = NULL;
+                    }
+                }
+            }
+            /* handle the growing list */
+            if (new_reader_count >  max_reader_count) {
+                SCARD_READERSTATE_A *new_reader_states;
+
+                /* grow the list */
+                new_reader_states =
+                    (SCARD_READERSTATE_A *)realloc(reader_states,
+                        sizeof(SCARD_READERSTATE_A)*new_reader_count);
+                if (new_reader_states) {
+                    /* successful, update our current state */
+                    reader_states = new_reader_states;
+                    max_reader_count = new_reader_count;
+                } else {
+                    new_reader_count = max_reader_count; /* couldn't get enough
+                                                          * space to handle
+                                                          * all the new readers
+                                                          * */
+                }
+                /* mark our new entries as empty */
+                for (i = reader_count; i > new_reader_count; i++) {
+                    reader_states[i].szReader = NULL;
+                }
+            }
+            /* now walk the reader list, updating the state */
+            for (reader_entry = new_reader_list; *reader_entry;
+                 reader_entry += strlen(reader_entry)+1) {
+                SCARD_READERSTATE_A *this_state;
+                this_state = passthru_get_reader_state(reader_states,
+                                                       new_reader_count,
+                                                       reader_entry);
+                if (this_state) {
+                    /* replace the old copy of the string with the new copy.
+                     * This will allow us to free reader_list at the end */
+                    reader_states->szReader = reader_entry;
+                    continue;
+                }
+                /* this is a new reader, add it to the list */
+                this_state =
+                    passthru_get_blank_reader(reader_states, new_reader_count);
+                if (!this_state) {
+                    continue; /* this can happen of we couldn't get enough
+                                 slots in the grow list */
+                }
+                this_state->szReader = reader_entry;
+                this_state->dwCurrentState = SCARD_STATE_UNAWARE;
+                reader = vreader_new(reader_entry, NULL, NULL);
+                if (reader) {
+                    vreader_add_reader(reader);
+                }
+                vreader_free(reader);
+            }
+            /* finally update our current variables */
+            qemu_free(reader_list);
+            reader_list = new_reader_list;
+            reader_list_len = new_reader_list_len;
+            reader_count = new_reader_count;
+        }
+next:
+        rv = SCardGetStatusChange(global_context, timeout,
+                                  reader_states, reader_count);
+        if (rv == SCARD_E_TIMEOUT) {
+            continue; /* check for new readers */
+        }
+        if (rv != SCARD_S_SUCCESS) {
+            static int restarts;
+            VCardStatus status;
+
+            /* try resetting the pcsc_lite subsystem */
+            SCardReleaseContext(global_context);
+            global_context = 0; /* should close it */
+            error_report("SCard failure %x\n", rv);
+            restarts++;
+            if (restarts >= 3) {
+                error_report("SCard failed %d times\n", restarts);
+                return; /* exit thread */
+            }
+            status = passthru_pcsc_lite_init();
+            assert(status == CARD_DONE);
+            sleep(1);
+            continue;
+        }
+        /* deal with card insertion/removal */
+        for (i = 0; i < reader_count ; i++) {
+            if ((reader_states[i].dwEventState & SCARD_STATE_CHANGED) == 0) {
+                continue;
+            }
+            reader_states[i].dwCurrentState = reader_states[i].dwEventState;
+            reader = vreader_get_reader_by_name(reader_states[i].szReader);
+            if (reader == NULL) {
+                continue;
+            }
+            if (reader_states[i].dwEventState & SCARD_STATE_EMPTY) {
+                if (vreader_card_is_present(reader) == VREADER_OK) {
+                    vreader_insert_card(reader, NULL);
+                }
+            }
+            if (reader_states[i].dwEventState & SCARD_STATE_PRESENT) {
+                VCard *card;
+                VCardStatus status = VCARD_FAIL;
+                /* if there already was a card present, eject it before we
+                 * insert the new one */
+                if (vreader_card_is_present(reader) == VREADER_OK) {
+                    vreader_insert_card(reader, NULL);
+                }
+
+                card = vcard_new(NULL, NULL);
+                if (card != NULL) {
+                    status = passthru_card_init(reader, card, "",
+                                                NULL, NULL, NULL, 0);
+                    passthru_card_set_atr(card, reader_states[i].rgbAtr,
+                                  reader_states[i].cbAtr);
+                    vcard_set_atr_func(card, passthru_card_get_atr);
+                }
+                if (status == VCARD_DONE) {
+                    vreader_insert_card(reader, card);
+                }
+                vcard_free(card);
+            }
+            vreader_free(reader);
+        }
+
+    } while (1);
+    return NULL;
+}
+
+/*
+ *  Initializing the passthru emul is simply initializing pcsc-lite and
+ *  launching the event thread.
+ */
+VCardStatus
+passthru_emul_init(VCardEmulOptions *options)
+{
+    QemuThread tid;
+    thread_status_t tstatus;
+    VCardStatus status;
+
+    vreader_init();
+    vevent_queue_init();
+
+    status = passthru_pcsc_lite_init();
+    if (status != VCARD_DONE) {
+        return status;
+    }
+
+    /* launch reader thread (qemu_thread_create exits on error) */
+    qemu_thread_create(tid, passthru_emul_event_thread, NULL);
+    return VCARD_DONE;
+}
+
+
+VCardEmulOptions *
+passthru_emul_options(const char *args)
+{
+    return NULL;
+}
+#endif
diff --git a/libcacard/passthru.h b/libcacard/passthru.h
new file mode 100644
index 0000000..68946ab
--- /dev/null
+++ b/libcacard/passthru.h
@@ -0,0 +1,53 @@
+/*
+ * passthru card type emulator and passhtru emulator.
+ *
+ * passhtru card type emulator can be used with other low level card emulators,
+ * as long as they can recognize card insertion and removals.
+ *
+ * the passthru vcard_emulator, can only use passthru card types.
+ *
+ * Be careful using passthru. 1) passthru does not know the locking state of
+ * the card from the guest side, and thus does not try to get locks. This means
+ * client access can interfere with the guest use of the card. 2) passthru does
+ * not provide the guest and client unique login states for the card. That
+ * means that it is possible for the guest to access private data on the
+ * card without authenticating. You have been warned.
+ *
+ * Passthru is most useful in the following cases: 1) provisioning. Card type
+ *  emulators cannot emulate the open platform secure connections because the
+ *  client software does not have access to the global platform keys on the
+ *  card. Passthru drives these apdu's directly to the card. 2) odd cards. If
+ *  you have guest software the knows how to access the card, but no client
+ *  side PKCS #11 module, then passthru can provide access to those cards.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef PASSTHRU_H
+#define PASSTHRU_H 1
+
+#include "vcard.h"
+#include "vcard_emul.h"
+#include "vreader.h"
+
+/*
+ * Initialize the card. This is the only 'card type emulator' portion of this
+ * the rest are connected through function pointers. NOTE: certs are ignored,
+ * keys are freed.
+ */
+VCardStatus passthru_card_init(VReader *vreader, VCard *card,
+              const char *flags, unsigned char * const *cert, int cert_len[],
+              VCardKey *key[], int cert_count);
+
+/*
+ * Use this instead of vcard_emul_init to initialize passthru.
+ * passthru is the exception to the rule that only one emul can be compiled
+ * at once. NOTE: you can still have only one emul active at once. The
+ * passhtru card type emul, however can be used with other emuls.
+ *
+ * passthru does not support other card type emuls.
+ */
+VCardStatus passthru_emul_init(VCardEmulOptions *options);
+VCardEmulOptions *passthru_emul_options(const char *args);
+#endif
diff --git a/libcacard/vcard_emul_type.c b/libcacard/vcard_emul_type.c
index 59a1458..d4b5557 100644
--- a/libcacard/vcard_emul_type.c
+++ b/libcacard/vcard_emul_type.c
@@ -12,6 +12,7 @@
 #include "vcardt.h"
 #include "vcard_emul_type.h"
 #include "cac.h"
+#include "passthru.h"
 
 VCardStatus vcard_init(VReader *vreader, VCard *vcard,
                        VCardEmulType type, const char *params,
@@ -24,6 +25,11 @@ VCardStatus vcard_init(VReader *vreader, VCard *vcard,
     case VCARD_EMUL_CAC:
         return cac_card_init(vreader, vcard, params,
                              cert, cert_len, key,  cert_count);
+#ifdef USE_PASSTHRU
+    case VCARD_EMUL_PASSTHRU:
+        return passthru_card_init(vreader, vcard, params,
+                                  cert, cert_len, key,  cert_count);
+#endif
     /* add new ones here */
     default:
         break;
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index 8dde449..590feef 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -30,6 +30,7 @@
 #include "vreader.h"
 #include "vcard_emul.h"
 #include "vevent.h"
+#include "passthru.h"
 
 int verbose;
 
@@ -500,6 +501,7 @@ main(
      VReaderStatus reader_status;
     VReader *reader = NULL;
     VCardEmulOptions *command_line_options = NULL;
+    int passthru = 0;
 
     char *cert_names[MAX_CERTS];
     char *emul_args = NULL;
@@ -519,8 +521,12 @@ main(
             emul_args = optarg;
             break;
         case 'p':
+#ifdef USE_PASSTHRU
+            passthru = 1;
+#else
             print_usage();
             exit(4);
+#endif
             break;
         case 'd':
             verbose = get_id_from_string(optarg, 1);
@@ -533,7 +539,7 @@ main(
         exit(4);
     }
 
-    if (cert_count > 0) {
+    if (!passthru && cert_count > 0) {
         char *new_args;
         int len, i;
         /* if we've given some -c options, we clearly we want do so some
@@ -559,7 +565,12 @@ main(
         emul_args = new_args;
     }
     if (emul_args) {
-        command_line_options = vcard_emul_options(emul_args);
+#ifdef USE_PASSTHRU
+        command_line_options = passthru ? passthru_emul_options(emul_args) :
+#else
+        command_line_options =
+#endif
+                                          vcard_emul_options(emul_args);
     }
 
     qemu_host = strdup(argv[argc - 2]);
@@ -570,7 +581,12 @@ main(
     qemu_mutex_init(&pending_reader_lock);
     qemu_cond_init(&pending_reader_condition);
 
-    vcard_emul_init(command_line_options);
+#ifdef USE_PASSTHRU
+    if (passthru) {
+        passthru_emul_init(command_line_options);
+    } else
+#endif
+        vcard_emul_init(command_line_options);
 
     printf("> ");
     fflush(stdout);
