Changeset 3506 for trunk/src/libopensc/reader-pcsc.c
- Timestamp:
- 04/29/08 19:01:19 (7 months ago)
- Files:
-
- 1 modified
-
trunk/src/libopensc/reader-pcsc.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libopensc/reader-pcsc.c
r3502 r3506 645 645 rv = priv->gpriv->SCardBeginTransaction(pslot->pcsc_card); 646 646 647 if ((unsigned int)rv == SCARD_W_RESET_CARD) { 648 /* try to reconnect if the card was reset by some other application */ 649 rv = pcsc_reconnect(reader, slot, 0); 650 if (rv != SCARD_S_SUCCESS) { 651 PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv); 647 switch (rv) { 648 case SCARD_E_INVALID_HANDLE: 649 case SCARD_E_READER_UNAVAILABLE: 650 rv = pcsc_connect(reader, slot); 651 if (rv != SCARD_S_SUCCESS) { 652 PCSC_ERROR(reader->ctx, "SCardConnect failed", rv); 653 return pcsc_ret_to_error(rv); 654 } 655 /* return failure so that upper layers will be notified and try to lock again */ 656 return SC_ERROR_READER_REATTACHED; 657 case SCARD_W_RESET_CARD: 658 /* try to reconnect if the card was reset by some other application */ 659 rv = pcsc_reconnect(reader, slot, 0); 660 if (rv != SCARD_S_SUCCESS) { 661 PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv); 662 return pcsc_ret_to_error(rv); 663 } 664 /* return failure so that upper layers will be notified and try to lock again */ 665 return SC_ERROR_CARD_RESET; 666 case SCARD_S_SUCCESS: 667 pslot->locked = 1; 668 return SC_SUCCESS; 669 default: 670 PCSC_ERROR(reader->ctx, "SCardBeginTransaction failed", rv); 652 671 return pcsc_ret_to_error(rv); 653 } 654 /* Now try to begin a new transaction after we reconnected and we fail if 655 some other program was faster to lock the reader */ 656 rv = priv->gpriv->SCardBeginTransaction(pslot->pcsc_card); 657 } 658 659 if (rv != SCARD_S_SUCCESS) { 660 PCSC_ERROR(reader->ctx, "SCardBeginTransaction failed", rv); 661 return pcsc_ret_to_error(rv); 662 } 663 664 pslot->locked = 1; 665 666 return SC_SUCCESS; 672 } 667 673 } 668 674 … … 732 738 { 733 739 LONG rv; 734 DWORD reader_buf_size;735 char *reader_buf = NULL, *p;736 const char *mszGroups = NULL;737 int r;738 740 struct pcsc_global_private_data *gpriv; 739 741 scconf_block *conf_block = NULL; … … 754 756 gpriv->enable_pinpad = 0; 755 757 gpriv->provider_library = DEFAULT_PCSC_PROVIDER; 758 gpriv->pcsc_ctx = -1; 756 759 757 760 conf_block = sc_get_conf_block(ctx, "reader_driver", "pcsc", 1); … … 819 822 } 820 823 821 rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, 822 NULL, NULL, &gpriv->pcsc_ctx); 823 if (rv != SCARD_S_SUCCESS) { 824 ret = pcsc_ret_to_error(rv); 824 *reader_data = gpriv; 825 gpriv = NULL; 826 ret = SC_SUCCESS; 827 828 out: 829 if (ret != SC_SUCCESS) { 830 if (gpriv->pcsc_ctx != 0) 831 gpriv->SCardReleaseContext(gpriv->pcsc_ctx); 832 if (gpriv->dlhandle != NULL) 833 lt_dlclose(gpriv->dlhandle); 834 if (gpriv != NULL) 835 free(gpriv); 836 } 837 838 return 0; 839 } 840 841 static int pcsc_finish(sc_context_t *ctx, void *prv_data) 842 { 843 struct pcsc_global_private_data *priv = (struct pcsc_global_private_data *) prv_data; 844 845 if (priv) { 846 priv->SCardReleaseContext(priv->pcsc_ctx); 847 lt_dlclose(priv->dlhandle); 848 free(priv); 849 } 850 851 return 0; 852 } 853 854 static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) 855 { 856 struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; 857 LONG rv; 858 DWORD reader_buf_size; 859 char *reader_buf = NULL, *p; 860 const char *mszGroups = NULL; 861 int ret = SC_ERROR_INTERNAL; 862 int again; 863 864 if (!prv_data) { 865 ret = SC_ERROR_NO_READERS_FOUND; 825 866 goto out; 826 867 } 827 rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, 828 (LPDWORD) &reader_buf_size); 829 if (rv != SCARD_S_SUCCESS || reader_buf_size < 2) { 830 ret = pcsc_ret_to_error(rv); /* No readers configured */ 831 goto out; 832 } 868 869 do { 870 rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, 871 (LPDWORD) &reader_buf_size); 872 if (rv != SCARD_S_SUCCESS) { 873 if (rv != SCARD_E_INVALID_HANDLE) { 874 ret = pcsc_ret_to_error(rv); 875 goto out; 876 } 877 878 rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, 879 NULL, NULL, &gpriv->pcsc_ctx); 880 if (rv != SCARD_S_SUCCESS) { 881 ret = pcsc_ret_to_error(rv); 882 goto out; 883 } 884 885 rv = SCARD_E_INVALID_HANDLE; 886 } 887 } while (rv != SCARD_S_SUCCESS); 833 888 834 889 reader_buf = (char *) malloc(sizeof(char) * reader_buf_size); … … 843 898 goto out; 844 899 } 845 p = reader_buf; 846 do { 847 sc_reader_t *reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t)); 848 struct pcsc_private_data *priv = (struct pcsc_private_data *) malloc(sizeof(struct pcsc_private_data)); 849 struct pcsc_slot_data *pslot = (struct pcsc_slot_data *) malloc(sizeof(struct pcsc_slot_data)); 850 sc_slot_info_t *slot; 851 852 if (reader == NULL || priv == NULL || pslot == NULL) { 853 if (reader) 854 free(reader); 855 if (priv) 856 free(priv); 857 if (pslot) 858 free(pslot); 859 break; 900 for (p = reader_buf; *p != '\x0'; p += strlen (p) + 1) { 901 sc_reader_t *reader = NULL; 902 struct pcsc_private_data *priv = NULL; 903 struct pcsc_slot_data *pslot = NULL; 904 sc_slot_info_t *slot = NULL; 905 int i; 906 int found = 0; 907 908 for (i=0;i < sc_ctx_get_reader_count (ctx) && !found;i++) { 909 sc_reader_t *reader = sc_ctx_get_reader (ctx, i); 910 if (reader == NULL) { 911 ret = SC_ERROR_INTERNAL; 912 goto err1; 913 } 914 if (reader->ops == &pcsc_ops && !strcmp (reader->name, p)) { 915 found = 1; 916 } 917 } 918 919 /* Reader already available, skip */ 920 if (found) { 921 continue; 922 } 923 924 if ((reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t))) == NULL) { 925 ret = SC_ERROR_OUT_OF_MEMORY; 926 goto err1; 927 } 928 if ((priv = (struct pcsc_private_data *) malloc(sizeof(struct pcsc_private_data))) == NULL) { 929 ret = SC_ERROR_OUT_OF_MEMORY; 930 goto err1; 931 } 932 if ((pslot = (struct pcsc_slot_data *) malloc(sizeof(struct pcsc_slot_data))) == NULL) { 933 ret = SC_ERROR_OUT_OF_MEMORY; 934 goto err1; 860 935 } 861 936 … … 864 939 reader->driver = &pcsc_drv; 865 940 reader->slot_count = 1; 866 reader->name = strdup(p); 941 if ((reader->name = strdup(p)) == NULL) { 942 ret = SC_ERROR_OUT_OF_MEMORY; 943 goto err1; 944 } 867 945 priv->gpriv = gpriv; 868 priv->reader_name = strdup(p); 869 r = _sc_add_reader(ctx, reader); 870 if (r) { 871 free(priv->reader_name); 872 free(priv); 873 free(reader->name); 874 free(reader); 875 free(pslot); 876 break; 946 if ((priv->reader_name = strdup(p)) == NULL) { 947 ret = SC_ERROR_OUT_OF_MEMORY; 948 goto err1; 877 949 } 878 950 slot = &reader->slot[0]; … … 880 952 slot->drv_data = pslot; 881 953 memset(pslot, 0, sizeof(*pslot)); 954 if (_sc_add_reader(ctx, reader)) { 955 ret = SC_SUCCESS; /* silent ignore */ 956 goto err1; 957 } 882 958 refresh_slot_attributes(reader, slot); 883 959 884 while (*p++ != 0); 885 } while (p < (reader_buf + reader_buf_size - 1)); 886 887 *reader_data = gpriv; 888 gpriv = NULL; 960 continue; 961 962 err1: 963 if (priv != NULL) { 964 if (priv->reader_name) 965 free(priv->reader_name); 966 free(priv); 967 } 968 if (reader != NULL) { 969 if (reader->name) 970 free(reader->name); 971 free(reader); 972 } 973 if (slot != NULL) 974 free(pslot); 975 976 goto out; 977 } 978 889 979 ret = SC_SUCCESS; 890 980 891 981 out: 892 if (ret != SC_SUCCESS) { 893 if (gpriv->pcsc_ctx != 0) 894 gpriv->SCardReleaseContext(gpriv->pcsc_ctx); 895 if (reader_buf != NULL) 896 free(reader_buf); 897 if (gpriv->dlhandle != NULL) 898 lt_dlclose(gpriv->dlhandle); 899 if (gpriv != NULL) 900 free(gpriv); 901 } 902 903 return 0; 904 } 905 906 static int pcsc_finish(sc_context_t *ctx, void *prv_data) 907 { 908 struct pcsc_global_private_data *priv = (struct pcsc_global_private_data *) prv_data; 909 910 if (priv) { 911 priv->SCardReleaseContext(priv->pcsc_ctx); 912 lt_dlclose(priv->dlhandle); 913 free(priv); 914 } 915 916 return 0; 982 983 if (reader_buf != NULL) 984 free (reader_buf); 985 986 return ret; 917 987 } 918 988 … … 932 1002 pcsc_ops.init = pcsc_init; 933 1003 pcsc_ops.finish = pcsc_finish; 1004 pcsc_ops.detect_readers = pcsc_detect_readers; 934 1005 pcsc_ops.transmit = pcsc_transmit; 935 1006 pcsc_ops.detect_card_presence = pcsc_detect_card_presence;
