~ubuntu-branches/ubuntu/jaunty/pcsc-lite/jaunty-security

« back to all changes in this revision

Viewing changes to src/winscard_clnt.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2007-05-16 14:40:30 UTC
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20070516144030-6wk53ou910ctb9ds
Tags: upstream-1.4.1
ImportĀ upstreamĀ versionĀ 1.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 *  Damien Sauveron <damien.sauveron@labri.fr>
7
7
 *  Ludovic Rousseau <ludovic.rousseau@free.fr>
8
8
 *
9
 
 * $Id: winscard_clnt.c 2377 2007-02-05 13:13:56Z rousseau $
 
9
 * $Id: winscard_clnt.c 2527 2007-05-15 20:53:49Z rousseau $
10
10
 */
11
11
 
12
12
/**
31
31
#include "winscard.h"
32
32
#include "debug.h"
33
33
#include "thread_generic.h"
 
34
#include "strlcpycat.h"
34
35
 
35
36
#include "readerfactory.h"
36
37
#include "eventhandler.h"
37
38
#include "sys_generic.h"
38
39
#include "winscard_msg.h"
 
40
#include "utils.h"
39
41
 
40
42
/** used for backward compatibility */
41
43
#define SCARD_PROTOCOL_ANY_OLD  0x1000
42
44
 
43
 
#ifndef min
44
 
#define min(a,b) (((a) < (b)) ? (a) : (b))
45
 
#endif
46
 
 
47
45
#ifndef TRUE
48
46
#define TRUE 1
49
47
#define FALSE 0
59
57
struct timeval profile_time_start;
60
58
FILE *fd;
61
59
char profile_tty;
 
60
char fct_name[100];
62
61
 
63
62
#define PROFILE_START profile_start(__FUNCTION__);
64
 
#define PROFILE_END profile_end(__FUNCTION__);
 
63
#define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
65
64
 
66
65
static void profile_start(const char *f)
67
66
{
88
87
                        profile_tty = FALSE;
89
88
        }
90
89
 
 
90
        /* PROFILE_END was not called before? */
 
91
        if (profile_tty && fct_name[0])
 
92
                printf("\33[01;34m WARNING: %s starts before %s finishes\33[0m\n",
 
93
                        f, fct_name);
 
94
 
 
95
        strlcpy(fct_name, f, sizeof(fct_name));
 
96
 
91
97
        gettimeofday(&profile_time_start, NULL);
92
98
} /* profile_start */
93
99
 
107
113
} /* time_sub */
108
114
 
109
115
 
110
 
static void profile_end(const char *f)
 
116
static void profile_end(const char *f, LONG rv)
111
117
{
112
118
        struct timeval profile_time_end;
113
119
        long d;
116
122
        d = time_sub(&profile_time_end, &profile_time_start);
117
123
 
118
124
        if (profile_tty)
119
 
                fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
 
125
        {
 
126
                if (fct_name[0])
 
127
                {
 
128
                        if (strncmp(fct_name, f, sizeof(fct_name)))
 
129
                                printf("\33[01;34m WARNING: %s ends before %s\33[0m\n",
 
130
                                                f, fct_name);
 
131
                }
 
132
                else
 
133
                        printf("\33[01;34m WARNING: %s ends but we lost its start\33[0m\n",
 
134
                                f);
 
135
 
 
136
                /* allow to detect missing PROFILE_END calls */
 
137
                fct_name[0] = '\0';
 
138
 
 
139
                if (rv != SCARD_S_SUCCESS)
 
140
                        fprintf(stderr,
 
141
                                "\33[01;31mRESULT %s \33[35m%ld \33[34m0x%08lX %s\33[0m\n",
 
142
                                f, d, rv, pcsc_stringify_error(rv));
 
143
                else
 
144
                        fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m\n", f, d);
 
145
        }
120
146
        fprintf(fd, "%s %ld\n", f, d);
121
147
        fflush(fd);
122
148
} /* profile_end */
123
149
 
124
150
#else
125
151
#define PROFILE_START
126
 
#define PROFILE_END
 
152
#define PROFILE_END(rv)
127
153
#endif
128
154
 
129
155
/**
157
183
 */
158
184
static short isExecuted = 0;
159
185
 
 
186
 
 
187
/**
 
188
 * creation time of pcscd PCSCLITE_PUBSHM_FILE file
 
189
 */
 
190
static time_t daemon_ctime = 0;
 
191
static pid_t daemon_pid = 0;
 
192
 
