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

« back to all changes in this revision

Viewing changes to src/eventhandler.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2004-06-13 21:45:56 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040613214556-zio7hrzkz9wwtffx
Tags: 1.2.9-beta2-2
* debian/rules: add -lpthread to LDFLAGS so that pthread_* symbols are
  included in the library (problem only seen on mips and mipsel).
  Closes: #253629
* debian/control: make libpcsclite-dev and libpcsclite1 at Priority:
  optional so that other packages at Priority: optional can use them.
  Closes: #249374

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************************
2
 
 
3
 
        MUSCLE SmartCard Development ( http://www.linuxnet.com )
4
 
            Title  : eventhandler.c
5
 
            Package: pcsc lite
6
 
            Author : David Corcoran
7
 
            Date   : 3/13/00
8
 
            License: Copyright (C) 2000 David Corcoran
9
 
                     <corcoran@linuxnet.com>
10
 
            Purpose: This keeps track of card insertion/removal events
11
 
            and updates ATR, protocol, and status information.
12
 
 
13
 
********************************************************************/
14
 
 
 
1
/*
 
2
 * This keeps track of card insertion/removal events
 
3
 * and updates ATR, protocol, and status information.
 
4
 *
 
5
 * MUSCLE SmartCard Development ( http://www.linuxnet.com )
 
6
 *
 
7
 * Copyright (C) 2000
 
8
 *  David Corcoran <corcoran@linuxnet.com>
 
9
 * Copyright (C) 2004
 
10
 *  Ludovic Rousseau <ludovic.rousseau@free.fr>
 
11
 *
 
12
 * $Id: eventhandler.c,v 1.15 2004/04/21 21:42:33 rousseau Exp $
 
13
 */
 
14
 
 
15
#include "config.h"
15
16
#include <sys/types.h>
16
17
#include <sys/stat.h>
17
 
#include <sys/errno.h>
 
18
#include <errno.h>
18
19
#include <fcntl.h>
 
20
#include <string.h>
 
21
#include <stdlib.h>
19
22
 
20
 
#include "config.h"
21
23
#include "wintypes.h"
22
24
#include "pcsclite.h"
23
25
#include "thread_generic.h"
25
27
#include "eventhandler.h"
26
28
#include "dyn_generic.h"
27
29
#include "sys_generic.h"
28
 
#include "ifdhandler.h" 
 
30
#include "ifdhandler.h"
29
31
#include "ifdwrapper.h"
30
32
#include "debuglog.h"
31
33
#include "prothandler.h"
32
34
 
33
 
static PREADER_STATES readerStates[PCSCLITE_MAX_CONTEXTS];
34
 
 
35
 
void EHStatusHandlerThread( PREADER_CONTEXT );
36
 
 
37
 
 
38
 
LONG EHInitializeEventStructures( ) {
39
 
 
40
 
  int fd, i, pageSize;
41
 
 
42
 
  fd=0; i=0; pageSize=0;
43
 
 
44
 
  SYS_RemoveFile( PCSCLITE_PUBSHM_FILE );
45
 
 
46
 
  fd = SYS_OpenFile( PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, 00644 );
47
 
  if ( fd < 0 ) {
48
 
    DebugLogA("Error: Cannot open public shared file");
49
 
    exit(1);
50
 
  }
51
 
 
52
 
  SYS_Chmod( PCSCLITE_PUBSHM_FILE, S_IRGRP | S_IREAD | S_IWRITE | S_IROTH );
53
 
 
54
 
   pageSize = SYS_GetPageSize();
55
 
 
56
 
  /* Jump to end of file space and allocate zero's */
57
 
  SYS_SeekFile( fd, pageSize * PCSCLITE_MAX_CONTEXTS );    
58
 
  SYS_WriteFile( fd, "", 1 );
59
 
 
60
 
  /* Allocate each reader structure */
61
 
  for ( i=0; i < PCSCLITE_MAX_CONTEXTS; i++ ) {
62
 
    readerStates[i] = (PREADER_STATES)
63
 
      SYS_MemoryMap( sizeof(READER_STATES), 
64
 
                     fd, (i*pageSize) );    
65
 
    if ( readerStates[i] == 0 ) {
66
 
      DebugLogA("Error: Cannot public memory map");
67
 
      exit(1);     
68
 
    }
69
 
 
70
 
    /* Zero out each value in the struct */
71
 
    memset((readerStates[i])->readerName, 0, MAX_READERNAME);
72
 
    memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
73
 
    (readerStates[i])->readerID      = 0;
74
 
    (readerStates[i])->readerState   = 0;
75
 
    (readerStates[i])->lockState     = 0;
76
 
    (readerStates[i])->readerSharing = 0;
77
 
    (readerStates[i])->cardAtrLength = 0;
78
 
    (readerStates[i])->cardProtocol  = 0;
79
 
  }
80
 
 
81
 
  return SCARD_S_SUCCESS;
82
 
}
83
 
 
84
 
LONG EHDestroyEventHandler( PREADER_CONTEXT rContext ) {
85
 
 
86
 
  LONG rv;
87
 
  int i;
88
 
 
89
 
  i=0; rv=0;
90
 
 
91
 
  /* Set the thread to 0 to exit thread */
92
 
  rContext->dwLockId = 0xFFFF;
93
 
 
94
 
  DebugLogA("EHDestroyEventHandler: Stomping thread.");
95
 
 
96
 
  do {
97
 
    /* Wait 0.05 seconds for the child to respond */
98
 
    SYS_USleep(50000);
99
 
  } while ( rContext->dwLockId == 0xFFFF );
100
 
 
101
 
 
102
 
  /* Zero out the public status struct to allow 
103
 
     it to be recycled and used again
104
 
  */
105
 
 
106
 
  i = rContext->dwPublicID;
107
 
  memset((readerStates[i])->readerName, 0, MAX_READERNAME);
108
 
  memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
109
 
  (readerStates[i])->readerID      = 0;
110
 
  (readerStates[i])->readerState   = 0;
111
 
  (readerStates[i])->lockState     = 0;
112
 
  (readerStates[i])->readerSharing = 0;
113
 
  (readerStates[i])->cardAtrLength = 0;
114
 
  (readerStates[i])->cardProtocol  = 0;
115
 
 
116
 
  DebugLogA("EHDestroyEventHandler: Thread stomped.");
117
 
 
118
 
  return SCARD_S_SUCCESS;
119
 
}
120
 
 
121
 
LONG EHSpawnEventHandler( PREADER_CONTEXT rContext ) {
122
 
 
123
 
  LONG rv;
124
 
  LPCSTR lpcReader;
125
 
  DWORD dwStatus, dwProtocol;
126
 
  int i;  
127
 
 
128
 
  /* Zero out everything */
129
 
  rv=0; lpcReader=0; dwStatus=0; dwProtocol=0; i=0;
130
 
 
131
 
  lpcReader = rContext->lpcReader;
132
 
  
133
 
  rv = IFDStatusICC( rContext, &dwStatus,
134
 
                     &dwProtocol, rContext->ucAtr, 
135
 
                     &rContext->dwAtrLen );    
136
 
 
137
 
  if ( rv != SCARD_S_SUCCESS ) {
138
 
    DebugLogB("EHSpawnEventHandler: Initial Check Failed on %s", lpcReader);
139
 
    return SCARD_F_UNKNOWN_ERROR;
140
 
  }
141
 
 
142
 
  /* Find an empty reader slot and insert the new reader */
143
 
  for (i=0; i < PCSCLITE_MAX_CONTEXTS; i++) {
144
 
    if ( (readerStates[i])->readerID == 0 ) {
145
 
      break;
146
 
    }
147
 
  }
148
 
 
149
 
  if ( i == PCSCLITE_MAX_CONTEXTS ) {
150
 
    return SCARD_F_INTERNAL_ERROR;
151
 
  }
152
 
 
153
 
 
154
 
  /* Set all the attributes to this reader */
155
 
  strcpy((readerStates[i])->readerName, rContext->lpcReader);
156
 
  memcpy((readerStates[i])->cardAtr, rContext->ucAtr, rContext->dwAtrLen);
157
 
  (readerStates[i])->readerID      = i+100;
158
 
  (readerStates[i])->readerState   = rContext->dwStatus;
159
 
  (readerStates[i])->readerSharing = rContext->dwContexts;
160
 
  (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
161
 
  (readerStates[i])->cardProtocol  = rContext->dwProtocol;
162
 
  /* So the thread can access this array indice */
163
 
  rContext->dwPublicID             = i;
164
 
 
165
 
  rv = SYS_ThreadCreate( &rContext->pthThread, NULL, 
166
 
                         (LPVOID)EHStatusHandlerThread,
167
 
                         (LPVOID)rContext );
168
 
  if ( rv == 1 ) {
169
 
    return SCARD_S_SUCCESS;
170
 
  } else {
171
 
    return SCARD_E_NO_MEMORY;
172
 
  }
173
 
 
174
 
}
175
 
 
176
 
 
177
 
void EHStatusHandlerThread( PREADER_CONTEXT rContext ) {
178
 
 
179
 
  LONG rv;
180
 
  LPCSTR lpcReader;
181
 
  DWORD dwStatus, dwProtocol, dwReaderSharing;
182
 
  DWORD dwErrorCount, dwCurrentState;
183
 
  int i, pageSize;
184
 
 
185
 
  /* Zero out everything */
186
 
  rv=0; lpcReader=0; dwStatus=0; dwProtocol=0; dwReaderSharing=0;
187
 
  dwCurrentState=0; dwErrorCount=0; i=0; pageSize=0;
188
 
 
189
 
  lpcReader = rContext->lpcReader;
190
 
  i         = rContext->dwPublicID;
191
 
 
192
 
  pageSize = SYS_GetPageSize();
193
 
 
194
 
  rv = IFDStatusICC( rContext, &dwStatus,
195
 
                     &dwProtocol, rContext->ucAtr, 
196
 
                     &rContext->dwAtrLen );    
197
 
  
198
 
  if ( dwStatus & SCARD_PRESENT ) {
199
 
 
200
 
    rv = IFDPowerICC( rContext, IFD_POWER_UP, 
201
 
                      rContext->ucAtr, 
202
 
                      &rContext->dwAtrLen );
203
 
 
204
 
    if ( rv == IFD_SUCCESS ) {
205
 
      rContext->dwProtocol  = PHGetDefaultProtocol( rContext->ucAtr, 
206
 
                                                    rContext->dwAtrLen );
207
 
      rContext->dwStatus   |= SCARD_PRESENT;
208
 
      rContext->dwStatus   &= ~SCARD_ABSENT;
209
 
      rContext->dwStatus   |= SCARD_POWERED;
210
 
      rContext->dwStatus   |= SCARD_NEGOTIABLE;
211
 
      rContext->dwStatus   &= ~SCARD_SPECIFIC;
212
 
      rContext->dwStatus   &= ~SCARD_SWALLOWED;
213
 
      rContext->dwStatus   &= ~SCARD_UNKNOWN;
214
 
    } else {
215
 
      rContext->dwStatus   |= SCARD_PRESENT;
216
 
      rContext->dwStatus   &= ~SCARD_ABSENT;
217
 
      rContext->dwStatus   |= SCARD_SWALLOWED;
218
 
      rContext->dwStatus   &= ~SCARD_POWERED;
219
 
      rContext->dwStatus   &= ~SCARD_NEGOTIABLE;
220
 
      rContext->dwStatus   &= ~SCARD_SPECIFIC;
221
 
      rContext->dwStatus   &= ~SCARD_UNKNOWN;
222
 
      rContext->dwProtocol  = 0;
223
 
      rContext->dwAtrLen    = 0;
224
 
    }
225
 
   
226
 
    dwCurrentState        = SCARD_PRESENT;
227
 
 
228
 
  } else {
229
 
    dwCurrentState        = SCARD_ABSENT;
230
 
    rContext->dwStatus   |= SCARD_ABSENT;
231
 
    rContext->dwStatus   &= ~SCARD_PRESENT;
232
 
    rContext->dwStatus   &= ~SCARD_POWERED;
233
 
    rContext->dwStatus   &= ~SCARD_NEGOTIABLE;
234
 
    rContext->dwStatus   &= ~SCARD_SPECIFIC;
235
 
    rContext->dwStatus   &= ~SCARD_SWALLOWED;
236
 
    rContext->dwStatus   &= ~SCARD_UNKNOWN;
237
 
    rContext->dwAtrLen    = 0;
238
 
    rContext->dwProtocol  = 0;
239
 
  }
240
 
 
241
 
  /* Set all the public attributes to this reader */
242
 
  (readerStates[i])->readerState   = rContext->dwStatus;
243
 
  (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
244
 
  (readerStates[i])->cardProtocol  = rContext->dwProtocol;
245
 
  (readerStates[i])->readerSharing = dwReaderSharing = rContext->dwContexts;
246
 
  memcpy((readerStates[i])->cardAtr, rContext->ucAtr, 
247
 
         rContext->dwAtrLen);
248
 
 
249
 
  SYS_MMapSynchronize( (void *)readerStates[i], pageSize );
250
 
 
251
 
  while(1) {      
252
 
 
253
 
    dwStatus   = 0;
254
 
    
255
 
    rv = IFDStatusICC( rContext, &dwStatus,
256
 
                       &dwProtocol, rContext->ucAtr, 
257
 
                       &rContext->dwAtrLen );
258
 
    
259
 
    if ( rv != SCARD_S_SUCCESS ) {
260
 
      DebugLogB("EHSpawnEventHandler: Error communicating to: %s", lpcReader);
261
 
 
262
 
      /* Set error status on this reader while errors occur */
263
 
 
264
 
      rContext->dwStatus   &= ~SCARD_ABSENT;
265
 
      rContext->dwStatus   &= ~SCARD_PRESENT;
266
 
      rContext->dwStatus   &= ~SCARD_POWERED;
267
 
      rContext->dwStatus   &= ~SCARD_NEGOTIABLE;
268
 
      rContext->dwStatus   &= ~SCARD_SPECIFIC;
269
 
      rContext->dwStatus   &= ~SCARD_SWALLOWED;
270
 
      rContext->dwStatus   |= SCARD_UNKNOWN;
271
 
      rContext->dwAtrLen    = 0;
272
 
      rContext->dwProtocol  = 0;
273
 
      
274
 
      dwCurrentState = SCARD_UNKNOWN; 
275
 
 
276
 
      /* Set all the public attributes to this reader */
277
 
      (readerStates[i])->readerState   = rContext->dwStatus;
278
 
      (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
279
 
      (readerStates[i])->cardProtocol  = rContext->dwProtocol;
280
 
      memcpy((readerStates[i])->cardAtr, rContext->ucAtr, 
281
 
             rContext->dwAtrLen);
282
 
 
283
 
      SYS_MMapSynchronize( (void *)readerStates[i], pageSize );
284
 
      
285
 
      /* This code causes race conditions on 
286
 
         G4's with USB insertion */
287
 
/*
288
 
      dwErrorCount += 1;
289
 
      SYS_Sleep(1);
290
 
*/
291
 
      /* After 10 seconds of errors, try to reinitialize the reader
292
 
         This sometimes helps bring readers out of *crazy* states.
293
 
      */
294
 
/*
295
 
      if ( dwErrorCount == 10 ) {
296
 
        RFUnInitializeReader( rContext );
297
 
        RFInitializeReader( rContext );
 
35
static PREADER_STATES readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
 
36
 
 
37
void EHStatusHandlerThread(PREADER_CONTEXT);
 
38
 
 
39
LONG EHInitializeEventStructures()
 
40
{
 
41
        int fd, i, pageSize;
 
42
 
 
43
        fd = 0;
 
44
        i = 0;
 
45
        pageSize = 0;
 
46
 
 
47
        SYS_RemoveFile(PCSCLITE_PUBSHM_FILE);
 
48
 
 
49
        fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, 00644);
 
50
        if (fd < 0)
 
51
        {
 
52
                DebugLogC("Cannot create public shared file %s: %s",
 
53
                        PCSCLITE_PUBSHM_FILE, strerror(errno));
 
54
                exit(1);
 
55
        }
 
56
 
 
57
        SYS_Chmod(PCSCLITE_PUBSHM_FILE,
 
58
                S_IRGRP | S_IREAD | S_IWRITE | S_IROTH);
 
59
 
 
60
        pageSize = SYS_GetPageSize();
 
61
 
 
62
        /*
 
63
         * Jump to end of file space and allocate zero's 
 
64
         */
 
65
        SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS);
 
66
        SYS_WriteFile(fd, "", 1);
 
67
 
 
68
        /*
 
69
         * Allocate each reader structure 
 
70
         */
 
71
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
72
        {
 
73
                readerStates[i] = (PREADER_STATES)
 
74
                        SYS_MemoryMap(sizeof(READER_STATES), fd, (i * pageSize));
 
75
                if (readerStates[i] == 0)
 
76
                {
 
77
                        DebugLogC("Cannot memory map public shared file %s: %s",
 
78
                                PCSCLITE_PUBSHM_FILE, strerror(errno));
 
79
                        exit(1);
 
80
                }
 
81
 
 
82
                /*
 
83
                 * Zero out each value in the struct 
 
84
                 */
 
85
                memset((readerStates[i])->readerName, 0, MAX_READERNAME);
 
86
                memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
 
87
                (readerStates[i])->readerID = 0;
 
88
                (readerStates[i])->readerState = 0;
 
89
                (readerStates[i])->lockState = 0;
 
90
                (readerStates[i])->readerSharing = 0;
 
91
                (readerStates[i])->cardAtrLength = 0;
 
92
                (readerStates[i])->cardProtocol = 0;
 
93
        }
 
94
 
 
95
        return SCARD_S_SUCCESS;
 
96
}
 
97
 
 
98
LONG EHDestroyEventHandler(PREADER_CONTEXT rContext)
 
99
{
 
100
        LONG rv;
 
101
        int i;
 
102
 
 
103
        i = 0;
 
104
        rv = 0;
 
105
 
 
106
 
 
107
        i = rContext->dwPublicID;
 
108
        if ((readerStates[i])->readerName[0] == 0)
 
109
        {
 
110
                DebugLogA("Thread already stomped.");
 
111
                return SCARD_S_SUCCESS;
 
112
        }
 
113
 
 
114
        /*
 
115
         * Set the thread to 0 to exit thread 
 
116
         */
 
117
        rContext->dwLockId = 0xFFFF;
 
118
 
 
119
        DebugLogA("Stomping thread.");
 
120
 
 
121
        do
 
122
        {
 
123
                /*
 
124
                 * Wait 0.05 seconds for the child to respond 
 
125
                 */
 
126
                SYS_USleep(50000);
 
127
        }
 
128
        while (rContext->dwLockId == 0xFFFF);
 
129
        /*
 
130
         * Zero out the public status struct to allow it to be recycled and
 
131
         * used again 
 
132
         */
 
133
 
 
134
        memset((readerStates[i])->readerName, 0, MAX_READERNAME);
 
135
        memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
 
136
        (readerStates[i])->readerID = 0;
 
137
        (readerStates[i])->readerState = 0;
 
138
        (readerStates[i])->lockState = 0;
 
139
        (readerStates[i])->readerSharing = 0;
 
140
        (readerStates[i])->cardAtrLength = 0;
 
141
        (readerStates[i])->cardProtocol = 0;
 
142
 
 
143
        /* Zero the thread */
 
144
        rContext->pthThread = 0;
 
145
 
 
146
        DebugLogA("Thread stomped.");
 
147
 
 
148
        return SCARD_S_SUCCESS;
 
149
}
 
150
 
 
151
LONG EHSpawnEventHandler(PREADER_CONTEXT rContext)
 
152
{
 
153
        LONG rv;
 
154
        LPCSTR lpcReader;
 
155
        DWORD dwStatus, dwProtocol;
 
156
        int i;
 
157
 
 
158
        /*
 
159
         * Zero out everything 
 
160
         */
 
161
        rv = 0;
 
162
        lpcReader = 0;
 
163
        dwStatus = 0;
 
164
        dwProtocol = 0;
 
165
        i = 0;
 
166
 
 
167
        lpcReader = rContext->lpcReader;
 
168
 
 
169
        rv = IFDStatusICC(rContext, &dwStatus,
 
170
                &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
 
171
 
 
172
        if (rv != SCARD_S_SUCCESS)
 
173
        {
 
174
                DebugLogB("Initial Check Failed on %s", lpcReader);
 
175
                return SCARD_F_UNKNOWN_ERROR;
 
176
        }
 
177
 
 
178
        /*
 
179
         * Find an empty reader slot and insert the new reader 
 
180
         */
 
181
        for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
 
182
        {
 
183
                if ((readerStates[i])->readerID == 0)
 
184
                        break;
 
185
        }
 
186
 
 
187
        if (i == PCSCLITE_MAX_READERS_CONTEXTS)
 
188
                return SCARD_F_INTERNAL_ERROR;
 
189
 
 
190
        /*
 
191
         * Set all the attributes to this reader 
 
192
         */
 
193
        strcpy((readerStates[i])->readerName, rContext->lpcReader);
 
194
        memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
 
195
                rContext->dwAtrLen);
 
196
        (readerStates[i])->readerID = i + 100;
 
197
        (readerStates[i])->readerState = rContext->dwStatus;
 
198
        (readerStates[i])->readerSharing = rContext->dwContexts;
 
199
        (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
 
200
        (readerStates[i])->cardProtocol = rContext->dwProtocol;
 
201
        /*
 
202
         * So the thread can access this array indice 
 
203
         */
 
204
        rContext->dwPublicID = i;
 
205
 
 
206
        rv = SYS_ThreadCreate(&rContext->pthThread, NULL,
 
207
                (LPVOID) EHStatusHandlerThread, (LPVOID) rContext);
 
208
        if (rv == 1)
 
209
                return SCARD_S_SUCCESS;
 
210
        else
 
211
                return SCARD_E_NO_MEMORY;
 
212
}
 
213
 
 
214
void EHStatusHandlerThread(PREADER_CONTEXT rContext)
 
215
{
 
216
        LONG rv;
 
217
        LPCSTR lpcReader;
 
218
        DWORD dwStatus, dwProtocol, dwReaderSharing;
 
219
        DWORD dwErrorCount, dwCurrentState;
 
220
        int i, pageSize;
 
221
 
 
222
        /*
 
223
         * Zero out everything 
 
224
         */
 
225
        rv = 0;
 
226
        lpcReader = 0;
 
227
        dwStatus = 0;
 
228
        dwProtocol = 0;
 
229
        dwReaderSharing = 0;
 
230
        dwCurrentState = 0;
298
231
        dwErrorCount = 0;
299
 
      }
300
 
*/
301
 
 
302
 
      /* End of race condition code block */
303
 
 
304
 
    }
305
 
 
306
 
 
307
 
    if ( dwStatus & SCARD_ABSENT ) {
308
 
      if ( dwCurrentState == SCARD_PRESENT ||
309
 
           dwCurrentState == SCARD_UNKNOWN ) {
310
 
        
311
 
        /* Change the status structure */
312
 
        DebugLogB("EHSpawnEventHandler: Card Removed From %s", lpcReader);
313
 
        /* Notify the card has been removed */
314
 
        RFSetReaderEventState( rContext, SCARD_REMOVED );
315
 
 
316
 
        rContext->dwAtrLen   = 0;
317
 
        rContext->dwProtocol = 0;
318
 
        rContext->dwStatus  |= SCARD_ABSENT;
319
 
        rContext->dwStatus  &= ~SCARD_UNKNOWN;
320
 
        rContext->dwStatus  &= ~SCARD_PRESENT;
321
 
        rContext->dwStatus  &= ~SCARD_POWERED;
322
 
        rContext->dwStatus  &= ~SCARD_NEGOTIABLE;
323
 
        rContext->dwStatus  &= ~SCARD_SWALLOWED;
324
 
        rContext->dwStatus  &= ~SCARD_SPECIFIC;
325
 
        dwCurrentState       = SCARD_ABSENT;
326
 
 
327
 
        /* Set all the public attributes to this reader */
328
 
        (readerStates[i])->readerState   = rContext->dwStatus;
329
 
        (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
330
 
        (readerStates[i])->cardProtocol  = rContext->dwProtocol;
331
 
        memcpy((readerStates[i])->cardAtr, rContext->ucAtr, 
332
 
               rContext->dwAtrLen);
333
 
 
334
 
        SYS_MMapSynchronize( (void *)readerStates[i], pageSize );
335
 
      }
336
 
      
337
 
    } else if ( dwStatus & SCARD_PRESENT ) {
338
 
      if ( dwCurrentState == SCARD_ABSENT || 
339
 
           dwCurrentState == SCARD_UNKNOWN ) {
340
 
 
341
 
        /* Power and reset the card */
342
 
        SYS_USleep( PCSCLITE_STATUS_WAIT );
343
 
        rv = IFDPowerICC( rContext, IFD_POWER_UP, 
344
 
                          rContext->ucAtr, 
345
 
                          &rContext->dwAtrLen );
346
 
 
347
 
        if ( rv == IFD_SUCCESS ) {
348
 
          rContext->dwProtocol  = PHGetDefaultProtocol( rContext->ucAtr, 
349
 
                                                        rContext->dwAtrLen );
350
 
          rContext->dwStatus   |= SCARD_PRESENT;
351
 
          rContext->dwStatus   &= ~SCARD_ABSENT;
352
 
          rContext->dwStatus   |= SCARD_POWERED;
353
 
          rContext->dwStatus   |= SCARD_NEGOTIABLE;
354
 
          rContext->dwStatus   &= ~SCARD_SPECIFIC;
355
 
          rContext->dwStatus   &= ~SCARD_UNKNOWN;
356
 
          rContext->dwStatus   &= ~SCARD_SWALLOWED;
357
 
 
358
 
 
359
 
          /* Notify the card has been reset */
360
 
          /*      RFSetReaderEventState( rContext, SCARD_RESET ); */
361
 
        } else {
362
 
          rContext->dwStatus   |= SCARD_PRESENT;
363
 
          rContext->dwStatus   &= ~SCARD_ABSENT;
364
 
          rContext->dwStatus   |= SCARD_SWALLOWED;
365
 
          rContext->dwStatus   &= ~SCARD_POWERED;
366
 
          rContext->dwStatus   &= ~SCARD_NEGOTIABLE;
367
 
          rContext->dwStatus   &= ~SCARD_SPECIFIC;
368
 
          rContext->dwStatus   &= ~SCARD_UNKNOWN;
369
 
          rContext->dwAtrLen   = 0;
370
 
          rContext->dwProtocol = 0;
371
 
        }
372
 
        
373
 
        dwCurrentState        = SCARD_PRESENT;
374
 
 
375
 
        /* Set all the public attributes to this reader */
376
 
        (readerStates[i])->readerState   = rContext->dwStatus;
377
 
        (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
378
 
        (readerStates[i])->cardProtocol  = rContext->dwProtocol;
379
 
        memcpy((readerStates[i])->cardAtr, rContext->ucAtr, 
380
 
               rContext->dwAtrLen);
381
 
 
382
 
        SYS_MMapSynchronize( (void *)readerStates[i], pageSize );
383
 
 
384
 
 
385
 
        DebugLogB("EHSpawnEventHandler: Card inserted into %s", lpcReader);
386
 
 
387
 
        if ( rv == IFD_SUCCESS ) {
388
 
          if ( rContext->dwAtrLen > 0 ) {
389
 
            DebugXxd("EHSpawnEventHandler: Card ATR: ",
390
 
                                rContext->ucAtr, rContext->dwAtrLen);
391
 
          } else {
392
 
            DebugLogA("EHSpawnEventHandler: Card ATR: (NULL)");
393
 
          }
394
 
            
395
 
        } else {
396
 
          DebugLogA("EHSpawnEventHandler: Error powering up card.");
397
 
        }         
398
 
      }
399
 
    }     
400
 
    
401
 
    if ( rContext->dwLockId == 0xFFFF) {
402
 
      /* Exit and notify the caller */
403
 
      rContext->dwLockId = 0; 
404
 
      SYS_ThreadDetach( rContext->pthThread );
405
 
      SYS_ThreadExit(0);
406
 
    }
407
 
 
408
 
    /* Sharing may change w/o an event pass it on */
409
 
 
410
 
    if ( dwReaderSharing != rContext->dwContexts ) {
411
 
      dwReaderSharing = rContext->dwContexts;
412
 
      (readerStates[i])->readerSharing = dwReaderSharing;
413
 
      SYS_MMapSynchronize( (void *)readerStates[i], pageSize );
414
 
    }
415
 
 
416
 
    SYS_USleep( PCSCLITE_STATUS_POLL_RATE );
417
 
  }
 
232
        i = 0;
 
233
        pageSize = 0;
 
234
 
 
235
        lpcReader = rContext->lpcReader;
 
236
        i = rContext->dwPublicID;
 
237
 
 
238
        pageSize = SYS_GetPageSize();
 
239
 
 
240
        rv = IFDStatusICC(rContext, &dwStatus,
 
241
                &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
 
242
 
 
243
        if (dwStatus & SCARD_PRESENT)
 
244
        {
 
245
                rv = IFDPowerICC(rContext, IFD_POWER_UP,
 
246
                        rContext->ucAtr, &rContext->dwAtrLen);
 
247
 
 
248
                if (rv == IFD_SUCCESS)
 
249
                {
 
250
                        rContext->dwProtocol = PHGetDefaultProtocol(rContext->ucAtr,
 
251
                                rContext->dwAtrLen);
 
252
                        rContext->dwStatus |= SCARD_PRESENT;
 
253
                        rContext->dwStatus &= ~SCARD_ABSENT;
 
254
                        rContext->dwStatus |= SCARD_POWERED;
 
255
                        rContext->dwStatus |= SCARD_NEGOTIABLE;
 
256
                        rContext->dwStatus &= ~SCARD_SPECIFIC;
 
257
                        rContext->dwStatus &= ~SCARD_SWALLOWED;
 
258
                        rContext->dwStatus &= ~SCARD_UNKNOWN;
 
259
                }
 
260
                else
 
261
                {
 
262
                        rContext->dwStatus |= SCARD_PRESENT;
 
263
                        rContext->dwStatus &= ~SCARD_ABSENT;
 
264
                        rContext->dwStatus |= SCARD_SWALLOWED;
 
265
                        rContext->dwStatus &= ~SCARD_POWERED;
 
266
                        rContext->dwStatus &= ~SCARD_NEGOTIABLE;
 
267
                        rContext->dwStatus &= ~SCARD_SPECIFIC;
 
268
                        rContext->dwStatus &= ~SCARD_UNKNOWN;
 
269
                        rContext->dwProtocol = 0;
 
270
                        rContext->dwAtrLen = 0;
 
271
                }
 
272
 
 
273
                dwCurrentState = SCARD_PRESENT;
 
274
 
 
275
        }
 
276
        else
 
277
        {
 
278
                dwCurrentState = SCARD_ABSENT;
 
279
                rContext->dwStatus |= SCARD_ABSENT;
 
280
                rContext->dwStatus &= ~SCARD_PRESENT;
 
281
                rContext->dwStatus &= ~SCARD_POWERED;
 
282
                rContext->dwStatus &= ~SCARD_NEGOTIABLE;
 
283
                rContext->dwStatus &= ~SCARD_SPECIFIC;
 
284
                rContext->dwStatus &= ~SCARD_SWALLOWED;
 
285
                rContext->dwStatus &= ~SCARD_UNKNOWN;
 
286
                rContext->dwAtrLen = 0;
 
287
                rContext->dwProtocol = 0;
 
288
        }
 
289
 
 
290
        /*
 
291
         * Set all the public attributes to this reader 
 
292
         */
 
293
        (readerStates[i])->readerState = rContext->dwStatus;
 
294
        (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
 
295
        (readerStates[i])->cardProtocol = rContext->dwProtocol;
 
296
        (readerStates[i])->readerSharing = dwReaderSharing =
 
297
                rContext->dwContexts;
 
298
        memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
 
299
                rContext->dwAtrLen);
 
300
 
 
301
        SYS_MMapSynchronize((void *) readerStates[i], pageSize);
 
302
 
 
303
        while (1)
 
304
        {
 
305
                dwStatus = 0;
 
306
 
 
307
                rv = IFDStatusICC(rContext, &dwStatus,
 
308
                        &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
 
309
 
 
310
                if (rv != SCARD_S_SUCCESS)
 
311
                {
 
312
                        DebugLogB("Error communicating to: %s", lpcReader);
 
313
 
 
314
                        /*
 
315
                         * Set error status on this reader while errors occur 
 
316
                         */
 
317
 
 
318
                        rContext->dwStatus &= ~SCARD_ABSENT;
 
319
                        rContext->dwStatus &= ~SCARD_PRESENT;
 
320
                        rContext->dwStatus &= ~SCARD_POWERED;
 
321
                        rContext->dwStatus &= ~SCARD_NEGOTIABLE;
 
322
                        rContext->dwStatus &= ~SCARD_SPECIFIC;
 
323
                        rContext->dwStatus &= ~SCARD_SWALLOWED;
 
324
                        rContext->dwStatus |= SCARD_UNKNOWN;
 
325
                        rContext->dwAtrLen = 0;
 
326
                        rContext->dwProtocol = 0;
 
327
 
 
328
                        dwCurrentState = SCARD_UNKNOWN;
 
329
 
 
330
                        /*
 
331
                         * Set all the public attributes to this reader 
 
332
                         */
 
333
                        (readerStates[i])->readerState = rContext->dwStatus;
 
334
                        (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
 
335
                        (readerStates[i])->cardProtocol = rContext->dwProtocol;
 
336
                        memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
 
337
                                rContext->dwAtrLen);
 
338
 
 
339
                        SYS_MMapSynchronize((void *) readerStates[i], pageSize);
 
340
 
 
341
                        /*
 
342
                         * This code causes race conditions on G4's with USB
 
343
                         * insertion 
 
344
                         */
 
345
                        /*
 
346
                         * dwErrorCount += 1; SYS_Sleep(1); 
 
347
                         */
 
348
                        /*
 
349
                         * After 10 seconds of errors, try to reinitialize the reader
 
350
                         * This sometimes helps bring readers out of *crazy* states. 
 
351
                         */
 
352
                        /*
 
353
                         * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext
 
354
                         * ); RFInitializeReader( rContext ); dwErrorCount = 0; } 
 
355
                         */
 
356
 
 
357
                        /*
 
358
                         * End of race condition code block 
 
359
                         */
 
360
                }
 
361
 
 
362
                if (dwStatus & SCARD_ABSENT)
 
363
                {
 
364
                        if (dwCurrentState == SCARD_PRESENT ||
 
365
                                dwCurrentState == SCARD_UNKNOWN)
 
366
                        {
 
367
                                /*
 
368
                                 * Change the status structure 
 
369
                                 */
 
370
                                DebugLogB("Card Removed From %s", lpcReader);
 
371
                                /*
 
372
                                 * Notify the card has been removed 
 
373
                                 */
 
374
                                RFSetReaderEventState(rContext, SCARD_REMOVED);
 
375
 
 
376
                                rContext->dwAtrLen = 0;
 
377
                                rContext->dwProtocol = 0;
 
378
                                rContext->dwStatus |= SCARD_ABSENT;
 
379
                                rContext->dwStatus &= ~SCARD_UNKNOWN;
 
380
                                rContext->dwStatus &= ~SCARD_PRESENT;
 
381
                                rContext->dwStatus &= ~SCARD_POWERED;
 
382
                                rContext->dwStatus &= ~SCARD_NEGOTIABLE;
 
383
                                rContext->dwStatus &= ~SCARD_SWALLOWED;
 
384
                                rContext->dwStatus &= ~SCARD_SPECIFIC;
 
385
                                dwCurrentState = SCARD_ABSENT;
 
386
 
 
387
                                /*
 
388
                                 * Set all the public attributes to this reader 
 
389
                                 */
 
390
                                (readerStates[i])->readerState = rContext->dwStatus;
 
391
                                (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
 
392
                                (readerStates[i])->cardProtocol = rContext->dwProtocol;
 
393
                                memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
 
394
                                        rContext->dwAtrLen);
 
395
 
 
396
                                SYS_MMapSynchronize((void *) readerStates[i], pageSize);
 
397
                        }
 
398
 
 
399
                }
 
400
                else if (dwStatus & SCARD_PRESENT)
 
401
                {
 
402
                        if (dwCurrentState == SCARD_ABSENT ||
 
403
                                dwCurrentState == SCARD_UNKNOWN)
 
404
                        {
 
405
                                /*
 
406
                                 * Power and reset the card 
 
407
                                 */
 
408
                                SYS_USleep(PCSCLITE_STATUS_WAIT);
 
409
                                rv = IFDPowerICC(rContext, IFD_POWER_UP,
 
410
                                        rContext->ucAtr, &rContext->dwAtrLen);
 
411
 
 
412
                                if (rv == IFD_SUCCESS)
 
413
                                {
 
414
                                        rContext->dwProtocol =
 
415
                                                PHGetDefaultProtocol(rContext->ucAtr,
 
416
                                                rContext->dwAtrLen);
 
417
                                        rContext->dwStatus |= SCARD_PRESENT;
 
418
                                        rContext->dwStatus &= ~SCARD_ABSENT;
 
419
                                        rContext->dwStatus |= SCARD_POWERED;
 
420
                                        rContext->dwStatus |= SCARD_NEGOTIABLE;
 
421
                                        rContext->dwStatus &= ~SCARD_SPECIFIC;
 
422
                                        rContext->dwStatus &= ~SCARD_UNKNOWN;
 
423
                                        rContext->dwStatus &= ~SCARD_SWALLOWED;
 
424
 
 
425
                                        /*
 
426
                                         * Notify the card has been reset 
 
427
                                         */
 
428
                                        /*
 
429
                                         * RFSetReaderEventState( rContext, SCARD_RESET ); 
 
430
                                         */
 
431
                                }
 
432
                                else
 
433
                                {
 
434
                                        rContext->dwStatus |= SCARD_PRESENT;
 
435
                                        rContext->dwStatus &= ~SCARD_ABSENT;
 
436
                                        rContext->dwStatus |= SCARD_SWALLOWED;
 
437
                                        rContext->dwStatus &= ~SCARD_POWERED;
 
438
                                        rContext->dwStatus &= ~SCARD_NEGOTIABLE;
 
439
                                        rContext->dwStatus &= ~SCARD_SPECIFIC;
 
440
                                        rContext->dwStatus &= ~SCARD_UNKNOWN;
 
441
                                        rContext->dwAtrLen = 0;
 
442
                                        rContext->dwProtocol = 0;
 
443
                                }
 
444
 
 
445
                                dwCurrentState = SCARD_PRESENT;
 
446
 
 
447
                                /*
 
448
                                 * Set all the public attributes to this reader 
 
449
                                 */
 
450
                                (readerStates[i])->readerState = rContext->dwStatus;
 
451
                                (readerStates[i])->cardAtrLength = rContext->dwAtrLen;
 
452
                                (readerStates[i])->cardProtocol = rContext->dwProtocol;
 
453
                                memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
 
454
                                        rContext->dwAtrLen);
 
455
 
 
456
                                SYS_MMapSynchronize((void *) readerStates[i], pageSize);
 
457
 
 
458
                                DebugLogB("Card inserted into %s", lpcReader);
 
459
 
 
460
                                if (rv == IFD_SUCCESS)
 
461
                                {
 
462
                                        if (rContext->dwAtrLen > 0)
 
463
                                        {
 
464
                                                DebugXxd("Card ATR: ",
 
465
                                                        rContext->ucAtr, rContext->dwAtrLen);
 
466
                                        }
 
467
                                        else
 
468
                                                DebugLogA("Card ATR: (NULL)");
 
469
                                }
 
470
                                else
 
471
                                        DebugLogA("Error powering up card.");
 
472
                        }
 
473
                }
 
474
 
 
475
                if (rContext->dwLockId == 0xFFFF)
 
476
                {
 
477
                        /*
 
478
                         * Exit and notify the caller 
 
479
                         */
 
480
                        rContext->dwLockId = 0;
 
481
                        SYS_ThreadDetach(rContext->pthThread);
 
482
                        SYS_ThreadExit(0);
 
483
                }
 
484
 
 
485
                /*
 
486
                 * Sharing may change w/o an event pass it on 
 
487
                 */
 
488
 
 
489
                if (dwReaderSharing != rContext->dwContexts)
 
490
                {
 
491
                        dwReaderSharing = rContext->dwContexts;
 
492
                        (readerStates[i])->readerSharing = dwReaderSharing;
 
493
                        SYS_MMapSynchronize((void *) readerStates[i], pageSize);
 
494
                }
 
495
 
 
496
                SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
 
497
        }
418
498
}
419
 
 
420
 
void EHSetSharingEvent( PREADER_CONTEXT rContext, DWORD dwValue ) {
421
 
 
422
 
  (readerStates[rContext->dwPublicID])->lockState = dwValue;
423
 
 
 
499
 
 
500
void EHSetSharingEvent(PREADER_CONTEXT rContext, DWORD dwValue)
 
501
{
 
502
        (readerStates[rContext->dwPublicID])->lockState = dwValue;
424
503
}