diff options
author | Sven Gothel <[email protected]> | 2013-06-21 03:45:07 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-06-21 03:45:07 +0200 |
commit | eb842815498f5926828b49c48fffce22fc9586a2 (patch) | |
tree | b3aac763bb16890f7f3b3c69b5cdec3febf654f2 /src/java | |
parent | 19bef683d38f4ce7b0dcb5c516244c6f87504e41 (diff) |
Security: Tighten DynamicLinker*, NativeLibrary and DynamicLibraryBundle access (2)
- Completes 23341a2df2d2ea36784a16fa1db8bc7385351a12
- Replace 'DynamicLinker' interface w/ well documented one
- All DynamicLinker methods are now considered secure, i.e.:
- open/lookup and close utilize reference counting on handle via a hash map.
- lookupSymbol(..) and close(..) impl. validate the passed library handle
whether it's retrieved via open*.
This is the fast path, not that expensive.
- lookupSymbolGlobal(..) performs
Check acccess of 'new RuntimePermission("loadLibrary.*")' if SecurityManager is installed.
This is the slow path.
- DynamicLibraryBundleInfo now reflects the security requirements,
i.e. whether priviledged access is needed.
Diffstat (limited to 'src/java')
9 files changed, 190 insertions, 108 deletions
diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java index fc36908..31ca372 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java @@ -324,7 +324,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper { long addr = 0; NativeLibrary lib = null; - if(info.shallLookupGlobal()) { + if( info.shallLookupGlobal() ) { // Try a global symbol lookup first .. addr = NativeLibrary.dynamicLookupFunctionGlobal(funcName); } diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java index dc90eab..ef44298 100644 --- a/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java +++ b/src/java/com/jogamp/common/os/DynamicLibraryBundleInfo.java @@ -28,14 +28,19 @@ package com.jogamp.common.os; -import java.util.*; +import java.util.List; import com.jogamp.common.util.RunnableExecutor; + public interface DynamicLibraryBundleInfo { public static final boolean DEBUG = DynamicLibraryBundle.DEBUG; - /** @return a list of Tool library names or alternative library name lists.<br> + /** + * If a {@link SecurityManager} is installed, user needs link permissions + * for the named libraries. + * + * @return a list of Tool library names or alternative library name lists.<br> * <ul> * <li>GL/GLU example Unix: [ [ "libGL.so.1", "libGL.so", "GL" ], [ "libGLU.so", "GLU" ] ] </li> * <li>GL/GLU example Windows: [ "OpenGL32", "GLU32" ] </li> @@ -44,7 +49,11 @@ public interface DynamicLibraryBundleInfo { */ public List<List<String>> getToolLibNames(); - /** @return a list of Glue library names.<br> + /** + * If a {@link SecurityManager} is installed, user needs link permissions + * for the named libraries. + * + * @return a list of Glue library names.<br> * <ul> * <li>GL: [ "nativewindow_x11", "jogl_gl2es12", "jogl_desktop" ] </li> * <li>NEWT: [ "nativewindow_x11", "newt" ] </li> @@ -55,23 +64,21 @@ public interface DynamicLibraryBundleInfo { */ public List<String> getGlueLibNames(); - /** May return the native libraries <pre>GetProcAddressFunc</pre> names, the first found function is being used.<br> + /** + * May return the native libraries <pre>GetProcAddressFunc</pre> names, the first found function is being used.<br> * This could be eg: <pre> glXGetProcAddressARB, glXGetProcAddressARB </pre>.<br> * If your Tool does not has this facility, just return null. * @see #toolGetProcAddress(long, String) */ public List<String> getToolGetProcAddressFuncNameList() ; - /** May implement the lookup function using the Tools facility.<br> + /** + * May implement the lookup function using the Tools facility.<br> * The actual function pointer is provided to allow proper bootstrapping of the ProcAddressTable, * using one of the provided function names by {@link #getToolGetProcAddressFuncNameList()}.<br> */ public long toolGetProcAddress(long toolGetProcAddressHandle, String funcName); - /** May implement the lookup function using the Tools facility.<br> - * The actual function pointer is provided to allow proper bootstrapping of the ProcAddressTable.<br> - */ - /** * @param funcName * @return true if {@link #toolGetProcAddress(long, String)} shall be tried before @@ -83,7 +90,13 @@ public interface DynamicLibraryBundleInfo { /** @return true if the native library symbols shall be made available for symbol resolution of subsequently loaded libraries. */ public boolean shallLinkGlobal(); - /** @return true if the dynamic symbol lookup shall happen system wide, over all loaded libraries. Otherwise only the loaded native libraries are used for lookup, which shall be the default. */ + /** + * If method returns <code>true</code> <i>and</i> if a {@link SecurityManager} is installed, user needs link permissions + * for <b>all</b> libraries, i.e. for <code>new RuntimePermission("loadLibrary.*");</code>! + * + * @return true if the dynamic symbol lookup shall happen system wide, over all loaded libraries. + * Otherwise only the loaded native libraries are used for lookup, which shall be the default. + */ public boolean shallLookupGlobal(); /** diff --git a/src/java/com/jogamp/common/os/DynamicLinker.java b/src/java/com/jogamp/common/os/DynamicLinker.java index b1671b9..ed52413 100644 --- a/src/java/com/jogamp/common/os/DynamicLinker.java +++ b/src/java/com/jogamp/common/os/DynamicLinker.java @@ -1,55 +1,102 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. */ package com.jogamp.common.os; -/** Provides an abstract interface to the OS's low-level dynamic - linking functionality. */ - +/** Low level secure dynamic linker access. */ public interface DynamicLinker { public static final boolean DEBUG = NativeLibrary.DEBUG; public static final boolean DEBUG_LOOKUP = NativeLibrary.DEBUG_LOOKUP; - + + /** + * If a {@link SecurityManager} is installed, user needs link permissions + * for the named library. + * <p> + * Opens the named library, allowing system wide access for other <i>users</i>. + * </p> + * + * @param pathname the full pathname for the library to open + * @param debug set to true to enable debugging + * @return the library handle, maybe 0 if not found. + * @throws SecurityException if user is not granted access for the named library. + */ public long openLibraryGlobal(String pathname, boolean debug) throws SecurityException; + + /** + * If a {@link SecurityManager} is installed, user needs link permissions + * for the named library. + * <p> + * Opens the named library, restricting access to this process. + * </p> + * + * @param pathname the full pathname for the library to open + * @param debug set to true to enable debugging + * @return the library handle, maybe 0 if not found. + * @throws SecurityException if user is not granted access for the named library. + */ public long openLibraryLocal(String pathname, boolean debug) throws SecurityException; - public long lookupSymbol(long libraryHandle, String symbolName); - public long lookupSymbolGlobal(String symbolName); - public void closeLibrary(long libraryHandle); + + /** + * If a {@link SecurityManager} is installed, user needs link permissions + * for <b>all</b> libraries, i.e. for <code>new RuntimePermission("loadLibrary.*");</code>! + * + * @param symbolName global symbol name to lookup up system wide. + * @return the library handle, maybe 0 if not found. + * @throws SecurityException if user is not granted access for all libraries. + */ + public long lookupSymbolGlobal(String symbolName) throws SecurityException; + + /** + * Security checks are implicit by previous call of + * {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)} + * retrieving the <code>librarHandle</code>. + * + * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @param symbolName global symbol name to lookup up system wide. + * @return the library handle, maybe 0 if not found. + * @throws IllegalArgumentException in case case <code>libraryHandle</code> is unknown. + */ + public long lookupSymbol(long libraryHandle, String symbolName) throws IllegalArgumentException; + + /** + * Security checks are implicit by previous call of + * {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)} + * retrieving the <code>librarHandle</code>. + * + * @param libraryHandle a library handle previously retrieved via {@link #openLibraryLocal(String, boolean)} or {@link #openLibraryGlobal(String, boolean)}. + * @throws IllegalArgumentException in case case <code>libraryHandle</code> is unknown. + */ + public void closeLibrary(long libraryHandle) throws IllegalArgumentException; + + /** + * Returns a string containing the last error. + * Maybe called for debuging purposed if any method fails. + * @return error string, maybe null. A null or non-null value has no semantics. + */ public String getLastError(); } diff --git a/src/java/com/jogamp/common/os/NativeLibrary.java b/src/java/com/jogamp/common/os/NativeLibrary.java index 9a86209..3d81479 100644 --- a/src/java/com/jogamp/common/os/NativeLibrary.java +++ b/src/java/com/jogamp/common/os/NativeLibrary.java @@ -76,10 +76,6 @@ public final class NativeLibrary implements DynamicLookupHelper { private static final DynamicLinker dynLink; private static final String[] prefixes; private static final String[] suffixes; - /** TODO: Hide all lookup methods - Then make protected method accessible .. - private static final Method dynLinkLookupLocal; - private static final Method dynLinkLookupGlobal; - */ static { // Instantiate dynamic linker implementation @@ -114,23 +110,6 @@ public final class NativeLibrary implements DynamicLookupHelper { suffixes = new String[] { ".so" }; break; } - - /** TODO: Hide all lookup methods - Then make protected method accessible .. - // public long lookupSymbol(long libraryHandle, String symbolName); - // public long lookupSymbolGlobal(String symbolName); - final Method[] dlLookups = AccessController.doPrivileged(new PrivilegedAction<Method[]>() { - public Method[] run() { - final Method[] ms = new Method[2]; - ms[0] = ReflectionUtil.getMethod(dynLink.getClass(), "lookupSymbol", Long.class, String.class); - ms[0].setAccessible(true); - ms[1] = ReflectionUtil.getMethod(dynLink.getClass(), "lookupSymbolGlobal", String.class); - ms[0].setAccessible(true); - return ms; - } - } ); - dynLinkLookupLocal = dlLookups[0]; - dynLinkLookupGlobal = dlLookups[1]; - */ } // Platform-specific representation for the handle to the open @@ -258,7 +237,6 @@ public final class NativeLibrary implements DynamicLookupHelper { throw new RuntimeException("Library is not open"); } return dynLink.lookupSymbol(libraryHandle, funcName); - // TODO: return ( (Long) ReflectionUtil.callMethod(dynLink, dynLinkLookupLocal, Long.valueOf(libraryHandle), funcName) ).longValue(); } @Override @@ -267,19 +245,16 @@ public final class NativeLibrary implements DynamicLookupHelper { throw new RuntimeException("Library is not open"); } return 0 != dynLink.lookupSymbol(libraryHandle, funcName); - // TODO return 0 != ( (Long) ReflectionUtil.callMethod(dynLink, dynLinkLookupLocal, Long.valueOf(libraryHandle), funcName) ).longValue(); } /** Looks up the given function name in all loaded libraries. */ public static final long dynamicLookupFunctionGlobal(String funcName) { return dynLink.lookupSymbolGlobal(funcName); - // TODO return ( (Long) ReflectionUtil.callMethod(dynLink, dynLinkLookupGlobal, funcName) ).longValue(); } /** Looks up the given function name in all loaded libraries. */ public static final boolean isFunctionAvailableGlobal(String funcName) { return 0 != dynLink.lookupSymbolGlobal(funcName); - // TODO return 0 != ( (Long) ReflectionUtil.callMethod(dynLink, dynLinkLookupGlobal, funcName) ).longValue(); } /** Retrieves the low-level library handle from this NativeLibrary @@ -300,7 +275,7 @@ public final class NativeLibrary implements DynamicLookupHelper { if (DEBUG) { System.err.println("NativeLibrary.close(): closing " + this); } - if (libraryHandle == 0) { + if ( 0 == libraryHandle ) { throw new RuntimeException("Library already closed"); } long handle = libraryHandle; diff --git a/src/java/com/jogamp/common/util/SecurityUtil.java b/src/java/com/jogamp/common/util/SecurityUtil.java index 4d7aa5d..6b35c9c 100644 --- a/src/java/com/jogamp/common/util/SecurityUtil.java +++ b/src/java/com/jogamp/common/util/SecurityUtil.java @@ -142,6 +142,17 @@ public class SecurityUtil { } /** + * Throws an {@link SecurityException} if an installed {@link SecurityManager} + * does not permit to dynamically link to all libraries. + */ + public static final void checkAllLinkPermission() throws SecurityException { + if( null != securityManager ) { + securityManager.checkPermission(allLinkPermission); + } + } + private static final RuntimePermission allLinkPermission = new RuntimePermission("loadLibrary.*"); + + /** * @param clz * @return * @throws SecurityException if the caller has no permission to access the ProtectedDomain of the given class. diff --git a/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java b/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java index b4ae70e..15d884f 100644 --- a/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/BionicDynamicLinkerImpl.java @@ -55,7 +55,13 @@ public final class BionicDynamicLinkerImpl extends UnixDynamicLinkerImpl { // having to dlsym all entry points. System.loadLibrary() uses // RTLD_LOCAL visibility so can't be used for this purpose. SecurityUtil.checkLinkPermission(pathname); - return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + final long handle = dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + if( 0 != handle ) { + incrLibRefCount(handle, pathname); + } else if ( DEBUG || debug ) { + System.err.println("dlopen \""+pathname+"\" local failed, error: "+dlerror()); + } + return handle; } @Override @@ -68,11 +74,18 @@ public final class BionicDynamicLinkerImpl extends UnixDynamicLinkerImpl { // having to dlsym all entry points. System.loadLibrary() uses // RTLD_LOCAL visibility so can't be used for this purpose. SecurityUtil.checkLinkPermission(pathname); - return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + final long handle = dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + if( 0 != handle ) { + incrLibRefCount(handle, pathname); + } else if ( DEBUG || debug ) { + System.err.println("dlopen \""+pathname+"\" global failed, error: "+dlerror()); + } + return handle; } @Override - public final long lookupSymbolGlobal(String symbolName) { + public final long lookupSymbolGlobal(String symbolName) throws SecurityException { + SecurityUtil.checkAllLinkPermission(); final long addr = dlsym(RTLD_DEFAULT, symbolName); if(DEBUG_LOOKUP) { System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr)); diff --git a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java index b0b77ce..beab5d5 100644 --- a/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/MacOSXDynamicLinkerImpl.java @@ -53,7 +53,13 @@ public final class MacOSXDynamicLinkerImpl extends UnixDynamicLinkerImpl { // having to dlsym all entry points. System.loadLibrary() uses // RTLD_LOCAL visibility so can't be used for this purpose. SecurityUtil.checkLinkPermission(pathname); - return dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + final long handle = dlopen(pathname, RTLD_LAZY | RTLD_LOCAL); + if( 0 != handle ) { + incrLibRefCount(handle, pathname); + } else if ( DEBUG || debug ) { + System.err.println("dlopen \""+pathname+"\" local failed, error: "+dlerror()); + } + return handle; } @Override @@ -66,11 +72,18 @@ public final class MacOSXDynamicLinkerImpl extends UnixDynamicLinkerImpl { // having to dlsym all entry points. System.loadLibrary() uses // RTLD_LOCAL visibility so can't be used for this purpose. SecurityUtil.checkLinkPermission(pathname); - return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + final long handle = dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); + if( 0 != handle ) { + incrLibRefCount(handle, pathname); + } else if ( DEBUG || debug ) { + System.err.println("dlopen \""+pathname+"\" global failed, error: "+dlerror()); + } + return handle; } @Override - public final long lookupSymbolGlobal(String symbolName) { + public final long lookupSymbolGlobal(String symbolName) throws SecurityException { + SecurityUtil.checkAllLinkPermission(); final long addr = dlsym(RTLD_DEFAULT, symbolName); if(DEBUG_LOOKUP) { System.err.println("DynamicLinkerImpl.lookupSymbolGlobal("+symbolName+") -> 0x"+Long.toHexString(addr)); diff --git a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java index 1942477..25f4072 100644 --- a/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/UnixDynamicLinkerImpl.java @@ -27,9 +27,7 @@ */ package jogamp.common.os; -import com.jogamp.common.os.DynamicLinker; - -/* pp */ abstract class UnixDynamicLinkerImpl implements DynamicLinker { +/* pp */ abstract class UnixDynamicLinkerImpl extends DynamicLinkerImpl { // // Package private scope of class w/ protected native code access @@ -49,9 +47,11 @@ import com.jogamp.common.os.DynamicLinker; /** Interface to C language function: <br> <code> void * dlsym(void * , const char * ); </code> */ protected static native long dlsym(long arg0, java.lang.String arg1); - @Override - public final long lookupSymbol(long libraryHandle, String symbolName) { + public final long lookupSymbol(long libraryHandle, String symbolName) throws IllegalArgumentException { + if( null == getLibRef( libraryHandle ) ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); + } final long addr = dlsym(libraryHandle, symbolName); if(DEBUG_LOOKUP) { System.err.println("DynamicLinkerImpl.lookupSymbol(0x"+Long.toHexString(libraryHandle)+", "+symbolName+") -> 0x"+Long.toHexString(addr)); @@ -60,7 +60,10 @@ import com.jogamp.common.os.DynamicLinker; } @Override - public final void closeLibrary(long libraryHandle) { + public final void closeLibrary(long libraryHandle) throws IllegalArgumentException { + if( null == decrLibRefCount( libraryHandle ) ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); + } dlclose(libraryHandle); } diff --git a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java index b95f204..adb2492 100644 --- a/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java +++ b/src/java/jogamp/common/os/WindowsDynamicLinkerImpl.java @@ -27,10 +27,9 @@ */ package jogamp.common.os; -import com.jogamp.common.os.DynamicLinker; import com.jogamp.common.util.SecurityUtil; -public final class WindowsDynamicLinkerImpl implements DynamicLinker { +public final class WindowsDynamicLinkerImpl extends DynamicLinkerImpl { /** Interface to C language function: <br> <code> BOOL FreeLibrary(HANDLE hLibModule); </code> */ private static native int FreeLibrary(long hLibModule); @@ -44,7 +43,6 @@ public final class WindowsDynamicLinkerImpl implements DynamicLinker { /** Interface to C language function: <br> <code> HANDLE LoadLibraryW(LPCWSTR lpLibFileName); </code> */ private static native long LoadLibraryW(java.lang.String lpLibFileName); - @Override public final long openLibraryLocal(String libraryName, boolean debug) throws SecurityException { // How does that work under Windows ? @@ -55,8 +53,10 @@ public final class WindowsDynamicLinkerImpl implements DynamicLinker { @Override public final long openLibraryGlobal(String libraryName, boolean debug) throws SecurityException { SecurityUtil.checkLinkPermission(libraryName); - long handle = LoadLibraryW(libraryName); - if(0==handle && debug) { + final long handle = LoadLibraryW(libraryName); + if( 0 != handle ) { + incrLibRefCount(handle, libraryName); + } else if ( DEBUG || debug ) { int err = GetLastError(); System.err.println("LoadLibraryW \""+libraryName+"\" failed, error code: 0x"+Integer.toHexString(err)+", "+err); } @@ -64,7 +64,20 @@ public final class WindowsDynamicLinkerImpl implements DynamicLinker { } @Override - public final long lookupSymbol(long libraryHandle, String symbolName) { + public final long lookupSymbolGlobal(String symbolName) throws SecurityException { + SecurityUtil.checkAllLinkPermission(); + if(DEBUG_LOOKUP) { + System.err.println("lookupSymbolGlobal: Not supported on Windows"); + } + // allow DynamicLibraryBundle to continue w/ local libs + return 0; + } + + @Override + public final long lookupSymbol(long libraryHandle, String symbolName) throws IllegalArgumentException { + if( null == getLibRef( libraryHandle ) ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); + } String _symbolName = symbolName; long addr = GetProcAddressA(libraryHandle, _symbolName); if(0==addr) { @@ -84,16 +97,10 @@ public final class WindowsDynamicLinkerImpl implements DynamicLinker { } @Override - public final long lookupSymbolGlobal(String symbolName) { - if(DEBUG_LOOKUP) { - System.err.println("lookupSymbolGlobal: Not supported on Windows"); + public final void closeLibrary(long libraryHandle) throws IllegalArgumentException { + if( null == decrLibRefCount( libraryHandle ) ) { + throw new IllegalArgumentException("Library handle 0x"+Long.toHexString(libraryHandle)+" unknown."); } - // allow DynamicLibraryBundle to continue w/ local libs - return 0; - } - - @Override - public final void closeLibrary(long libraryHandle) { FreeLibrary(libraryHandle); } |