160
193
/**
161
194
 * Memory mapped address used to read status information about the readers.
162
195
 * Each element in the vector \ref readerStates makes references to a part of
187
220
static LONG SCardGetContextIndice(SCARDCONTEXT);
188
221
static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
189
222
static LONG SCardRemoveContext(SCARDCONTEXT);
 
223
static LONG SCardCleanContext(LONG indice);
190
224
 
191
225
static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPSTR);
192
226
static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD, PDWORD);
196
230
static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
197
231
        LPBYTE pbAttr, LPDWORD pcbAttrLen);
198
232
 
199
 
static LONG SCardCheckDaemonAvailability(void);
 
233
LONG SCardCheckDaemonAvailability(void);
 
234
 
 
235
void DESTRUCTOR SCardUnload(void);
200
236
 
201
237
/*
202
238
 * Thread safety functions
245
281
 
246
282
        PROFILE_START
247
283
 
 
284
        /* Check if the server is running */
 
285
        if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
 
286
                return SCARD_E_NO_SERVICE;
 
287
 
248
288
        SCardLockThread();
249
289
        rv = SCardEstablishContextTH(dwScope, pvReserved1,
250
290
                pvReserved2, phContext);
251
291
        SCardUnlockThread();
252
292
 
253
 
        PROFILE_END
 
293
        PROFILE_END(rv)
254
294
 
255
295
        return rv;
256
296
}
294
334
        else
295
335
                *phContext = 0;
296
336
 
297
 
        /* Check if the server is running */
298
 
        if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
299
 
                return SCARD_E_NO_SERVICE;
300
 
 
301
337
        /*
302
338
         * Do this only once:
303
339
         * - Initialize debug of need.
325
361
                        return SCARD_E_NO_SERVICE;
326
362
                }
327
363
 
 
364
                /* close on exec so that child processes do not inherits the file
 
365
                 * descriptor. The child process will call SCardEstablishContext()
 
366
                 * if needed. */
 
367
                fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
 
368
 
328
369
                pageSize = SYS_GetPageSize();
329
370
 
330
371
                /*
547
588
        SCardRemoveContext(hContext);
548
589
        SCardUnlockThread();
549
590
 
550
 
        PROFILE_END
 
591
        PROFILE_END(scReleaseStruct.rv)
551
592
 
552
593
        return scReleaseStruct.rv;
553
594
}
713
754
                rv = SCardAddHandle(*phCard, dwContextIndex, (LPSTR) szReader);
714
755
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
715
756
 
716
 
                PROFILE_END
 
757
                PROFILE_END(rv)
717
758
 
718
759
                return rv;
719
760
        }
720
761
 
721
762
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
722
763
 
723
 
        PROFILE_END
 
764
        PROFILE_END(scConnectStruct.rv)
724
765
 
725
766
        return scConnectStruct.rv;
726
767
}
852
893
                return SCARD_E_READER_UNAVAILABLE;
853
894
        }
854
895
 
855
 
        scReconnectStruct.hCard = hCard;
856
 
        scReconnectStruct.dwShareMode = dwShareMode;
857
 
        scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
858
 
        scReconnectStruct.dwInitialization = dwInitialization;
859
 
        scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
860
 
 
861
 
        rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
862
 
                sizeof(scReconnectStruct),
863
 
                PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
864
 
 
865
 
        if (rv == -1)
866
 
        {
867
 
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
868
 
                return SCARD_E_NO_SERVICE;
869
 
        }
870
 
 
871
 
        /*
872
 
         * Read a message from the server
873
 
         */
874
 
        rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
875
 
 
876
 
        memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
877
 
 
878
 
        if (rv == -1)
879
 
        {
880
 
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
881
 
                return SCARD_F_COMM_ERROR;
882
 
        }
 
896
        do
 
897
        {
 
898
                scReconnectStruct.hCard = hCard;
 
899
                scReconnectStruct.dwShareMode = dwShareMode;
 
900
                scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
 
901
                scReconnectStruct.dwInitialization = dwInitialization;
 
902
                scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
 
903
 
 
904
                rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
 
905
                        sizeof(scReconnectStruct),
 
906
                        PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
 
907
 
 
908
                if (rv == -1)
 
909
                {
 
910
                        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
911
                        return SCARD_E_NO_SERVICE;
 
912
                }
 
913
 
 
914
                /*
 
915
                 * Read a message from the server
 
916
                 */
 
917
                rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
 
918
 
 
919
                memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
 
920
 
 
921
                if (rv == -1)
 
922
                {
 
923
                        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
924
                        return SCARD_F_COMM_ERROR;
 
925
                }
 
926
        } while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
883
927
 
884
928
        *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
885
929
 
886
930
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
887
931
 
888
 
        PROFILE_END
 
932
        PROFILE_END(scReconnectStruct.rv)
889
933
 
890
934
        return scReconnectStruct.rv;
891
935
}
981
1025
 
982
1026
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
983
1027
 
984
 
        PROFILE_END
 
1028
        PROFILE_END(scDisconnectStruct.rv)
985
1029
 
986
1030
        return scDisconnectStruct.rv;
987
1031
}
1097
1141
 
1098
1142
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1099
1143
 
1100
 
        PROFILE_END
 
1144
        PROFILE_END(scBeginStruct.rv);
1101
1145
 
1102
1146
        return scBeginStruct.rv;
1103
1147
}
1225
1269
 
1226
1270
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1227
1271
 
1228
 
        PROFILE_END
 
1272
        PROFILE_END(scEndStruct.rv)
1229
1273
 
1230
1274
        return scEndStruct.rv;
1231
1275
}
1300
1344
 
1301
1345
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1302
1346
 
1303
 
        PROFILE_END
 
1347
        PROFILE_END(scCancelStruct.rv)
1304
1348
 
1305
1349
        return scCancelStruct.rv;
1306
1350
}
1500
1544
 
1501
1545
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1502
1546
 
1503
 
        PROFILE_END
 
1547
        PROFILE_END(rv)
1504
1548
 
1505
1549
        return rv;
1506
1550
}
1646
1690
                                         */
1647
1691
                                        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1648
1692
 
1649
 
                                        PROFILE_END
 
1693
                                        PROFILE_END(SCARD_S_SUCCESS)
1650
1694
 
1651
1695
                                        return SCARD_S_SUCCESS;
1652
1696
                                }
1671
1715
                                {
1672
1716
                                        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1673
1717
 
1674
 
                                        PROFILE_END
 
1718
                                        PROFILE_END(SCARD_E_TIMEOUT)
1675
1719
 
1676
1720
                                        return SCARD_E_TIMEOUT;
1677
1721
                                }
1735
1779
 
1736
1780
                if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
1737
1781
                {
1738
 
                        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
1782
                        if (psContextMap[dwContextIndex].mMutex)
 
1783
                                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
1739
1784
 
1740
 
                        PROFILE_END
 
1785
                        PROFILE_END(SCARD_E_NO_SERVICE)
1741
1786
 
1742
1787
                        return SCARD_E_NO_SERVICE;
1743
1788
                }
1821
1866
                                 * Now we check all the Reader States
1822
1867
                                 */
1823
1868
                                dwState = rContext->readerState;
 
1869
                                {
 
1870
                                        int currentCounter, stateCounter;
 
1871
 
 
1872
                                        stateCounter = (dwState >> 16) & 0xFFFF;
 
1873
                                        currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;
 
1874
 
 
1875
                                        /* has the event counter changed since the last call? */
 
1876
                                        if (stateCounter != currentCounter)
 
1877
                                                currReader->dwEventState |= SCARD_STATE_CHANGED;
 
1878
 
 
1879
                                        /* add an event counter in the upper word of dwEventState */
 
1880
                                        currReader->dwEventState =
 
1881
                                                ((currReader->dwEventState & 0xffff )
 
1882
                                                | (stateCounter << 16));  
 
1883
                                }
1824
1884
 
1825
1885
        /*********** Check if the reader is in the correct state ********/
1826
1886
                                if (dwState & SCARD_UNKNOWN)
1889
1949
                                        /*
1890
1950
                                         * After present the rest are assumed
1891
1951
                                         */
1892
 
                                        if (currReader->dwCurrentState & SCARD_STATE_PRESENT
1893
 
                                                || currReader->dwCurrentState & SCARD_STATE_ATRMATCH
1894
 
                                                || currReader->dwCurrentState & SCARD_STATE_EXCLUSIVE
1895
 
                                                || currReader->dwCurrentState & SCARD_STATE_INUSE)
 
1952
                                        if (currReader->dwCurrentState & SCARD_STATE_PRESENT)
1896
1953
                                        {
1897
1954
                                                currReader->dwEventState |= SCARD_STATE_CHANGED;
1898
1955
                                                dwBreakFlag = 1;
2052
2109
                        if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
2053
2110
                        {
2054
2111
                                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
2112
                                PROFILE_END(SCARD_E_TIMEOUT)
2055
2113
                                return SCARD_E_TIMEOUT;
2056
2114
                        }
2057
2115
                }
2073
2131
                        BLOCK_STATUS_RESUME)
2074
2132
        {
2075
2133
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
2134
                PROFILE_END(SCARD_E_CANCELLED)
2076
2135
                return SCARD_E_CANCELLED;
2077
2136
        }
2078
2137
 
