First version of DLL preloader.
[wincetools.git] / 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 <marcus@g10code.com>
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 <windows.h>
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