2 * WoW64 private definitions
4 * Copyright 2021 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 __WOW64_PRIVATE_H
22 #define __WOW64_PRIVATE_H
27 #define SYSCALL_ENTRY(func) extern NTSTATUS WINAPI wow64_ ## func( UINT *args ) DECLSPEC_HIDDEN;
31 void * WINAPI
Wow64AllocateTemp( SIZE_T size
);
32 void WINAPI
Wow64ApcRoutine( ULONG_PTR arg1
, ULONG_PTR arg2
, ULONG_PTR arg3
, CONTEXT
*context
);
33 void WINAPI
Wow64PassExceptionToGuest( EXCEPTION_POINTERS
*ptrs
);
35 extern void init_image_mapping( HMODULE module
) DECLSPEC_HIDDEN
;
36 extern void init_file_redirects(void) DECLSPEC_HIDDEN
;
37 extern BOOL
get_file_redirect( OBJECT_ATTRIBUTES
*attr
) DECLSPEC_HIDDEN
;
39 extern USHORT native_machine DECLSPEC_HIDDEN
;
40 extern USHORT current_machine DECLSPEC_HIDDEN
;
41 extern ULONG_PTR args_alignment DECLSPEC_HIDDEN
;
42 extern ULONG_PTR highest_user_address DECLSPEC_HIDDEN
;
43 extern ULONG_PTR default_zero_bits DECLSPEC_HIDDEN
;
44 extern SYSTEM_DLL_INIT_BLOCK
*pLdrSystemDllInitBlock DECLSPEC_HIDDEN
;
48 OBJECT_ATTRIBUTES attr
;
50 SECURITY_DESCRIPTOR sd
;
53 static inline void *get_rva( HMODULE module
, DWORD va
)
55 return (void *)((char *)module
+ va
);
58 /* cf. GetSystemWow64Directory2 */
59 static inline const WCHAR
*get_machine_wow64_dir( USHORT machine
)
63 case IMAGE_FILE_MACHINE_TARGET_HOST
: return L
"\\??\\C:\\windows\\system32";
64 case IMAGE_FILE_MACHINE_I386
: return L
"\\??\\C:\\windows\\syswow64";
65 case IMAGE_FILE_MACHINE_ARMNT
: return L
"\\??\\C:\\windows\\sysarm32";
66 case IMAGE_FILE_MACHINE_AMD64
: return L
"\\??\\C:\\windows\\sysx8664";
67 case IMAGE_FILE_MACHINE_ARM64
: return L
"\\??\\C:\\windows\\sysarm64";
72 static inline ULONG
get_ulong( UINT
**args
) { return *(*args
)++; }
73 static inline HANDLE
get_handle( UINT
**args
) { return LongToHandle( *(*args
)++ ); }
74 static inline void *get_ptr( UINT
**args
) { return ULongToPtr( *(*args
)++ ); }
76 static inline ULONG64
get_ulong64( UINT
**args
)
80 *args
= (UINT
*)(((ULONG_PTR
)*args
+ args_alignment
- 1) & ~(args_alignment
- 1));
81 ret
= *(ULONG64
*)*args
;
86 static inline ULONG_PTR
get_zero_bits( ULONG_PTR zero_bits
)
88 return zero_bits
? zero_bits
: default_zero_bits
;
91 static inline void **addr_32to64( void **addr
, ULONG
*addr32
)
93 if (!addr32
) return NULL
;
94 *addr
= ULongToPtr( *addr32
);
98 static inline SIZE_T
*size_32to64( SIZE_T
*size
, ULONG
*size32
)
100 if (!size32
) return NULL
;
105 static inline void *apc_32to64( ULONG func
)
107 return func
? Wow64ApcRoutine
: NULL
;
110 static inline void *apc_param_32to64( ULONG func
, ULONG context
)
112 if (!func
) return ULongToPtr( context
);
113 return (void *)(ULONG_PTR
)(((ULONG64
)func
<< 32) | context
);
116 static inline IO_STATUS_BLOCK
*iosb_32to64( IO_STATUS_BLOCK
*io
, IO_STATUS_BLOCK32
*io32
)
118 if (!io32
) return NULL
;
123 static inline UNICODE_STRING
*unicode_str_32to64( UNICODE_STRING
*str
, const UNICODE_STRING32
*str32
)
125 if (!str32
) return NULL
;
126 str
->Length
= str32
->Length
;
127 str
->MaximumLength
= str32
->MaximumLength
;
128 str
->Buffer
= ULongToPtr( str32
->Buffer
);
132 static inline CLIENT_ID
*client_id_32to64( CLIENT_ID
*id
, const CLIENT_ID32
*id32
)
134 if (!id32
) return NULL
;
135 id
->UniqueProcess
= LongToHandle( id32
->UniqueProcess
);
136 id
->UniqueThread
= LongToHandle( id32
->UniqueThread
);
140 static inline SECURITY_DESCRIPTOR
*secdesc_32to64( SECURITY_DESCRIPTOR
*out
, const SECURITY_DESCRIPTOR
*in
)
142 /* relative descr has the same layout for 32 and 64 */
143 const SECURITY_DESCRIPTOR_RELATIVE
*sd
= (const SECURITY_DESCRIPTOR_RELATIVE
*)in
;
145 if (!in
) return NULL
;
146 out
->Revision
= sd
->Revision
;
147 out
->Sbz1
= sd
->Sbz1
;
148 out
->Control
= sd
->Control
& ~SE_SELF_RELATIVE
;
149 if (sd
->Control
& SE_SELF_RELATIVE
)
151 out
->Owner
= sd
->Owner
? (PSID
)((BYTE
*)sd
+ sd
->Owner
) : NULL
;
152 out
->Group
= sd
->Group
? (PSID
)((BYTE
*)sd
+ sd
->Group
) : NULL
;
153 out
->Sacl
= ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
) ? (PSID
)((BYTE
*)sd
+ sd
->Sacl
) : NULL
;
154 out
->Dacl
= ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
) ? (PSID
)((BYTE
*)sd
+ sd
->Dacl
) : NULL
;
158 out
->Owner
= ULongToPtr( sd
->Owner
);
159 out
->Group
= ULongToPtr( sd
->Group
);
160 out
->Sacl
= (sd
->Control
& SE_SACL_PRESENT
) ? ULongToPtr( sd
->Sacl
) : NULL
;
161 out
->Dacl
= (sd
->Control
& SE_DACL_PRESENT
) ? ULongToPtr( sd
->Dacl
) : NULL
;
166 static inline OBJECT_ATTRIBUTES
*objattr_32to64( struct object_attr64
*out
, const OBJECT_ATTRIBUTES32
*in
)
168 memset( out
, 0, sizeof(*out
) );
169 if (!in
) return NULL
;
170 if (in
->Length
!= sizeof(*in
)) return &out
->attr
;
172 out
->attr
.Length
= sizeof(out
->attr
);
173 out
->attr
.RootDirectory
= LongToHandle( in
->RootDirectory
);
174 out
->attr
.Attributes
= in
->Attributes
;
175 out
->attr
.ObjectName
= unicode_str_32to64( &out
->str
, ULongToPtr( in
->ObjectName
));
176 out
->attr
.SecurityQualityOfService
= ULongToPtr( in
->SecurityQualityOfService
);
177 out
->attr
.SecurityDescriptor
= secdesc_32to64( &out
->sd
, ULongToPtr( in
->SecurityDescriptor
));
181 static inline OBJECT_ATTRIBUTES
*objattr_32to64_redirect( struct object_attr64
*out
,
182 const OBJECT_ATTRIBUTES32
*in
)
184 OBJECT_ATTRIBUTES
*attr
= objattr_32to64( out
, in
);
186 if (attr
) get_file_redirect( attr
);
190 static inline void put_handle( ULONG
*handle32
, HANDLE handle
)
192 *handle32
= HandleToULong( handle
);
195 static inline void put_addr( ULONG
*addr32
, void *addr
)
197 if (addr32
) *addr32
= PtrToUlong( addr
);
200 static inline void put_size( ULONG
*size32
, SIZE_T size
)
202 if (size32
) *size32
= min( size
, MAXDWORD
);
205 static inline void put_client_id( CLIENT_ID32
*id32
, const CLIENT_ID
*id
)
208 id32
->UniqueProcess
= HandleToLong( id
->UniqueProcess
);
209 id32
->UniqueThread
= HandleToLong( id
->UniqueThread
);
212 static inline void put_iosb( IO_STATUS_BLOCK32
*io32
, const IO_STATUS_BLOCK
*io
)
214 /* sync I/O modifies the 64-bit iosb right away, so in that case we update the 32-bit one */
215 /* async I/O leaves the 64-bit one untouched and updates the 32-bit one directly later on */
216 if (io32
&& io
->Pointer
!= io32
)
218 io32
->Status
= io
->Status
;
219 io32
->Information
= io
->Information
;
223 extern void put_section_image_info( SECTION_IMAGE_INFORMATION32
*info32
,
224 const SECTION_IMAGE_INFORMATION
*info
) DECLSPEC_HIDDEN
;
225 extern void put_vm_counters( VM_COUNTERS_EX32
*info32
, const VM_COUNTERS_EX
*info
,
226 ULONG size
) DECLSPEC_HIDDEN
;
228 #endif /* __WOW64_PRIVATE_H */