2079
2138
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
2080
2139
 
2081
 
        PROFILE_END
 
2140
        PROFILE_END(SCARD_S_SUCCESS)
2082
2141
 
2083
2142
        return SCARD_S_SUCCESS;
2084
2143
}
2298
2357
 
2299
2358
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
2300
2359
 
2301
 
        PROFILE_END
 
2360
        PROFILE_END(rv)
2302
2361
 
2303
2362
        return rv;
2304
2363
}
2386
2445
LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
2387
2446
        LPDWORD pcbAttrLen)
2388
2447
{
 
2448
        LONG ret;
 
2449
 
2389
2450
        PROFILE_START
2390
2451
 
2391
2452
        if (NULL == pcbAttrLen)
2396
2457
                /* this variable may not be set by the caller. use a reasonable size */
2397
2458
                *pcbAttrLen = MAX_BUFFER_SIZE;
2398
2459
 
2399
 
        PROFILE_END
2400
 
 
2401
 
        return SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
 
2460
        ret = SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
2402
2461
                pcbAttrLen);
 
2462
 
 
2463
        PROFILE_END(ret)
 
2464
 
 
2465
        return ret;
2403
2466
}
2404
2467
 
2405
2468
/**
2435
2498
LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
2436
2499
        DWORD cbAttrLen)
2437
2500
{
 
2501
        LONG ret;
 
2502
 
2438
2503
        PROFILE_START
2439
2504
 
2440
2505
        if (NULL == pbAttr || 0 == cbAttrLen)
2441
2506
                return SCARD_E_INVALID_PARAMETER;
2442
2507
 
2443
 
        PROFILE_END
2444
 
 
2445
 
        return SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
 
2508
        ret = SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
2446
2509
                &cbAttrLen);
 
2510
 
 
2511
        PROFILE_END(ret)
 
2512
 
 
2513
        return ret;
2447
2514
}
2448
2515
 
2449
2516
static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
2450
2517
        LPBYTE pbAttr, LPDWORD pcbAttrLen)
2451
2518
{
2452
 
        PROFILE_START
2453
 
 
2454
2519
        LONG rv;
2455
2520
        getset_struct scGetSetStruct;
2456
2521
        sharedSegmentMsg msgStruct;
2542
2607
 
2543
2608
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
2544
2609
 
2545
 
        PROFILE_END
2546
 
 
2547
2610
        return scGetSetStruct.rv;
2548
2611
}
2549
2612
 
2805
2868
                rv = scTransmitStruct.rv;
2806
2869
        }
2807
2870
 
2808
 
        PROFILE_END
 
2871
        PROFILE_END(rv)
2809
2872
 
2810
2873
        return rv;
2811
2874
}
2879
2942
        {
2880
2943
                *pcchReaders = dwReadersLen;
2881
2944
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
2945
                PROFILE_END(SCARD_S_SUCCESS)
2882
2946
                return SCARD_S_SUCCESS;
2883
2947
        }
2884
2948
 
2886
2950
        {
2887
2951
                *pcchReaders = dwReadersLen;
2888
2952
                SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
2953
                PROFILE_END(SCARD_E_INSUFFICIENT_BUFFER)
2889
2954
                return SCARD_E_INSUFFICIENT_BUFFER;
2890
2955
        }
2891
2956
 
2907
2972
 
2908
2973
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
2909
2974
 
2910
 
        PROFILE_END
 
2975
        PROFILE_END(SCARD_S_SUCCESS)
2911
2976
 
2912
2977
        return SCARD_S_SUCCESS;
2913
2978
}
2982
3047
 
2983
3048
        SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
2984
3049
 
2985
 
        PROFILE_END
 
3050
        PROFILE_END(rv)
2986
3051
 
2987
3052
        return rv;
2988
3053
}
3031
3096
         */
3032
3097
        psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
3033
3098
 
3034
 
        PROFILE_END
 
3099
        PROFILE_END(SCARD_S_SUCCESS)
3035
3100
 
3036
3101
        return SCARD_S_SUCCESS;
3037
3102
}
3068
3133
 
3069
3134
        rv = SCARD_S_SUCCESS;
3070
3135
 
 
3136
        /* Check if the _same_ server is running */
 
3137
        if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
 
3138
                return SCARD_E_INVALID_HANDLE;
 
3139
 
3071
3140
        /*
3072
3141
         * Make sure this context has been opened
3073
3142
         */
3075
3144
        if (dwContextIndex == -1)
3076
3145
                rv = SCARD_E_INVALID_HANDLE;
3077
3146
 
3078
 
        PROFILE_END
 
3147
        PROFILE_END(rv)
