Files
SteamAchievementManager/SAM.API/Steam.cs
2017-11-24 08:56:38 -06:00

152 lines
5.2 KiB
C#

/* Copyright (c) 2017 Rick (rick 'at' gibbed 'dot' us)
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace SAM.API
{
public static class Steam
{
private struct Native
{
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr module, string name);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr LoadLibraryEx(string path, IntPtr file, uint flags);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr SetDllDirectory(string path);
internal const uint LoadWithAlteredSearchPath = 8;
}
private static Delegate GetExportDelegate<TDelegate>(IntPtr module, string name)
{
IntPtr address = Native.GetProcAddress(module, name);
return address == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer(address, typeof(TDelegate));
}
private static TDelegate GetExportFunction<TDelegate>(IntPtr module, string name)
where TDelegate : class
{
return (TDelegate)((object)GetExportDelegate<TDelegate>(module, name));
}
private static IntPtr _Handle = IntPtr.Zero;
public static string GetInstallPath()
{
return (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\Valve\Steam", "InstallPath", null);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate IntPtr NativeCreateInterface(string version, IntPtr returnCode);
private static NativeCreateInterface _CallCreateInterface;
public static TClass CreateInterface<TClass>(string version)
where TClass : INativeWrapper, new()
{
IntPtr address = _CallCreateInterface(version, IntPtr.Zero);
if (address == IntPtr.Zero)
{
return default(TClass);
}
var rez = new TClass();
rez.SetupFunctions(address);
return rez;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private delegate bool NativeSteamGetCallback(int pipe, out Types.CallbackMessage message, out int call);
private static NativeSteamGetCallback _CallSteamBGetCallback;
public static bool GetCallback(int pipe, out Types.CallbackMessage message, out int call)
{
return _CallSteamBGetCallback(pipe, out message, out call);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
private delegate bool NativeSteamFreeLastCallback(int pipe);
private static NativeSteamFreeLastCallback _CallSteamFreeLastCallback;
public static bool FreeLastCallback(int pipe)
{
return _CallSteamFreeLastCallback(pipe);
}
public static bool Load()
{
if (_Handle != IntPtr.Zero)
{
return true;
}
string path = GetInstallPath();
if (path == null)
{
return false;
}
Native.SetDllDirectory(path + ";" + Path.Combine(path, "bin"));
path = Path.Combine(path, "steamclient.dll");
IntPtr module = Native.LoadLibraryEx(path, IntPtr.Zero, Native.LoadWithAlteredSearchPath);
if (module == IntPtr.Zero)
{
return false;
}
_CallCreateInterface = GetExportFunction<NativeCreateInterface>(module, "CreateInterface");
if (_CallCreateInterface == null)
{
return false;
}
_CallSteamBGetCallback = GetExportFunction<NativeSteamGetCallback>(module, "Steam_BGetCallback");
if (_CallSteamBGetCallback == null)
{
return false;
}
_CallSteamFreeLastCallback = GetExportFunction<NativeSteamFreeLastCallback>(module, "Steam_FreeLastCallback");
if (_CallSteamFreeLastCallback == null)
{
return false;
}
_Handle = module;
return true;
}
}
}