xref: /reactos/dll/win32/kernel32/client/utils.c (revision 39f11249)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:         ReactOS system libraries
4c2c66affSColin Finck  * FILE:            dll/win32/kernel32/client/utils.c
5c2c66affSColin Finck  * PURPOSE:         Utility and Support Functions
6c2c66affSColin Finck  * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
7c2c66affSColin Finck  *                  Pierre Schweitzer (pierre.schweitzer@reactos.org)
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck /* INCLUDES ******************************************************************/
11c2c66affSColin Finck 
12c2c66affSColin Finck #include <k32.h>
13c2c66affSColin Finck #ifdef _M_IX86
14c2c66affSColin Finck #include "i386/ketypes.h"
15c2c66affSColin Finck #elif defined _M_AMD64
16c2c66affSColin Finck #include "amd64/ketypes.h"
17c2c66affSColin Finck #endif
18c2c66affSColin Finck 
19c2c66affSColin Finck #define NDEBUG
20c2c66affSColin Finck #include <debug.h>
21c2c66affSColin Finck 
22c2c66affSColin Finck /* GLOBALS ********************************************************************/
23c2c66affSColin Finck 
24c2c66affSColin Finck UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted");
25c2c66affSColin Finck BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
26c2c66affSColin Finck PRTL_CONVERT_STRING Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
27c2c66affSColin Finck PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString;
28c2c66affSColin Finck PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize;
29c2c66affSColin Finck PRTL_COUNT_STRINGA Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize;
30c2c66affSColin Finck 
31c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
32c2c66affSColin Finck 
33c2c66affSColin Finck ULONG
34c2c66affSColin Finck NTAPI
BasepUnicodeStringToOemSize(IN PUNICODE_STRING String)35c2c66affSColin Finck BasepUnicodeStringToOemSize(IN PUNICODE_STRING String)
36c2c66affSColin Finck {
37c2c66affSColin Finck     return RtlUnicodeStringToOemSize(String);
38c2c66affSColin Finck }
39c2c66affSColin Finck 
40c2c66affSColin Finck ULONG
41c2c66affSColin Finck NTAPI
BasepOemStringToUnicodeSize(IN PANSI_STRING String)42c2c66affSColin Finck BasepOemStringToUnicodeSize(IN PANSI_STRING String)
43c2c66affSColin Finck {
44c2c66affSColin Finck     return RtlOemStringToUnicodeSize(String);
45c2c66affSColin Finck }
46c2c66affSColin Finck 
47c2c66affSColin Finck ULONG
48c2c66affSColin Finck NTAPI
BasepUnicodeStringToAnsiSize(IN PUNICODE_STRING String)49c2c66affSColin Finck BasepUnicodeStringToAnsiSize(IN PUNICODE_STRING String)
50c2c66affSColin Finck {
51c2c66affSColin Finck     return RtlUnicodeStringToAnsiSize(String);
52c2c66affSColin Finck }
53c2c66affSColin Finck 
54c2c66affSColin Finck ULONG
55c2c66affSColin Finck NTAPI
BasepAnsiStringToUnicodeSize(IN PANSI_STRING String)56c2c66affSColin Finck BasepAnsiStringToUnicodeSize(IN PANSI_STRING String)
57c2c66affSColin Finck {
58c2c66affSColin Finck     return RtlAnsiStringToUnicodeSize(String);
59c2c66affSColin Finck }
60c2c66affSColin Finck 
61c2c66affSColin Finck HANDLE
62c2c66affSColin Finck WINAPI
BaseGetNamedObjectDirectory(VOID)63c2c66affSColin Finck BaseGetNamedObjectDirectory(VOID)
64c2c66affSColin Finck {
65c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes;
66c2c66affSColin Finck     NTSTATUS Status;
67c2c66affSColin Finck     HANDLE DirHandle, BnoHandle, Token, NewToken;
68c2c66affSColin Finck 
69c2c66affSColin Finck     if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory;
70c2c66affSColin Finck 
71c2c66affSColin Finck     if (NtCurrentTeb()->IsImpersonating)
72c2c66affSColin Finck     {
73c2c66affSColin Finck         Status = NtOpenThreadToken(NtCurrentThread(),
74c2c66affSColin Finck                                    TOKEN_IMPERSONATE,
75c2c66affSColin Finck                                    TRUE,
76c2c66affSColin Finck                                    &Token);
77c2c66affSColin Finck         if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory;
78c2c66affSColin Finck 
79c2c66affSColin Finck         NewToken = NULL;
80c2c66affSColin Finck         Status = NtSetInformationThread(NtCurrentThread(),
81c2c66affSColin Finck                                         ThreadImpersonationToken,
82c2c66affSColin Finck                                         &NewToken,
83c2c66affSColin Finck                                         sizeof(HANDLE));
84c2c66affSColin Finck         if (!NT_SUCCESS (Status))
85c2c66affSColin Finck         {
86c2c66affSColin Finck             NtClose(Token);
87c2c66affSColin Finck             return BaseNamedObjectDirectory;
88c2c66affSColin Finck         }
89c2c66affSColin Finck     }
90c2c66affSColin Finck     else
91c2c66affSColin Finck     {
92c2c66affSColin Finck         Token = NULL;
93c2c66affSColin Finck     }
94c2c66affSColin Finck 
95c2c66affSColin Finck     RtlAcquirePebLock();
96c2c66affSColin Finck     if (BaseNamedObjectDirectory) goto Quickie;
97c2c66affSColin Finck 
98c2c66affSColin Finck     InitializeObjectAttributes(&ObjectAttributes,
99c2c66affSColin Finck                                &BaseStaticServerData->NamedObjectDirectory,
100c2c66affSColin Finck                                OBJ_CASE_INSENSITIVE,
101c2c66affSColin Finck                                NULL,
102c2c66affSColin Finck                                NULL);
103c2c66affSColin Finck 
104c2c66affSColin Finck     Status = NtOpenDirectoryObject(&BnoHandle,
105c2c66affSColin Finck                                    DIRECTORY_QUERY |
106c2c66affSColin Finck                                    DIRECTORY_TRAVERSE |
107c2c66affSColin Finck                                    DIRECTORY_CREATE_OBJECT |
108c2c66affSColin Finck                                    DIRECTORY_CREATE_SUBDIRECTORY,
109c2c66affSColin Finck                                    &ObjectAttributes);
110c2c66affSColin Finck     if (!NT_SUCCESS(Status))
111c2c66affSColin Finck     {
112c2c66affSColin Finck         Status = NtOpenDirectoryObject(&DirHandle,
113c2c66affSColin Finck                                        DIRECTORY_TRAVERSE,
114c2c66affSColin Finck                                        &ObjectAttributes);
115c2c66affSColin Finck 
116c2c66affSColin Finck         if (NT_SUCCESS(Status))
117c2c66affSColin Finck         {
118c2c66affSColin Finck             InitializeObjectAttributes(&ObjectAttributes,
119c2c66affSColin Finck                                        (PUNICODE_STRING)&Restricted,
120c2c66affSColin Finck                                        OBJ_CASE_INSENSITIVE,
121c2c66affSColin Finck                                        DirHandle,
122c2c66affSColin Finck                                        NULL);
123c2c66affSColin Finck 
124c2c66affSColin Finck             Status = NtOpenDirectoryObject(&BnoHandle,
125c2c66affSColin Finck                                            DIRECTORY_QUERY |
126c2c66affSColin Finck                                            DIRECTORY_TRAVERSE |
127c2c66affSColin Finck                                            DIRECTORY_CREATE_OBJECT |
128c2c66affSColin Finck                                            DIRECTORY_CREATE_SUBDIRECTORY,
129c2c66affSColin Finck                                            &ObjectAttributes);
130c2c66affSColin Finck             NtClose(DirHandle);
131c2c66affSColin Finck 
132c2c66affSColin Finck         }
133c2c66affSColin Finck     }
134c2c66affSColin Finck 
135c2c66affSColin Finck     if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle;
136c2c66affSColin Finck 
137c2c66affSColin Finck Quickie:
138c2c66affSColin Finck 
139c2c66affSColin Finck     RtlReleasePebLock();
140c2c66affSColin Finck 
141c2c66affSColin Finck     if (Token)
142c2c66affSColin Finck     {
143c2c66affSColin Finck         NtSetInformationThread(NtCurrentThread(),
144c2c66affSColin Finck                                ThreadImpersonationToken,
145c2c66affSColin Finck                                &Token,
146c2c66affSColin Finck                                sizeof(Token));
147c2c66affSColin Finck 
148c2c66affSColin Finck         NtClose(Token);
149c2c66affSColin Finck     }
150c2c66affSColin Finck 
151c2c66affSColin Finck     return BaseNamedObjectDirectory;
152c2c66affSColin Finck }
153c2c66affSColin Finck 
154c2c66affSColin Finck VOID
155c2c66affSColin Finck NTAPI
BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry,IN PVOID Context,OUT BOOLEAN * StopEnumeration)156c2c66affSColin Finck BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry,
157c2c66affSColin Finck                        IN PVOID Context,
158c2c66affSColin Finck                        OUT BOOLEAN *StopEnumeration)
159c2c66affSColin Finck {
160c2c66affSColin Finck     /* Make sure we get Entry, Context and valid StopEnumeration pointer */
161c2c66affSColin Finck     ASSERT(Entry);
162c2c66affSColin Finck     ASSERT(Context);
163c2c66affSColin Finck     ASSERT(StopEnumeration);
164c2c66affSColin Finck 
165c2c66affSColin Finck     /* If entry is already found - signal to stop */
166c2c66affSColin Finck     if (BasepExeLdrEntry)
167c2c66affSColin Finck     {
168c2c66affSColin Finck         *StopEnumeration = TRUE;
169c2c66affSColin Finck         return;
170c2c66affSColin Finck     }
171c2c66affSColin Finck 
172c2c66affSColin Finck     /* Otherwise keep enumerating until we find a match */
173c2c66affSColin Finck     if (Entry->DllBase == Context)
174c2c66affSColin Finck     {
175c2c66affSColin Finck         /* It matches, so remember the ldr entry */
176c2c66affSColin Finck         BasepExeLdrEntry = Entry;
177c2c66affSColin Finck 
178c2c66affSColin Finck         /* And stop enumeration */
179c2c66affSColin Finck         *StopEnumeration = TRUE;
180c2c66affSColin Finck     }
181c2c66affSColin Finck }
182c2c66affSColin Finck 
183c2c66affSColin Finck /*
184c2c66affSColin Finck  * Converts an ANSI or OEM String to the TEB StaticUnicodeString
185c2c66affSColin Finck  */
186c2c66affSColin Finck PUNICODE_STRING
187c2c66affSColin Finck WINAPI
Basep8BitStringToStaticUnicodeString(IN LPCSTR String)188c2c66affSColin Finck Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
189c2c66affSColin Finck {
190c2c66affSColin Finck     PUNICODE_STRING StaticString = &(NtCurrentTeb()->StaticUnicodeString);
191c2c66affSColin Finck     ANSI_STRING AnsiString;
192c2c66affSColin Finck     NTSTATUS Status;
193c2c66affSColin Finck 
194c2c66affSColin Finck     /* Initialize an ANSI String */
195c2c66affSColin Finck     Status = RtlInitAnsiStringEx(&AnsiString, String);
196c2c66affSColin Finck     if (!NT_SUCCESS(Status))
197c2c66affSColin Finck     {
198c2c66affSColin Finck         Status = STATUS_BUFFER_OVERFLOW;
199c2c66affSColin Finck     }
200c2c66affSColin Finck     else
201c2c66affSColin Finck     {
202c2c66affSColin Finck         /* Convert it */
203c2c66affSColin Finck         Status = Basep8BitStringToUnicodeString(StaticString, &AnsiString, FALSE);
204c2c66affSColin Finck     }
205c2c66affSColin Finck 
206c2c66affSColin Finck     if (NT_SUCCESS(Status)) return StaticString;
207c2c66affSColin Finck 
208c2c66affSColin Finck     if (Status == STATUS_BUFFER_OVERFLOW)
209c2c66affSColin Finck     {
210c2c66affSColin Finck         SetLastError(ERROR_FILENAME_EXCED_RANGE);
211c2c66affSColin Finck     }
212c2c66affSColin Finck     else
213c2c66affSColin Finck     {
214c2c66affSColin Finck         BaseSetLastNTError(Status);
215c2c66affSColin Finck     }
216c2c66affSColin Finck 
217c2c66affSColin Finck     return NULL;
218c2c66affSColin Finck }
219c2c66affSColin Finck 
220c2c66affSColin Finck /*
221c2c66affSColin Finck  * Allocates space from the Heap and converts an Unicode String into it
222c2c66affSColin Finck  */
223c2c66affSColin Finck BOOLEAN
224c2c66affSColin Finck WINAPI
Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString,IN LPCSTR String)225c2c66affSColin Finck Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString,
226c2c66affSColin Finck                                       IN LPCSTR String)
227c2c66affSColin Finck {
228c2c66affSColin Finck     ANSI_STRING AnsiString;
229c2c66affSColin Finck     NTSTATUS Status;
230c2c66affSColin Finck 
231c2c66affSColin Finck     /* Initialize an ANSI String */
232c2c66affSColin Finck     Status = RtlInitAnsiStringEx(&AnsiString, String);
233c2c66affSColin Finck     if (!NT_SUCCESS(Status))
234c2c66affSColin Finck     {
235c2c66affSColin Finck         Status = STATUS_BUFFER_OVERFLOW;
236c2c66affSColin Finck     }
237c2c66affSColin Finck     else
238c2c66affSColin Finck     {
239c2c66affSColin Finck         /* Convert it */
240c2c66affSColin Finck         Status = Basep8BitStringToUnicodeString(UnicodeString, &AnsiString, TRUE);
241c2c66affSColin Finck     }
242c2c66affSColin Finck 
243c2c66affSColin Finck     if (NT_SUCCESS(Status)) return TRUE;
244c2c66affSColin Finck 
245c2c66affSColin Finck     if (Status == STATUS_BUFFER_OVERFLOW)
246c2c66affSColin Finck     {
247c2c66affSColin Finck         SetLastError(ERROR_FILENAME_EXCED_RANGE);
248c2c66affSColin Finck     }
249c2c66affSColin Finck     else
250c2c66affSColin Finck     {
251c2c66affSColin Finck         BaseSetLastNTError(Status);
252c2c66affSColin Finck     }
253c2c66affSColin Finck 
254c2c66affSColin Finck     return FALSE;
255c2c66affSColin Finck }
256c2c66affSColin Finck 
257c2c66affSColin Finck /*
258c2c66affSColin Finck  * Allocates space from the Heap and converts an Ansi String into it
259c2c66affSColin Finck  */
260c2c66affSColin Finck  /*NOTE: API IS A HACK */
261c2c66affSColin Finck VOID
262c2c66affSColin Finck WINAPI
BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString,OUT LPWSTR * UnicodeString)263c2c66affSColin Finck BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString,
264c2c66affSColin Finck                                    OUT LPWSTR* UnicodeString)
265c2c66affSColin Finck {
266c2c66affSColin Finck     ANSI_STRING AnsiTemp;
267c2c66affSColin Finck     UNICODE_STRING UnicodeTemp;
268c2c66affSColin Finck 
269c2c66affSColin Finck     DPRINT("BasepAnsiStringToHeapUnicodeString\n");
270c2c66affSColin Finck 
271c2c66affSColin Finck     /* First create the ANSI_STRING */
272c2c66affSColin Finck     RtlInitAnsiString(&AnsiTemp, AnsiString);
273c2c66affSColin Finck 
274c2c66affSColin Finck     if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeTemp,
275c2c66affSColin Finck                                                 &AnsiTemp,
276c2c66affSColin Finck                                                 TRUE)))
277c2c66affSColin Finck     {
278c2c66affSColin Finck         *UnicodeString = UnicodeTemp.Buffer;
279c2c66affSColin Finck     }
280c2c66affSColin Finck     else
281c2c66affSColin Finck     {
282c2c66affSColin Finck         *UnicodeString = NULL;
283c2c66affSColin Finck     }
284c2c66affSColin Finck }
285c2c66affSColin Finck 
286c2c66affSColin Finck PLARGE_INTEGER
287c2c66affSColin Finck WINAPI
BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout,IN DWORD dwMilliseconds)288c2c66affSColin Finck BaseFormatTimeOut(OUT PLARGE_INTEGER Timeout,
289c2c66affSColin Finck                   IN DWORD dwMilliseconds)
290c2c66affSColin Finck {
291c2c66affSColin Finck     /* Check if this is an infinite wait, which means no timeout argument */
292c2c66affSColin Finck     if (dwMilliseconds == INFINITE) return NULL;
293c2c66affSColin Finck 
294c2c66affSColin Finck     /* Otherwise, convert the time to NT Format */
295c2c66affSColin Finck     Timeout->QuadPart = dwMilliseconds * -10000LL;
296c2c66affSColin Finck     return Timeout;
297c2c66affSColin Finck }
298c2c66affSColin Finck 
299c2c66affSColin Finck /*
300c2c66affSColin Finck  * Converts lpSecurityAttributes + Object Name into ObjectAttributes.
301c2c66affSColin Finck  */
302c2c66affSColin Finck POBJECT_ATTRIBUTES
303c2c66affSColin Finck WINAPI
BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes,IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL,IN PUNICODE_STRING ObjectName)304c2c66affSColin Finck BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes,
305c2c66affSColin Finck                            IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL,
306c2c66affSColin Finck                            IN PUNICODE_STRING ObjectName)
307c2c66affSColin Finck {
308c2c66affSColin Finck     ULONG Attributes;
309c2c66affSColin Finck     HANDLE RootDirectory;
310c2c66affSColin Finck     PVOID SecurityDescriptor;
311c2c66affSColin Finck     DPRINT("BaseFormatObjectAttributes. Security: %p, Name: %p\n",
312c2c66affSColin Finck             SecurityAttributes, ObjectName);
313c2c66affSColin Finck 
314c2c66affSColin Finck     /* Get the attributes if present */
315c2c66affSColin Finck     if (SecurityAttributes)
316c2c66affSColin Finck     {
317c2c66affSColin Finck         Attributes = SecurityAttributes->bInheritHandle ? OBJ_INHERIT : 0;
318c2c66affSColin Finck         SecurityDescriptor = SecurityAttributes->lpSecurityDescriptor;
319c2c66affSColin Finck     }
320c2c66affSColin Finck     else
321c2c66affSColin Finck     {
322c2c66affSColin Finck         if (!ObjectName) return NULL;
323c2c66affSColin Finck         Attributes = 0;
324c2c66affSColin Finck         SecurityDescriptor = NULL;
325c2c66affSColin Finck     }
326c2c66affSColin Finck 
327c2c66affSColin Finck     if (ObjectName)
328c2c66affSColin Finck     {
329c2c66affSColin Finck         Attributes |= OBJ_OPENIF;
330c2c66affSColin Finck         RootDirectory = BaseGetNamedObjectDirectory();
331c2c66affSColin Finck     }
332c2c66affSColin Finck     else
333c2c66affSColin Finck     {
334c2c66affSColin Finck         RootDirectory = NULL;
335c2c66affSColin Finck     }
336c2c66affSColin Finck 
337c2c66affSColin Finck     /* Create the Object Attributes */
338c2c66affSColin Finck     InitializeObjectAttributes(ObjectAttributes,
339c2c66affSColin Finck                                ObjectName,
340c2c66affSColin Finck                                Attributes,
341c2c66affSColin Finck                                RootDirectory,
342c2c66affSColin Finck                                SecurityDescriptor);
343c2c66affSColin Finck     DPRINT("Attributes: %lx, RootDirectory: %p, SecurityDescriptor: %p\n",
344c2c66affSColin Finck             Attributes, RootDirectory, SecurityDescriptor);
345c2c66affSColin Finck     return ObjectAttributes;
346c2c66affSColin Finck }
347c2c66affSColin Finck 
348c2c66affSColin Finck /*
349effdb6f2SHermès Bélusca-Maïto  * Creates a stack for a thread or fiber.
350effdb6f2SHermès Bélusca-Maïto  * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpCreateUserStack().
351c2c66affSColin Finck  */
352c2c66affSColin Finck NTSTATUS
353c2c66affSColin Finck WINAPI
BaseCreateStack(_In_ HANDLE hProcess,_In_opt_ SIZE_T StackCommit,_In_opt_ SIZE_T StackReserve,_Out_ PINITIAL_TEB InitialTeb)354effdb6f2SHermès Bélusca-Maïto BaseCreateStack(
355effdb6f2SHermès Bélusca-Maïto     _In_ HANDLE hProcess,
356effdb6f2SHermès Bélusca-Maïto     _In_opt_ SIZE_T StackCommit,
357effdb6f2SHermès Bélusca-Maïto     _In_opt_ SIZE_T StackReserve,
358effdb6f2SHermès Bélusca-Maïto     _Out_ PINITIAL_TEB InitialTeb)
359c2c66affSColin Finck {
360c2c66affSColin Finck     NTSTATUS Status;
361c2c66affSColin Finck     PIMAGE_NT_HEADERS Headers;
362c2c66affSColin Finck     ULONG_PTR Stack;
363c2c66affSColin Finck     BOOLEAN UseGuard;
364effdb6f2SHermès Bélusca-Maïto     ULONG PageSize, AllocationGranularity, Dummy;
365effdb6f2SHermès Bélusca-Maïto     SIZE_T MinimumStackCommit, GuardPageSize;
366effdb6f2SHermès Bélusca-Maïto 
367effdb6f2SHermès Bélusca-Maïto     DPRINT("BaseCreateStack(hProcess: 0x%p, Max: 0x%lx, Current: 0x%lx)\n",
368c2c66affSColin Finck             hProcess, StackReserve, StackCommit);
369c2c66affSColin Finck 
370c2c66affSColin Finck     /* Read page size */
371c2c66affSColin Finck     PageSize = BaseStaticServerData->SysInfo.PageSize;
372c2c66affSColin Finck     AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity;
373c2c66affSColin Finck 
374c2c66affSColin Finck     /* Get the Image Headers */
375c2c66affSColin Finck     Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
376c2c66affSColin Finck     if (!Headers) return STATUS_INVALID_IMAGE_FORMAT;
377c2c66affSColin Finck 
378effdb6f2SHermès Bélusca-Maïto     if (StackReserve == 0)
379effdb6f2SHermès Bélusca-Maïto         StackReserve = Headers->OptionalHeader.SizeOfStackReserve;
380c2c66affSColin Finck 
381effdb6f2SHermès Bélusca-Maïto     if (StackCommit == 0)
382c2c66affSColin Finck     {
383effdb6f2SHermès Bélusca-Maïto         StackCommit = Headers->OptionalHeader.SizeOfStackCommit;
384c2c66affSColin Finck     }
385effdb6f2SHermès Bélusca-Maïto     /* Check if the commit is higher than the reserve */
386c2c66affSColin Finck     else if (StackCommit >= StackReserve)
387c2c66affSColin Finck     {
388effdb6f2SHermès Bélusca-Maïto         /* Grow the reserve beyond the commit, up to 1MB alignment */
389c2c66affSColin Finck         StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
390c2c66affSColin Finck     }
391c2c66affSColin Finck 
392effdb6f2SHermès Bélusca-Maïto     /* Align everything to Page Size */
393c2c66affSColin Finck     StackCommit = ROUND_UP(StackCommit, PageSize);
394c2c66affSColin Finck     StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
395c2c66affSColin Finck 
396effdb6f2SHermès Bélusca-Maïto     MinimumStackCommit = NtCurrentPeb()->MinimumStackCommit;
397effdb6f2SHermès Bélusca-Maïto     if ((MinimumStackCommit != 0) && (StackCommit < MinimumStackCommit))
398c2c66affSColin Finck     {
399effdb6f2SHermès Bélusca-Maïto         StackCommit = MinimumStackCommit;
400c2c66affSColin Finck     }
401c2c66affSColin Finck 
402effdb6f2SHermès Bélusca-Maïto     /* Check if the commit is higher than the reserve */
403c2c66affSColin Finck     if (StackCommit >= StackReserve)
404c2c66affSColin Finck     {
405effdb6f2SHermès Bélusca-Maïto         /* Grow the reserve beyond the commit, up to 1MB alignment */
406c2c66affSColin Finck         StackReserve = ROUND_UP(StackCommit, 1024 * 1024);
407c2c66affSColin Finck     }
408c2c66affSColin Finck 
409effdb6f2SHermès Bélusca-Maïto     /* Align everything to Page Size */
410c2c66affSColin Finck     StackCommit = ROUND_UP(StackCommit, PageSize);
411c2c66affSColin Finck     StackReserve = ROUND_UP(StackReserve, AllocationGranularity);
412c2c66affSColin Finck 
413c2c66affSColin Finck     /* Reserve memory for the stack */
414c2c66affSColin Finck     Stack = 0;
415c2c66affSColin Finck     Status = NtAllocateVirtualMemory(hProcess,
416c2c66affSColin Finck                                      (PVOID*)&Stack,
417c2c66affSColin Finck                                      0,
418c2c66affSColin Finck                                      &StackReserve,
419c2c66affSColin Finck                                      MEM_RESERVE,
420c2c66affSColin Finck                                      PAGE_READWRITE);
421c2c66affSColin Finck     if (!NT_SUCCESS(Status))
422c2c66affSColin Finck     {
423c2c66affSColin Finck         DPRINT1("Failure to reserve stack: %lx\n", Status);
424c2c66affSColin Finck         return Status;
425c2c66affSColin Finck     }
426c2c66affSColin Finck 
427c2c66affSColin Finck     /* Now set up some basic Initial TEB Parameters */
428c2c66affSColin Finck     InitialTeb->AllocatedStackBase = (PVOID)Stack;
429c2c66affSColin Finck     InitialTeb->StackBase = (PVOID)(Stack + StackReserve);
430c2c66affSColin Finck     InitialTeb->PreviousStackBase = NULL;
431c2c66affSColin Finck     InitialTeb->PreviousStackLimit = NULL;
432c2c66affSColin Finck 
433effdb6f2SHermès Bélusca-Maïto     /* Update the stack position */
434c2c66affSColin Finck     Stack += StackReserve - StackCommit;
435c2c66affSColin Finck 
436effdb6f2SHermès Bélusca-Maïto     /* Check if we can add a guard page */
437effdb6f2SHermès Bélusca-Maïto     if (StackReserve >= StackCommit + PageSize)
438c2c66affSColin Finck     {
439c2c66affSColin Finck         Stack -= PageSize;
440c2c66affSColin Finck         StackCommit += PageSize;
441c2c66affSColin Finck         UseGuard = TRUE;
442c2c66affSColin Finck     }
443c2c66affSColin Finck     else
444c2c66affSColin Finck     {
445c2c66affSColin Finck         UseGuard = FALSE;
446c2c66affSColin Finck     }
447c2c66affSColin Finck 
448c2c66affSColin Finck     /* Allocate memory for the stack */
449c2c66affSColin Finck     Status = NtAllocateVirtualMemory(hProcess,
450c2c66affSColin Finck                                      (PVOID*)&Stack,
451c2c66affSColin Finck                                      0,
452c2c66affSColin Finck                                      &StackCommit,
453c2c66affSColin Finck                                      MEM_COMMIT,
454c2c66affSColin Finck                                      PAGE_READWRITE);
455c2c66affSColin Finck     if (!NT_SUCCESS(Status))
456c2c66affSColin Finck     {
457c2c66affSColin Finck         DPRINT1("Failure to allocate stack\n");
458c2c66affSColin Finck         GuardPageSize = 0;
459c2c66affSColin Finck         NtFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE);
460c2c66affSColin Finck         return Status;
461c2c66affSColin Finck     }
462c2c66affSColin Finck 
463c2c66affSColin Finck     /* Now set the current Stack Limit */
464c2c66affSColin Finck     InitialTeb->StackLimit = (PVOID)Stack;
465c2c66affSColin Finck 
466effdb6f2SHermès Bélusca-Maïto     /* Create a guard page if needed */
467c2c66affSColin Finck     if (UseGuard)
468c2c66affSColin Finck     {
469effdb6f2SHermès Bélusca-Maïto         GuardPageSize = PageSize;
470c2c66affSColin Finck         Status = NtProtectVirtualMemory(hProcess,
471c2c66affSColin Finck                                         (PVOID*)&Stack,
472c2c66affSColin Finck                                         &GuardPageSize,
473c2c66affSColin Finck                                         PAGE_GUARD | PAGE_READWRITE,
474c2c66affSColin Finck                                         &Dummy);
475c2c66affSColin Finck         if (!NT_SUCCESS(Status))
476c2c66affSColin Finck         {
477c2c66affSColin Finck             DPRINT1("Failure to set guard page\n");
478c2c66affSColin Finck             return Status;
479c2c66affSColin Finck         }
480c2c66affSColin Finck 
481c2c66affSColin Finck         /* Update the Stack Limit keeping in mind the Guard Page */
482c2c66affSColin Finck         InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit +
483c2c66affSColin Finck                                          GuardPageSize);
484c2c66affSColin Finck     }
485c2c66affSColin Finck 
486c2c66affSColin Finck     /* We are done! */
487c2c66affSColin Finck     return STATUS_SUCCESS;
488c2c66affSColin Finck }
489c2c66affSColin Finck 
490effdb6f2SHermès Bélusca-Maïto /*
491effdb6f2SHermès Bélusca-Maïto  * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpFreeUserStack().
492effdb6f2SHermès Bélusca-Maïto  */
493c2c66affSColin Finck VOID
494c2c66affSColin Finck WINAPI
BaseFreeThreadStack(_In_ HANDLE hProcess,_In_ PINITIAL_TEB InitialTeb)495effdb6f2SHermès Bélusca-Maïto BaseFreeThreadStack(
496effdb6f2SHermès Bélusca-Maïto     _In_ HANDLE hProcess,
497effdb6f2SHermès Bélusca-Maïto     _In_ PINITIAL_TEB InitialTeb)
498c2c66affSColin Finck {
499c2c66affSColin Finck     SIZE_T Dummy = 0;
500c2c66affSColin Finck 
501c2c66affSColin Finck     /* Free the Stack */
502c2c66affSColin Finck     NtFreeVirtualMemory(hProcess,
503c2c66affSColin Finck                         &InitialTeb->AllocatedStackBase,
504c2c66affSColin Finck                         &Dummy,
505c2c66affSColin Finck                         MEM_RELEASE);
506c2c66affSColin Finck }
507c2c66affSColin Finck 
508c2c66affSColin Finck /*
509c2c66affSColin Finck  * Creates the Initial Context for a Thread or Fiber
510c2c66affSColin Finck  */
511c2c66affSColin Finck VOID
512c2c66affSColin Finck WINAPI
BaseInitializeContext(IN PCONTEXT Context,IN PVOID Parameter,IN PVOID StartAddress,IN PVOID StackAddress,IN ULONG ContextType)513c2c66affSColin Finck BaseInitializeContext(IN PCONTEXT Context,
514c2c66affSColin Finck                       IN PVOID Parameter,
515c2c66affSColin Finck                       IN PVOID StartAddress,
516c2c66affSColin Finck                       IN PVOID StackAddress,
517c2c66affSColin Finck                       IN ULONG ContextType)
518c2c66affSColin Finck {
519c2c66affSColin Finck #ifdef _M_IX86
520c2c66affSColin Finck     ULONG ContextFlags;
521c2c66affSColin Finck     DPRINT("BaseInitializeContext: %p\n", Context);
522c2c66affSColin Finck 
523c2c66affSColin Finck     /* Setup the Initial Win32 Thread Context */
524c2c66affSColin Finck     Context->Eax = (ULONG)StartAddress;
525c2c66affSColin Finck     Context->Ebx = (ULONG)Parameter;
526c2c66affSColin Finck     Context->Esp = (ULONG)StackAddress;
527c2c66affSColin Finck     /* The other registers are undefined */
528c2c66affSColin Finck 
529c2c66affSColin Finck     /* Setup the Segments */
530c2c66affSColin Finck     Context->SegFs = KGDT_R3_TEB;
531c2c66affSColin Finck     Context->SegEs = KGDT_R3_DATA;
532c2c66affSColin Finck     Context->SegDs = KGDT_R3_DATA;
533c2c66affSColin Finck     Context->SegCs = KGDT_R3_CODE;
534c2c66affSColin Finck     Context->SegSs = KGDT_R3_DATA;
535c2c66affSColin Finck     Context->SegGs = 0;
536c2c66affSColin Finck 
537c2c66affSColin Finck     /* Set the Context Flags */
538c2c66affSColin Finck     ContextFlags = Context->ContextFlags;
539c2c66affSColin Finck     Context->ContextFlags = CONTEXT_FULL;
540c2c66affSColin Finck 
541c2c66affSColin Finck     /* Give it some room for the Parameter */
542c2c66affSColin Finck     Context->Esp -= sizeof(PVOID);
543c2c66affSColin Finck 
544c2c66affSColin Finck     /* Set the EFLAGS */
545c2c66affSColin Finck     Context->EFlags = 0x3000; /* IOPL 3 */
546c2c66affSColin Finck 
547c2c66affSColin Finck     /* What kind of context is being created? */
548c2c66affSColin Finck     if (ContextType == 1)
549c2c66affSColin Finck     {
550c2c66affSColin Finck         /* For Threads */
551c2c66affSColin Finck         Context->Eip = (ULONG)BaseThreadStartupThunk;
552c2c66affSColin Finck     }
553c2c66affSColin Finck     else if (ContextType == 2)
554c2c66affSColin Finck     {
555c2c66affSColin Finck         /* This is a fiber: make space for the return address */
556c2c66affSColin Finck         Context->Esp -= sizeof(PVOID);
557c2c66affSColin Finck         *((PVOID*)Context->Esp) = BaseFiberStartup;
558c2c66affSColin Finck 
559c2c66affSColin Finck         /* Is FPU state required? */
560c2c66affSColin Finck         Context->ContextFlags |= ContextFlags;
561c2c66affSColin Finck         if ((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
562c2c66affSColin Finck         {
563c2c66affSColin Finck             /* Set an initial state */
564c2c66affSColin Finck             Context->FloatSave.ControlWord = 0x27F;
565c2c66affSColin Finck             Context->FloatSave.StatusWord = 0;
566c2c66affSColin Finck             Context->FloatSave.TagWord = 0xFFFF;
567c2c66affSColin Finck             Context->FloatSave.ErrorOffset = 0;
568c2c66affSColin Finck             Context->FloatSave.ErrorSelector = 0;
569c2c66affSColin Finck             Context->FloatSave.DataOffset = 0;
570c2c66affSColin Finck             Context->FloatSave.DataSelector = 0;
571c2c66affSColin Finck             if (SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE])
572c2c66affSColin Finck                 Context->Dr6 = 0x1F80;
573c2c66affSColin Finck         }
574c2c66affSColin Finck     }
575c2c66affSColin Finck     else
576c2c66affSColin Finck     {
577c2c66affSColin Finck         /* For first thread in a Process */
578c2c66affSColin Finck         Context->Eip = (ULONG)BaseProcessStartThunk;
579c2c66affSColin Finck     }
580c2c66affSColin Finck 
581c2c66affSColin Finck #elif defined(_M_AMD64)
582c2c66affSColin Finck     DPRINT("BaseInitializeContext: %p\n", Context);
5838df1bd61STimo Kreuzer     ASSERT(((ULONG_PTR)StackAddress & 15) == 0);
5848df1bd61STimo Kreuzer 
5858df1bd61STimo Kreuzer     RtlZeroMemory(Context, sizeof(*Context));
586c2c66affSColin Finck 
587c2c66affSColin Finck     /* Setup the Initial Win32 Thread Context */
5888df1bd61STimo Kreuzer     Context->Rcx = (ULONG_PTR)StartAddress;
5898df1bd61STimo Kreuzer     Context->Rdx = (ULONG_PTR)Parameter;
5908df1bd61STimo Kreuzer     Context->Rsp = (ULONG_PTR)StackAddress - 5 * sizeof(PVOID);
591c2c66affSColin Finck 
592c2c66affSColin Finck     /* Setup the Segments */
593c2c66affSColin Finck     Context->SegGs = KGDT64_R3_DATA | RPL_MASK;
594c2c66affSColin Finck     Context->SegEs = KGDT64_R3_DATA | RPL_MASK;
595c2c66affSColin Finck     Context->SegDs = KGDT64_R3_DATA | RPL_MASK;
596c2c66affSColin Finck     Context->SegCs = KGDT64_R3_CODE | RPL_MASK;
597c2c66affSColin Finck     Context->SegSs = KGDT64_R3_DATA | RPL_MASK;
598c2c66affSColin Finck     Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
599c2c66affSColin Finck 
600c2c66affSColin Finck     /* Set the EFLAGS */
6018df1bd61STimo Kreuzer     Context->EFlags = 0x3000 | EFLAGS_INTERRUPT_MASK; /* IOPL 3 */
602c2c66affSColin Finck 
603*39f11249STimo Kreuzer     /* Set MXCSR */
604*39f11249STimo Kreuzer     Context->MxCsr = INITIAL_MXCSR;
605*39f11249STimo Kreuzer 
606c2c66affSColin Finck     if (ContextType == 1)      /* For Threads */
607c2c66affSColin Finck     {
6088df1bd61STimo Kreuzer         Context->Rip = (ULONG_PTR)BaseThreadStartup;
609c2c66affSColin Finck     }
610c2c66affSColin Finck     else if (ContextType == 2) /* For Fibers */
611c2c66affSColin Finck     {
612c2c66affSColin Finck         Context->Rip = (ULONG_PTR)BaseFiberStartup;
613c2c66affSColin Finck     }
614c2c66affSColin Finck     else                       /* For first thread in a Process */
615c2c66affSColin Finck     {
6168df1bd61STimo Kreuzer         Context->Rip = (ULONG_PTR)BaseProcessStartup;
617c2c66affSColin Finck     }
618c2c66affSColin Finck 
619c2c66affSColin Finck     /* Set the Context Flags */
620c2c66affSColin Finck     Context->ContextFlags = CONTEXT_FULL;
621c2c66affSColin Finck #elif defined(_M_ARM)
622c2c66affSColin Finck     DPRINT("BaseInitializeContext: %p\n", Context);
623c2c66affSColin Finck 
624c2c66affSColin Finck     // FIXME: check if this is correct!
625c2c66affSColin Finck     /* Setup the Initial Win32 Thread Context */
626c2c66affSColin Finck     Context->R0 = (ULONG_PTR)StartAddress;
627c2c66affSColin Finck     Context->R1 = (ULONG_PTR)Parameter;
628c2c66affSColin Finck     Context->Sp = (ULONG_PTR)StackAddress;
629c2c66affSColin Finck 
630c2c66affSColin Finck     if (ContextType == 1)      /* For Threads */
631c2c66affSColin Finck     {
632c2c66affSColin Finck         Context->Pc = (ULONG_PTR)BaseThreadStartupThunk;
633c2c66affSColin Finck     }
634c2c66affSColin Finck     else if (ContextType == 2) /* For Fibers */
635c2c66affSColin Finck     {
636c2c66affSColin Finck         Context->Pc = (ULONG_PTR)BaseFiberStartup;
637c2c66affSColin Finck     }
638c2c66affSColin Finck     else                       /* For first thread in a Process */
639c2c66affSColin Finck     {
640c2c66affSColin Finck         Context->Pc = (ULONG_PTR)BaseProcessStartThunk;
641c2c66affSColin Finck     }
642c2c66affSColin Finck 
643c2c66affSColin Finck     /* Set the Context Flags */
644c2c66affSColin Finck     Context->ContextFlags = CONTEXT_FULL;
645c2c66affSColin Finck 
646c2c66affSColin Finck     /* Give it some room for the Parameter */
647c2c66affSColin Finck     Context->Sp -= sizeof(PVOID);
648c2c66affSColin Finck #else
649c2c66affSColin Finck #warning Unknown architecture
650c2c66affSColin Finck     UNIMPLEMENTED;
651c2c66affSColin Finck     DbgBreakPoint();
652c2c66affSColin Finck #endif
653c2c66affSColin Finck }
654c2c66affSColin Finck 
655c2c66affSColin Finck /*
656c2c66affSColin Finck  * Checks if the privilege for Real-Time Priority is there
657c2c66affSColin Finck  * Beware about this function behavior:
658c2c66affSColin Finck  * - In case Keep is set to FALSE, then the function will only check
659c2c66affSColin Finck  * whether real time is allowed and won't grant the privilege. In that case
660c2c66affSColin Finck  * it will return TRUE if allowed, FALSE otherwise. Not a state!
661c2c66affSColin Finck  * It means you don't have to release privilege when calling with FALSE.
662c2c66affSColin Finck  */
663c2c66affSColin Finck PVOID
664c2c66affSColin Finck WINAPI
BasepIsRealtimeAllowed(IN BOOLEAN Keep)665c2c66affSColin Finck BasepIsRealtimeAllowed(IN BOOLEAN Keep)
666c2c66affSColin Finck {
667c2c66affSColin Finck     ULONG Privilege = SE_INC_BASE_PRIORITY_PRIVILEGE;
668c2c66affSColin Finck     PVOID State;
669c2c66affSColin Finck     NTSTATUS Status;
670c2c66affSColin Finck 
671c2c66affSColin Finck     Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State);
672c2c66affSColin Finck     if (!NT_SUCCESS(Status)) return NULL;
673c2c66affSColin Finck 
674c2c66affSColin Finck     if (!Keep)
675c2c66affSColin Finck     {
676c2c66affSColin Finck         RtlReleasePrivilege(State);
677c2c66affSColin Finck         State = (PVOID)TRUE;
678c2c66affSColin Finck     }
679c2c66affSColin Finck 
680c2c66affSColin Finck     return State;
681c2c66affSColin Finck }
682c2c66affSColin Finck 
683c2c66affSColin Finck /*
684c2c66affSColin Finck  * Maps an image file into a section
685c2c66affSColin Finck  */
686c2c66affSColin Finck NTSTATUS
687c2c66affSColin Finck WINAPI
BasepMapFile(IN LPCWSTR lpApplicationName,OUT PHANDLE hSection,IN PUNICODE_STRING ApplicationName)688c2c66affSColin Finck BasepMapFile(IN LPCWSTR lpApplicationName,
689c2c66affSColin Finck              OUT PHANDLE hSection,
690c2c66affSColin Finck              IN PUNICODE_STRING ApplicationName)
691c2c66affSColin Finck {
692c2c66affSColin Finck     RTL_RELATIVE_NAME_U RelativeName;
693c2c66affSColin Finck     OBJECT_ATTRIBUTES ObjectAttributes;
694c2c66affSColin Finck     NTSTATUS Status;
695c2c66affSColin Finck     HANDLE hFile = NULL;
696c2c66affSColin Finck     IO_STATUS_BLOCK IoStatusBlock;
697c2c66affSColin Finck 
698c2c66affSColin Finck     DPRINT("BasepMapFile\n");
699c2c66affSColin Finck 
700c2c66affSColin Finck     /* Zero out the Relative Directory */
701c2c66affSColin Finck     RelativeName.ContainingDirectory = NULL;
702c2c66affSColin Finck 
703c2c66affSColin Finck     /* Find the application name */
704c2c66affSColin Finck     if (!RtlDosPathNameToNtPathName_U(lpApplicationName,
705c2c66affSColin Finck                                       ApplicationName,
706c2c66affSColin Finck                                       NULL,
707c2c66affSColin Finck                                       &RelativeName))
708c2c66affSColin Finck     {
709c2c66affSColin Finck         return STATUS_OBJECT_PATH_NOT_FOUND;
710c2c66affSColin Finck     }
711c2c66affSColin Finck 
712c2c66affSColin Finck     DPRINT("ApplicationName %wZ\n", ApplicationName);
713c2c66affSColin Finck     DPRINT("RelativeName %wZ\n", &RelativeName.RelativeName);
714c2c66affSColin Finck 
715c2c66affSColin Finck     /* Did we get a relative name? */
716c2c66affSColin Finck     if (RelativeName.RelativeName.Length)
717c2c66affSColin Finck     {
718c2c66affSColin Finck         ApplicationName = &RelativeName.RelativeName;
719c2c66affSColin Finck     }
720c2c66affSColin Finck 
721c2c66affSColin Finck     /* Initialize the Object Attributes */
722c2c66affSColin Finck     InitializeObjectAttributes(&ObjectAttributes,
723c2c66affSColin Finck                                ApplicationName,
724c2c66affSColin Finck                                OBJ_CASE_INSENSITIVE,
725c2c66affSColin Finck                                RelativeName.ContainingDirectory,
726c2c66affSColin Finck                                NULL);
727c2c66affSColin Finck 
728c2c66affSColin Finck     /* Try to open the executable */
729c2c66affSColin Finck     Status = NtOpenFile(&hFile,
730c2c66affSColin Finck                         SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,
731c2c66affSColin Finck                         &ObjectAttributes,
732c2c66affSColin Finck                         &IoStatusBlock,
733c2c66affSColin Finck                         FILE_SHARE_DELETE | FILE_SHARE_READ,
734c2c66affSColin Finck                         FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
735c2c66affSColin Finck     if (!NT_SUCCESS(Status))
736c2c66affSColin Finck     {
737c2c66affSColin Finck         DPRINT1("Failed to open file\n");
738c2c66affSColin Finck         BaseSetLastNTError(Status);
739c2c66affSColin Finck         return Status;
740c2c66affSColin Finck     }
741c2c66affSColin Finck 
742c2c66affSColin Finck     /* Create a section for this file */
743c2c66affSColin Finck     Status = NtCreateSection(hSection,
744c2c66affSColin Finck                              SECTION_ALL_ACCESS,
745c2c66affSColin Finck                              NULL,
746c2c66affSColin Finck                              NULL,
747c2c66affSColin Finck                              PAGE_EXECUTE,
748c2c66affSColin Finck                              SEC_IMAGE,
749c2c66affSColin Finck                              hFile);
750c2c66affSColin Finck     NtClose(hFile);
751c2c66affSColin Finck 
752c2c66affSColin Finck     /* Return status */
753c2c66affSColin Finck     DPRINT("Section: %p for file: %p\n", *hSection, hFile);
754c2c66affSColin Finck     return Status;
755c2c66affSColin Finck }
756c2c66affSColin Finck 
757c2c66affSColin Finck /*
758c2c66affSColin Finck  * @implemented
759c2c66affSColin Finck  */
760c2c66affSColin Finck BOOLEAN
761c2c66affSColin Finck WINAPI
Wow64EnableWow64FsRedirection(IN BOOLEAN Wow64EnableWow64FsRedirection)762c2c66affSColin Finck Wow64EnableWow64FsRedirection(IN BOOLEAN Wow64EnableWow64FsRedirection)
763c2c66affSColin Finck {
764c2c66affSColin Finck     NTSTATUS Status;
765c2c66affSColin Finck     BOOL Result;
766c2c66affSColin Finck 
767c2c66affSColin Finck     Status = RtlWow64EnableFsRedirection(Wow64EnableWow64FsRedirection);
768c2c66affSColin Finck     if (NT_SUCCESS(Status))
769c2c66affSColin Finck     {
770c2c66affSColin Finck         Result = TRUE;
771c2c66affSColin Finck     }
772c2c66affSColin Finck     else
773c2c66affSColin Finck     {
774c2c66affSColin Finck         BaseSetLastNTError(Status);
775c2c66affSColin Finck         Result = FALSE;
776c2c66affSColin Finck     }
777c2c66affSColin Finck     return Result;
778c2c66affSColin Finck }
779c2c66affSColin Finck 
780c2c66affSColin Finck /*
781c2c66affSColin Finck  * @implemented
782c2c66affSColin Finck  */
783c2c66affSColin Finck BOOL
784c2c66affSColin Finck WINAPI
Wow64DisableWow64FsRedirection(IN PVOID * OldValue)785c2c66affSColin Finck Wow64DisableWow64FsRedirection(IN PVOID *OldValue)
786c2c66affSColin Finck {
787c2c66affSColin Finck     NTSTATUS Status;
788c2c66affSColin Finck     BOOL Result;
789c2c66affSColin Finck 
790c2c66affSColin Finck     Status = RtlWow64EnableFsRedirectionEx((PVOID)TRUE, OldValue);
791c2c66affSColin Finck     if (NT_SUCCESS(Status))
792c2c66affSColin Finck     {
793c2c66affSColin Finck         Result = TRUE;
794c2c66affSColin Finck     }
795c2c66affSColin Finck     else
796c2c66affSColin Finck     {
797c2c66affSColin Finck         BaseSetLastNTError(Status);
798c2c66affSColin Finck         Result = FALSE;
799c2c66affSColin Finck     }
800c2c66affSColin Finck     return Result;
801c2c66affSColin Finck }
802c2c66affSColin Finck 
803c2c66affSColin Finck /*
804c2c66affSColin Finck  * @implemented
805c2c66affSColin Finck  */
806c2c66affSColin Finck BOOL
807c2c66affSColin Finck WINAPI
Wow64RevertWow64FsRedirection(IN PVOID OldValue)808c2c66affSColin Finck Wow64RevertWow64FsRedirection(IN PVOID OldValue)
809c2c66affSColin Finck {
810c2c66affSColin Finck     NTSTATUS Status;
811c2c66affSColin Finck     BOOL Result;
812c2c66affSColin Finck 
813c2c66affSColin Finck     Status = RtlWow64EnableFsRedirectionEx(OldValue, &OldValue);
814c2c66affSColin Finck     if (NT_SUCCESS(Status))
815c2c66affSColin Finck     {
816c2c66affSColin Finck         Result = TRUE;
817c2c66affSColin Finck     }
818c2c66affSColin Finck     else
819c2c66affSColin Finck     {
820c2c66affSColin Finck         BaseSetLastNTError(Status);
821c2c66affSColin Finck         Result = FALSE;
822c2c66affSColin Finck     }
823c2c66affSColin Finck     return Result;
824c2c66affSColin Finck }
825c2c66affSColin Finck 
826c2c66affSColin Finck /*
827c2c66affSColin Finck  * @implemented
828c2c66affSColin Finck  */
829c2c66affSColin Finck VOID
830c2c66affSColin Finck WINAPI
SetFileApisToOEM(VOID)831c2c66affSColin Finck SetFileApisToOEM(VOID)
832c2c66affSColin Finck {
833c2c66affSColin Finck     /* Set the correct Base Api */
834c2c66affSColin Finck     Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
835c2c66affSColin Finck     BasepUnicodeStringTo8BitString = RtlUnicodeStringToOemString;
836c2c66affSColin Finck     BasepUnicodeStringTo8BitSize = BasepUnicodeStringToOemSize;
837c2c66affSColin Finck     Basep8BitStringToUnicodeSize = BasepOemStringToUnicodeSize;
838c2c66affSColin Finck 
839c2c66affSColin Finck     /* FIXME: Old, deprecated way */
840c2c66affSColin Finck     bIsFileApiAnsi = FALSE;
841c2c66affSColin Finck }
842c2c66affSColin Finck 
843c2c66affSColin Finck 
844c2c66affSColin Finck /*
845c2c66affSColin Finck  * @implemented
846c2c66affSColin Finck  */
847c2c66affSColin Finck VOID
848c2c66affSColin Finck WINAPI
SetFileApisToANSI(VOID)849c2c66affSColin Finck SetFileApisToANSI(VOID)
850c2c66affSColin Finck {
851c2c66affSColin Finck     /* Set the correct Base Api */
852c2c66affSColin Finck     Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
853c2c66affSColin Finck     BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString;
854c2c66affSColin Finck     BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize;
855c2c66affSColin Finck     Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize;
856c2c66affSColin Finck 
857c2c66affSColin Finck     /* FIXME: Old, deprecated way */
858c2c66affSColin Finck     bIsFileApiAnsi = TRUE;
859c2c66affSColin Finck }
860c2c66affSColin Finck 
861c2c66affSColin Finck /*
862c2c66affSColin Finck  * @implemented
863c2c66affSColin Finck  */
864c2c66affSColin Finck BOOL
865c2c66affSColin Finck WINAPI
AreFileApisANSI(VOID)866c2c66affSColin Finck AreFileApisANSI(VOID)
867c2c66affSColin Finck {
868c2c66affSColin Finck    return Basep8BitStringToUnicodeString == RtlAnsiStringToUnicodeString;
869c2c66affSColin Finck }
870c2c66affSColin Finck 
871c2c66affSColin Finck /*
872c2c66affSColin Finck  * @implemented
873c2c66affSColin Finck  */
874c2c66affSColin Finck VOID
875c2c66affSColin Finck WINAPI
BaseMarkFileForDelete(IN HANDLE FileHandle,IN ULONG FileAttributes)876c2c66affSColin Finck BaseMarkFileForDelete(IN HANDLE FileHandle,
877c2c66affSColin Finck                       IN ULONG FileAttributes)
878c2c66affSColin Finck {
879c2c66affSColin Finck     IO_STATUS_BLOCK IoStatusBlock;
880c2c66affSColin Finck     FILE_BASIC_INFORMATION FileBasicInfo;
881c2c66affSColin Finck     FILE_DISPOSITION_INFORMATION FileDispositionInfo;
882c2c66affSColin Finck 
883c2c66affSColin Finck     /* If no attributes were given, get them */
884c2c66affSColin Finck     if (!FileAttributes)
885c2c66affSColin Finck     {
886c2c66affSColin Finck         FileBasicInfo.FileAttributes = 0;
887c2c66affSColin Finck         NtQueryInformationFile(FileHandle,
888c2c66affSColin Finck                                &IoStatusBlock,
889c2c66affSColin Finck                                &FileBasicInfo,
890c2c66affSColin Finck                                sizeof(FileBasicInfo),
891c2c66affSColin Finck                                FileBasicInformation);
892c2c66affSColin Finck         FileAttributes = FileBasicInfo.FileAttributes;
893c2c66affSColin Finck     }
894c2c66affSColin Finck 
895c2c66affSColin Finck     /* If file is marked as RO, reset its attributes */
896c2c66affSColin Finck     if (FileAttributes & FILE_ATTRIBUTE_READONLY)
897c2c66affSColin Finck     {
898c2c66affSColin Finck         RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
899c2c66affSColin Finck         FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
900c2c66affSColin Finck         NtSetInformationFile(FileHandle,
901c2c66affSColin Finck                              &IoStatusBlock,
902c2c66affSColin Finck                              &FileBasicInfo,
903c2c66affSColin Finck                              sizeof(FileBasicInfo),
904c2c66affSColin Finck                              FileBasicInformation);
905c2c66affSColin Finck     }
906c2c66affSColin Finck 
907c2c66affSColin Finck     /* Finally, mark the file for deletion */
908c2c66affSColin Finck     FileDispositionInfo.DeleteFile = TRUE;
909c2c66affSColin Finck     NtSetInformationFile(FileHandle,
910c2c66affSColin Finck                          &IoStatusBlock,
911c2c66affSColin Finck                          &FileDispositionInfo,
912c2c66affSColin Finck                          sizeof(FileDispositionInfo),
913c2c66affSColin Finck                          FileDispositionInformation);
914c2c66affSColin Finck }
915c2c66affSColin Finck 
916c2c66affSColin Finck /*
917c2c66affSColin Finck  * @unimplemented
918c2c66affSColin Finck  */
919c2c66affSColin Finck NTSTATUS
920c2c66affSColin Finck WINAPI
BasepCheckWinSaferRestrictions(IN HANDLE UserToken,IN LPWSTR ApplicationName,IN HANDLE FileHandle,OUT PBOOLEAN InJob,OUT PHANDLE NewToken,OUT PHANDLE JobHandle)921c2c66affSColin Finck BasepCheckWinSaferRestrictions(IN HANDLE UserToken,
922c2c66affSColin Finck                                IN LPWSTR ApplicationName,
923c2c66affSColin Finck                                IN HANDLE FileHandle,
924c2c66affSColin Finck                                OUT PBOOLEAN InJob,
925c2c66affSColin Finck                                OUT PHANDLE NewToken,
926c2c66affSColin Finck                                OUT PHANDLE JobHandle)
927c2c66affSColin Finck {
928c2c66affSColin Finck     NTSTATUS Status;
929c2c66affSColin Finck 
930c2c66affSColin Finck     /* Validate that there's a name */
931c2c66affSColin Finck     if ((ApplicationName) && *(ApplicationName))
932c2c66affSColin Finck     {
933c2c66affSColin Finck         /* Validate that the required output parameters are there */
934c2c66affSColin Finck         if ((InJob) && (NewToken) && (JobHandle))
935c2c66affSColin Finck         {
936c2c66affSColin Finck             /* Do the work (one day...) */
937c2c66affSColin Finck             DPRINT("BasepCheckWinSaferRestrictions is UNIMPLEMENTED\n");
938c2c66affSColin Finck             Status = STATUS_SUCCESS;
939c2c66affSColin Finck         }
940c2c66affSColin Finck         else
941c2c66affSColin Finck         {
942c2c66affSColin Finck             /* Act as if SEH hit this */
943c2c66affSColin Finck             Status = STATUS_ACCESS_VIOLATION;
944c2c66affSColin Finck         }
945c2c66affSColin Finck     }
946c2c66affSColin Finck     else
947c2c66affSColin Finck     {
948c2c66affSColin Finck         /* Input is invalid */
949c2c66affSColin Finck         Status = STATUS_INVALID_PARAMETER;
950c2c66affSColin Finck     }
951c2c66affSColin Finck 
952c2c66affSColin Finck     /* Return the status */
953c2c66affSColin Finck     return Status;
954c2c66affSColin Finck }
955