2 * Win32 virtual memory functions
4 * Copyright 1997, 2002 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
27 #include <sys/types.h>
30 #define WIN32_NO_STATUS
31 #define NONAMELESSUNION
34 #include "wine/debug.h"
35 #include "ntdll_misc.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(virtual);
40 /**********************************************************************
41 * RtlCreateUserStack (NTDLL.@)
43 NTSTATUS WINAPI
RtlCreateUserStack( SIZE_T commit
, SIZE_T reserve
, ULONG zero_bits
,
44 SIZE_T commit_align
, SIZE_T reserve_align
, INITIAL_TEB
*stack
)
46 PROCESS_STACK_ALLOCATION_INFORMATION alloc
;
49 TRACE("commit %#lx, reserve %#lx, zero_bits %u, commit_align %#lx, reserve_align %#lx, stack %p\n",
50 commit
, reserve
, zero_bits
, commit_align
, reserve_align
, stack
);
52 if (!commit_align
|| !reserve_align
)
53 return STATUS_INVALID_PARAMETER
;
55 if (!commit
|| !reserve
)
57 IMAGE_NT_HEADERS
*nt
= RtlImageNtHeader( NtCurrentTeb()->Peb
->ImageBaseAddress
);
58 if (!reserve
) reserve
= nt
->OptionalHeader
.SizeOfStackReserve
;
59 if (!commit
) commit
= nt
->OptionalHeader
.SizeOfStackCommit
;
62 reserve
= (reserve
+ reserve_align
- 1) & ~(reserve_align
- 1);
63 commit
= (commit
+ commit_align
- 1) & ~(commit_align
- 1);
65 if (reserve
< commit
) reserve
= commit
;
66 if (reserve
< 0x100000) reserve
= 0x100000;
67 reserve
= (reserve
+ 0xffff) & ~0xffff; /* round to 64K boundary */
69 alloc
.ReserveSize
= reserve
;
70 alloc
.ZeroBits
= zero_bits
;
71 status
= NtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
72 &alloc
, sizeof(alloc
) );
75 void *addr
= alloc
.StackBase
;
76 SIZE_T size
= page_size
;
78 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_NOACCESS
);
79 addr
= (char *)alloc
.StackBase
+ page_size
;
80 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_READWRITE
| PAGE_GUARD
);
81 addr
= (char *)alloc
.StackBase
+ 2 * page_size
;
82 size
= reserve
- 2 * page_size
;
83 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_READWRITE
);
85 /* note: limit is lower than base since the stack grows down */
86 stack
->OldStackBase
= 0;
87 stack
->OldStackLimit
= 0;
88 stack
->DeallocationStack
= alloc
.StackBase
;
89 stack
->StackBase
= (char *)alloc
.StackBase
+ reserve
;
90 stack
->StackLimit
= (char *)alloc
.StackBase
+ 2 * page_size
;
96 /**********************************************************************
97 * RtlFreeUserStack (NTDLL.@)
99 void WINAPI
RtlFreeUserStack( void *stack
)
103 TRACE("stack %p\n", stack
);
105 NtFreeVirtualMemory( NtCurrentProcess(), &stack
, &size
, MEM_RELEASE
);