PCSC那事儿(十七--SCardGetStatusChange)

来源:互联网 发布:java 字符串搜索 编辑:程序博客网 时间:2024/05/17 00:17

 

SCardGetStatusChange

SCardGetStatusChange定义在winscard_clnt.c

实现如下:

1872 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,

1873         LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)

1874 {

1875         PSCARD_READERSTATE_A currReader;

1876         PREADER_STATE rContext;

1877         long dwTime = dwTimeout;

1878         DWORD dwState;

1879         DWORD dwBreakFlag = 0;

1880         int j;

1881         LONG dwContextIndex;

1882         int currentReaderCount = 0;

1883         LONG rv = SCARD_S_SUCCESS;

1884

1885         PROFILE_START

1886

1887         if ((rgReaderStates == NULL && cReaders > 0)

1888                 || (cReaders > PCSCLITE_MAX_READERS_CONTEXTS))

1889                 return SCARD_E_INVALID_PARAMETER;

1890

1891         /* Check the integrity of the reader states structures */

1892         for (j = 0; j < cReaders; j++)

1893         {

1894                 if (rgReaderStates[j].szReader == NULL)

1895                         return SCARD_E_INVALID_VALUE;

1896         }

 

 

1887~1889行,1892~1896行,两组条件检查,easy,不是吗?

1898         /* return if all readers are SCARD_STATE_IGNORE */

1899         if (cReaders > 0)

1900         {

1901                 int nbNonIgnoredReaders = cReaders;

1902

1903                 for (j=0; j<cReaders; j++)

1904                         if (rgReaderStates[j].dwCurrentState & SCARD_STATE_IGNORE)

 

1905                                 nbNonIgnoredReaders--;

1906

1907                 if (0 == nbNonIgnoredReaders)

1908                         return SCARD_S_SUCCESS;

1909         }

 

 

 

1898~1909行说明如果当前所有读卡器状态是 SCARD_STATE_IGNORE

则直接返回,因为这个标志,代表APPLICATION不想知道读卡器的状态。

不想知道,就不要再去获取读卡器的状态了。APPLICATION不想要,

ResourceManager也不好意硬给。

SCARD_STATE_xxxn多状态,见上面的卷5分析。

 

1911         rv = SCardCheckDaemonAvailability();

1912         if (rv != SCARD_S_SUCCESS)

1913                 return rv;

1914

1915         /*

1916          * Make sure this context has been opened

1917          */

1918         dwContextIndex = SCardGetContextIndice(hContext);

1919         if (dwContextIndex == -1)

1920                 return SCARD_E_INVALID_HANDLE;

1921

1922         (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);

1923

1924         /* check the context is still opened */

1925         dwContextIndex = SCardGetContextIndice(hContext);

1926         if (dwContextIndex == -1)

1927                 /* the context is now invalid

1928                  * -> another thread may have called SCardReleaseContext

1929                  * -> so the mMutex has been unlocked */

1930                 return SCARD_E_INVALID_HANDLE;

 

 

 

1911~1930行,略过,说了n次。

1938         if (cReaders == 0)

1939         {

1940                 while (1)

1941                 {

1942                         int i;

 

1943

1944                         rv = SCardCheckDaemonAvailability();

1945                         if (rv != SCARD_S_SUCCESS)

1946                                 goto end;

1947

1948                         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)

1949                         {

1950                                 if ((readerStates[i])->readerID != 0)

1951                                 {

1952                                         /* Reader was found */

1953                                         rv = SCARD_S_SUCCESS;

1954                                         goto end;

1955                                 }

1956                         }

 

 

 

1938行,可是特殊情况, cReaders==0,表示想等待第一台可用的读卡器。

只要有一台可用,则 SCardGetStatusChange成功返回。

1944 行,略过。

1948~1956行,再次查询readerStates状态,如果查到有可用的读卡器,

则成功返回。别忘记,readerStates可是共享内存。

1958                         if (dwTimeout == 0)

1959                         {

1960                                 /* return immediately - no reader available */

1961                                 rv = SCARD_E_READER_UNAVAILABLE;

1962                                 goto end;

1963                         }

 

 

 

1958行表示即使目前没有可用的读卡器,函数也立刻返回,

不用进入超时等待可用的读卡器。

1965                         dwTime = WaitForPcscdEvent(hContext, dwTime);

1966                         if (dwTimeout != INFINITE)

1967                         {

1968                                 if (dwTime <= 0)

1969                                 {

1970                                         rv = SCARD_E_TIMEOUT;

1971                                         goto end;

1972                                 }

1973                         }

 

1974                 }

1975         }

 

 

 

