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
);
35 static BOOL WINAPIV
send_cross_process_notification( HANDLE process
, UINT id
, const void *addr
, SIZE_T size
,
38 CROSS_PROCESS_WORK_LIST
*list
;
39 CROSS_PROCESS_WORK_ENTRY
*entry
;
45 RtlOpenCrossProcessEmulatorWorkConnection( process
, §ion
, (void **)&list
);
46 if (!list
) return FALSE
;
47 if ((entry
= RtlWow64PopCrossProcessWorkFromFreeList( &list
->free_list
)))
50 entry
->addr
= (ULONG_PTR
)addr
;
54 va_start( args
, nb_args
);
55 for (i
= 0; i
< nb_args
; i
++) entry
->args
[i
] = va_arg( args
, int );
58 RtlWow64PushCrossProcessWorkOntoWorkList( &list
->work_list
, entry
, &unused
);
60 NtUnmapViewOfSection( GetCurrentProcess(), list
);
66 static MEMORY_RANGE_ENTRY
*memory_range_entry_array_32to64( const MEMORY_RANGE_ENTRY32
*addresses32
,
69 MEMORY_RANGE_ENTRY
*addresses
= Wow64AllocateTemp( sizeof(MEMORY_RANGE_ENTRY
) * count
);
72 for (i
= 0; i
< count
; i
++)
74 addresses
[i
].VirtualAddress
= ULongToPtr( addresses32
[i
].VirtualAddress
);
75 addresses
[i
].NumberOfBytes
= addresses32
[i
].NumberOfBytes
;
81 static NTSTATUS
mem_extended_parameters_32to64( MEM_EXTENDED_PARAMETER
**ret_params
,
82 const MEM_EXTENDED_PARAMETER32
*params32
, ULONG
*count
,
86 MEM_EXTENDED_PARAMETER
*params
;
87 MEM_ADDRESS_REQUIREMENTS
*req
;
88 MEM_ADDRESS_REQUIREMENTS32
*req32
= NULL
;
90 if (*count
&& !params32
) return STATUS_INVALID_PARAMETER
;
92 params
= Wow64AllocateTemp( (*count
+ 1) * sizeof(*params
) + sizeof(*req
) );
93 req
= (MEM_ADDRESS_REQUIREMENTS
*)(params
+ *count
+ 1);
95 for (i
= 0; i
< *count
; i
++)
97 params
[i
].Type
= params32
[i
].Type
;
98 params
[i
].Reserved
= 0;
99 switch (params
[i
].Type
)
101 case MemExtendedParameterAddressRequirements
:
102 req32
= ULongToPtr( params32
[i
].Pointer
);
103 params
[i
].Pointer
= req
;
105 case MemExtendedParameterAttributeFlags
:
106 case MemExtendedParameterNumaNode
:
107 case MemExtendedParameterImageMachine
:
108 params
[i
].ULong
= params32
[i
].ULong
;
110 case MemExtendedParameterPartitionHandle
:
111 case MemExtendedParameterUserPhysicalHandle
:
112 params
[i
].Handle
= ULongToHandle( params32
[i
].Handle
);
119 if (req32
->HighestEndingAddress
> highest_user_address
) return STATUS_INVALID_PARAMETER
;
120 req
->LowestStartingAddress
= ULongToPtr( req32
->LowestStartingAddress
);
121 req
->HighestEndingAddress
= ULongToPtr( req32
->HighestEndingAddress
);
122 req
->Alignment
= req32
->Alignment
;
126 req
->LowestStartingAddress
= NULL
;
127 req
->HighestEndingAddress
= (void *)highest_user_address
;
130 params
[i
].Type
= MemExtendedParameterAddressRequirements
;
131 params
[i
].Reserved
= 0;
132 params
[i
].Pointer
= req
;
135 *ret_params
= params
;
136 return STATUS_SUCCESS
;
139 /**********************************************************************
140 * wow64_NtAllocateVirtualMemory
142 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemory( UINT
*args
)
144 HANDLE process
= get_handle( &args
);
145 ULONG
*addr32
= get_ptr( &args
);
146 ULONG_PTR zero_bits
= get_ulong( &args
);
147 ULONG
*size32
= get_ptr( &args
);
148 ULONG type
= get_ulong( &args
);
149 ULONG protect
= get_ulong( &args
);
151 void *addr
= ULongToPtr( *addr32
);
152 SIZE_T size
= *size32
;
153 BOOL is_current
= RtlIsCurrentProcess( process
);
156 if (!addr
&& (type
& MEM_COMMIT
)) type
|= MEM_RESERVE
;
159 send_cross_process_notification( process
, CrossProcessPreVirtualAlloc
,
160 addr
, size
, 3, type
, protect
, 0 );
162 status
= NtAllocateVirtualMemory( process
, &addr
, get_zero_bits( zero_bits
), &size
, type
, protect
);
165 send_cross_process_notification( process
, CrossProcessPostVirtualAlloc
,
166 addr
, size
, 3, type
, protect
, status
);
170 if (is_current
&& pBTCpuNotifyMemoryAlloc
) pBTCpuNotifyMemoryAlloc( addr
, size
, type
, protect
);
171 put_addr( addr32
, addr
);
172 put_size( size32
, size
);
178 /**********************************************************************
179 * wow64_NtAllocateVirtualMemoryEx
181 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemoryEx( UINT
*args
)
183 HANDLE process
= get_handle( &args
);
184 ULONG
*addr32
= get_ptr( &args
);
185 ULONG
*size32
= get_ptr( &args
);
186 ULONG type
= get_ulong( &args
);
187 ULONG protect
= get_ulong( &args
);
188 MEM_EXTENDED_PARAMETER32
*params32
= get_ptr( &args
);
189 ULONG count
= get_ulong( &args
);
191 void *addr
= ULongToPtr( *addr32
);
192 SIZE_T size
= *size32
;
194 MEM_EXTENDED_PARAMETER
*params64
;
195 BOOL is_current
= RtlIsCurrentProcess( process
);
196 BOOL set_limit
= (!*addr32
&& is_current
);
198 if (!addr
) type
|= MEM_RESERVE
;
200 if ((status
= mem_extended_parameters_32to64( ¶ms64
, params32
, &count
, set_limit
))) return status
;
202 if (!is_current
) send_cross_process_notification( process
, CrossProcessPreVirtualAlloc
,
203 addr
, size
, 3, type
, protect
, 0 );
205 status
= NtAllocateVirtualMemoryEx( process
, &addr
, &size
, type
, protect
, params64
, count
);
207 if (!is_current
) send_cross_process_notification( process
, CrossProcessPostVirtualAlloc
,
208 addr
, size
, 3, type
, protect
, status
);
212 if (is_current
&& pBTCpuNotifyMemoryAlloc
) pBTCpuNotifyMemoryAlloc( addr
, size
, type
, protect
);
213 put_addr( addr32
, addr
);
214 put_size( size32
, size
);
220 /**********************************************************************
221 * wow64_NtAreMappedFilesTheSame
223 NTSTATUS WINAPI
wow64_NtAreMappedFilesTheSame( UINT
*args
)
225 void *ptr1
= get_ptr( &args
);
226 void *ptr2
= get_ptr( &args
);
228 return NtAreMappedFilesTheSame( ptr1
, ptr2
);
232 /**********************************************************************
233 * wow64_NtFlushInstructionCache
235 NTSTATUS WINAPI
wow64_NtFlushInstructionCache( UINT
*args
)
237 HANDLE process
= get_handle( &args
);
238 const void *addr
= get_ptr( &args
);
239 SIZE_T size
= get_ulong( &args
);
241 if (RtlIsCurrentProcess( process
))
243 if (pBTCpuNotifyFlushInstructionCache2
) pBTCpuNotifyFlushInstructionCache2( addr
, size
);
245 else send_cross_process_notification( process
, CrossProcessFlushCache
, addr
, size
, 0 );
247 return NtFlushInstructionCache( process
, addr
, size
);
251 /**********************************************************************
252 * wow64_NtFlushVirtualMemory
254 NTSTATUS WINAPI
wow64_NtFlushVirtualMemory( UINT
*args
)
256 HANDLE process
= get_handle( &args
);
257 ULONG
*addr32
= get_ptr( &args
);
258 ULONG
*size32
= get_ptr( &args
);
259 ULONG unknown
= get_ulong( &args
);
265 status
= NtFlushVirtualMemory( process
, (const void **)addr_32to64( &addr
, addr32
),
266 size_32to64( &size
, size32
), unknown
);
269 put_addr( addr32
, addr
);
270 put_size( size32
, size
);
276 /**********************************************************************
277 * wow64_NtFreeVirtualMemory
279 NTSTATUS WINAPI
wow64_NtFreeVirtualMemory( UINT
*args
)
281 HANDLE process
= get_handle( &args
);
282 ULONG
*addr32
= get_ptr( &args
);
283 ULONG
*size32
= get_ptr( &args
);
284 ULONG type
= get_ulong( &args
);
286 void *addr
= ULongToPtr( *addr32
);
287 SIZE_T size
= *size32
;
288 BOOL is_current
= RtlIsCurrentProcess( process
);
293 if (pBTCpuNotifyMemoryFree
) pBTCpuNotifyMemoryFree( addr
, size
, type
);
295 else send_cross_process_notification( process
, CrossProcessPreVirtualFree
,
296 addr
, size
, 2, type
, 0 );
298 status
= NtFreeVirtualMemory( process
, &addr
, &size
, type
);
300 if (!is_current
) send_cross_process_notification( process
, CrossProcessPostVirtualFree
,
301 addr
, size
, 2, type
, status
);
304 put_addr( addr32
, addr
);
305 put_size( size32
, size
);
311 /**********************************************************************
312 * wow64_NtGetNlsSectionPtr
314 NTSTATUS WINAPI
wow64_NtGetNlsSectionPtr( UINT
*args
)
316 ULONG type
= get_ulong( &args
);
317 ULONG id
= get_ulong( &args
);
318 void *unknown
= get_ptr( &args
);
319 ULONG
*addr32
= get_ptr( &args
);
320 ULONG
*size32
= get_ptr( &args
);
326 status
= NtGetNlsSectionPtr( type
, id
, unknown
, addr_32to64( &addr
, addr32
),
327 size_32to64( &size
, size32
));
330 put_addr( addr32
, addr
);
331 put_size( size32
, size
);
337 /**********************************************************************
338 * wow64_NtGetWriteWatch
340 NTSTATUS WINAPI
wow64_NtGetWriteWatch( UINT
*args
)
342 HANDLE handle
= get_handle( &args
);
343 ULONG flags
= get_ulong( &args
);
344 void *base
= get_ptr( &args
);
345 SIZE_T size
= get_ulong( &args
);
346 ULONG
*addr_ptr
= get_ptr( &args
);
347 ULONG
*count_ptr
= get_ptr( &args
);
348 ULONG
*granularity
= get_ptr( &args
);
350 ULONG_PTR i
, count
= *count_ptr
;
354 if (!count
|| !size
) return STATUS_INVALID_PARAMETER
;
355 if (flags
& ~WRITE_WATCH_FLAG_RESET
) return STATUS_INVALID_PARAMETER
;
356 if (!addr_ptr
) return STATUS_ACCESS_VIOLATION
;
358 addresses
= Wow64AllocateTemp( count
* sizeof(*addresses
) );
359 if (!(status
= NtGetWriteWatch( handle
, flags
, base
, size
, addresses
, &count
, granularity
)))
361 for (i
= 0; i
< count
; i
++) addr_ptr
[i
] = PtrToUlong( addresses
[i
] );
368 /**********************************************************************
369 * wow64_NtInitializeNlsFiles
371 NTSTATUS WINAPI
wow64_NtInitializeNlsFiles( UINT
*args
)
373 ULONG
*addr32
= get_ptr( &args
);
374 LCID
*lcid
= get_ptr( &args
);
375 LARGE_INTEGER
*size
= get_ptr( &args
);
380 status
= NtInitializeNlsFiles( addr_32to64( &addr
, addr32
), lcid
, size
);
381 if (!status
) put_addr( addr32
, addr
);
386 /**********************************************************************
387 * wow64_NtLockVirtualMemory
389 NTSTATUS WINAPI
wow64_NtLockVirtualMemory( UINT
*args
)
391 HANDLE process
= get_handle( &args
);
392 ULONG
*addr32
= get_ptr( &args
);
393 ULONG
*size32
= get_ptr( &args
);
394 ULONG unknown
= get_ulong( &args
);
400 status
= NtLockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
401 size_32to64( &size
, size32
), unknown
);
404 put_addr( addr32
, addr
);
405 put_size( size32
, size
);
411 /**********************************************************************
412 * wow64_NtMapViewOfSection
414 NTSTATUS WINAPI
wow64_NtMapViewOfSection( UINT
*args
)
416 HANDLE handle
= get_handle( &args
);
417 HANDLE process
= get_handle( &args
);
418 ULONG
*addr32
= get_ptr( &args
);
419 ULONG_PTR zero_bits
= get_ulong( &args
);
420 SIZE_T commit
= get_ulong( &args
);
421 const LARGE_INTEGER
*offset
= get_ptr( &args
);
422 ULONG
*size32
= get_ptr( &args
);
423 SECTION_INHERIT inherit
= get_ulong( &args
);
424 ULONG alloc
= get_ulong( &args
);
425 ULONG protect
= get_ulong( &args
);
431 status
= NtMapViewOfSection( handle
, process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
432 commit
, offset
, size_32to64( &size
, size32
), inherit
, alloc
, protect
);
433 if (NT_SUCCESS(status
))
435 SECTION_IMAGE_INFORMATION info
;
437 if (RtlIsCurrentProcess( process
) &&
438 !NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
) &&
439 info
.Machine
== current_machine
)
441 if (pBTCpuNotifyMapViewOfSection
) pBTCpuNotifyMapViewOfSection( addr
);
442 init_image_mapping( addr
);
444 put_addr( addr32
, addr
);
445 put_size( size32
, size
);
450 /**********************************************************************
451 * wow64_NtMapViewOfSectionEx
453 NTSTATUS WINAPI
wow64_NtMapViewOfSectionEx( UINT
*args
)
455 HANDLE handle
= get_handle( &args
);
456 HANDLE process
= get_handle( &args
);
457 ULONG
*addr32
= get_ptr( &args
);
458 const LARGE_INTEGER
*offset
= get_ptr( &args
);
459 ULONG
*size32
= get_ptr( &args
);
460 ULONG alloc
= get_ulong( &args
);
461 ULONG protect
= get_ulong( &args
);
462 MEM_EXTENDED_PARAMETER32
*params32
= get_ptr( &args
);
463 ULONG count
= get_ulong( &args
);
468 MEM_EXTENDED_PARAMETER
*params64
;
469 BOOL is_current
= RtlIsCurrentProcess( process
);
470 BOOL set_limit
= (!*addr32
&& is_current
);
472 if ((status
= mem_extended_parameters_32to64( ¶ms64
, params32
, &count
, set_limit
))) return status
;
474 status
= NtMapViewOfSectionEx( handle
, process
, addr_32to64( &addr
, addr32
), offset
,
475 size_32to64( &size
, size32
), alloc
, protect
, params64
, count
);
476 if (NT_SUCCESS(status
))
478 SECTION_IMAGE_INFORMATION info
;
481 !NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
) &&
482 info
.Machine
== current_machine
)
484 if (pBTCpuNotifyMapViewOfSection
) pBTCpuNotifyMapViewOfSection( addr
);
485 init_image_mapping( addr
);
487 put_addr( addr32
, addr
);
488 put_size( size32
, size
);
493 /**********************************************************************
494 * wow64_NtProtectVirtualMemory
496 NTSTATUS WINAPI
wow64_NtProtectVirtualMemory( UINT
*args
)
498 HANDLE process
= get_handle( &args
);
499 ULONG
*addr32
= get_ptr( &args
);
500 ULONG
*size32
= get_ptr( &args
);
501 ULONG new_prot
= get_ulong( &args
);
502 ULONG
*old_prot
= get_ptr( &args
);
504 void *addr
= ULongToPtr( *addr32
);
505 SIZE_T size
= *size32
;
506 BOOL is_current
= RtlIsCurrentProcess( process
);
511 if (pBTCpuNotifyMemoryProtect
) pBTCpuNotifyMemoryProtect( addr
, size
, new_prot
);
513 else send_cross_process_notification( process
, CrossProcessPreVirtualProtect
,
514 addr
, size
, 2, new_prot
, 0 );
516 status
= NtProtectVirtualMemory( process
, &addr
, &size
, new_prot
, old_prot
);
518 if (!is_current
) send_cross_process_notification( process
, CrossProcessPostVirtualProtect
,
519 addr
, size
, 2, new_prot
, status
);
523 put_addr( addr32
, addr
);
524 put_size( size32
, size
);
530 /**********************************************************************
531 * wow64_NtQueryVirtualMemory
533 NTSTATUS WINAPI
wow64_NtQueryVirtualMemory( UINT
*args
)
535 HANDLE handle
= get_handle( &args
);
536 void *addr
= get_ptr( &args
);
537 MEMORY_INFORMATION_CLASS
class = get_ulong( &args
);
538 void *ptr
= get_ptr( &args
);
539 ULONG len
= get_ulong( &args
);
540 ULONG
*retlen
= get_ptr( &args
);
547 case MemoryBasicInformation
: /* MEMORY_BASIC_INFORMATION */
548 if (len
< sizeof(MEMORY_BASIC_INFORMATION32
))
549 status
= STATUS_INFO_LENGTH_MISMATCH
;
550 else if ((ULONG_PTR
)addr
> highest_user_address
)
551 status
= STATUS_INVALID_PARAMETER
;
554 MEMORY_BASIC_INFORMATION info
;
555 MEMORY_BASIC_INFORMATION32
*info32
= ptr
;
557 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
559 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
560 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
561 info32
->AllocationProtect
= info
.AllocationProtect
;
562 info32
->RegionSize
= info
.RegionSize
;
563 info32
->State
= info
.State
;
564 info32
->Protect
= info
.Protect
;
565 info32
->Type
= info
.Type
;
566 if ((ULONG_PTR
)info
.BaseAddress
+ info
.RegionSize
> highest_user_address
)
567 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.BaseAddress
+ 1;
570 res_len
= sizeof(MEMORY_BASIC_INFORMATION32
);
573 case MemoryMappedFilenameInformation
: /* MEMORY_SECTION_NAME */
575 MEMORY_SECTION_NAME
*info
;
576 MEMORY_SECTION_NAME32
*info32
= ptr
;
577 SIZE_T size
= len
+ sizeof(*info
) - sizeof(*info32
);
579 info
= Wow64AllocateTemp( size
);
580 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, size
, &res_len
)))
582 info32
->SectionFileName
.Length
= info
->SectionFileName
.Length
;
583 info32
->SectionFileName
.MaximumLength
= info
->SectionFileName
.MaximumLength
;
584 info32
->SectionFileName
.Buffer
= PtrToUlong( info32
+ 1 );
585 memcpy( info32
+ 1, info
->SectionFileName
.Buffer
, info
->SectionFileName
.MaximumLength
);
587 res_len
+= sizeof(*info32
) - sizeof(*info
);
591 case MemoryRegionInformation
: /* MEMORY_REGION_INFORMATION */
593 if (len
< sizeof(MEMORY_REGION_INFORMATION32
))
594 status
= STATUS_INFO_LENGTH_MISMATCH
;
595 else if ((ULONG_PTR
)addr
> highest_user_address
)
596 status
= STATUS_INVALID_PARAMETER
;
599 MEMORY_REGION_INFORMATION info
;
600 MEMORY_REGION_INFORMATION32
*info32
= ptr
;
602 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
604 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
605 info32
->AllocationProtect
= info
.AllocationProtect
;
606 info32
->RegionType
= info
.RegionType
;
607 info32
->RegionSize
= info
.RegionSize
;
608 info32
->CommitSize
= info
.CommitSize
;
609 info32
->PartitionId
= info
.PartitionId
;
610 info32
->NodePreference
= info
.NodePreference
;
611 if ((ULONG_PTR
)info
.AllocationBase
+ info
.RegionSize
> highest_user_address
)
612 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.AllocationBase
+ 1;
615 res_len
= sizeof(MEMORY_REGION_INFORMATION32
);
619 case MemoryWorkingSetExInformation
: /* MEMORY_WORKING_SET_EX_INFORMATION */
621 MEMORY_WORKING_SET_EX_INFORMATION32
*info32
= ptr
;
622 MEMORY_WORKING_SET_EX_INFORMATION
*info
;
623 ULONG i
, count
= len
/ sizeof(*info32
);
625 info
= Wow64AllocateTemp( count
* sizeof(*info
) );
626 for (i
= 0; i
< count
; i
++) info
[i
].VirtualAddress
= ULongToPtr( info32
[i
].VirtualAddress
);
627 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, count
* sizeof(*info
), &res_len
)))
629 count
= res_len
/ sizeof(*info
);
630 for (i
= 0; i
< count
; i
++) info32
[i
].VirtualAttributes
.Flags
= info
[i
].VirtualAttributes
.Flags
;
631 res_len
= count
* sizeof(*info32
);
636 case MemoryImageInformation
: /* MEMORY_IMAEG_INFORMATION */
638 if (len
< sizeof(MEMORY_IMAGE_INFORMATION32
)) return STATUS_INFO_LENGTH_MISMATCH
;
640 if ((ULONG_PTR
)addr
> highest_user_address
) status
= STATUS_INVALID_PARAMETER
;
643 MEMORY_IMAGE_INFORMATION info
;
644 MEMORY_IMAGE_INFORMATION32
*info32
= ptr
;
646 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
648 info32
->ImageBase
= PtrToUlong( info
.ImageBase
);
649 info32
->SizeOfImage
= info
.SizeOfImage
;
650 info32
->ImageFlags
= info
.ImageFlags
;
653 res_len
= sizeof(MEMORY_IMAGE_INFORMATION32
);
657 case MemoryWineUnixWow64Funcs
:
658 return STATUS_INVALID_INFO_CLASS
;
660 case MemoryWineUnixFuncs
:
661 status
= NtQueryVirtualMemory( handle
, addr
, MemoryWineUnixWow64Funcs
, ptr
, len
, &res_len
);
665 FIXME( "unsupported class %u\n", class );
666 return STATUS_INVALID_INFO_CLASS
;
668 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
) put_size( retlen
, res_len
);
673 /**********************************************************************
674 * wow64_NtReadVirtualMemory
676 NTSTATUS WINAPI
wow64_NtReadVirtualMemory( UINT
*args
)
678 HANDLE process
= get_handle( &args
);
679 const void *addr
= get_ptr( &args
);
680 void *buffer
= get_ptr( &args
);
681 SIZE_T size
= get_ulong( &args
);
682 ULONG
*retlen
= get_ptr( &args
);
687 status
= NtReadVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
688 put_size( retlen
, ret_size
);
693 /**********************************************************************
694 * wow64_NtResetWriteWatch
696 NTSTATUS WINAPI
wow64_NtResetWriteWatch( UINT
*args
)
698 HANDLE process
= get_handle( &args
);
699 void *base
= get_ptr( &args
);
700 SIZE_T size
= get_ulong( &args
);
702 return NtResetWriteWatch( process
, base
, size
);
706 /**********************************************************************
707 * wow64_NtSetInformationVirtualMemory
709 NTSTATUS WINAPI
wow64_NtSetInformationVirtualMemory( UINT
*args
)
711 HANDLE process
= get_handle( &args
);
712 VIRTUAL_MEMORY_INFORMATION_CLASS info_class
= get_ulong( &args
);
713 ULONG count
= get_ulong( &args
);
714 MEMORY_RANGE_ENTRY32
*addresses32
= get_ptr( &args
);
715 PVOID ptr
= get_ptr( &args
);
716 ULONG len
= get_ulong( &args
);
718 MEMORY_RANGE_ENTRY
*addresses
;
720 if (!count
) return STATUS_INVALID_PARAMETER_3
;
721 addresses
= memory_range_entry_array_32to64( addresses32
, count
);
725 case VmPrefetchInformation
:
728 FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n",
729 process
, info_class
, count
, addresses32
, ptr
, len
);
730 return STATUS_INVALID_PARAMETER_2
;
733 return NtSetInformationVirtualMemory( process
, info_class
, count
, addresses
, ptr
, len
);
737 /**********************************************************************
738 * wow64_NtSetLdtEntries
740 NTSTATUS WINAPI
wow64_NtSetLdtEntries( UINT
*args
)
742 ULONG sel1
= get_ulong( &args
);
743 ULONG entry1_low
= get_ulong( &args
);
744 ULONG entry1_high
= get_ulong( &args
);
745 ULONG sel2
= get_ulong( &args
);
746 ULONG entry2_low
= get_ulong( &args
);
747 ULONG entry2_high
= get_ulong( &args
);
749 FIXME( "%04lx %08lx %08lx %04lx %08lx %08lx: stub\n",
750 sel1
, entry1_low
, entry1_high
, sel2
, entry2_low
, entry2_high
);
751 return STATUS_NOT_IMPLEMENTED
;
755 /**********************************************************************
756 * wow64_NtUnlockVirtualMemory
758 NTSTATUS WINAPI
wow64_NtUnlockVirtualMemory( UINT
*args
)
760 HANDLE process
= get_handle( &args
);
761 ULONG
*addr32
= get_ptr( &args
);
762 ULONG
*size32
= get_ptr( &args
);
763 ULONG unknown
= get_ulong( &args
);
769 status
= NtUnlockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
770 size_32to64( &size
, size32
), unknown
);
773 put_addr( addr32
, addr
);
774 put_size( size32
, size
);
780 /**********************************************************************
781 * wow64_NtUnmapViewOfSection
783 NTSTATUS WINAPI
wow64_NtUnmapViewOfSection( UINT
*args
)
785 HANDLE process
= get_handle( &args
);
786 void *addr
= get_ptr( &args
);
788 if (pBTCpuNotifyUnmapViewOfSection
&& RtlIsCurrentProcess( process
))
789 pBTCpuNotifyUnmapViewOfSection( addr
);
791 return NtUnmapViewOfSection( process
, addr
);
795 /**********************************************************************
796 * wow64_NtUnmapViewOfSectionEx
798 NTSTATUS WINAPI
wow64_NtUnmapViewOfSectionEx( UINT
*args
)
800 HANDLE process
= get_handle( &args
);
801 void *addr
= get_ptr( &args
);
802 ULONG flags
= get_ulong( &args
);
804 if (pBTCpuNotifyUnmapViewOfSection
&& RtlIsCurrentProcess( process
))
805 pBTCpuNotifyUnmapViewOfSection( addr
);
807 return NtUnmapViewOfSectionEx( process
, addr
, flags
);
811 /**********************************************************************
812 * wow64_NtWow64AllocateVirtualMemory64
814 NTSTATUS WINAPI
wow64_NtWow64AllocateVirtualMemory64( UINT
*args
)
816 HANDLE process
= get_handle( &args
);
817 void **addr
= get_ptr( &args
);
818 ULONG_PTR zero_bits
= get_ulong64( &args
);
819 SIZE_T
*size
= get_ptr( &args
);
820 ULONG type
= get_ulong( &args
);
821 ULONG protect
= get_ulong( &args
);
823 return NtAllocateVirtualMemory( process
, addr
, zero_bits
, size
, type
, protect
);
827 /**********************************************************************
828 * wow64_NtWow64ReadVirtualMemory64
830 NTSTATUS WINAPI
wow64_NtWow64ReadVirtualMemory64( UINT
*args
)
832 HANDLE process
= get_handle( &args
);
833 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
834 void *buffer
= get_ptr( &args
);
835 SIZE_T size
= get_ulong64( &args
);
836 SIZE_T
*ret_size
= get_ptr( &args
);
838 return NtReadVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
842 /**********************************************************************
843 * wow64_NtWow64WriteVirtualMemory64
845 NTSTATUS WINAPI
wow64_NtWow64WriteVirtualMemory64( UINT
*args
)
847 HANDLE process
= get_handle( &args
);
848 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
849 const void *buffer
= get_ptr( &args
);
850 SIZE_T size
= get_ulong64( &args
);
851 SIZE_T
*ret_size
= get_ptr( &args
);
853 return NtWriteVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
857 /**********************************************************************
858 * wow64_NtWriteVirtualMemory
860 NTSTATUS WINAPI
wow64_NtWriteVirtualMemory( UINT
*args
)
862 HANDLE process
= get_handle( &args
);
863 void *addr
= get_ptr( &args
);
864 const void *buffer
= get_ptr( &args
);
865 SIZE_T size
= get_ulong( &args
);
866 ULONG
*retlen
= get_ptr( &args
);
871 status
= NtWriteVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
872 put_size( retlen
, ret_size
);