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
= Wow64AllocateTemp( 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
] );
211 /**********************************************************************
212 * wow64_NtLockVirtualMemory
214 NTSTATUS WINAPI
wow64_NtLockVirtualMemory( UINT
*args
)
216 HANDLE process
= get_handle( &args
);
217 ULONG
*addr32
= get_ptr( &args
);
218 ULONG
*size32
= get_ptr( &args
);
219 ULONG unknown
= get_ulong( &args
);
225 status
= NtLockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
226 size_32to64( &size
, size32
), unknown
);
229 put_addr( addr32
, addr
);
230 put_size( size32
, size
);
236 /**********************************************************************
237 * wow64_NtMapViewOfSection
239 NTSTATUS WINAPI
wow64_NtMapViewOfSection( UINT
*args
)
241 HANDLE handle
= get_handle( &args
);
242 HANDLE process
= get_handle( &args
);
243 ULONG
*addr32
= get_ptr( &args
);
244 ULONG_PTR zero_bits
= get_ulong( &args
);
245 SIZE_T commit
= get_ulong( &args
);
246 const LARGE_INTEGER
*offset
= get_ptr( &args
);
247 ULONG
*size32
= get_ptr( &args
);
248 SECTION_INHERIT inherit
= get_ulong( &args
);
249 ULONG alloc
= get_ulong( &args
);
250 ULONG protect
= get_ulong( &args
);
256 status
= NtMapViewOfSection( handle
, process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
257 commit
, offset
, size_32to64( &size
, size32
), inherit
, alloc
, protect
);
258 if (NT_SUCCESS(status
))
260 SECTION_IMAGE_INFORMATION info
;
262 if (!NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
))
264 if (info
.Machine
== current_machine
) init_image_mapping( addr
);
266 put_addr( addr32
, addr
);
267 put_size( size32
, size
);
273 /**********************************************************************
274 * wow64_NtProtectVirtualMemory
276 NTSTATUS WINAPI
wow64_NtProtectVirtualMemory( UINT
*args
)
278 HANDLE process
= get_handle( &args
);
279 ULONG
*addr32
= get_ptr( &args
);
280 ULONG
*size32
= get_ptr( &args
);
281 ULONG new_prot
= get_ulong( &args
);
282 ULONG
*old_prot
= get_ptr( &args
);
288 status
= NtProtectVirtualMemory( process
, addr_32to64( &addr
, addr32
),
289 size_32to64( &size
, size32
), new_prot
, old_prot
);
292 put_addr( addr32
, addr
);
293 put_size( size32
, size
);
299 /**********************************************************************
300 * wow64_NtQueryVirtualMemory
302 NTSTATUS WINAPI
wow64_NtQueryVirtualMemory( UINT
*args
)
304 HANDLE handle
= get_handle( &args
);
305 void *addr
= get_ptr( &args
);
306 MEMORY_INFORMATION_CLASS
class = get_ulong( &args
);
307 void *ptr
= get_ptr( &args
);
308 ULONG len
= get_ulong( &args
);
309 ULONG
*retlen
= get_ptr( &args
);
316 case MemoryBasicInformation
: /* MEMORY_BASIC_INFORMATION */
317 if (len
>= sizeof(MEMORY_BASIC_INFORMATION32
))
319 MEMORY_BASIC_INFORMATION info
;
320 MEMORY_BASIC_INFORMATION32
*info32
= ptr
;
322 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
324 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
325 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
326 info32
->AllocationProtect
= info
.AllocationProtect
;
327 info32
->RegionSize
= info
.RegionSize
;
328 info32
->State
= info
.State
;
329 info32
->Protect
= info
.Protect
;
330 info32
->Type
= info
.Type
;
333 else status
= STATUS_INFO_LENGTH_MISMATCH
;
334 res_len
= sizeof(MEMORY_BASIC_INFORMATION32
);
337 case MemoryMappedFilenameInformation
: /* MEMORY_SECTION_NAME */
339 MEMORY_SECTION_NAME
*info
;
340 MEMORY_SECTION_NAME32
*info32
= ptr
;
341 SIZE_T size
= len
+ sizeof(*info
) - sizeof(*info32
);
343 info
= Wow64AllocateTemp( size
);
344 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, size
, &res_len
)))
346 info32
->SectionFileName
.Length
= info
->SectionFileName
.Length
;
347 info32
->SectionFileName
.MaximumLength
= info
->SectionFileName
.MaximumLength
;
348 info32
->SectionFileName
.Buffer
= PtrToUlong( info32
+ 1 );
349 memcpy( info32
+ 1, info
->SectionFileName
.Buffer
, info
->SectionFileName
.MaximumLength
);
351 res_len
+= sizeof(*info32
) - sizeof(*info
);
355 case MemoryWorkingSetExInformation
: /* MEMORY_WORKING_SET_EX_INFORMATION */
357 MEMORY_WORKING_SET_EX_INFORMATION32
*info32
= ptr
;
358 MEMORY_WORKING_SET_EX_INFORMATION
*info
;
359 ULONG i
, count
= len
/ sizeof(*info32
);
361 info
= Wow64AllocateTemp( count
* sizeof(*info
) );
362 for (i
= 0; i
< count
; i
++) info
[i
].VirtualAddress
= ULongToPtr( info32
[i
].VirtualAddress
);
363 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, count
* sizeof(*info
), &res_len
)))
365 count
= res_len
/ sizeof(*info
);
366 for (i
= 0; i
< count
; i
++) info32
[i
].VirtualAttributes
.Flags
= info
[i
].VirtualAttributes
.Flags
;
367 res_len
= count
* sizeof(*info32
);
372 case MemoryWineUnixWow64Funcs
:
373 return STATUS_INVALID_INFO_CLASS
;
375 case MemoryWineUnixFuncs
:
376 status
= NtQueryVirtualMemory( handle
, addr
, MemoryWineUnixWow64Funcs
, ptr
, len
, &res_len
);
380 FIXME( "unsupported class %u\n", class );
381 return STATUS_INVALID_INFO_CLASS
;
383 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
) put_size( retlen
, res_len
);
388 /**********************************************************************
389 * wow64_NtReadVirtualMemory
391 NTSTATUS WINAPI
wow64_NtReadVirtualMemory( UINT
*args
)
393 HANDLE process
= get_handle( &args
);
394 const void *addr
= get_ptr( &args
);
395 void *buffer
= get_ptr( &args
);
396 SIZE_T size
= get_ulong( &args
);
397 ULONG
*retlen
= get_ptr( &args
);
402 status
= NtReadVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
403 put_size( retlen
, ret_size
);
408 /**********************************************************************
409 * wow64_NtResetWriteWatch
411 NTSTATUS WINAPI
wow64_NtResetWriteWatch( UINT
*args
)
413 HANDLE process
= get_handle( &args
);
414 void *base
= get_ptr( &args
);
415 SIZE_T size
= get_ulong( &args
);
417 return NtResetWriteWatch( process
, base
, size
);
421 /**********************************************************************
422 * wow64_NtSetLdtEntries
424 NTSTATUS WINAPI
wow64_NtSetLdtEntries( UINT
*args
)
426 ULONG sel1
= get_ulong( &args
);
427 ULONG entry1_low
= get_ulong( &args
);
428 ULONG entry1_high
= get_ulong( &args
);
429 ULONG sel2
= get_ulong( &args
);
430 ULONG entry2_low
= get_ulong( &args
);
431 ULONG entry2_high
= get_ulong( &args
);
433 FIXME( "%04x %08x %08x %04x %08x %08x: stub\n",
434 sel1
, entry1_low
, entry1_high
, sel2
, entry2_low
, entry2_high
);
435 return STATUS_NOT_IMPLEMENTED
;
439 /**********************************************************************
440 * wow64_NtUnlockVirtualMemory
442 NTSTATUS WINAPI
wow64_NtUnlockVirtualMemory( UINT
*args
)
444 HANDLE process
= get_handle( &args
);
445 ULONG
*addr32
= get_ptr( &args
);
446 ULONG
*size32
= get_ptr( &args
);
447 ULONG unknown
= get_ulong( &args
);
453 status
= NtUnlockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
454 size_32to64( &size
, size32
), unknown
);
457 put_addr( addr32
, addr
);
458 put_size( size32
, size
);
464 /**********************************************************************
465 * wow64_NtUnmapViewOfSection
467 NTSTATUS WINAPI
wow64_NtUnmapViewOfSection( UINT
*args
)
469 HANDLE process
= get_handle( &args
);
470 void *addr
= get_ptr( &args
);
472 return NtUnmapViewOfSection( process
, addr
);
476 /**********************************************************************
477 * wow64_NtWow64AllocateVirtualMemory64
479 NTSTATUS WINAPI
wow64_NtWow64AllocateVirtualMemory64( UINT
*args
)
481 HANDLE process
= get_handle( &args
);
482 void **addr
= get_ptr( &args
);
483 ULONG_PTR zero_bits
= get_ulong64( &args
);
484 SIZE_T
*size
= get_ptr( &args
);
485 ULONG type
= get_ulong( &args
);
486 ULONG protect
= get_ulong( &args
);
488 return NtAllocateVirtualMemory( process
, addr
, zero_bits
, size
, type
, protect
);
492 /**********************************************************************
493 * wow64_NtWow64ReadVirtualMemory64
495 NTSTATUS WINAPI
wow64_NtWow64ReadVirtualMemory64( UINT
*args
)
497 HANDLE process
= get_handle( &args
);
498 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
499 void *buffer
= get_ptr( &args
);
500 SIZE_T size
= get_ulong64( &args
);
501 SIZE_T
*ret_size
= get_ptr( &args
);
503 return NtReadVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
507 /**********************************************************************
508 * wow64_NtWow64WriteVirtualMemory64
510 NTSTATUS WINAPI
wow64_NtWow64WriteVirtualMemory64( UINT
*args
)
512 HANDLE process
= get_handle( &args
);
513 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
514 const void *buffer
= get_ptr( &args
);
515 SIZE_T size
= get_ulong64( &args
);
516 SIZE_T
*ret_size
= get_ptr( &args
);
518 return NtWriteVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
522 /**********************************************************************
523 * wow64_NtWriteVirtualMemory
525 NTSTATUS WINAPI
wow64_NtWriteVirtualMemory( UINT
*args
)
527 HANDLE process
= get_handle( &args
);
528 void *addr
= get_ptr( &args
);
529 const void *buffer
= get_ptr( &args
);
530 SIZE_T size
= get_ulong( &args
);
531 ULONG
*retlen
= get_ptr( &args
);
536 status
= NtWriteVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
537 put_size( retlen
, ret_size
);