1965~1975行,在dwTime设定的时间内等待读卡器事件的出现。事件是通过文件fifo来实现的。

1877         long dwTime = dwTimeout;

 

如果dwTimeout没有设置为INFINITE,则如果在设定时间内,

没有出现事件,则超时返回。

否则 WaitForPcscdEvent将永远等待。

Waiting for eventsfrom Monday to Sunday.

 

1965行,WaitForPcscdEventwinscard_clnt.c中定义

实现如下:

1724 static long WaitForPcscdEvent(SCARDCONTEXT hContext, long dwTime)

1725 {

1726         char filename[FILENAME_MAX];

1727         char buf[1];

1728         int fd, r;

1729         struct timeval tv, *ptv = NULL;

1730         struct timeval before, after;

1731         fd_set read_fd;

1732

1733         if (INFINITE != dwTime)

1734         {

1735                 if (dwTime < 0)

1736                         return 0;

1737                 gettimeofday(&before, NULL);

1738                 tv.tv_sec = dwTime/1000;

1739                 tv.tv_usec = dwTime*1000 - tv.tv_sec*1000000;

1740                 ptv = &tv;

1741         }

1742

1743         (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",

1744                 PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);

1745         r = mkfifo(filename, 0644);

1746         if (-1 == r)

1747         {

1748                 Log2(PCSC_LOG_CRITICAL, "Can't create event fifo: %s", strerror(errno));

1749                 goto exit;

1750         }

1751

 

1752         fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);

1753

1754         /* the file may have been removed between the mkfifo() and open() */

1755         if (-1 != fd)

1756         {

1757                 FD_ZERO(&read_fd);

1758                 FD_SET(fd, &read_fd);

1759

1760                 (void)select(fd+1, &read_fd, NULL, NULL, ptv);

1761

1762                 (void)SYS_ReadFile(fd, buf, 1);

1763                 (void)SYS_CloseFile(fd);

1764         }

1765

1766         (void)SYS_RemoveFile(filename);

1767

1768         if (INFINITE != dwTime)

1769         {

1770                 long int diff;

1771

1772                 gettimeofday(&after, NULL);

1773                 diff = time_sub(&after, &before);

1774                 dwTime -= diff/1000;

1775         }

1776

1777 exit:

1778         return dwTime;

1779 }

 

 

1738行,                 tv.tv_sec = dwTime/1000;

 

说明dwTime的粒度是ms.

1745行 mkfifo明确地说明,event就是fifo,文件fifo不是匿名fifo通讯。

1752行 SYS_OpenFile打开fifo文件,非阻塞方式。fifo文件存在于

PCSCLITE_EVENTS_DIR也就是/var/run/pcscd/pcscd.events

文件名以APPLICATIONpidhContext组合。

 

1760行 select进行超时读取。

1768~1775行 返回剩余的等待时间。当然如果是dwTime==INFINITE

select将永久等待,知道fifo可读。

select永久等待。因为它知道,会有读卡器来。所以它一直等。

而在现实中呢?比如select某人,永久?那只是在歌词所咏颂的情景中才会出现的故事。

现实中的绝大部分故事解决注定是悲剧。

 

现实总是和理想相差太远。昨天盼今天,今天盼明天,年头盼年尾,

今年盼明年。所谓希望总是有的。哈哈...

 

问:想知道fifo是谁写入的。

答案是,继续看吧,到了第三章的服务端解说,就有知道的。

 

 

回头,继续。

回到 SCardGetStatusChange

1938~1975完成。但是1935~1936有行,原版注释

1935          * This is DEPRECATED. Use the special reader name //?PnP?/Notification

1936          * instead

 

 

也就是1938~1975已经放弃了,估计是为了兼容以前的版本,现在要探测

可用的读卡器,是使用特殊的读卡器名字来调用SCardGetStatusChange

这个名字就是//?PnP?/Notification

