include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / krnl386.exe16 / selector.c
blobf0c29c8b10d046cf935ed9576374bb8bb2a7e28b
1 /*
2 * Selector manipulation functions
4 * Copyright 1995 Alexandre Julliard
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <string.h>
23 #include "wine/winbase16.h"
24 #include "wine/debug.h"
25 #include "kernel16_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(selector);
29 const struct ldt_copy *ldt_copy = NULL;
31 static ULONG bitmap_data[LDT_SIZE / 32];
32 static RTL_BITMAP ldt_bitmap = { LDT_SIZE, bitmap_data };
33 static const LDT_ENTRY null_entry;
34 static WORD first_ldt_entry = 32;
36 /* get the number of selectors needed to cover up to the selector limit */
37 static inline WORD get_sel_count( WORD sel )
39 return (ldt_get_limit( sel ) >> 16) + 1;
42 static inline int is_gdt_sel( WORD sel )
44 return !(sel & 4);
47 static LDT_ENTRY ldt_make_entry( const void *base, unsigned int limit, unsigned char flags )
49 LDT_ENTRY entry;
51 entry.BaseLow = (WORD)(ULONG_PTR)base;
52 entry.HighWord.Bits.BaseMid = (BYTE)((ULONG_PTR)base >> 16);
53 entry.HighWord.Bits.BaseHi = (BYTE)((ULONG_PTR)base >> 24);
54 if ((entry.HighWord.Bits.Granularity = (limit >= 0x100000))) limit >>= 12;
55 entry.LimitLow = (WORD)limit;
56 entry.HighWord.Bits.LimitHi = limit >> 16;
57 entry.HighWord.Bits.Dpl = 3;
58 entry.HighWord.Bits.Pres = 1;
59 entry.HighWord.Bits.Type = flags;
60 entry.HighWord.Bits.Sys = 0;
61 entry.HighWord.Bits.Reserved_0 = 0;
62 entry.HighWord.Bits.Default_Big = (flags & LDT_FLAGS_32BIT) != 0;
63 return entry;
66 /***********************************************************************
67 * init_selectors
69 void init_selectors(void)
71 if (!is_gdt_sel( get_gs() )) first_ldt_entry += 512;
72 if (!is_gdt_sel( get_fs() )) first_ldt_entry += 512;
73 RtlSetBits( &ldt_bitmap, 0, first_ldt_entry );
74 NtQueryInformationProcess( GetCurrentProcess(), ProcessWineLdtCopy, &ldt_copy, sizeof(ldt_copy), NULL );
77 /***********************************************************************
78 * ldt_is_system
80 BOOL ldt_is_system( WORD sel )
82 return is_gdt_sel( sel ) || ((sel >> 3) < first_ldt_entry);
85 /***********************************************************************
86 * ldt_is_valid
88 BOOL ldt_is_valid( WORD sel )
90 return !ldt_is_system( sel ) && RtlAreBitsSet( &ldt_bitmap, sel >> 3, 1 );
93 /***********************************************************************
94 * ldt_get_ptr
96 void *ldt_get_ptr( WORD sel, DWORD offset )
98 if (ldt_is_system( sel )) return (void *)offset;
99 if (!(ldt_get_flags( sel ) & LDT_FLAGS_32BIT)) offset &= 0xffff;
100 return (char *)ldt_get_base( sel ) + offset;
103 /***********************************************************************
104 * ldt_get_entry
106 BOOL ldt_get_entry( WORD sel, LDT_ENTRY *entry )
108 if (!ldt_is_valid( sel ))
110 *entry = null_entry;
111 return FALSE;
113 *entry = ldt_make_entry( ldt_get_base( sel ), ldt_get_limit( sel ), ldt_get_flags( sel ));
114 return TRUE;
117 /***********************************************************************
118 * ldt_set_entry
120 void ldt_set_entry( WORD sel, LDT_ENTRY entry )
122 NtSetLdtEntries( sel, entry, 0, null_entry );
126 static ULONG alloc_entries( ULONG count )
128 ULONG idx = RtlFindClearBitsAndSet( &ldt_bitmap, count, first_ldt_entry );
130 if (idx == ~0u) return 0;
131 return (idx << 3) | 7;
134 static void free_entries( ULONG sel, ULONG count )
136 RtlClearBits( &ldt_bitmap, sel >> 3, count );
137 while (count--)
139 ldt_set_entry( sel, null_entry );
140 sel += 8;
145 /***********************************************************************
146 * AllocSelectorArray (KERNEL.206)
148 WORD WINAPI AllocSelectorArray16( WORD count )
150 WORD i, sel = alloc_entries( count );
152 if (sel)
154 LDT_ENTRY entry = ldt_make_entry( 0, 1, LDT_FLAGS_DATA ); /* avoid 0 base and limit */
155 for (i = 0; i < count; i++) ldt_set_entry( sel + (i << 3), entry );
157 return sel;
161 /***********************************************************************
162 * AllocSelector (KERNEL.175)
164 WORD WINAPI AllocSelector16( WORD sel )
166 WORD newsel, count, i;
168 count = sel ? get_sel_count(sel) : 1;
169 newsel = alloc_entries( count );
170 TRACE("(%04x): returning %04x\n", sel, newsel );
171 if (!newsel) return 0;
172 if (!sel) return newsel; /* nothing to copy */
173 for (i = 0; i < count; i++)
175 LDT_ENTRY entry;
176 if (!ldt_get_entry( sel + (i << 3), &entry )) break;
177 ldt_set_entry( newsel + (i << 3), entry );
179 return newsel;
183 /***********************************************************************
184 * FreeSelector (KERNEL.176)
186 WORD WINAPI FreeSelector16( WORD sel )
188 WORD idx = sel >> 3;
190 if (idx < first_ldt_entry) return sel; /* error */
191 if (!RtlAreBitsSet( &ldt_bitmap, idx, 1 )) return sel; /* error */
192 free_entries( sel, 1 );
193 return 0;
197 /***********************************************************************
198 * SELECTOR_SetEntries
200 * Set the LDT entries for an array of selectors.
202 static void SELECTOR_SetEntries( WORD sel, const void *base, DWORD size, unsigned char flags )
204 WORD i, count = (size + 0xffff) / 0x10000;
206 for (i = 0; i < count; i++)
208 ldt_set_entry( sel + (i << 3), ldt_make_entry( base, size - 1, flags ));
209 base = (const char *)base + 0x10000;
210 size -= 0x10000; /* yep, Windows sets limit like that, not 64K sel units */
215 /***********************************************************************
216 * SELECTOR_AllocBlock
218 * Allocate selectors for a block of linear memory.
220 WORD SELECTOR_AllocBlock( const void *base, DWORD size, unsigned char flags )
222 WORD sel, count;
224 if (!size) return 0;
225 count = (size + 0xffff) / 0x10000;
226 if ((sel = alloc_entries( count ))) SELECTOR_SetEntries( sel, base, size, flags );
227 return sel;
231 /***********************************************************************
232 * SELECTOR_FreeBlock
234 * Free a block of selectors.
236 void SELECTOR_FreeBlock( WORD sel )
238 WORD idx = sel >> 3, count = get_sel_count( sel );
240 TRACE("(%04x,%d)\n", sel, count );
242 if (idx < first_ldt_entry) return; /* error */
243 if (!RtlAreBitsSet( &ldt_bitmap, idx, count )) return; /* error */
244 free_entries( sel, count );
248 /***********************************************************************
249 * SELECTOR_ReallocBlock
251 * Change the size of a block of selectors.
253 WORD SELECTOR_ReallocBlock( WORD sel, const void *base, DWORD size )
255 int oldcount, newcount;
256 BYTE flags;
258 if (!size) size = 1;
259 if (!ldt_is_valid( sel )) return sel;
260 flags = ldt_get_flags( sel );
261 oldcount = (ldt_get_limit( sel ) >> 16) + 1;
262 newcount = (size + 0xffff) >> 16;
264 if (oldcount < newcount) /* we need to add selectors */
266 ULONG idx = sel >> 3;
268 if (RtlAreBitsClear( &ldt_bitmap, idx + oldcount, newcount - oldcount ))
270 RtlSetBits( &ldt_bitmap, idx + oldcount, newcount - oldcount );
272 else
274 free_entries( sel, oldcount );
275 sel = alloc_entries( newcount );
278 else if (oldcount > newcount)
280 free_entries( sel + (newcount << 3), oldcount - newcount );
282 if (sel) SELECTOR_SetEntries( sel, base, size, flags );
283 return sel;
287 /***********************************************************************
288 * PrestoChangoSelector (KERNEL.177)
290 WORD WINAPI PrestoChangoSelector16( WORD selSrc, WORD selDst )
292 if (!ldt_is_valid( selSrc )) return selDst;
293 /* toggle the executable bit */
294 ldt_set_entry( selDst, ldt_make_entry( ldt_get_base( selSrc ), ldt_get_limit( selSrc ),
295 ldt_get_flags( selSrc ) ^ (LDT_FLAGS_CODE ^ LDT_FLAGS_DATA) ));
296 return selDst;
300 /***********************************************************************
301 * AllocCStoDSAlias (KERNEL.170)
302 * AllocAlias (KERNEL.172)
304 WORD WINAPI AllocCStoDSAlias16( WORD sel )
306 WORD newsel;
308 if (!ldt_is_valid( sel )) return 0;
309 newsel = AllocSelector16( 0 );
310 TRACE("(%04x): returning %04x\n", sel, newsel );
311 if (!newsel) return 0;
312 ldt_set_entry( newsel, ldt_make_entry( ldt_get_base(sel), ldt_get_limit(sel), LDT_FLAGS_DATA ));
313 return newsel;
317 /***********************************************************************
318 * AllocDStoCSAlias (KERNEL.171)
320 WORD WINAPI AllocDStoCSAlias16( WORD sel )
322 WORD newsel;
324 if (!ldt_is_valid( sel )) return 0;
325 newsel = AllocSelector16( 0 );
326 TRACE("(%04x): returning %04x\n", sel, newsel );
327 if (!newsel) return 0;
328 ldt_set_entry( newsel, ldt_make_entry( ldt_get_base(sel), ldt_get_limit(sel), LDT_FLAGS_CODE ));
329 return newsel;
333 /***********************************************************************
334 * LongPtrAdd (KERNEL.180)
336 void WINAPI LongPtrAdd16( SEGPTR ptr, DWORD add )
338 WORD sel = SELECTOROF( ptr );
340 if (!ldt_is_valid( sel )) return;
341 ldt_set_entry( sel, ldt_make_entry( (char *)ldt_get_base( sel ) + add,
342 ldt_get_limit( sel ), ldt_get_flags( sel )));
346 /***********************************************************************
347 * GetSelectorBase (KERNEL.186)
349 DWORD WINAPI GetSelectorBase( WORD sel )
351 /* if base points into DOSMEM, assume we have to
352 * return pointer into physical lower 1MB */
353 return DOSMEM_MapLinearToDos( ldt_get_base( sel ));
357 /***********************************************************************
358 * SetSelectorBase (KERNEL.187)
360 WORD WINAPI SetSelectorBase( WORD sel, DWORD base )
362 if (!ldt_is_valid( sel )) return 0;
363 ldt_set_entry( sel, ldt_make_entry( DOSMEM_MapDosToLinear(base),
364 ldt_get_limit( sel ), ldt_get_flags( sel )));
365 return sel;
369 /***********************************************************************
370 * GetSelectorLimit (KERNEL.188)
372 DWORD WINAPI GetSelectorLimit16( WORD sel )
374 return ldt_get_limit( sel );
378 /***********************************************************************
379 * SetSelectorLimit (KERNEL.189)
381 WORD WINAPI SetSelectorLimit16( WORD sel, DWORD limit )
383 if (!ldt_is_valid( sel )) return 0;
384 ldt_set_entry( sel, ldt_make_entry( ldt_get_base( sel ), limit, ldt_get_flags( sel )));
385 return sel;
389 /***********************************************************************
390 * SelectorAccessRights (KERNEL.196)
392 WORD WINAPI SelectorAccessRights16( WORD sel, WORD op, WORD val )
394 LDT_ENTRY entry;
396 if (!ldt_get_entry( sel, &entry )) return 0;
397 if (op == 0) /* get */
399 return entry.HighWord.Bytes.Flags1 | ((entry.HighWord.Bytes.Flags2 & 0xf0) << 8);
401 else /* set */
403 entry.HighWord.Bytes.Flags1 = LOBYTE(val) | 0xf0;
404 entry.HighWord.Bytes.Flags2 = (entry.HighWord.Bytes.Flags2 & 0x0f) | (HIBYTE(val) & 0xf0);
405 ldt_set_entry( sel, entry );
406 return 0;
411 /***********************************************************************
412 * IsBadCodePtr (KERNEL.336)
414 BOOL16 WINAPI IsBadCodePtr16( SEGPTR ptr )
416 WORD sel = SELECTOROF( ptr );
418 /* check for code segment, ignoring conforming, read-only and accessed bits */
419 if ((ldt_get_flags( sel ) ^ LDT_FLAGS_CODE) & 0x18) return TRUE;
420 if (OFFSETOF(ptr) > ldt_get_limit( sel )) return TRUE;
421 return FALSE;
425 /***********************************************************************
426 * IsBadStringPtr (KERNEL.337)
428 BOOL16 WINAPI IsBadStringPtr16( SEGPTR ptr, UINT16 size )
430 WORD sel = SELECTOROF( ptr );
432 /* check for data or readable code segment */
433 if (!(ldt_get_flags( sel ) & 0x10)) return TRUE; /* system descriptor */
434 if ((ldt_get_flags( sel ) & 0x0a) == 0x08) return TRUE; /* non-readable code segment */
435 if (strlen(MapSL(ptr)) < size) size = strlen(MapSL(ptr)) + 1;
436 if (size && (OFFSETOF(ptr) + size - 1 > ldt_get_limit( sel ))) return TRUE;
437 return FALSE;
441 /***********************************************************************
442 * IsBadHugeReadPtr (KERNEL.346)
444 BOOL16 WINAPI IsBadHugeReadPtr16( SEGPTR ptr, DWORD size )
446 WORD sel = SELECTOROF( ptr );
448 /* check for data or readable code segment */
449 if (!(ldt_get_flags( sel ) & 0x10)) return TRUE; /* system descriptor */
450 if ((ldt_get_flags( sel ) & 0x0a) == 0x08) return TRUE; /* non-readable code segment */
451 if (size && (OFFSETOF(ptr) + size - 1 > ldt_get_limit( sel ))) return TRUE;
452 return FALSE;
456 /***********************************************************************
457 * IsBadHugeWritePtr (KERNEL.347)
459 BOOL16 WINAPI IsBadHugeWritePtr16( SEGPTR ptr, DWORD size )
461 WORD sel = SELECTOROF( ptr );
463 /* check for writable data segment, ignoring expand-down and accessed flags */
464 if ((ldt_get_flags( sel ) ^ LDT_FLAGS_DATA) & 0x1a) return TRUE;
465 if (size && (OFFSETOF(ptr) + size - 1 > ldt_get_limit( sel ))) return TRUE;
466 return FALSE;
469 /***********************************************************************
470 * IsBadReadPtr (KERNEL.334)
472 BOOL16 WINAPI IsBadReadPtr16( SEGPTR ptr, UINT16 size )
474 return IsBadHugeReadPtr16( ptr, size );
478 /***********************************************************************
479 * IsBadWritePtr (KERNEL.335)
481 BOOL16 WINAPI IsBadWritePtr16( SEGPTR ptr, UINT16 size )
483 return IsBadHugeWritePtr16( ptr, size );
487 /***********************************************************************
488 * IsBadFlatReadWritePtr (KERNEL.627)
490 BOOL16 WINAPI IsBadFlatReadWritePtr16( SEGPTR ptr, DWORD size, BOOL16 bWrite )
492 return bWrite? IsBadHugeWritePtr16( ptr, size )
493 : IsBadHugeReadPtr16( ptr, size );
497 /************************************* Win95 pointer mapping functions *
501 struct mapls_entry
503 struct mapls_entry *next;
504 void *addr; /* linear address */
505 int count; /* ref count */
506 WORD sel; /* selector */
509 static struct mapls_entry *first_entry;
512 /***********************************************************************
513 * MapLS (KERNEL32.@)
514 * MapLS (KERNEL.358)
516 * Maps linear pointer to segmented.
518 SEGPTR WINAPI MapLS( void *ptr )
520 struct mapls_entry *entry, *free = NULL;
521 const void *base;
522 SEGPTR ret = 0;
524 if (!HIWORD(ptr)) return (SEGPTR)LOWORD(ptr);
526 base = (const char *)ptr - ((ULONG_PTR)ptr & 0x7fff);
527 HeapLock( GetProcessHeap() );
528 for (entry = first_entry; entry; entry = entry->next)
530 if (entry->addr == base) break;
531 if (!entry->count) free = entry;
534 if (!entry)
536 if (!free) /* no free entry found, create a new one */
538 if (!(free = HeapAlloc( GetProcessHeap(), 0, sizeof(*free) ))) goto done;
539 if (!(free->sel = SELECTOR_AllocBlock( base, 0x10000, LDT_FLAGS_DATA )))
541 HeapFree( GetProcessHeap(), 0, free );
542 goto done;
544 free->count = 0;
545 free->next = first_entry;
546 first_entry = free;
548 SetSelectorBase( free->sel, (DWORD)base );
549 free->addr = (void*)base;
550 entry = free;
552 entry->count++;
553 ret = MAKESEGPTR( entry->sel, (const char *)ptr - (char *)entry->addr );
554 done:
555 HeapUnlock( GetProcessHeap() );
556 return ret;
559 /***********************************************************************
560 * UnMapLS (KERNEL32.@)
561 * UnMapLS (KERNEL.359)
563 * Free mapped selector.
565 void WINAPI UnMapLS( SEGPTR sptr )
567 struct mapls_entry *entry;
568 WORD sel = SELECTOROF(sptr);
570 if (sel)
572 HeapLock( GetProcessHeap() );
573 for (entry = first_entry; entry; entry = entry->next) if (entry->sel == sel) break;
574 if (entry && entry->count > 0) entry->count--;
575 HeapUnlock( GetProcessHeap() );
579 /***********************************************************************
580 * MapSL (KERNEL32.@)
581 * MapSL (KERNEL.357)
583 * Maps fixed segmented pointer to linear.
585 LPVOID WINAPI MapSL( SEGPTR sptr )
587 return (char *)ldt_get_base( SELECTOROF(sptr) ) + OFFSETOF(sptr);
590 /***********************************************************************
591 * MapSLFix (KERNEL32.@)
593 * FIXME: MapSLFix and UnMapSLFixArray should probably prevent
594 * unexpected linear address change when GlobalCompact() shuffles
595 * moveable blocks.
598 LPVOID WINAPI MapSLFix( SEGPTR sptr )
600 return MapSL(sptr);
604 /***********************************************************************
605 * UnMapSLFixArray (KERNEL32.@)
607 * Must not change EAX, hence defined as asm function.
609 __ASM_STDCALL_FUNC( UnMapSLFixArray, 8, "ret $8" )
611 /***********************************************************************
612 * SMapLS (KERNEL32.@)
614 __ASM_STDCALL_FUNC( SMapLS, 0,
615 "xor %edx,%edx\n\t"
616 "testl $0xffff0000,%eax\n\t"
617 "jz 1f\n\t"
618 "pushl %eax\n\t"
619 "call " __ASM_STDCALL("MapLS",4) "\n\t"
620 "movl %eax,%edx\n"
621 "1:\tret" )
623 /***********************************************************************
624 * SUnMapLS (KERNEL32.@)
626 __ASM_STDCALL_FUNC( SUnMapLS, 0,
627 "pushl %eax\n\t" /* preserve eax */
628 "pushl %eax\n\t"
629 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
630 "popl %eax\n\t"
631 "ret" )
633 /***********************************************************************
634 * SMapLS_IP_EBP_8 (KERNEL32.@)
636 * These functions map linear pointers at [EBP+xxx] to segmented pointers
637 * and return them.
638 * Win95 uses some kind of alias structs, which it stores in [EBP+x] to
639 * unravel them at SUnMapLS. We just store the segmented pointer there.
641 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_8, 0,
642 "movl 8(%ebp),%eax\n\t"
643 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
644 "movl %edx,8(%ebp)\n\t"
645 "ret" )
647 /***********************************************************************
648 * SMapLS_IP_EBP_12 (KERNEL32.@)
650 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_12, 0,
651 "movl 12(%ebp),%eax\n\t"
652 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
653 "movl %edx,12(%ebp)\n\t"
654 "ret" )
656 /***********************************************************************
657 * SMapLS_IP_EBP_16 (KERNEL32.@)
659 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_16, 0,
660 "movl 16(%ebp),%eax\n\t"
661 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
662 "movl %edx,16(%ebp)\n\t"
663 "ret" )
665 /***********************************************************************
666 * SMapLS_IP_EBP_20 (KERNEL32.@)
668 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_20, 0,
669 "movl 20(%ebp),%eax\n\t"
670 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
671 "movl %edx,20(%ebp)\n\t"
672 "ret" )
674 /***********************************************************************
675 * SMapLS_IP_EBP_24 (KERNEL32.@)
677 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_24, 0,
678 "movl 24(%ebp),%eax\n\t"
679 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
680 "movl %edx,24(%ebp)\n\t"
681 "ret" )
683 /***********************************************************************
684 * SMapLS_IP_EBP_28 (KERNEL32.@)
686 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_28, 0,
687 "movl 28(%ebp),%eax\n\t"
688 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
689 "movl %edx,28(%ebp)\n\t"
690 "ret" )
692 /***********************************************************************
693 * SMapLS_IP_EBP_32 (KERNEL32.@)
695 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_32, 0,
696 "movl 32(%ebp),%eax\n\t"
697 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
698 "movl %edx,32(%ebp)\n\t"
699 "ret" )
701 /***********************************************************************
702 * SMapLS_IP_EBP_36 (KERNEL32.@)
704 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_36, 0,
705 "movl 36(%ebp),%eax\n\t"
706 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
707 "movl %edx,36(%ebp)\n\t"
708 "ret" )
710 /***********************************************************************
711 * SMapLS_IP_EBP_40 (KERNEL32.@)
713 __ASM_STDCALL_FUNC( SMapLS_IP_EBP_40, 0,
714 "movl 40(%ebp),%eax\n\t"
715 "call " __ASM_STDCALL("SMapLS",0) "\n\t"
716 "movl %edx,40(%ebp)\n\t"
717 "ret" )
719 /***********************************************************************
720 * SUnMapLS_IP_EBP_8 (KERNEL32.@)
722 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_8, 0,
723 "pushl %eax\n\t" /* preserve eax */
724 "pushl 8(%ebp)\n\t"
725 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
726 "movl $0,8(%ebp)\n\t"
727 "popl %eax\n\t"
728 "ret" )
730 /***********************************************************************
731 * SUnMapLS_IP_EBP_12 (KERNEL32.@)
733 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_12, 0,
734 "pushl %eax\n\t" /* preserve eax */
735 "pushl 12(%ebp)\n\t"
736 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
737 "movl $0,12(%ebp)\n\t"
738 "popl %eax\n\t"
739 "ret" )
741 /***********************************************************************
742 * SUnMapLS_IP_EBP_16 (KERNEL32.@)
744 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_16, 0,
745 "pushl %eax\n\t" /* preserve eax */
746 "pushl 16(%ebp)\n\t"
747 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
748 "movl $0,16(%ebp)\n\t"
749 "popl %eax\n\t"
750 "ret" )
752 /***********************************************************************
753 * SUnMapLS_IP_EBP_20 (KERNEL32.@)
755 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_20, 0,
756 "pushl %eax\n\t" /* preserve eax */
757 "pushl 20(%ebp)\n\t"
758 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
759 "movl $0,20(%ebp)\n\t"
760 "popl %eax\n\t"
761 "ret" )
763 /***********************************************************************
764 * SUnMapLS_IP_EBP_24 (KERNEL32.@)
766 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_24, 0,
767 "pushl %eax\n\t" /* preserve eax */
768 "pushl 24(%ebp)\n\t"
769 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
770 "movl $0,24(%ebp)\n\t"
771 "popl %eax\n\t"
772 "ret" )
774 /***********************************************************************
775 * SUnMapLS_IP_EBP_28 (KERNEL32.@)
777 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_28, 0,
778 "pushl %eax\n\t" /* preserve eax */
779 "pushl 28(%ebp)\n\t"
780 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
781 "movl $0,28(%ebp)\n\t"
782 "popl %eax\n\t"
783 "ret" )
785 /***********************************************************************
786 * SUnMapLS_IP_EBP_32 (KERNEL32.@)
788 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_32, 0,
789 "pushl %eax\n\t" /* preserve eax */
790 "pushl 32(%ebp)\n\t"
791 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
792 "movl $0,32(%ebp)\n\t"
793 "popl %eax\n\t"
794 "ret" )
796 /***********************************************************************
797 * SUnMapLS_IP_EBP_36 (KERNEL32.@)
799 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_36, 0,
800 "pushl %eax\n\t" /* preserve eax */
801 "pushl 36(%ebp)\n\t"
802 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
803 "movl $0,36(%ebp)\n\t"
804 "popl %eax\n\t"
805 "ret" )
807 /***********************************************************************
808 * SUnMapLS_IP_EBP_40 (KERNEL32.@)
810 __ASM_STDCALL_FUNC( SUnMapLS_IP_EBP_40, 0,
811 "pushl %eax\n\t" /* preserve eax */
812 "pushl 40(%ebp)\n\t"
813 "call " __ASM_STDCALL("UnMapLS",4) "\n\t"
814 "movl $0,40(%ebp)\n\t"
815 "popl %eax\n\t"
816 "ret" )