Properly fix lib loading (builds upon 77bbc4128
)
Also cleaned up OSTailoredCode.cs and fixed qualifiers in Program.cs
This commit is contained in:
parent
9b8db26086
commit
7df71f2c86
|
@ -152,16 +152,16 @@ namespace SevenZip
|
|||
//{
|
||||
// throw new SevenZipLibraryException("DLL file does not exist.");
|
||||
//}
|
||||
if ((_modulePtr = libLoader.LoadPlatformSpecific(_libraryFileName)) == IntPtr.Zero)
|
||||
if ((_modulePtr = libLoader.LoadOrNull(_libraryFileName).Value) == IntPtr.Zero)
|
||||
{
|
||||
//try a different directory
|
||||
string alternateFilename = Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName),"dll"),"7z.dll");
|
||||
if ((_modulePtr = libLoader.LoadPlatformSpecific(alternateFilename)) == IntPtr.Zero)
|
||||
if ((_modulePtr = libLoader.LoadOrNull(_libraryFileName).Value) == IntPtr.Zero)
|
||||
throw new SevenZipLibraryException("failed to load library.");
|
||||
}
|
||||
if (libLoader.GetProcAddr(_modulePtr, "GetHandlerProperty") == IntPtr.Zero)
|
||||
{
|
||||
libLoader.FreePlatformSpecific(_modulePtr);
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
throw new SevenZipLibraryException("library is invalid.");
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ namespace SevenZip
|
|||
if (_totalUsers == 0)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
libLoader.FreePlatformSpecific(_modulePtr);
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
|
||||
#endif
|
||||
_modulePtr = IntPtr.Zero;
|
||||
|
|
|
@ -30,36 +30,33 @@ namespace BizHawk.Client.EmuHawk
|
|||
//try loading libraries we know we'll need
|
||||
//something in the winforms, etc. code below will cause .net to popup a missing msvcr100.dll in case that one's missing
|
||||
//but oddly it lets us proceed and we'll then catch it here
|
||||
var d3dx9 = libLoader.LoadPlatformSpecific("d3dx9_43.dll");
|
||||
var vc2015 = libLoader.LoadPlatformSpecific("vcruntime140.dll");
|
||||
var vc2012 = libLoader.LoadPlatformSpecific("msvcr120.dll"); //TODO - check version?
|
||||
var vc2010 = libLoader.LoadPlatformSpecific("msvcr100.dll"); //TODO - check version?
|
||||
var vc2010p = libLoader.LoadPlatformSpecific("msvcp100.dll");
|
||||
var fail = vc2015 == IntPtr.Zero || vc2010 == IntPtr.Zero || vc2012 == IntPtr.Zero || vc2010p == IntPtr.Zero;
|
||||
var warn = d3dx9 == IntPtr.Zero;
|
||||
if (fail || warn)
|
||||
var d3dx9 = libLoader.LoadOrNull("d3dx9_43.dll");
|
||||
var vc2015 = libLoader.LoadOrNull("vcruntime140.dll");
|
||||
var vc2012 = libLoader.LoadOrNull("msvcr120.dll"); //TODO - check version?
|
||||
var vc2010 = libLoader.LoadOrNull("msvcr100.dll"); //TODO - check version?
|
||||
var vc2010p = libLoader.LoadOrNull("msvcp100.dll");
|
||||
var reqPresent = vc2015.HasValue && vc2010.HasValue && vc2012.HasValue && vc2010p.HasValue;
|
||||
var optPresent = d3dx9.HasValue;
|
||||
if (!reqPresent || !optPresent)
|
||||
{
|
||||
var alertLines = new[]
|
||||
{
|
||||
"[ OK ] .NET CLR (You wouldn't even get here without it)",
|
||||
$"[{(d3dx9 == IntPtr.Zero ? "WARN" : " OK ")}] Direct3d 9",
|
||||
$"[{(vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2010 SP1 Runtime",
|
||||
$"[{(vc2012 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2012 Runtime",
|
||||
$"[{(vc2015 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2015 Runtime"
|
||||
$"[{(d3dx9.HasValue ? " OK " : "WARN")}] Direct3d 9",
|
||||
$"[{(vc2010.HasValue && vc2010p.HasValue ? " OK " : "FAIL")}] Visual C++ 2010 SP1 Runtime",
|
||||
$"[{(vc2012.HasValue ? " OK " : "FAIL")}] Visual C++ 2012 Runtime",
|
||||
$"[{(vc2015.HasValue ? " OK " : "FAIL")}] Visual C++ 2015 Runtime"
|
||||
};
|
||||
var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail)
|
||||
var box = new CustomControls.PrereqsAlert(reqPresent)
|
||||
{
|
||||
textBox1 = { Text = string.Join(Environment.NewLine, alertLines) }
|
||||
};
|
||||
box.ShowDialog();
|
||||
if (fail) System.Diagnostics.Process.GetCurrentProcess().Kill();
|
||||
if (!reqPresent) Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
libLoader.FreePlatformSpecific(d3dx9);
|
||||
libLoader.FreePlatformSpecific(vc2015);
|
||||
libLoader.FreePlatformSpecific(vc2012);
|
||||
libLoader.FreePlatformSpecific(vc2010);
|
||||
libLoader.FreePlatformSpecific(vc2010p);
|
||||
foreach (var p in new[] { d3dx9, vc2015, vc2012, vc2010, vc2010p })
|
||||
if (p.HasValue) libLoader.FreeByPtr(p.Value);
|
||||
|
||||
// this will look in subdirectory "dll" to load pinvoked stuff
|
||||
var dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
|
||||
|
@ -110,7 +107,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
BizHawk.Common.TempFileManager.Start();
|
||||
TempFileManager.Start();
|
||||
|
||||
HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler();
|
||||
|
||||
|
@ -129,8 +126,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
Global.Config.ResolveDefaults();
|
||||
|
||||
BizHawk.Client.Common.StringLogUtil.DefaultToDisk = Global.Config.MoviesOnDisk;
|
||||
BizHawk.Client.Common.StringLogUtil.DefaultToAWE = Global.Config.MoviesInAWE;
|
||||
StringLogUtil.DefaultToDisk = Global.Config.MoviesOnDisk;
|
||||
StringLogUtil.DefaultToAWE = Global.Config.MoviesInAWE;
|
||||
|
||||
// super hacky! this needs to be done first. still not worth the trouble to make this system fully proper
|
||||
if (Array.Exists(args, arg => arg.StartsWith("--gdi", StringComparison.InvariantCultureIgnoreCase)))
|
||||
|
|
|
@ -5,15 +5,15 @@ using BizHawk.Common;
|
|||
|
||||
namespace BizHawk.Common.BizInvoke
|
||||
{
|
||||
/// TODO move this and all in IImportResolver.cs to OSTailoredCode.cs and refactor
|
||||
public class DynamicLibraryImportResolver : IImportResolver, IDisposable
|
||||
{
|
||||
private IntPtr _p;
|
||||
private readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager;
|
||||
private readonly OSTailoredCode.ILinkedLibManager libLoader = OSTailoredCode.LinkedLibManager; //TODO inline?
|
||||
|
||||
public DynamicLibraryImportResolver(string dllName)
|
||||
{
|
||||
_p = libLoader.LoadPlatformSpecific(dllName);
|
||||
if (_p == IntPtr.Zero) throw new InvalidOperationException($"null pointer returned by {nameof(libLoader.LoadPlatformSpecific)}");
|
||||
_p = libLoader.LoadOrThrow(dllName);
|
||||
}
|
||||
|
||||
public IntPtr Resolve(string entryPoint)
|
||||
|
@ -23,8 +23,8 @@ namespace BizHawk.Common.BizInvoke
|
|||
|
||||
private void Free()
|
||||
{
|
||||
if (_p == IntPtr.Zero) return;
|
||||
libLoader.FreePlatformSpecific(_p);
|
||||
if (_p == IntPtr.Zero) return; // already freed
|
||||
libLoader.FreeByPtr(_p);
|
||||
_p = IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,13 @@ namespace BizHawk.Common
|
|||
|
||||
public static ILinkedLibManager LinkedLibManager => _LinkedLibManager.Value;
|
||||
|
||||
/// <remarks>this interface's inheritors hide OS-specific implementation details</remarks>
|
||||
public interface ILinkedLibManager
|
||||
{
|
||||
IntPtr LoadPlatformSpecific(string dllToLoad);
|
||||
IntPtr GetProcAddr(IntPtr hModule, string procName);
|
||||
int FreePlatformSpecific(IntPtr hModule);
|
||||
IntPtr? LoadOrNull(string dllToLoad);
|
||||
IntPtr LoadOrThrow(string dllToLoad);
|
||||
IntPtr GetProcAddr(IntPtr hModule, string procName); //TODO also split into nullable and throwing?
|
||||
int FreeByPtr(IntPtr hModule);
|
||||
}
|
||||
|
||||
/// <remarks>This class is copied from a tutorial, so don't git blame and then email me expecting insight.</remarks>
|
||||
|
@ -43,41 +45,67 @@ namespace BizHawk.Common
|
|||
{
|
||||
private const int RTLD_NOW = 2;
|
||||
[DllImport("libdl.so.2")]
|
||||
private static extern IntPtr dlopen(string fileName, int flags);
|
||||
private static extern int dlclose(IntPtr handle);
|
||||
[DllImport("libdl.so.2")]
|
||||
private static extern IntPtr dlerror();
|
||||
[DllImport("libdl.so.2")]
|
||||
private static extern IntPtr dlsym(IntPtr handle, string symbol);
|
||||
private static extern IntPtr dlopen(string fileName, int flags);
|
||||
[DllImport("libdl.so.2")]
|
||||
private static extern int dlclose(IntPtr handle);
|
||||
private static extern IntPtr dlsym(IntPtr handle, string symbol);
|
||||
|
||||
public IntPtr LoadPlatformSpecific(string dllToLoad) => dlopen(dllToLoad, RTLD_NOW);
|
||||
public IntPtr GetProcAddr(IntPtr hModule, string procName)
|
||||
{
|
||||
dlerror();
|
||||
var res = dlsym(hModule, procName);
|
||||
var errPtr = dlerror();
|
||||
if (errPtr != IntPtr.Zero) throw new InvalidOperationException($"error in dlsym: {Marshal.PtrToStringAnsi(errPtr)}");
|
||||
if (errPtr != IntPtr.Zero) throw new InvalidOperationException($"error in {nameof(dlsym)}: {Marshal.PtrToStringAnsi(errPtr)}");
|
||||
return res;
|
||||
}
|
||||
public int FreePlatformSpecific(IntPtr hModule) => dlclose(hModule);
|
||||
|
||||
public int FreeByPtr(IntPtr hModule) => dlclose(hModule);
|
||||
|
||||
public IntPtr? LoadOrNull(string dllToLoad)
|
||||
{
|
||||
var p = dlopen(dllToLoad, RTLD_NOW);
|
||||
return p == IntPtr.Zero ? default(IntPtr?) : p;
|
||||
}
|
||||
|
||||
public IntPtr LoadOrThrow(string dllToLoad)
|
||||
{
|
||||
var p = LoadOrNull(dllToLoad);
|
||||
if (!p.HasValue) throw new InvalidOperationException($"got null pointer from {nameof(dlopen)}, error: {Marshal.PtrToStringAnsi(dlerror())}");
|
||||
return p.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private class WindowsLLManager : ILinkedLibManager
|
||||
{
|
||||
// comments reference extern functions removed from SevenZip.NativeMethods
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr hModule); // return type was annotated MarshalAs(UnmanagedType.Bool)
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern uint GetLastError();
|
||||
[DllImport("kernel32.dll")] // had BestFitMapping = false, ThrowOnUnmappableChar = true
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad); // param dllToLoad was annotated `[MarshalAs(UnmanagedType.LPStr)]`
|
||||
[DllImport("kernel32.dll")] // had BestFitMapping = false, ThrowOnUnmappableChar = true
|
||||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); // param procName was annotated `[MarshalAs(UnmanagedType.LPStr)]`
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool FreeLibrary(IntPtr hModule); // return type was annotated MarshalAs(UnmanagedType.Bool)
|
||||
[DllImport("kernel32.dll")] // had BestFitMapping = false, ThrowOnUnmappableChar = true
|
||||
private static extern IntPtr LoadLibrary(string dllToLoad); // param dllToLoad was annotated `[MarshalAs(UnmanagedType.LPStr)]`
|
||||
|
||||
public IntPtr LoadPlatformSpecific(string dllToLoad) => LoadLibrary(dllToLoad);
|
||||
public IntPtr GetProcAddr(IntPtr hModule, string procName) => GetProcAddress(hModule, procName);
|
||||
public int FreePlatformSpecific(IntPtr hModule) => FreeLibrary(hModule) ? 1 : 0;
|
||||
|
||||
public int FreeByPtr(IntPtr hModule) => FreeLibrary(hModule) ? 1 : 0;
|
||||
|
||||
public IntPtr? LoadOrNull(string dllToLoad)
|
||||
{
|
||||
var p = LoadLibrary(dllToLoad);
|
||||
return p == IntPtr.Zero ? default(IntPtr?) : p;
|
||||
}
|
||||
|
||||
public IntPtr LoadOrThrow(string dllToLoad)
|
||||
{
|
||||
var p = LoadOrNull(dllToLoad);
|
||||
if (!p.HasValue) throw new InvalidOperationException($"got null pointer from {nameof(LoadLibrary)}, error code: {GetLastError()}");
|
||||
return p.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DistinctOS : byte
|
||||
|
@ -91,7 +119,7 @@ namespace BizHawk.Common
|
|||
/// <param name="args">POSIX <c>$*</c> (space-delimited)</param>
|
||||
/// <param name="checkStdout">stdout is discarded if false</param>
|
||||
/// <param name="checkStderr">stderr is discarded if false</param>
|
||||
/// <remarks>OS is implicit and needs to be checked at callsite, returned <see cref="Process"/> has not been started</remarks>
|
||||
/// <remarks>OS is implicit and needs to be checked at callsite. Returned <see cref="Process"/> has not been started.</remarks>
|
||||
public static Process ConstructSubshell(string cmd, string args, bool checkStdout = true, bool checkStderr = false) =>
|
||||
new Process {
|
||||
StartInfo = new ProcessStartInfo {
|
||||
|
|
|
@ -484,9 +484,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
}
|
||||
this.bizhawkCore = bizhawkCore;
|
||||
|
||||
CoreDll = libLoader.LoadPlatformSpecific("mupen64plus");
|
||||
if (CoreDll == IntPtr.Zero)
|
||||
throw new InvalidOperationException("Failed to load mupen64plus.dll");
|
||||
CoreDll = libLoader.LoadOrThrow("mupen64plus");
|
||||
|
||||
connectFunctionPointers();
|
||||
|
||||
|
@ -914,7 +912,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
|
||||
m64pCoreDoCommandPtr(m64p_command.M64CMD_ROM_CLOSE, 0, IntPtr.Zero);
|
||||
m64pCoreShutdown();
|
||||
libLoader.FreePlatformSpecific(CoreDll);
|
||||
libLoader.FreeByPtr(CoreDll);
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
@ -934,10 +932,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
DetachPlugin(type);
|
||||
|
||||
AttachedPlugin plugin;
|
||||
plugin.dllHandle = libLoader.LoadPlatformSpecific(PluginName);
|
||||
if (plugin.dllHandle == IntPtr.Zero)
|
||||
throw new InvalidOperationException($"Failed to load plugin {PluginName}");
|
||||
|
||||
plugin.dllHandle = libLoader.LoadOrThrow(PluginName);
|
||||
plugin.dllStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginStartup"), typeof(PluginStartup));
|
||||
plugin.dllShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(libLoader.GetProcAddr(plugin.dllHandle, "PluginShutdown"), typeof(PluginShutdown));
|
||||
plugin.dllStartup(CoreDll, null, null);
|
||||
|
@ -945,7 +940,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
m64p_error result = m64pCoreAttachPlugin(type, plugin.dllHandle);
|
||||
if (result != m64p_error.M64ERR_SUCCESS)
|
||||
{
|
||||
libLoader.FreePlatformSpecific(plugin.dllHandle);
|
||||
libLoader.FreeByPtr(plugin.dllHandle);
|
||||
throw new InvalidOperationException($"Error during attaching plugin {PluginName}");
|
||||
}
|
||||
|
||||
|
@ -961,7 +956,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
plugins.Remove(type);
|
||||
m64pCoreDetachPlugin(type);
|
||||
plugin.dllShutdown();
|
||||
libLoader.FreePlatformSpecific(plugin.dllHandle);
|
||||
libLoader.FreeByPtr(plugin.dllHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue