1/*
2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
30
31#include <dlfcn.h>
32
33#include <winscard.h>
34
35#include "sun_security_smartcardio_PlatformPCSC.h"
36
37#include "pcsc_md.h"
38
39void *hModule;
40FPTR_SCardEstablishContext scardEstablishContext;
41FPTR_SCardConnect scardConnect;
42FPTR_SCardDisconnect scardDisconnect;
43FPTR_SCardStatus scardStatus;
44FPTR_SCardGetStatusChange scardGetStatusChange;
45FPTR_SCardTransmit scardTransmit;
46FPTR_SCardListReaders scardListReaders;
47FPTR_SCardBeginTransaction scardBeginTransaction;
48FPTR_SCardEndTransaction scardEndTransaction;
49FPTR_SCardControl scardControl;
50
51/*
52 * Throws a Java Exception by name
53 */
54void throwByName(JNIEnv *env, const char *name, const char *msg)
55{
56 jclass cls = (*env)->FindClass(env, name);
57
58 if (cls != 0) /* Otherwise an exception has already been thrown */
59 (*env)->ThrowNew(env, cls, msg);
60}
61
62/*
63 * Throws java.lang.NullPointerException
64 */
65void throwNullPointerException(JNIEnv *env, const char *msg)
66{
67 throwByName(env, "java/lang/NullPointerException", msg);
68}
69
70/*
71 * Throws java.io.IOException
72 */
73void throwIOException(JNIEnv *env, const char *msg)
74{
75 throwByName(env, "java/io/IOException", msg);
76}
77
78void *findFunction(JNIEnv *env, void *hModule, char *functionName) {
79 void *fAddress = dlsym(hModule, functionName);
80 if (fAddress == NULL) {
81 char errorMessage[256];
82 snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
83 throwNullPointerException(env, errorMessage);
84 return NULL;
85 }
86 return fAddress;
87}
88
89JNIEXPORT void JNICALL Java_sun_security_smartcardio_PlatformPCSC_initialize
90 (JNIEnv *env, jclass thisClass, jstring jLibName) {
91 const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
92 if (libName == NULL) {
93 throwNullPointerException(env, "PCSC library name is null");
94 return;
95 }
96 hModule = dlopen(libName, RTLD_LAZY);
97 (*env)->ReleaseStringUTFChars(env, jLibName, libName);
98
99 if (hModule == NULL) {
100 throwIOException(env, dlerror());
101 return;
102 }
103 scardEstablishContext = (FPTR_SCardEstablishContext)findFunction(env, hModule, "SCardEstablishContext");
104 if ((*env)->ExceptionCheck(env)) {
105 return;
106 }
107 scardConnect = (FPTR_SCardConnect) findFunction(env, hModule, "SCardConnect");
108 if ((*env)->ExceptionCheck(env)) {
109 return;
110 }
111 scardDisconnect = (FPTR_SCardDisconnect) findFunction(env, hModule, "SCardDisconnect");
112 if ((*env)->ExceptionCheck(env)) {
113 return;
114 }
115 scardStatus = (FPTR_SCardStatus) findFunction(env, hModule, "SCardStatus");
116 if ((*env)->ExceptionCheck(env)) {
117 return;
118 }
119 scardGetStatusChange = (FPTR_SCardGetStatusChange) findFunction(env, hModule, "SCardGetStatusChange");
120 if ((*env)->ExceptionCheck(env)) {
121 return;
122 }
123 scardTransmit = (FPTR_SCardTransmit) findFunction(env, hModule, "SCardTransmit");
124 if ((*env)->ExceptionCheck(env)) {
125 return;
126 }
127 scardListReaders = (FPTR_SCardListReaders) findFunction(env, hModule, "SCardListReaders");
128 if ((*env)->ExceptionCheck(env)) {
129 return;
130 }
131 scardBeginTransaction = (FPTR_SCardBeginTransaction)findFunction(env, hModule, "SCardBeginTransaction");
132 if ((*env)->ExceptionCheck(env)) {
133 return;
134 }
135 scardEndTransaction = (FPTR_SCardEndTransaction) findFunction(env, hModule, "SCardEndTransaction");
136 if ((*env)->ExceptionCheck(env)) {
137 return;
138 }
139#ifndef __APPLE__
140 scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl");
141#else
142 scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl132");
143#endif // __APPLE__
144}
145