2 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 // pcsc++ - PCSC client interface layer in C++
31 #include <security_utilities/debugging.h>
41 static void decode(vector
<string
> &names
, const char *buffer
, size_t size
)
44 for (size_t pos
= 0; pos
< size
- 1; ) {
45 size_t len
= strlen(buffer
+ pos
);
46 names
.push_back(string(buffer
+ pos
, len
));
51 inline void decode(vector
<string
> &names
, const vector
<char> &buffer
, size_t size
)
53 decode(names
, &buffer
[0], size
);
60 Error::Error(long err
) : error(err
)
62 IFDEBUG(debugDiagnose(this));
66 const char *Error::what() const throw ()
68 return pcsc_stringify_error(error
);
72 void Error::throwMe(long err
)
78 OSStatus
Error::osStatus() const
80 return -1; //@@@ preliminary
83 int Error::unixError() const
85 return EINVAL
; //@@@ preliminary
89 void Error::debugDiagnose(const void *id
) const
91 secdebug("exception", "%p PCSC::Error %s (%ld) osStatus %ld",
92 id
, pcsc_stringify_error(error
), error
, osStatus());
100 void ReaderState::set(const char *name
, unsigned long known
)
105 dwCurrentState
= known
;
109 void ReaderState::lastKnown(unsigned long s
)
111 // clear out CHANGED and UNAVAILABLE
112 dwCurrentState
= s
& ~(SCARD_STATE_CHANGED
| SCARD_STATE_UNAVAILABLE
);
116 #if defined(DEBUGDUMP)
118 void ReaderState::dump()
120 Debug::dump("reader(%s) state=0x%lx events=0x%lx",
121 szReader
? szReader
: "(null)", dwCurrentState
, dwEventState
);
122 Debug::dumpData(" ATR", rgbAtr
, cbAtr
);
141 Error::check(SCardReleaseContext(mContext
));
146 // (Re)establish PCSC context.
147 // Don't fail on SCARD_F_INTERNAL_ERROR (pcscd not running).
152 Error::check(::SCardEstablishContext(SCARD_SCOPE_SYSTEM
, NULL
, NULL
, &mContext
));
154 secdebug("pcsc", "context opened");
155 } catch (const Error
&err
) {
156 if (err
.error
== long(SCARD_F_INTERNAL_ERROR
)) {
157 secdebug("pcsc", "context not opened");
165 bool Session::check(long rc
)
168 case SCARD_S_SUCCESS
:
169 return true; // got reader(s), call succeeded
170 case SCARD_E_READER_UNAVAILABLE
:
171 return false; // no readers, but don't treat as error
174 return false; // placebo
179 void Session::listReaders(vector
<string
> &readers
, const char *groups
)
181 mReaderBuffer
.resize(1000); //@@@ preliminary hack
182 unsigned long size
= mReaderBuffer
.size();
183 if (check(::SCardListReaders(mContext
, groups
, &mReaderBuffer
[0], &size
)))
184 decode(readers
, mReaderBuffer
, size
);
186 readers
.clear(); // treat as success (returning zero readers)
191 // Reader status check
193 void Session::statusChange(ReaderState
*readers
, unsigned int nReaders
, long timeout
)
196 return; // no readers, no foul
197 check(::SCardGetStatusChange(mContext
, timeout
, readers
, nReaders
));
213 void Card::open(Session
&session
, const char *reader
,
214 unsigned long share
, unsigned long protocols
)
216 Error::check(::SCardConnect(session
.mContext
,
217 reader
, share
, protocols
, &mHandle
, &mProtocol
));
221 void Card::close(unsigned long disposition
)
224 Error::check(::SCardDisconnect(mHandle
, disposition
));
231 } // namespace Security