|
| 1 | +#include <stdbool.h> |
| 2 | +#include <stddef.h> |
| 3 | + |
| 4 | +#if defined(_WIN32) |
| 5 | +# if defined(_MSC_VER) |
| 6 | +# pragma warning(push) |
| 7 | +# pragma warning(disable : 4255) |
| 8 | +# pragma warning(disable : 4668) |
| 9 | +# endif |
| 10 | + |
| 11 | +# include <windows.h> |
| 12 | +# include <stdio.h> |
| 13 | + |
| 14 | +# if defined(_MSC_VER) |
| 15 | +# pragma warning(pop) |
| 16 | +# endif |
| 17 | + |
| 18 | +inline static void * getlib(void) |
| 19 | +{ |
| 20 | + void * ret_val = LoadLibraryW(L"asar.dll"); |
| 21 | + |
| 22 | + if (ret_val == NULL) |
| 23 | + { |
| 24 | + // TODO: Add a better method of error checking? This won't do much for people who are using |
| 25 | + // Asar with a GUI application, they probably won't see this error output. |
| 26 | + char buf[1024]; |
| 27 | + sprintf(buf, "Failed to load Asar DLL! HRESULT: 0x%08x\n", (unsigned int)HRESULT_FROM_WIN32(GetLastError())); |
| 28 | + printf("%s", buf); |
| 29 | + OutputDebugStringA(buf); |
| 30 | + } |
| 31 | + |
| 32 | + return ret_val; |
| 33 | +} |
| 34 | + |
| 35 | +inline static void * getlibfrompath(const char * path) |
| 36 | +{ |
| 37 | + int required_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); |
| 38 | + if (required_size <= 0) return NULL; |
| 39 | + |
| 40 | + wchar_t* path_buf = (wchar_t*)malloc((size_t)required_size * sizeof(wchar_t)); |
| 41 | + if (path_buf == NULL) return NULL; |
| 42 | + |
| 43 | + int converted_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, path_buf, required_size); |
| 44 | + |
| 45 | + if (converted_size == 0) |
| 46 | + { |
| 47 | + return NULL; |
| 48 | + } |
| 49 | + |
| 50 | + void * ret_val = LoadLibraryW(path_buf); |
| 51 | + free(path_buf); |
| 52 | + |
| 53 | + if (ret_val == NULL) |
| 54 | + { |
| 55 | + // TODO: Add a better method of error checking? This won't do much for people who are using |
| 56 | + // Asar with a GUI application, they probably won't see this error output. |
| 57 | + char buf[1024]; |
| 58 | + sprintf(buf, "Failed to load Asar DLL! HRESULT: 0x%08x\n", (unsigned int)HRESULT_FROM_WIN32(GetLastError())); |
| 59 | + printf("%s", buf); |
| 60 | + OutputDebugStringA(buf); |
| 61 | + } |
| 62 | + |
| 63 | + return ret_val; |
| 64 | +} |
| 65 | + |
| 66 | +inline static bool setfunction(void* target, FARPROC fn) |
| 67 | +{ |
| 68 | + memcpy(target, &fn, sizeof(fn)); |
| 69 | + return fn; |
| 70 | +} |
| 71 | +# define loadraw(name, target) require(setfunction(&target, GetProcAddress((HINSTANCE)asardll, name))) |
| 72 | +# define closelib(var) FreeLibrary((HINSTANCE)var) |
| 73 | +#else |
| 74 | +# include <dlfcn.h> |
| 75 | +# include <stdio.h> |
| 76 | + |
| 77 | +# ifdef __APPLE__ |
| 78 | +# define EXTENSION ".dylib" |
| 79 | +# else |
| 80 | +# define EXTENSION ".so" |
| 81 | +# endif |
| 82 | + |
| 83 | + inline static void * getlib(void) |
| 84 | + { |
| 85 | + const char * names[]={"./libasar"EXTENSION, "libasar", NULL}; |
| 86 | + for (int i=0;names[i];i++) |
| 87 | + { |
| 88 | + void * rval=dlopen(names[i], RTLD_LAZY); |
| 89 | + const char*e=dlerror(); |
| 90 | + if(e)puts(e); |
| 91 | + if (rval) return rval; |
| 92 | + } |
| 93 | + return NULL; |
| 94 | + } |
| 95 | + |
| 96 | + inline static void * getlibfrompath(const char * path) |
| 97 | + { |
| 98 | + void * rval = dlopen(path, RTLD_LAZY); |
| 99 | + const char*e = dlerror(); |
| 100 | + if (e)puts(e); |
| 101 | + if (rval) return rval; |
| 102 | + return NULL; |
| 103 | + } |
| 104 | + |
| 105 | +# define loadraw(name, target) *(void **)(&target)=dlsym(asardll, name); require(target) |
| 106 | +# define closelib(var) dlclose(var) |
| 107 | +#endif |
| 108 | + |
| 109 | +#include "asardll.h" |
| 110 | + |
| 111 | +static void * asardll=NULL; |
| 112 | + |
| 113 | +static bool (*asar_i_init)(void); |
| 114 | +static void(*asar_i_close)(void); |
| 115 | +$FUNCTIONPROTOS$ |
| 116 | + |
| 117 | +#define require(b) if (!(b)) { asardll=NULL; return false; } |
| 118 | + |
| 119 | +static bool asar_init_shared(void) |
| 120 | +{ |
| 121 | + loadraw("asar_init", asar_i_init); |
| 122 | + loadraw("asar_close", asar_i_close); |
| 123 | +$FUNCTIONLOADS$ |
| 124 | + if (asar_apiversion() < expectedapiversion || (asar_apiversion() / 100) > (expectedapiversion / 100)) return false; |
| 125 | + require(asar_i_init()); |
| 126 | + return true; |
| 127 | +} |
| 128 | + |
| 129 | +bool asar_init(void) |
| 130 | +{ |
| 131 | + if (asardll) return true; |
| 132 | + asardll=getlib(); |
| 133 | + require(asardll); |
| 134 | + if (!asar_init_shared()) return false; |
| 135 | + return true; |
| 136 | +} |
| 137 | + |
| 138 | +bool asar_init_with_dll_path(const char * dllpath) |
| 139 | +{ |
| 140 | + if (asardll) return true; |
| 141 | + asardll = getlibfrompath(dllpath); |
| 142 | + require(asardll); |
| 143 | + if (!asar_init_shared()) return false; |
| 144 | + return true; |
| 145 | +} |
| 146 | + |
| 147 | +void asar_close(void) |
| 148 | +{ |
| 149 | + if (!asardll) return; |
| 150 | + asar_i_close(); |
| 151 | + closelib(asardll); |
| 152 | + asardll=NULL; |
| 153 | +} |
0 commit comments