。多in的名字呀,PnP

这和ms有很大的关系呀,和大佬攀上关系。那当然好。现实中也有很多

这样高攀的例子。别抱怨,你有背景吗?你有天线吗?没有,那么请take a hike.

 

继续。

1882         int currentReaderCount = 0;

currentReaderCount当前系统中的读卡器数量初始化为0.

1976

1977         /*

1978          * End of search for readers

1979          */

1980

1981         /* Clear the event state for all readers */

1982         for (j = 0; j < cReaders; j++)

1983                 rgReaderStates[j].dwEventState = 0;

1984

1985         /* Now is where we start our event checking loop */

1986         Log1(PCSC_LOG_DEBUG, "Event Loop Start");

1987

1988         psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;

1989

 

 

1976~1989行,正如注释说。

 

1990         /* Get the initial reader count on the system */

 

1991         for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)

 

1992                 if ((readerStates[j])->readerID != 0)

 

1993                         currentReaderCount++;

 

 

1990~1993获取系统中目前可用的读卡器数量.目的是准备和参数中传入

的给定名字的读卡器进行比对,确定状态变化。

1995         j = 0;

1996         do

1997         {

1998                 rv = SCardCheckDaemonAvailability();

1999                 if (rv != SCARD_S_SUCCESS)

2000                 {

2001                         if (psContextMap[dwContextIndex].mMutex)

2002                                 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

2003

2004                         PROFILE_END(rv)

2005

2006                         return rv;

2007                 }

2008

2009                 currReader = &rgReaderStates[j];

 

 

接下来就逐个比对了。

 

1998行,再次判断服务端是否存在。

2009行,从参数获取第j个读卡器状态。要开始比对了。

 

2012                 if (!(currReader->dwCurrentState & SCARD_STATE_IGNORE))

2013                 {

2014                         LPSTR lpcReaderName;

2015                         int i;

2016

2017           /************ Looks for correct readernames *********************/

2018

2019                         lpcReaderName = (char *) currReader->szReader;

2020

 

2021                         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)

2022                         {

2023                                 if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)

2024                                         break;

2025                         }

 

 

 

2012行,SCARD_STATE_IGNORE,前面提过了。

2023行,开始比对名字,把参数传入的读卡器数组名字逐个和所有的readerStatesreaderName进行比较。

2028                         if (i == PCSCLITE_MAX_READERS_CONTEXTS)

2029                         {

 

 

 

2028~2029说明参数传入的读卡器 currReader当前不存在于系统中。

存在两种可能,就是currReader的名字是否是"////?PnP?//Notification",正如上面所说的,

如果和ms有莫大关系,自然要特殊情况特殊处理呀。

 

特殊关照如下

2031                                 if (strcasecmp(lpcReaderName, "////?PnP?//Notification") == 0)

2032                                 {

2033                                         int k, newReaderCount = 0;

2034

2035                                         for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)

2036                                                 if ((readerStates[k])->readerID != 0)

2037                                                         newReaderCount++;

2038

2039                                         if (newReaderCount != currentReaderCount)

2040                                         {

2041                                                 Log1(PCSC_LOG_INFO, "Reader list changed");

2042                                                 currentReaderCount = newReaderCount;

2043

2044                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2045                                                 dwBreakFlag = 1;

2046                                         }

2047                                 }

 

 

 

 

 

2031~2047 看来有些着急,毕竟是ms委托的。

原先在1993的时候,已经获得了currentReaderCount

现在立刻再次获取当前的ReaderCount,也就是 newReaderCount

如果相比currentReaderCount,有变化,不管少了还是多了。赶紧上报。并标志

currReader->dwEventState.

 

2048                                 else

2049                                 {

2050                                         currReader->dwEventState = SCARD_STATE_UNKNOWN | SCARD_STATE_UNAVA     ILABLE;

2051                                         if (!(currReader->dwCurrentState & SCARD_STATE_UNKNOWN))

2052                                         {

2053                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2054                                                 /*

2055                                                  * Spec says use SCARD_STATE_IGNORE but a removed USB

2056                                                  * reader with eventState fed into currentState will

2057                                                  * be ignored forever

2058                                                  */

2059                                                 dwBreakFlag = 1;

2060                                         }

2061                                 }

 

 

 

 

2048行说明对于currReader没有比对成功。修改 currReader->dwEventState.

SCARD_STATE_xxx,前面提过了,卷5也提过了。

 

接下来是什么呢?当然是比对成功情况下的具体处理。

更新currReaderddwEventState.

2063                         else

2064                         {

2065                                 /* The reader has come back after being away */

2066                                 if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)

2067                                 {

2068                                         currReader->dwEventState |= SCARD_STATE_CHANGED;

 

2069                                         currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;

2070                                         Log0(PCSC_LOG_DEBUG);

2071                                         dwBreakFlag = 1;

2072                                 }

2073

2074         /*****************************************************************/

2075

2076                                 /* Set the reader status structure */

2077                                 rContext = readerStates[i];

2078

2076                                 /* Set the reader status structure */

2077                                 rContext = readerStates[i];

2078

2079                                 /* Now we check all the Reader States */

2080                                 dwState = rContext->readerState;

2081

2082                                 /* only if current state has an non null event counter */

2083                                 if (currReader->dwCurrentState & 0xFFFF0000)

2084                                 {

2085                                         int currentCounter, stateCounter;

2086

2087                                         stateCounter = (dwState >> 16) & 0xFFFF;

2088                                         currentCounter = (currReader->dwCurrentState >> 16) & 0xFFFF;

2089

2090                                         /* has the event counter changed since the last call? */

2091                                         if (stateCounter != currentCounter)

2092                                         {

2093                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2094                                                 Log0(PCSC_LOG_DEBUG);

2095                                                 dwBreakFlag = 1;

2096                                         }

2097

2098                                         /* add an event counter in the upper word of dwEventState */

2099                                         currReader->dwEventState =

2100                                                 ((currReader->dwEventState & 0xffff )

2101                                                 | (stateCounter << 16));

2102                                 }

 

 

 

 

原来currReader->dwCurrentState的类型是unsignedlong(4字节,由体系结构决定),16(31~16bit)用来装currReader的当前事件计数。

 

2083~2102行,把currReader和前面找到的和currReader读卡器名字相同的readerStates

进行计数比较,确定系统中原本已经存在的读卡器是否发生了新的事件。原本就存在于系统中的读卡器,是否发生状态变化,还得依靠计数。

把当前计数更新到currReader->dwEventState.

 

接着从readerStates也就是共享内存中进一步获取当前读卡器当前状态,与currReader->dwCurrentState也就是APPLICATION传入的状态,进行比对,进一步确定发生的具体事件。

2104         /*********** Check if the reader is in the correct state ********/

2105                                 if (dwState & SCARD_UNKNOWN)

2106                                 {

2107                                         /* reader is in bad state */

2108                                         currReader->dwEventState = SCARD_STATE_UNAVAILABLE;

2109                                         if (!(currReader->dwCurrentState & SCARD_STATE_UNAVAILABLE))

2110                                         {

2111                                                 /* App thinks reader is in good state and it is not */

2112                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2113                                                 Log0(PCSC_LOG_DEBUG);

2114                                                 dwBreakFlag = 1;

2115                                         }

2116                                 }

2117                                 else

2118                                 {

2119                                         /* App thinks reader in bad state but it is not */

2120                                         if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)

2121                                         {

2122                                                 currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;

2123                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2124                                                 Log0(PCSC_LOG_DEBUG);

2125                                                 dwBreakFlag = 1;

2126                                         }

2127                                 }

2128

2129         /********** Check for card presence in the reader **************/

 

2130

2131                                 if (dwState & SCARD_PRESENT)

2132                                 {

2133                                         /* card present but not yet powered up */

2134                                         if (0 == rContext->cardAtrLength)

2135                                                 /* Allow the status thread to convey information */

2136                                                 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);

2137

2138                                         currReader->cbAtr = rContext->cardAtrLength;

2139                                         memcpy(currReader->rgbAtr, rContext->cardAtr,

2140                                                 currReader->cbAtr);

2141                                 }

2142                                 else

2143                                         currReader->cbAtr = 0;

2144

2145                                 /* Card is now absent */

2146                                 if (dwState & SCARD_ABSENT)

