Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Selector manipulation functions |
| 3 | * |
| 4 | * Copyright 1995 Alexandre Julliard |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2.1 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
Francois Gouget | e5ddd26 | 2001-10-14 16:18:52 +0000 | [diff] [blame] | 21 | #include "config.h" |
Alexandre Julliard | 894b188 | 2002-04-25 21:40:56 +0000 | [diff] [blame] | 22 | #include "wine/port.h" |
Francois Gouget | e5ddd26 | 2001-10-14 16:18:52 +0000 | [diff] [blame] | 23 | |
Alexandre Julliard | fa68b75 | 1995-04-03 16:55:37 +0000 | [diff] [blame] | 24 | #include <string.h> |
Dimitrie O. Paun | 0b7a7bb | 2000-11-25 01:31:17 +0000 | [diff] [blame] | 25 | |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 26 | #include "winerror.h" |
Marcus Meissner | 04c3e1d | 1999-02-19 10:37:02 +0000 | [diff] [blame] | 27 | #include "wine/winbase16.h" |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 28 | #include "miscemu.h" |
Alexandre Julliard | fa68b75 | 1995-04-03 16:55:37 +0000 | [diff] [blame] | 29 | #include "selectors.h" |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 30 | #include "stackframe.h" |
Alexandre Julliard | 37e9503 | 2001-07-19 00:39:09 +0000 | [diff] [blame] | 31 | #include "wine/server.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 32 | #include "wine/debug.h" |
Patrik Stridvall | 1ed4ecf | 1999-06-26 14:58:24 +0000 | [diff] [blame] | 33 | #include "toolhelp.h" |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 34 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 35 | WINE_DEFAULT_DEBUG_CHANNEL(selector); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 36 | |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 37 | #define LDT_SIZE 8192 |
| 38 | |
| 39 | /* get the number of selectors needed to cover up to the selector limit */ |
| 40 | inline static WORD get_sel_count( WORD sel ) |
| 41 | { |
| 42 | return (wine_ldt_copy.limit[sel >> __AHSHIFT] >> 16) + 1; |
| 43 | } |
| 44 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 45 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 46 | /*********************************************************************** |
| 47 | * AllocSelectorArray (KERNEL.206) |
| 48 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 49 | WORD WINAPI AllocSelectorArray16( WORD count ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 50 | { |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 51 | WORD i, sel = wine_ldt_alloc_entries( count ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 52 | |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 53 | if (sel) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 54 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 55 | LDT_ENTRY entry; |
| 56 | wine_ldt_set_base( &entry, 0 ); |
| 57 | wine_ldt_set_limit( &entry, 1 ); /* avoid 0 base and limit */ |
| 58 | wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_DATA ); |
| 59 | for (i = 0; i < count; i++) wine_ldt_set_entry( sel + (i << __AHSHIFT), &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 60 | } |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 61 | return sel; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | |
| 65 | /*********************************************************************** |
| 66 | * AllocSelector (KERNEL.175) |
| 67 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 68 | WORD WINAPI AllocSelector16( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 69 | { |
| 70 | WORD newsel, count, i; |
| 71 | |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 72 | count = sel ? get_sel_count(sel) : 1; |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 73 | newsel = wine_ldt_alloc_entries( count ); |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 74 | TRACE("(%04x): returning %04x\n", sel, newsel ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 75 | if (!newsel) return 0; |
| 76 | if (!sel) return newsel; /* nothing to copy */ |
| 77 | for (i = 0; i < count; i++) |
| 78 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 79 | LDT_ENTRY entry; |
| 80 | wine_ldt_get_entry( sel + (i << __AHSHIFT), &entry ); |
| 81 | wine_ldt_set_entry( newsel + (i << __AHSHIFT), &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 82 | } |
| 83 | return newsel; |
| 84 | } |
| 85 | |
| 86 | |
| 87 | /*********************************************************************** |
| 88 | * FreeSelector (KERNEL.176) |
| 89 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 90 | WORD WINAPI FreeSelector16( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 91 | { |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 92 | LDT_ENTRY entry; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 93 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 94 | wine_ldt_get_entry( sel, &entry ); |
| 95 | if (wine_ldt_is_empty( &entry )) return sel; /* error */ |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 96 | #ifdef __i386__ |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 97 | /* Check if we are freeing current %fs selector */ |
Alexandre Julliard | 4ced7ef | 2002-08-14 21:10:50 +0000 | [diff] [blame] | 98 | if (!((wine_get_fs() ^ sel) & ~3)) |
Alexandre Julliard | 5900867 | 2002-05-16 20:32:16 +0000 | [diff] [blame] | 99 | WARN("Freeing %%fs selector (%04x), not good.\n", wine_get_fs() ); |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 100 | #endif /* __i386__ */ |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 101 | wine_ldt_free_entries( sel, 1 ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 102 | return 0; |
| 103 | } |
| 104 | |
| 105 | |
| 106 | /*********************************************************************** |
| 107 | * SELECTOR_SetEntries |
| 108 | * |
| 109 | * Set the LDT entries for an array of selectors. |
| 110 | */ |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 111 | static void SELECTOR_SetEntries( WORD sel, const void *base, DWORD size, unsigned char flags ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 112 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 113 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 114 | WORD i, count; |
| 115 | |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 116 | wine_ldt_set_base( &entry, base ); |
Alexandre Julliard | 4ced7ef | 2002-08-14 21:10:50 +0000 | [diff] [blame] | 117 | wine_ldt_set_limit( &entry, size - 1 ); |
Andreas Mohr | 757e7cb | 2002-05-08 00:20:40 +0000 | [diff] [blame] | 118 | wine_ldt_set_flags( &entry, flags ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 119 | count = (size + 0xffff) / 0x10000; |
| 120 | for (i = 0; i < count; i++) |
| 121 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 122 | wine_ldt_set_entry( sel + (i << __AHSHIFT), &entry ); |
Gregg Mattinson | 7c4cb51 | 2002-07-03 21:10:43 +0000 | [diff] [blame] | 123 | wine_ldt_set_base( &entry, (char*)wine_ldt_get_base(&entry) + 0x10000); |
Andreas Mohr | 757e7cb | 2002-05-08 00:20:40 +0000 | [diff] [blame] | 124 | /* yep, Windows sets limit like that, not 64K sel units */ |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 125 | wine_ldt_set_limit( &entry, wine_ldt_get_limit(&entry) - 0x10000 ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 126 | } |
| 127 | } |
| 128 | |
| 129 | |
| 130 | /*********************************************************************** |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 131 | * SELECTOR_AllocBlock |
| 132 | * |
| 133 | * Allocate selectors for a block of linear memory. |
| 134 | */ |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 135 | WORD SELECTOR_AllocBlock( const void *base, DWORD size, unsigned char flags ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 136 | { |
| 137 | WORD sel, count; |
| 138 | |
| 139 | if (!size) return 0; |
| 140 | count = (size + 0xffff) / 0x10000; |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 141 | sel = wine_ldt_alloc_entries( count ); |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 142 | if (sel) SELECTOR_SetEntries( sel, base, size, flags ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 143 | return sel; |
| 144 | } |
| 145 | |
| 146 | |
| 147 | /*********************************************************************** |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 148 | * SELECTOR_FreeBlock |
| 149 | * |
| 150 | * Free a block of selectors. |
| 151 | */ |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 152 | void SELECTOR_FreeBlock( WORD sel ) |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 153 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 154 | WORD i, count = get_sel_count( sel ); |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 155 | |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 156 | TRACE("(%04x,%d)\n", sel, count ); |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 157 | for (i = 0; i < count; i++) FreeSelector16( sel + (i << __AHSHIFT) ); |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | |
| 161 | /*********************************************************************** |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 162 | * SELECTOR_ReallocBlock |
| 163 | * |
| 164 | * Change the size of a block of selectors. |
| 165 | */ |
Alexandre Julliard | 284c9b9 | 1999-04-11 15:07:13 +0000 | [diff] [blame] | 166 | WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 167 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 168 | LDT_ENTRY entry; |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 169 | int oldcount, newcount; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 170 | |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 171 | if (!size) size = 1; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 172 | wine_ldt_get_entry( sel, &entry ); |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 173 | oldcount = (wine_ldt_get_limit(&entry) >> 16) + 1; |
| 174 | newcount = (size + 0xffff) >> 16; |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 175 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 176 | sel = wine_ldt_realloc_entries( sel, oldcount, newcount ); |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 177 | if (sel) SELECTOR_SetEntries( sel, base, size, wine_ldt_get_flags(&entry) ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 178 | return sel; |
| 179 | } |
| 180 | |
| 181 | |
| 182 | /*********************************************************************** |
| 183 | * PrestoChangoSelector (KERNEL.177) |
| 184 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 185 | WORD WINAPI PrestoChangoSelector16( WORD selSrc, WORD selDst ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 186 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 187 | LDT_ENTRY entry; |
| 188 | wine_ldt_get_entry( selSrc, &entry ); |
| 189 | /* toggle the executable bit */ |
| 190 | entry.HighWord.Bits.Type ^= (WINE_LDT_FLAGS_CODE ^ WINE_LDT_FLAGS_DATA); |
| 191 | wine_ldt_set_entry( selDst, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 192 | return selDst; |
| 193 | } |
| 194 | |
| 195 | |
| 196 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 197 | * AllocCStoDSAlias (KERNEL.170) |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 198 | * AllocAlias (KERNEL.172) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 199 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 200 | WORD WINAPI AllocCStoDSAlias16( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 201 | { |
| 202 | WORD newsel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 203 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 204 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 205 | newsel = wine_ldt_alloc_entries( 1 ); |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 206 | TRACE("(%04x): returning %04x\n", |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 207 | sel, newsel ); |
| 208 | if (!newsel) return 0; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 209 | wine_ldt_get_entry( sel, &entry ); |
| 210 | entry.HighWord.Bits.Type = WINE_LDT_FLAGS_DATA; |
| 211 | wine_ldt_set_entry( newsel, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 212 | return newsel; |
| 213 | } |
| 214 | |
| 215 | |
| 216 | /*********************************************************************** |
| 217 | * AllocDStoCSAlias (KERNEL.171) |
| 218 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 219 | WORD WINAPI AllocDStoCSAlias16( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 220 | { |
| 221 | WORD newsel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 222 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 223 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 224 | newsel = wine_ldt_alloc_entries( 1 ); |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 225 | TRACE("(%04x): returning %04x\n", |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 226 | sel, newsel ); |
| 227 | if (!newsel) return 0; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 228 | wine_ldt_get_entry( sel, &entry ); |
| 229 | entry.HighWord.Bits.Type = WINE_LDT_FLAGS_CODE; |
| 230 | wine_ldt_set_entry( newsel, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 231 | return newsel; |
| 232 | } |
| 233 | |
| 234 | |
| 235 | /*********************************************************************** |
| 236 | * LongPtrAdd (KERNEL.180) |
| 237 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 238 | void WINAPI LongPtrAdd16( DWORD ptr, DWORD add ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 239 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 240 | LDT_ENTRY entry; |
| 241 | wine_ldt_get_entry( SELECTOROF(ptr), &entry ); |
| 242 | wine_ldt_set_base( &entry, (char *)wine_ldt_get_base(&entry) + add ); |
| 243 | wine_ldt_set_entry( SELECTOROF(ptr), &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 244 | } |
| 245 | |
| 246 | |
| 247 | /*********************************************************************** |
Jukka Heinonen | 56dff0d | 2002-11-20 19:40:12 +0000 | [diff] [blame] | 248 | * GetSelectorBase (KERNEL.186) |
Patrik Stridvall | b5bb32c | 2002-09-24 18:29:39 +0000 | [diff] [blame] | 249 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 250 | DWORD WINAPI GetSelectorBase( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 251 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 252 | void *base = wine_ldt_copy.base[sel >> __AHSHIFT]; |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 253 | |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 254 | /* if base points into DOSMEM, assume we have to |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 255 | * return pointer into physical lower 1MB */ |
| 256 | |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 257 | return DOSMEM_MapLinearToDos( base ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 258 | } |
| 259 | |
| 260 | |
| 261 | /*********************************************************************** |
Jukka Heinonen | 56dff0d | 2002-11-20 19:40:12 +0000 | [diff] [blame] | 262 | * SetSelectorBase (KERNEL.187) |
Patrik Stridvall | b5bb32c | 2002-09-24 18:29:39 +0000 | [diff] [blame] | 263 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 264 | WORD WINAPI SetSelectorBase( WORD sel, DWORD base ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 265 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 266 | LDT_ENTRY entry; |
| 267 | wine_ldt_get_entry( sel, &entry ); |
| 268 | wine_ldt_set_base( &entry, DOSMEM_MapDosToLinear(base) ); |
| 269 | wine_ldt_set_entry( sel, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 270 | return sel; |
| 271 | } |
| 272 | |
| 273 | |
| 274 | /*********************************************************************** |
| 275 | * GetSelectorLimit (KERNEL.188) |
| 276 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 277 | DWORD WINAPI GetSelectorLimit16( WORD sel ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 278 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 279 | return wine_ldt_copy.limit[sel >> __AHSHIFT]; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 280 | } |
| 281 | |
| 282 | |
| 283 | /*********************************************************************** |
| 284 | * SetSelectorLimit (KERNEL.189) |
| 285 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 286 | WORD WINAPI SetSelectorLimit16( WORD sel, DWORD limit ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 287 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 288 | LDT_ENTRY entry; |
| 289 | wine_ldt_get_entry( sel, &entry ); |
| 290 | wine_ldt_set_limit( &entry, limit ); |
| 291 | wine_ldt_set_entry( sel, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 292 | return sel; |
| 293 | } |
| 294 | |
| 295 | |
| 296 | /*********************************************************************** |
| 297 | * SelectorAccessRights (KERNEL.196) |
| 298 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 299 | WORD WINAPI SelectorAccessRights16( WORD sel, WORD op, WORD val ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 300 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 301 | LDT_ENTRY entry; |
| 302 | wine_ldt_get_entry( sel, &entry ); |
| 303 | |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 304 | if (op == 0) /* get */ |
| 305 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 306 | return entry.HighWord.Bytes.Flags1 | ((entry.HighWord.Bytes.Flags2 << 8) & 0xf0); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 307 | } |
| 308 | else /* set */ |
| 309 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 310 | entry.HighWord.Bytes.Flags1 = LOBYTE(val) | 0xf0; |
| 311 | entry.HighWord.Bytes.Flags2 = (entry.HighWord.Bytes.Flags2 & 0x0f) | (HIBYTE(val) & 0xf0); |
| 312 | wine_ldt_set_entry( sel, &entry ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 313 | return 0; |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | |
| 318 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 319 | * IsBadCodePtr (KERNEL.336) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 320 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 321 | BOOL16 WINAPI IsBadCodePtr16( SEGPTR lpfn ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 322 | { |
| 323 | WORD sel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 324 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 325 | |
| 326 | sel = SELECTOROF(lpfn); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 327 | if (!sel) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 328 | wine_ldt_get_entry( sel, &entry ); |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 329 | if (wine_ldt_is_empty( &entry )) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 330 | /* check for code segment, ignoring conforming, read-only and accessed bits */ |
| 331 | if ((entry.HighWord.Bits.Type ^ WINE_LDT_FLAGS_CODE) & 0x18) return TRUE; |
| 332 | if (OFFSETOF(lpfn) > wine_ldt_get_limit(&entry)) return TRUE; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 333 | return FALSE; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 334 | } |
| 335 | |
| 336 | |
| 337 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 338 | * IsBadStringPtr (KERNEL.337) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 339 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 340 | BOOL16 WINAPI IsBadStringPtr16( SEGPTR ptr, UINT16 size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 341 | { |
| 342 | WORD sel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 343 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 344 | |
| 345 | sel = SELECTOROF(ptr); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 346 | if (!sel) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 347 | wine_ldt_get_entry( sel, &entry ); |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 348 | if (wine_ldt_is_empty( &entry )) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 349 | /* check for data or readable code segment */ |
| 350 | if (!(entry.HighWord.Bits.Type & 0x10)) return TRUE; /* system descriptor */ |
| 351 | if ((entry.HighWord.Bits.Type & 0x0a) == 0x08) return TRUE; /* non-readable code segment */ |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 352 | if (strlen(MapSL(ptr)) < size) size = strlen(MapSL(ptr)) + 1; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 353 | if (size && (OFFSETOF(ptr) + size - 1 > wine_ldt_get_limit(&entry))) return TRUE; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 354 | return FALSE; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 355 | } |
| 356 | |
| 357 | |
| 358 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 359 | * IsBadHugeReadPtr (KERNEL.346) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 360 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 361 | BOOL16 WINAPI IsBadHugeReadPtr16( SEGPTR ptr, DWORD size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 362 | { |
| 363 | WORD sel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 364 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 365 | |
| 366 | sel = SELECTOROF(ptr); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 367 | if (!sel) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 368 | wine_ldt_get_entry( sel, &entry ); |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 369 | if (wine_ldt_is_empty( &entry )) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 370 | /* check for data or readable code segment */ |
| 371 | if (!(entry.HighWord.Bits.Type & 0x10)) return TRUE; /* system descriptor */ |
| 372 | if ((entry.HighWord.Bits.Type & 0x0a) == 0x08) return TRUE; /* non-readable code segment */ |
| 373 | if (size && (OFFSETOF(ptr) + size - 1 > wine_ldt_get_limit( &entry ))) return TRUE; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 374 | return FALSE; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 375 | } |
| 376 | |
| 377 | |
| 378 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 379 | * IsBadHugeWritePtr (KERNEL.347) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 380 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 381 | BOOL16 WINAPI IsBadHugeWritePtr16( SEGPTR ptr, DWORD size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 382 | { |
| 383 | WORD sel; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 384 | LDT_ENTRY entry; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 385 | |
| 386 | sel = SELECTOROF(ptr); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 387 | if (!sel) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 388 | wine_ldt_get_entry( sel, &entry ); |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 389 | if (wine_ldt_is_empty( &entry )) return TRUE; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 390 | /* check for writeable data segment, ignoring expand-down and accessed flags */ |
| 391 | if ((entry.HighWord.Bits.Type ^ WINE_LDT_FLAGS_DATA) & ~5) return TRUE; |
| 392 | if (size && (OFFSETOF(ptr) + size - 1 > wine_ldt_get_limit( &entry ))) return TRUE; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 393 | return FALSE; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 394 | } |
| 395 | |
| 396 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 397 | * IsBadReadPtr (KERNEL.334) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 398 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 399 | BOOL16 WINAPI IsBadReadPtr16( SEGPTR ptr, UINT16 size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 400 | { |
Alexandre Julliard | 8bbf818 | 1996-09-13 16:50:47 +0000 | [diff] [blame] | 401 | return IsBadHugeReadPtr16( ptr, size ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | |
| 405 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 406 | * IsBadWritePtr (KERNEL.335) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 407 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 408 | BOOL16 WINAPI IsBadWritePtr16( SEGPTR ptr, UINT16 size ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 409 | { |
Alexandre Julliard | 8bbf818 | 1996-09-13 16:50:47 +0000 | [diff] [blame] | 410 | return IsBadHugeWritePtr16( ptr, size ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 411 | } |
| 412 | |
| 413 | |
| 414 | /*********************************************************************** |
Patrik Stridvall | 01d5e5b | 2001-07-02 19:59:40 +0000 | [diff] [blame] | 415 | * IsBadFlatReadWritePtr (KERNEL.627) |
Ulrich Weigand | 98b5f77 | 1999-07-27 17:09:14 +0000 | [diff] [blame] | 416 | */ |
| 417 | BOOL16 WINAPI IsBadFlatReadWritePtr16( SEGPTR ptr, DWORD size, BOOL16 bWrite ) |
| 418 | { |
| 419 | return bWrite? IsBadHugeWritePtr16( ptr, size ) |
| 420 | : IsBadHugeReadPtr16( ptr, size ); |
| 421 | } |
| 422 | |
| 423 | |
| 424 | /*********************************************************************** |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 425 | * MemoryRead (TOOLHELP.78) |
| 426 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 427 | DWORD WINAPI MemoryRead16( WORD sel, DWORD offset, void *buffer, DWORD count ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 428 | { |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 429 | LDT_ENTRY entry; |
| 430 | DWORD limit; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 431 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 432 | wine_ldt_get_entry( sel, &entry ); |
| 433 | if (wine_ldt_is_empty( &entry )) return 0; |
| 434 | limit = wine_ldt_get_limit( &entry ); |
| 435 | if (offset > limit) return 0; |
| 436 | if (offset + count > limit + 1) count = limit + 1 - offset; |
| 437 | memcpy( buffer, (char *)wine_ldt_get_base(&entry) + offset, count ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 438 | return count; |
| 439 | } |
| 440 | |
| 441 | |
| 442 | /*********************************************************************** |
| 443 | * MemoryWrite (TOOLHELP.79) |
| 444 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 445 | DWORD WINAPI MemoryWrite16( WORD sel, DWORD offset, void *buffer, DWORD count ) |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 446 | { |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 447 | LDT_ENTRY entry; |
| 448 | DWORD limit; |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 449 | |
Alexandre Julliard | ce13153 | 2003-02-26 20:34:45 +0000 | [diff] [blame] | 450 | wine_ldt_get_entry( sel, &entry ); |
| 451 | if (wine_ldt_is_empty( &entry )) return 0; |
| 452 | limit = wine_ldt_get_limit( &entry ); |
| 453 | if (offset > limit) return 0; |
| 454 | if (offset + count > limit) count = limit + 1 - offset; |
| 455 | memcpy( (char *)wine_ldt_get_base(&entry) + offset, buffer, count ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 456 | return count; |
| 457 | } |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 458 | |
| 459 | /************************************* Win95 pointer mapping functions * |
| 460 | * |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 461 | */ |
| 462 | |
Alexandre Julliard | b0f5861 | 2001-12-19 19:16:27 +0000 | [diff] [blame] | 463 | struct mapls_entry |
| 464 | { |
| 465 | struct mapls_entry *next; |
| 466 | void *addr; /* linear address */ |
| 467 | int count; /* ref count */ |
| 468 | WORD sel; /* selector */ |
| 469 | }; |
| 470 | |
| 471 | static struct mapls_entry *first_entry; |
| 472 | |
| 473 | |
| 474 | /*********************************************************************** |
| 475 | * MapLS (KERNEL32.@) |
| 476 | * MapLS (KERNEL.358) |
| 477 | * |
| 478 | * Maps linear pointer to segmented. |
| 479 | */ |
| 480 | SEGPTR WINAPI MapLS( LPCVOID ptr ) |
| 481 | { |
| 482 | struct mapls_entry *entry, *free = NULL; |
| 483 | void *base; |
| 484 | SEGPTR ret = 0; |
| 485 | |
| 486 | if (!HIWORD(ptr)) return (SEGPTR)ptr; |
| 487 | |
| 488 | base = (char *)ptr - ((unsigned int)ptr & 0x7fff); |
| 489 | HeapLock( GetProcessHeap() ); |
| 490 | for (entry = first_entry; entry; entry = entry->next) |
| 491 | { |
| 492 | if (entry->addr == base) break; |
| 493 | if (!entry->count) free = entry; |
| 494 | } |
| 495 | |
| 496 | if (!entry) |
| 497 | { |
| 498 | if (!free) /* no free entry found, create a new one */ |
| 499 | { |
| 500 | if (!(free = HeapAlloc( GetProcessHeap(), 0, sizeof(*free) ))) goto done; |
| 501 | if (!(free->sel = SELECTOR_AllocBlock( base, 0x10000, WINE_LDT_FLAGS_DATA ))) |
| 502 | { |
| 503 | HeapFree( GetProcessHeap(), 0, free ); |
| 504 | goto done; |
| 505 | } |
| 506 | free->count = 0; |
| 507 | free->next = first_entry; |
| 508 | first_entry = free; |
| 509 | } |
| 510 | SetSelectorBase( free->sel, (DWORD)base ); |
| 511 | free->addr = base; |
| 512 | entry = free; |
| 513 | } |
| 514 | entry->count++; |
| 515 | ret = MAKESEGPTR( entry->sel, (char *)ptr - (char *)entry->addr ); |
| 516 | done: |
| 517 | HeapUnlock( GetProcessHeap() ); |
| 518 | return ret; |
| 519 | } |
| 520 | |
| 521 | /*********************************************************************** |
| 522 | * UnMapLS (KERNEL32.@) |
| 523 | * UnMapLS (KERNEL.359) |
| 524 | * |
| 525 | * Free mapped selector. |
| 526 | */ |
| 527 | void WINAPI UnMapLS( SEGPTR sptr ) |
| 528 | { |
| 529 | struct mapls_entry *entry; |
| 530 | WORD sel = SELECTOROF(sptr); |
| 531 | |
| 532 | if (sel) |
| 533 | { |
| 534 | HeapLock( GetProcessHeap() ); |
| 535 | for (entry = first_entry; entry; entry = entry->next) if (entry->sel == sel) break; |
| 536 | if (entry && entry->count > 0) entry->count--; |
| 537 | HeapUnlock( GetProcessHeap() ); |
| 538 | } |
| 539 | } |
| 540 | |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 541 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 542 | * MapSL (KERNEL32.@) |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 543 | * MapSL (KERNEL.357) |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 544 | * |
| 545 | * Maps fixed segmented pointer to linear. |
| 546 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 547 | LPVOID WINAPI MapSL( SEGPTR sptr ) |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 548 | { |
Alexandre Julliard | 914406f | 2000-11-14 01:54:49 +0000 | [diff] [blame] | 549 | return (char *)wine_ldt_copy.base[SELECTOROF(sptr) >> __AHSHIFT] + OFFSETOF(sptr); |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 550 | } |
| 551 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 552 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 553 | * MapSLFix (KERNEL32.@) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 554 | * |
| 555 | * FIXME: MapSLFix and UnMapSLFixArray should probably prevent |
| 556 | * unexpected linear address change when GlobalCompact() shuffles |
| 557 | * moveable blocks. |
| 558 | */ |
| 559 | |
| 560 | LPVOID WINAPI MapSLFix( SEGPTR sptr ) |
| 561 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 562 | return MapSL(sptr); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 563 | } |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 564 | |
| 565 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 566 | * UnMapSLFixArray (KERNEL32.@) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 567 | */ |
| 568 | |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 569 | void WINAPI UnMapSLFixArray( SEGPTR sptr[], INT length, CONTEXT86 *context ) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 570 | { |
Ulrich Weigand | 90c245c | 1999-02-02 10:34:46 +0000 | [diff] [blame] | 571 | /* Must not change EAX, hence defined as 'register' function */ |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 572 | } |
| 573 | |
| 574 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 575 | * GetThreadSelectorEntry (KERNEL32.@) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 576 | */ |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 577 | BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 578 | { |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 579 | #ifdef __i386__ |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 580 | BOOL ret; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 581 | |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 582 | if (!(sel & 4)) /* GDT selector */ |
| 583 | { |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 584 | sel &= ~3; /* ignore RPL */ |
| 585 | if (!sel) /* null selector */ |
| 586 | { |
| 587 | memset( ldtent, 0, sizeof(*ldtent) ); |
| 588 | return TRUE; |
| 589 | } |
| 590 | ldtent->BaseLow = 0; |
| 591 | ldtent->HighWord.Bits.BaseMid = 0; |
| 592 | ldtent->HighWord.Bits.BaseHi = 0; |
| 593 | ldtent->LimitLow = 0xffff; |
| 594 | ldtent->HighWord.Bits.LimitHi = 0xf; |
| 595 | ldtent->HighWord.Bits.Dpl = 3; |
| 596 | ldtent->HighWord.Bits.Sys = 0; |
| 597 | ldtent->HighWord.Bits.Pres = 1; |
| 598 | ldtent->HighWord.Bits.Granularity = 1; |
| 599 | ldtent->HighWord.Bits.Default_Big = 1; |
| 600 | ldtent->HighWord.Bits.Type = 0x12; |
| 601 | /* it has to be one of the system GDT selectors */ |
Alexandre Julliard | 5900867 | 2002-05-16 20:32:16 +0000 | [diff] [blame] | 602 | if (sel == (wine_get_ds() & ~3)) return TRUE; |
| 603 | if (sel == (wine_get_ss() & ~3)) return TRUE; |
| 604 | if (sel == (wine_get_cs() & ~3)) |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 605 | { |
| 606 | ldtent->HighWord.Bits.Type |= 8; /* code segment */ |
| 607 | return TRUE; |
| 608 | } |
| 609 | SetLastError( ERROR_NOACCESS ); |
| 610 | return FALSE; |
| 611 | } |
| 612 | |
Alexandre Julliard | 67a7499 | 2001-02-27 02:09:16 +0000 | [diff] [blame] | 613 | SERVER_START_REQ( get_selector_entry ) |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 614 | { |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 615 | req->handle = hthread; |
| 616 | req->entry = sel >> __AHSHIFT; |
Alexandre Julliard | 9caa71e | 2001-11-30 18:46:42 +0000 | [diff] [blame] | 617 | if ((ret = !wine_server_call_err( req ))) |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 618 | { |
Alexandre Julliard | 9caa71e | 2001-11-30 18:46:42 +0000 | [diff] [blame] | 619 | if (!(reply->flags & WINE_LDT_FLAGS_ALLOCATED)) |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 620 | { |
| 621 | SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */ |
| 622 | ret = FALSE; |
| 623 | } |
| 624 | else |
| 625 | { |
Alexandre Julliard | 9caa71e | 2001-11-30 18:46:42 +0000 | [diff] [blame] | 626 | wine_ldt_set_base( ldtent, (void *)reply->base ); |
| 627 | wine_ldt_set_limit( ldtent, reply->limit ); |
| 628 | wine_ldt_set_flags( ldtent, reply->flags ); |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 629 | } |
| 630 | } |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 631 | } |
Alexandre Julliard | 9c2370b | 2000-08-30 00:00:48 +0000 | [diff] [blame] | 632 | SERVER_END_REQ; |
| 633 | return ret; |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 634 | #else |
Ulrich Weigand | afd6a4b | 2000-06-04 01:48:05 +0000 | [diff] [blame] | 635 | SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); |
Alexandre Julliard | 0a7c1f6 | 2000-01-27 02:54:17 +0000 | [diff] [blame] | 636 | return FALSE; |
| 637 | #endif |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 638 | } |
| 639 | |
| 640 | |
| 641 | /********************************************************************** |
| 642 | * SMapLS* (KERNEL32) |
| 643 | * These functions map linear pointers at [EBP+xxx] to segmented pointers |
| 644 | * and return them. |
| 645 | * Win95 uses some kind of alias structs, which it stores in [EBP+x] to |
| 646 | * unravel them at SUnMapLS. We just store the segmented pointer there. |
| 647 | */ |
| 648 | static void |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 649 | x_SMapLS_IP_EBP_x(CONTEXT86 *context,int argoff) { |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 650 | DWORD val,ptr; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 651 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 652 | val =*(DWORD*)(context->Ebp + argoff); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 653 | if (val<0x10000) { |
| 654 | ptr=val; |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 655 | *(DWORD*)(context->Ebp + argoff) = 0; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 656 | } else { |
| 657 | ptr = MapLS((LPVOID)val); |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 658 | *(DWORD*)(context->Ebp + argoff) = ptr; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 659 | } |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 660 | context->Eax = ptr; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 661 | } |
| 662 | |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 663 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 664 | * SMapLS_IP_EBP_8 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 665 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 666 | void WINAPI SMapLS_IP_EBP_8 (CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context, 8);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 667 | |
| 668 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 669 | * SMapLS_IP_EBP_12 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 670 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 671 | void WINAPI SMapLS_IP_EBP_12(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,12);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 672 | |
| 673 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 674 | * SMapLS_IP_EBP_16 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 675 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 676 | void WINAPI SMapLS_IP_EBP_16(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,16);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 677 | |
| 678 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 679 | * SMapLS_IP_EBP_20 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 680 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 681 | void WINAPI SMapLS_IP_EBP_20(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,20);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 682 | |
| 683 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 684 | * SMapLS_IP_EBP_24 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 685 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 686 | void WINAPI SMapLS_IP_EBP_24(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,24);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 687 | |
| 688 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 689 | * SMapLS_IP_EBP_28 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 690 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 691 | void WINAPI SMapLS_IP_EBP_28(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,28);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 692 | |
| 693 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 694 | * SMapLS_IP_EBP_32 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 695 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 696 | void WINAPI SMapLS_IP_EBP_32(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,32);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 697 | |
| 698 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 699 | * SMapLS_IP_EBP_36 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 700 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 701 | void WINAPI SMapLS_IP_EBP_36(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,36);} |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 702 | |
| 703 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 704 | * SMapLS_IP_EBP_40 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 705 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 706 | void WINAPI SMapLS_IP_EBP_40(CONTEXT86 *context) {x_SMapLS_IP_EBP_x(context,40);} |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 707 | |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 708 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 709 | * SMapLS (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 710 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 711 | void WINAPI SMapLS( CONTEXT86 *context ) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 712 | { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 713 | if (HIWORD(context->Eax)) |
| 714 | { |
| 715 | context->Eax = MapLS( (LPVOID)context->Eax ); |
| 716 | context->Edx = context->Eax; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 717 | } else { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 718 | context->Edx = 0; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 719 | } |
| 720 | } |
| 721 | |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 722 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 723 | * SUnMapLS (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 724 | */ |
| 725 | |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 726 | void WINAPI SUnMapLS( CONTEXT86 *context ) |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 727 | { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 728 | if (HIWORD(context->Eax)) UnMapLS( (SEGPTR)context->Eax ); |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 729 | } |
| 730 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 731 | inline static void x_SUnMapLS_IP_EBP_x(CONTEXT86 *context,int argoff) |
| 732 | { |
| 733 | SEGPTR *ptr = (SEGPTR *)(context->Ebp + argoff); |
| 734 | if (*ptr) |
| 735 | { |
| 736 | UnMapLS( *ptr ); |
| 737 | *ptr = 0; |
| 738 | } |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 739 | } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 740 | |
| 741 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 742 | * SUnMapLS_IP_EBP_8 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 743 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 744 | void WINAPI SUnMapLS_IP_EBP_8 (CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context, 8); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 745 | |
| 746 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 747 | * SUnMapLS_IP_EBP_12 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 748 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 749 | void WINAPI SUnMapLS_IP_EBP_12(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,12); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 750 | |
| 751 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 752 | * SUnMapLS_IP_EBP_16 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 753 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 754 | void WINAPI SUnMapLS_IP_EBP_16(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,16); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 755 | |
| 756 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 757 | * SUnMapLS_IP_EBP_20 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 758 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 759 | void WINAPI SUnMapLS_IP_EBP_20(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,20); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 760 | |
| 761 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 762 | * SUnMapLS_IP_EBP_24 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 763 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 764 | void WINAPI SUnMapLS_IP_EBP_24(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,24); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 765 | |
| 766 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 767 | * SUnMapLS_IP_EBP_28 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 768 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 769 | void WINAPI SUnMapLS_IP_EBP_28(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,28); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 770 | |
| 771 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 772 | * SUnMapLS_IP_EBP_32 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 773 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 774 | void WINAPI SUnMapLS_IP_EBP_32(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,32); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 775 | |
| 776 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 777 | * SUnMapLS_IP_EBP_36 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 778 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 779 | void WINAPI SUnMapLS_IP_EBP_36(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,36); } |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 780 | |
| 781 | /*********************************************************************** |
Patrik Stridvall | dae8de6 | 2001-06-13 20:13:18 +0000 | [diff] [blame] | 782 | * SUnMapLS_IP_EBP_40 (KERNEL32.@) |
Patrik Stridvall | 54fe838 | 2000-04-06 20:21:16 +0000 | [diff] [blame] | 783 | */ |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 784 | void WINAPI SUnMapLS_IP_EBP_40(CONTEXT86 *context) { x_SUnMapLS_IP_EBP_x(context,40); } |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 785 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 786 | /********************************************************************** |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 787 | * AllocMappedBuffer (KERNEL32.38) |
| 788 | * |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 789 | * This is a undocumented KERNEL32 function that |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 790 | * SMapLS's a GlobalAlloc'ed buffer. |
| 791 | * |
| 792 | * Input: EDI register: size of buffer to allocate |
| 793 | * Output: EDI register: pointer to buffer |
| 794 | * |
Francois Gouget | 519346a | 2000-12-02 20:18:08 +0000 | [diff] [blame] | 795 | * Note: The buffer is preceded by 8 bytes: |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 796 | * ... |
| 797 | * edi+0 buffer |
| 798 | * edi-4 SEGPTR to buffer |
| 799 | * edi-8 some magic Win95 needs for SUnMapLS |
| 800 | * (we use it for the memory handle) |
| 801 | * |
| 802 | * The SEGPTR is used by the caller! |
| 803 | */ |
| 804 | |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 805 | void WINAPI AllocMappedBuffer( CONTEXT86 *context ) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 806 | { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 807 | HGLOBAL handle = GlobalAlloc(0, context->Edi + 8); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 808 | DWORD *buffer = (DWORD *)GlobalLock(handle); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 809 | SEGPTR ptr = 0; |
| 810 | |
| 811 | if (buffer) |
| 812 | if (!(ptr = MapLS(buffer + 2))) |
| 813 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 814 | GlobalUnlock(handle); |
| 815 | GlobalFree(handle); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 816 | } |
| 817 | |
| 818 | if (!ptr) |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 819 | context->Eax = context->Edi = 0; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 820 | else |
| 821 | { |
Alexandre Julliard | 7375597 | 2002-07-31 19:26:03 +0000 | [diff] [blame] | 822 | buffer[0] = (DWORD)handle; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 823 | buffer[1] = ptr; |
| 824 | |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 825 | context->Eax = (DWORD) ptr; |
| 826 | context->Edi = (DWORD)(buffer + 2); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 827 | } |
| 828 | } |
| 829 | |
| 830 | /********************************************************************** |
| 831 | * FreeMappedBuffer (KERNEL32.39) |
| 832 | * |
| 833 | * Free a buffer allocated by AllocMappedBuffer |
| 834 | * |
| 835 | * Input: EDI register: pointer to buffer |
| 836 | */ |
| 837 | |
Ulrich Weigand | eb94c7d | 1999-11-13 23:54:04 +0000 | [diff] [blame] | 838 | void WINAPI FreeMappedBuffer( CONTEXT86 *context ) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 839 | { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 840 | if (context->Edi) |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 841 | { |
Alexandre Julliard | d8fab2e | 2000-09-25 23:53:07 +0000 | [diff] [blame] | 842 | DWORD *buffer = (DWORD *)context->Edi - 2; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 843 | |
| 844 | UnMapLS(buffer[1]); |
| 845 | |
Alexandre Julliard | 7375597 | 2002-07-31 19:26:03 +0000 | [diff] [blame] | 846 | GlobalUnlock((HGLOBAL)buffer[0]); |
| 847 | GlobalFree((HGLOBAL)buffer[0]); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 848 | } |
| 849 | } |