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 static MEMORY_RANGE_ENTRY
*memory_range_entry_array_32to64( const MEMORY_RANGE_ENTRY32
*addresses32
,
39 MEMORY_RANGE_ENTRY
*addresses
= Wow64AllocateTemp( sizeof(MEMORY_RANGE_ENTRY
) * count
);
42 for (i
= 0; i
< count
; i
++)
44 addresses
[i
].VirtualAddress
= ULongToPtr( addresses32
[i
].VirtualAddress
);
45 addresses
[i
].NumberOfBytes
= addresses32
[i
].NumberOfBytes
;
51 static NTSTATUS
mem_extended_parameters_32to64( MEM_EXTENDED_PARAMETER
**ret_params
,
52 const MEM_EXTENDED_PARAMETER32
*params32
, ULONG
*count
,
56 MEM_EXTENDED_PARAMETER
*params
;
57 MEM_ADDRESS_REQUIREMENTS
*req
;
58 MEM_ADDRESS_REQUIREMENTS32
*req32
= NULL
;
60 if (*count
&& !params32
) return STATUS_INVALID_PARAMETER
;
62 params
= Wow64AllocateTemp( (*count
+ 1) * sizeof(*params
) + sizeof(*req
) );
63 req
= (MEM_ADDRESS_REQUIREMENTS
*)(params
+ *count
+ 1);
65 for (i
= 0; i
< *count
; i
++)
67 params
[i
].Type
= params32
[i
].Type
;
68 params
[i
].Reserved
= 0;
69 switch (params
[i
].Type
)
71 case MemExtendedParameterAddressRequirements
:
72 req32
= ULongToPtr( params32
[i
].Pointer
);
73 params
[i
].Pointer
= req
;
75 case MemExtendedParameterAttributeFlags
:
76 case MemExtendedParameterNumaNode
:
77 case MemExtendedParameterImageMachine
:
78 params
[i
].ULong
= params32
[i
].ULong
;
80 case MemExtendedParameterPartitionHandle
:
81 case MemExtendedParameterUserPhysicalHandle
:
82 params
[i
].Handle
= ULongToHandle( params32
[i
].Handle
);
89 if (req32
->HighestEndingAddress
> highest_user_address
) return STATUS_INVALID_PARAMETER
;
90 req
->LowestStartingAddress
= ULongToPtr( req32
->LowestStartingAddress
);
91 req
->HighestEndingAddress
= ULongToPtr( req32
->HighestEndingAddress
);
92 req
->Alignment
= req32
->Alignment
;
96 req
->LowestStartingAddress
= NULL
;
97 req
->HighestEndingAddress
= (void *)highest_user_address
;
100 params
[i
].Type
= MemExtendedParameterAddressRequirements
;
101 params
[i
].Reserved
= 0;
102 params
[i
].Pointer
= req
;
105 *ret_params
= params
;
106 return STATUS_SUCCESS
;
109 /**********************************************************************
110 * wow64_NtAllocateVirtualMemory
112 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemory( UINT
*args
)
114 HANDLE process
= get_handle( &args
);
115 ULONG
*addr32
= get_ptr( &args
);
116 ULONG_PTR zero_bits
= get_ulong( &args
);
117 ULONG
*size32
= get_ptr( &args
);
118 ULONG type
= get_ulong( &args
);
119 ULONG protect
= get_ulong( &args
);
125 status
= NtAllocateVirtualMemory( process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
126 size_32to64( &size
, size32
), type
, protect
);
129 if (pBTCpuNotifyMemoryAlloc
&& RtlIsCurrentProcess(process
))
130 pBTCpuNotifyMemoryAlloc( addr
, size
, type
, protect
);
131 put_addr( addr32
, addr
);
132 put_size( size32
, size
);
138 /**********************************************************************
139 * wow64_NtAllocateVirtualMemoryEx
141 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemoryEx( UINT
*args
)
143 HANDLE process
= get_handle( &args
);
144 ULONG
*addr32
= get_ptr( &args
);
145 ULONG
*size32
= get_ptr( &args
);
146 ULONG type
= get_ulong( &args
);
147 ULONG protect
= get_ulong( &args
);
148 MEM_EXTENDED_PARAMETER32
*params32
= get_ptr( &args
);
149 ULONG count
= get_ulong( &args
);
154 MEM_EXTENDED_PARAMETER
*params64
;
155 BOOL is_current
= RtlIsCurrentProcess( process
);
156 BOOL set_limit
= (!*addr32
&& is_current
);
158 if ((status
= mem_extended_parameters_32to64( ¶ms64
, params32
, &count
, set_limit
))) return status
;
160 status
= NtAllocateVirtualMemoryEx( process
, addr_32to64( &addr
, addr32
), size_32to64( &size
, size32
),
161 type
, protect
, params64
, count
);
164 if (pBTCpuNotifyMemoryAlloc
&& is_current
) pBTCpuNotifyMemoryAlloc( addr
, size
, type
, protect
);
165 put_addr( addr32
, addr
);
166 put_size( size32
, size
);
172 /**********************************************************************
173 * wow64_NtAreMappedFilesTheSame
175 NTSTATUS WINAPI
wow64_NtAreMappedFilesTheSame( UINT
*args
)
177 void *ptr1
= get_ptr( &args
);
178 void *ptr2
= get_ptr( &args
);
180 return NtAreMappedFilesTheSame( ptr1
, ptr2
);
184 /**********************************************************************
185 * wow64_NtFlushVirtualMemory
187 NTSTATUS WINAPI
wow64_NtFlushVirtualMemory( UINT
*args
)
189 HANDLE process
= get_handle( &args
);
190 ULONG
*addr32
= get_ptr( &args
);
191 ULONG
*size32
= get_ptr( &args
);
192 ULONG unknown
= get_ulong( &args
);
198 status
= NtFlushVirtualMemory( process
, (const void **)addr_32to64( &addr
, addr32
),
199 size_32to64( &size
, size32
), unknown
);
202 put_addr( addr32
, addr
);
203 put_size( size32
, size
);
209 /**********************************************************************
210 * wow64_NtFreeVirtualMemory
212 NTSTATUS WINAPI
wow64_NtFreeVirtualMemory( UINT
*args
)
214 HANDLE process
= get_handle( &args
);
215 ULONG
*addr32
= get_ptr( &args
);
216 ULONG
*size32
= get_ptr( &args
);
217 ULONG type
= get_ulong( &args
);
219 void *addr
= ULongToPtr( *addr32
);
220 SIZE_T size
= *size32
;
223 if (pBTCpuNotifyMemoryFree
&& RtlIsCurrentProcess( process
))
224 pBTCpuNotifyMemoryFree( addr
, size
);
226 status
= NtFreeVirtualMemory( process
, &addr
, &size
, type
);
229 put_addr( addr32
, addr
);
230 put_size( size32
, size
);
236 /**********************************************************************
237 * wow64_NtGetNlsSectionPtr
239 NTSTATUS WINAPI
wow64_NtGetNlsSectionPtr( UINT
*args
)
241 ULONG type
= get_ulong( &args
);
242 ULONG id
= get_ulong( &args
);
243 void *unknown
= get_ptr( &args
);
244 ULONG
*addr32
= get_ptr( &args
);
245 ULONG
*size32
= get_ptr( &args
);
251 status
= NtGetNlsSectionPtr( type
, id
, unknown
, addr_32to64( &addr
, addr32
),
252 size_32to64( &size
, size32
));
255 put_addr( addr32
, addr
);
256 put_size( size32
, size
);
262 /**********************************************************************
263 * wow64_NtGetWriteWatch
265 NTSTATUS WINAPI
wow64_NtGetWriteWatch( UINT
*args
)
267 HANDLE handle
= get_handle( &args
);
268 ULONG flags
= get_ulong( &args
);
269 void *base
= get_ptr( &args
);
270 SIZE_T size
= get_ulong( &args
);
271 ULONG
*addr_ptr
= get_ptr( &args
);
272 ULONG
*count_ptr
= get_ptr( &args
);
273 ULONG
*granularity
= get_ptr( &args
);
275 ULONG_PTR i
, count
= *count_ptr
;
279 if (!count
|| !size
) return STATUS_INVALID_PARAMETER
;
280 if (flags
& ~WRITE_WATCH_FLAG_RESET
) return STATUS_INVALID_PARAMETER
;
281 if (!addr_ptr
) return STATUS_ACCESS_VIOLATION
;
283 addresses
= Wow64AllocateTemp( count
* sizeof(*addresses
) );
284 if (!(status
= NtGetWriteWatch( handle
, flags
, base
, size
, addresses
, &count
, granularity
)))
286 for (i
= 0; i
< count
; i
++) addr_ptr
[i
] = PtrToUlong( addresses
[i
] );
293 /**********************************************************************
294 * wow64_NtInitializeNlsFiles
296 NTSTATUS WINAPI
wow64_NtInitializeNlsFiles( UINT
*args
)
298 ULONG
*addr32
= get_ptr( &args
);
299 LCID
*lcid
= get_ptr( &args
);
300 LARGE_INTEGER
*size
= get_ptr( &args
);
305 status
= NtInitializeNlsFiles( addr_32to64( &addr
, addr32
), lcid
, size
);
306 if (!status
) put_addr( addr32
, addr
);
311 /**********************************************************************
312 * wow64_NtLockVirtualMemory
314 NTSTATUS WINAPI
wow64_NtLockVirtualMemory( UINT
*args
)
316 HANDLE process
= get_handle( &args
);
317 ULONG
*addr32
= get_ptr( &args
);
318 ULONG
*size32
= get_ptr( &args
);
319 ULONG unknown
= get_ulong( &args
);
325 status
= NtLockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
326 size_32to64( &size
, size32
), unknown
);
329 put_addr( addr32
, addr
);
330 put_size( size32
, size
);
336 /**********************************************************************
337 * wow64_NtMapViewOfSection
339 NTSTATUS WINAPI
wow64_NtMapViewOfSection( UINT
*args
)
341 HANDLE handle
= get_handle( &args
);
342 HANDLE process
= get_handle( &args
);
343 ULONG
*addr32
= get_ptr( &args
);
344 ULONG_PTR zero_bits
= get_ulong( &args
);
345 SIZE_T commit
= get_ulong( &args
);
346 const LARGE_INTEGER
*offset
= get_ptr( &args
);
347 ULONG
*size32
= get_ptr( &args
);
348 SECTION_INHERIT inherit
= get_ulong( &args
);
349 ULONG alloc
= get_ulong( &args
);
350 ULONG protect
= get_ulong( &args
);
356 status
= NtMapViewOfSection( handle
, process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
357 commit
, offset
, size_32to64( &size
, size32
), inherit
, alloc
, protect
);
358 if (NT_SUCCESS(status
))
360 SECTION_IMAGE_INFORMATION info
;
362 if (RtlIsCurrentProcess( process
) &&
363 !NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
) &&
364 info
.Machine
== current_machine
)
366 if (pBTCpuNotifyMapViewOfSection
) pBTCpuNotifyMapViewOfSection( addr
);
367 init_image_mapping( addr
);
369 put_addr( addr32
, addr
);
370 put_size( size32
, size
);
375 /**********************************************************************
376 * wow64_NtMapViewOfSectionEx
378 NTSTATUS WINAPI
wow64_NtMapViewOfSectionEx( UINT
*args
)
380 HANDLE handle
= get_handle( &args
);
381 HANDLE process
= get_handle( &args
);
382 ULONG
*addr32
= get_ptr( &args
);
383 const LARGE_INTEGER
*offset
= get_ptr( &args
);
384 ULONG
*size32
= get_ptr( &args
);
385 ULONG alloc
= get_ulong( &args
);
386 ULONG protect
= get_ulong( &args
);
387 MEM_EXTENDED_PARAMETER32
*params32
= get_ptr( &args
);
388 ULONG count
= get_ulong( &args
);
393 MEM_EXTENDED_PARAMETER
*params64
;
394 BOOL is_current
= RtlIsCurrentProcess( process
);
395 BOOL set_limit
= (!*addr32
&& is_current
);
397 if ((status
= mem_extended_parameters_32to64( ¶ms64
, params32
, &count
, set_limit
))) return status
;
399 status
= NtMapViewOfSectionEx( handle
, process
, addr_32to64( &addr
, addr32
), offset
,
400 size_32to64( &size
, size32
), alloc
, protect
, params64
, count
);
401 if (NT_SUCCESS(status
))
403 SECTION_IMAGE_INFORMATION info
;
406 !NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
) &&
407 info
.Machine
== current_machine
)
409 if (pBTCpuNotifyMapViewOfSection
) pBTCpuNotifyMapViewOfSection( addr
);
410 init_image_mapping( addr
);
412 put_addr( addr32
, addr
);
413 put_size( size32
, size
);
418 /**********************************************************************
419 * wow64_NtProtectVirtualMemory
421 NTSTATUS WINAPI
wow64_NtProtectVirtualMemory( UINT
*args
)
423 HANDLE process
= get_handle( &args
);
424 ULONG
*addr32
= get_ptr( &args
);
425 ULONG
*size32
= get_ptr( &args
);
426 ULONG new_prot
= get_ulong( &args
);
427 ULONG
*old_prot
= get_ptr( &args
);
429 void *addr
= ULongToPtr( *addr32
);
430 SIZE_T size
= *size32
;
433 if (pBTCpuNotifyMemoryProtect
&& RtlIsCurrentProcess(process
))
434 pBTCpuNotifyMemoryProtect( addr
, size
, new_prot
);
436 status
= NtProtectVirtualMemory( process
, &addr
, &size
, new_prot
, old_prot
);
439 put_addr( addr32
, addr
);
440 put_size( size32
, size
);
446 /**********************************************************************
447 * wow64_NtQueryVirtualMemory
449 NTSTATUS WINAPI
wow64_NtQueryVirtualMemory( UINT
*args
)
451 HANDLE handle
= get_handle( &args
);
452 void *addr
= get_ptr( &args
);
453 MEMORY_INFORMATION_CLASS
class = get_ulong( &args
);
454 void *ptr
= get_ptr( &args
);
455 ULONG len
= get_ulong( &args
);
456 ULONG
*retlen
= get_ptr( &args
);
463 case MemoryBasicInformation
: /* MEMORY_BASIC_INFORMATION */
464 if (len
< sizeof(MEMORY_BASIC_INFORMATION32
))
465 status
= STATUS_INFO_LENGTH_MISMATCH
;
466 else if ((ULONG_PTR
)addr
> highest_user_address
)
467 status
= STATUS_INVALID_PARAMETER
;
470 MEMORY_BASIC_INFORMATION info
;
471 MEMORY_BASIC_INFORMATION32
*info32
= ptr
;
473 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
475 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
476 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
477 info32
->AllocationProtect
= info
.AllocationProtect
;
478 info32
->RegionSize
= info
.RegionSize
;
479 info32
->State
= info
.State
;
480 info32
->Protect
= info
.Protect
;
481 info32
->Type
= info
.Type
;
482 if ((ULONG_PTR
)info
.BaseAddress
+ info
.RegionSize
> highest_user_address
)
483 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.BaseAddress
+ 1;
486 res_len
= sizeof(MEMORY_BASIC_INFORMATION32
);
489 case MemoryMappedFilenameInformation
: /* MEMORY_SECTION_NAME */
491 MEMORY_SECTION_NAME
*info
;
492 MEMORY_SECTION_NAME32
*info32
= ptr
;
493 SIZE_T size
= len
+ sizeof(*info
) - sizeof(*info32
);
495 info
= Wow64AllocateTemp( size
);
496 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, size
, &res_len
)))
498 info32
->SectionFileName
.Length
= info
->SectionFileName
.Length
;
499 info32
->SectionFileName
.MaximumLength
= info
->SectionFileName
.MaximumLength
;
500 info32
->SectionFileName
.Buffer
= PtrToUlong( info32
+ 1 );
501 memcpy( info32
+ 1, info
->SectionFileName
.Buffer
, info
->SectionFileName
.MaximumLength
);
503 res_len
+= sizeof(*info32
) - sizeof(*info
);
507 case MemoryRegionInformation
: /* MEMORY_REGION_INFORMATION */
509 if (len
< sizeof(MEMORY_REGION_INFORMATION32
))
510 status
= STATUS_INFO_LENGTH_MISMATCH
;
511 else if ((ULONG_PTR
)addr
> highest_user_address
)
512 status
= STATUS_INVALID_PARAMETER
;
515 MEMORY_REGION_INFORMATION info
;
516 MEMORY_REGION_INFORMATION32
*info32
= ptr
;
518 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
520 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
521 info32
->AllocationProtect
= info
.AllocationProtect
;
522 info32
->RegionType
= info
.RegionType
;
523 info32
->RegionSize
= info
.RegionSize
;
524 info32
->CommitSize
= info
.CommitSize
;
525 info32
->PartitionId
= info
.PartitionId
;
526 info32
->NodePreference
= info
.NodePreference
;
527 if ((ULONG_PTR
)info
.AllocationBase
+ info
.RegionSize
> highest_user_address
)
528 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.AllocationBase
+ 1;
531 res_len
= sizeof(MEMORY_REGION_INFORMATION32
);
535 case MemoryWorkingSetExInformation
: /* MEMORY_WORKING_SET_EX_INFORMATION */
537 MEMORY_WORKING_SET_EX_INFORMATION32
*info32
= ptr
;
538 MEMORY_WORKING_SET_EX_INFORMATION
*info
;
539 ULONG i
, count
= len
/ sizeof(*info32
);
541 info
= Wow64AllocateTemp( count
* sizeof(*info
) );
542 for (i
= 0; i
< count
; i
++) info
[i
].VirtualAddress
= ULongToPtr( info32
[i
].VirtualAddress
);
543 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, count
* sizeof(*info
), &res_len
)))
545 count
= res_len
/ sizeof(*info
);
546 for (i
= 0; i
< count
; i
++) info32
[i
].VirtualAttributes
.Flags
= info
[i
].VirtualAttributes
.Flags
;
547 res_len
= count
* sizeof(*info32
);
552 case MemoryImageInformation
: /* MEMORY_IMAEG_INFORMATION */
554 if (len
< sizeof(MEMORY_IMAGE_INFORMATION32
)) return STATUS_INFO_LENGTH_MISMATCH
;
556 if ((ULONG_PTR
)addr
> highest_user_address
) status
= STATUS_INVALID_PARAMETER
;
559 MEMORY_IMAGE_INFORMATION info
;
560 MEMORY_IMAGE_INFORMATION32
*info32
= ptr
;
562 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
564 info32
->ImageBase
= PtrToUlong( info
.ImageBase
);
565 info32
->SizeOfImage
= info
.SizeOfImage
;
566 info32
->ImageFlags
= info
.ImageFlags
;
569 res_len
= sizeof(MEMORY_IMAGE_INFORMATION32
);
573 case MemoryWineUnixWow64Funcs
:
574 return STATUS_INVALID_INFO_CLASS
;
576 case MemoryWineUnixFuncs
:
577 status
= NtQueryVirtualMemory( handle
, addr
, MemoryWineUnixWow64Funcs
, ptr
, len
, &res_len
);
581 FIXME( "unsupported class %u\n", class );
582 return STATUS_INVALID_INFO_CLASS
;
584 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
) put_size( retlen
, res_len
);
589 /**********************************************************************
590 * wow64_NtReadVirtualMemory
592 NTSTATUS WINAPI
wow64_NtReadVirtualMemory( UINT
*args
)
594 HANDLE process
= get_handle( &args
);
595 const void *addr
= get_ptr( &args
);
596 void *buffer
= get_ptr( &args
);
597 SIZE_T size
= get_ulong( &args
);
598 ULONG
*retlen
= get_ptr( &args
);
603 status
= NtReadVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
604 put_size( retlen
, ret_size
);
609 /**********************************************************************
610 * wow64_NtResetWriteWatch
612 NTSTATUS WINAPI
wow64_NtResetWriteWatch( UINT
*args
)
614 HANDLE process
= get_handle( &args
);
615 void *base
= get_ptr( &args
);
616 SIZE_T size
= get_ulong( &args
);
618 return NtResetWriteWatch( process
, base
, size
);
622 /**********************************************************************
623 * wow64_NtSetInformationVirtualMemory
625 NTSTATUS WINAPI
wow64_NtSetInformationVirtualMemory( UINT
*args
)
627 HANDLE process
= get_handle( &args
);
628 VIRTUAL_MEMORY_INFORMATION_CLASS info_class
= get_ulong( &args
);
629 ULONG count
= get_ulong( &args
);
630 MEMORY_RANGE_ENTRY32
*addresses32
= get_ptr( &args
);
631 PVOID ptr
= get_ptr( &args
);
632 ULONG len
= get_ulong( &args
);
634 MEMORY_RANGE_ENTRY
*addresses
;
636 if (!count
) return STATUS_INVALID_PARAMETER_3
;
637 addresses
= memory_range_entry_array_32to64( addresses32
, count
);
641 case VmPrefetchInformation
:
644 FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n",
645 process
, info_class
, count
, addresses32
, ptr
, len
);
646 return STATUS_INVALID_PARAMETER_2
;
649 return NtSetInformationVirtualMemory( process
, info_class
, count
, addresses
, ptr
, len
);
653 /**********************************************************************
654 * wow64_NtSetLdtEntries
656 NTSTATUS WINAPI
wow64_NtSetLdtEntries( UINT
*args
)
658 ULONG sel1
= get_ulong( &args
);
659 ULONG entry1_low
= get_ulong( &args
);
660 ULONG entry1_high
= get_ulong( &args
);
661 ULONG sel2
= get_ulong( &args
);
662 ULONG entry2_low
= get_ulong( &args
);
663 ULONG entry2_high
= get_ulong( &args
);
665 FIXME( "%04lx %08lx %08lx %04lx %08lx %08lx: stub\n",
666 sel1
, entry1_low
, entry1_high
, sel2
, entry2_low
, entry2_high
);
667 return STATUS_NOT_IMPLEMENTED
;
671 /**********************************************************************
672 * wow64_NtUnlockVirtualMemory
674 NTSTATUS WINAPI
wow64_NtUnlockVirtualMemory( UINT
*args
)
676 HANDLE process
= get_handle( &args
);
677 ULONG
*addr32
= get_ptr( &args
);
678 ULONG
*size32
= get_ptr( &args
);
679 ULONG unknown
= get_ulong( &args
);
685 status
= NtUnlockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
686 size_32to64( &size
, size32
), unknown
);
689 put_addr( addr32
, addr
);
690 put_size( size32
, size
);
696 /**********************************************************************
697 * wow64_NtUnmapViewOfSection
699 NTSTATUS WINAPI
wow64_NtUnmapViewOfSection( UINT
*args
)
701 HANDLE process
= get_handle( &args
);
702 void *addr
= get_ptr( &args
);
704 if (pBTCpuNotifyUnmapViewOfSection
&& RtlIsCurrentProcess( process
))
705 pBTCpuNotifyUnmapViewOfSection( addr
);
707 return NtUnmapViewOfSection( process
, addr
);
711 /**********************************************************************
712 * wow64_NtUnmapViewOfSectionEx
714 NTSTATUS WINAPI
wow64_NtUnmapViewOfSectionEx( UINT
*args
)
716 HANDLE process
= get_handle( &args
);
717 void *addr
= get_ptr( &args
);
718 ULONG flags
= get_ulong( &args
);
720 if (pBTCpuNotifyUnmapViewOfSection
&& RtlIsCurrentProcess( process
))
721 pBTCpuNotifyUnmapViewOfSection( addr
);
723 return NtUnmapViewOfSectionEx( process
, addr
, flags
);
727 /**********************************************************************
728 * wow64_NtWow64AllocateVirtualMemory64
730 NTSTATUS WINAPI
wow64_NtWow64AllocateVirtualMemory64( UINT
*args
)
732 HANDLE process
= get_handle( &args
);
733 void **addr
= get_ptr( &args
);
734 ULONG_PTR zero_bits
= get_ulong64( &args
);
735 SIZE_T
*size
= get_ptr( &args
);
736 ULONG type
= get_ulong( &args
);
737 ULONG protect
= get_ulong( &args
);
739 return NtAllocateVirtualMemory( process
, addr
, zero_bits
, size
, type
, protect
);
743 /**********************************************************************
744 * wow64_NtWow64ReadVirtualMemory64
746 NTSTATUS WINAPI
wow64_NtWow64ReadVirtualMemory64( UINT
*args
)
748 HANDLE process
= get_handle( &args
);
749 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
750 void *buffer
= get_ptr( &args
);
751 SIZE_T size
= get_ulong64( &args
);
752 SIZE_T
*ret_size
= get_ptr( &args
);
754 return NtReadVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
758 /**********************************************************************
759 * wow64_NtWow64WriteVirtualMemory64
761 NTSTATUS WINAPI
wow64_NtWow64WriteVirtualMemory64( UINT
*args
)
763 HANDLE process
= get_handle( &args
);
764 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
765 const void *buffer
= get_ptr( &args
);
766 SIZE_T size
= get_ulong64( &args
);
767 SIZE_T
*ret_size
= get_ptr( &args
);
769 return NtWriteVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
773 /**********************************************************************
774 * wow64_NtWriteVirtualMemory
776 NTSTATUS WINAPI
wow64_NtWriteVirtualMemory( UINT
*args
)
778 HANDLE process
= get_handle( &args
);
779 void *addr
= get_ptr( &args
);
780 const void *buffer
= get_ptr( &args
);
781 SIZE_T size
= get_ulong( &args
);
782 ULONG
*retlen
= get_ptr( &args
);
787 status
= NtWriteVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
788 put_size( retlen
, ret_size
);