2147                                 {

2148                                         currReader->dwEventState |= SCARD_STATE_EMPTY;

2149                                         currReader->dwEventState &= ~SCARD_STATE_PRESENT;

2150                                         currReader->dwEventState &= ~SCARD_STATE_UNAWARE;

2151                                         currReader->dwEventState &= ~SCARD_STATE_IGNORE;

2152                                         currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;

2153                                         currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;

2154                                         currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;

2155                                         currReader->dwEventState &= ~SCARD_STATE_MUTE;

2156                                         currReader->dwEventState &= ~SCARD_STATE_INUSE;

2157

2158                                         /* After present the rest are assumed */

2159                                         if (currReader->dwCurrentState & SCARD_STATE_PRESENT)

2160                                         {

2161                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2162                                                 Log0(PCSC_LOG_DEBUG);

2163                                                 dwBreakFlag = 1;

 

2164                                         }

2165                                 }

2166                                 /* Card is now present */

2167                                 else if (dwState & SCARD_PRESENT)

2168                                 {

2169                                         currReader->dwEventState |= SCARD_STATE_PRESENT;

2170                                         currReader->dwEventState &= ~SCARD_STATE_EMPTY;

2171                                         currReader->dwEventState &= ~SCARD_STATE_UNAWARE;

2172                                         currReader->dwEventState &= ~SCARD_STATE_IGNORE;

2173                                         currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;

2174                                         currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;

2175                                         currReader->dwEventState &= ~SCARD_STATE_MUTE;

2176

2177                                         if (currReader->dwCurrentState & SCARD_STATE_EMPTY)

2178                                         {

2179                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2180                                                 Log0(PCSC_LOG_DEBUG);

2181                                                 dwBreakFlag = 1;

2182                                         }

2183

2184                                         if (dwState & SCARD_SWALLOWED)

2185                                         {

2186                                                 currReader->dwEventState |= SCARD_STATE_MUTE;

2187                                                 if (!(currReader->dwCurrentState & SCARD_STATE_MUTE))

2188                                                 {

2189                                                         currReader->dwEventState |= SCARD_STATE_CHANGED;

2190                                                         Log0(PCSC_LOG_DEBUG);

2191                                                         dwBreakFlag = 1;

2192                                                 }

2193                                         }

2194                                         else

2195                                         {

 

2196                                                 /* App thinks card is mute but it is not */

2197                                                 if (currReader->dwCurrentState & SCARD_STATE_MUTE)

2198                                                 {

2199                                                         currReader->dwEventState |= SCARD_STATE_CHANGED;

2200                                                         Log0(PCSC_LOG_DEBUG);

2201                                                         dwBreakFlag = 1;

2202                                                 }

2203                                         }

2204                                 }

 

 

 

2104~2204都很好理解的,主要目的就是更新 currReader->dwEventState.

 

2205

2206                                 /* Now figure out sharing modes */

2207                                 if (rContext->readerSharing == -1)

2208                                 {

2209                                         currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;

2210                                         currReader->dwEventState &= ~SCARD_STATE_INUSE;

2211                                         if (currReader->dwCurrentState & SCARD_STATE_INUSE)

2212                                         {

2213                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2214                                                 Log0(PCSC_LOG_DEBUG);

2215                                                 dwBreakFlag = 1;

2216                                         }

2217                                 }

2218                                 else if (rContext->readerSharing >= 1)

2219                                 {

2220                                         /* A card must be inserted for it to be INUSE */

2221                                         if (dwState & SCARD_PRESENT)

2222                                         {

2223                                                 currReader->dwEventState |= SCARD_STATE_INUSE;

2224                                                 currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;

2225                                                 if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)

 

2226                                                 {

2227                                                         currReader->dwEventState |= SCARD_STATE_CHANGED;

2228                                                         Log0(PCSC_LOG_DEBUG);

2229                                                         dwBreakFlag = 1;

2230                                                 }

2231                                         }

2232                                 }

2233                                 else if (rContext->readerSharing == 0)

2234                                 {

2235                                         currReader->dwEventState &= ~SCARD_STATE_INUSE;

2236                                         currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;

2237

2238                                         if (currReader->dwCurrentState & SCARD_STATE_INUSE)

2239                                         {

2240                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2241                                                 Log0(PCSC_LOG_DEBUG);

2242                                                 dwBreakFlag = 1;

2243                                         }

2244                                         else if (currReader-> dwCurrentState

2245                                                 & SCARD_STATE_EXCLUSIVE)

2246                                         {

2247                                                 currReader->dwEventState |= SCARD_STATE_CHANGED;

2248                                                 Log0(PCSC_LOG_DEBUG);

2249                                                 dwBreakFlag = 1;

2250                                         }

2251                                 }

 

 

 

2205~2251行,对共享模式进行特殊处理。

rContext->readerSharing==-1表示目前读卡器处于排它模式,但是没有任何一个APPLICATION在使用读卡器。

rContext->readerSharing>= 1表示目前读卡器处于共享模式。且有多个应用同时在使用

读卡器。而rContext->readerSharing的值就是当前在该读卡器上所打开的上下文数量。

rContext->readerSharing== 0

rContext->readerSharing== 0表示当前的 readerStates已经处于初始状态。发生在reader

被移除。

2252

 

2253                                 if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)

2254                                 {

2255                                         /*

2256                                          * Break out of the while .. loop and return status

2257                                          * once all the status's for all readers is met

2258                                          */

2259                                         currReader->dwEventState |= SCARD_STATE_CHANGED;

2260                                         Log0(PCSC_LOG_DEBUG);

2261                                         dwBreakFlag = 1;

2262                                 }

2263                         }       /* End of SCARD_STATE_UNKNOWN */

2264                 }       /* End of SCARD_STATE_IGNORE */

 

 

 

2253行 表示应用不知道目前读卡器的状态。

2259行 表示告知应用读卡器状态发生变化了。

2265

2266                 /* Counter and resetter */

2267                 j++;

2268                 if (j == cReaders)

2269                 {

2270                         /* go back to the first reader */

2271                         j = 0;

2272

2273                         /* Declare all the break conditions */

2274

2275                         /* Break if UNAWARE is set and all readers have been checked */

2276                         if (dwBreakFlag == 1)

2277                                 break;

2278

2279                         if (BLOCK_STATUS_RESUME

2280                                 == psContextMap[dwContextIndex].contextBlockStatus)

2281                                 break;

2282

2283                         /* Only sleep once for each cycle of reader checks. */

2284                         dwTime = WaitForPcscdEvent(hContext, dwTime);

2285

2286                         if (dwTimeout != INFINITE)

2287                         {

2288                                 /* If time is greater than timeout and all readers have been

 

2289                                  * checked

2290                                  */

2291                                 if (dwTime <= 0)

2292                                 {

2293                                         rv = SCARD_E_TIMEOUT;

2294                                         goto end;

2295                                 }

2296                         }

2297                 }

2298         }

2299         while (1);

 

 

 

 

2265~2299行,很好理解。

2284行,WaitForPcscdEvent,在每一次while(1)大循环中,等待事件。发生变化,更新

currReader的各状态。这就是while(1)内部循环体的任务。

2300

2301         if (psContextMap[dwContextIndex].contextBlockStatus == BLOCK_STATUS_RESUME)

2302                 rv = SCARD_E_CANCELLED;

2303

2304 end:

2305         Log1(PCSC_LOG_DEBUG, "Event Loop End");

2306

2307         (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

2308

2309         PROFILE_END(rv)

2310

2311         return rv;

2312 }

 

 

 

SCardGetStatusChange解说结束前,说说

contextBlockStatus,这个存在于

 175 static struct _psContextMap

 176 {

 177         DWORD dwClientID;                               /**< Client Connection ID */

 178         SCARDCONTEXT hContext;                  /**< Application Context ID */

 179         DWORD contextBlockStatus;

 180         PCSCLITE_MUTEX_T mMutex;                /**< Mutex for this context */

 

 181         CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];

 182 } psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];

 

 

没有注释说明 contextBlockStatus做什么的。

搜索整个工程只有winscard_clnt.c用到且只有个地方用到。

这是一个状态值且只有两个状态定义于pcscd.h

#define BLOCK_STATUS_RESUME             0x00FF  /**< Normal resume */

#define BLOCK_STATUS_BLOCKING           0x00FA  /**< Function is blocking */

 

 

猜到了吧。

如果还没有,那么请看

原创粉丝点击