├── README ├── loader ├── libhimemce.def ├── debug.h ├── ChangeLog ├── NEWS ├── libhimemce.c ├── himemce.h ├── himemce-pre.h ├── himemce-map-provider.h ├── kernel32_kernel_private.h ├── himemce-tool.c ├── himemce-real.cpp ├── himemce-map.c ├── CMakeLists.txt ├── server_protocol.h ├── compat.c ├── himemce.c ├── my_winternl.h ├── wine.h ├── himemce-map.h ├── himemce-map-provider.c ├── kernel32_process.c ├── kernel32_module.c ├── README ├── server_mapping.c ├── himemce-pre.c ├── dlmalloc.h ├── ntdll_virtual.c ├── AUTHORS └── COPYING └── inspection ├── memory-layout-stuff.c ├── global-memory-status.c ├── virtual-alloc.c ├── get-system-info.c ├── dump-active-process.c ├── virtual-query.c └── virtual-query-imager.py /README: -------------------------------------------------------------------------------- 1 | A collection of tools to support development on W32CE systems. 2 | 3 | -------------------------------------------------------------------------------- /loader/libhimemce.def: -------------------------------------------------------------------------------- 1 | LIBRARY "libhimemce.dll" 2 | EXPORTS 3 | himemce_set_dllmain_cb 4 | -------------------------------------------------------------------------------- /loader/debug.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Debugging output. FIXME: For now... */ 4 | #define TRACE printf 5 | #define ERR printf 6 | -------------------------------------------------------------------------------- /loader/ChangeLog: -------------------------------------------------------------------------------- 1 | 2010-08-24 Marcus Brinkmann 2 | 3 | * Initial release. 4 | 5 | 6 | 7 | Copyright 2010 g10 Code GmbH 8 | 9 | This file is free software; as a special exception the author gives 10 | unlimited permission to copy and/or distribute it, with or without 11 | modifications, as long as this notice is preserved. 12 | 13 | This file is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 15 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | -------------------------------------------------------------------------------- /loader/NEWS: -------------------------------------------------------------------------------- 1 | Noteworthy changes in version 0.0.1 (unreleased) 2 | ------------------------------------------------ 3 | 4 | * Initialize release. 5 | 6 | 7 | Copyright 2010 g10 Code GmbH 8 | 9 | This file is free software; as a special exception the author gives 10 | unlimited permission to copy and/or distribute it, with or without 11 | modifications, as long as this notice is preserved. 12 | 13 | This file is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 15 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | -------------------------------------------------------------------------------- /loader/libhimemce.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static void dllmain_cb (DWORD reason, LPVOID reserved); 4 | 5 | 6 | /* This library is necessary, because if DLLs are loaded high, they 7 | need to be notified of new threads, and we can't do that without 8 | a DLL that receives these notifications from the system. */ 9 | 10 | BOOL 11 | DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 12 | { 13 | if (fdwReason != DLL_THREAD_ATTACH && fdwReason != DLL_THREAD_DETACH) 14 | return TRUE; 15 | 16 | if (dllmain_cb) 17 | (*dllmain_cb) (fdwReason, lpvReserved); 18 | } 19 | 20 | 21 | void 22 | himemce_set_dllmain_cb (void (*cb) (DWORD, LPVOID)) 23 | { 24 | dllmain_cb = cb; 25 | } 26 | -------------------------------------------------------------------------------- /inspection/memory-layout-stuff.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int some_data; 5 | char *str = "test"; 6 | int some_more_data = 10; 7 | 8 | int 9 | main (int argc, char* argv[]) 10 | { 11 | int a = argc; 12 | void *p = malloc (128); 13 | 14 | printf ("Code: %p\n", &main); 15 | printf ("RO D: %p\n", str); 16 | printf ("RW D: %p\n", &some_more_data); 17 | printf ("BSS: %p\n", &some_data); 18 | printf ("Stack: %p\n", &a); 19 | printf ("Heap: %p\n", p); 20 | printf ("DLL: %p\n", GetProcAddress(GetModuleHandle(TEXT("coredll.dll")), 21 | TEXT("Sleep"))); 22 | 23 | /* Give ssh time to flush buffers. */ 24 | fflush (stdout); 25 | Sleep (300); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /inspection/global-memory-status.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main (int argc, char* argv[]) 6 | { 7 | MEMORYSTATUS ms; 8 | memset (&ms, '\0', sizeof (ms)); 9 | ms.dwLength = sizeof (ms); 10 | 11 | GlobalMemoryStatus (&ms); 12 | printf ("Overall memory load (0-100): %i\n", 13 | ms.dwMemoryLoad); 14 | printf ("Physical memory available/total: 0x%08x/0x%08x (%i)\n", 15 | ms.dwAvailPhys, ms.dwTotalPhys); 16 | printf ("Pagefile memory available/total: 0x%08x/0x%08x (%i)\n", 17 | ms.dwAvailPageFile, ms.dwTotalPageFile); 18 | printf ("Virtual memory available/total: 0x%08x/0x%08x (%i)\n", 19 | ms.dwAvailVirtual, ms.dwTotalVirtual); 20 | 21 | /* Give ssh time to flush buffers. */ 22 | fflush (stdout); 23 | Sleep (300); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /inspection/virtual-alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | main (int argc, char *argv[]) 5 | { 6 | int asize = 1024*1024*1024; 7 | int total_high = 0; 8 | int total_low = 0; 9 | 10 | printf ("Trying size 0x%08x\n", asize); 11 | 12 | while (asize >= 4096) 13 | { 14 | void *ptr; 15 | 16 | ptr = VirtualAlloc (NULL, asize, MEM_RESERVE, PAGE_NOACCESS); 17 | if (ptr != NULL) 18 | { 19 | printf ("Allocated region of size 0x%08x at 0x%p\n", asize, ptr); 20 | if (ptr >= (void*)0x40000000) 21 | total_high += asize; 22 | else 23 | total_low += asize; 24 | } 25 | else 26 | { 27 | asize /= 2; 28 | printf ("Trying size 0x%08x\n", asize); 29 | } 30 | } 31 | printf ("Total High: 0x%08x\n", total_high); 32 | printf ("Total Low: 0x%08x\n", total_low); 33 | Sleep (300); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /loader/himemce.h: -------------------------------------------------------------------------------- 1 | /* himemce.h - High Memory for Windows CE interfaces 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #ifndef HIMEMCE_H 23 | #define HIMEMCE_H 24 | 25 | #include 26 | 27 | #include "debug.h" 28 | 29 | 30 | /* Global options. */ 31 | 32 | extern int verbose; 33 | 34 | 35 | /* Exports from the wine code. */ 36 | 37 | #include "wine.h" 38 | 39 | 40 | /* libhimemce.c */ 41 | void himemce_set_dllmain_cb (void (*cb) (DWORD, LPVOID)); 42 | 43 | 44 | #endif /* HIMEMCE_H */ 45 | -------------------------------------------------------------------------------- /loader/himemce-pre.h: -------------------------------------------------------------------------------- 1 | /* himemce-pre.h - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #ifndef HIMEMCE_PRE_H 23 | #define HIMEMCE_PRE_H 1 24 | 25 | #include "himemce-map.h" 26 | 27 | 28 | struct himemce_map *map_create (void); 29 | 30 | void *map_alloc (struct himemce_map *map, int size); 31 | 32 | struct himemce_module *map_add_module (struct himemce_map *map, 33 | wchar_t filename, void *base); 34 | 35 | void *map_reserve_low (struct himemce_map *map, int size); 36 | 37 | 38 | #endif /* HIMEMCE_PRE_H */ 39 | -------------------------------------------------------------------------------- /loader/himemce-map-provider.h: -------------------------------------------------------------------------------- 1 | /* himemce-map-provider.h - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #ifndef HIMEMCE_MAP_PROVIDER_H 23 | #define HIMEMCE_MAP_PROVIDER_H 1 24 | 25 | #include "himemce-map.h" 26 | 27 | 28 | struct himemce_map *map_create (void); 29 | 30 | void *map_alloc (struct himemce_map *map, int size); 31 | 32 | void *map_reserve_low (struct himemce_map *map, int size); 33 | 34 | struct himemce_module *map_add_module (struct himemce_map *map, 35 | wchar_t *filename, void *base); 36 | 37 | 38 | #endif /* HIMEMCE_MAP_PROVIDER_H */ 39 | -------------------------------------------------------------------------------- /loader/kernel32_kernel_private.h: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/dlls/kernel32/kernel_private.h */ 2 | 3 | /* 4 | * Kernel32 undocumented and private functions definition 5 | * 6 | * Copyright 2003 Eric Pouech 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 | */ 22 | 23 | #ifndef __WINE_KERNEL_PRIVATE_H 24 | #define __WINE_KERNEL_PRIVATE_H 25 | 26 | 27 | enum binary_type 28 | { 29 | BINARY_UNKNOWN = 0, 30 | BINARY_PE, 31 | BINARY_WIN16, 32 | BINARY_OS216, 33 | BINARY_DOS, 34 | BINARY_UNIX_EXE, 35 | BINARY_UNIX_LIB 36 | }; 37 | 38 | #define BINARY_FLAG_DLL 0x01 39 | #define BINARY_FLAG_64BIT 0x02 40 | 41 | struct binary_info 42 | { 43 | enum binary_type type; 44 | DWORD flags; 45 | void *res_start; 46 | void *res_end; 47 | WORD machine; 48 | }; 49 | 50 | /* module.c */ 51 | extern void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /inspection/get-system-info.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char const* 5 | get_proc_arch (WORD proc_arch) 6 | { 7 | switch (proc_arch) 8 | { 9 | case PROCESSOR_ARCHITECTURE_INTEL: 10 | return "INTEL"; 11 | 12 | case PROCESSOR_ARCHITECTURE_MIPS: 13 | return "MIPS"; 14 | 15 | case PROCESSOR_ARCHITECTURE_ALPHA: 16 | return "ALPHA"; 17 | 18 | case PROCESSOR_ARCHITECTURE_PPC: 19 | return "PPC"; 20 | 21 | case PROCESSOR_ARCHITECTURE_SHX: 22 | return "SHX"; 23 | 24 | case PROCESSOR_ARCHITECTURE_ARM: 25 | return "ARM"; 26 | 27 | case PROCESSOR_ARCHITECTURE_IA64: 28 | return "IA64"; 29 | 30 | case PROCESSOR_ARCHITECTURE_ALPHA64: 31 | return "ALPHA64"; 32 | 33 | case PROCESSOR_ARCHITECTURE_MSIL: 34 | return "MSIL"; 35 | 36 | case PROCESSOR_ARCHITECTURE_AMD64: 37 | return "AMD64"; 38 | 39 | case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: 40 | return "WIN64"; 41 | 42 | case PROCESSOR_ARCHITECTURE_UNKNOWN: 43 | return "UNKNOWN"; 44 | 45 | default: 46 | return "(unknown)"; 47 | } 48 | }; 49 | 50 | 51 | int 52 | main (int argc, char* argv[]) 53 | { 54 | SYSTEM_INFO si; 55 | memset (&si, '\0', sizeof (si)); 56 | 57 | GetSystemInfo (&si); 58 | printf ("Processor Architecture/Type/Level/Revision: %s/%i/%i/%i\n", 59 | get_proc_arch (si.wProcessorArchitecture), 60 | si.dwProcessorType, (int) si.wProcessorLevel, (int)si.wProcessorRevision); 61 | printf ("Page Size: %i\n", si.dwPageSize); 62 | printf ("Application Virtual Address Space: %p - %p\n", 63 | si.lpMinimumApplicationAddress, 64 | si.lpMaximumApplicationAddress); 65 | printf ("Allocation Granularity: %i\n", 66 | si.dwAllocationGranularity); 67 | 68 | /* Give ssh time to flush buffers. */ 69 | fflush (stdout); 70 | Sleep (300); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /loader/himemce-tool.c: -------------------------------------------------------------------------------- 1 | /* himemce-tool.c - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | #include 24 | 25 | #include "himemce-map.h" 26 | 27 | int 28 | main (int argc, char *argv[]) 29 | { 30 | struct himemce_map *map; 31 | int i; 32 | 33 | /* Open the map data (which must exist). */ 34 | map = himemce_map_open (); 35 | if (! map) 36 | { 37 | fprintf (stderr, "could not open himem map: %i\n", GetLastError ()); 38 | exit (1); 39 | } 40 | 41 | printf ("Found map at %p (size 0x%x)\n", map, map->size); 42 | printf ("Low memory reserve at %p (size 0x%x)\n", 43 | map->low_start, map->low_size); 44 | printf ("Listing %i modules:\n", map->nr_modules); 45 | for (i = 0; i < map->nr_modules; i++) 46 | { 47 | struct himemce_module *mod = &map->module[i]; 48 | printf ("module[%2i] = %s %p\n", i, mod->name, mod->base); 49 | /* TODO: Loop through sections, show some more info. */ 50 | } 51 | 52 | himemce_map_close (map); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /loader/himemce-real.cpp: -------------------------------------------------------------------------------- 1 | /* himemce-real.cpp - High Memory for Windows CE Test program 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | 23 | #include 24 | 25 | #define KB(x) ((x) * 1024) 26 | #define MB(x) (KB(x) * 1024) 27 | 28 | /* Test read-only data section. */ 29 | const char teststr_ro[] = { 'R', 'e', 'a', 'd', '-', 30 | 'o', 'n', 'l', 'y', '.' }; 31 | 32 | /* Make program wastefully large and test read/write data section. */ 33 | char teststr_rw[MB(4)] = { 'R', 'e', 'a', 'd', '-', 34 | 'w', 'r', 'i', 't', 'e', '.', '\0' }; 35 | 36 | /* FIXME: TODO: Add BSS test. */ 37 | // char teststr_bs[512]; 38 | 39 | 40 | /* Test static constructors/destructors. */ 41 | class Foo 42 | { 43 | public: 44 | Foo() 45 | { 46 | printf ("CONSTRUCTED FOO\n"); 47 | } 48 | ~Foo() 49 | { 50 | printf ("DECONSTRUCTED FOO\n"); 51 | } 52 | }; 53 | 54 | Foo foo; 55 | 56 | 57 | int 58 | main (int argc, char *argv[]) 59 | { 60 | int i; 61 | 62 | printf ("TEST: argc = %i\n", argc); 63 | for (i = 0; i < argc; i++) 64 | printf ("TEST: argv[%i] = %s\n", i, argv[i]); 65 | 66 | printf ("TEST: RO: %s\n", teststr_ro); 67 | printf ("TEST: RW: %s\n", teststr_rw); 68 | // printf ("TEST: BS: %s\n", teststr_bs); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /loader/himemce-map.c: -------------------------------------------------------------------------------- 1 | /* himemce-map.c - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | 24 | #include "himemce-map.h" 25 | 26 | /* Open the map data (which must exist). */ 27 | struct himemce_map * 28 | himemce_map_open (void) 29 | { 30 | HANDLE *hnd; 31 | struct himemce_map *map; 32 | 33 | hnd = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 34 | HIMEMCE_MAP_SIZE, HIMEMCE_MAP_NAME); 35 | if (! hnd) 36 | return NULL; 37 | map = MapViewOfFile (hnd, FILE_MAP_READ, 0, 0, 0); 38 | CloseHandle (hnd); 39 | if (! map) 40 | return NULL; 41 | if (map->magic != HIMEMCE_MAP_MAGIC) 42 | return NULL; 43 | 44 | return map; 45 | } 46 | 47 | 48 | /* Release the map data. */ 49 | void 50 | himemce_map_close (struct himemce_map *map) 51 | { 52 | UnmapViewOfFile (map); 53 | } 54 | 55 | 56 | /* Find the DLL with the name DLLNAME in the map. */ 57 | struct himemce_module * 58 | himemce_map_find_module (struct himemce_map *map, const char *name) 59 | { 60 | int i; 61 | 62 | for (i = 0; i < map->nr_modules; i++) 63 | if (! _stricmp (map->module[i].name, name)) 64 | break; 65 | 66 | if (i < map->nr_modules) 67 | return &map->module[i]; 68 | 69 | return NULL; 70 | } 71 | -------------------------------------------------------------------------------- /loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(himemce) 2 | cmake_minimum_required(VERSION 2.6.0) 3 | 4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 5 | 6 | # For dlmalloc.h 7 | add_definitions(-DUSE_DL_PREFIX=1) 8 | 9 | add_library(libhimemce SHARED libhimemce.c libhimemce.def) 10 | install(TARGETS libhimemce DESTINATION bin) 11 | 12 | add_executable(himemce himemce.c 13 | wine.h my_winternl.h compat.c 14 | # dlmalloc.h dlmalloc.c 15 | kernel32_kernel_private.h kernel32_process.c kernel32_module.c 16 | ntdll_error.c ntdll_loader.c ntdll_virtual.c 17 | server_protocol.h server_mapping.c) 18 | target_link_libraries(himemce libhimemce) 19 | install(TARGETS himemce DESTINATION bin) 20 | 21 | 22 | #Example rules how to build a library. 23 | #add_library(newtest SHARED newtest.cpp newtest.def) 24 | #add_executable(newtestex newtestex.cpp) 25 | #target_link_libraries(newtestex newtest) 26 | #install(TARGETS newtest newtestex DESTINATION bin) 27 | 28 | add_executable(himemce-real himemce-real.cpp) 29 | SET_TARGET_PROPERTIES(himemce-real PROPERTIES LINK_FLAGS " /FIXED:NO") 30 | # Not necessary anymore. 31 | #SET_TARGET_PROPERTIES(himemce-real PROPERTIES LINK_FLAGS " /FILEALIGN:4096") 32 | install(TARGETS himemce-real DESTINATION bin) 33 | 34 | add_executable(himemce-tool himemce-tool.c 35 | himemce-map.h himemce-map.c) 36 | install(TARGETS himemce-tool DESTINATION bin) 37 | 38 | add_executable(himemce-pre himemce-pre.c 39 | himemce-map.h himemce-map.c 40 | himemce-map-provider.c 41 | wine.h my_winternl.h compat.c 42 | # dlmalloc.h dlmalloc.c 43 | kernel32_kernel_private.h kernel32_process.c kernel32_module.c 44 | ntdll_error.c ntdll_loader.c ntdll_virtual.c 45 | server_protocol.h server_mapping.c) 46 | target_link_libraries(himemce-pre libhimemce) 47 | install(TARGETS himemce-pre DESTINATION bin) 48 | 49 | 50 | # Copyright 2010 g10 Code GmbH 51 | # 52 | # This file is free software; as a special exception the author gives 53 | # unlimited permission to copy and/or distribute it, with or without 54 | # modifications, as long as this notice is preserved. 55 | # 56 | # This file is distributed in the hope that it will be useful, but 57 | # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 58 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 59 | -------------------------------------------------------------------------------- /loader/server_protocol.h: -------------------------------------------------------------------------------- 1 | /* -*- C -*- 2 | * 3 | * Wine server protocol definition 4 | * 5 | * Copyright (C) 2001 Alexandre Julliard 6 | * Copyright 2010 g10 Code GmbH 7 | * 8 | * This file is used by tools/make_requests to build the 9 | * protocol structures in include/wine/server_protocol.h 10 | * 11 | * This library is free software; you can redistribute it and/or 12 | * modify it under the terms of the GNU Lesser General Public 13 | * License as published by the Free Software Foundation; either 14 | * version 2.1 of the License, or (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * Lesser General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public 22 | * License along with this library; if not, write to the Free Software 23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24 | */ 25 | 26 | 27 | #ifndef PROTOCOL_SERVER_H 28 | #define PROTOCOL_SERVER_H 1 29 | 30 | typedef int mem_size_t; // Normally 64 bit, but good enough. 31 | 32 | 33 | /* per-page protection flags */ 34 | #define VPROT_READ 0x01 35 | #define VPROT_WRITE 0x02 36 | #define VPROT_EXEC 0x04 37 | #define VPROT_WRITECOPY 0x08 38 | #define VPROT_GUARD 0x10 39 | #define VPROT_NOCACHE 0x20 40 | #define VPROT_COMMITTED 0x40 41 | #define VPROT_WRITEWATCH 0x80 42 | /* per-mapping protection flags */ 43 | #define VPROT_IMAGE 0x0100 /* mapping for an exe image */ 44 | #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ 45 | #define VPROT_VALLOC 0x0400 /* allocated by VirtualAlloc */ 46 | #define VPROT_NOEXEC 0x0800 /* don't force exec permission */ 47 | 48 | 49 | /* Server mapping. */ 50 | NTSTATUS SERVER_create_mapping (ACCESS_MASK access, /* const OBJECT_ATTRIBUTES *attr */ void *attr, 51 | HANDLE file_handle, long long size, unsigned int protect, HANDLE *handle); 52 | NTSTATUS SERVER_get_mapping_info (HANDLE _mapping, ACCESS_MASK access, unsigned int *protect, 53 | void **base, mem_size_t *size, int *header_size, HANDLE *fhandle, 54 | HANDLE *handle); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /loader/compat.c: -------------------------------------------------------------------------------- 1 | /* compat.c - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include "wine.h" 23 | 24 | struct _PEB _peb; 25 | 26 | size_t 27 | pread (HANDLE handle, char *buffer, size_t len, off_t offset) 28 | { 29 | DWORD out = -1; 30 | if (SetFilePointer (handle, offset, NULL, SEEK_SET) == -1) 31 | return -1; 32 | if (!ReadFile (handle, buffer, len, &out, NULL)) 33 | return -1; 34 | return out; 35 | } 36 | 37 | 38 | int get_prot_flags (int vprot) 39 | { 40 | int rwx = vprot & (VPROT_READ | VPROT_WRITE | VPROT_WRITECOPY | VPROT_EXEC); 41 | int res = 0; 42 | 43 | switch(rwx) 44 | { 45 | case VPROT_READ: 46 | res = PAGE_READONLY; 47 | break; 48 | case VPROT_READ | VPROT_WRITE: 49 | res = PAGE_READWRITE; 50 | break; 51 | case VPROT_READ | VPROT_WRITECOPY: 52 | // res = PAGE_WRITECOPY; 53 | res = PAGE_READWRITE; 54 | break; 55 | case VPROT_EXEC: 56 | res = PAGE_EXECUTE; 57 | break; 58 | case VPROT_EXEC | VPROT_READ: 59 | res = PAGE_EXECUTE_READ; 60 | break; 61 | case VPROT_EXEC | VPROT_READ | VPROT_WRITE: 62 | res = PAGE_EXECUTE_READWRITE; 63 | break; 64 | case VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY: 65 | // res = PAGE_EXECUTE_WRITECOPY; 66 | res = PAGE_EXECUTE_READWRITE; 67 | break; 68 | default: 69 | res = PAGE_NOACCESS; 70 | } 71 | if (vprot & VPROT_GUARD) res |= PAGE_GUARD; 72 | if (vprot & VPROT_NOCACHE) res |= PAGE_NOCACHE; 73 | return res; 74 | } 75 | -------------------------------------------------------------------------------- /loader/himemce.c: -------------------------------------------------------------------------------- 1 | /* himemce.c - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | #include 24 | 25 | #include "himemce.h" 26 | 27 | /* True if debug output should be given. */ 28 | int verbose = 1; 29 | 30 | 31 | /* Get the filename of the image file to load. Normally, this is the 32 | current exe name, with "-real.exe" instead of any existing 33 | ending. */ 34 | static wchar_t * 35 | get_app_name (void) 36 | { 37 | /* Nine for "-real.exe" and one for good luck. */ 38 | static wchar_t filename[MAX_PATH + 10]; 39 | int res; 40 | wchar_t *end; 41 | 42 | res = GetModuleFileName (GetModuleHandle (NULL), filename, MAX_PATH); 43 | if (! res) 44 | { 45 | ERR ("can not determine module filename: %i\n", 46 | GetLastError ()); 47 | exit (1); 48 | } 49 | 50 | end = wcsrchr (filename, L'.'); 51 | if (! end) 52 | end = filename + wcslen (filename); 53 | 54 | wcscpy (end, L"-real.exe"); 55 | return filename; 56 | } 57 | 58 | 59 | int 60 | main (int argc, char *argv[]) 61 | { 62 | WCHAR *app_name; 63 | WCHAR *cmdline; 64 | BOOL ret; 65 | int result = 0; 66 | 67 | app_name = get_app_name (); 68 | cmdline = GetCommandLine (); 69 | 70 | TRACE ("starting %S %S\n", app_name, cmdline); 71 | 72 | /* Note that this does not spawn a new process, but just calls into 73 | the startup function of the app eventually, and returns with its 74 | exit code. */ 75 | ret = MyCreateProcessW (app_name, cmdline, &result); 76 | if (! ret) 77 | { 78 | ERR ("starting %S failed: %i\n", app_name, GetLastError()); 79 | return 1; 80 | } 81 | 82 | return result; 83 | } 84 | -------------------------------------------------------------------------------- /loader/my_winternl.h: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/include/winternl.h */ 2 | 3 | /* 4 | * Internal NT APIs and data structures 5 | * 6 | * Copyright (C) the Wine project 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 | */ 22 | 23 | #ifndef __WINE_WINTERNL_H 24 | #define __WINE_WINTERNL_H 25 | 26 | #include 27 | 28 | 29 | typedef struct _PEB 30 | { 31 | HMODULE ImageBaseAddress; 32 | 33 | wchar_t *ImagePathName; 34 | wchar_t *CommandLine; 35 | 36 | /* The exit code after completion of the executed image. */ 37 | int ExitStatus; 38 | } PEB, *PPEB; 39 | 40 | 41 | typedef enum _SECTION_INHERIT { 42 | ViewShare = 1, 43 | ViewUnmap = 2 44 | } SECTION_INHERIT; 45 | 46 | 47 | #define NtCurrentProcess() ((HANDLE)-1) 48 | 49 | typedef struct _LDR_MODULE 50 | { 51 | #if 0 52 | LIST_ENTRY InLoadOrderModuleList; 53 | LIST_ENTRY InMemoryOrderModuleList; 54 | LIST_ENTRY InInitializationOrderModuleList; 55 | #endif 56 | void* BaseAddress; 57 | void* EntryPoint; 58 | ULONG SizeOfImage; 59 | wchar_t FullDllName[MAX_PATH]; 60 | wchar_t BaseDllName[MAX_PATH]; 61 | ULONG Flags; 62 | SHORT LoadCount; 63 | SHORT TlsIndex; 64 | HANDLE SectionHandle; 65 | ULONG CheckSum; 66 | ULONG TimeDateStamp; 67 | HANDLE ActivationContext; 68 | } LDR_MODULE, *PLDR_MODULE; 69 | 70 | /* those defines are (some of the) regular LDR_MODULE.Flags values */ 71 | #define LDR_IMAGE_IS_DLL 0x00000004 72 | #define LDR_LOAD_IN_PROGRESS 0x00001000 73 | #define LDR_UNLOAD_IN_PROGRESS 0x00002000 74 | #define LDR_NO_DLL_CALLS 0x00040000 75 | #define LDR_PROCESS_ATTACHED 0x00080000 76 | #define LDR_MODULE_REBASED 0x00200000 77 | 78 | /* these ones is Wine specific */ 79 | #define LDR_DONT_RESOLVE_REFS 0x40000000 80 | #define LDR_WINE_INTERNAL 0x80000000 81 | 82 | #endif /* __WINE_WINTERNL_H */ 83 | -------------------------------------------------------------------------------- /loader/wine.h: -------------------------------------------------------------------------------- 1 | /* wine.h 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #ifndef HIMEMCE_WINE_H 23 | #define HIMEMCE_WINE_H 24 | 25 | #include 26 | 27 | #include "debug.h" 28 | 29 | #include "my_winternl.h" 30 | #include "server_protocol.h" 31 | 32 | /* Support for the wine code. */ 33 | extern struct _PEB _peb; 34 | #define current_peb() (&_peb) 35 | 36 | #define OBJECT_ATTRIBUTES void 37 | 38 | typedef int off_t; 39 | 40 | /* compat.c */ 41 | size_t pread(HANDLE handle, char *buffer, size_t len, off_t offset); 42 | 43 | int get_prot_flags (int vprot); 44 | 45 | 46 | /* ntdll_error.c */ 47 | ULONG MyRtlNtStatusToDosError (NTSTATUS status); 48 | 49 | /* ntdll_loader.c */ 50 | PIMAGE_NT_HEADERS MyRtlImageNtHeader (HMODULE hModule); 51 | NTSTATUS MyLdrLoadDll (LPCWSTR path_name, DWORD flags, 52 | LPCWSTR libname, HMODULE* hModule); 53 | void MyLdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2, 54 | ULONG_PTR unknown3, ULONG_PTR unknown4 ); 55 | IMAGE_BASE_RELOCATION *MyLdrProcessRelocationBlock (void *page, UINT count, 56 | USHORT *relocs, 57 | INT_PTR delta); 58 | PVOID MyRtlImageDirectoryEntryToData( HMODULE module, BOOL image, 59 | WORD dir, ULONG *size ); 60 | 61 | 62 | /* ntdll_virtual.c */ 63 | NTSTATUS MyNtCreateSection (HANDLE *handle, ACCESS_MASK access, 64 | const OBJECT_ATTRIBUTES *attr, 65 | const LARGE_INTEGER *size, ULONG protect, 66 | ULONG sec_flags, HANDLE file); 67 | NTSTATUS MyNtMapViewOfSection (HANDLE handle, HANDLE process, 68 | PVOID *addr_ptr, ULONG zero_bits, 69 | SIZE_T commit_size, 70 | const LARGE_INTEGER *offset_ptr, 71 | SIZE_T *size_ptr, 72 | SECTION_INHERIT inherit, ULONG alloc_type, 73 | ULONG protect); 74 | 75 | /* kernel32_module.c */ 76 | HMODULE MyLoadLibraryExW (LPCWSTR libnameW, HANDLE hfile, DWORD flags); 77 | 78 | /* kernel32_process.c */ 79 | BOOL MyCreateProcessW (LPCWSTR app_name, LPWSTR cmd_line, int *exit_code); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /loader/himemce-map.h: -------------------------------------------------------------------------------- 1 | /* himemce-map.h - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #ifndef HIMEMCE_MAP_H 23 | #define HIMEMCE_MAP_H 1 24 | 25 | #include 26 | 27 | /* The preloader makes its information available at a shared memory 28 | object of this name and size. */ 29 | #define HIMEMCE_MAP_NAME L"himemcemap" 30 | #define HIMEMCE_MAP_SIZE (128 * 1024) 31 | #define HIMEMCE_MAP_MAGIC 0x400b1337 32 | 33 | /* The default base address. Users should take the actual value from 34 | the LOW_START member of struct himemce_map. */ 35 | #define _HIMEMCE_MAP_LOW_BASE ((void *) (2 * 1024 * 1024)) 36 | 37 | /* Maximum number of DLLs that can be mapped. */ 38 | #define HIMEMCE_MAP_MAX_MODULES 64 39 | 40 | 41 | /* Each module provides this. */ 42 | struct himemce_module 43 | { 44 | wchar_t *filename; 45 | 46 | /* Points into filename. */ 47 | wchar_t *dllname; 48 | 49 | /* Export DLL name (same as DLLNAME, but in ASCII). */ 50 | char *name; 51 | 52 | /* The base address of the module image. */ 53 | void *base; 54 | 55 | /* The low (in-process) address of read-write sections is available 56 | in the PointerToLinenumbers in the section header, which is 57 | recycled for that purpose. */ 58 | }; 59 | 60 | 61 | struct himemce_map 62 | { 63 | /* Must be HIMEMCE_MAP_MAGIC. */ 64 | unsigned int magic; 65 | 66 | /* Actual size of the map. */ 67 | unsigned int size; 68 | 69 | /* The low addresses of sections are within this range, which must 70 | be reserved by the program that wants to use mapped modules as 71 | soon as possible. */ 72 | void *low_start; 73 | int low_size; 74 | 75 | /* Number of mapped modules. */ 76 | int nr_modules; 77 | 78 | struct himemce_module module[HIMEMCE_MAP_MAX_MODULES]; 79 | }; 80 | 81 | 82 | /* Open the map data (which must exist). */ 83 | struct himemce_map *himemce_map_open (void); 84 | 85 | /* Release the map data. */ 86 | void himemce_map_close (struct himemce_map *map); 87 | 88 | /* Find the DLL with the name DLLNAME in the map. */ 89 | struct himemce_module *himemce_map_find_module (struct himemce_map *map, 90 | const char *name); 91 | 92 | #endif /* HIMEMCE_MAP_H */ 93 | -------------------------------------------------------------------------------- /loader/himemce-map-provider.c: -------------------------------------------------------------------------------- 1 | /* himemce-map-provider.c - High Memory for Windows CE 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | 24 | #include "debug.h" 25 | #include "himemce-map-provider.h" 26 | 27 | #define ALIGN(x,a) ((x + ((a) - 1)) & ~(a - 1)) 28 | 29 | struct himemce_map * 30 | map_create (void) 31 | { 32 | HANDLE *hnd; 33 | struct himemce_map *map; 34 | 35 | hnd = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 36 | HIMEMCE_MAP_SIZE, HIMEMCE_MAP_NAME); 37 | if (! hnd) 38 | { 39 | ERR ("creating himemce map file failed: %i\n", GetLastError ()); 40 | return NULL; 41 | } 42 | map = MapViewOfFile (hnd, FILE_MAP_READ, 0, 0, 0); 43 | CloseHandle (hnd); 44 | if (! map) 45 | { 46 | ERR ("mapping himemce map file failed: %i\n", GetLastError ()); 47 | return NULL; 48 | } 49 | 50 | if (map->magic == HIMEMCE_MAP_MAGIC) 51 | { 52 | /* Already running. */ 53 | ERR ("himemce map already present\n"); 54 | UnmapViewOfFile (map); 55 | return NULL; 56 | } 57 | 58 | /* Set the defaults. */ 59 | map->magic = HIMEMCE_MAP_MAGIC; 60 | map->size = sizeof (struct himemce_map); 61 | map->low_start = _HIMEMCE_MAP_LOW_BASE; 62 | return map; 63 | } 64 | 65 | 66 | void * 67 | map_alloc (struct himemce_map *map, int size) 68 | { 69 | void *ptr = ((char *) map) + map->size; 70 | 71 | /* Word-align. */ 72 | map->size += ALIGN (size, 4); 73 | if (size >= HIMEMCE_MAP_SIZE) 74 | { 75 | ERR ("out of map memory allocating %i bytes\n", size); 76 | return NULL; 77 | } 78 | return ptr; 79 | } 80 | 81 | 82 | void * 83 | map_reserve_low (struct himemce_map *map, int size) 84 | { 85 | void *ptr = ((char *) map->low_start) + map->low_size; 86 | 87 | /* Alignment for module sections. */ 88 | map->low_size += ALIGN (size, 1024); 89 | return ptr; 90 | } 91 | 92 | 93 | struct himemce_module * 94 | map_add_module (struct himemce_map *map, wchar_t *filename, void *base) 95 | { 96 | struct himemce_module *mod; 97 | int len; 98 | int idx; 99 | 100 | if (map->nr_modules == HIMEMCE_MAP_MAX_MODULES) 101 | { 102 | ERR ("too many modules\n"); 103 | return NULL; 104 | } 105 | 106 | mod = &map->module[map->nr_modules]; 107 | 108 | len = wcslen (filename); 109 | mod->filename = map_alloc (map, (len + 1) * sizeof (wchar_t)); 110 | if (! mod->filename) 111 | return NULL; 112 | wcscpy (mod->filename, filename); 113 | idx = len; 114 | while (idx > 0 && mod->filename[idx - 1] != '\\' 115 | && mod->filename[idx - 1] != '/') 116 | idx--; 117 | mod->dllname = &mod->filename[idx]; 118 | mod->base = base; 119 | 120 | len = WideCharToMultiByte (CP_UTF8, 0, mod->dllname, -1, NULL, 0, NULL, NULL); 121 | if (len == 0) 122 | { 123 | ERR ("conversion failure: %i\n", GetLastError ()); 124 | return NULL; 125 | } 126 | mod->name = map_alloc (map, len); 127 | if (! mod->name) 128 | return NULL; 129 | 130 | if (WideCharToMultiByte (CP_UTF8, 0, mod->dllname, -1, mod->name, len, 131 | NULL, NULL) != len) 132 | { 133 | ERR ("conversion inconsistency: %i\n", GetLastError ()); 134 | return NULL; 135 | } 136 | 137 | map->nr_modules++; 138 | return mod; 139 | } 140 | 141 | 142 | -------------------------------------------------------------------------------- /inspection/dump-active-process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void 6 | dump_mbi_header () 7 | { 8 | printf ("alc-base alc-prot address size state protect type \n"); 9 | } 10 | 11 | 12 | int 13 | dump_protect_flags (DWORD flags) 14 | { 15 | DWORD pr = flags & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE 16 | | PAGE_EXECUTE_WRITECOPY | PAGE_READONLY 17 | | PAGE_READWRITE | PAGE_WRITECOPY); 18 | DWORD pw = flags & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY 19 | | PAGE_READWRITE | PAGE_WRITECOPY); 20 | DWORD pc = flags & (PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY); 21 | DWORD px = flags & (PAGE_EXECUTE | PAGE_EXECUTE_READ 22 | | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); 23 | 24 | printf ("%c%c%c %c%c%c ", 25 | pr ? 'r' : '-', pc ? 'c' : (pw ? 'w' : '-'), px ? 'x' : '-', 26 | (flags & PAGE_GUARD) ? 'g' : '-', 27 | (flags & PAGE_NOCACHE) ? 'n' : '-', 28 | #ifdef PAGE_PHYSICAL 29 | (flags & PAGE_PHYSICAL) ? 'p' : 30 | #endif 31 | '-'); 32 | return pr; 33 | } 34 | 35 | 36 | void 37 | dump_state (DWORD state) 38 | { 39 | switch (state) 40 | { 41 | case MEM_COMMIT: 42 | printf ("commit "); 43 | return; 44 | case MEM_FREE: 45 | printf ("free "); 46 | return; 47 | case MEM_RESERVE: 48 | printf ("reserve "); 49 | return; 50 | default: 51 | printf ("unknown "); 52 | } 53 | } 54 | 55 | 56 | void 57 | dump_type (DWORD mtype) 58 | { 59 | switch (mtype) 60 | { 61 | case MEM_IMAGE: 62 | printf ("image "); 63 | return; 64 | case MEM_MAPPED: 65 | printf ("mapped "); 66 | return; 67 | case MEM_PRIVATE: 68 | printf ("private "); 69 | return; 70 | default: 71 | printf ("unknown "); 72 | } 73 | } 74 | 75 | 76 | void 77 | dump_region (unsigned char *base, unsigned int size) 78 | { 79 | int i; 80 | int in_nulls = 0; 81 | 82 | /* Base and size are page-aligned. */ 83 | while (size != 0) 84 | { 85 | for (i = 0; i < 16; i++) 86 | if (base[i]) 87 | break; 88 | if (i == 16) 89 | { 90 | /* Only zeroes. */ 91 | if (! in_nulls) 92 | { 93 | printf ("*\n"); 94 | in_nulls = 1; 95 | } 96 | goto next; 97 | } 98 | in_nulls = 0; 99 | printf ("0x%08x:", base); 100 | for (i = 0; i < 16; i++) 101 | { 102 | if (i == 8) 103 | printf (" "); 104 | printf (" %02x", base[i]); 105 | } 106 | printf (" "); 107 | for (i = 0; i < 16; i++) 108 | { 109 | if (i == 8) 110 | printf (" "); 111 | printf ("%c", isprint(base[i]) ? base[i] : '.'); 112 | } 113 | printf ("\n"); 114 | next: 115 | base += 16; 116 | size -= 16; 117 | } 118 | } 119 | 120 | 121 | void 122 | dump_mbi (PMEMORY_BASIC_INFORMATION mbi) 123 | { 124 | int pr; 125 | printf ("0x%08x ", mbi->AllocationBase); 126 | dump_protect_flags (mbi->AllocationProtect); 127 | printf ("0x%08x ", mbi->BaseAddress); 128 | printf ("0x%08x ", mbi->RegionSize); 129 | dump_state (mbi->State); 130 | pr = dump_protect_flags (mbi->Protect); 131 | dump_type (mbi->Type); 132 | printf ("\n"); 133 | if (pr) 134 | dump_region (mbi->BaseAddress, mbi->RegionSize); 135 | } 136 | 137 | 138 | int 139 | main (int argc, char* argv[]) 140 | { 141 | MEMORY_BASIC_INFORMATION mbi; 142 | SYSTEM_INFO si; 143 | void *addr; 144 | 145 | memset (&si, '\0', sizeof (si)); 146 | GetSystemInfo (&si); 147 | dump_mbi_header (); 148 | 149 | addr = 0; 150 | do 151 | { 152 | DWORD res; 153 | void *new_addr; 154 | 155 | memset (&mbi, '\0', sizeof (mbi)); 156 | res = VirtualQuery (addr, &mbi, sizeof (mbi)); 157 | if (res == 0) 158 | { 159 | printf ("Skipping over %p\n", addr); 160 | new_addr = addr + si.dwPageSize; 161 | if (new_addr < addr) 162 | break; 163 | addr = new_addr; 164 | continue; 165 | } 166 | if (res != sizeof (mbi)) 167 | { 168 | printf ("Unexpected return size: %i (expected %i)\n", 169 | res, sizeof (mbi)); 170 | } 171 | dump_mbi (&mbi); 172 | /* Check for overflow. */ 173 | new_addr = addr + mbi.RegionSize; 174 | if (new_addr < addr) 175 | break; 176 | addr = new_addr; 177 | } 178 | while (1); 179 | 180 | /* Give ssh time to flush buffers. */ 181 | fflush (stdout); 182 | Sleep (300); 183 | return 0; 184 | } 185 | -------------------------------------------------------------------------------- /loader/kernel32_process.c: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/dlls/kernel32/process.c */ 2 | 3 | /* 4 | * Win32 processes 5 | * 6 | * Copyright 1996, 1998 Alexandre Julliard 7 | * Copyright 2010 g10 Code GmbH 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 | */ 23 | 24 | #include 25 | #include "wine.h" 26 | #include "kernel32_kernel_private.h" 27 | 28 | 29 | typedef int (APIENTRY *ENTRY_POINT) (HINSTANCE hInstance, 30 | HINSTANCE hPrevInstance, 31 | LPWSTR lpCmdLine, int nCmdShow); 32 | 33 | static BOOL start_process( PEB *peb ) 34 | { 35 | IMAGE_NT_HEADERS *nt; 36 | ENTRY_POINT entry; 37 | 38 | nt = MyRtlImageNtHeader( peb->ImageBaseAddress ); 39 | entry = (ENTRY_POINT)((char *)peb->ImageBaseAddress + 40 | nt->OptionalHeader.AddressOfEntryPoint); 41 | 42 | if (!nt->OptionalHeader.AddressOfEntryPoint) 43 | { 44 | ERR( "%S doesn't have an entry point, it cannot be executed\n", 45 | peb->ImagePathName ); 46 | SetLastError (ERROR_BAD_EXE_FORMAT); 47 | return FALSE; 48 | } 49 | 50 | TRACE( "Starting process %S (entryproc=%p)\n", 51 | peb->ImagePathName, entry ); 52 | 53 | SetLastError( 0 ); /* clear error code */ 54 | peb->ExitStatus = entry (GetModuleHandle (NULL), NULL, peb->CommandLine, 0); 55 | 56 | return 0; 57 | } 58 | 59 | 60 | static BOOL __wine_kernel_init (HANDLE hFile, LPCWSTR main_exe_name, 61 | LPWSTR cmd_line, int *exit_code) 62 | { 63 | PEB *peb = current_peb(); 64 | 65 | peb->CommandLine = cmd_line; 66 | peb->ImageBaseAddress = MyLoadLibraryExW( main_exe_name, 0, 67 | DONT_RESOLVE_DLL_REFERENCES ); 68 | 69 | if (! peb->ImageBaseAddress) 70 | { 71 | ERR ("can not load %S: %i\n", main_exe_name, GetLastError()); 72 | return FALSE; 73 | } 74 | 75 | /* FIXME: Error checking? */ 76 | MyLdrInitializeThunk( start_process, 0, 0, 0 ); 77 | 78 | *exit_code = peb->ExitStatus; 79 | return TRUE; 80 | } 81 | 82 | 83 | static HANDLE open_exe_file (LPCWSTR name, struct binary_info *binary_info) 84 | { 85 | HANDLE handle; 86 | 87 | handle = CreateFileForMappingW( name, GENERIC_READ, FILE_SHARE_READ, 88 | NULL, OPEN_EXISTING, 0, 0 ); 89 | if (handle != INVALID_HANDLE_VALUE) 90 | MODULE_get_binary_info( handle, binary_info ); 91 | 92 | return handle; 93 | } 94 | 95 | 96 | BOOL MyCreateProcessW (LPCWSTR app_name, LPWSTR cmd_line, 97 | int *exit_code) 98 | { 99 | BOOL retv = FALSE; 100 | HANDLE hFile = 0; 101 | struct binary_info binary_info; 102 | 103 | hFile = open_exe_file (app_name, &binary_info); 104 | if (hFile == INVALID_HANDLE_VALUE) 105 | { 106 | ERR ("could not open file %S: %i\n", app_name, GetLastError()); 107 | goto err; 108 | } 109 | 110 | TRACE ("MyCreateProcessW: 0x%p type=0x%x flags=0x%x " 111 | "res_start=0x%p res_end=0x%p\n", 112 | hFile, binary_info.type, binary_info.flags, 113 | binary_info.res_start, binary_info.res_end); 114 | 115 | /* Some sanity checks. */ 116 | if (binary_info.flags & BINARY_FLAG_DLL) 117 | { 118 | ERR ("not starting %S since it is a DLL\n", app_name); 119 | SetLastError( ERROR_BAD_EXE_FORMAT ); 120 | goto err; 121 | } 122 | 123 | if (binary_info.flags & BINARY_FLAG_64BIT) 124 | { 125 | ERR( "starting 64-bit process %S not supported on this platform\n", 126 | app_name); 127 | SetLastError( ERROR_BAD_EXE_FORMAT ); 128 | return FALSE; 129 | } 130 | 131 | if (binary_info.type != BINARY_PE) 132 | { 133 | ERR ("not starting %S of type %i (expected %i)\n", app_name, 134 | binary_info.type, BINARY_PE); 135 | SetLastError( ERROR_BAD_EXE_FORMAT ); 136 | return FALSE; 137 | } 138 | 139 | retv = __wine_kernel_init (hFile, app_name, cmd_line, exit_code); 140 | 141 | err: 142 | if (hFile) 143 | CloseHandle( hFile ); 144 | 145 | return retv; 146 | } 147 | 148 | -------------------------------------------------------------------------------- /loader/kernel32_module.c: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/dlls/kernel32/module.c */ 2 | 3 | /* 4 | * Modules 5 | * 6 | * Copyright 1995 Alexandre Julliard 7 | * Copyright 2010 g10 Code GmbH 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 | */ 23 | 24 | 25 | #include "wine.h" 26 | #include "kernel32_kernel_private.h" 27 | 28 | 29 | void MODULE_get_binary_info (HANDLE hfile, struct binary_info *info) 30 | { 31 | union 32 | { 33 | IMAGE_DOS_HEADER mz; 34 | } header; 35 | 36 | DWORD len; 37 | 38 | memset( info, 0, sizeof(*info) ); 39 | /* Seek to the start of the file and read the header information. */ 40 | if (SetFilePointer( hfile, 0, NULL, SEEK_SET ) == -1) return; 41 | if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) return; 42 | 43 | if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) 44 | { 45 | union 46 | { 47 | IMAGE_OS2_HEADER os2; 48 | IMAGE_NT_HEADERS32 nt; 49 | } ext_header; 50 | 51 | /* We do have a DOS image so we will now try to seek into 52 | * the file by the amount indicated by the field 53 | * "Offset to extended header" and read in the 54 | * "magic" field information at that location. 55 | * This will tell us if there is more header information 56 | * to read or not. 57 | */ 58 | info->type = BINARY_DOS; 59 | if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) return; 60 | if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) return; 61 | 62 | /* Reading the magic field succeeded so 63 | * we will try to determine what type it is. 64 | */ 65 | if (!memcmp( &ext_header.nt.Signature, "PE\0\0", 4 )) 66 | { 67 | if (len >= sizeof(ext_header.nt.FileHeader)) 68 | { 69 | info->type = BINARY_PE; 70 | if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) 71 | info->flags |= BINARY_FLAG_DLL; 72 | if (len < sizeof(ext_header.nt)) /* clear remaining part of header if missing */ 73 | memset( (char *)&ext_header.nt + len, 0, sizeof(ext_header.nt) - len ); 74 | switch (ext_header.nt.OptionalHeader.Magic) 75 | { 76 | case IMAGE_NT_OPTIONAL_HDR32_MAGIC: 77 | info->res_start = (void *)(ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase; 78 | info->res_end = (void *)((ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase + 79 | ext_header.nt.OptionalHeader.SizeOfImage); 80 | break; 81 | case IMAGE_NT_OPTIONAL_HDR64_MAGIC: 82 | info->flags |= BINARY_FLAG_64BIT; 83 | break; 84 | } 85 | 86 | info->machine = ext_header.nt.FileHeader.Machine; 87 | } 88 | } 89 | } 90 | } 91 | 92 | 93 | static HMODULE load_library( LPCWSTR libname, DWORD flags ) 94 | { 95 | NTSTATUS nts; 96 | HMODULE hModule; 97 | 98 | /* We don't use any special DLL load path. */ 99 | 100 | if (flags & LOAD_LIBRARY_AS_DATAFILE) 101 | { 102 | SetLastError(ERROR_INVALID_PARAMETER); 103 | return NULL; 104 | } 105 | 106 | nts = MyLdrLoadDll( NULL, flags, libname, &hModule ); 107 | if (nts != STATUS_SUCCESS) 108 | { 109 | hModule = 0; 110 | SetLastError( MyRtlNtStatusToDosError( nts ) ); 111 | } 112 | return hModule; 113 | } 114 | 115 | 116 | HMODULE MyLoadLibraryExW(LPCWSTR libnameW, HANDLE hfile, DWORD flags) 117 | { 118 | /* We would like to use the native LoadLibraryEx, but on Windows CE 119 | that is only implemented for DLLs. Also, base addresses are 120 | restricted to the process slot, but we want to load at high 121 | addresses. */ 122 | TRACE ("MyLoadLibraryExW (\"%S\", 0x%p, 0x%x)\n", libnameW, hfile, flags); 123 | if (!libnameW) 124 | { 125 | SetLastError(ERROR_INVALID_PARAMETER); 126 | return 0; 127 | } 128 | return load_library( libnameW, flags ); 129 | } 130 | -------------------------------------------------------------------------------- /inspection/virtual-query.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | FILE *fp; 5 | 6 | void 7 | dump_mbi_header () 8 | { 9 | fprintf (fp, "alc-base alc-prot address size state protect type \n"); 10 | } 11 | 12 | 13 | void 14 | dump_protect_flags (DWORD flags) 15 | { 16 | DWORD pr = flags & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE 17 | | PAGE_EXECUTE_WRITECOPY | PAGE_READONLY 18 | | PAGE_READWRITE | PAGE_WRITECOPY); 19 | DWORD pw = flags & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY 20 | | PAGE_READWRITE | PAGE_WRITECOPY); 21 | DWORD pc = flags & (PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY); 22 | DWORD px = flags & (PAGE_EXECUTE | PAGE_EXECUTE_READ 23 | | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); 24 | 25 | fprintf (fp, "%c%c%c %c%c%c ", 26 | pr ? 'r' : '-', pc ? 'c' : (pw ? 'w' : '-'), px ? 'x' : '-', 27 | (flags & PAGE_GUARD) ? 'g' : '-', 28 | (flags & PAGE_NOCACHE) ? 'n' : '-', 29 | #ifdef PAGE_PHYSICAL 30 | (flags & PAGE_PHYSICAL) ? 'p' : 31 | #endif 32 | '-'); 33 | } 34 | 35 | 36 | void 37 | dump_state (DWORD state) 38 | { 39 | switch (state) 40 | { 41 | case MEM_COMMIT: 42 | fprintf (fp, "commit "); 43 | return; 44 | case MEM_FREE: 45 | fprintf (fp, "free "); 46 | return; 47 | case MEM_RESERVE: 48 | fprintf (fp, "reserve "); 49 | return; 50 | default: 51 | fprintf (fp, "unknown "); 52 | } 53 | } 54 | 55 | 56 | void 57 | dump_type (DWORD mtype) 58 | { 59 | switch (mtype) 60 | { 61 | case MEM_IMAGE: 62 | fprintf (fp, "image "); 63 | return; 64 | case MEM_MAPPED: 65 | fprintf (fp, "mapped "); 66 | return; 67 | case MEM_PRIVATE: 68 | fprintf (fp, "private "); 69 | return; 70 | default: 71 | fprintf (fp, "unknown "); 72 | } 73 | } 74 | 75 | 76 | void 77 | dump_mbi (PMEMORY_BASIC_INFORMATION mbi) 78 | { 79 | fprintf (fp, "0x%08x ", mbi->AllocationBase); 80 | dump_protect_flags (mbi->AllocationProtect); 81 | fprintf (fp, "0x%08x ", mbi->BaseAddress); 82 | fprintf (fp, "0x%08x ", mbi->RegionSize); 83 | dump_state (mbi->State); 84 | dump_protect_flags (mbi->Protect); 85 | dump_type (mbi->Type); 86 | fprintf (fp, "\n"); 87 | } 88 | 89 | #include 90 | #include 91 | #define MAX_PROCESSES 32 92 | 93 | DWORD GetMaxProcessNameLength( PROCESSENTRY32 lppe[MAX_PROCESSES], DWORD ProcessCount ) 94 | { 95 | DWORD index ; 96 | DWORD MaxLength = 0; 97 | DWORD CurrentLength; 98 | for( index = 0; index < ProcessCount; index++ ) 99 | { 100 | CurrentLength = wcslen( lppe[ index ].szExeFile ); 101 | if( MaxLength < CurrentLength ) 102 | MaxLength = CurrentLength; 103 | } 104 | return MaxLength; 105 | } 106 | 107 | #define TH32CS_SNAPNOHEAPS 0x40000000 108 | 109 | DWORD GetRunningProcesses( PROCESSENTRY32 *pProcess ) 110 | { 111 | HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPNOHEAPS, 0); 112 | DWORD index = 0; 113 | if(hSnapShot == (HANDLE)-1) 114 | { 115 | #if 1 116 | fprintf (fp, "GetRunningProcesses: Failed CreateToolhelp32Snapshot Error: %d\n", 117 | GetLastError()); 118 | #endif 119 | return 0; 120 | } 121 | 122 | memset(pProcess,0,sizeof(PROCESSENTRY32)); 123 | index = 0; 124 | pProcess->dwSize = sizeof(PROCESSENTRY32); 125 | if(Process32First(hSnapShot, pProcess)) 126 | { 127 | while(TRUE) 128 | { 129 | index += 1; 130 | if( index < MAX_PROCESSES ) 131 | { 132 | memcpy( pProcess + 1, pProcess, sizeof(PROCESSENTRY32)); 133 | pProcess++; 134 | if(!Process32Next(hSnapShot, pProcess)) 135 | { 136 | break; 137 | } 138 | } 139 | else 140 | { 141 | index = MAX_PROCESSES; 142 | break; 143 | } 144 | } 145 | } 146 | CloseToolhelp32Snapshot (hSnapShot); 147 | return index ; 148 | } 149 | 150 | int 151 | main (int argc, char* argv[]) 152 | { 153 | MEMORY_BASIC_INFORMATION mbi; 154 | SYSTEM_INFO si; 155 | void *addr; 156 | int skipping = 0; 157 | 158 | fp = fopen ("\\Speicherkarte\\vmemory.txt", "w"); 159 | { 160 | PROCESSENTRY32 *CurrentProcess; 161 | PROCESSENTRY32 Process[ MAX_PROCESSES ]; 162 | DWORD ProcessCount; 163 | DWORD index ; 164 | DWORD MaxProcessNameLength; 165 | // Get the list of running processes 166 | ProcessCount = GetRunningProcesses( Process ); 167 | // Get the length of the longest process name so that we can format 168 | // the output to be pretty 169 | MaxProcessNameLength = GetMaxProcessNameLength( Process, ProcessCount ); 170 | // Output a header to describe each column 171 | fprintf (fp, "%-*s %8s %13s %9s %9s %10s\n", 172 | MaxProcessNameLength, "Process", "PID", "Base Priority", "# Threads", "Base Addr", "Access Key"); 173 | 174 | // Output information for each running process 175 | for( index = 0; index < ProcessCount; index++ ) 176 | { 177 | CurrentProcess = &(Process[ index ] ); 178 | fprintf (fp, "%-*S %8X %13d %9d %9X %10X\n", 179 | MaxProcessNameLength, CurrentProcess->szExeFile, 180 | CurrentProcess->th32ProcessID, 181 | CurrentProcess->pcPriClassBase, 182 | CurrentProcess->cntThreads, 183 | CurrentProcess->th32MemoryBase, 184 | CurrentProcess->th32AccessKey 185 | ); 186 | } 187 | } 188 | 189 | memset (&si, '\0', sizeof (si)); 190 | GetSystemInfo (&si); 191 | dump_mbi_header (); 192 | 193 | addr = 0; 194 | do 195 | { 196 | DWORD res; 197 | void *new_addr; 198 | 199 | memset (&mbi, '\0', sizeof (mbi)); 200 | res = VirtualQuery (addr, &mbi, sizeof (mbi)); 201 | if (res == 0) 202 | { 203 | if (!skipping) 204 | fprintf (fp, "Skipping over %p...\n", addr); 205 | skipping = 1; 206 | new_addr = (void*)(((unsigned int)addr) + si.dwPageSize); 207 | if (new_addr < addr) 208 | break; 209 | addr = new_addr; 210 | continue; 211 | } 212 | if (res != sizeof (mbi)) 213 | { 214 | fprintf (fp, "Unexpected return size: %i (expected %i)\n", 215 | res, sizeof (mbi)); 216 | } 217 | skipping = 0; 218 | dump_mbi (&mbi); 219 | /* Check for overflow. */ 220 | new_addr = (void*)(((unsigned int)addr) + mbi.RegionSize); 221 | if (new_addr < addr) 222 | break; 223 | addr = new_addr; 224 | } 225 | while (1); 226 | 227 | /* Give ssh time to flush buffers. */ 228 | fflush (fp); 229 | fclose (fp); 230 | Sleep (300); 231 | return 0; 232 | } 233 | -------------------------------------------------------------------------------- /loader/README: -------------------------------------------------------------------------------- 1 | HiMemCE 2 | ======= 3 | 4 | HiMemCE is a high memory loader for Windows CE. It softens the 32 MB 5 | process limit by allowing the EXE to load in the large file area 6 | reserved for file mappings. This way, the EXE can be as large as free 7 | unfragmented virtual memory in that region, or free physical memory 8 | (whatever is smaller). By linking libraries statically to the 9 | program, problems with too large or too many DLLs can be avoided. 10 | 11 | The usage of the loader is very simple. 12 | 13 | 1. First, the program to be loaded has to be linked with the option 14 | /FIXED:NO (in MSVS, this setting can be found under Properties, 15 | Configuration Properties, Linker, Advanced, Fixed Base Address, choose 16 | "Generate a relocation section"). Here is a CMake example: 17 | 18 | SET_TARGET_PROPERTIES(foo PROPERTIES LINK_FLAGS " /FIXED:NO") 19 | 20 | 2. Install the program "foo" under foo-real.exe, and copy the loader's 21 | himemce.exe side-by-side to it as foo.exe. Then the loader (as 22 | foo.exe) transparently proxies all start ups of the foo program. It 23 | will automatically look for foo-real.exe and load that into high 24 | memory, continueing execution there. 25 | 26 | Contained in this package is a himemce-real.exe, that serves as an 27 | example/test program. In the special case of "himemce.exe", verbose 28 | output is on by default. 29 | 30 | How it works 31 | ------------ 32 | 33 | HiMemCE allocates a virtual memory region with VirtulAlloc 34 | (MEM_RESERVE, PAGE_NOACCESS) large enough to cover the whole image 35 | (SizeOfImage). If that is larger than 2 MB, Windows CE automatically 36 | uses the large memory area for the allocation. Then HiMemCE loads the 37 | sections into the designated place. This immediately commits all 38 | pages[1]. 39 | 40 | The image is then relocated (this is why /FIXED:NO is required). 41 | Although an attempt is made to honor the preferred base address, once 42 | all pages are copied, there is no big advantage to avoiding 43 | relocating, so setting a preferred base address (without a way to also 44 | use MapViewOfFile) is currently not recommended. 45 | 46 | The next step is to resolve imports. For this, the import section is 47 | processed, and for each DLL listed there, we use LoadLibrary to pass 48 | off the load request to the system loader. We don't do any DLL 49 | loading ourselves[1]. For every DLL loaded this way, we resolve 50 | references by GetProcAddress, which supports lookup by name as well as 51 | by ordinal. 52 | 53 | Finally, pass execution to the loaded program. Because the entry 54 | point is a normal C function, we can reuse the current thread and all 55 | its state. The first argument is the module handle of the started 56 | image. As we constructed this ourselve, there is no valid module 57 | handle for it, so we reuse the module handle of the loader as well.[3] 58 | Because this affects argv[0], we give the loader the same name as the 59 | executable we want to load (and rename the loaded executable to 60 | foo-real.exe). 61 | 62 | 63 | Footnotes 64 | 65 | [1] This is a pessimization, but because only MapViewOfFile and 66 | not MapVieOfFileEx is available, mapping in the read only sections of 67 | the file directly is difficult, and when relocating the image, many 68 | pages end up being dirty anyway. See Optimization options. 69 | 70 | [2] This avoids the complexity of sharing DLLs across applications as 71 | well as walking the dependency chain. A more complex loader, that can 72 | also load DLLs and thus effectively extend the slot 61 and 60 by 73 | further slots is feasible, but quite a bit of work. The only benefit 74 | over static linking this has is code sharing, but if we are only 75 | talking about a couple of MB, then code duplication across a small 76 | number of programs is not a big problem. And the number of processes 77 | in Windows CE is necessarily small! 78 | 79 | [3] Note that this could confuse some programs that do deep 80 | introspection and want to manually load custom sections or do other 81 | magic. 82 | 83 | 84 | TODO 85 | ---- 86 | 87 | * Switch off verbose output for non-himemce.exe named copies of 88 | the loader (but allow a switch --himemce-log to switch it back on). 89 | 90 | * Show load errors in a diagnostic window for the user. 91 | 92 | * Handle DISCARDABLE flag? 93 | 94 | 95 | Optimization options 96 | -------------------- 97 | 98 | * Physical memory pressure can be relieved by trying to use 99 | MapViewOfFile opportunistically (create relocated image, save to 100 | temporary file, map it). 101 | 102 | * Handle DISCARDABLE sections (if any). 103 | 104 | 105 | How it works (DLL version) 106 | -------------------------- 107 | 108 | The preloader (himemce-pre) should be run when the device starts up, 109 | and must be run before any program is loaded high with himemce. It 110 | preloads the DLLs that should be loaded high. 111 | 112 | Note that these DLLs are unknown to the system and can only be used by 113 | himemce. This means that any program resp. DLL that depends on a high 114 | loaded DLL must be loaded by himemce resp. himemce-pre as well. 115 | Further note that himemce can not generate stub code for ARM, so ARM 116 | DLLs such as gpgme, gpg-error etc can not be preloaded and should be 117 | exempted. 118 | 119 | The himemce-pre program looks for all .dll files in its directory and 120 | preloads them, unless they are in the blacklist (FIXME: implement and 121 | document blacklist mechanism). 122 | 123 | The preloader performs the following steps: 124 | 125 | 1. For all preloaded DLLs, map them to high memory without resolving 126 | their references. 127 | 128 | 2. For all preloaded DLLs, identify sections that are writable and 129 | thus need to be allocated per process. For these DLLs, reserve some 130 | memory in a continuous range at the bottom of the process address 131 | space (_HIMEMCE_MAP_LOW_BASE == 2 MB). Also rewrite all base 132 | relocations that point into these sections to point to the low memory 133 | instead. 134 | 135 | 3. For all preloaded DLLs, import their dependencies. For DLLs 136 | managed by himemce-pre, this will resolve to the entry points in the 137 | high loaded DLLs (adjusting entry points into writable section to 138 | their low memory variant). For system managed DLLs, use the normal 139 | LoadLibrary/GetProcAddressA mechanism. 140 | 141 | 4. Map the data structures describing all this to a shared memory 142 | region named HIMEMCE_MAP_NAME == L"himemcemap". This can be accessed 143 | by himemce. 144 | 145 | 5. Sleep forever. It is important that this process does not exit, 146 | because if this was the last user of HIMEMCE_MAP_NAME, the preloaded 147 | libraries will be deallocated. 148 | 149 | These steps must be executed for programs that run with preloaded 150 | DLLs (done by himemce): 151 | 152 | 1. At startup, reserve the low memory sections. 153 | 154 | 2. For each preloaded DLL, copy its writable sections to the process 155 | memory reserved in step 1. 156 | 157 | 3. For each system DLL that is used by preloaded DLLs, call 158 | LoadLibrary to copy their writable sections into the process memory. 159 | 160 | 4. For each preloaded DLL, call DllMain (their entry point). 161 | 162 | [5. TODO: Load a himemce.dll library that calls these DllMain's for 163 | each Thread in its DllMain.] 164 | 165 | 166 | Copyright 2010 g10 Code GmbH 167 | 168 | This file is free software; as a special exception the author gives 169 | unlimited permission to copy and/or distribute it, with or without 170 | modifications, as long as this notice is preserved. 171 | 172 | This file is distributed in the hope that it will be useful, but 173 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 174 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 175 | -------------------------------------------------------------------------------- /loader/server_mapping.c: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/server/mapping.c */ 2 | 3 | /* 4 | * Server-side file mapping management 5 | * 6 | * Copyright (C) 1999 Alexandre Julliard 7 | * Copyright 2010 g10 Code GmbH 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 | */ 23 | 24 | #include "wine.h" 25 | #include 26 | 27 | /* These are always the same. */ 28 | # define page_mask 0xfff 29 | # define page_shift 12 30 | # define init_page_size() do { /* nothing */ } while(0) 31 | 32 | #define set_error(x) SetLastError(x) 33 | 34 | #define ROUND_SIZE(size) (((size) + page_mask) & ~page_mask) 35 | 36 | 37 | 38 | struct mapping 39 | { 40 | void *obj; 41 | mem_size_t size; /* mapping size */ 42 | int protect; /* protection flags */ 43 | HANDLE *fhnd; /* handle for file */ 44 | HANDLE *hnd; /* handle for mapped file */ 45 | int header_size; /* size of headers (for PE image mapping) */ 46 | void *base; /* default base addr (for PE image mapping) */ 47 | }; 48 | 49 | 50 | 51 | /* retrieve the mapping parameters for an executable (PE) image */ 52 | static int get_image_params( struct mapping *mapping, HANDLE unix_fd ) 53 | { 54 | IMAGE_DOS_HEADER dos; 55 | IMAGE_SECTION_HEADER *sec = NULL; 56 | struct 57 | { 58 | DWORD Signature; 59 | IMAGE_FILE_HEADER FileHeader; 60 | union 61 | { 62 | IMAGE_OPTIONAL_HEADER32 hdr32; 63 | IMAGE_OPTIONAL_HEADER64 hdr64; 64 | } opt; 65 | } nt; 66 | off_t pos; 67 | int size; 68 | 69 | /* load the headers */ 70 | 71 | if (pread( unix_fd, (char *) &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error; 72 | if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error; 73 | pos = dos.e_lfanew; 74 | 75 | size = pread( unix_fd, (char *) &nt, sizeof(nt), pos ); 76 | if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) goto error; 77 | /* zero out Optional header in the case it's not present or partial */ 78 | if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size ); 79 | if (nt.Signature != IMAGE_NT_SIGNATURE) goto error; 80 | 81 | switch (nt.opt.hdr32.Magic) 82 | { 83 | case IMAGE_NT_OPTIONAL_HDR32_MAGIC: 84 | mapping->size = ROUND_SIZE( nt.opt.hdr32.SizeOfImage ); 85 | mapping->base = (void *) nt.opt.hdr32.ImageBase; 86 | mapping->header_size = nt.opt.hdr32.SizeOfHeaders; 87 | break; 88 | case IMAGE_NT_OPTIONAL_HDR64_MAGIC: 89 | mapping->size = ROUND_SIZE( nt.opt.hdr64.SizeOfImage ); 90 | mapping->base = (void *) nt.opt.hdr64.ImageBase; 91 | mapping->header_size = nt.opt.hdr64.SizeOfHeaders; 92 | break; 93 | default: 94 | goto error; 95 | } 96 | 97 | /* load the section headers */ 98 | 99 | pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader; 100 | size = sizeof(*sec) * nt.FileHeader.NumberOfSections; 101 | if (pos + size > mapping->size) goto error; 102 | if (pos + size > mapping->header_size) mapping->header_size = pos + size; 103 | if (!(sec = malloc( size ))) goto error; 104 | if (pread( unix_fd, (void *) sec, size, pos ) != size) goto error; 105 | 106 | // if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error; 107 | 108 | // if (mapping->shared_file) list_add_head( &shared_list, &mapping->shared_entry ); 109 | 110 | mapping->protect = VPROT_IMAGE; 111 | free( sec ); 112 | return 1; 113 | 114 | error: 115 | free( sec ); 116 | set_error( STATUS_INVALID_FILE_FOR_SECTION ); 117 | return 0; 118 | } 119 | 120 | 121 | void *create_mapping(/* struct directory *root */ void *root, 122 | /* const struct unicode_str *name */ void *name, 123 | unsigned int attr, mem_size_t size, int protect, 124 | HANDLE handle, /* const struct security_descriptor *sd */ void *sd) 125 | { 126 | struct mapping *mapping; 127 | #if 0 128 | struct file *file; 129 | struct fd *fd; 130 | #endif 131 | int access = 0; 132 | #if 0 133 | int unix_fd; 134 | #endif 135 | 136 | if (!page_mask) init_page_size(); 137 | 138 | if (!(mapping = malloc (sizeof (struct mapping)))) 139 | return NULL; 140 | 141 | mapping->obj = NULL; 142 | mapping->header_size = 0; 143 | mapping->base = 0; 144 | mapping->fhnd = handle; 145 | mapping->hnd = 0; 146 | 147 | if (protect & VPROT_READ) access |= FILE_READ_DATA; 148 | if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA; 149 | 150 | if (handle) 151 | { 152 | // unsigned int mapping_access = FILE_MAPPING_ACCESS; 153 | 154 | if (!(protect & VPROT_COMMITTED)) 155 | { 156 | SetLastError( STATUS_INVALID_PARAMETER ); 157 | goto error; 158 | } 159 | 160 | mapping->hnd = CreateFileMapping (handle, NULL, get_prot_flags (protect), 161 | 0, size, NULL); 162 | if (mapping->hnd == INVALID_HANDLE_VALUE) 163 | goto error; 164 | 165 | #if 0 166 | /* file sharing rules for mappings are different so we use magic the access rights */ 167 | if (protect & VPROT_IMAGE) mapping_access |= FILE_MAPPING_IMAGE; 168 | else if (protect & VPROT_WRITE) mapping_access |= FILE_MAPPING_WRITE; 169 | #endif 170 | 171 | if (protect & VPROT_IMAGE) 172 | { 173 | if (!get_image_params( mapping, handle )) goto error; 174 | return &mapping->obj; 175 | } 176 | #if 0 177 | if (fstat( unix_fd, &st ) == -1) 178 | { 179 | file_set_error(); 180 | goto error; 181 | } 182 | if (!size) 183 | { 184 | if (!(size = st.st_size)) 185 | { 186 | set_error( STATUS_MAPPED_FILE_SIZE_ZERO ); 187 | goto error; 188 | } 189 | } 190 | else if (st.st_size < size && !grow_file( unix_fd, size )) goto error; 191 | #endif 192 | } 193 | else /* Anonymous mapping (no associated file) */ 194 | { 195 | #if 0 196 | if (!size || (protect & VPROT_IMAGE)) 197 | { 198 | set_error( STATUS_INVALID_PARAMETER ); 199 | goto error; 200 | } 201 | if (!(protect & VPROT_COMMITTED)) 202 | { 203 | if (!(mapping->committed = mem_alloc( offsetof(struct ranges, ranges[8]) ))) goto error; 204 | mapping->committed->count = 0; 205 | mapping->committed->max = 8; 206 | } 207 | if ((unix_fd = create_temp_file( size )) == -1) goto error; 208 | if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj, 209 | FILE_SYNCHRONOUS_IO_NONALERT ))) goto error; 210 | #endif 211 | assert (!"Not implemented."); 212 | } 213 | mapping->size = (size + page_mask) & ~((mem_size_t)page_mask); 214 | mapping->protect = protect; 215 | return &mapping->obj; 216 | 217 | error: 218 | free( mapping ); 219 | return NULL; 220 | } 221 | 222 | 223 | /* create a file mapping */ 224 | NTSTATUS SERVER_create_mapping (ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, 225 | HANDLE file_handle, long long size, unsigned int protect, HANDLE *handle) 226 | { 227 | void *obj; 228 | 229 | *handle = 0; 230 | 231 | obj = create_mapping( NULL, NULL, 0, (mem_size_t) size, protect, file_handle, NULL ); 232 | if (! obj) 233 | return GetLastError (); 234 | 235 | *handle = (HANDLE)obj; 236 | 237 | return STATUS_SUCCESS; 238 | } 239 | 240 | 241 | NTSTATUS SERVER_get_mapping_info (HANDLE _mapping, ACCESS_MASK access, unsigned int *protect, 242 | void **base, mem_size_t *size, int *header_size, HANDLE *fhandle, 243 | HANDLE *handle) 244 | { 245 | struct mapping *mapping = (struct mapping *) _mapping; 246 | 247 | /* Ignore access. */ 248 | 249 | *size = mapping->size; 250 | *protect = mapping->protect; 251 | *fhandle = mapping->fhnd; 252 | *handle = mapping->hnd; 253 | *header_size = mapping->header_size; 254 | *base = mapping->base; 255 | 256 | return STATUS_SUCCESS; 257 | } 258 | 259 | -------------------------------------------------------------------------------- /inspection/virtual-query-imager.py: -------------------------------------------------------------------------------- 1 | import fileinput 2 | import Image, ImageDraw, ImageFont, ImageOps 3 | 4 | 5 | # Pagesize 6 | psize = 4096 7 | 8 | # A column is 32MB 9 | p_per_col = 32*1024*1024/psize 10 | # 4 GB address space. 11 | slots = 2*1024*1024*1024/psize/p_per_col 12 | 13 | slotwidth = 60 14 | pheight = 1 15 | 16 | # colors: 17 | 18 | size = p_per_col * pheight, slotwidth * slots 19 | 20 | im = Image.new ("RGB", size) 21 | 22 | draw = ImageDraw.Draw(im) 23 | draw.rectangle ((0,0) + im.size, fill="#ffffff") 24 | 25 | 26 | def getcolor (state, prot, prot_, type): 27 | if state == "free": 28 | return "#cccccc" 29 | if state == "reserve": 30 | if type == "image": 31 | return "#88ff88" 32 | if type == "private": 33 | return "#ff8888" 34 | if type == "mapped": 35 | return "#8888ff" 36 | return "#ffff00" 37 | if state == "commit": 38 | if type == "image": 39 | return "#44dd44" 40 | if type == "private": 41 | return "#dd4444" 42 | if type == "mapped": 43 | return "#4444dd" 44 | return "#ffff00" 45 | return "#ffff00" 46 | 47 | # alc-base alc-prot address size state protect type 48 | # 0x00000000 --- --- 0x00001000 0x0000f000 free --- --- unknown 49 | # 0x00010000 --- --- 0x00014000 0x0000a000 reserve --- --- image 50 | # 0x00000000 --- --- 0x0001e000 0x017a2000 free --- --- unknown 51 | # 0x017c0000 --- --- 0x017c0000 0x000fe000 reserve --- --- private 52 | # 0x017c0000 --- --- 0x018be000 0x00002000 commit rw- --- private 53 | # 0x018c0000 --- --- 0x018c0000 0x00002000 commit rw- -n- private 54 | 55 | 56 | def upperleft (col, row): 57 | col = slots - col - 1 58 | return (row * pheight, col * slotwidth) 59 | 60 | def lowerright (col, row): 61 | col = slots - col - 1 62 | return ((row + 1) * pheight - 1, (col + 1) * slotwidth - 1) 63 | 64 | 65 | def drawit_ (draw, pstart, pstop, state, prot, prot_, type): 66 | col = pstart / p_per_col 67 | pstart = pstart - col * p_per_col 68 | # inclusive now 69 | pstop = (pstop - col * p_per_col) - 1 70 | 71 | # Same col for pstop, ensured by drawit 72 | color = getcolor (state, prot, prot_, type) 73 | draw.rectangle (upperleft(col, pstop) + lowerright (col, pstart), 74 | color) 75 | 76 | 77 | def drawit (draw, addr, size, state, prot, prot_, type): 78 | if addr >= 2*1024*1024*1024: 79 | return 80 | 81 | end = addr + size 82 | while addr < end: 83 | next = ((addr + p_per_col) / p_per_col) * p_per_col 84 | if next > end: 85 | next = end 86 | drawit_ (draw, addr, next, state, prot, prot_, type) 87 | addr = next 88 | 89 | process = [''] * 32 90 | threads = [0] * 32 91 | mode = 0 92 | for line in fileinput.input(): 93 | if mode == 0: 94 | field = line.split(); 95 | if field[0] == "alc-base": 96 | mode = 1 97 | continue 98 | if field[0] == "Process": 99 | continue 100 | # Process PID Base Priority # Threads Base Addr Access Key 101 | # NK.EXE FFFF002 3 2 C2000000 1 102 | # filesys.exe FFEEE5E 3 18 4000000 2 103 | # akonadi_agent_server 6CD3C9B6 3 1 6000000 4 104 | base = int(field[4], 16) 105 | idx = base / (32*1024*1024) - 2; 106 | if idx >= 0 and idx < 32: 107 | process[idx] = field[0] 108 | threads[idx] = int(field[3]) 109 | else: 110 | if line[0] != '0': 111 | continue 112 | # alc-base alc-prot address size state protect type 113 | # 0x00000000 --- --- 0x00001000 0x0000f000 free --- --- unknown 114 | # 0x00010000 --- --- 0x00014000 0x0000a000 reserve --- --- image 115 | # 0x00000000 --- --- 0x0001e000 0x017a2000 free --- --- unknown 116 | # 0x017c0000 --- --- 0x017c0000 0x000fe000 reserve --- --- private 117 | # 0x017c0000 --- --- 0x018be000 0x00002000 commit rw- --- private 118 | # 0x018c0000 --- --- 0x018c0000 0x00002000 commit rw- -n- private 119 | 120 | fields = line.split() 121 | addr, size, state, prot, prot_, type = fields[3:] 122 | addr = int(addr, 16) / 4096 123 | size = int(size, 16) / 4096 124 | 125 | drawit (draw, addr, size, state, prot, prot_, type) 126 | 127 | 128 | # Create grid. 129 | for col in xrange(slots): 130 | draw.line ((0, col*slotwidth) + (im.size[0], col*slotwidth), fill="#666666") 131 | for col in xrange(3): 132 | draw.rectangle ((0, (col+1)*(slots/4)*slotwidth - slotwidth/16) 133 | + (im.size[0], (col+1)*(slots/4)*slotwidth + slotwidth/16), fill="#666666") 134 | for row in xrange(31): 135 | draw.line (((row+1)*(p_per_col/32)*pheight, 0) + (((row+1)*(p_per_col/32))*pheight, im.size[1]), fill="#666666") 136 | 137 | del draw 138 | 139 | # Compose documented image. 140 | fsize = (im.size[0] + 30 * slotwidth, im.size[1] + 6 * slotwidth) 141 | ulpaste = (28*slotwidth, 3*slotwidth) 142 | fim = Image.new ("RGB", fsize) 143 | draw = ImageDraw.Draw(fim) 144 | 145 | draw.rectangle ((0,0) + fim.size, fill="#ffffff") 146 | draw.rectangle ((ulpaste[0]-2, ulpaste[1]-2) + (ulpaste[0] + im.size[0] + 2, ulpaste[1] + im.size[1] + 2), fill="#000000") 147 | fim.paste (im, ulpaste) 148 | 149 | fs = int (slotwidth * 2 / 3) 150 | dpf = ImageFont.truetype ("datapro.ttf", int(fs * 1.5)) 151 | draw.text((slotwidth/2,slotwidth), "Virtual Memory Map of Windows CE", fill="#000000", font=dpf) 152 | 153 | dpf = ImageFont.truetype ("datapro.ttf", fs) 154 | 155 | def getrow(i): 156 | return 5 + ulpaste[1] + im.size[1] - slotwidth * (i + 1) 157 | 158 | for i in xrange(slots): 159 | draw.text ((ulpaste[0] - 6 * slotwidth, getrow(i) ), 160 | "0x%08x" % (i * 0x02000000), fill="#444444", font=dpf) 161 | 162 | for row in xrange(32): 163 | txt=Image.new("L", (600,60)) 164 | d = ImageDraw.Draw(txt) 165 | d.text ((0,0), "0x%08x" % (row * 0x00100000), fill=255, font=dpf) 166 | del d 167 | rtxt = txt.rotate (17.5, expand=1) 168 | fim.paste (ImageOps.colorize(rtxt, "#ffffff", "#444444"), 169 | (ulpaste[0] + (row*(p_per_col/32)*pheight), ulpaste[1] - 4*slotwidth), rtxt) 170 | del txt 171 | del rtxt 172 | 173 | #draw.text ((ulpaste[0] + 0x00011000 * p_per_col*pheight / (32*1024*1024), ulpaste[1] + 65*slotwidth), 174 | # "Code/Data", fill="#000000", font=dpf) 175 | #draw.text ((ulpaste[0] + 0x018C0000 * p_per_col*pheight / (32*1024*1024), ulpaste[1] + 65*slotwidth), 176 | # "Stack/Heap", fill="#000000", font=dpf) 177 | 178 | 179 | def writerow(i, str): 180 | draw.text ((10 * slotwidth, getrow(i) ), str, fill="#000000", font=dpf) 181 | 182 | writerow (0, "Slot 0: Active Process") 183 | writerow (1, "Slot 1: ROM Image") 184 | for i in xrange (31): 185 | writerow (2 + i, "Slot %2i: Process %i" % (i + 2, i)) 186 | if process[i] != "": 187 | if threads[i] > 1: 188 | writerow (2 + i, " %s (%i threads)" % (process[i], threads[i])) 189 | else: 190 | writerow (2 + i, " %s" % (process[i])) 191 | for i in xrange (26): 192 | writerow (33 + i, "Slot %2i: Shared Area" % (33 + i)) 193 | writerow (59, "Slot 59: Driver Stacks") 194 | writerow (60, "Slot 60: Large DLLs") 195 | writerow (61, "Slot 61: Large DLLs") 196 | writerow (62, "Slot 62: Shared Heaps") 197 | writerow (63, "Slot 63: Resource DLLs") 198 | 199 | def writelegend(i, col, str): 200 | draw.rectangle ((1 * slotwidth, getrow(63-i), 2 * slotwidth - 10, getrow(63-i - 1) - 10), fill=col) 201 | draw.rectangle ((1 * slotwidth, getrow(63-i), 2 * slotwidth - 10, getrow(63-i - 1) - 10), outline="#444444") 202 | draw.text ((2 * slotwidth, getrow(63-i) ), str, fill="#000000", font=dpf) 203 | 204 | writelegend(0, "#ffffff", "unused") 205 | writelegend(1, getcolor("free", 0, 0, ""), "free") 206 | writelegend(2, getcolor("reserve", 0, 0, "image"), "image") 207 | writelegend(3, getcolor("commit", 0, 0, "image"), "... committed") 208 | writelegend(4, getcolor("reserve", 0, 0, "private"), "private") 209 | writelegend(5, getcolor("commit", 0, 0, "private"), "... committed") 210 | writelegend(6, getcolor("reserve", 0, 0, "mapped"), "mapped") 211 | writelegend(7, getcolor("commit", 0, 0, "mapped"), "... committed") 212 | 213 | def writeextra(i, str): 214 | draw.text ((1 * slotwidth, getrow(63-i) ), str, fill="#000000", font=dpf) 215 | writeextra(9, "1px = 4 KB") 216 | 217 | 218 | del draw 219 | fim.save("output.png", "PNG") 220 | -------------------------------------------------------------------------------- /loader/himemce-pre.c: -------------------------------------------------------------------------------- 1 | /* himemce-pre.c - High Memory for Windows CE (preloader) 2 | Copyright (C) 2010 g10 Code GmbH 3 | Written by Marcus Brinkmann 4 | 5 | This file is part of HiMemCE. 6 | 7 | HiMemCE is free software; you can redistribute it and/or modify it 8 | under the terms of the GNU Lesser General Public License as 9 | published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | HiMemCE is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 | 02111-1307, USA. */ 21 | 22 | #include 23 | #include 24 | 25 | #include "debug.h" 26 | 27 | #include "kernel32_kernel_private.h" 28 | #include "wine.h" 29 | #include "himemce-map-provider.h" 30 | 31 | 32 | # define page_mask 0xfff 33 | # define page_shift 12 34 | # define page_size 0x1000 35 | 36 | #define ROUND_SIZE(size) \ 37 | (((SIZE_T)(size) + page_mask) & ~page_mask) 38 | 39 | #define SECTION_IS_LOW(sec) \ 40 | (((sec)->Characteristics & IMAGE_SCN_MEM_WRITE) && \ 41 | ! ((sec)->Characteristics & IMAGE_SCN_MEM_SHARED)) 42 | 43 | 44 | /* Find all modules to preload and add them to the map. */ 45 | static int 46 | find_modules (struct himemce_map *map) 47 | { 48 | /* Five for "*.dll" and one for good luck. */ 49 | wchar_t dirname[MAX_PATH + 6]; 50 | wchar_t filename[2 * MAX_PATH + 1]; 51 | int res; 52 | wchar_t *end; 53 | int idx; 54 | HANDLE hSearch; 55 | WIN32_FIND_DATA FileData; 56 | BOOL bFinished = FALSE; 57 | 58 | res = GetModuleFileName (GetModuleHandle (NULL), dirname, MAX_PATH); 59 | if (! res) 60 | { 61 | ERR ("can not determine module filename: %i\n", 62 | GetLastError ()); 63 | return 0; 64 | } 65 | 66 | idx = wcslen (dirname); 67 | while (idx > 0 && dirname[idx - 1] != '\\' && dirname[idx - 1] != '/') 68 | idx--; 69 | dirname[idx] = '\0'; 70 | 71 | wcscpy (filename, dirname); 72 | wcscpy (&dirname[idx], L"*.dll"); 73 | end = &filename[idx]; 74 | 75 | hSearch = FindFirstFile (dirname, &FileData); 76 | if (hSearch == INVALID_HANDLE_VALUE) 77 | { 78 | ERR ("no .dll files found\n"); 79 | return 0; 80 | } 81 | 82 | while (!bFinished) 83 | { 84 | struct himemce_module *mod; 85 | struct binary_info info; 86 | HANDLE hnd; 87 | 88 | TRACE ("considering %S: ", FileData.cFileName); 89 | 90 | wcscpy (end, FileData.cFileName); 91 | 92 | if (FileData.cFileName[0] != L'Q') 93 | { 94 | TRACE ("skip non-Qt library for testing\n"); 95 | goto skipit; 96 | } 97 | 98 | hnd = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL, 99 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 100 | if (hnd == INVALID_HANDLE_VALUE) 101 | { 102 | TRACE ("skip (probe failure: %i)\n", GetLastError ()); 103 | goto skipit; 104 | } 105 | 106 | MODULE_get_binary_info (hnd, &info); 107 | CloseHandle (hnd); 108 | if (info.machine != IMAGE_FILE_MACHINE_THUMB) 109 | { 110 | TRACE ("skip (machine type: %04x)\n", info.machine); 111 | goto skipit; 112 | } 113 | 114 | /* FIXME: Keep a blacklist. Maybe exclude ARM (not THUMB) 115 | binaries automatically (gpgme and friends). */ 116 | 117 | TRACE ("accept [%2i]\n", map->nr_modules); 118 | mod = map_add_module (map, filename, 0); 119 | if (! mod) 120 | return 0; 121 | 122 | skipit: 123 | if (!FindNextFile (hSearch, &FileData)) 124 | { 125 | bFinished = TRUE; 126 | 127 | if (GetLastError () != ERROR_NO_MORE_FILES) 128 | { 129 | ERR ("unable to find next .dll file\n"); 130 | return 0; 131 | } 132 | } 133 | } 134 | if (!FindClose (hSearch)) 135 | { 136 | ERR ("unable to close search handle: %i\n", GetLastError ()); 137 | return 0; 138 | } 139 | return 1; 140 | } 141 | 142 | 143 | static SIZE_T 144 | section_size (IMAGE_SECTION_HEADER *sec) 145 | { 146 | static const SIZE_T sector_align = 0x1ff; 147 | SIZE_T map_size, file_size, end; 148 | 149 | if (!sec->Misc.VirtualSize) 150 | map_size = ROUND_SIZE( sec->SizeOfRawData ); 151 | else 152 | map_size = ROUND_SIZE( sec->Misc.VirtualSize ); 153 | 154 | file_size = (sec->SizeOfRawData + (sec->PointerToRawData & sector_align) + sector_align) & ~sector_align; 155 | if (file_size > map_size) file_size = map_size; 156 | end = ROUND_SIZE( file_size ); 157 | if (end > map_size) end = map_size; 158 | return end; 159 | } 160 | 161 | 162 | static void * 163 | get_rva_low (char *module, size_t rva) 164 | { 165 | IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)module; 166 | IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(module + dos->e_lfanew); 167 | IMAGE_SECTION_HEADER *sec; 168 | int sec_cnt; 169 | int idx; 170 | 171 | sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader); 172 | sec_cnt = nt->FileHeader.NumberOfSections; 173 | 174 | for (idx = 0; idx < sec_cnt; idx++) 175 | { 176 | if (! sec[idx].PointerToLinenumbers) 177 | continue; 178 | if (rva >= sec[idx].VirtualAddress 179 | && rva < sec[idx].VirtualAddress + section_size (&sec[idx])) 180 | break; 181 | } 182 | if (idx == sec_cnt) 183 | return (void *)((char *)module + rva); 184 | 185 | return (void *)((char *)sec[idx].PointerToLinenumbers 186 | + (rva - sec[idx].VirtualAddress)); 187 | } 188 | 189 | 190 | static IMAGE_BASE_RELOCATION * 191 | LowLdrProcessRelocationBlock (void *base, void *page, UINT count, 192 | USHORT *relocs) 193 | { 194 | char *ptr; 195 | IMAGE_DOS_HEADER *dos; 196 | IMAGE_NT_HEADERS *nt; 197 | IMAGE_SECTION_HEADER *sec; 198 | int sec_cnt; 199 | int idx; 200 | 201 | ptr = base; 202 | dos = (IMAGE_DOS_HEADER *) ptr; 203 | nt = (IMAGE_NT_HEADERS *) (ptr + dos->e_lfanew); 204 | sec = (IMAGE_SECTION_HEADER *) ((char*) &nt->OptionalHeader 205 | + nt->FileHeader.SizeOfOptionalHeader); 206 | sec_cnt = nt->FileHeader.NumberOfSections; 207 | idx = sec_cnt; 208 | 209 | /* Small optimization: Exclude read-only sections at the start and 210 | end of the list. */ 211 | while (sec_cnt > 0 && SECTION_IS_LOW (sec)) 212 | { 213 | sec++; 214 | sec_cnt--; 215 | } 216 | while (sec_cnt > 0 && SECTION_IS_LOW (&sec[sec_cnt - 1])) 217 | sec_cnt--; 218 | 219 | while (count--) 220 | { 221 | USHORT offset = *relocs & 0xfff; 222 | int type = *relocs >> 12; 223 | size_t addr; 224 | size_t old_addr; 225 | size_t off; 226 | 227 | switch(type) 228 | { 229 | case IMAGE_REL_BASED_ABSOLUTE: 230 | goto nextreloc; 231 | case IMAGE_REL_BASED_HIGH: 232 | addr = HIWORD (*(short *)((char *)page + offset)); 233 | break; 234 | case IMAGE_REL_BASED_LOW: 235 | addr = LOWORD (*(short *)((char *)page + offset)); 236 | break; 237 | case IMAGE_REL_BASED_HIGHLOW: 238 | addr = *(int *)((char *)page + offset); 239 | break; 240 | default: 241 | TRACE("Unknown/unsupported fixup type %x.\n", type); 242 | goto nextreloc; 243 | } 244 | 245 | if ((void *) addr < base) 246 | { 247 | ERR ("ignoring relocation that points below image"); 248 | goto nextreloc; 249 | } 250 | off = ((char *) addr) - ((char *) base); 251 | 252 | /* Check if ADDR points into a rw segment. First check the 253 | cached index. */ 254 | if (idx < sec_cnt) 255 | { 256 | if (off >= sec[idx].VirtualAddress 257 | && off < sec[idx].VirtualAddress + section_size (&sec[idx])) 258 | ; /* Found it. */ 259 | else 260 | idx = sec_cnt; 261 | } 262 | if (idx == sec_cnt) 263 | { 264 | for (idx = 0; idx < sec_cnt; idx++) 265 | { 266 | if (! sec[idx].PointerToLinenumbers) 267 | continue; 268 | if (off >= sec[idx].VirtualAddress 269 | && off < sec[idx].VirtualAddress + section_size (&sec[idx])) 270 | break; 271 | } 272 | if (idx == sec_cnt) 273 | goto nextreloc; 274 | } 275 | old_addr = addr; 276 | addr = sec[idx].PointerToLinenumbers + (off - sec[idx].VirtualAddress); 277 | 278 | #if 0 279 | TRACE ("rewriting relocation at %p to rw section from %p to %p\n", 280 | ((char *)page + offset), old_addr, addr); 281 | #endif 282 | 283 | switch(type) 284 | { 285 | case IMAGE_REL_BASED_HIGH: 286 | *(short *)((char *)page + offset) = HIWORD(addr); 287 | break; 288 | case IMAGE_REL_BASED_LOW: 289 | *(short *)((char *)page + offset) = LOWORD(addr); 290 | break; 291 | case IMAGE_REL_BASED_HIGHLOW: 292 | *(int *)((char *)page + offset) = addr; 293 | break; 294 | } 295 | nextreloc: 296 | relocs++; 297 | } 298 | return (IMAGE_BASE_RELOCATION *)relocs; /* return address of next block */ 299 | } 300 | 301 | 302 | static void 303 | relocate_rw_sections (struct himemce_map *map, void *base) 304 | { 305 | char *ptr; 306 | IMAGE_DOS_HEADER *dos; 307 | IMAGE_NT_HEADERS *nt; 308 | IMAGE_SECTION_HEADER *sec; 309 | int i; 310 | IMAGE_BASE_RELOCATION *rel, *end; 311 | const IMAGE_DATA_DIRECTORY *relocs; 312 | 313 | TRACE ("adjusting rw sections at %p\n", base); 314 | 315 | ptr = base; 316 | dos = (IMAGE_DOS_HEADER *) ptr; 317 | nt = (IMAGE_NT_HEADERS *) (ptr + dos->e_lfanew); 318 | sec = (IMAGE_SECTION_HEADER *) ((char*) &nt->OptionalHeader 319 | + nt->FileHeader.SizeOfOptionalHeader); 320 | 321 | /* Go through all the sections, reserve low memory for the writable 322 | sections. */ 323 | for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) 324 | { 325 | if (SECTION_IS_LOW (sec)) 326 | { 327 | SIZE_T map_size; 328 | 329 | if (! sec->Misc.VirtualSize) 330 | map_size = ROUND_SIZE (sec->SizeOfRawData); 331 | else 332 | map_size = ROUND_SIZE (sec->Misc.VirtualSize); 333 | 334 | sec->PointerToLinenumbers = (DWORD) map_reserve_low (map, map_size); 335 | 336 | TRACE ("mapping r/w section %.8s at %p off %x (%lx) flags " 337 | "%x to low mem %p\n", 338 | sec->Name, ptr + sec->VirtualAddress, 339 | sec->PointerToRawData, map_size, 340 | sec->Characteristics, sec->PointerToLinenumbers); 341 | } 342 | else 343 | sec->PointerToLinenumbers = 0; 344 | } 345 | 346 | /* Perform base relocations pointing into low sections. Before 347 | that, these relocations point into the high mem address. */ 348 | 349 | relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 350 | rel = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress); 351 | end = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress + relocs->Size); 352 | 353 | while (rel < end - 1 && rel->SizeOfBlock) 354 | { 355 | rel = LowLdrProcessRelocationBlock 356 | (base, ptr + rel->VirtualAddress, 357 | (rel->SizeOfBlock - sizeof (*rel)) / sizeof (USHORT), 358 | (USHORT *)(rel + 1)); 359 | } 360 | } 361 | 362 | 363 | /* convert PE image VirtualAddress to Real Address */ 364 | static void * 365 | get_rva (HMODULE module, DWORD va) 366 | { 367 | return (void *) ((char *) module + va); 368 | } 369 | 370 | 371 | /* convert from straight ASCII to Unicode without depending on the 372 | current codepage */ 373 | static void 374 | ascii_to_unicode (WCHAR *dst, const char *src, size_t len) 375 | { 376 | while (len--) 377 | *dst++ = (unsigned char) *src++; 378 | } 379 | 380 | 381 | #define allocate_stub(x,y) ((void *)0xdeadbeef) 382 | 383 | 384 | static FARPROC 385 | find_ordinal_export (void *module, const IMAGE_EXPORT_DIRECTORY *exports, 386 | DWORD exp_size, DWORD ordinal) 387 | { 388 | FARPROC proc; 389 | const DWORD *functions = get_rva (module, exports->AddressOfFunctions); 390 | 391 | if (ordinal >= exports->NumberOfFunctions) 392 | { 393 | TRACE(" ordinal %d out of range!\n", ordinal + exports->Base ); 394 | return NULL; 395 | } 396 | if (!functions[ordinal]) return NULL; 397 | 398 | #if 0 399 | /* if the address falls into the export dir, it's a forward */ 400 | if (((const char *)proc >= (const char *)exports) && 401 | ((const char *)proc < (const char *)exports + exp_size)) 402 | return find_forwarded_export( module, (const char *)proc, load_path ); 403 | #endif 404 | 405 | proc = get_rva_low (module, functions[ordinal]); 406 | return proc; 407 | } 408 | 409 | 410 | static FARPROC 411 | find_named_export (void *module, const IMAGE_EXPORT_DIRECTORY *exports, 412 | DWORD exp_size, const char *name, int hint) 413 | { 414 | const WORD *ordinals = get_rva (module, exports->AddressOfNameOrdinals); 415 | const DWORD *names = get_rva (module, exports->AddressOfNames); 416 | int min = 0, max = exports->NumberOfNames - 1; 417 | 418 | /* first check the hint */ 419 | if (hint >= 0 && hint <= max) 420 | { 421 | char *ename = get_rva( module, names[hint] ); 422 | if (!strcmp( ename, name )) 423 | return find_ordinal_export( module, exports, exp_size, ordinals[hint]); 424 | } 425 | 426 | /* then do a binary search */ 427 | while (min <= max) 428 | { 429 | int res, pos = (min + max) / 2; 430 | char *ename = get_rva( module, names[pos] ); 431 | if (!(res = strcmp( ename, name ))) 432 | return find_ordinal_export( module, exports, exp_size, ordinals[pos]); 433 | if (res > 0) max = pos - 1; 434 | else min = pos + 1; 435 | } 436 | return NULL; 437 | } 438 | 439 | 440 | /************************************************************************* 441 | * import_dll 442 | * 443 | * Import the dll specified by the given import descriptor. 444 | * The loader_section must be locked while calling this function. 445 | */ 446 | static void * 447 | import_dll (struct himemce_map *map, HMODULE module, 448 | const IMAGE_IMPORT_DESCRIPTOR *descr) 449 | { 450 | int status = 0; 451 | const char *name = get_rva (module, descr->Name); 452 | DWORD len = strlen(name); 453 | const IMAGE_THUNK_DATA *import_list; 454 | IMAGE_THUNK_DATA *thunk_list; 455 | void *imp_base = 0; 456 | HMODULE imp_mod = 0; 457 | const IMAGE_EXPORT_DIRECTORY *exports; 458 | DWORD exp_size; 459 | WCHAR buffer[32]; 460 | int i; 461 | 462 | thunk_list = get_rva (module, (DWORD)descr->FirstThunk); 463 | if (descr->OriginalFirstThunk) 464 | import_list = get_rva (module, (DWORD)descr->OriginalFirstThunk); 465 | else 466 | import_list = thunk_list; 467 | 468 | while (len && name[len-1] == ' ') len--; /* remove trailing spaces */ 469 | 470 | /* First check for the modules in the map. */ 471 | for (i = 0; i < map->nr_modules; i++) 472 | { 473 | if (! strncmp (name, map->module[i].name, len)) 474 | break; 475 | } 476 | if (i < map->nr_modules) 477 | { 478 | imp_base = map->module[i].base; 479 | TRACE("Loading library %s internal\n", name); 480 | } 481 | else if (len * sizeof(WCHAR) < sizeof(buffer)) 482 | { 483 | ascii_to_unicode( buffer, name, len ); 484 | buffer[len] = 0; 485 | imp_mod = LoadLibrary (buffer); 486 | if (imp_mod == INVALID_HANDLE_VALUE) 487 | status = GetLastError (); 488 | } 489 | else 490 | { 491 | WCHAR *ptr = malloc ((len + 1) * sizeof(WCHAR) ); 492 | if (!ptr) return NULL; 493 | ascii_to_unicode( ptr, name, len ); 494 | ptr[len] = 0; 495 | imp_mod = LoadLibrary (ptr); 496 | if (imp_mod == INVALID_HANDLE_VALUE) 497 | status = GetLastError (); 498 | free (ptr); 499 | } 500 | if (status) 501 | { 502 | if (status == ERROR_DLL_NOT_FOUND) 503 | TRACE("Library %s not found\n", name); 504 | else 505 | TRACE("Loading library %s failed (error %x).\n", name, status); 506 | return NULL; 507 | } 508 | 509 | if (imp_base) 510 | { 511 | exports = MyRtlImageDirectoryEntryToData (imp_base, TRUE, 512 | IMAGE_DIRECTORY_ENTRY_EXPORT, 513 | &exp_size); 514 | if (!exports) 515 | { 516 | /* set all imported function to deadbeef */ 517 | while (import_list->u1.Ordinal) 518 | { 519 | if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) 520 | { 521 | int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal); 522 | TRACE ("No implementation for %s.%d", name, ordinal); 523 | thunk_list->u1.Function 524 | = (PDWORD) allocate_stub (name, IntToPtr (ordinal)); 525 | } 526 | else 527 | { 528 | IMAGE_IMPORT_BY_NAME *pe_name 529 | = get_rva (module, (DWORD) import_list->u1.AddressOfData); 530 | TRACE ("No implementation for %s.%s", name, pe_name->Name); 531 | thunk_list->u1.Function 532 | = (PDWORD) allocate_stub (name, (const char*) pe_name->Name); 533 | } 534 | import_list++; 535 | thunk_list++; 536 | } 537 | goto done; 538 | } 539 | } 540 | 541 | while (import_list->u1.Ordinal) 542 | { 543 | if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) 544 | { 545 | int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal); 546 | 547 | if (imp_base) 548 | thunk_list->u1.Function = (PDWORD)(ULONG_PTR) 549 | find_ordinal_export (imp_base, exports, exp_size, 550 | ordinal - exports->Base); 551 | else 552 | thunk_list->u1.Function = (PDWORD)(ULONG_PTR) 553 | GetProcAddress (imp_mod, (void *) (ordinal & 0xffff)); 554 | if (!thunk_list->u1.Function) 555 | { 556 | thunk_list->u1.Function = (PDWORD) allocate_stub( name, IntToPtr(ordinal) ); 557 | TRACE("No implementation for %s.%d imported, setting to %p\n", 558 | name, ordinal, 559 | (void *)thunk_list->u1.Function ); 560 | } 561 | TRACE("--- Ordinal %s.%d = %p\n", name, ordinal, (void *)thunk_list->u1.Function ); 562 | } 563 | else /* import by name */ 564 | { 565 | IMAGE_IMPORT_BY_NAME *pe_name; 566 | pe_name = get_rva( module, (DWORD)import_list->u1.AddressOfData ); 567 | if (imp_base) 568 | thunk_list->u1.Function = (PDWORD)(ULONG_PTR) 569 | find_named_export (imp_base, exports, exp_size, 570 | (const char*)pe_name->Name, pe_name->Hint); 571 | else 572 | thunk_list->u1.Function = (PDWORD)(ULONG_PTR) 573 | GetProcAddressA (imp_mod, (const char*)pe_name->Name); 574 | if (!thunk_list->u1.Function) 575 | { 576 | thunk_list->u1.Function 577 | = (PDWORD) allocate_stub (name, (const char*)pe_name->Name); 578 | TRACE ("No implementation for %s.%s imported, setting to %p\n", 579 | name, pe_name->Name, (void *)thunk_list->u1.Function); 580 | } 581 | TRACE("--- %s %s.%d = %p\n", 582 | pe_name->Name, name, pe_name->Hint, 583 | (void *)thunk_list->u1.Function); 584 | } 585 | import_list++; 586 | thunk_list++; 587 | } 588 | 589 | done: 590 | return (void*)1; 591 | } 592 | 593 | 594 | static void 595 | fixup_imports (struct himemce_map *map, void *base) 596 | { 597 | int i, nb_imports; 598 | const IMAGE_IMPORT_DESCRIPTOR *imports; 599 | DWORD size; 600 | 601 | imports = MyRtlImageDirectoryEntryToData (base, TRUE, 602 | IMAGE_DIRECTORY_ENTRY_IMPORT, 603 | &size); 604 | if (!imports) 605 | return; 606 | 607 | nb_imports = 0; 608 | while (imports[nb_imports].Name && imports[nb_imports].FirstThunk) 609 | nb_imports++; 610 | if (!nb_imports) 611 | return; 612 | 613 | for (i = 0; i < nb_imports; i++) 614 | { 615 | if (! import_dll (map, base, &imports[i])) 616 | { 617 | SetLastError (ERROR_DLL_NOT_FOUND); 618 | break; 619 | } 620 | } 621 | } 622 | 623 | 624 | int 625 | main (int argc, char *argv[]) 626 | { 627 | struct himemce_map *map; 628 | int result = 0; 629 | int i; 630 | 631 | TRACE ("creating map file...\n"); 632 | 633 | map = map_create (); 634 | if (! map) 635 | return 1; 636 | 637 | TRACE ("finding modules...\n"); 638 | 639 | result = find_modules (map); 640 | if (! result) 641 | exit (1); 642 | 643 | TRACE ("loading modules...\n"); 644 | 645 | /* For each module: load it high without resolving references. */ 646 | for (i = 0; i < map->nr_modules; i++) 647 | { 648 | struct himemce_module *mod = &map->module[i]; 649 | void *base = MyLoadLibraryExW (mod->filename, 0, 650 | DONT_RESOLVE_DLL_REFERENCES); 651 | 652 | if (! base) 653 | { 654 | ERR ("could not load %S: %i\n", mod->filename, GetLastError()); 655 | exit (1); 656 | } 657 | mod->base = base; 658 | } 659 | 660 | TRACE ("relocationg writable sections...\n"); 661 | 662 | for (i = 0; i < map->nr_modules; i++) 663 | { 664 | struct himemce_module *mod = &map->module[i]; 665 | 666 | /* Allocate low mem for read-write sections and adjust 667 | relocations pointing into them. */ 668 | relocate_rw_sections (map, mod->base); 669 | } 670 | 671 | /* Export entries are handled at time of import on the other side, 672 | when we check for low memory mapped sections and adjust the 673 | imported address accordingly. */ 674 | 675 | TRACE ("resolve module dependencies...\n"); 676 | 677 | for (i = 0; i < map->nr_modules; i++) 678 | { 679 | struct himemce_module *mod = &map->module[i]; 680 | 681 | /* Fixup imports (this loads all dependencies as well!). */ 682 | fixup_imports (map, mod->base); 683 | } 684 | 685 | TRACE ("sleeping..."); 686 | 687 | while (1) 688 | Sleep (3600 * 1000); 689 | 690 | return 0; 691 | } 692 | -------------------------------------------------------------------------------- /loader/dlmalloc.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_DL_PREFIX 2 | #define USE_DL_PREFIX 1 3 | #endif 4 | 5 | /* 6 | Default header file for malloc-2.8.x, written by Doug Lea 7 | and released to the public domain, as explained at 8 | http://creativecommons.org/licenses/publicdomain. 9 | 10 | last update: Wed May 27 14:25:17 2009 Doug Lea (dl at gee) 11 | 12 | This header is for ANSI C/C++ only. You can set any of 13 | the following #defines before including: 14 | 15 | * If USE_DL_PREFIX is defined, it is assumed that malloc.c 16 | was also compiled with this option, so all routines 17 | have names starting with "dl". 18 | 19 | * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this 20 | file will be #included AFTER . This is needed only if 21 | your system defines a struct mallinfo that is incompatible with the 22 | standard one declared here. Otherwise, you can include this file 23 | INSTEAD of your system system . At least on ANSI, all 24 | declarations should be compatible with system versions 25 | 26 | * If MSPACES is defined, declarations for mspace versions are included. 27 | */ 28 | 29 | #ifndef MALLOC_280_H 30 | #define MALLOC_280_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include /* for size_t */ 37 | 38 | #ifndef ONLY_MSPACES 39 | #define ONLY_MSPACES 0 /* define to a value */ 40 | #endif /* ONLY_MSPACES */ 41 | #ifndef NO_MALLINFO 42 | #define NO_MALLINFO 0 43 | #endif /* NO_MALLINFO */ 44 | 45 | 46 | #if !ONLY_MSPACES 47 | 48 | #ifndef USE_DL_PREFIX 49 | #define dlcalloc calloc 50 | #define dlfree free 51 | #define dlmalloc malloc 52 | #define dlmemalign memalign 53 | #define dlrealloc realloc 54 | #define dlvalloc valloc 55 | #define dlpvalloc pvalloc 56 | #define dlmallinfo mallinfo 57 | #define dlmallopt mallopt 58 | #define dlmalloc_trim malloc_trim 59 | #define dlmalloc_stats malloc_stats 60 | #define dlmalloc_usable_size malloc_usable_size 61 | #define dlmalloc_footprint malloc_footprint 62 | #define dlindependent_calloc independent_calloc 63 | #define dlindependent_comalloc independent_comalloc 64 | #endif /* USE_DL_PREFIX */ 65 | #if !NO_MALLINFO 66 | #ifndef HAVE_USR_INCLUDE_MALLOC_H 67 | #ifndef _MALLOC_H 68 | #ifndef MALLINFO_FIELD_TYPE 69 | #define MALLINFO_FIELD_TYPE size_t 70 | #endif /* MALLINFO_FIELD_TYPE */ 71 | #ifndef STRUCT_MALLINFO_DECLARED 72 | #define STRUCT_MALLINFO_DECLARED 1 73 | struct mallinfo { 74 | MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ 75 | MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ 76 | MALLINFO_FIELD_TYPE smblks; /* always 0 */ 77 | MALLINFO_FIELD_TYPE hblks; /* always 0 */ 78 | MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ 79 | MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ 80 | MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ 81 | MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ 82 | MALLINFO_FIELD_TYPE fordblks; /* total free space */ 83 | MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ 84 | }; 85 | #endif /* STRUCT_MALLINFO_DECLARED */ 86 | #endif /* _MALLOC_H */ 87 | #endif /* HAVE_USR_INCLUDE_MALLOC_H */ 88 | #endif /* !NO_MALLINFO */ 89 | 90 | /* 91 | malloc(size_t n) 92 | Returns a pointer to a newly allocated chunk of at least n bytes, or 93 | null if no space is available, in which case errno is set to ENOMEM 94 | on ANSI C systems. 95 | 96 | If n is zero, malloc returns a minimum-sized chunk. (The minimum 97 | size is 16 bytes on most 32bit systems, and 32 bytes on 64bit 98 | systems.) Note that size_t is an unsigned type, so calls with 99 | arguments that would be negative if signed are interpreted as 100 | requests for huge amounts of space, which will often fail. The 101 | maximum supported value of n differs across systems, but is in all 102 | cases less than the maximum representable value of a size_t. 103 | */ 104 | void* dlmalloc(size_t); 105 | 106 | /* 107 | free(void* p) 108 | Releases the chunk of memory pointed to by p, that had been previously 109 | allocated using malloc or a related routine such as realloc. 110 | It has no effect if p is null. If p was not malloced or already 111 | freed, free(p) will by default cuase the current program to abort. 112 | */ 113 | void dlfree(void*); 114 | 115 | /* 116 | calloc(size_t n_elements, size_t element_size); 117 | Returns a pointer to n_elements * element_size bytes, with all locations 118 | set to zero. 119 | */ 120 | void* dlcalloc(size_t, size_t); 121 | 122 | /* 123 | realloc(void* p, size_t n) 124 | Returns a pointer to a chunk of size n that contains the same data 125 | as does chunk p up to the minimum of (n, p's size) bytes, or null 126 | if no space is available. 127 | 128 | The returned pointer may or may not be the same as p. The algorithm 129 | prefers extending p in most cases when possible, otherwise it 130 | employs the equivalent of a malloc-copy-free sequence. 131 | 132 | If p is null, realloc is equivalent to malloc. 133 | 134 | If space is not available, realloc returns null, errno is set (if on 135 | ANSI) and p is NOT freed. 136 | 137 | if n is for fewer bytes than already held by p, the newly unused 138 | space is lopped off and freed if possible. realloc with a size 139 | argument of zero (re)allocates a minimum-sized chunk. 140 | 141 | The old unix realloc convention of allowing the last-free'd chunk 142 | to be used as an argument to realloc is not supported. 143 | */ 144 | 145 | void* dlrealloc(void*, size_t); 146 | 147 | /* 148 | memalign(size_t alignment, size_t n); 149 | Returns a pointer to a newly allocated chunk of n bytes, aligned 150 | in accord with the alignment argument. 151 | 152 | The alignment argument should be a power of two. If the argument is 153 | not a power of two, the nearest greater power is used. 154 | 8-byte alignment is guaranteed by normal malloc calls, so don't 155 | bother calling memalign with an argument of 8 or less. 156 | 157 | Overreliance on memalign is a sure way to fragment space. 158 | */ 159 | void* dlmemalign(size_t, size_t); 160 | 161 | /* 162 | valloc(size_t n); 163 | Equivalent to memalign(pagesize, n), where pagesize is the page 164 | size of the system. If the pagesize is unknown, 4096 is used. 165 | */ 166 | void* dlvalloc(size_t); 167 | 168 | /* 169 | mallopt(int parameter_number, int parameter_value) 170 | Sets tunable parameters The format is to provide a 171 | (parameter-number, parameter-value) pair. mallopt then sets the 172 | corresponding parameter to the argument value if it can (i.e., so 173 | long as the value is meaningful), and returns 1 if successful else 174 | 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, 175 | normally defined in malloc.h. None of these are use in this malloc, 176 | so setting them has no effect. But this malloc also supports other 177 | options in mallopt: 178 | 179 | Symbol param # default allowed param values 180 | M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) 181 | M_GRANULARITY -2 page size any power of 2 >= page size 182 | M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) 183 | */ 184 | int dlmallopt(int, int); 185 | 186 | #define M_TRIM_THRESHOLD (-1) 187 | #define M_GRANULARITY (-2) 188 | #define M_MMAP_THRESHOLD (-3) 189 | 190 | 191 | /* 192 | malloc_footprint(); 193 | Returns the number of bytes obtained from the system. The total 194 | number of bytes allocated by malloc, realloc etc., is less than this 195 | value. Unlike mallinfo, this function returns only a precomputed 196 | result, so can be called frequently to monitor memory consumption. 197 | Even if locks are otherwise defined, this function does not use them, 198 | so results might not be up to date. 199 | */ 200 | size_t dlmalloc_footprint(); 201 | 202 | #if !NO_MALLINFO 203 | /* 204 | mallinfo() 205 | Returns (by copy) a struct containing various summary statistics: 206 | 207 | arena: current total non-mmapped bytes allocated from system 208 | ordblks: the number of free chunks 209 | smblks: always zero. 210 | hblks: current number of mmapped regions 211 | hblkhd: total bytes held in mmapped regions 212 | usmblks: the maximum total allocated space. This will be greater 213 | than current total if trimming has occurred. 214 | fsmblks: always zero 215 | uordblks: current total allocated space (normal or mmapped) 216 | fordblks: total free space 217 | keepcost: the maximum number of bytes that could ideally be released 218 | back to system via malloc_trim. ("ideally" means that 219 | it ignores page restrictions etc.) 220 | 221 | Because these fields are ints, but internal bookkeeping may 222 | be kept as longs, the reported values may wrap around zero and 223 | thus be inaccurate. 224 | */ 225 | 226 | struct mallinfo dlmallinfo(void); 227 | #endif /* NO_MALLINFO */ 228 | 229 | /* 230 | independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); 231 | 232 | independent_calloc is similar to calloc, but instead of returning a 233 | single cleared space, it returns an array of pointers to n_elements 234 | independent elements that can hold contents of size elem_size, each 235 | of which starts out cleared, and can be independently freed, 236 | realloc'ed etc. The elements are guaranteed to be adjacently 237 | allocated (this is not guaranteed to occur with multiple callocs or 238 | mallocs), which may also improve cache locality in some 239 | applications. 240 | 241 | The "chunks" argument is optional (i.e., may be null, which is 242 | probably the most typical usage). If it is null, the returned array 243 | is itself dynamically allocated and should also be freed when it is 244 | no longer needed. Otherwise, the chunks array must be of at least 245 | n_elements in length. It is filled in with the pointers to the 246 | chunks. 247 | 248 | In either case, independent_calloc returns this pointer array, or 249 | null if the allocation failed. If n_elements is zero and "chunks" 250 | is null, it returns a chunk representing an array with zero elements 251 | (which should be freed if not wanted). 252 | 253 | Each element must be individually freed when it is no longer 254 | needed. If you'd like to instead be able to free all at once, you 255 | should instead use regular calloc and assign pointers into this 256 | space to represent elements. (In this case though, you cannot 257 | independently free elements.) 258 | 259 | independent_calloc simplifies and speeds up implementations of many 260 | kinds of pools. It may also be useful when constructing large data 261 | structures that initially have a fixed number of fixed-sized nodes, 262 | but the number is not known at compile time, and some of the nodes 263 | may later need to be freed. For example: 264 | 265 | struct Node { int item; struct Node* next; }; 266 | 267 | struct Node* build_list() { 268 | struct Node** pool; 269 | int n = read_number_of_nodes_needed(); 270 | if (n <= 0) return 0; 271 | pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); 272 | if (pool == 0) die(); 273 | // organize into a linked list... 274 | struct Node* first = pool[0]; 275 | for (i = 0; i < n-1; ++i) 276 | pool[i]->next = pool[i+1]; 277 | free(pool); // Can now free the array (or not, if it is needed later) 278 | return first; 279 | } 280 | */ 281 | void** dlindependent_calloc(size_t, size_t, void**); 282 | 283 | /* 284 | independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); 285 | 286 | independent_comalloc allocates, all at once, a set of n_elements 287 | chunks with sizes indicated in the "sizes" array. It returns 288 | an array of pointers to these elements, each of which can be 289 | independently freed, realloc'ed etc. The elements are guaranteed to 290 | be adjacently allocated (this is not guaranteed to occur with 291 | multiple callocs or mallocs), which may also improve cache locality 292 | in some applications. 293 | 294 | The "chunks" argument is optional (i.e., may be null). If it is null 295 | the returned array is itself dynamically allocated and should also 296 | be freed when it is no longer needed. Otherwise, the chunks array 297 | must be of at least n_elements in length. It is filled in with the 298 | pointers to the chunks. 299 | 300 | In either case, independent_comalloc returns this pointer array, or 301 | null if the allocation failed. If n_elements is zero and chunks is 302 | null, it returns a chunk representing an array with zero elements 303 | (which should be freed if not wanted). 304 | 305 | Each element must be individually freed when it is no longer 306 | needed. If you'd like to instead be able to free all at once, you 307 | should instead use a single regular malloc, and assign pointers at 308 | particular offsets in the aggregate space. (In this case though, you 309 | cannot independently free elements.) 310 | 311 | independent_comallac differs from independent_calloc in that each 312 | element may have a different size, and also that it does not 313 | automatically clear elements. 314 | 315 | independent_comalloc can be used to speed up allocation in cases 316 | where several structs or objects must always be allocated at the 317 | same time. For example: 318 | 319 | struct Head { ... } 320 | struct Foot { ... } 321 | 322 | void send_message(char* msg) { 323 | int msglen = strlen(msg); 324 | size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; 325 | void* chunks[3]; 326 | if (independent_comalloc(3, sizes, chunks) == 0) 327 | die(); 328 | struct Head* head = (struct Head*)(chunks[0]); 329 | char* body = (char*)(chunks[1]); 330 | struct Foot* foot = (struct Foot*)(chunks[2]); 331 | // ... 332 | } 333 | 334 | In general though, independent_comalloc is worth using only for 335 | larger values of n_elements. For small values, you probably won't 336 | detect enough difference from series of malloc calls to bother. 337 | 338 | Overuse of independent_comalloc can increase overall memory usage, 339 | since it cannot reuse existing noncontiguous small chunks that 340 | might be available for some of the elements. 341 | */ 342 | void** dlindependent_comalloc(size_t, size_t*, void**); 343 | 344 | 345 | /* 346 | pvalloc(size_t n); 347 | Equivalent to valloc(minimum-page-that-holds(n)), that is, 348 | round up n to nearest pagesize. 349 | */ 350 | void* dlpvalloc(size_t); 351 | 352 | /* 353 | malloc_trim(size_t pad); 354 | 355 | If possible, gives memory back to the system (via negative arguments 356 | to sbrk) if there is unused memory at the `high' end of the malloc 357 | pool or in unused MMAP segments. You can call this after freeing 358 | large blocks of memory to potentially reduce the system-level memory 359 | requirements of a program. However, it cannot guarantee to reduce 360 | memory. Under some allocation patterns, some large free blocks of 361 | memory will be locked between two used chunks, so they cannot be 362 | given back to the system. 363 | 364 | The `pad' argument to malloc_trim represents the amount of free 365 | trailing space to leave untrimmed. If this argument is zero, only 366 | the minimum amount of memory to maintain internal data structures 367 | will be left. Non-zero arguments can be supplied to maintain enough 368 | trailing space to service future expected allocations without having 369 | to re-obtain memory from the system. 370 | 371 | Malloc_trim returns 1 if it actually released any memory, else 0. 372 | */ 373 | int dlmalloc_trim(size_t); 374 | 375 | /* 376 | malloc_stats(); 377 | Prints on stderr the amount of space obtained from the system (both 378 | via sbrk and mmap), the maximum amount (which may be more than 379 | current if malloc_trim and/or munmap got called), and the current 380 | number of bytes allocated via malloc (or realloc, etc) but not yet 381 | freed. Note that this is the number of bytes allocated, not the 382 | number requested. It will be larger than the number requested 383 | because of alignment and bookkeeping overhead. Because it includes 384 | alignment wastage as being in use, this figure may be greater than 385 | zero even when no user-level chunks are allocated. 386 | 387 | The reported current and maximum system memory can be inaccurate if 388 | a program makes other calls to system memory allocation functions 389 | (normally sbrk) outside of malloc. 390 | 391 | malloc_stats prints only the most commonly interesting statistics. 392 | More information can be obtained by calling mallinfo. 393 | */ 394 | void dlmalloc_stats(); 395 | 396 | #endif /* !ONLY_MSPACES */ 397 | 398 | /* 399 | malloc_usable_size(void* p); 400 | 401 | Returns the number of bytes you can actually use in 402 | an allocated chunk, which may be more than you requested (although 403 | often not) due to alignment and minimum size constraints. 404 | You can use this many bytes without worrying about 405 | overwriting other allocated objects. This is not a particularly great 406 | programming practice. malloc_usable_size can be more useful in 407 | debugging and assertions, for example: 408 | 409 | p = malloc(n); 410 | assert(malloc_usable_size(p) >= 256); 411 | */ 412 | size_t dlmalloc_usable_size(void*); 413 | 414 | 415 | #if MSPACES 416 | 417 | /* 418 | mspace is an opaque type representing an independent 419 | region of space that supports mspace_malloc, etc. 420 | */ 421 | typedef void* mspace; 422 | 423 | /* 424 | create_mspace creates and returns a new independent space with the 425 | given initial capacity, or, if 0, the default granularity size. It 426 | returns null if there is no system memory available to create the 427 | space. If argument locked is non-zero, the space uses a separate 428 | lock to control access. The capacity of the space will grow 429 | dynamically as needed to service mspace_malloc requests. You can 430 | control the sizes of incremental increases of this space by 431 | compiling with a different DEFAULT_GRANULARITY or dynamically 432 | setting with mallopt(M_GRANULARITY, value). 433 | */ 434 | mspace create_mspace(size_t capacity, int locked); 435 | 436 | /* 437 | destroy_mspace destroys the given space, and attempts to return all 438 | of its memory back to the system, returning the total number of 439 | bytes freed. After destruction, the results of access to all memory 440 | used by the space become undefined. 441 | */ 442 | size_t destroy_mspace(mspace msp); 443 | 444 | /* 445 | create_mspace_with_base uses the memory supplied as the initial base 446 | of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this 447 | space is used for bookkeeping, so the capacity must be at least this 448 | large. (Otherwise 0 is returned.) When this initial space is 449 | exhausted, additional memory will be obtained from the system. 450 | Destroying this space will deallocate all additionally allocated 451 | space (if possible) but not the initial base. 452 | */ 453 | mspace create_mspace_with_base(void* base, size_t capacity, int locked); 454 | 455 | /* 456 | mspace_track_large_chunks controls whether requests for large chunks 457 | are allocated in their own untracked mmapped regions, separate from 458 | others in this mspace. By default large chunks are not tracked, 459 | which reduces fragmentation. However, such chunks are not 460 | necessarily released to the system upon destroy_mspace. Enabling 461 | tracking by setting to true may increase fragmentation, but avoids 462 | leakage when relying on destroy_mspace to release all memory 463 | allocated using this space. The function returns the previous 464 | setting. 465 | */ 466 | int mspace_track_large_chunks(mspace msp, int enable); 467 | 468 | /* 469 | mspace_malloc behaves as malloc, but operates within 470 | the given space. 471 | */ 472 | void* mspace_malloc(mspace msp, size_t bytes); 473 | 474 | /* 475 | mspace_free behaves as free, but operates within 476 | the given space. 477 | 478 | If compiled with FOOTERS==1, mspace_free is not actually needed. 479 | free may be called instead of mspace_free because freed chunks from 480 | any space are handled by their originating spaces. 481 | */ 482 | void mspace_free(mspace msp, void* mem); 483 | 484 | /* 485 | mspace_realloc behaves as realloc, but operates within 486 | the given space. 487 | 488 | If compiled with FOOTERS==1, mspace_realloc is not actually 489 | needed. realloc may be called instead of mspace_realloc because 490 | realloced chunks from any space are handled by their originating 491 | spaces. 492 | */ 493 | void* mspace_realloc(mspace msp, void* mem, size_t newsize); 494 | 495 | /* 496 | mspace_calloc behaves as calloc, but operates within 497 | the given space. 498 | */ 499 | void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); 500 | 501 | /* 502 | mspace_memalign behaves as memalign, but operates within 503 | the given space. 504 | */ 505 | void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); 506 | 507 | /* 508 | mspace_independent_calloc behaves as independent_calloc, but 509 | operates within the given space. 510 | */ 511 | void** mspace_independent_calloc(mspace msp, size_t n_elements, 512 | size_t elem_size, void* chunks[]); 513 | 514 | /* 515 | mspace_independent_comalloc behaves as independent_comalloc, but 516 | operates within the given space. 517 | */ 518 | void** mspace_independent_comalloc(mspace msp, size_t n_elements, 519 | size_t sizes[], void* chunks[]); 520 | 521 | /* 522 | mspace_footprint() returns the number of bytes obtained from the 523 | system for this space. 524 | */ 525 | size_t mspace_footprint(mspace msp); 526 | 527 | 528 | #if !NO_MALLINFO 529 | /* 530 | mspace_mallinfo behaves as mallinfo, but reports properties of 531 | the given space. 532 | */ 533 | struct mallinfo mspace_mallinfo(mspace msp); 534 | #endif /* NO_MALLINFO */ 535 | 536 | /* 537 | malloc_usable_size(void* p) behaves the same as malloc_usable_size; 538 | */ 539 | size_t mspace_usable_size(void* mem); 540 | 541 | /* 542 | mspace_malloc_stats behaves as malloc_stats, but reports 543 | properties of the given space. 544 | */ 545 | void mspace_malloc_stats(mspace msp); 546 | 547 | /* 548 | mspace_trim behaves as malloc_trim, but 549 | operates within the given space. 550 | */ 551 | int mspace_trim(mspace msp, size_t pad); 552 | 553 | /* 554 | An alias for mallopt. 555 | */ 556 | int mspace_mallopt(int, int); 557 | 558 | #endif /* MSPACES */ 559 | 560 | #ifdef __cplusplus 561 | }; /* end of extern "C" */ 562 | #endif 563 | 564 | #endif /* MALLOC_280_H */ 565 | -------------------------------------------------------------------------------- /loader/ntdll_virtual.c: -------------------------------------------------------------------------------- 1 | /* From wine1.2-1.1.42/dlls/ntdll/virtual.c */ 2 | 3 | /* 4 | * Win32 virtual memory functions 5 | * 6 | * Copyright 1997, 2002 Alexandre Julliard 7 | * Copyright 2010 g10 Code GmbH 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 | */ 23 | 24 | 25 | #include 26 | #include 27 | 28 | #include "wine.h" 29 | 30 | /* File view */ 31 | typedef struct file_view 32 | { 33 | void *base; /* Base address */ 34 | size_t size; /* Size in bytes */ 35 | HANDLE mapping; /* Handle to the file mapping */ 36 | unsigned int protect; /* Protection for all pages at allocation time */ 37 | } FILE_VIEW; 38 | 39 | 40 | # define page_mask 0xfff 41 | # define page_shift 12 42 | # define page_size 0x1000 43 | 44 | 45 | #define ROUND_SIZE(addr,size) \ 46 | (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask) 47 | 48 | 49 | static size_t get_mask( ULONG zero_bits ) 50 | { 51 | if (!zero_bits) return 0xffff; /* allocations are aligned to 64K by default */ 52 | if (zero_bits < page_shift) zero_bits = page_shift; 53 | return (1 << zero_bits) - 1; 54 | } 55 | 56 | 57 | static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot ) 58 | { 59 | switch(protect & 0xff) 60 | { 61 | case PAGE_READONLY: 62 | *vprot = VPROT_READ; 63 | break; 64 | case PAGE_READWRITE: 65 | *vprot = VPROT_READ | VPROT_WRITE; 66 | break; 67 | case PAGE_WRITECOPY: 68 | *vprot = VPROT_READ | VPROT_WRITECOPY; 69 | break; 70 | case PAGE_EXECUTE: 71 | *vprot = VPROT_EXEC; 72 | break; 73 | case PAGE_EXECUTE_READ: 74 | *vprot = VPROT_EXEC | VPROT_READ; 75 | break; 76 | case PAGE_EXECUTE_READWRITE: 77 | *vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE; 78 | break; 79 | case PAGE_EXECUTE_WRITECOPY: 80 | *vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY; 81 | break; 82 | case PAGE_NOACCESS: 83 | *vprot = 0; 84 | break; 85 | default: 86 | return STATUS_INVALID_PARAMETER; 87 | } 88 | if (protect & PAGE_GUARD) *vprot |= VPROT_GUARD; 89 | if (protect & PAGE_NOCACHE) *vprot |= VPROT_NOCACHE; 90 | return STATUS_SUCCESS; 91 | } 92 | 93 | 94 | static void delete_view( struct file_view *view ) /* [in] View */ 95 | { 96 | VirtualFree (view->base, view->size, MEM_RELEASE); 97 | // if (view->mapping) NtClose( view->mapping ); 98 | free (view); 99 | } 100 | 101 | 102 | static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t mask, 103 | int top_down, unsigned int vprot ) 104 | { 105 | int prot = get_prot_flags (vprot); 106 | struct file_view *view; 107 | void *ptr; 108 | void *new_ptr; 109 | 110 | view = malloc (sizeof (struct file_view)); 111 | if (!view) 112 | return STATUS_NO_MEMORY; 113 | 114 | // FIXME: Only with NOACCESS does Windows CE prefer the high mem area 115 | // even for smaller areas. 116 | ptr = VirtualAlloc(base, size < (2* 1024*1024) ? 2*1024*1024 : size, MEM_RESERVE, PAGE_NOACCESS /*prot*/); 117 | if (!ptr) 118 | { 119 | free (view); 120 | return GetLastError(); 121 | } 122 | /* We have to zero map the whole thing. */ 123 | new_ptr = VirtualAlloc (ptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 124 | if (new_ptr != ptr) 125 | { 126 | free (view); 127 | return GetLastError(); 128 | } 129 | view->base = ptr; 130 | view->size = size; 131 | view->protect = vprot; 132 | view->mapping = 0; 133 | *view_ret = view; 134 | return STATUS_SUCCESS; 135 | } 136 | 137 | 138 | static NTSTATUS map_file_into_view( struct file_view *view, HANDLE fhandle, size_t start, size_t size, 139 | off_t offset, unsigned int vprot, BOOL removable ) 140 | { 141 | void *ptr; 142 | int prot = get_prot_flags (vprot); 143 | BOOL shared_write = (vprot & VPROT_WRITE) != 0; 144 | 145 | assert( start < view->size ); 146 | assert( start + size <= view->size ); 147 | 148 | #if 0 149 | /* only try mmap if media is not removable (or if we require write access) */ 150 | if (!removable || shared_write) 151 | { 152 | int flags = MAP_FIXED | (shared_write ? MAP_SHARED : MAP_PRIVATE); 153 | 154 | if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != (void *)-1) 155 | goto done; 156 | 157 | /* mmap() failed; if this is because the file offset is not */ 158 | /* page-aligned (EINVAL), or because the underlying filesystem */ 159 | /* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */ 160 | if ((errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV)) return FILE_GetNtStatus(); 161 | if (shared_write) /* we cannot fake shared write mappings */ 162 | { 163 | if (errno == EINVAL) return STATUS_INVALID_PARAMETER; 164 | ERR( "shared writable mmap not supported, broken filesystem?\n" ); 165 | return STATUS_NOT_SUPPORTED; 166 | } 167 | } 168 | #endif 169 | 170 | #if 0 171 | /* Already done by map_view. */ 172 | /* Reserve the memory with an anonymous mmap */ 173 | ptr = VirtualAlloc ((char *)view->base + start, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 174 | if (ptr == (void *)-1) return GetLastError(); 175 | #else 176 | ptr = (char *)view->base + start; 177 | #endif 178 | 179 | /* Now read in the file */ 180 | pread( fhandle, ptr, size, offset ); 181 | // if (prot != (PROT_READ|PROT_WRITE)) mprotect( ptr, size, prot ); /* Set the right protection */ 182 | //done: 183 | // memset( view->prot + (start >> page_shift), vprot, ROUND_SIZE(start,size) >> page_shift ); 184 | return STATUS_SUCCESS; 185 | } 186 | 187 | 188 | static NTSTATUS map_image (HANDLE hmapping, HANDLE hfile, HANDLE hmap, char *base, SIZE_T total_size, SIZE_T mask, 189 | SIZE_T header_size, int shared_fd, HANDLE dup_mapping, PVOID *addr_ptr) 190 | { 191 | IMAGE_DOS_HEADER *dos; 192 | IMAGE_NT_HEADERS *nt; 193 | IMAGE_SECTION_HEADER *sec; 194 | IMAGE_DATA_DIRECTORY *imports; 195 | NTSTATUS status = STATUS_CONFLICTING_ADDRESSES; 196 | int i; 197 | off_t pos; 198 | DWORD fsize; 199 | struct file_view *view = NULL; 200 | char *ptr, *header_end; 201 | INT_PTR delta = 0; 202 | 203 | 204 | /* zero-map the whole range */ 205 | 206 | if (base >= (char *)0x110000) /* make sure the DOS area remains free */ 207 | status = map_view( &view, base, total_size, mask, FALSE, 208 | VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY | VPROT_IMAGE ); 209 | 210 | if (status != STATUS_SUCCESS) 211 | status = map_view( &view, NULL, total_size, mask, FALSE, 212 | VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY | VPROT_IMAGE ); 213 | 214 | if (status != STATUS_SUCCESS) goto error; 215 | 216 | ptr = view->base; 217 | TRACE( "mapped PE file at %p-%p\n", ptr, ptr + total_size ); 218 | 219 | /* map the header */ 220 | 221 | fsize = GetFileSize (hfile, NULL); 222 | if (fsize == INVALID_FILE_SIZE) 223 | { 224 | status = GetLastError(); 225 | goto error; 226 | } 227 | status = STATUS_INVALID_IMAGE_FORMAT; /* generic error */ 228 | header_size = min( header_size, fsize ); 229 | if (map_file_into_view( view, hfile, 0, header_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, 230 | !dup_mapping ) != STATUS_SUCCESS) goto error; 231 | dos = (IMAGE_DOS_HEADER *)ptr; 232 | nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew); 233 | header_end = ptr + ROUND_SIZE( 0, header_size ); 234 | memset( ptr + header_size, 0, header_end - (ptr + header_size) ); 235 | if ((char *)(nt + 1) > header_end) goto error; 236 | sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader); 237 | if ((char *)(sec + nt->FileHeader.NumberOfSections) > header_end) goto error; 238 | 239 | imports = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT; 240 | if (!imports->Size || !imports->VirtualAddress) imports = NULL; 241 | 242 | /* check the architecture */ 243 | 244 | if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_ARM 245 | && nt->FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB) 246 | { 247 | TRACE("Trying to load PE image for unsupported architecture ("); 248 | switch (nt->FileHeader.Machine) 249 | { 250 | case IMAGE_FILE_MACHINE_UNKNOWN: TRACE("Unknown"); break; 251 | case IMAGE_FILE_MACHINE_I386: TRACE("I386"); break; 252 | case IMAGE_FILE_MACHINE_R3000: TRACE("R3000"); break; 253 | case IMAGE_FILE_MACHINE_R4000: TRACE("R4000"); break; 254 | case IMAGE_FILE_MACHINE_R10000: TRACE("R10000"); break; 255 | case IMAGE_FILE_MACHINE_ALPHA: TRACE("Alpha"); break; 256 | case IMAGE_FILE_MACHINE_POWERPC: TRACE("PowerPC"); break; 257 | case IMAGE_FILE_MACHINE_IA64: TRACE("IA-64"); break; 258 | case IMAGE_FILE_MACHINE_ALPHA64: TRACE("Alpha-64"); break; 259 | case IMAGE_FILE_MACHINE_ARM: TRACE("ARM"); break; 260 | default: TRACE("Unknown-%04x", nt->FileHeader.Machine); break; 261 | } 262 | TRACE(")\n"); 263 | goto error; 264 | } 265 | 266 | /* check for non page-aligned binary */ 267 | 268 | if (nt->OptionalHeader.SectionAlignment <= page_mask) 269 | { 270 | /* unaligned sections, this happens for native subsystem binaries */ 271 | /* in that case Windows simply maps in the whole file */ 272 | 273 | if (map_file_into_view( view, hfile, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ, 274 | !dup_mapping ) != STATUS_SUCCESS) goto error; 275 | 276 | /* check that all sections are loaded at the right offset */ 277 | if (nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) goto error; 278 | for (i = 0; i < nt->FileHeader.NumberOfSections; i++) 279 | { 280 | if (sec[i].VirtualAddress != sec[i].PointerToRawData) 281 | goto error; /* Windows refuses to load in that case too */ 282 | } 283 | #if 0 284 | /* set the image protections */ 285 | VIRTUAL_SetProt( view, ptr, total_size, 286 | VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC ); 287 | #endif 288 | 289 | #if 0 290 | /* no relocations are performed on non page-aligned binaries */ 291 | goto done; 292 | #else 293 | goto reloc; 294 | #endif 295 | } 296 | 297 | 298 | /* map all the sections */ 299 | 300 | for (i = pos = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) 301 | { 302 | static const SIZE_T sector_align = 0x1ff; 303 | SIZE_T map_size, file_start, file_size, end; 304 | 305 | if (!sec->Misc.VirtualSize) 306 | map_size = ROUND_SIZE( 0, sec->SizeOfRawData ); 307 | else 308 | map_size = ROUND_SIZE( 0, sec->Misc.VirtualSize ); 309 | 310 | /* file positions are rounded to sector boundaries regardless of OptionalHeader.FileAlignment */ 311 | file_start = sec->PointerToRawData & ~sector_align; 312 | file_size = (sec->SizeOfRawData + (sec->PointerToRawData & sector_align) + sector_align) & ~sector_align; 313 | if (file_size > map_size) file_size = map_size; 314 | 315 | /* a few sanity checks */ 316 | end = sec->VirtualAddress + ROUND_SIZE( sec->VirtualAddress, map_size ); 317 | if (sec->VirtualAddress > total_size || end > total_size || end < sec->VirtualAddress) 318 | { 319 | ERR ( "Section %.8s too large (%x+%lx/%lx)\n", 320 | sec->Name, sec->VirtualAddress, map_size, total_size ); 321 | goto error; 322 | } 323 | 324 | if ((sec->Characteristics & IMAGE_SCN_MEM_SHARED) && 325 | (sec->Characteristics & IMAGE_SCN_MEM_WRITE)) 326 | { 327 | TRACE( "mapping shared section %.8s at %p off %x (%x) size %lx (%lx) flags %x\n", 328 | sec->Name, ptr + sec->VirtualAddress, 329 | sec->PointerToRawData, (int)pos, file_size, map_size, 330 | sec->Characteristics ); 331 | if (map_file_into_view( view, hfile, sec->VirtualAddress, map_size, pos, 332 | VPROT_COMMITTED | VPROT_READ | VPROT_WRITE, 333 | FALSE ) != STATUS_SUCCESS) 334 | { 335 | ERR ( "Could not map shared section %.8s\n", sec->Name ); 336 | goto error; 337 | } 338 | 339 | /* check if the import directory falls inside this section */ 340 | if (imports && imports->VirtualAddress >= sec->VirtualAddress && 341 | imports->VirtualAddress < sec->VirtualAddress + map_size) 342 | { 343 | UINT_PTR base = imports->VirtualAddress & ~page_mask; 344 | UINT_PTR end = base + ROUND_SIZE( imports->VirtualAddress, imports->Size ); 345 | if (end > sec->VirtualAddress + map_size) end = sec->VirtualAddress + map_size; 346 | if (end > base) 347 | map_file_into_view( view, hfile, base, end - base, 348 | pos + (base - sec->VirtualAddress), 349 | VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, 350 | FALSE ); 351 | } 352 | pos += map_size; 353 | continue; 354 | } 355 | 356 | ERR( "mapping section %.8s at %p off %x size %x virt %x flags %x\n", 357 | sec->Name, ptr + sec->VirtualAddress, 358 | sec->PointerToRawData, sec->SizeOfRawData, 359 | sec->Misc.VirtualSize, sec->Characteristics ); 360 | 361 | if (!sec->PointerToRawData || !file_size) continue; 362 | 363 | /* Note: if the section is not aligned properly map_file_into_view will magically 364 | * fall back to read(), so we don't need to check anything here. 365 | */ 366 | end = file_start + file_size; 367 | if (sec->PointerToRawData >= fsize || 368 | end > ((fsize + sector_align) & ~sector_align) || 369 | end < file_start || 370 | map_file_into_view( view, hfile, sec->VirtualAddress, file_size, file_start, 371 | VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, 372 | !dup_mapping ) != STATUS_SUCCESS) 373 | { 374 | ERR( "Could not map section %.8s, file probably truncated\n", sec->Name ); 375 | goto error; 376 | } 377 | 378 | if (file_size & page_mask) 379 | { 380 | end = ROUND_SIZE( 0, file_size ); 381 | if (end > map_size) end = map_size; 382 | TRACE("clearing %p - %p\n", 383 | ptr + sec->VirtualAddress + file_size, 384 | ptr + sec->VirtualAddress + end ); 385 | memset( ptr + sec->VirtualAddress + file_size, 0, end - file_size ); 386 | } 387 | } 388 | 389 | reloc: 390 | /* perform base relocation, if necessary */ 391 | 392 | if (ptr != base) 393 | // && 394 | // ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) || 395 | // !NtCurrentTeb()->Peb->ImageBaseAddress) ) 396 | { 397 | IMAGE_BASE_RELOCATION *rel, *end; 398 | const IMAGE_DATA_DIRECTORY *relocs; 399 | 400 | if (nt->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) 401 | { 402 | TRACE( "Need to relocate module from %p to %p, but there are no relocation records\n", 403 | base, ptr ); 404 | status = STATUS_CONFLICTING_ADDRESSES; 405 | goto error; 406 | } 407 | 408 | TRACE( "relocating from %p-%p to %p-%p\n", 409 | base, base + total_size, ptr, ptr + total_size ); 410 | 411 | relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 412 | rel = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress); 413 | end = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress + relocs->Size); 414 | delta = ptr - base; 415 | 416 | while (rel < end - 1 && rel->SizeOfBlock) 417 | { 418 | if (rel->VirtualAddress >= total_size) 419 | { 420 | TRACE( "invalid address %p in relocation %p\n", ptr + rel->VirtualAddress, rel ); 421 | status = STATUS_ACCESS_VIOLATION; 422 | goto error; 423 | } 424 | rel = MyLdrProcessRelocationBlock( ptr + rel->VirtualAddress, 425 | (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT), 426 | (USHORT *)(rel + 1), delta ); 427 | if (!rel) goto error; 428 | } 429 | } 430 | #if 0 431 | /* set the image protections */ 432 | VIRTUAL_SetProt( view, ptr, ROUND_SIZE( 0, header_size ), VPROT_COMMITTED | VPROT_READ ); 433 | 434 | sec = (IMAGE_SECTION_HEADER*)((char *)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader); 435 | for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) 436 | { 437 | SIZE_T size; 438 | BYTE vprot = VPROT_COMMITTED; 439 | 440 | if (sec->Misc.VirtualSize) 441 | size = ROUND_SIZE( sec->VirtualAddress, sec->Misc.VirtualSize ); 442 | else 443 | size = ROUND_SIZE( sec->VirtualAddress, sec->SizeOfRawData ); 444 | 445 | if (sec->Characteristics & IMAGE_SCN_MEM_READ) vprot |= VPROT_READ; 446 | if (sec->Characteristics & IMAGE_SCN_MEM_WRITE) vprot |= VPROT_READ|VPROT_WRITECOPY; 447 | if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) vprot |= VPROT_EXEC; 448 | 449 | /* Dumb game crack lets the AOEP point into a data section. Adjust. */ 450 | if ((nt->OptionalHeader.AddressOfEntryPoint >= sec->VirtualAddress) && 451 | (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress + size)) 452 | vprot |= VPROT_EXEC; 453 | 454 | VIRTUAL_SetProt( view, ptr + sec->VirtualAddress, size, vprot ); 455 | } 456 | #endif 457 | 458 | // done: 459 | *addr_ptr = ptr; 460 | #ifdef VALGRIND_LOAD_PDB_DEBUGINFO 461 | VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta); 462 | #endif 463 | if (ptr != base) return STATUS_IMAGE_NOT_AT_BASE; 464 | return STATUS_SUCCESS; 465 | 466 | error: 467 | if (view) delete_view( view ); 468 | return status; 469 | } 470 | 471 | 472 | NTSTATUS MyNtCreateSection (HANDLE *handle, ACCESS_MASK access, 473 | /* const OBJECT_ATTRIBUTES *attr */ void *attr, 474 | const LARGE_INTEGER *size, ULONG protect, 475 | ULONG sec_flags, HANDLE file) 476 | { 477 | NTSTATUS ret; 478 | unsigned int vprot; 479 | 480 | if ((ret = get_vprot_flags( protect, &vprot ))) return ret; 481 | 482 | assert (attr == NULL); 483 | 484 | if (!(sec_flags & SEC_RESERVE)) vprot |= VPROT_COMMITTED; 485 | if (sec_flags & SEC_NOCACHE) vprot |= VPROT_NOCACHE; 486 | if (sec_flags & SEC_IMAGE) vprot |= VPROT_IMAGE; 487 | 488 | ret = SERVER_create_mapping (access, attr, file, size ? size->QuadPart : 0, 489 | vprot, handle); 490 | 491 | return ret; 492 | } 493 | 494 | 495 | NTSTATUS MyNtMapViewOfSection (HANDLE handle, HANDLE process, PVOID *addr_ptr, ULONG zero_bits, 496 | SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, 497 | SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect) 498 | { 499 | NTSTATUS res; 500 | mem_size_t full_size; 501 | ACCESS_MASK access; 502 | SIZE_T size, mask = get_mask( zero_bits ); 503 | unsigned int map_vprot; 504 | // unsigned int vprot; 505 | void *base; 506 | // struct file_view *view; 507 | DWORD header_size; 508 | HANDLE fhandle; 509 | HANDLE mhandle; 510 | LARGE_INTEGER offset; 511 | 512 | offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0; 513 | 514 | TRACE("handle=%p process=%p addr=%p off=%x%08x size=%lx access=%x\n", 515 | handle, process, *addr_ptr, offset.u.HighPart, offset.u.LowPart, *size_ptr, protect ); 516 | 517 | /* Check parameters */ 518 | 519 | if ((offset.u.LowPart & mask) || (*addr_ptr && ((UINT_PTR)*addr_ptr & mask))) 520 | return STATUS_INVALID_PARAMETER; 521 | 522 | switch(protect) 523 | { 524 | case PAGE_NOACCESS: 525 | access = 0; 526 | break; 527 | case PAGE_READWRITE: 528 | case PAGE_EXECUTE_READWRITE: 529 | access = SECTION_MAP_WRITE; 530 | break; 531 | case PAGE_READONLY: 532 | case PAGE_WRITECOPY: 533 | case PAGE_EXECUTE: 534 | case PAGE_EXECUTE_READ: 535 | case PAGE_EXECUTE_WRITECOPY: 536 | access = SECTION_MAP_READ; 537 | break; 538 | default: 539 | return STATUS_INVALID_PARAMETER; 540 | } 541 | 542 | res = SERVER_get_mapping_info (handle, access, &map_vprot, &base, &full_size, &header_size, &fhandle, &mhandle); 543 | if (res) return res; 544 | 545 | if (map_vprot & VPROT_IMAGE) 546 | { 547 | size = full_size; 548 | if (size != full_size) /* truncated */ 549 | { 550 | TRACE( "Modules larger than 4Gb not supported\n"); 551 | res = STATUS_INVALID_PARAMETER; 552 | goto done; 553 | } 554 | res = map_image( handle, fhandle, mhandle, base, size, mask, header_size, 555 | -1, INVALID_HANDLE_VALUE, addr_ptr ); 556 | if (res >= 0) *size_ptr = size; 557 | return res; 558 | } 559 | 560 | assert (!"Not supported"); 561 | #if 0 562 | res = STATUS_INVALID_PARAMETER; 563 | if (offset.QuadPart >= full_size) goto done; 564 | if (*size_ptr) 565 | { 566 | if (*size_ptr > full_size - offset.QuadPart) goto done; 567 | size = ROUND_SIZE( offset.u.LowPart, *size_ptr ); 568 | if (size < *size_ptr) goto done; /* wrap-around */ 569 | } 570 | else 571 | { 572 | size = full_size - offset.QuadPart; 573 | if (size != full_size - offset.QuadPart) /* truncated */ 574 | { 575 | WARN( "Files larger than 4Gb (%s) not supported on this platform\n", 576 | wine_dbgstr_longlong(full_size) ); 577 | goto done; 578 | } 579 | } 580 | 581 | /* Reserve a properly aligned area */ 582 | 583 | server_enter_uninterrupted_section( &csVirtual, &sigset ); 584 | 585 | get_vprot_flags( protect, &vprot ); 586 | vprot |= (map_vprot & VPROT_COMMITTED); 587 | res = map_view( &view, *addr_ptr, size, mask, FALSE, vprot ); 588 | if (res) 589 | { 590 | server_leave_uninterrupted_section( &csVirtual, &sigset ); 591 | goto done; 592 | } 593 | 594 | /* Map the file */ 595 | 596 | TRACE("handle=%p size=%lx offset=%x%08x\n", 597 | handle, size, offset.u.HighPart, offset.u.LowPart ); 598 | 599 | res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, vprot, !dup_mapping ); 600 | if (res == STATUS_SUCCESS) 601 | { 602 | *addr_ptr = view->base; 603 | *size_ptr = size; 604 | view->mapping = dup_mapping; 605 | dup_mapping = 0; /* don't close it */ 606 | } 607 | else 608 | { 609 | ERR( "map_file_into_view %p %lx %x%08x failed\n", 610 | view->base, size, offset.u.HighPart, offset.u.LowPart ); 611 | delete_view( view ); 612 | } 613 | 614 | server_leave_uninterrupted_section( &csVirtual, &sigset ); 615 | #endif 616 | 617 | done: 618 | return res; 619 | 620 | // *addr_ptr = MapViewOfFile (handle, 621 | // protect == PAGE_READONLY ? FILE_MAP_READ : FILE_MAP_WRITE, 622 | // offset_ptr ? offset_ptr->HighPart : 0, 623 | // offset_ptr ? offset_ptr->LowPart : 0, 624 | // size_ptr ? size_ptr->LowPart : 0); 625 | // if (*addr_ptr == NULL) 626 | // return GetLastError (); 627 | // 628 | // return STATUS_SUCCESS; 629 | } 630 | -------------------------------------------------------------------------------- /loader/AUTHORS: -------------------------------------------------------------------------------- 1 | Package: himemce 2 | Maintainer: Marcus Brinkmann 3 | License (software): LGPLv2.1+ 4 | 5 | g10 Code GmbH 6 | - All changes to the wine code base since 2010-08-13, and packaging. 7 | 8 | Wine project authors 9 | - wine 1.1.42 10 | 11 | Copyright (c) 1993-2010 the Wine project authors (see the file AUTHORS 12 | for a complete list) 13 | 14 | Wine is free software; you can redistribute it and/or modify it under 15 | the terms of the GNU Lesser General Public License as published by the 16 | Free Software Foundation; either version 2.1 of the License, or (at 17 | your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, but 20 | WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | Lesser General Public License for more details. 23 | 24 | A copy of the GNU Lesser General Public License is included in the 25 | Wine distribution in the file COPYING.LIB. If you did not receive this 26 | copy, write to the Free Software Foundation, Inc., 51 Franklin St, 27 | Fifth Floor, Boston, MA 02110-1301, USA. 28 | 29 | Wine is available thanks to the work of: 30 | 31 | Sami Aario 32 | James Abbatiello 33 | Michael Abbott 34 | Michael Abd-El-Malek 35 | Howard Abrams 36 | David Adam 37 | Mark G. Adams 38 | Bruno Afonso 39 | Farshad Agah 40 | Samir Al-Battran 41 | Guy Albertelli 42 | Jens Albretsen 43 | Apostolos Alexiadis 44 | Jesse Allen 45 | Stewart Allen 46 | Jose Alonso 47 | Cihan Altinay 48 | Gustavo Junior Alves 49 | Patrick Ammann 50 | Markus Amsler 51 | Bob Amstadt 52 | C. Scott Ananian 53 | David Anderson 54 | James Dean Anderson 55 | Russ Andersson 56 | Torbjörn Andersson 57 | Eric Anholt 58 | Benjamin Arai 59 | Pedro Araujo Chaves Jr 60 | Alex Arazi 61 | Augusto Arcoverde da Rocha 62 | Alam Arias 63 | Aaron Arvey 64 | Matthew D'Asaro 65 | Dag Asheim 66 | Fatih Aşıcı 67 | Rémi Assailly 68 | Jim Aston 69 | Zimler Attila 70 | Christian Authmann 71 | Martin Ayotte 72 | Viktor Babrian 73 | Karl Backström 74 | Bradley Baetz 75 | Paul Bain 76 | Warren Baird 77 | Peter Bajusz 78 | Tijs van Bakel 79 | Nerijus Baliunas 80 | Alexandru Balut 81 | Scott Bambrough 82 | Andre Malafaya Baptista 83 | Denis Baranov 84 | Justin Santa Barbara 85 | Aaron Barnes 86 | Cesar Eduardo Barros 87 | Ismael Barros 88 | Guido Barzini 89 | Jean-Claude Batista 90 | Jacek Bator 91 | Marcel Baur 92 | Michael Beach 93 | Francis Beaudet 94 | Tom Bech 95 | David Beck 96 | Ralf Beck 97 | Matthew Becker 98 | Nathan Beckmann 99 | Dave Belanger 100 | Ken Belleau 101 | Yvon Belleau 102 | Maxime Bellengé 103 | Elias Benali 104 | Luke Benstead 105 | Leo van den Berg 106 | Anders Bergh 107 | Christopher Berner 108 | Vincent Béron 109 | Alec Berryman 110 | Molle Bestefich 111 | Joris Beugnies 112 | Eric van Beurden 113 | Peter Beutner 114 | Stephan Beuze 115 | Georg Beyerle 116 | Pierre Beyssac 117 | Przemysław Białek 118 | Fabian Bieler 119 | Giuseppe Bilotta 120 | Bobby Bingham 121 | Ross Biro 122 | Hartmut Birr 123 | Marco Bizzarri 124 | Andreas Bjerkeholt 125 | Dennis Björklund 126 | David Black 127 | Charles Blacklock 128 | Zygo Blaxell 129 | Kai Blin 130 | Matthew Bloch 131 | Laurent Blume 132 | Martin Boehme 133 | Francois Boisvert 134 | Pim Bollen 135 | Erik Inge Bolsø 136 | Mike Bond 137 | Uwe Bonnes 138 | Samuel Lidén Borell 139 | Andrew Borodin 140 | Peter Bortas 141 | Noel Borthwick 142 | Erik Bos 143 | Fons Botman 144 | Sylvain Bouchard 145 | Frederic Boulanger 146 | Finlo Boyde 147 | Justin Bradford 148 | Aleksey Bragin 149 | Günther Brammer 150 | Luke Bratch 151 | John Brezak 152 | Alastair Bridgewater 153 | Simon Britnell 154 | Christian Britz 155 | Dustin Brody 156 | Nicolas Brouard 157 | Alban Browaeys 158 | Marcus R. Brown 159 | Philip Brown 160 | Zachary Brown 161 | Gregor Brunmar 162 | Stefan Brüns 163 | Tom Brus 164 | Przemyslaw Bruski 165 | Gabriel Buades Rubio 166 | Vitaly Budovski 167 | Jan Van Buggenhout 168 | Andrew Bulhak 169 | Christoph Bumiller 170 | Divan Burger 171 | Tobias Burnus 172 | Nick Burns 173 | John Burton 174 | Alex Busenius 175 | Bernd Buschinski 176 | Luis Carlos Busquets Pérez 177 | Sergei Butakov 178 | Jonathan Buzzard 179 | Jacek Caban 180 | Piotr Caban 181 | Stewart Caie 182 | Jim Cameron 183 | Brad Campbell 184 | Jose Marcos López Caravaca 185 | Michael Cardenas 186 | Tomas Carnecky 187 | Eddie Carpenter 188 | Niels de Carpentier 189 | Mike Castle 190 | Erik de Castro Lopo 191 | Julien Cegarra 192 | Ron Cemer 193 | Fabian Cenedese 194 | Gordon Chaffee 195 | Gael de Chalendar 196 | Royal Chan 197 | Hervé Chanal 198 | Brian Chang 199 | Matt Chapman 200 | Peter Chapman 201 | Antoine Chavasse 202 | Mauro Carvalho Chehab 203 | Ethan Chen 204 | Jau-Horng Chen 205 | Tisheng Chen 206 | Rustam Chernotkach 207 | Justin Chevrier 208 | Yong Chi 209 | Jimen Ching 210 | Hann-huei Chiou 211 | Paul Chitescu 212 | Leslie Choong 213 | Panagiotis Christeas 214 | Kieran Clancy 215 | Geoff Clare 216 | Duane Clark 217 | Matthew Clarke 218 | Matthew Cline 219 | Antonio Codazzi 220 | Robert 'Admiral' Coeyman 221 | Richard Cohen 222 | Phil Cole 223 | Ken Coleman 224 | Roderick Colenbrander 225 | Jens Collin 226 | Kees Cook 227 | Tijl Coosemans 228 | Christian Costa 229 | Phil Costin 230 | Jean-Claude Cote 231 | James Courtier-Dutton 232 | Chuck Crayne 233 | Stephen Crowley 234 | Ryan Cumming 235 | Pascal Cuoq 236 | Bill Currie 237 | David A. Cuthbert 238 | Benjamin Cutler 239 | Aric Cyr 240 | Brian Joseph Czapiga 241 | Ulrich Czekalla 242 | Johan Dahlin 243 | Wilbur N. Dale 244 | Martin Dalecki 245 | Gunnar Dalsnes 246 | Fergal Daly 247 | Qingdoa Daoo 248 | Jean-Michel Dault 249 | Huw D. M. Davies 250 | Joshua Davies 251 | Matthew Davison 252 | Evan Deaubl 253 | Lionel Debroux 254 | Bryan DeGrendel 255 | Moses DeJong 256 | Frédéric Delanoy 257 | Nicolas Delcros 258 | Sam Dennis 259 | Matthias Derer 260 | Andrei Derevyanko 261 | Raul Dias 262 | Robert Dickenson 263 | Darryl Dixon 264 | Jan Djarv 265 | Petar Djukic 266 | Petr Dlouhý 267 | Roman Dolejsi 268 | François Dorin 269 | Alexander Dorofeyev 270 | Frans van Dorsselaer 271 | Stefan Dösinger 272 | Jeremy Drake 273 | Yann Droneaud 274 | Josh DuBois 275 | Marcelo Duarte 276 | Charles Duffy 277 | Mark Dufour 278 | Warren Dumortier 279 | Reece H. Dunn 280 | EA Durbin 281 | Zoran Dzelajlija 282 | Jason Edmeades 283 | Steven Edwards 284 | Christian Eggers 285 | Rikhardur Egilsson 286 | Andrew Eikum 287 | Karsten Elfenbein 288 | John Elliot 289 | David Elliott 290 | Steven Elliott 291 | Dan Engel 292 | Ralf S. Engelschall 293 | Austin English 294 | Rich Ercolani 295 | Morten Eriksen 296 | Jakob Eriksson 297 | Hib Eris 298 | Jonathan Ernst 299 | Nicolas Escuder 300 | Andrey Esin 301 | Phillip Ezolt 302 | Chris Faherty 303 | Carsten Fallesen 304 | Paul Falstad 305 | Alexander Farber 306 | Susan Farley 307 | Rob Farnum 308 | David Faure 309 | Matthias Fechner 310 | Massimo Del Fedele 311 | Andrew Fenn 312 | Tim Ferguson 313 | Raul Fernandes 314 | Filipe Ferreira 315 | Wesley Filardo 316 | Ricardo Filipe 317 | Colin Finck 318 | Matt Finnicum 319 | Aurimas Fischer 320 | Claus Fischer 321 | Aurimas Fišeras 322 | Thomas Fitzsimmons 323 | Olaf Flebbe 324 | Yuval Fledel 325 | Jeremiah Flerchinger 326 | Tom Fogal 327 | Krzysztof Foltman 328 | Chad Fraleigh 329 | Matthew Francis 330 | Kolbjørn Fredheim 331 | Lars-Ake Fredlund 332 | Eric Frias 333 | Christoph Frick 334 | Klemens Friedl 335 | Todd T. Fries 336 | Alexander Frink 337 | Michael Fritscher 338 | Philippe Froidevaux 339 | Mike Frysinger 340 | Martin Fuchs 341 | Bernd Fuhrmann 342 | Shunichi Fuji 343 | Satsuki Fujishima 344 | Ron Gage 345 | Louis Philippe Gagnon 346 | Peter Galbavy 347 | Gabriel Gambetta 348 | Peter Ganten 349 | Gabriel Garcia 350 | Ramon Garcia 351 | Johan Gardell 352 | Michael Gardiner 353 | Jérôme Gardou 354 | Martin Garton 355 | Jeff Garzik 356 | Sebastian Gasiorek 357 | Patrick Gauthier 358 | Christopher Gautier 359 | David Gay 360 | Julio César Gázquez 361 | Ge van Geldorp 362 | Klaas van Gend 363 | Abey George 364 | Henning Gerhardt 365 | Brian Gerst 366 | Matthew Ghio 367 | Johan Gill 368 | John Gilmore 369 | Denver Gingerich 370 | Gabriele Giorgetti 371 | Kristoffer Gleditsch 372 | Christian Gmeiner 373 | Jody Goldberg 374 | Zach Goldberg 375 | David Golding 376 | Markus Gömmel 377 | Julio E. Gonzalez P 378 | Bob Goodwin 379 | Eugeny Gorelov 380 | Zach Gorman 381 | Florian Goth 382 | Mathias Gottschlag 383 | Alexander Gottwald 384 | François Gouget 385 | George Gov 386 | J A Gow 387 | Hans de Graaff 388 | Igor Grahek 389 | David Grant 390 | Brian Grayson 391 | Jaco Greeff 392 | Chris Green 393 | Jason Green 394 | Jon Griffiths 395 | Kevin Groeneveld 396 | Gerhard W. Gruber 397 | Michael Gruber 398 | Tobias Gruetzmacher 399 | Marcin Grześkowiak 400 | Daniel Gudbjartsson 401 | Stefano Guidoni 402 | Adam Gundy 403 | Michael Günnewig 404 | Ivan Gyurdiev 405 | Albert den Haan 406 | Jess Haas 407 | David D. Hagood 408 | Hagop Hagopian 409 | Robert W Hall 410 | Patrick Haller 411 | Stefan Haller 412 | Jake Hamby 413 | David Hammerton 414 | Paul TBBle Hampson 415 | Noomen Hamza 416 | Anssi Hannula 417 | Charles M. Hannum 418 | Vincent Hardy 419 | Yorick Hardy 420 | Boaz Harrosh 421 | Adrian Harvey 422 | Christopher Harvey 423 | John Harvey 424 | James Hatheway 425 | Geoffrey Hausheer 426 | Kalevi J Hautaniemi 427 | Bill Hawes 428 | Dave Hawkes 429 | James Hawkins 430 | Peter Hawkins 431 | Shi Quan He 432 | Mike Hearn 433 | Waldek Hebisch 434 | Ulrich Hecht 435 | David Hedberg 436 | Peter Hedlund 437 | Lars Heete 438 | Cameron Heide 439 | Hagen Heiduck 440 | Jukka Heinonen 441 | David Hemmo 442 | André Hentschel 443 | Pierre d'Herbemont 444 | Juraj Hercek 445 | Bernd Herd 446 | Robert van Herk 447 | Theodore S. Hetke 448 | Dan Hipschman 449 | Markus Hitter 450 | Haithem Hmida 451 | Roger Hoang 452 | Ben Hodgetts 453 | Jochen Hoenicke 454 | Henning Hoffmann 455 | Jens Hoffmann 456 | Michael Hoffman 457 | Erik Hofman 458 | Jörg Höhle 459 | John K. Hohm 460 | Kevin Holbrook 461 | Joel Holdsworth 462 | Nick Holloway 463 | Alfons Hoogervorst 464 | Erich Hoover 465 | Aaron Hope 466 | Enrico Horn 467 | Casper Hornstrup 468 | Olivier Houchard 469 | Onno Hovers 470 | David Howells 471 | Vit Hrachovy 472 | Sin-ta Hsiea 473 | Jeffrey Hsu 474 | Zhangrong Huang 475 | Edgar Hucek 476 | Sean Huckins 477 | Stefan Huehner 478 | Andrew John Hughes 479 | Tom Hughes 480 | Joris Huizer 481 | Peter Hunnisett 482 | A C Hurst 483 | Choe Hwanjin 484 | Miguel de Icaza 485 | Mikio Idneuma 486 | Mounir Idrassi 487 | Romain Iehl 488 | Jukka Iivonen 489 | Vladdy Impaler 490 | Hiroshi Inoue 491 | Simon C. Ion 492 | Kostya Ivanov 493 | Serge Ivanov 494 | Peter Ivanyi 495 | Lance Jackson 496 | Michael Jacobsen 497 | Francois Jacques 498 | Lee Jaekil 499 | Gautam Jain 500 | Tobias Jakobi 501 | Jeroen Janssen 502 | Oldrich Jedlicka 503 | György 'Nog' Jeney 504 | Jerry Jenkins 505 | Niels Kristian Bech Jensen 506 | Ron Jensen 507 | Byeong-Sik Jeon 508 | Tomasz Jezierski 509 | Rajeev Jhangiani 510 | Jerry Ji 511 | Antonio Larrosa Jiménez 512 | Bill Jin 513 | Jeff Johann 514 | André Johansen 515 | Andrew Johnston 516 | Matt Jones 517 | Anders Jonsson 518 | Damjan Jovanovic 519 | Alexandre Julliard 520 | Jussi Jumppanen 521 | Bang Jun-Young 522 | Michael Jung 523 | Raphael Junqueira 524 | James Juran 525 | Mario Kacmar 526 | Achim Kaiser 527 | Rolf Kalbermatter 528 | Maciek Kaliszewski 529 | Kaj Kaloinen 530 | Yuriy Kaminskiy 531 | Alexander Kanavin 532 | Srivatsa Kanchi, R 533 | Jukka Kangas 534 | Thorsten Kani 535 | Pavel Kankovsky 536 | Lauris Kaplinski 537 | Mike Kaplinskiy 538 | Michael Karcher 539 | Reinhard Karcher 540 | Niclas Karlsson 541 | Jochen Karrer 542 | Valery Kartel 543 | Rudolf Kastl 544 | Hirofumi Katayama 545 | Michael Kaufmann 546 | Tapio Kautto 547 | Dan Kegel 548 | Matthew Kehrer 549 | Don Kelly 550 | Robert Key 551 | Yuri Khan 552 | Thomas Kho 553 | Sergey Khodych 554 | Vijay Kiran Kamuju 555 | Andreas Kirschbaum 556 | Dmitry Kislyuk 557 | Simon Kissane 558 | Rafael Kitover 559 | Rein Klazes 560 | John Klehm 561 | Ben Klein 562 | Albrecht Kleine 563 | Dietmar Kling 564 | William Knop 565 | Florian Köberle 566 | Johannes Koch 567 | Eric Kohl 568 | Kevin Koltzau 569 | Konstantin Kondratyuk 570 | Jon Konrath 571 | Ilya Konstantinov 572 | Frans Kool 573 | Oleg Korda 574 | Ilya Korniyko 575 | Alex Korobka 576 | David Korth 577 | Mathias Kosch 578 | Misha Koshelev 579 | Krzysztof Kotlenga 580 | Kusanagi Kouichi 581 | András Kovács 582 | Zoltan Kovacs 583 | Yuri Kozlov 584 | Milko Krachounov 585 | Kevin Krammer 586 | Saulius Krasuckas 587 | Jan Kratochvil 588 | David Kredba 589 | Marko Kreen 590 | Greg Kreider 591 | Timo Kreuzer 592 | Oleg Krylov 593 | Phil Krylov 594 | Junichi Kuchinishi 595 | Maksim Kuleshov 596 | Vik Kumar 597 | Anand Kumria 598 | Matthias Kupfer 599 | Gerson Kurz 600 | Ove Kåven 601 | Jean Labrousse 602 | Dusan Lacko 603 | Bernard Ladenthin 604 | Eric Laforest 605 | William Lahti 606 | Scott A. Laird 607 | Matthew Lake 608 | Hamza Lakhani 609 | David Lee Lambert 610 | Tony Lambregts 611 | Eric Lammerts 612 | Juan Lang 613 | Stephen Langasek 614 | Sean Langley 615 | Dan Langlois 616 | Maarten Lankhorst 617 | Jared Lapsley 618 | Peter Berg Larsen 619 | Thomas Brix Larsen 620 | Alexander Larsson 621 | Tommy Schultz Lassen 622 | Alex Villacís Lasso 623 | David Lassonde 624 | Jeff Latimer 625 | Paul Laufer 626 | Klaus Layer 627 | Nicolas Le Cam 628 | Albert Lee 629 | Jaekil Lee 630 | Sander van Leeuwen 631 | Stefan Leichter 632 | Hans Leidekker 633 | Peter Lemenkov 634 | Kristiaan Lenaerts 635 | Louis Lenders 636 | Crestez Leonard 637 | Alistair Leslie-Hughes 638 | Karl Lessard 639 | Pascal Lessard 640 | Eddie Leung 641 | Hin-Tak Leung 642 | Blake Leverett 643 | Wim Lewis 644 | Andrew Lewycky 645 | John Li 646 | Weisheng Li 647 | Xiang Li 648 | Nigel Liang 649 | David Lichterman 650 | James Liggett 651 | Kim Lilliestierna 652 | Michael Lin 653 | Per Lindström 654 | Vitaly Lipatov 655 | Brian Litzinger 656 | Anderson Lizardo 657 | Juergen Lock 658 | Phil Lodwick 659 | Charles Loep 660 | Stéphane Loeuillet 661 | Tobias Loew 662 | Martin von Loewis 663 | Michiel van Loon 664 | Richard A Lough 665 | Carlos Lozano 666 | Jean-Bruno Luginbühl 667 | Denis Lukianov 668 | Alexander V. Lukyanov 669 | Austin Lund 670 | Daniel Lund 671 | Magnus Lundborg 672 | Robert Lunnon 673 | Jiuming Luo 674 | Christian Lupien 675 | Stephane Lussier 676 | Steve Lustbader 677 | David Luyer 678 | Anatoly Lyutin 679 | Ragnvald Maartmann-Moe IV 680 | José Marcos López 681 | Kenneth MacDonald 682 | Peter MacDonald 683 | Ondrej Macek 684 | Kester Maddock 685 | Pierre Mageau 686 | Michael C. Maggio 687 | William Magro 688 | Pedro Maia 689 | Emmanuel Maillard 690 | Rok Mandeljc 691 | Vitaliy Margolen 692 | Cyril Margorin 693 | Alexey Markachev 694 | Daniel Marmier 695 | Juergen Marquardt 696 | Greg Marsden 697 | Kris Marsh 698 | Brad Martin 699 | Philip Mason 700 | Alberto Massari 701 | Ricardo Massaro 702 | Matthew Mastracci 703 | Keith Matthews 704 | Gregg Mattinson 705 | Jason Mawdsley 706 | Joerg Mayer 707 | Eugene Mayevski 708 | Ben Mayhew 709 | Bryan Mayland 710 | Davin McCall 711 | Rob McClinton 712 | Michael McCormack 713 | David McCullough 714 | Rhys McGuckin 715 | Alastair McKinstry 716 | Jason McMullan 717 | Harry McNally 718 | Caolan McNamara 719 | Patrick J. McNerthney 720 | Paul McNett 721 | Bill Medland 722 | Marcus Meissner 723 | Josef Meixner 724 | Américo José Melo 725 | Fabrice Ménard 726 | Graham Menhennitt 727 | Luis Javier Merino 728 | Thomas Mertes 729 | Johann Messner 730 | David Metcalfe 731 | Francois Methot 732 | Raul Metsma 733 | Travis Michielsen 734 | Wojciech Migda 735 | Toufic Milan 736 | Robert Millan 737 | Paul Millar 738 | Dave Miller 739 | David Miller 740 | Donn Miller 741 | Jeff Miller 742 | Bruce Milner 743 | Roman Mindalev 744 | Michal Janusz Miroslaw 745 | Anish Mistry 746 | Royce Mitchell III 747 | Sagar Mittal 748 | Peter Mladek 749 | Steffen Moeller 750 | Andreas Mohr 751 | Todd Mokros 752 | Slava Monich 753 | James Moody 754 | Jan de Mooij 755 | David Moore 756 | Patrick Moran 757 | Chris Morgan 758 | Kai Morich 759 | Elie Morisse 760 | Alexander Morozov 761 | John Morris 762 | Shaun Morris 763 | Richard Mortimer 764 | Adam D. Moss 765 | Michael Moss 766 | Julien Muchembled 767 | Jeff Muizelaar 768 | Vasudev Mulchandani 769 | Gregor Münch 770 | Krishna Murthy 771 | Rick Mutzke 772 | Philippe De Muyter 773 | Rafał Mużyło 774 | Ken Myers 775 | Kimmo Myllyvirta 776 | Zoltan Nagy 777 | Itai Nahshon 778 | Filip Navara 779 | Juan M. Navarro 780 | Dustin Navea 781 | Felix Nawothnig 782 | Jonathan Naylor 783 | Jens Nestler 784 | Nathan Neulinger 785 | Christian Neumair 786 | Jeremy Newman 787 | Tim Newsome 788 | Andrew Nguyen 789 | Thuy Nguyen 790 | Hongbo Ni 791 | Kristian Nielsen 792 | Arjen Nienhuis 793 | Jan Nieuwenhuizen 794 | Jan-Peter Nilsson 795 | Philip Nilsson 796 | Nix N. Nix 797 | Muneyuki Noguchi 798 | Sami Nopanen 799 | Leonard Norrgård 800 | Robert North 801 | Tomasz Nowiński 802 | Oleh R. Nykyforchyn 803 | Daniel Nylander 804 | Per Nystrom 805 | Robert O'Callahan 806 | Damien O'Neill 807 | Mike O'Regan 808 | Peter Oberndorfer 809 | Walt Ogburn 810 | Damyan Ognyanoff 811 | Henrik Olsen 812 | Magnus Olsen 813 | Roger Olson 814 | Neil Olver 815 | José Manuel Ferrer Ortiz 816 | Knut St. Osmundsen 817 | Andriy Palamarchuk 818 | Giovanni Pancotti 819 | Vladimir Pankratov 820 | Andrey Panov 821 | Won Kyu Park 822 | Joel Parker 823 | Evan G. Parry 824 | Jon Parshall 825 | Marcel Partap 826 | Alex Pasadyn 827 | Sven Paschukat 828 | Michal Pasternak 829 | Gerard Patel 830 | Michael Patra 831 | Murali Pattathe 832 | Catalin Patulea 833 | Doug Paul 834 | Dimitrie O. Paun 835 | Bernd Paysan 836 | Vincent Pelletier 837 | Victor Pelt 838 | Brad Pepers 839 | Ted Percival 840 | Vitaly Perov 841 | James Perry 842 | Ori Pessach 843 | Adam Petaccia 844 | Nemeth Peter 845 | Chris Peterson 846 | Jim Peterson 847 | Sylvain Petreolle 848 | Konstantin Petrov 849 | Ofir Petruska 850 | Diego Pettenò 851 | Gerald Pfeifer 852 | Jason Phillips 853 | Dave Pickles 854 | Marco Pietrobono 855 | Alessandro Pignotti 856 | Ian Pilcher 857 | Simeon Pilgrim 858 | Martin Pilka 859 | Laurent Pinchart 860 | Aviad Pineles 861 | Brian Pirie 862 | Colin Pitrat 863 | Davide Pizzetti 864 | Michael Ploujnikov 865 | William Poetra Yoga Hadisoesen 866 | Gracjan Polak 867 | Michael Poole 868 | Andrzej Popowski 869 | Dmitry Potapov 870 | Eric Pouech 871 | Robert Pouliot 872 | Vahid Pourlotfali 873 | Hervé Poussineau 874 | Vincent Povirk 875 | Chad Powell 876 | Joseph Pranevich 877 | Raimonds Praude 878 | Aneurin Price 879 | Alex Priem 880 | Martin Profittlich 881 | Oleg Prokhorov 882 | Roberto Augusto Pungartnik 883 | Francesco Di Punzio 884 | Ivan Leo Puoti 885 | Andrew de Quincey 886 | Paul Quinn 887 | Peter Quiring 888 | L. Rahyen 889 | Hernan Rajchert 890 | Renu Rajput 891 | Pete Ratzlaff 892 | Jaime Rave 893 | Ron Record 894 | Robert Reif 895 | Stefan Reimer 896 | Petter Reinholdtsen 897 | John Reiser 898 | Karl Relton 899 | Daniel Remenak 900 | Andrew de los Reyes 901 | Keith Reynolds 902 | Slaven Rezic 903 | Artem Reznikov 904 | John Richardson 905 | Rick Richardson 906 | Frank Richter 907 | Simon Richter 908 | Douglas Ridgway 909 | Konrad Rieck 910 | Andrew Riedi 911 | Detlef Riekenberg 912 | Robert Riggs 913 | Peter Riocreux 914 | Scott Ritchie 915 | Paul Bryan Roberts 916 | Matthew Robertson 917 | Chris Robinson 918 | Vedran Rodic 919 | Wino Rojo 920 | Troy Rollo 921 | Paul Romanyszyn 922 | Drew Ronneberg 923 | Stephan Rose 924 | Andreas Rosenberg 925 | Bernhard Rosenkraenzer 926 | Pavel Roskin 927 | Herbert Rosmanith 928 | Elias Ross 929 | Lilia Roumiantseva 930 | Owen Rudge 931 | Paul Rupe 932 | Mike Ruprecht 933 | Johannes Ruscheinski 934 | Andy Rysin 935 | Daniel Sabo 936 | Adam Sacarny 937 | Ivan de Saedeleer 938 | Madhura Sahasrabudhe 939 | Diaa Sami 940 | Kasper Sandberg 941 | Thomas Sandford 942 | Daniel Santos 943 | Constantine Sapuntzakis 944 | Pablo Saratxaga 945 | Kouji Sasaki 946 | Mike Schaadt 947 | Carl van Schaik 948 | Florian Tobias Schandinat 949 | Peter Schauer 950 | Paul van Schayck 951 | Daniel Schepler 952 | Johannes E. Schindelin 953 | Christian Schlaile 954 | Peter Schlaile 955 | Michael Schlüter 956 | Ulrich Schmid 957 | Axel Schmidt 958 | Bernd Schmidt 959 | Ian Schmidt 960 | Ryan Schmidt 961 | Juergen Schmied 962 | Ingo Schneider 963 | Victor Schneider 964 | Kees Schoenmakers 965 | Glenn Schrader 966 | Rico Schüller 967 | Marco Schuster 968 | Waldeck Schutzer 969 | Tim Schwartz 970 | Federico Schwindt 971 | Wolfgang Schwotzer 972 | Dan Scott 973 | Alexander Scott-Johns 974 | Tim Segall 975 | Hajime Segawa 976 | Pavel Semerad 977 | Hippocrates Sendoukas 978 | Stas Sergeev 979 | Ken Sharp 980 | Jeremy Shaw 981 | Roy Shea 982 | Robert Shearman 983 | John Sheets 984 | Shachar Shemesh 985 | Nickolay V. Shmyrev 986 | Ilya Shpigor 987 | Santosh Siddheshwar 988 | Stefan Siebert 989 | Yngvi Sigurjonsson 990 | Gustavo Noronha Silva 991 | Stephen Simmons 992 | Alasdair Sinclair 993 | Andrej Sinicyn 994 | Ivan Sinitsin 995 | Dmitrij Sinukov 996 | Willie Sippel 997 | Nikolay Sivov 998 | Kjell Rune Skaaraas 999 | Daniel Skorka 1000 | Jesper Skov 1001 | Neil Skrypuch 1002 | Rick Sladkey 1003 | Sasha Slijepcevic 1004 | Kirill Smelkov 1005 | Kirill K. Smirnov 1006 | David Smith 1007 | Dylan Smith 1008 | Jeff Smith 1009 | William Smith 1010 | Juris Smotrovs 1011 | Ed Snow 1012 | Jaroslaw Piotr Sobieszek 1013 | Carl Sopchak 1014 | Alexander Nicolaysen Sørnes 1015 | Pablo Spallanzani 1016 | Thomas Spear 1017 | Chris Spencer 1018 | Liu Spider 1019 | Matej Spindler 1020 | Patrick Spinler 1021 | Serge S. Spiridonoff 1022 | Alexey Spiridonov 1023 | Sylvain St-Germain 1024 | Evan Stade 1025 | Malte Starostik 1026 | Gavriel State 1027 | Sheri Steeves 1028 | Michael Stefaniuc 1029 | Jozef Stefanka 1030 | Nikolay Stefanov 1031 | Steven Stein 1032 | Igor Stepin 1033 | Keith Stevens 1034 | Norman Stevens 1035 | Aric Stewart 1036 | Johannes Stezenbach 1037 | Oliver Stieber 1038 | Clinton Stimpson 1039 | William Stinson 1040 | Adam Stoelting 1041 | Richard Stonehouse 1042 | Stefan Stranz 1043 | Dominik Strasser 1044 | Patrik Stridvall 1045 | Vadim Strizhevsky 1046 | Bertho Stultiens 1047 | John F Sturtz 1048 | Michal Suchanek 1049 | Abraham Sudhakar 1050 | Petr Sumbera 1051 | Supphachoke Suntiwichaya 1052 | Charles Suprin 1053 | James Sutherland 1054 | Erik Svendsen 1055 | Artur Szymiec 1056 | Dylan Taft 1057 | Yoshiro Takeno 1058 | Hidenori Takeshima 1059 | Andrew Talbot 1060 | Hiroshi Tanabe 1061 | Igor Tarasov 1062 | Tristan Tarrant 1063 | Andrew Taylor 1064 | Ben Taylor 1065 | Brian Teague 1066 | Evan Teran 1067 | Petr Tesarik 1068 | Wolfgang Thaller 1069 | Kanit Therdsteerasukdi 1070 | Jean-Philippe Theriault 1071 | Joshua Thielen 1072 | Ingmar Thiemann 1073 | Dirk Thierbach 1074 | Jean-Louis Thirot 1075 | Ken Thomases 1076 | Duncan C Thomson 1077 | Geoff Thorpe 1078 | Adrian Thurston 1079 | Goran Thyni 1080 | Steve Tibbett 1081 | Dmitry Timoshkov 1082 | Marco Timpano 1083 | Will Tipton 1084 | Jimmy Tirtawangsa 1085 | Petr Tomasek 1086 | Jon Tombs 1087 | Janusz Tomczak 1088 | Allan Tong 1089 | Gal Topper 1090 | Linus Torvalds 1091 | Luc Tourangeau 1092 | Jeff Tranter 1093 | Pavel Troller 1094 | Gregory Trubetskoy 1095 | Lauri Tulmin 1096 | Petri Tuomola 1097 | Sergey Turchanov 1098 | Warren Turkal 1099 | Andrey Turkin 1100 | Gregory M. Turner 1101 | Peter Dons Tychsen 1102 | Lionel Ulmer 1103 | Peter Urbanec 1104 | Moshe Vainer 1105 | Hleb Valoska 1106 | Hannu Valtonen 1107 | Carroll Vance 1108 | Tomas Vanek 1109 | Charles Vaughn 1110 | Stephen R. Veit 1111 | Michael Veksler 1112 | Henri Verbeet 1113 | Sven Verdoolaege 1114 | Martijn Vernooij 1115 | Peter Verthez 1116 | Todd Vierling 1117 | Brian Vincent 1118 | Leonardo Quijano Vincenzi 1119 | Vasily I. Volchenko 1120 | Erez Volk 1121 | Jerome Vouillon 1122 | Paul Vriens 1123 | Laurent Vromman 1124 | Duc Vuong 1125 | Trent Waddington 1126 | William Waghorn 1127 | Ferenc Wagner 1128 | Ronan Waide 1129 | Daniel Walker 1130 | Martin Walker 1131 | Wolfgang Walter 1132 | Simon Walton 1133 | Owen Wang 1134 | Eric Warnke 1135 | Tony Wasserka 1136 | Andrew Webb 1137 | Leigh Wedding 1138 | Randy Weems 1139 | Manfred Weichel 1140 | Thomas Weidenmueller 1141 | Ulrich Weigand 1142 | Markus Weiland 1143 | David Welch 1144 | Morten Welinder 1145 | Marcelo Welter 1146 | Mark Westcott 1147 | Michael Wetherell 1148 | Jeremy White 1149 | Len White 1150 | Lawson Whitney 1151 | Tom Wickline 1152 | Michał Wiernowolski 1153 | Martin Wilck 1154 | Jan Willamowius 1155 | Carl Williams 1156 | Eric Williams 1157 | Grant Williamson 1158 | Chris Wilson 1159 | Jed Wing 1160 | Andre Wisplinghoff 1161 | Christoph von Wittich 1162 | Łukasz Wojniłowicz 1163 | Dan Wolf 1164 | Erwin Wolff 1165 | Philipp Wollermann 1166 | Ivan Wong 1167 | Brandon Woodmansee 1168 | Alex Woods 1169 | Cliff Wright 1170 | Tim Wright 1171 | Chia-I Wu 1172 | Gerold Jens Wucherpfennig 1173 | Karl Guenter Wuensch 1174 | Chris Wulff 1175 | Glenn Wurster 1176 | Jon Yang 1177 | Mehmet Yasar 1178 | Alexander Yaworsky 1179 | Sean Young 1180 | Eric Youngdale 1181 | James Youngman 1182 | Nikita V. Youshchenko 1183 | Hwang YunSong 1184 | Mikołaj Zalewski 1185 | Simen Zamecnik 1186 | Jeff Zaroyko 1187 | Steve Zellers 1188 | Jan Zerebecki 1189 | John Zero 1190 | Lei Zhang 1191 | Yuxi Zhang 1192 | Shanren Zhou 1193 | Andrew Ziem 1194 | G. Paul Ziemba 1195 | Daniel Zimmermann 1196 | Nikolas Zimmermann 1197 | Alex Zorach 1198 | Nathan Zorich 1199 | Luiz Otavio L. Zorzella 1200 | Rizsanyi Zsolt 1201 | Per Ångström 1202 | Peter Åstrand 1203 | 1204 | 1205 | 1206 | Copyright 2010 g10 Code GmbH 1207 | 1208 | This file is free software; as a special exception the author gives 1209 | unlimited permission to copy and/or distribute it, with or without 1210 | modifications, as long as this notice is preserved. 1211 | 1212 | This file is distributed in the hope that it will be useful, but 1213 | WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 1214 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 1215 | -------------------------------------------------------------------------------- /loader/COPYING: -------------------------------------------------------------------------------- 1 | 2 | GNU LESSER GENERAL PUBLIC LICENSE 3 | Version 2.1, February 1999 4 | 5 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 6 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | [This is the first released version of the Lesser GPL. It also counts 11 | as the successor of the GNU Library Public License, version 2, hence 12 | the version number 2.1.] 13 | 14 | Preamble 15 | 16 | The licenses for most software are designed to take away your 17 | freedom to share and change it. By contrast, the GNU General Public 18 | Licenses are intended to guarantee your freedom to share and change 19 | free software--to make sure the software is free for all its users. 20 | 21 | This license, the Lesser General Public License, applies to some 22 | specially designated software packages--typically libraries--of the 23 | Free Software Foundation and other authors who decide to use it. You 24 | can use it too, but we suggest you first think carefully about whether 25 | this license or the ordinary General Public License is the better 26 | strategy to use in any particular case, based on the explanations 27 | below. 28 | 29 | When we speak of free software, we are referring to freedom of use, 30 | not price. Our General Public Licenses are designed to make sure that 31 | you have the freedom to distribute copies of free software (and charge 32 | for this service if you wish); that you receive source code or can get 33 | it if you want it; that you can change the software and use pieces of 34 | it in new free programs; and that you are informed that you can do 35 | these things. 36 | 37 | To protect your rights, we need to make restrictions that forbid 38 | distributors to deny you these rights or to ask you to surrender these 39 | rights. These restrictions translate to certain responsibilities for 40 | you if you distribute copies of the library or if you modify it. 41 | 42 | For example, if you distribute copies of the library, whether gratis 43 | or for a fee, you must give the recipients all the rights that we gave 44 | you. You must make sure that they, too, receive or can get the source 45 | code. If you link other code with the library, you must provide 46 | complete object files to the recipients, so that they can relink them 47 | with the library after making changes to the library and recompiling 48 | it. And you must show them these terms so they know their rights. 49 | 50 | We protect your rights with a two-step method: (1) we copyright the 51 | library, and (2) we offer you this license, which gives you legal 52 | permission to copy, distribute and/or modify the library. 53 | 54 | To protect each distributor, we want to make it very clear that 55 | there is no warranty for the free library. Also, if the library is 56 | modified by someone else and passed on, the recipients should know 57 | that what they have is not the original version, so that the original 58 | author's reputation will not be affected by problems that might be 59 | introduced by others. 60 | 61 | Finally, software patents pose a constant threat to the existence of 62 | any free program. We wish to make sure that a company cannot 63 | effectively restrict the users of a free program by obtaining a 64 | restrictive license from a patent holder. Therefore, we insist that 65 | any patent license obtained for a version of the library must be 66 | consistent with the full freedom of use specified in this license. 67 | 68 | Most GNU software, including some libraries, is covered by the 69 | ordinary GNU General Public License. This license, the GNU Lesser 70 | General Public License, applies to certain designated libraries, and 71 | is quite different from the ordinary General Public License. We use 72 | this license for certain libraries in order to permit linking those 73 | libraries into non-free programs. 74 | 75 | When a program is linked with a library, whether statically or using 76 | a shared library, the combination of the two is legally speaking a 77 | combined work, a derivative of the original library. The ordinary 78 | General Public License therefore permits such linking only if the 79 | entire combination fits its criteria of freedom. The Lesser General 80 | Public License permits more lax criteria for linking other code with 81 | the library. 82 | 83 | We call this license the "Lesser" General Public License because it 84 | does Less to protect the user's freedom than the ordinary General 85 | Public License. It also provides other free software developers Less 86 | of an advantage over competing non-free programs. These disadvantages 87 | are the reason we use the ordinary General Public License for many 88 | libraries. However, the Lesser license provides advantages in certain 89 | special circumstances. 90 | 91 | For example, on rare occasions, there may be a special need to 92 | encourage the widest possible use of a certain library, so that it 93 | becomes a de-facto standard. To achieve this, non-free programs must 94 | be allowed to use the library. A more frequent case is that a free 95 | library does the same job as widely used non-free libraries. In this 96 | case, there is little to gain by limiting the free library to free 97 | software only, so we use the Lesser General Public License. 98 | 99 | In other cases, permission to use a particular library in non-free 100 | programs enables a greater number of people to use a large body of 101 | free software. For example, permission to use the GNU C Library in 102 | non-free programs enables many more people to use the whole GNU 103 | operating system, as well as its variant, the GNU/Linux operating 104 | system. 105 | 106 | Although the Lesser General Public License is Less protective of the 107 | users' freedom, it does ensure that the user of a program that is 108 | linked with the Library has the freedom and the wherewithal to run 109 | that program using a modified version of the Library. 110 | 111 | The precise terms and conditions for copying, distribution and 112 | modification follow. Pay close attention to the difference between a 113 | "work based on the library" and a "work that uses the library". The 114 | former contains code derived from the library, whereas the latter must 115 | be combined with the library in order to run. 116 | 117 | GNU LESSER GENERAL PUBLIC LICENSE 118 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 119 | 120 | 0. This License Agreement applies to any software library or other 121 | program which contains a notice placed by the copyright holder or 122 | other authorized party saying it may be distributed under the terms of 123 | this Lesser General Public License (also called "this License"). 124 | Each licensee is addressed as "you". 125 | 126 | A "library" means a collection of software functions and/or data 127 | prepared so as to be conveniently linked with application programs 128 | (which use some of those functions and data) to form executables. 129 | 130 | The "Library", below, refers to any such software library or work 131 | which has been distributed under these terms. A "work based on the 132 | Library" means either the Library or any derivative work under 133 | copyright law: that is to say, a work containing the Library or a 134 | portion of it, either verbatim or with modifications and/or translated 135 | straightforwardly into another language. (Hereinafter, translation is 136 | included without limitation in the term "modification".) 137 | 138 | "Source code" for a work means the preferred form of the work for 139 | making modifications to it. For a library, complete source code means 140 | all the source code for all modules it contains, plus any associated 141 | interface definition files, plus the scripts used to control 142 | compilation and installation of the library. 143 | 144 | Activities other than copying, distribution and modification are not 145 | covered by this License; they are outside its scope. The act of 146 | running a program using the Library is not restricted, and output from 147 | such a program is covered only if its contents constitute a work based 148 | on the Library (independent of the use of the Library in a tool for 149 | writing it). Whether that is true depends on what the Library does 150 | and what the program that uses the Library does. 151 | 152 | 1. You may copy and distribute verbatim copies of the Library's 153 | complete source code as you receive it, in any medium, provided that 154 | you conspicuously and appropriately publish on each copy an 155 | appropriate copyright notice and disclaimer of warranty; keep intact 156 | all the notices that refer to this License and to the absence of any 157 | warranty; and distribute a copy of this License along with the 158 | Library. 159 | 160 | You may charge a fee for the physical act of transferring a copy, 161 | and you may at your option offer warranty protection in exchange for a 162 | fee. 163 | 164 | 2. You may modify your copy or copies of the Library or any portion 165 | of it, thus forming a work based on the Library, and copy and 166 | distribute such modifications or work under the terms of Section 1 167 | above, provided that you also meet all of these conditions: 168 | 169 | a) The modified work must itself be a software library. 170 | 171 | b) You must cause the files modified to carry prominent notices 172 | stating that you changed the files and the date of any change. 173 | 174 | c) You must cause the whole of the work to be licensed at no 175 | charge to all third parties under the terms of this License. 176 | 177 | d) If a facility in the modified Library refers to a function or a 178 | table of data to be supplied by an application program that uses 179 | the facility, other than as an argument passed when the facility 180 | is invoked, then you must make a good faith effort to ensure that, 181 | in the event an application does not supply such function or 182 | table, the facility still operates, and performs whatever part of 183 | its purpose remains meaningful. 184 | 185 | (For example, a function in a library to compute square roots has 186 | a purpose that is entirely well-defined independent of the 187 | application. Therefore, Subsection 2d requires that any 188 | application-supplied function or table used by this function must 189 | be optional: if the application does not supply it, the square 190 | root function must still compute square roots.) 191 | 192 | These requirements apply to the modified work as a whole. If 193 | identifiable sections of that work are not derived from the Library, 194 | and can be reasonably considered independent and separate works in 195 | themselves, then this License, and its terms, do not apply to those 196 | sections when you distribute them as separate works. But when you 197 | distribute the same sections as part of a whole which is a work based 198 | on the Library, the distribution of the whole must be on the terms of 199 | this License, whose permissions for other licensees extend to the 200 | entire whole, and thus to each and every part regardless of who wrote 201 | it. 202 | 203 | Thus, it is not the intent of this section to claim rights or contest 204 | your rights to work written entirely by you; rather, the intent is to 205 | exercise the right to control the distribution of derivative or 206 | collective works based on the Library. 207 | 208 | In addition, mere aggregation of another work not based on the Library 209 | with the Library (or with a work based on the Library) on a volume of 210 | a storage or distribution medium does not bring the other work under 211 | the scope of this License. 212 | 213 | 3. You may opt to apply the terms of the ordinary GNU General Public 214 | License instead of this License to a given copy of the Library. To do 215 | this, you must alter all the notices that refer to this License, so 216 | that they refer to the ordinary GNU General Public License, version 2, 217 | instead of to this License. (If a newer version than version 2 of the 218 | ordinary GNU General Public License has appeared, then you can specify 219 | that version instead if you wish.) Do not make any other change in 220 | these notices. 221 | 222 | Once this change is made in a given copy, it is irreversible for 223 | that copy, so the ordinary GNU General Public License applies to all 224 | subsequent copies and derivative works made from that copy. 225 | 226 | This option is useful when you wish to copy part of the code of 227 | the Library into a program that is not a library. 228 | 229 | 4. You may copy and distribute the Library (or a portion or 230 | derivative of it, under Section 2) in object code or executable form 231 | under the terms of Sections 1 and 2 above provided that you accompany 232 | it with the complete corresponding machine-readable source code, which 233 | must be distributed under the terms of Sections 1 and 2 above on a 234 | medium customarily used for software interchange. 235 | 236 | If distribution of object code is made by offering access to copy 237 | from a designated place, then offering equivalent access to copy the 238 | source code from the same place satisfies the requirement to 239 | distribute the source code, even though third parties are not 240 | compelled to copy the source along with the object code. 241 | 242 | 5. A program that contains no derivative of any portion of the 243 | Library, but is designed to work with the Library by being compiled or 244 | linked with it, is called a "work that uses the Library". Such a 245 | work, in isolation, is not a derivative work of the Library, and 246 | therefore falls outside the scope of this License. 247 | 248 | However, linking a "work that uses the Library" with the Library 249 | creates an executable that is a derivative of the Library (because it 250 | contains portions of the Library), rather than a "work that uses the 251 | library". The executable is therefore covered by this License. 252 | Section 6 states terms for distribution of such executables. 253 | 254 | When a "work that uses the Library" uses material from a header file 255 | that is part of the Library, the object code for the work may be a 256 | derivative work of the Library even though the source code is not. 257 | Whether this is true is especially significant if the work can be 258 | linked without the Library, or if the work is itself a library. The 259 | threshold for this to be true is not precisely defined by law. 260 | 261 | If such an object file uses only numerical parameters, data 262 | structure layouts and accessors, and small macros and small inline 263 | functions (ten lines or less in length), then the use of the object 264 | file is unrestricted, regardless of whether it is legally a derivative 265 | work. (Executables containing this object code plus portions of the 266 | Library will still fall under Section 6.) 267 | 268 | Otherwise, if the work is a derivative of the Library, you may 269 | distribute the object code for the work under the terms of Section 6. 270 | Any executables containing that work also fall under Section 6, 271 | whether or not they are linked directly with the Library itself. 272 | 273 | 6. As an exception to the Sections above, you may also combine or 274 | link a "work that uses the Library" with the Library to produce a 275 | work containing portions of the Library, and distribute that work 276 | under terms of your choice, provided that the terms permit 277 | modification of the work for the customer's own use and reverse 278 | engineering for debugging such modifications. 279 | 280 | You must give prominent notice with each copy of the work that the 281 | Library is used in it and that the Library and its use are covered by 282 | this License. You must supply a copy of this License. If the work 283 | during execution displays copyright notices, you must include the 284 | copyright notice for the Library among them, as well as a reference 285 | directing the user to the copy of this License. Also, you must do one 286 | of these things: 287 | 288 | a) Accompany the work with the complete corresponding 289 | machine-readable source code for the Library including whatever 290 | changes were used in the work (which must be distributed under 291 | Sections 1 and 2 above); and, if the work is an executable linked 292 | with the Library, with the complete machine-readable "work that 293 | uses the Library", as object code and/or source code, so that the 294 | user can modify the Library and then relink to produce a modified 295 | executable containing the modified Library. (It is understood 296 | that the user who changes the contents of definitions files in the 297 | Library will not necessarily be able to recompile the application 298 | to use the modified definitions.) 299 | 300 | b) Use a suitable shared library mechanism for linking with the 301 | Library. A suitable mechanism is one that (1) uses at run time a 302 | copy of the library already present on the user's computer system, 303 | rather than copying library functions into the executable, and (2) 304 | will operate properly with a modified version of the library, if 305 | the user installs one, as long as the modified version is 306 | interface-compatible with the version that the work was made with. 307 | 308 | c) Accompany the work with a written offer, valid for at least 309 | three years, to give the same user the materials specified in 310 | Subsection 6a, above, for a charge no more than the cost of 311 | performing this distribution. 312 | 313 | d) If distribution of the work is made by offering access to copy 314 | from a designated place, offer equivalent access to copy the above 315 | specified materials from the same place. 316 | 317 | e) Verify that the user has already received a copy of these 318 | materials or that you have already sent this user a copy. 319 | 320 | For an executable, the required form of the "work that uses the 321 | Library" must include any data and utility programs needed for 322 | reproducing the executable from it. However, as a special exception, 323 | the materials to be distributed need not include anything that is 324 | normally distributed (in either source or binary form) with the major 325 | components (compiler, kernel, and so on) of the operating system on 326 | which the executable runs, unless that component itself accompanies 327 | the executable. 328 | 329 | It may happen that this requirement contradicts the license 330 | restrictions of other proprietary libraries that do not normally 331 | accompany the operating system. Such a contradiction means you cannot 332 | use both them and the Library together in an executable that you 333 | distribute. 334 | 335 | 7. You may place library facilities that are a work based on the 336 | Library side-by-side in a single library together with other library 337 | facilities not covered by this License, and distribute such a combined 338 | library, provided that the separate distribution of the work based on 339 | the Library and of the other library facilities is otherwise 340 | permitted, and provided that you do these two things: 341 | 342 | a) Accompany the combined library with a copy of the same work 343 | based on the Library, uncombined with any other library 344 | facilities. This must be distributed under the terms of the 345 | Sections above. 346 | 347 | b) Give prominent notice with the combined library of the fact 348 | that part of it is a work based on the Library, and explaining 349 | where to find the accompanying uncombined form of the same work. 350 | 351 | 8. You may not copy, modify, sublicense, link with, or distribute 352 | the Library except as expressly provided under this License. Any 353 | attempt otherwise to copy, modify, sublicense, link with, or 354 | distribute the Library is void, and will automatically terminate your 355 | rights under this License. However, parties who have received copies, 356 | or rights, from you under this License will not have their licenses 357 | terminated so long as such parties remain in full compliance. 358 | 359 | 9. You are not required to accept this License, since you have not 360 | signed it. However, nothing else grants you permission to modify or 361 | distribute the Library or its derivative works. These actions are 362 | prohibited by law if you do not accept this License. Therefore, by 363 | modifying or distributing the Library (or any work based on the 364 | Library), you indicate your acceptance of this License to do so, and 365 | all its terms and conditions for copying, distributing or modifying 366 | the Library or works based on it. 367 | 368 | 10. Each time you redistribute the Library (or any work based on the 369 | Library), the recipient automatically receives a license from the 370 | original licensor to copy, distribute, link with or modify the Library 371 | subject to these terms and conditions. You may not impose any further 372 | restrictions on the recipients' exercise of the rights granted herein. 373 | You are not responsible for enforcing compliance by third parties with 374 | this License. 375 | 376 | 11. If, as a consequence of a court judgment or allegation of patent 377 | infringement or for any other reason (not limited to patent issues), 378 | conditions are imposed on you (whether by court order, agreement or 379 | otherwise) that contradict the conditions of this License, they do not 380 | excuse you from the conditions of this License. If you cannot 381 | distribute so as to satisfy simultaneously your obligations under this 382 | License and any other pertinent obligations, then as a consequence you 383 | may not distribute the Library at all. For example, if a patent 384 | license would not permit royalty-free redistribution of the Library by 385 | all those who receive copies directly or indirectly through you, then 386 | the only way you could satisfy both it and this License would be to 387 | refrain entirely from distribution of the Library. 388 | 389 | If any portion of this section is held invalid or unenforceable under 390 | any particular circumstance, the balance of the section is intended to 391 | apply, and the section as a whole is intended to apply in other 392 | circumstances. 393 | 394 | It is not the purpose of this section to induce you to infringe any 395 | patents or other property right claims or to contest validity of any 396 | such claims; this section has the sole purpose of protecting the 397 | integrity of the free software distribution system which is 398 | implemented by public license practices. Many people have made 399 | generous contributions to the wide range of software distributed 400 | through that system in reliance on consistent application of that 401 | system; it is up to the author/donor to decide if he or she is willing 402 | to distribute software through any other system and a licensee cannot 403 | impose that choice. 404 | 405 | This section is intended to make thoroughly clear what is believed to 406 | be a consequence of the rest of this License. 407 | 408 | 12. If the distribution and/or use of the Library is restricted in 409 | certain countries either by patents or by copyrighted interfaces, the 410 | original copyright holder who places the Library under this License 411 | may add an explicit geographical distribution limitation excluding those 412 | countries, so that distribution is permitted only in or among 413 | countries not thus excluded. In such case, this License incorporates 414 | the limitation as if written in the body of this License. 415 | 416 | 13. The Free Software Foundation may publish revised and/or new 417 | versions of the Lesser General Public License from time to time. 418 | Such new versions will be similar in spirit to the present version, 419 | but may differ in detail to address new problems or concerns. 420 | 421 | Each version is given a distinguishing version number. If the Library 422 | specifies a version number of this License which applies to it and 423 | "any later version", you have the option of following the terms and 424 | conditions either of that version or of any later version published by 425 | the Free Software Foundation. If the Library does not specify a 426 | license version number, you may choose any version ever published by 427 | the Free Software Foundation. 428 | 429 | 14. If you wish to incorporate parts of the Library into other free 430 | programs whose distribution conditions are incompatible with these, 431 | write to the author to ask for permission. For software which is 432 | copyrighted by the Free Software Foundation, write to the Free 433 | Software Foundation; we sometimes make exceptions for this. Our 434 | decision will be guided by the two goals of preserving the free status 435 | of all derivatives of our free software and of promoting the sharing 436 | and reuse of software generally. 437 | 438 | NO WARRANTY 439 | 440 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 441 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 442 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 443 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 444 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 445 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 446 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 447 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 448 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 449 | 450 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 451 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 452 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 453 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 454 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 455 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 456 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 457 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 458 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 459 | DAMAGES. 460 | 461 | END OF TERMS AND CONDITIONS 462 | 463 | How to Apply These Terms to Your New Libraries 464 | 465 | If you develop a new library, and you want it to be of the greatest 466 | possible use to the public, we recommend making it free software that 467 | everyone can redistribute and change. You can do so by permitting 468 | redistribution under these terms (or, alternatively, under the terms 469 | of the ordinary General Public License). 470 | 471 | To apply these terms, attach the following notices to the library. 472 | It is safest to attach them to the start of each source file to most 473 | effectively convey the exclusion of warranty; and each file should 474 | have at least the "copyright" line and a pointer to where the full 475 | notice is found. 476 | 477 | 478 | 479 | Copyright (C) 480 | 481 | This library is free software; you can redistribute it and/or 482 | modify it under the terms of the GNU Lesser General Public 483 | License as published by the Free Software Foundation; either 484 | version 2.1 of the License, or (at your option) any later version. 485 | 486 | This library is distributed in the hope that it will be useful, 487 | but WITHOUT ANY WARRANTY; without even the implied warranty of 488 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 489 | Lesser General Public License for more details. 490 | 491 | You should have received a copy of the GNU Lesser General Public 492 | License along with this library; if not, write to the Free Software 493 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 494 | 495 | Also add information on how to contact you by electronic and paper mail. 496 | 497 | You should also get your employer (if you work as a programmer) or 498 | your school, if any, to sign a "copyright disclaimer" for the library, 499 | if necessary. Here is a sample; alter the names: 500 | 501 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 502 | library `Frob' (a library for tweaking knobs) written by James 503 | Random Hacker. 504 | 505 | , 1 April 1990 506 | Ty Coon, President of Vice 507 | 508 | That's all there is to it! 509 | 510 | 511 | --------------------------------------------------------------------------------