From 0884dccfa70ccbb857e44e250fb772931e479580 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Thu, 2 Nov 2017 20:15:22 +0100 Subject: [PATCH 01/14] Update mingw -dev package for Trusty. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3c45d20..737c970 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,8 @@ addons: - binutils-mingw-w64-i686 - binutils-mingw-w64-x86-64 - cmake - - mingw-w64-dev + - mingw-w64-i686-dev + - mingw-w64-x86-64-dev - g++-mingw-w64-i686 - g++-mingw-w64-x86-64 - gcc-mingw-w64-i686 From 98b95eca4cc467fedded96386bcadaba3addf18e Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Thu, 2 Nov 2017 21:02:26 +0100 Subject: [PATCH 02/14] Implement binary search for looking up exports by name. Code based on #74 which contained code from py2exe. --- MemoryModule.c | 73 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/MemoryModule.c b/MemoryModule.c index cf38388..59a5844 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -22,6 +22,12 @@ * Portions created by Joachim Bauch are Copyright (C) 2004-2015 * Joachim Bauch. All Rights Reserved. * + * + * THeller: Added binary search in MemoryGetProcAddress function + * (#define USE_BINARY_SEARCH to enable it). This gives a very large + * speedup for libraries that exports lots of functions. + * + * These portions are Copyright (C) 2013 Thomas Heller. */ #include @@ -56,6 +62,11 @@ #include "MemoryModule.h" +struct ExportNameEntry { + LPCSTR name; + WORD idx; +}; + typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); typedef int (WINAPI *ExeEntryProc)(void); @@ -72,6 +83,7 @@ typedef struct { CustomLoadLibraryFunc loadLibrary; CustomGetProcAddressFunc getProcAddress; CustomFreeLibraryFunc freeLibrary; + struct ExportNameEntry *nameExportsTable; void *userdata; ExeEntryProc exeEntry; DWORD pageSize; @@ -688,12 +700,27 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size, return NULL; } -FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name) +static int _compare(const void *a, const void *b) +{ + const struct ExportNameEntry *p1 = (const struct ExportNameEntry*) a; + const struct ExportNameEntry *p2 = (const struct ExportNameEntry*) b; + return _stricmp(p1->name, p2->name); +} + +static int _find(const void *a, const void *b) +{ + LPCSTR *name = (LPCSTR *) a; + const struct ExportNameEntry *p = (const struct ExportNameEntry*) b; + return _stricmp(*name, p->name); +} + +FARPROC MemoryGetProcAddress(HMEMORYMODULE mod, LPCSTR name) { - unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; + PMEMORYMODULE module = (PMEMORYMODULE)mod; + unsigned char *codeBase = module->codeBase; DWORD idx = 0; PIMAGE_EXPORT_DIRECTORY exports; - PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); + PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT); if (directory->Size == 0) { // no export table found SetLastError(ERROR_PROC_NOT_FOUND); @@ -715,25 +742,44 @@ FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name) } idx = LOWORD(name) - exports->Base; + } else if (!exports->NumberOfNames) { + SetLastError(ERROR_PROC_NOT_FOUND); + return NULL; } else { - // search function name in list of exported names - DWORD i; - DWORD *nameRef = (DWORD *) (codeBase + exports->AddressOfNames); - WORD *ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); - BOOL found = FALSE; - for (i=0; iNumberOfNames; i++, nameRef++, ordinal++) { - if (_stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) { - idx = *ordinal; - found = TRUE; - break; + const struct ExportNameEntry *found; + + // Lazily build name table and sort it by names + if (!module->nameExportsTable) { + DWORD i; + DWORD *nameRef = (DWORD *) (codeBase + exports->AddressOfNames); + WORD *ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals); + struct ExportNameEntry *entry = (struct ExportNameEntry*) malloc(exports->NumberOfNames * sizeof(struct ExportNameEntry)); + module->nameExportsTable = entry; + if (!entry) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; } + for (i=0; iNumberOfNames; i++, nameRef++, ordinal++, entry++) { + entry->name = (const char *) (codeBase + (*nameRef)); + entry->idx = *ordinal; + } + qsort(module->nameExportsTable, + exports->NumberOfNames, + sizeof(struct ExportNameEntry), _compare); } + // search function name in list of exported names with binary search + found = (const struct ExportNameEntry*) bsearch(&name, + module->nameExportsTable, + exports->NumberOfNames, + sizeof(struct ExportNameEntry), _find); if (!found) { // exported symbol not found SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } + + idx = found->idx; } if (idx > exports->NumberOfFunctions) { @@ -759,6 +805,7 @@ void MemoryFreeLibrary(HMEMORYMODULE mod) (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0); } + free(module->nameExportsTable); if (module->modules != NULL) { // free previously opened libraries int i; From ac78ea10e7ba666ae24b753a1564c8c93ccff4bd Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Thu, 2 Nov 2017 21:37:14 +0100 Subject: [PATCH 03/14] Add test that loads a dll with lots of exports. --- .gitignore | 3 ++ tests/LoadDll.cpp | 75 +++++++++++++++++++++++++++++++++++++-- tests/Makefile | 7 ++++ tests/generate-exports.sh | 52 +++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 2 deletions(-) create mode 100755 tests/generate-exports.sh diff --git a/.gitignore b/.gitignore index 6c07d24..508c3dc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ *.exe tests/*.dll tests/*.res + +tests/SampleExports.cpp +tests/SampleExports.h diff --git a/tests/LoadDll.cpp b/tests/LoadDll.cpp index 07a2538..8cb215b 100644 --- a/tests/LoadDll.cpp +++ b/tests/LoadDll.cpp @@ -11,6 +11,7 @@ #include "../MemoryModule.h" +typedef int (*addProc)(int); typedef int (*addNumberProc)(int, int); // Thanks to Tim Cooper (from http://stackoverflow.com/a/8584708) @@ -127,6 +128,11 @@ BOOL LoadFromMemory(char *filename) } addNumber = (addNumberProc)MemoryGetProcAddress(handle, "addNumbers"); + if (!addNumber) { + _tprintf(_T("MemoryGetProcAddress(\"addNumber\") returned NULL\n")); + result = FALSE; + goto exit; + } _tprintf(_T("From memory: %d\n"), addNumber(1, 2)); // the DLL only exports one function, try to load by ordinal value @@ -218,6 +224,65 @@ BOOL LoadFromMemory(char *filename) return result; } +BOOL LoadExportsFromMemory(char *filename) +{ + FILE *fp; + unsigned char *data=NULL; + long size; + size_t read; + HMEMORYMODULE handle = NULL; + int i; + BOOL result = TRUE; + + fp = fopen(filename, "rb"); + if (fp == NULL) + { + printf("Can't open DLL file \"%s\".", filename); + result = FALSE; + goto exit; + } + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + assert(size > 0); + data = (unsigned char *)malloc(size); + assert(data != NULL); + fseek(fp, 0, SEEK_SET); + read = fread(data, 1, size, fp); + assert(read == static_cast(size)); + fclose(fp); + + handle = MemoryLoadLibrary(data, size); + if (handle == NULL) + { + _tprintf(_T("Can't load library from memory.\n")); + result = FALSE; + goto exit; + } + + for (i = 1; i <= 100; i++) { + char name[100]; + sprintf(name, "add%d", i); + addProc addNumber = (addProc)MemoryGetProcAddress(handle, name); + if (!addNumber) { + _tprintf(_T("MemoryGetProcAddress(\"%s\") returned NULL\n"), name); + result = FALSE; + goto exit; + } + int result = addNumber(1); + if (result != 1 + i) { + _tprintf(_T("(\"%s\") returned %d, expected %d\n"), name, result, 1 + i); + result = FALSE; + goto exit; + } + _tprintf(_T("%s: %d\n"), name, result); + } +exit: + MemoryFreeLibrary(handle); + free(data); + return result; +} + int main(int argc, char* argv[]) { if (argc < 2) { @@ -225,8 +290,14 @@ int main(int argc, char* argv[]) return 1; } - if (!LoadFromMemory(argv[1])) { - return 2; + if (!strstr((const char *) argv[1], "exports")) { + if (!LoadFromMemory(argv[1])) { + return 2; + } + } else { + if (!LoadExportsFromMemory(argv[1])) { + return 2; + } } return 0; diff --git a/tests/Makefile b/tests/Makefile index 626611f..014cc80 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -47,6 +47,7 @@ TEST_DLLS = \ test-align-800.dll \ test-align-900.dll \ test-relocate.dll \ + test-exports.dll LOADDLL_OBJ = LoadDll.o ../MemoryModule.o TESTSUITE_OBJ = TestSuite.o ../MemoryModule.o @@ -72,6 +73,12 @@ test-align-%.dll: $(DLL_OBJ) test-relocate.dll: $(DLL_OBJ) $(CXX) $(LDFLAGS_DLL) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o $@ $(DLL_OBJ) +test-exports.dll: SampleExports.o + $(CXX) $(LDFLAGS_DLL) $(LDFLAGS) -o $@ SampleExports.o + +SampleExports.cpp: generate-exports.sh + ./generate-exports.sh + %.o: %.cpp $(CXX) $(CFLAGS) $(CFLAGS_DLL) -c $< diff --git a/tests/generate-exports.sh b/tests/generate-exports.sh new file mode 100755 index 0000000..974b2a6 --- /dev/null +++ b/tests/generate-exports.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +## +## Generate header file. +## + +cat > SampleExports.h << EOF +extern "C" { + +#ifdef SAMPLEDLL_EXPORTS +#define SAMPLEDLL_API __declspec(dllexport) +#else +#define SAMPLEDLL_API __declspec(dllimport) +#endif + +EOF + +for i in `seq 1 100`; +do +cat >> SampleExports.h << EOF +SAMPLEDLL_API int add$i(int a); +EOF +done + +cat >> SampleExports.h << EOF +} +EOF + + +## +## Generate source file. +## + +cat > SampleExports.cpp << EOF +#include "SampleExports.h" + +extern "C" { +EOF + +for i in `seq 1 100 | sort -R`; +do +cat >> SampleExports.cpp << EOF +SAMPLEDLL_API int add$i(int a) +{ + return a + $i; +} +EOF +done + +cat >> SampleExports.cpp << EOF +} +EOF From 9e295953a8b056036525c4274fb1ddf91dbb85c7 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 20:31:28 +0100 Subject: [PATCH 04/14] Prevent memory of library from spanning over 4GB bounaries. Based on code from #67 / #79, fixes #63. --- MemoryModule.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/MemoryModule.c b/MemoryModule.c index 59a5844..05646e1 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -70,6 +70,13 @@ struct ExportNameEntry { typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); typedef int (WINAPI *ExeEntryProc)(void); +#ifdef _WIN64 +typedef struct POINTER_LIST { + struct POINTER_LIST *next; + void *address; +} POINTER_LIST; +#endif + typedef struct { PIMAGE_NT_HEADERS headers; unsigned char *codeBase; @@ -87,6 +94,9 @@ typedef struct { void *userdata; ExeEntryProc exeEntry; DWORD pageSize; +#ifdef _WIN64 + POINTER_LIST *blockedMemory; +#endif } MEMORYMODULE, *PMEMORYMODULE; typedef struct { @@ -137,6 +147,21 @@ OutputLastError(const char *msg) #endif } +#ifdef _WIN64 +static void +FreePointerList(POINTER_LIST *head, CustomFreeFunc freeMemory, void *userdata) +{ + POINTER_LIST *node = head; + while (node) { + POINTER_LIST *next; + freeMemory(node->address, 0, MEM_RELEASE, userdata); + next = node->next; + free(node); + node = next; + } +} +#endif + static BOOL CheckSize(size_t size, size_t expected) { if (size < expected) { @@ -535,6 +560,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size, size_t optionalSectionSize; size_t lastSectionEnd = 0; size_t alignedImageSize; +#ifdef _WIN64 + POINTER_LIST *blockedMemory = NULL; +#endif if (!CheckSize(size, sizeof(IMAGE_DOS_HEADER))) { return NULL; @@ -610,9 +638,40 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size, } } +#ifdef _WIN64 + // Memory block may not span 4 GB boundaries. + while ((((uintptr_t) code) >> 32) < (((uintptr_t) (code + alignedImageSize)) >> 32)) { + POINTER_LIST *node = (POINTER_LIST*) malloc(sizeof(POINTER_LIST)); + if (!node) { + freeMemory(code, 0, MEM_RELEASE, userdata); + FreePointerList(blockedMemory, freeMemory, userdata); + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + + node->next = blockedMemory; + node->address = code; + blockedMemory = node; + + code = (unsigned char *)allocMemory(NULL, + alignedImageSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE, + userdata); + if (code == NULL) { + FreePointerList(blockedMemory, freeMemory, userdata); + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } + } +#endif + result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MEMORYMODULE)); if (result == NULL) { freeMemory(code, 0, MEM_RELEASE, userdata); +#ifdef _WIN64 + FreePointerList(blockedMemory, freeMemory, userdata); +#endif SetLastError(ERROR_OUTOFMEMORY); return NULL; } @@ -626,6 +685,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size, result->freeLibrary = freeLibrary; result->userdata = userdata; result->pageSize = sysInfo.dwPageSize; +#ifdef _WIN64 + result->blockedMemory = blockedMemory; +#endif if (!CheckSize(size, old_header->OptionalHeader.SizeOfHeaders)) { goto error; @@ -823,6 +885,9 @@ void MemoryFreeLibrary(HMEMORYMODULE mod) module->free(module->codeBase, 0, MEM_RELEASE, module->userdata); } +#ifdef _WIN64 + FreePointerList(module->blockedMemory, module->free, module->userdata); +#endif HeapFree(GetProcessHeap(), 0, module); } From 9ecfeb025d9d13160038518df7dc69973fb6ee0f Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 20:41:25 +0100 Subject: [PATCH 05/14] Remove all object files on clean. --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 014cc80..028bcad 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -89,7 +89,7 @@ SampleExports.cpp: generate-exports.sh $(RC) $(RCFLAGS) -o $*.res $< clean: - $(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ) + $(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ) $(TESTSUITE_OBJ) SampleExports.o test: all ./runwine.sh $(PLATFORM) TestSuite.exe From 663ddca84b9ef35ca6fd1e705599f30d8d1cda32 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 20:49:55 +0100 Subject: [PATCH 06/14] Update WINEPATH for Trusty. --- tests/runwine.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/runwine.sh b/tests/runwine.sh index eaee1fc..c56fa27 100755 --- a/tests/runwine.sh +++ b/tests/runwine.sh @@ -10,6 +10,6 @@ else export WINEPREFIX=${HOME}/.wine/ WINE=wine fi -export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.6/ +export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.8/;/usr/${PLATFORM}-w64-mingw32/lib exec ${WINE} $@ From 0acf4e7785d547ac37ddbf339aa00cb4f7a2b07d Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 20:52:52 +0100 Subject: [PATCH 07/14] Fix typo. --- tests/runwine.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/runwine.sh b/tests/runwine.sh index c56fa27..826b8c3 100755 --- a/tests/runwine.sh +++ b/tests/runwine.sh @@ -10,6 +10,6 @@ else export WINEPREFIX=${HOME}/.wine/ WINE=wine fi -export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.8/;/usr/${PLATFORM}-w64-mingw32/lib +export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.8/:/usr/${PLATFORM}-w64-mingw32/lib exec ${WINE} $@ From e7d53b53e0e9111cb1910940a98df375c25e655c Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 21:48:58 +0100 Subject: [PATCH 08/14] Only install packages necessary for job. --- .travis.yml | 100 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 737c970..0ea5624 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,82 @@ sudo: false -env: - - PLATFORM=x86_64 UNICODE= CMAKE= - - PLATFORM=i686 UNICODE= CMAKE= - - PLATFORM=x86_64 UNICODE=1 CMAKE= - - PLATFORM=i686 UNICODE=1 CMAKE= - - PLATFORM=x86_64 UNICODE= CMAKE=1 - - PLATFORM=i686 UNICODE= CMAKE=1 - - PLATFORM=x86_64 UNICODE=1 CMAKE=1 - - PLATFORM=i686 UNICODE=1 CMAKE=1 +matrix: + include: + - env: PLATFORM=x86_64 UNICODE= CMAKE= + addons: + apt: + packages: + - binutils-mingw-w64-x86-64 + - mingw-w64-x86-64-dev + - g++-mingw-w64-x86-64 + - gcc-mingw-w64-x86-64 + - wine:amd64 + - env: PLATFORM=i686 UNICODE= CMAKE= + addons: + apt: + packages: + - binutils-mingw-w64-i686 + - mingw-w64-i686-dev + - g++-mingw-w64-i686 + - gcc-mingw-w64-i686 + - wine:i386 + - env: PLATFORM=x86_64 UNICODE=1 CMAKE= + addons: + apt: + packages: + - binutils-mingw-w64-x86-64 + - mingw-w64-x86-64-dev + - g++-mingw-w64-x86-64 + - gcc-mingw-w64-x86-64 + - wine:amd64 + - env: PLATFORM=i686 UNICODE=1 CMAKE= + addons: + apt: + packages: + - binutils-mingw-w64-i686 + - mingw-w64-i686-dev + - g++-mingw-w64-i686 + - gcc-mingw-w64-i686 + - wine:i386 + - env: PLATFORM=x86_64 UNICODE= CMAKE=1 + addons: + apt: + packages: + - binutils-mingw-w64-x86-64 + - mingw-w64-x86-64-dev + - g++-mingw-w64-x86-64 + - gcc-mingw-w64-x86-64 + - wine:amd64 + - env: PLATFORM=i686 UNICODE= CMAKE=1 + addons: + apt: + packages: + - binutils-mingw-w64-i686 + - cmake + - mingw-w64-i686-dev + - g++-mingw-w64-i686 + - gcc-mingw-w64-i686 + - wine:i386 + - env: PLATFORM=x86_64 UNICODE=1 CMAKE=1 + addons: + apt: + packages: + - binutils-mingw-w64-x86-64 + - cmake + - mingw-w64-x86-64-dev + - g++-mingw-w64-x86-64 + - gcc-mingw-w64-x86-64 + - wine:amd64 + - env: PLATFORM=i686 UNICODE=1 CMAKE=1 + addons: + apt: + packages: + - binutils-mingw-w64-i686 + - cmake + - mingw-w64-i686-dev + - g++-mingw-w64-i686 + - gcc-mingw-w64-i686 + - wine:i386 language: cpp @@ -16,20 +84,6 @@ cache: - apt - ccache -addons: - apt: - packages: - - binutils-mingw-w64-i686 - - binutils-mingw-w64-x86-64 - - cmake - - mingw-w64-i686-dev - - mingw-w64-x86-64-dev - - g++-mingw-w64-i686 - - g++-mingw-w64-x86-64 - - gcc-mingw-w64-i686 - - gcc-mingw-w64-x86-64 - - wine - before_script: - if [ ! -z "$CMAKE" ]; then cmake -DPLATFORM=$PLATFORM -DUNICODE=$UNICODE -DTESTSUITE=ON -H. -B.; fi From 403a31e7bbc28967334c081311fa6779588cd033 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Wed, 14 Feb 2018 21:54:42 +0100 Subject: [PATCH 09/14] Run with sudo enabled. This fixes an issue where running wine fails on i386 with /usr/bin/wine: error while loading shared libraries: libwine.so.1: cannot create shared object descriptor: Operation not permitted --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0ea5624..93c6273 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -sudo: false +sudo: true matrix: include: From 060f0bd73608e4233a881ca566dd538ecba78bc1 Mon Sep 17 00:00:00 2001 From: Scavanger Date: Thu, 8 Mar 2018 13:23:39 +0100 Subject: [PATCH 10/14] Search for function names should be case sensitive --- MemoryModule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MemoryModule.c b/MemoryModule.c index 05646e1..9f95a70 100644 --- a/MemoryModule.c +++ b/MemoryModule.c @@ -766,14 +766,14 @@ static int _compare(const void *a, const void *b) { const struct ExportNameEntry *p1 = (const struct ExportNameEntry*) a; const struct ExportNameEntry *p2 = (const struct ExportNameEntry*) b; - return _stricmp(p1->name, p2->name); + return strcmp(p1->name, p2->name); } static int _find(const void *a, const void *b) { LPCSTR *name = (LPCSTR *) a; const struct ExportNameEntry *p = (const struct ExportNameEntry*) b; - return _stricmp(*name, p->name); + return strcmp(*name, p->name); } FARPROC MemoryGetProcAddress(HMEMORYMODULE mod, LPCSTR name) From a15e0769b01f59a0f5f33ab411bc3db6e59864a1 Mon Sep 17 00:00:00 2001 From: Ian Bell Date: Fri, 18 May 2018 00:37:57 -0600 Subject: [PATCH 11/14] Make .h file accessible to superprojects As is, you need to add_subdirectory and also add the include, this kills two birds with one stone --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3ba63c..cfddbfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ else () endif () add_library (MemoryModule STATIC MemoryModule.c MemoryModule.h) +target_include_directories(MemoryModule PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") if (NOT MSVC) set_target_properties ("MemoryModule" PROPERTIES PREFIX "") endif () From d1a08247332aa24dec8491df77fb5ca2efd6530a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Sun, 24 Feb 2019 13:49:51 +0100 Subject: [PATCH 12/14] Fix version for AppVeyor. --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4282d88..5bc1608 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ # Status available at # https://ci.appveyor.com/project/fancycode/memorymodule -version: #{build} +version: 1.0.{build} os: - Visual Studio 2015 From 9f379524076322f7875175f251b38e9c4083600a Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Sun, 24 Feb 2019 15:07:24 +0100 Subject: [PATCH 13/14] Switch to Xenial for CI runs. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 93c6273..2a0f624 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,6 +80,8 @@ matrix: language: cpp +dist: xenial + cache: - apt - ccache From 316aa59c48cd6ab1c10b8a1a99bc1e7aa6f719f4 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Sun, 24 Feb 2019 15:17:41 +0100 Subject: [PATCH 14/14] Get latest stable version of Wine when testing. --- .travis.yml | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a0f624..0bb4efe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: true matrix: include: - - env: PLATFORM=x86_64 UNICODE= CMAKE= + - env: PLATFORM=x86_64 UNICODE= CMAKE= WINE_PACKAGE=winehq-stable:amd64 addons: apt: packages: @@ -10,8 +10,7 @@ matrix: - mingw-w64-x86-64-dev - g++-mingw-w64-x86-64 - gcc-mingw-w64-x86-64 - - wine:amd64 - - env: PLATFORM=i686 UNICODE= CMAKE= + - env: PLATFORM=i686 UNICODE= CMAKE= WINE_PACKAGE=winehq-stable:i386 addons: apt: packages: @@ -19,8 +18,7 @@ matrix: - mingw-w64-i686-dev - g++-mingw-w64-i686 - gcc-mingw-w64-i686 - - wine:i386 - - env: PLATFORM=x86_64 UNICODE=1 CMAKE= + - env: PLATFORM=x86_64 UNICODE=1 CMAKE= WINE_PACKAGE=winehq-stable:amd64 addons: apt: packages: @@ -28,8 +26,7 @@ matrix: - mingw-w64-x86-64-dev - g++-mingw-w64-x86-64 - gcc-mingw-w64-x86-64 - - wine:amd64 - - env: PLATFORM=i686 UNICODE=1 CMAKE= + - env: PLATFORM=i686 UNICODE=1 CMAKE= WINE_PACKAGE=winehq-stable:i386 addons: apt: packages: @@ -37,8 +34,7 @@ matrix: - mingw-w64-i686-dev - g++-mingw-w64-i686 - gcc-mingw-w64-i686 - - wine:i386 - - env: PLATFORM=x86_64 UNICODE= CMAKE=1 + - env: PLATFORM=x86_64 UNICODE= CMAKE=1 WINE_PACKAGE=winehq-stable:amd64 addons: apt: packages: @@ -46,8 +42,7 @@ matrix: - mingw-w64-x86-64-dev - g++-mingw-w64-x86-64 - gcc-mingw-w64-x86-64 - - wine:amd64 - - env: PLATFORM=i686 UNICODE= CMAKE=1 + - env: PLATFORM=i686 UNICODE= CMAKE=1 WINE_PACKAGE=winehq-stable:i386 addons: apt: packages: @@ -56,8 +51,7 @@ matrix: - mingw-w64-i686-dev - g++-mingw-w64-i686 - gcc-mingw-w64-i686 - - wine:i386 - - env: PLATFORM=x86_64 UNICODE=1 CMAKE=1 + - env: PLATFORM=x86_64 UNICODE=1 CMAKE=1 WINE_PACKAGE=winehq-stable:amd64 addons: apt: packages: @@ -66,8 +60,7 @@ matrix: - mingw-w64-x86-64-dev - g++-mingw-w64-x86-64 - gcc-mingw-w64-x86-64 - - wine:amd64 - - env: PLATFORM=i686 UNICODE=1 CMAKE=1 + - env: PLATFORM=i686 UNICODE=1 CMAKE=1 WINE_PACKAGE=winehq-stable:i386 addons: apt: packages: @@ -76,7 +69,6 @@ matrix: - mingw-w64-i686-dev - g++-mingw-w64-i686 - gcc-mingw-w64-i686 - - wine:i386 language: cpp @@ -87,6 +79,9 @@ cache: - ccache before_script: + - curl https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add - + - echo "deb https://dl.winehq.org/wine-builds/ubuntu/ xenial main" | sudo tee /etc/apt/sources.list.d/winehq.list + - sudo apt-get -y update && sudo apt-get -y install --install-recommends $WINE_PACKAGE - if [ ! -z "$CMAKE" ]; then cmake -DPLATFORM=$PLATFORM -DUNICODE=$UNICODE -DTESTSUITE=ON -H. -B.; fi script: