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
24 #include "../ntdll/ntsyscalls.h"
27 #define SYSCALL_ENTRY(id,name,_args) extern NTSTATUS WINAPI wow64_ ## name( UINT *args );
31 extern void init_image_mapping( HMODULE module
);
32 extern void init_file_redirects(void);
33 extern BOOL
get_file_redirect( OBJECT_ATTRIBUTES
*attr
);
35 extern USHORT native_machine
;
36 extern USHORT current_machine
;
37 extern ULONG_PTR args_alignment
;
38 extern ULONG_PTR highest_user_address
;
39 extern ULONG_PTR default_zero_bits
;
40 extern SYSTEM_DLL_INIT_BLOCK
*pLdrSystemDllInitBlock
;
42 extern void (WINAPI
*pBTCpuNotifyFlushInstructionCache2
)( const void *, SIZE_T
);
43 extern void (WINAPI
*pBTCpuNotifyMapViewOfSection
)( void * );
44 extern void (WINAPI
*pBTCpuNotifyMemoryAlloc
)( void *, SIZE_T
, ULONG
, ULONG
);
45 extern void (WINAPI
*pBTCpuNotifyMemoryDirty
)( void *, SIZE_T
);
46 extern void (WINAPI
*pBTCpuNotifyMemoryFree
)( void *, SIZE_T
, ULONG
);
47 extern void (WINAPI
*pBTCpuNotifyMemoryProtect
)( void *, SIZE_T
, ULONG
);
48 extern void (WINAPI
*pBTCpuNotifyUnmapViewOfSection
)( void * );
49 extern void (WINAPI
*pBTCpuUpdateProcessorInformation
)( SYSTEM_CPU_INFORMATION
* );
50 extern void (WINAPI
*pBTCpuThreadTerm
)( HANDLE
);
54 OBJECT_ATTRIBUTES attr
;
56 SECURITY_DESCRIPTOR sd
;
59 /* cf. GetSystemWow64Directory2 */
60 static inline const WCHAR
*get_machine_wow64_dir( USHORT machine
)
64 case IMAGE_FILE_MACHINE_TARGET_HOST
: return L
"\\??\\C:\\windows\\system32";
65 case IMAGE_FILE_MACHINE_I386
: return L
"\\??\\C:\\windows\\syswow64";
66 case IMAGE_FILE_MACHINE_ARMNT
: return L
"\\??\\C:\\windows\\sysarm32";
71 static inline ULONG
get_ulong( UINT
**args
) { return *(*args
)++; }
72 static inline HANDLE
get_handle( UINT
**args
) { return LongToHandle( *(*args
)++ ); }
73 static inline void *get_ptr( UINT
**args
) { return ULongToPtr( *(*args
)++ ); }
75 static inline ULONG64
get_ulong64( UINT
**args
)
79 *args
= (UINT
*)(((ULONG_PTR
)*args
+ args_alignment
- 1) & ~(args_alignment
- 1));
80 ret
= *(ULONG64
*)*args
;
85 static inline ULONG_PTR
get_zero_bits( ULONG_PTR zero_bits
)
87 return zero_bits
? zero_bits
: default_zero_bits
;
90 static inline void **addr_32to64( void **addr
, ULONG
*addr32
)
92 if (!addr32
) return NULL
;
93 *addr
= ULongToPtr( *addr32
);
97 static inline SIZE_T
*size_32to64( SIZE_T
*size
, ULONG
*size32
)
99 if (!size32
) return NULL
;
104 static inline void *apc_32to64( ULONG func
)
106 return func
? Wow64ApcRoutine
: NULL
;
109 static inline void *apc_param_32to64( ULONG func
, ULONG context
)
111 if (!func
) return ULongToPtr( context
);
112 return (void *)(ULONG_PTR
)(((ULONG64
)func
<< 32) | context
);
115 static inline IO_STATUS_BLOCK
*iosb_32to64( IO_STATUS_BLOCK
*io
, IO_STATUS_BLOCK32
*io32
)
117 if (!io32
) return NULL
;
122 static inline UNICODE_STRING
*unicode_str_32to64( UNICODE_STRING
*str
, const UNICODE_STRING32
*str32
)
124 if (!str32
) return NULL
;
125 str
->Length
= str32
->Length
;
126 str
->MaximumLength
= str32
->MaximumLength
;
127 str
->Buffer
= ULongToPtr( str32
->Buffer
);
131 static inline CLIENT_ID
*client_id_32to64( CLIENT_ID
*id
, const CLIENT_ID32
*id32
)
133 if (!id32
) return NULL
;
134 id
->UniqueProcess
= LongToHandle( id32
->UniqueProcess
);
135 id
->UniqueThread
= LongToHandle( id32
->UniqueThread
);
139 static inline SECURITY_DESCRIPTOR
*secdesc_32to64( SECURITY_DESCRIPTOR
*out
, const SECURITY_DESCRIPTOR
*in
)
141 /* relative descr has the same layout for 32 and 64 */
142 const SECURITY_DESCRIPTOR_RELATIVE
*sd
= (const SECURITY_DESCRIPTOR_RELATIVE
*)in
;
144 if (!in
) return NULL
;
145 out
->Revision
= sd
->Revision
;
146 out
->Sbz1
= sd
->Sbz1
;
147 out
->Control
= sd
->Control
& ~SE_SELF_RELATIVE
;
148 if (sd
->Control
& SE_SELF_RELATIVE
)
150 out
->Owner
= sd
->Owner
? (PSID
)((BYTE
*)sd
+ sd
->Owner
) : NULL
;
151 out
->Group
= sd
->Group
? (PSID
)((BYTE
*)sd
+ sd
->Group
) : NULL
;
152 out
->Sacl
= ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
) ? (PSID
)((BYTE
*)sd
+ sd
->Sacl
) : NULL
;
153 out
->Dacl
= ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
) ? (PSID
)((BYTE
*)sd
+ sd
->Dacl
) : NULL
;
157 out
->Owner
= ULongToPtr( sd
->Owner
);
158 out
->Group
= ULongToPtr( sd
->Group
);
159 out
->Sacl
= (sd
->Control
& SE_SACL_PRESENT
) ? ULongToPtr( sd
->Sacl
) : NULL
;
160 out
->Dacl
= (sd
->Control
& SE_DACL_PRESENT
) ? ULongToPtr( sd
->Dacl
) : NULL
;
165 static inline OBJECT_ATTRIBUTES
*objattr_32to64( struct object_attr64
*out
, const OBJECT_ATTRIBUTES32
*in
)
167 memset( out
, 0, sizeof(*out
) );
168 if (!in
) return NULL
;
169 if (in
->Length
!= sizeof(*in
)) return &out
->attr
;
171 out
->attr
.Length
= sizeof(out
->attr
);
172 out
->attr
.RootDirectory
= LongToHandle( in
->RootDirectory
);
173 out
->attr
.Attributes
= in
->Attributes
;
174 out
->attr
.ObjectName
= unicode_str_32to64( &out
->str
, ULongToPtr( in
->ObjectName
));
175 out
->attr
.SecurityQualityOfService
= ULongToPtr( in
->SecurityQualityOfService
);
176 out
->attr
.SecurityDescriptor
= secdesc_32to64( &out
->sd
, ULongToPtr( in
->SecurityDescriptor
));
180 static inline OBJECT_ATTRIBUTES
*objattr_32to64_redirect( struct object_attr64
*out
,
181 const OBJECT_ATTRIBUTES32
*in
)
183 OBJECT_ATTRIBUTES
*attr
= objattr_32to64( out
, in
);
185 if (attr
) get_file_redirect( attr
);
189 static inline TOKEN_USER
*token_user_32to64( TOKEN_USER
*out
, const TOKEN_USER32
*in
)
191 out
->User
.Sid
= ULongToPtr( in
->User
.Sid
);
192 out
->User
.Attributes
= in
->User
.Attributes
;
196 static inline TOKEN_OWNER
*token_owner_32to64( TOKEN_OWNER
*out
, const TOKEN_OWNER32
*in
)
198 out
->Owner
= ULongToPtr( in
->Owner
);
202 static inline TOKEN_PRIMARY_GROUP
*token_primary_group_32to64( TOKEN_PRIMARY_GROUP
*out
, const TOKEN_PRIMARY_GROUP32
*in
)
204 out
->PrimaryGroup
= ULongToPtr( in
->PrimaryGroup
);
208 static inline TOKEN_DEFAULT_DACL
*token_default_dacl_32to64( TOKEN_DEFAULT_DACL
*out
, const TOKEN_DEFAULT_DACL32
*in
)
210 out
->DefaultDacl
= ULongToPtr( in
->DefaultDacl
);
214 static inline void put_handle( ULONG
*handle32
, HANDLE handle
)
216 *handle32
= HandleToULong( handle
);
219 static inline void put_addr( ULONG
*addr32
, void *addr
)
221 if (addr32
) *addr32
= PtrToUlong( addr
);
224 static inline void put_size( ULONG
*size32
, SIZE_T size
)
226 if (size32
) *size32
= min( size
, MAXDWORD
);
229 static inline void put_client_id( CLIENT_ID32
*id32
, const CLIENT_ID
*id
)
232 id32
->UniqueProcess
= HandleToLong( id
->UniqueProcess
);
233 id32
->UniqueThread
= HandleToLong( id
->UniqueThread
);
236 static inline void put_iosb( IO_STATUS_BLOCK32
*io32
, const IO_STATUS_BLOCK
*io
)
238 /* sync I/O modifies the 64-bit iosb right away, so in that case we update the 32-bit one */
239 /* async I/O leaves the 64-bit one untouched and updates the 32-bit one directly later on */
240 if (io32
&& io
->Pointer
!= io32
)
242 io32
->Status
= io
->Status
;
243 io32
->Information
= io
->Information
;
247 extern void put_section_image_info( SECTION_IMAGE_INFORMATION32
*info32
,
248 const SECTION_IMAGE_INFORMATION
*info
);
249 extern void put_vm_counters( VM_COUNTERS_EX32
*info32
, const VM_COUNTERS_EX
*info
,
252 #endif /* __WOW64_PRIVATE_H */