2 * Ntdll Unix private interface
4 * Copyright (C) 2020 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 #ifndef __NTDLL_UNIX_PRIVATE_H
22 #define __NTDLL_UNIX_PRIVATE_H
27 #include "wine/unixlib.h"
28 #include "wine/server.h"
29 #include "wine/list.h"
30 #include "wine/debug.h"
35 static const WORD current_machine
= IMAGE_FILE_MACHINE_I386
;
36 #elif defined(__x86_64__)
37 static const WORD current_machine
= IMAGE_FILE_MACHINE_AMD64
;
38 #elif defined(__arm__)
39 static const WORD current_machine
= IMAGE_FILE_MACHINE_ARMNT
;
40 #elif defined(__aarch64__)
41 static const WORD current_machine
= IMAGE_FILE_MACHINE_ARM64
;
43 extern WORD native_machine DECLSPEC_HIDDEN
;
45 static const BOOL is_win64
= (sizeof(void *) > sizeof(int));
47 static inline BOOL
is_machine_64bit( WORD machine
)
49 return (machine
== IMAGE_FILE_MACHINE_AMD64
|| machine
== IMAGE_FILE_MACHINE_ARM64
);
53 typedef TEB32 WOW_TEB
;
54 typedef PEB32 WOW_PEB
;
55 static inline TEB64
*NtCurrentTeb64(void) { return NULL
; }
57 typedef TEB64 WOW_TEB
;
58 typedef PEB64 WOW_PEB
;
59 static inline TEB64
*NtCurrentTeb64(void) { return (TEB64
*)NtCurrentTeb()->GdiBatchCount
; }
62 extern WOW_PEB
*wow_peb DECLSPEC_HIDDEN
;
64 static inline WOW_TEB
*get_wow_teb( TEB
*teb
)
66 return teb
->WowTebOffset
? (WOW_TEB
*)((char *)teb
+ teb
->WowTebOffset
) : NULL
;
69 static inline BOOL
is_wow64(void)
74 /* check for old-style Wow64 (using a 32-bit ntdll.so) */
75 static inline BOOL
is_old_wow64(void)
77 return !is_win64
&& wow_peb
;
80 /* thread private data, stored in NtCurrentTeb()->GdiTebBatch */
81 struct ntdll_thread_data
83 void *cpu_data
[16]; /* reserved for CPU-specific data */
84 void *kernel_stack
; /* stack for thread startup and kernel syscalls */
85 int request_fd
; /* fd for sending server requests */
86 int reply_fd
; /* fd for receiving server replies */
87 int wait_fd
[2]; /* fd for sleeping server requests */
88 pthread_t pthread_id
; /* pthread thread id */
89 struct list entry
; /* entry in TEB list */
90 PRTL_THREAD_START_ROUTINE start
; /* thread entry point */
91 void *param
; /* thread entry point parameter */
92 void *jmp_buf; /* setjmp buffer for exception handling */
95 C_ASSERT( sizeof(struct ntdll_thread_data
) <= sizeof(((TEB
*)0)->GdiTebBatch
) );
97 static inline struct ntdll_thread_data
*ntdll_get_thread_data(void)
99 return (struct ntdll_thread_data
*)&NtCurrentTeb()->GdiTebBatch
;
102 /* returns TRUE if the async is complete; FALSE if it should be restarted */
103 typedef BOOL
async_callback_t( void *user
, ULONG_PTR
*info
, unsigned int *status
);
107 async_callback_t
*callback
;
108 struct async_fileio
*next
;
112 static const SIZE_T page_size
= 0x1000;
113 static const SIZE_T teb_size
= 0x3800; /* TEB64 + TEB32 + debug info */
114 static const SIZE_T signal_stack_mask
= 0xffff;
115 static const SIZE_T signal_stack_size
= 0x10000 - 0x3800;
116 static const SIZE_T kernel_stack_size
= 0x100000;
117 static const SIZE_T min_kernel_stack
= 0x2000;
118 static const LONG teb_offset
= 0x2000;
120 #define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1)
121 #define FILE_USE_FILE_POINTER_POSITION ((LONGLONG)-2)
123 /* callbacks to PE ntdll from the Unix side */
124 extern void (WINAPI
*pDbgUiRemoteBreakin
)( void *arg
) DECLSPEC_HIDDEN
;
125 extern NTSTATUS (WINAPI
*pKiRaiseUserExceptionDispatcher
)(void) DECLSPEC_HIDDEN
;
126 extern NTSTATUS (WINAPI
*pKiUserExceptionDispatcher
)(EXCEPTION_RECORD
*,CONTEXT
*) DECLSPEC_HIDDEN
;
127 extern void (WINAPI
*pKiUserApcDispatcher
)(CONTEXT
*,ULONG_PTR
,ULONG_PTR
,ULONG_PTR
,PNTAPCFUNC
) DECLSPEC_HIDDEN
;
128 extern void (WINAPI
*pKiUserCallbackDispatcher
)(ULONG
,void*,ULONG
) DECLSPEC_HIDDEN
;
129 extern void (WINAPI
*pLdrInitializeThunk
)(CONTEXT
*,void**,ULONG_PTR
,ULONG_PTR
) DECLSPEC_HIDDEN
;
130 extern void (WINAPI
*pRtlUserThreadStart
)( PRTL_THREAD_START_ROUTINE entry
, void *arg
) DECLSPEC_HIDDEN
;
131 extern void (WINAPI
*p__wine_ctrl_routine
)(void *) DECLSPEC_HIDDEN
;
132 extern SYSTEM_DLL_INIT_BLOCK
*pLdrSystemDllInitBlock DECLSPEC_HIDDEN
;
133 extern LONGLONG CDECL
fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN
;
135 struct _FILE_FS_DEVICE_INFORMATION
;
137 extern const char wine_build
[] DECLSPEC_HIDDEN
;
139 extern const char *home_dir DECLSPEC_HIDDEN
;
140 extern const char *data_dir DECLSPEC_HIDDEN
;
141 extern const char *build_dir DECLSPEC_HIDDEN
;
142 extern const char *config_dir DECLSPEC_HIDDEN
;
143 extern const char *user_name DECLSPEC_HIDDEN
;
144 extern const char **dll_paths DECLSPEC_HIDDEN
;
145 extern const char **system_dll_paths DECLSPEC_HIDDEN
;
146 extern pthread_key_t teb_key DECLSPEC_HIDDEN
;
147 extern PEB
*peb DECLSPEC_HIDDEN
;
148 extern USHORT
*uctable DECLSPEC_HIDDEN
;
149 extern USHORT
*lctable DECLSPEC_HIDDEN
;
150 extern SIZE_T startup_info_size DECLSPEC_HIDDEN
;
151 extern BOOL is_prefix_bootstrap DECLSPEC_HIDDEN
;
152 extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN
;
153 extern int main_argc DECLSPEC_HIDDEN
;
154 extern char **main_argv DECLSPEC_HIDDEN
;
155 extern char **main_envp DECLSPEC_HIDDEN
;
156 extern WCHAR
**main_wargv DECLSPEC_HIDDEN
;
157 extern const WCHAR system_dir
[] DECLSPEC_HIDDEN
;
158 extern unsigned int supported_machines_count DECLSPEC_HIDDEN
;
159 extern USHORT supported_machines
[8] DECLSPEC_HIDDEN
;
160 extern BOOL process_exiting DECLSPEC_HIDDEN
;
161 extern HANDLE keyed_event DECLSPEC_HIDDEN
;
162 extern timeout_t server_start_time DECLSPEC_HIDDEN
;
163 extern sigset_t server_block_set DECLSPEC_HIDDEN
;
164 extern struct _KUSER_SHARED_DATA
*user_shared_data DECLSPEC_HIDDEN
;
165 extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN
;
167 extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN
;
170 extern void init_environment( int argc
, char *argv
[], char *envp
[] ) DECLSPEC_HIDDEN
;
171 extern void init_startup_info(void) DECLSPEC_HIDDEN
;
172 extern void *create_startup_info( const UNICODE_STRING
*nt_image
, const RTL_USER_PROCESS_PARAMETERS
*params
,
173 DWORD
*info_size
) DECLSPEC_HIDDEN
;
174 extern char **build_envp( const WCHAR
*envW
) DECLSPEC_HIDDEN
;
175 extern char *get_alternate_wineloader( WORD machine
) DECLSPEC_HIDDEN
;
176 extern NTSTATUS
exec_wineloader( char **argv
, int socketfd
, const pe_image_info_t
*pe_info
) DECLSPEC_HIDDEN
;
177 extern NTSTATUS
load_builtin( const pe_image_info_t
*image_info
, WCHAR
*filename
, USHORT machine
,
178 void **addr_ptr
, SIZE_T
*size_ptr
, ULONG_PTR limit
) DECLSPEC_HIDDEN
;
179 extern BOOL
is_builtin_path( const UNICODE_STRING
*path
, WORD
*machine
) DECLSPEC_HIDDEN
;
180 extern NTSTATUS
load_main_exe( const WCHAR
*name
, const char *unix_name
, const WCHAR
*curdir
,
181 USHORT load_machine
, WCHAR
**image
, void **module
) DECLSPEC_HIDDEN
;
182 extern NTSTATUS
load_start_exe( WCHAR
**image
, void **module
) DECLSPEC_HIDDEN
;
183 extern void start_server( BOOL debug
) DECLSPEC_HIDDEN
;
185 extern unsigned int server_call_unlocked( void *req_ptr
) DECLSPEC_HIDDEN
;
186 extern void server_enter_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
) DECLSPEC_HIDDEN
;
187 extern void server_leave_uninterrupted_section( pthread_mutex_t
*mutex
, sigset_t
*sigset
) DECLSPEC_HIDDEN
;
188 extern unsigned int server_select( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
189 timeout_t abs_timeout
, context_t
*context
, user_apc_t
*user_apc
) DECLSPEC_HIDDEN
;
190 extern unsigned int server_wait( const select_op_t
*select_op
, data_size_t size
, UINT flags
,
191 const LARGE_INTEGER
*timeout
) DECLSPEC_HIDDEN
;
192 extern unsigned int server_queue_process_apc( HANDLE process
, const apc_call_t
*call
,
193 apc_result_t
*result
) DECLSPEC_HIDDEN
;
194 extern int server_get_unix_fd( HANDLE handle
, unsigned int wanted_access
, int *unix_fd
,
195 int *needs_close
, enum server_fd_type
*type
, unsigned int *options
) DECLSPEC_HIDDEN
;
196 extern void wine_server_send_fd( int fd
) DECLSPEC_HIDDEN
;
197 extern void process_exit_wrapper( int status
) DECLSPEC_HIDDEN
;
198 extern size_t server_init_process(void) DECLSPEC_HIDDEN
;
199 extern void server_init_process_done(void) DECLSPEC_HIDDEN
;
200 extern void server_init_thread( void *entry_point
, BOOL
*suspend
) DECLSPEC_HIDDEN
;
201 extern int server_pipe( int fd
[2] ) DECLSPEC_HIDDEN
;
203 extern void fpux_to_fpu( I386_FLOATING_SAVE_AREA
*fpu
, const XSAVE_FORMAT
*fpux
) DECLSPEC_HIDDEN
;
204 extern void fpu_to_fpux( XSAVE_FORMAT
*fpux
, const I386_FLOATING_SAVE_AREA
*fpu
) DECLSPEC_HIDDEN
;
205 extern void *get_cpu_area( USHORT machine
) DECLSPEC_HIDDEN
;
206 extern void set_thread_id( TEB
*teb
, DWORD pid
, DWORD tid
) DECLSPEC_HIDDEN
;
207 extern NTSTATUS
init_thread_stack( TEB
*teb
, ULONG_PTR limit
, SIZE_T reserve_size
, SIZE_T commit_size
) DECLSPEC_HIDDEN
;
208 extern void DECLSPEC_NORETURN
abort_thread( int status
) DECLSPEC_HIDDEN
;
209 extern void DECLSPEC_NORETURN
abort_process( int status
) DECLSPEC_HIDDEN
;
210 extern void DECLSPEC_NORETURN
exit_process( int status
) DECLSPEC_HIDDEN
;
211 extern void wait_suspend( CONTEXT
*context
) DECLSPEC_HIDDEN
;
212 extern NTSTATUS
send_debug_event( EXCEPTION_RECORD
*rec
, CONTEXT
*context
, BOOL first_chance
) DECLSPEC_HIDDEN
;
213 extern NTSTATUS
set_thread_context( HANDLE handle
, const void *context
, BOOL
*self
, USHORT machine
) DECLSPEC_HIDDEN
;
214 extern NTSTATUS
get_thread_context( HANDLE handle
, void *context
, BOOL
*self
, USHORT machine
) DECLSPEC_HIDDEN
;
215 extern unsigned int alloc_object_attributes( const OBJECT_ATTRIBUTES
*attr
, struct object_attributes
**ret
,
216 data_size_t
*ret_len
) DECLSPEC_HIDDEN
;
217 extern NTSTATUS
system_time_precise( void *args
) DECLSPEC_HIDDEN
;
219 extern void *anon_mmap_fixed( void *start
, size_t size
, int prot
, int flags
) DECLSPEC_HIDDEN
;
220 extern void *anon_mmap_alloc( size_t size
, int prot
) DECLSPEC_HIDDEN
;
221 extern void virtual_init(void) DECLSPEC_HIDDEN
;
222 extern ULONG_PTR
get_system_affinity_mask(void) DECLSPEC_HIDDEN
;
223 extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION
*info
, BOOL wow64
) DECLSPEC_HIDDEN
;
224 extern NTSTATUS
virtual_map_builtin_module( HANDLE mapping
, void **module
, SIZE_T
*size
, SECTION_IMAGE_INFORMATION
*info
,
225 ULONG_PTR limit
, WORD machine
, BOOL prefer_native
) DECLSPEC_HIDDEN
;
226 extern NTSTATUS
virtual_map_module( HANDLE mapping
, void **module
, SIZE_T
*size
, SECTION_IMAGE_INFORMATION
*info
,
227 ULONG_PTR limit
, USHORT machine
) DECLSPEC_HIDDEN
;
228 extern NTSTATUS
virtual_create_builtin_view( void *module
, const UNICODE_STRING
*nt_name
,
229 pe_image_info_t
*info
, void *so_handle
) DECLSPEC_HIDDEN
;
230 extern TEB
*virtual_alloc_first_teb(void) DECLSPEC_HIDDEN
;
231 extern NTSTATUS
virtual_alloc_teb( TEB
**ret_teb
) DECLSPEC_HIDDEN
;
232 extern void virtual_free_teb( TEB
*teb
) DECLSPEC_HIDDEN
;
233 extern NTSTATUS
virtual_clear_tls_index( ULONG index
) DECLSPEC_HIDDEN
;
234 extern NTSTATUS
virtual_alloc_thread_stack( INITIAL_TEB
*stack
, ULONG_PTR limit
, SIZE_T reserve_size
,
235 SIZE_T commit_size
, BOOL guard_page
) DECLSPEC_HIDDEN
;
236 extern void virtual_map_user_shared_data(void) DECLSPEC_HIDDEN
;
237 extern NTSTATUS
virtual_handle_fault( void *addr
, DWORD err
, void *stack
) DECLSPEC_HIDDEN
;
238 extern unsigned int virtual_locked_server_call( void *req_ptr
) DECLSPEC_HIDDEN
;
239 extern ssize_t
virtual_locked_read( int fd
, void *addr
, size_t size
) DECLSPEC_HIDDEN
;
240 extern ssize_t
virtual_locked_pread( int fd
, void *addr
, size_t size
, off_t offset
) DECLSPEC_HIDDEN
;
241 extern ssize_t
virtual_locked_recvmsg( int fd
, struct msghdr
*hdr
, int flags
) DECLSPEC_HIDDEN
;
242 extern BOOL
virtual_is_valid_code_address( const void *addr
, SIZE_T size
) DECLSPEC_HIDDEN
;
243 extern void *virtual_setup_exception( void *stack_ptr
, size_t size
, EXCEPTION_RECORD
*rec
) DECLSPEC_HIDDEN
;
244 extern BOOL
virtual_check_buffer_for_read( const void *ptr
, SIZE_T size
) DECLSPEC_HIDDEN
;
245 extern BOOL
virtual_check_buffer_for_write( void *ptr
, SIZE_T size
) DECLSPEC_HIDDEN
;
246 extern SIZE_T
virtual_uninterrupted_read_memory( const void *addr
, void *buffer
, SIZE_T size
) DECLSPEC_HIDDEN
;
247 extern NTSTATUS
virtual_uninterrupted_write_memory( void *addr
, const void *buffer
, SIZE_T size
) DECLSPEC_HIDDEN
;
248 extern void virtual_set_force_exec( BOOL enable
) DECLSPEC_HIDDEN
;
249 extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN
;
250 extern void virtual_fill_image_information( const pe_image_info_t
*pe_info
,
251 SECTION_IMAGE_INFORMATION
*info
) DECLSPEC_HIDDEN
;
252 extern void *get_builtin_so_handle( void *module
) DECLSPEC_HIDDEN
;
253 extern NTSTATUS
load_builtin_unixlib( void *module
, const char *name
) DECLSPEC_HIDDEN
;
254 extern NTSTATUS
unwind_builtin_dll( void *args
) DECLSPEC_HIDDEN
;
256 extern NTSTATUS
get_thread_ldt_entry( HANDLE handle
, void *data
, ULONG len
, ULONG
*ret_len
) DECLSPEC_HIDDEN
;
257 extern void *get_native_context( CONTEXT
*context
) DECLSPEC_HIDDEN
;
258 extern void *get_wow_context( CONTEXT
*context
) DECLSPEC_HIDDEN
;
259 extern BOOL
get_thread_times( int unix_pid
, int unix_tid
, LARGE_INTEGER
*kernel_time
,
260 LARGE_INTEGER
*user_time
) DECLSPEC_HIDDEN
;
261 extern void signal_init_threading(void) DECLSPEC_HIDDEN
;
262 extern NTSTATUS
signal_alloc_thread( TEB
*teb
) DECLSPEC_HIDDEN
;
263 extern void signal_free_thread( TEB
*teb
) DECLSPEC_HIDDEN
;
264 extern void signal_init_process(void) DECLSPEC_HIDDEN
;
265 extern void DECLSPEC_NORETURN
signal_start_thread( PRTL_THREAD_START_ROUTINE entry
, void *arg
,
266 BOOL suspend
, TEB
*teb
) DECLSPEC_HIDDEN
;
267 extern void DECLSPEC_NORETURN
signal_exit_thread( int status
, void (*func
)(int), TEB
*teb
) DECLSPEC_HIDDEN
;
268 extern SYSTEM_SERVICE_TABLE KeServiceDescriptorTable
[4] DECLSPEC_HIDDEN
;
269 extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN
;
270 extern void WINAPI DECLSPEC_NORETURN
__wine_syscall_dispatcher_return( void *frame
, ULONG_PTR retval
) DECLSPEC_HIDDEN
;
271 extern void __wine_unix_call_dispatcher(void) DECLSPEC_HIDDEN
;
272 extern NTSTATUS
signal_set_full_context( CONTEXT
*context
) DECLSPEC_HIDDEN
;
273 extern NTSTATUS
get_thread_wow64_context( HANDLE handle
, void *ctx
, ULONG size
) DECLSPEC_HIDDEN
;
274 extern NTSTATUS
set_thread_wow64_context( HANDLE handle
, const void *ctx
, ULONG size
) DECLSPEC_HIDDEN
;
275 extern void fill_vm_counters( VM_COUNTERS_EX
*pvmi
, int unix_pid
) DECLSPEC_HIDDEN
;
276 extern NTSTATUS
open_hkcu_key( const char *path
, HANDLE
*key
) DECLSPEC_HIDDEN
;
278 extern NTSTATUS
cdrom_DeviceIoControl( HANDLE device
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
,
279 IO_STATUS_BLOCK
*io
, UINT code
, void *in_buffer
,
280 UINT in_size
, void *out_buffer
, UINT out_size
) DECLSPEC_HIDDEN
;
281 extern NTSTATUS
serial_DeviceIoControl( HANDLE device
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
,
282 IO_STATUS_BLOCK
*io
, UINT code
, void *in_buffer
,
283 UINT in_size
, void *out_buffer
, UINT out_size
) DECLSPEC_HIDDEN
;
284 extern NTSTATUS
serial_FlushBuffersFile( int fd
) DECLSPEC_HIDDEN
;
285 extern NTSTATUS
sock_ioctl( HANDLE handle
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
, IO_STATUS_BLOCK
*io
,
286 UINT code
, void *in_buffer
, UINT in_size
, void *out_buffer
, UINT out_size
) DECLSPEC_HIDDEN
;
287 extern NTSTATUS
sock_read( HANDLE handle
, int fd
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
,
288 IO_STATUS_BLOCK
*io
, void *buffer
, ULONG length
) DECLSPEC_HIDDEN
;
289 extern NTSTATUS
sock_write( HANDLE handle
, int fd
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
,
290 IO_STATUS_BLOCK
*io
, const void *buffer
, ULONG length
) DECLSPEC_HIDDEN
;
291 extern NTSTATUS
tape_DeviceIoControl( HANDLE device
, HANDLE event
, PIO_APC_ROUTINE apc
, void *apc_user
,
292 IO_STATUS_BLOCK
*io
, UINT code
, void *in_buffer
,
293 UINT in_size
, void *out_buffer
, UINT out_size
) DECLSPEC_HIDDEN
;
295 extern struct async_fileio
*alloc_fileio( DWORD size
, async_callback_t callback
, HANDLE handle
) DECLSPEC_HIDDEN
;
296 extern void release_fileio( struct async_fileio
*io
) DECLSPEC_HIDDEN
;
297 extern NTSTATUS
errno_to_status( int err
) DECLSPEC_HIDDEN
;
298 extern BOOL
get_redirect( OBJECT_ATTRIBUTES
*attr
, UNICODE_STRING
*redir
) DECLSPEC_HIDDEN
;
299 extern NTSTATUS
nt_to_unix_file_name( const OBJECT_ATTRIBUTES
*attr
, char **name_ret
, UINT disposition
) DECLSPEC_HIDDEN
;
300 extern NTSTATUS
unix_to_nt_file_name( const char *name
, WCHAR
**nt
) DECLSPEC_HIDDEN
;
301 extern NTSTATUS
get_full_path( const WCHAR
*name
, const WCHAR
*curdir
, WCHAR
**path
) DECLSPEC_HIDDEN
;
302 extern NTSTATUS
open_unix_file( HANDLE
*handle
, const char *unix_name
, ACCESS_MASK access
,
303 OBJECT_ATTRIBUTES
*attr
, ULONG attributes
, ULONG sharing
, ULONG disposition
,
304 ULONG options
, void *ea_buffer
, ULONG ea_length
) DECLSPEC_HIDDEN
;
305 extern NTSTATUS
get_device_info( int fd
, struct _FILE_FS_DEVICE_INFORMATION
*info
) DECLSPEC_HIDDEN
;
306 extern void init_files(void) DECLSPEC_HIDDEN
;
307 extern void init_cpu_info(void) DECLSPEC_HIDDEN
;
308 extern void add_completion( HANDLE handle
, ULONG_PTR value
, NTSTATUS status
, ULONG info
, BOOL async
) DECLSPEC_HIDDEN
;
309 extern void set_async_direct_result( HANDLE
*async_handle
, NTSTATUS status
, ULONG_PTR information
, BOOL mark_pending
) DECLSPEC_HIDDEN
;
311 extern NTSTATUS
unixcall_wine_dbg_write( void *args
) DECLSPEC_HIDDEN
;
312 extern NTSTATUS
unixcall_wine_server_call( void *args
) DECLSPEC_HIDDEN
;
313 extern NTSTATUS
unixcall_wine_server_fd_to_handle( void *args
) DECLSPEC_HIDDEN
;
314 extern NTSTATUS
unixcall_wine_server_handle_to_fd( void *args
) DECLSPEC_HIDDEN
;
315 extern NTSTATUS
unixcall_wine_spawnvp( void *args
) DECLSPEC_HIDDEN
;
317 extern NTSTATUS
wow64_wine_dbg_write( void *args
) DECLSPEC_HIDDEN
;
318 extern NTSTATUS
wow64_wine_server_call( void *args
) DECLSPEC_HIDDEN
;
319 extern NTSTATUS
wow64_wine_server_fd_to_handle( void *args
) DECLSPEC_HIDDEN
;
320 extern NTSTATUS
wow64_wine_server_handle_to_fd( void *args
) DECLSPEC_HIDDEN
;
321 extern NTSTATUS
wow64_wine_spawnvp( void *args
) DECLSPEC_HIDDEN
;
324 extern void dbg_init(void) DECLSPEC_HIDDEN
;
326 extern NTSTATUS
call_user_apc_dispatcher( CONTEXT
*context_ptr
, ULONG_PTR arg1
, ULONG_PTR arg2
, ULONG_PTR arg3
,
327 PNTAPCFUNC func
, NTSTATUS status
) DECLSPEC_HIDDEN
;
328 extern NTSTATUS
call_user_exception_dispatcher( EXCEPTION_RECORD
*rec
, CONTEXT
*context
) DECLSPEC_HIDDEN
;
329 extern void call_raise_user_exception_dispatcher(void) DECLSPEC_HIDDEN
;
331 #define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
333 #define TICKSPERSEC 10000000
334 #define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)86400)
336 static inline ULONGLONG
ticks_from_time_t( time_t time
)
338 if (sizeof(time_t) == sizeof(int)) /* time_t may be signed */
339 return ((ULONGLONG
)(ULONG
)time
+ SECS_1601_TO_1970
) * TICKSPERSEC
;
341 return ((ULONGLONG
)time
+ SECS_1601_TO_1970
) * TICKSPERSEC
;
344 static inline const char *debugstr_us( const UNICODE_STRING
*us
)
346 if (!us
) return "<null>";
347 return debugstr_wn( us
->Buffer
, us
->Length
/ sizeof(WCHAR
) );
350 /* convert from straight ASCII to Unicode without depending on the current codepage */
351 static inline void ascii_to_unicode( WCHAR
*dst
, const char *src
, size_t len
)
353 while (len
--) *dst
++ = (unsigned char)*src
++;
356 static inline void *get_signal_stack(void)
358 return (void *)(((ULONG_PTR
)NtCurrentTeb() & ~signal_stack_mask
) + teb_size
);
361 static inline BOOL
is_inside_signal_stack( void *ptr
)
363 return ((char *)ptr
>= (char *)get_signal_stack() &&
364 (char *)ptr
< (char *)get_signal_stack() + signal_stack_size
);
367 static inline void mutex_lock( pthread_mutex_t
*mutex
)
369 if (!process_exiting
) pthread_mutex_lock( mutex
);
372 static inline void mutex_unlock( pthread_mutex_t
*mutex
)
374 if (!process_exiting
) pthread_mutex_unlock( mutex
);
377 static inline async_data_t
server_async( HANDLE handle
, struct async_fileio
*user
, HANDLE event
,
378 PIO_APC_ROUTINE apc
, void *apc_context
, client_ptr_t iosb
)
381 async
.handle
= wine_server_obj_handle( handle
);
382 async
.user
= wine_server_client_ptr( user
);
384 async
.event
= wine_server_obj_handle( event
);
385 async
.apc
= wine_server_client_ptr( apc
);
386 async
.apc_context
= wine_server_client_ptr( apc_context
);
390 static inline NTSTATUS
wait_async( HANDLE handle
, BOOL alertable
)
392 return NtWaitForSingleObject( handle
, alertable
, NULL
);
395 static inline BOOL
in_wow64_call(void)
397 return is_win64
&& is_wow64();
400 static inline void set_async_iosb( client_ptr_t iosb
, NTSTATUS status
, ULONG_PTR info
)
404 /* GetOverlappedResult() and WSAGetOverlappedResult() expect that if the
405 * status is written, that the information (and buffer, which was written
406 * earlier from the async callback) will be available. Hence we need to
407 * store the status last, with release semantics to ensure that those
408 * writes are visible. This release is paired with a read-acquire in
409 * GetOverlappedResult() and WSAGetOverlappedResult():
411 * CPU 0 (set_async_iosb) CPU 1 (GetOverlappedResultEx)
412 * =========================== ===========================
415 * WriteRelease(Status) <--------.
418 * (paired with) `-> ReadAcquire(Status)
428 } *io
= wine_server_get_ptr( iosb
);
429 io
->Information
= info
;
430 WriteRelease( &io
->Status
, status
);
434 IO_STATUS_BLOCK
*io
= wine_server_get_ptr( iosb
);
435 io
->Information
= info
;
436 WriteRelease( &io
->Status
, status
);
440 static inline client_ptr_t
iosb_client_ptr( IO_STATUS_BLOCK
*io
)
442 if (io
&& in_wow64_call()) return wine_server_client_ptr( io
->Pointer
);
443 return wine_server_client_ptr( io
);
446 static inline ULONG_PTR
get_zero_bits_limit( ULONG_PTR zero_bits
)
450 if (zero_bits
== 0) return 0;
452 if (zero_bits
< 32) shift
= 32 + zero_bits
;
457 if (zero_bits
>> 32) { shift
-= 32; zero_bits
>>= 32; }
459 if (zero_bits
>> 16) { shift
-= 16; zero_bits
>>= 16; }
460 if (zero_bits
>> 8) { shift
-= 8; zero_bits
>>= 8; }
461 if (zero_bits
>> 4) { shift
-= 4; zero_bits
>>= 4; }
462 if (zero_bits
>> 2) { shift
-= 2; zero_bits
>>= 2; }
463 if (zero_bits
>> 1) { shift
-= 1; }
465 return (~(UINT64
)0) >> shift
;
475 LO_NATIVE_BUILTIN
, /* native then builtin */
476 LO_BUILTIN_NATIVE
, /* builtin then native */
477 LO_DEFAULT
/* nothing specified, use default strategy */
480 extern void set_load_order_app_name( const WCHAR
*app_name
) DECLSPEC_HIDDEN
;
481 extern enum loadorder
get_load_order( const UNICODE_STRING
*nt_name
) DECLSPEC_HIDDEN
;
483 static inline WCHAR
ntdll_towupper( WCHAR ch
)
485 return ch
+ uctable
[uctable
[uctable
[ch
>> 8] + ((ch
>> 4) & 0x0f)] + (ch
& 0x0f)];
488 static inline WCHAR
ntdll_towlower( WCHAR ch
)
490 return ch
+ lctable
[lctable
[lctable
[ch
>> 8] + ((ch
>> 4) & 0x0f)] + (ch
& 0x0f)];
493 static inline WCHAR
*ntdll_wcsupr( WCHAR
*str
)
496 for (ret
= str
; *str
; str
++) *str
= ntdll_towupper(*str
);
500 #define wcsupr(str) ntdll_wcsupr(str)
501 #define towupper(c) ntdll_towupper(c)
502 #define towlower(c) ntdll_towlower(c)
504 static inline void init_unicode_string( UNICODE_STRING
*str
, const WCHAR
*data
)
506 str
->Length
= wcslen(data
) * sizeof(WCHAR
);
507 str
->MaximumLength
= str
->Length
+ sizeof(WCHAR
);
508 str
->Buffer
= (WCHAR
*)data
;
511 static inline NTSTATUS
map_section( HANDLE mapping
, void **ptr
, SIZE_T
*size
, ULONG protect
)
515 return NtMapViewOfSection( mapping
, NtCurrentProcess(), ptr
, is_win64
&& wow_peb
? 0x7fffffff : 0,
516 0, NULL
, size
, ViewShare
, 0, protect
);
519 #endif /* __NTDLL_UNIX_PRIVATE_H */