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/server.h"
35 #include "wine/debug.h"
36 #include "ntdll_misc.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(virtual);
41 /**********************************************************************
42 * RtlCreateUserStack (NTDLL.@)
44 NTSTATUS WINAPI
RtlCreateUserStack( SIZE_T commit
, SIZE_T reserve
, ULONG zero_bits
,
45 SIZE_T commit_align
, SIZE_T reserve_align
, INITIAL_TEB
*stack
)
47 PROCESS_STACK_ALLOCATION_INFORMATION alloc
;
50 TRACE("commit %#lx, reserve %#lx, zero_bits %u, commit_align %#lx, reserve_align %#lx, stack %p\n",
51 commit
, reserve
, zero_bits
, commit_align
, reserve_align
, stack
);
53 if (!commit_align
|| !reserve_align
)
54 return STATUS_INVALID_PARAMETER
;
56 if (!commit
|| !reserve
)
58 IMAGE_NT_HEADERS
*nt
= RtlImageNtHeader( NtCurrentTeb()->Peb
->ImageBaseAddress
);
59 if (!reserve
) reserve
= nt
->OptionalHeader
.SizeOfStackReserve
;
60 if (!commit
) commit
= nt
->OptionalHeader
.SizeOfStackCommit
;
63 reserve
= (reserve
+ reserve_align
- 1) & ~(reserve_align
- 1);
64 commit
= (commit
+ commit_align
- 1) & ~(commit_align
- 1);
66 if (reserve
< commit
) reserve
= commit
;
67 if (reserve
< 0x100000) reserve
= 0x100000;
68 reserve
= (reserve
+ 0xffff) & ~0xffff; /* round to 64K boundary */
70 alloc
.ReserveSize
= reserve
;
71 alloc
.ZeroBits
= zero_bits
;
72 status
= NtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation
,
73 &alloc
, sizeof(alloc
) );
76 void *addr
= alloc
.StackBase
;
77 SIZE_T size
= page_size
;
79 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_NOACCESS
);
80 addr
= (char *)alloc
.StackBase
+ page_size
;
81 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_READWRITE
| PAGE_GUARD
);
82 addr
= (char *)alloc
.StackBase
+ 2 * page_size
;
83 size
= reserve
- 2 * page_size
;
84 NtAllocateVirtualMemory( GetCurrentProcess(), &addr
, 0, &size
, MEM_COMMIT
, PAGE_READWRITE
);
86 /* note: limit is lower than base since the stack grows down */
87 stack
->OldStackBase
= 0;
88 stack
->OldStackLimit
= 0;
89 stack
->DeallocationStack
= alloc
.StackBase
;
90 stack
->StackBase
= (char *)alloc
.StackBase
+ reserve
;
91 stack
->StackLimit
= (char *)alloc
.StackBase
+ 2 * page_size
;
97 /**********************************************************************
98 * RtlFreeUserStack (NTDLL.@)
100 void WINAPI
RtlFreeUserStack( void *stack
)
104 TRACE("stack %p\n", stack
);
106 NtFreeVirtualMemory( NtCurrentProcess(), &stack
, &size
, MEM_RELEASE
);