3079
3148
 
3080
3149
        return rv;
3081
3150
}
3185
3254
        if (retIndice == -1)
3186
3255
                return SCARD_E_INVALID_HANDLE;
3187
3256
        else
 
3257
                return SCardCleanContext(retIndice);
 
3258
}
 
3259
 
 
3260
static LONG SCardCleanContext(LONG indice)
 
3261
{
 
3262
        int i;
 
3263
 
 
3264
        psContextMap[indice].hContext = 0;
 
3265
        SHMClientCloseSession(psContextMap[indice].dwClientID);
 
3266
        psContextMap[indice].dwClientID = 0;
 
3267
        free(psContextMap[indice].mMutex);
 
3268
        psContextMap[indice].mMutex = NULL;
 
3269
        psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;
 
3270
 
 
3271
        for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
3188
3272
        {
3189
 
                int i;
3190
 
 
3191
 
                psContextMap[retIndice].hContext = 0;
3192
 
                SHMClientCloseSession(psContextMap[retIndice].dwClientID);
3193
 
                psContextMap[retIndice].dwClientID = 0;
3194
 
                free(psContextMap[retIndice].mMutex);
3195
 
                psContextMap[retIndice].mMutex = NULL;
3196
 
                psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
3197
 
 
3198
 
                for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
3199
 
                {
3200
 
                        /*
3201
 
                         * Reset the \c hCard structs to zero
3202
 
                         */
3203
 
                        psContextMap[retIndice].psChannelMap[i].hCard = 0;
3204
 
                        free(psContextMap[retIndice].psChannelMap[i].readerName);
3205
 
                        psContextMap[retIndice].psChannelMap[i].readerName = NULL;
3206
 
                }
3207
 
 
3208
 
                return SCARD_S_SUCCESS;
 
3273
                /*
 
3274
                 * Reset the \c hCard structs to zero
 
3275
                 */
 
3276
                psContextMap[indice].psChannelMap[i].hCard = 0;
 
3277
                free(psContextMap[indice].psChannelMap[i].readerName);
 
3278
                psContextMap[indice].psChannelMap[i].readerName = NULL;
3209
3279
        }
 
3280
 
 
3281
        return SCARD_S_SUCCESS;
3210
3282
}
3211
3283
 
3212
3284
/*
3317
3389
 * @retval SCARD_S_SUCCESS Server is running (\ref SCARD_S_SUCCESS)
3318
3390
 * @retval SCARD_E_NO_SERVICE Server is not running (\ref SCARD_E_NO_SERVICE)
3319
3391
 */
3320
 
static LONG SCardCheckDaemonAvailability(void)
 
3392
LONG SCardCheckDaemonAvailability(void)
3321
3393
{
3322
3394
        LONG rv;
3323
3395
        struct stat statBuffer;
3330
3402
                return SCARD_E_NO_SERVICE;
3331
3403
        }
3332
3404
 
 
3405
        if (daemon_ctime)
 
3406
        {
 
3407
                /* when the _first_ reader is connected the ctime changes
 
3408
                 * I don't know why yet */
 
3409
                if (statBuffer.st_ctime > daemon_ctime)
 
3410
                {
 
3411
                        pid_t new_pid;
 
3412
 
 
3413
                        new_pid = GetDaemonPid();
 
3414
 
 
3415
                        /* so we also check the daemon pid to be sure it is a new pcscd */
 
3416
                        if (new_pid != daemon_pid)
 
3417
                        {
 
3418
                                int i;
 
3419
 
 
3420
                                Log1(PCSC_LOG_ERROR, "PCSC restarted");
 
3421
 
 
3422
                                /* invalid all handles */
 
3423
                                SCardLockThread();
 
3424
 
 
3425
                                for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
 
3426
                                        if (psContextMap[i].hContext)
 
3427
                                                SCardCleanContext(i);
 
3428
 
 
3429
                                SCardUnlockThread();
 
3430
 
 
3431
                                /* reset pcscd status */
 
3432
                                daemon_ctime = 0;
 
3433
 
 
3434
                                /* reset the lib */
 
3435
                                SCardUnload();
 
3436
 
 
3437
                                return SCARD_E_NO_SERVICE;
 
3438
                        }
 
3439
 
 
3440
                        daemon_ctime = statBuffer.st_ctime;
 
3441
                }
 
3442
        }
 
3443
        else
 
3444
        {
 
3445
                daemon_ctime = statBuffer.st_ctime;
 
3446
                daemon_pid = GetDaemonPid();
 
3447
        }
 
3448
 
3333
3449
        return SCARD_S_SUCCESS;
3334
3450
}
3335
3451