2 * WoW64 virtual memory functions
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
24 #define WIN32_NO_STATUS
30 #include "wow64_private.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(wow
);
36 /**********************************************************************
37 * wow64_NtAllocateVirtualMemory
39 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemory( UINT
*args
)
41 HANDLE process
= get_handle( &args
);
42 ULONG
*addr32
= get_ptr( &args
);
43 ULONG_PTR zero_bits
= get_ulong( &args
);
44 ULONG
*size32
= get_ptr( &args
);
45 ULONG type
= get_ulong( &args
);
46 ULONG protect
= get_ulong( &args
);
52 status
= NtAllocateVirtualMemory( process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
53 size_32to64( &size
, size32
), type
, protect
);
56 put_addr( addr32
, addr
);
57 put_size( size32
, size
);
63 /**********************************************************************
64 * wow64_NtAllocateVirtualMemoryEx
66 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemoryEx( UINT
*args
)
68 HANDLE process
= get_handle( &args
);
69 ULONG
*addr32
= get_ptr( &args
);
70 ULONG
*size32
= get_ptr( &args
);
71 ULONG type
= get_ulong( &args
);
72 ULONG protect
= get_ulong( &args
);
73 MEM_EXTENDED_PARAMETER
*params
= get_ptr( &args
);
74 ULONG count
= get_ulong( &args
);
80 if (count
) FIXME( "%d extended parameters %p\n", count
, params
);
81 status
= NtAllocateVirtualMemoryEx( process
, addr_32to64( &addr
, addr32
), size_32to64( &size
, size32
),
82 type
, protect
, params
, count
);
85 put_addr( addr32
, addr
);
86 put_size( size32
, size
);
92 /**********************************************************************
93 * wow64_NtAreMappedFilesTheSame
95 NTSTATUS WINAPI
wow64_NtAreMappedFilesTheSame( UINT
*args
)
97 void *ptr1
= get_ptr( &args
);
98 void *ptr2
= get_ptr( &args
);
100 return NtAreMappedFilesTheSame( ptr1
, ptr2
);
104 /**********************************************************************
105 * wow64_NtFlushVirtualMemory
107 NTSTATUS WINAPI
wow64_NtFlushVirtualMemory( UINT
*args
)
109 HANDLE process
= get_handle( &args
);
110 ULONG
*addr32
= get_ptr( &args
);
111 ULONG
*size32
= get_ptr( &args
);
112 ULONG unknown
= get_ulong( &args
);
118 status
= NtFlushVirtualMemory( process
, (const void **)addr_32to64( &addr
, addr32
),
119 size_32to64( &size
, size32
), unknown
);
122 put_addr( addr32
, addr
);
123 put_size( size32
, size
);
129 /**********************************************************************
130 * wow64_NtFreeVirtualMemory
132 NTSTATUS WINAPI
wow64_NtFreeVirtualMemory( UINT
*args
)
134 HANDLE process
= get_handle( &args
);
135 ULONG
*addr32
= get_ptr( &args
);
136 ULONG
*size32
= get_ptr( &args
);
137 ULONG type
= get_ulong( &args
);
143 status
= NtFreeVirtualMemory( process
, addr_32to64( &addr
, addr32
),
144 size_32to64( &size
, size32
), type
);
147 put_addr( addr32
, addr
);
148 put_size( size32
, size
);
154 /**********************************************************************
155 * wow64_NtGetNlsSectionPtr
157 NTSTATUS WINAPI
wow64_NtGetNlsSectionPtr( UINT
*args
)
159 ULONG type
= get_ulong( &args
);
160 ULONG id
= get_ulong( &args
);
161 void *unknown
= get_ptr( &args
);
162 ULONG
*addr32
= get_ptr( &args
);
163 ULONG
*size32
= get_ptr( &args
);
169 status
= NtGetNlsSectionPtr( type
, id
, unknown
, addr_32to64( &addr
, addr32
),
170 size_32to64( &size
, size32
));
173 put_addr( addr32
, addr
);
174 put_size( size32
, size
);
180 /**********************************************************************
181 * wow64_NtGetWriteWatch
183 NTSTATUS WINAPI
wow64_NtGetWriteWatch( UINT
*args
)
185 HANDLE handle
= get_handle( &args
);
186 ULONG flags
= get_ulong( &args
);
187 void *base
= get_ptr( &args
);
188 SIZE_T size
= get_ulong( &args
);
189 ULONG
*addr_ptr
= get_ptr( &args
);
190 ULONG
*count_ptr
= get_ptr( &args
);
191 ULONG
*granularity
= get_ptr( &args
);
193 ULONG_PTR i
, count
= *count_ptr
;
197 if (!count
|| !size
) return STATUS_INVALID_PARAMETER
;
198 if (flags
& ~WRITE_WATCH_FLAG_RESET
) return STATUS_INVALID_PARAMETER
;
199 if (!addr_ptr
) return STATUS_ACCESS_VIOLATION
;
201 addresses
= RtlAllocateHeap( GetProcessHeap(), 0, count
* sizeof(*addresses
) );
202 if (!(status
= NtGetWriteWatch( handle
, flags
, base
, size
, addresses
, &count
, granularity
)))
204 for (i
= 0; i
< count
; i
++) addr_ptr
[i
] = PtrToUlong( addresses
[i
] );
207 RtlFreeHeap( GetProcessHeap(), 0, addresses
);
212 /**********************************************************************
213 * wow64_NtLockVirtualMemory
215 NTSTATUS WINAPI
wow64_NtLockVirtualMemory( UINT
*args
)
217 HANDLE process
= get_handle( &args
);
218 ULONG
*addr32
= get_ptr( &args
);
219 ULONG
*size32
= get_ptr( &args
);
220 ULONG unknown
= get_ulong( &args
);
226 status
= NtLockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
227 size_32to64( &size
, size32
), unknown
);
230 put_addr( addr32
, addr
);
231 put_size( size32
, size
);
237 /**********************************************************************
238 * wow64_NtMapViewOfSection
240 NTSTATUS WINAPI
wow64_NtMapViewOfSection( UINT
*args
)
242 HANDLE handle
= get_handle( &args
);
243 HANDLE process
= get_handle( &args
);
244 ULONG
*addr32
= get_ptr( &args
);
245 ULONG_PTR zero_bits
= get_ulong( &args
);
246 SIZE_T commit
= get_ulong( &args
);
247 const LARGE_INTEGER
*offset
= get_ptr( &args
);
248 ULONG
*size32
= get_ptr( &args
);
249 SECTION_INHERIT inherit
= get_ulong( &args
);
250 ULONG alloc
= get_ulong( &args
);
251 ULONG protect
= get_ulong( &args
);
257 status
= NtMapViewOfSection( handle
, process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
258 commit
, offset
, size_32to64( &size
, size32
), inherit
, alloc
, protect
);
259 if (NT_SUCCESS(status
))
261 put_addr( addr32
, addr
);
262 put_size( size32
, size
);
268 /**********************************************************************
269 * wow64_NtProtectVirtualMemory
271 NTSTATUS WINAPI
wow64_NtProtectVirtualMemory( UINT
*args
)
273 HANDLE process
= get_handle( &args
);
274 ULONG
*addr32
= get_ptr( &args
);
275 ULONG
*size32
= get_ptr( &args
);
276 ULONG new_prot
= get_ulong( &args
);
277 ULONG
*old_prot
= get_ptr( &args
);
283 status
= NtProtectVirtualMemory( process
, addr_32to64( &addr
, addr32
),
284 size_32to64( &size
, size32
), new_prot
, old_prot
);
287 put_addr( addr32
, addr
);
288 put_size( size32
, size
);
294 /**********************************************************************
295 * wow64_NtQueryVirtualMemory
297 NTSTATUS WINAPI
wow64_NtQueryVirtualMemory( UINT
*args
)
299 HANDLE handle
= get_handle( &args
);
300 void *addr
= get_ptr( &args
);
301 MEMORY_INFORMATION_CLASS
class = get_ulong( &args
);
302 void *ptr
= get_ptr( &args
);
303 ULONG len
= get_ulong( &args
);
304 ULONG
*retlen
= get_ptr( &args
);
311 case MemoryBasicInformation
: /* MEMORY_BASIC_INFORMATION */
312 if (len
>= sizeof(MEMORY_BASIC_INFORMATION32
))
314 MEMORY_BASIC_INFORMATION info
;
315 MEMORY_BASIC_INFORMATION32
*info32
= ptr
;
317 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
319 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
320 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
321 info32
->AllocationProtect
= info
.AllocationProtect
;
322 info32
->RegionSize
= info
.RegionSize
;
323 info32
->State
= info
.State
;
324 info32
->Protect
= info
.Protect
;
325 info32
->Type
= info
.Type
;
328 else status
= STATUS_INFO_LENGTH_MISMATCH
;
329 res_len
= sizeof(MEMORY_BASIC_INFORMATION32
);
332 case MemorySectionName
: /* MEMORY_SECTION_NAME */
334 MEMORY_SECTION_NAME
*info
;
335 MEMORY_SECTION_NAME32
*info32
= ptr
;
336 SIZE_T size
= len
+ sizeof(*info
) - sizeof(*info32
);
338 info
= RtlAllocateHeap( GetProcessHeap(), 0, size
);
339 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, size
, &res_len
)))
341 info32
->SectionFileName
.Length
= info
->SectionFileName
.Length
;
342 info32
->SectionFileName
.MaximumLength
= info
->SectionFileName
.MaximumLength
;
343 info32
->SectionFileName
.Buffer
= PtrToUlong( info32
+ 1 );
344 memcpy( info32
+ 1, info
->SectionFileName
.Buffer
, info
->SectionFileName
.MaximumLength
);
346 res_len
+= sizeof(*info32
) - sizeof(*info
);
350 case MemoryWorkingSetExInformation
: /* MEMORY_WORKING_SET_EX_INFORMATION */
352 MEMORY_WORKING_SET_EX_INFORMATION32
*info32
= ptr
;
353 MEMORY_WORKING_SET_EX_INFORMATION
*info
;
354 ULONG i
, count
= len
/ sizeof(*info32
);
356 info
= RtlAllocateHeap( GetProcessHeap(), 0, count
* sizeof(*info
) );
357 for (i
= 0; i
< count
; i
++) info
[i
].VirtualAddress
= ULongToPtr( info32
[i
].VirtualAddress
);
358 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, count
* sizeof(*info
), &res_len
)))
360 count
= res_len
/ sizeof(*info
);
361 for (i
= 0; i
< count
; i
++) info32
[i
].VirtualAttributes
.Flags
= info
[i
].VirtualAttributes
.Flags
;
362 res_len
= count
* sizeof(*info32
);
368 FIXME( "unsupported class %u\n", class );
369 return STATUS_INVALID_INFO_CLASS
;
371 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
) put_size( retlen
, res_len
);
376 /**********************************************************************
377 * wow64_NtReadVirtualMemory
379 NTSTATUS WINAPI
wow64_NtReadVirtualMemory( UINT
*args
)
381 HANDLE process
= get_handle( &args
);
382 const void *addr
= get_ptr( &args
);
383 void *buffer
= get_ptr( &args
);
384 SIZE_T size
= get_ulong( &args
);
385 ULONG
*retlen
= get_ptr( &args
);
390 status
= NtReadVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
391 put_size( retlen
, ret_size
);
396 /**********************************************************************
397 * wow64_NtResetWriteWatch
399 NTSTATUS WINAPI
wow64_NtResetWriteWatch( UINT
*args
)
401 HANDLE process
= get_handle( &args
);
402 void *base
= get_ptr( &args
);
403 SIZE_T size
= get_ulong( &args
);
405 return NtResetWriteWatch( process
, base
, size
);
409 /**********************************************************************
410 * wow64_NtUnlockVirtualMemory
412 NTSTATUS WINAPI
wow64_NtUnlockVirtualMemory( UINT
*args
)
414 HANDLE process
= get_handle( &args
);
415 ULONG
*addr32
= get_ptr( &args
);
416 ULONG
*size32
= get_ptr( &args
);
417 ULONG unknown
= get_ulong( &args
);
423 status
= NtUnlockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
424 size_32to64( &size
, size32
), unknown
);
427 put_addr( addr32
, addr
);
428 put_size( size32
, size
);
434 /**********************************************************************
435 * wow64_NtUnmapViewOfSection
437 NTSTATUS WINAPI
wow64_NtUnmapViewOfSection( UINT
*args
)
439 HANDLE process
= get_handle( &args
);
440 void *addr
= get_ptr( &args
);
442 return NtUnmapViewOfSection( process
, addr
);
446 /**********************************************************************
447 * wow64_NtWow64AllocateVirtualMemory64
449 NTSTATUS WINAPI
wow64_NtWow64AllocateVirtualMemory64( UINT
*args
)
451 HANDLE process
= get_handle( &args
);
452 void **addr
= get_ptr( &args
);
453 ULONG_PTR zero_bits
= get_ulong64( &args
);
454 SIZE_T
*size
= get_ptr( &args
);
455 ULONG type
= get_ulong( &args
);
456 ULONG protect
= get_ulong( &args
);
458 return NtAllocateVirtualMemory( process
, addr
, zero_bits
, size
, type
, protect
);
462 /**********************************************************************
463 * wow64_NtWow64ReadVirtualMemory64
465 NTSTATUS WINAPI
wow64_NtWow64ReadVirtualMemory64( UINT
*args
)
467 HANDLE process
= get_handle( &args
);
468 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
469 void *buffer
= get_ptr( &args
);
470 SIZE_T size
= get_ulong64( &args
);
471 SIZE_T
*ret_size
= get_ptr( &args
);
473 return NtReadVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
477 /**********************************************************************
478 * wow64_NtWow64WriteVirtualMemory64
480 NTSTATUS WINAPI
wow64_NtWow64WriteVirtualMemory64( UINT
*args
)
482 HANDLE process
= get_handle( &args
);
483 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
484 const void *buffer
= get_ptr( &args
);
485 SIZE_T size
= get_ulong64( &args
);
486 SIZE_T
*ret_size
= get_ptr( &args
);
488 return NtWriteVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
492 /**********************************************************************
493 * wow64_NtWriteVirtualMemory
495 NTSTATUS WINAPI
wow64_NtWriteVirtualMemory( UINT
*args
)
497 HANDLE process
= get_handle( &args
);
498 void *addr
= get_ptr( &args
);
499 const void *buffer
= get_ptr( &args
);
500 SIZE_T size
= get_ulong( &args
);
501 ULONG
*retlen
= get_ptr( &args
);
506 status
= NtWriteVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
507 put_size( retlen
, ret_size
);