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 /**********************************************************************
52 * wow64_NtAllocateVirtualMemory
54 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemory( UINT
*args
)
56 HANDLE process
= get_handle( &args
);
57 ULONG
*addr32
= get_ptr( &args
);
58 ULONG_PTR zero_bits
= get_ulong( &args
);
59 ULONG
*size32
= get_ptr( &args
);
60 ULONG type
= get_ulong( &args
);
61 ULONG protect
= get_ulong( &args
);
67 status
= NtAllocateVirtualMemory( process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
68 size_32to64( &size
, size32
), type
, protect
);
71 put_addr( addr32
, addr
);
72 put_size( size32
, size
);
78 /**********************************************************************
79 * wow64_NtAllocateVirtualMemoryEx
81 NTSTATUS WINAPI
wow64_NtAllocateVirtualMemoryEx( UINT
*args
)
83 HANDLE process
= get_handle( &args
);
84 ULONG
*addr32
= get_ptr( &args
);
85 ULONG
*size32
= get_ptr( &args
);
86 ULONG type
= get_ulong( &args
);
87 ULONG protect
= get_ulong( &args
);
88 MEM_EXTENDED_PARAMETER
*params
= get_ptr( &args
);
89 ULONG count
= get_ulong( &args
);
94 SIZE_T alloc_size
= count
* sizeof(*params
);
95 MEM_EXTENDED_PARAMETER
*params64
;
96 BOOL set_highest_address
= (!*addr32
&& process
== GetCurrentProcess());
97 BOOL add_address_requirements
= set_highest_address
;
98 MEM_ADDRESS_REQUIREMENTS
*buf
;
101 if (count
&& !params
) return STATUS_INVALID_PARAMETER
;
103 for (i
= 0; i
< count
; ++i
)
105 if (params
[i
].Type
== MemExtendedParameterAddressRequirements
)
107 alloc_size
+= sizeof(MEM_ADDRESS_REQUIREMENTS
);
108 add_address_requirements
= FALSE
;
110 else if (params
[i
].Type
&& params
[i
].Type
< MemExtendedParameterMax
)
112 FIXME( "Unsupported parameter type %d.\n", params
[i
].Type
);
116 if (add_address_requirements
)
117 alloc_size
+= sizeof(*params
) + sizeof(MEM_ADDRESS_REQUIREMENTS
);
118 params64
= Wow64AllocateTemp( alloc_size
);
119 memcpy( params64
, params
, count
* sizeof(*params64
) );
120 if (add_address_requirements
)
122 buf
= (MEM_ADDRESS_REQUIREMENTS
*)((char *)params64
+ (count
+ 1) * sizeof(*params64
));
123 params64
[count
].Type
= MemExtendedParameterAddressRequirements
;
124 params64
[count
].Pointer
= buf
;
125 memset(buf
, 0, sizeof(*buf
));
126 buf
->HighestEndingAddress
= (void *)highest_user_address
;
131 buf
= (MEM_ADDRESS_REQUIREMENTS
*)((char *)params64
+ count
* sizeof(*params64
));
133 for (i
= 0; i
< count
; ++i
)
135 if (params64
[i
].Type
== MemExtendedParameterAddressRequirements
)
137 MEM_ADDRESS_REQUIREMENTS32
*p
= (MEM_ADDRESS_REQUIREMENTS32
*)params
[i
].Pointer
;
139 buf
->LowestStartingAddress
= ULongToPtr(p
->LowestStartingAddress
);
140 if (p
->HighestEndingAddress
)
142 if (p
->HighestEndingAddress
> highest_user_address
) return STATUS_INVALID_PARAMETER
;
143 buf
->HighestEndingAddress
= ULongToPtr(p
->HighestEndingAddress
);
147 buf
->HighestEndingAddress
= set_highest_address
? (void *)highest_user_address
: NULL
;
149 buf
->Alignment
= p
->Alignment
;
150 params64
[i
].Pointer
= buf
;
155 status
= NtAllocateVirtualMemoryEx( process
, addr_32to64( &addr
, addr32
), size_32to64( &size
, size32
),
156 type
, protect
, params64
, count
+ add_address_requirements
);
159 put_addr( addr32
, addr
);
160 put_size( size32
, size
);
166 /**********************************************************************
167 * wow64_NtAreMappedFilesTheSame
169 NTSTATUS WINAPI
wow64_NtAreMappedFilesTheSame( UINT
*args
)
171 void *ptr1
= get_ptr( &args
);
172 void *ptr2
= get_ptr( &args
);
174 return NtAreMappedFilesTheSame( ptr1
, ptr2
);
178 /**********************************************************************
179 * wow64_NtFlushVirtualMemory
181 NTSTATUS WINAPI
wow64_NtFlushVirtualMemory( UINT
*args
)
183 HANDLE process
= get_handle( &args
);
184 ULONG
*addr32
= get_ptr( &args
);
185 ULONG
*size32
= get_ptr( &args
);
186 ULONG unknown
= get_ulong( &args
);
192 status
= NtFlushVirtualMemory( process
, (const void **)addr_32to64( &addr
, addr32
),
193 size_32to64( &size
, size32
), unknown
);
196 put_addr( addr32
, addr
);
197 put_size( size32
, size
);
203 /**********************************************************************
204 * wow64_NtFreeVirtualMemory
206 NTSTATUS WINAPI
wow64_NtFreeVirtualMemory( UINT
*args
)
208 HANDLE process
= get_handle( &args
);
209 ULONG
*addr32
= get_ptr( &args
);
210 ULONG
*size32
= get_ptr( &args
);
211 ULONG type
= get_ulong( &args
);
217 status
= NtFreeVirtualMemory( process
, addr_32to64( &addr
, addr32
),
218 size_32to64( &size
, size32
), type
);
221 put_addr( addr32
, addr
);
222 put_size( size32
, size
);
228 /**********************************************************************
229 * wow64_NtGetNlsSectionPtr
231 NTSTATUS WINAPI
wow64_NtGetNlsSectionPtr( UINT
*args
)
233 ULONG type
= get_ulong( &args
);
234 ULONG id
= get_ulong( &args
);
235 void *unknown
= get_ptr( &args
);
236 ULONG
*addr32
= get_ptr( &args
);
237 ULONG
*size32
= get_ptr( &args
);
243 status
= NtGetNlsSectionPtr( type
, id
, unknown
, addr_32to64( &addr
, addr32
),
244 size_32to64( &size
, size32
));
247 put_addr( addr32
, addr
);
248 put_size( size32
, size
);
254 /**********************************************************************
255 * wow64_NtGetWriteWatch
257 NTSTATUS WINAPI
wow64_NtGetWriteWatch( UINT
*args
)
259 HANDLE handle
= get_handle( &args
);
260 ULONG flags
= get_ulong( &args
);
261 void *base
= get_ptr( &args
);
262 SIZE_T size
= get_ulong( &args
);
263 ULONG
*addr_ptr
= get_ptr( &args
);
264 ULONG
*count_ptr
= get_ptr( &args
);
265 ULONG
*granularity
= get_ptr( &args
);
267 ULONG_PTR i
, count
= *count_ptr
;
271 if (!count
|| !size
) return STATUS_INVALID_PARAMETER
;
272 if (flags
& ~WRITE_WATCH_FLAG_RESET
) return STATUS_INVALID_PARAMETER
;
273 if (!addr_ptr
) return STATUS_ACCESS_VIOLATION
;
275 addresses
= Wow64AllocateTemp( count
* sizeof(*addresses
) );
276 if (!(status
= NtGetWriteWatch( handle
, flags
, base
, size
, addresses
, &count
, granularity
)))
278 for (i
= 0; i
< count
; i
++) addr_ptr
[i
] = PtrToUlong( addresses
[i
] );
285 /**********************************************************************
286 * wow64_NtInitializeNlsFiles
288 NTSTATUS WINAPI
wow64_NtInitializeNlsFiles( UINT
*args
)
290 ULONG
*addr32
= get_ptr( &args
);
291 LCID
*lcid
= get_ptr( &args
);
292 LARGE_INTEGER
*size
= get_ptr( &args
);
297 status
= NtInitializeNlsFiles( addr_32to64( &addr
, addr32
), lcid
, size
);
298 if (!status
) put_addr( addr32
, addr
);
303 /**********************************************************************
304 * wow64_NtLockVirtualMemory
306 NTSTATUS WINAPI
wow64_NtLockVirtualMemory( UINT
*args
)
308 HANDLE process
= get_handle( &args
);
309 ULONG
*addr32
= get_ptr( &args
);
310 ULONG
*size32
= get_ptr( &args
);
311 ULONG unknown
= get_ulong( &args
);
317 status
= NtLockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
318 size_32to64( &size
, size32
), unknown
);
321 put_addr( addr32
, addr
);
322 put_size( size32
, size
);
328 /**********************************************************************
329 * wow64_NtMapViewOfSection
331 NTSTATUS WINAPI
wow64_NtMapViewOfSection( UINT
*args
)
333 HANDLE handle
= get_handle( &args
);
334 HANDLE process
= get_handle( &args
);
335 ULONG
*addr32
= get_ptr( &args
);
336 ULONG_PTR zero_bits
= get_ulong( &args
);
337 SIZE_T commit
= get_ulong( &args
);
338 const LARGE_INTEGER
*offset
= get_ptr( &args
);
339 ULONG
*size32
= get_ptr( &args
);
340 SECTION_INHERIT inherit
= get_ulong( &args
);
341 ULONG alloc
= get_ulong( &args
);
342 ULONG protect
= get_ulong( &args
);
348 status
= NtMapViewOfSection( handle
, process
, addr_32to64( &addr
, addr32
), get_zero_bits( zero_bits
),
349 commit
, offset
, size_32to64( &size
, size32
), inherit
, alloc
, protect
);
350 if (NT_SUCCESS(status
))
352 SECTION_IMAGE_INFORMATION info
;
354 if (!NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
))
356 if (info
.Machine
== current_machine
) init_image_mapping( addr
);
358 put_addr( addr32
, addr
);
359 put_size( size32
, size
);
364 /**********************************************************************
365 * wow64_NtMapViewOfSectionEx
367 NTSTATUS WINAPI
wow64_NtMapViewOfSectionEx( UINT
*args
)
369 HANDLE handle
= get_handle( &args
);
370 HANDLE process
= get_handle( &args
);
371 ULONG
*addr32
= get_ptr( &args
);
372 const LARGE_INTEGER
*offset
= get_ptr( &args
);
373 ULONG
*size32
= get_ptr( &args
);
374 ULONG alloc
= get_ulong( &args
);
375 ULONG protect
= get_ulong( &args
);
376 MEM_EXTENDED_PARAMETER
*params
= get_ptr( &args
);
377 ULONG params_count
= get_ulong( &args
);
383 status
= NtMapViewOfSectionEx( handle
, process
, addr_32to64( &addr
, addr32
), offset
, size_32to64( &size
, size32
), alloc
,
384 protect
, params
, params_count
);
385 if (NT_SUCCESS(status
))
387 SECTION_IMAGE_INFORMATION info
;
389 if (!NtQuerySection( handle
, SectionImageInformation
, &info
, sizeof(info
), NULL
))
391 if (info
.Machine
== current_machine
) init_image_mapping( addr
);
393 put_addr( addr32
, addr
);
394 put_size( size32
, size
);
399 /**********************************************************************
400 * wow64_NtProtectVirtualMemory
402 NTSTATUS WINAPI
wow64_NtProtectVirtualMemory( UINT
*args
)
404 HANDLE process
= get_handle( &args
);
405 ULONG
*addr32
= get_ptr( &args
);
406 ULONG
*size32
= get_ptr( &args
);
407 ULONG new_prot
= get_ulong( &args
);
408 ULONG
*old_prot
= get_ptr( &args
);
414 status
= NtProtectVirtualMemory( process
, addr_32to64( &addr
, addr32
),
415 size_32to64( &size
, size32
), new_prot
, old_prot
);
418 put_addr( addr32
, addr
);
419 put_size( size32
, size
);
425 /**********************************************************************
426 * wow64_NtQueryVirtualMemory
428 NTSTATUS WINAPI
wow64_NtQueryVirtualMemory( UINT
*args
)
430 HANDLE handle
= get_handle( &args
);
431 void *addr
= get_ptr( &args
);
432 MEMORY_INFORMATION_CLASS
class = get_ulong( &args
);
433 void *ptr
= get_ptr( &args
);
434 ULONG len
= get_ulong( &args
);
435 ULONG
*retlen
= get_ptr( &args
);
442 case MemoryBasicInformation
: /* MEMORY_BASIC_INFORMATION */
443 if (len
< sizeof(MEMORY_BASIC_INFORMATION32
))
444 status
= STATUS_INFO_LENGTH_MISMATCH
;
445 else if ((ULONG_PTR
)addr
> highest_user_address
)
446 status
= STATUS_INVALID_PARAMETER
;
449 MEMORY_BASIC_INFORMATION info
;
450 MEMORY_BASIC_INFORMATION32
*info32
= ptr
;
452 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
454 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
455 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
456 info32
->AllocationProtect
= info
.AllocationProtect
;
457 info32
->RegionSize
= info
.RegionSize
;
458 info32
->State
= info
.State
;
459 info32
->Protect
= info
.Protect
;
460 info32
->Type
= info
.Type
;
461 if ((ULONG_PTR
)info
.BaseAddress
+ info
.RegionSize
> highest_user_address
)
462 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.BaseAddress
+ 1;
465 res_len
= sizeof(MEMORY_BASIC_INFORMATION32
);
468 case MemoryMappedFilenameInformation
: /* MEMORY_SECTION_NAME */
470 MEMORY_SECTION_NAME
*info
;
471 MEMORY_SECTION_NAME32
*info32
= ptr
;
472 SIZE_T size
= len
+ sizeof(*info
) - sizeof(*info32
);
474 info
= Wow64AllocateTemp( size
);
475 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, size
, &res_len
)))
477 info32
->SectionFileName
.Length
= info
->SectionFileName
.Length
;
478 info32
->SectionFileName
.MaximumLength
= info
->SectionFileName
.MaximumLength
;
479 info32
->SectionFileName
.Buffer
= PtrToUlong( info32
+ 1 );
480 memcpy( info32
+ 1, info
->SectionFileName
.Buffer
, info
->SectionFileName
.MaximumLength
);
482 res_len
+= sizeof(*info32
) - sizeof(*info
);
486 case MemoryRegionInformation
: /* MEMORY_REGION_INFORMATION */
488 if (len
< sizeof(MEMORY_REGION_INFORMATION32
))
489 status
= STATUS_INFO_LENGTH_MISMATCH
;
490 if ((ULONG_PTR
)addr
> highest_user_address
)
491 status
= STATUS_INVALID_PARAMETER
;
494 MEMORY_REGION_INFORMATION info
;
495 MEMORY_REGION_INFORMATION32
*info32
= ptr
;
497 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, &info
, sizeof(info
), &res_len
)))
499 info32
->AllocationBase
= PtrToUlong( info
.AllocationBase
);
500 info32
->AllocationProtect
= info
.AllocationProtect
;
501 info32
->RegionType
= info
.RegionType
;
502 info32
->RegionSize
= info
.RegionSize
;
503 info32
->CommitSize
= info
.CommitSize
;
504 info32
->PartitionId
= info
.PartitionId
;
505 info32
->NodePreference
= info
.NodePreference
;
506 if ((ULONG_PTR
)info
.AllocationBase
+ info
.RegionSize
> highest_user_address
)
507 info32
->RegionSize
= highest_user_address
- (ULONG_PTR
)info
.AllocationBase
+ 1;
510 res_len
= sizeof(MEMORY_REGION_INFORMATION32
);
514 case MemoryWorkingSetExInformation
: /* MEMORY_WORKING_SET_EX_INFORMATION */
516 MEMORY_WORKING_SET_EX_INFORMATION32
*info32
= ptr
;
517 MEMORY_WORKING_SET_EX_INFORMATION
*info
;
518 ULONG i
, count
= len
/ sizeof(*info32
);
520 info
= Wow64AllocateTemp( count
* sizeof(*info
) );
521 for (i
= 0; i
< count
; i
++) info
[i
].VirtualAddress
= ULongToPtr( info32
[i
].VirtualAddress
);
522 if (!(status
= NtQueryVirtualMemory( handle
, addr
, class, info
, count
* sizeof(*info
), &res_len
)))
524 count
= res_len
/ sizeof(*info
);
525 for (i
= 0; i
< count
; i
++) info32
[i
].VirtualAttributes
.Flags
= info
[i
].VirtualAttributes
.Flags
;
526 res_len
= count
* sizeof(*info32
);
531 case MemoryWineUnixWow64Funcs
:
532 return STATUS_INVALID_INFO_CLASS
;
534 case MemoryWineUnixFuncs
:
535 status
= NtQueryVirtualMemory( handle
, addr
, MemoryWineUnixWow64Funcs
, ptr
, len
, &res_len
);
539 FIXME( "unsupported class %u\n", class );
540 return STATUS_INVALID_INFO_CLASS
;
542 if (!status
|| status
== STATUS_INFO_LENGTH_MISMATCH
) put_size( retlen
, res_len
);
547 /**********************************************************************
548 * wow64_NtReadVirtualMemory
550 NTSTATUS WINAPI
wow64_NtReadVirtualMemory( UINT
*args
)
552 HANDLE process
= get_handle( &args
);
553 const void *addr
= get_ptr( &args
);
554 void *buffer
= get_ptr( &args
);
555 SIZE_T size
= get_ulong( &args
);
556 ULONG
*retlen
= get_ptr( &args
);
561 status
= NtReadVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
562 put_size( retlen
, ret_size
);
567 /**********************************************************************
568 * wow64_NtResetWriteWatch
570 NTSTATUS WINAPI
wow64_NtResetWriteWatch( UINT
*args
)
572 HANDLE process
= get_handle( &args
);
573 void *base
= get_ptr( &args
);
574 SIZE_T size
= get_ulong( &args
);
576 return NtResetWriteWatch( process
, base
, size
);
580 /**********************************************************************
581 * wow64_NtSetInformationVirtualMemory
583 NTSTATUS WINAPI
wow64_NtSetInformationVirtualMemory( UINT
*args
)
585 HANDLE process
= get_handle( &args
);
586 VIRTUAL_MEMORY_INFORMATION_CLASS info_class
= get_ulong( &args
);
587 ULONG count
= get_ulong( &args
);
588 MEMORY_RANGE_ENTRY32
*addresses32
= get_ptr( &args
);
589 PVOID ptr
= get_ptr( &args
);
590 ULONG len
= get_ulong( &args
);
592 MEMORY_RANGE_ENTRY
*addresses
;
594 if (!count
) return STATUS_INVALID_PARAMETER_3
;
595 addresses
= memory_range_entry_array_32to64( addresses32
, count
);
599 case VmPrefetchInformation
:
602 FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n",
603 process
, info_class
, count
, addresses32
, ptr
, len
);
604 return STATUS_INVALID_PARAMETER_2
;
607 return NtSetInformationVirtualMemory( process
, info_class
, count
, addresses
, ptr
, len
);
611 /**********************************************************************
612 * wow64_NtSetLdtEntries
614 NTSTATUS WINAPI
wow64_NtSetLdtEntries( UINT
*args
)
616 ULONG sel1
= get_ulong( &args
);
617 ULONG entry1_low
= get_ulong( &args
);
618 ULONG entry1_high
= get_ulong( &args
);
619 ULONG sel2
= get_ulong( &args
);
620 ULONG entry2_low
= get_ulong( &args
);
621 ULONG entry2_high
= get_ulong( &args
);
623 FIXME( "%04lx %08lx %08lx %04lx %08lx %08lx: stub\n",
624 sel1
, entry1_low
, entry1_high
, sel2
, entry2_low
, entry2_high
);
625 return STATUS_NOT_IMPLEMENTED
;
629 /**********************************************************************
630 * wow64_NtUnlockVirtualMemory
632 NTSTATUS WINAPI
wow64_NtUnlockVirtualMemory( UINT
*args
)
634 HANDLE process
= get_handle( &args
);
635 ULONG
*addr32
= get_ptr( &args
);
636 ULONG
*size32
= get_ptr( &args
);
637 ULONG unknown
= get_ulong( &args
);
643 status
= NtUnlockVirtualMemory( process
, addr_32to64( &addr
, addr32
),
644 size_32to64( &size
, size32
), unknown
);
647 put_addr( addr32
, addr
);
648 put_size( size32
, size
);
654 /**********************************************************************
655 * wow64_NtUnmapViewOfSection
657 NTSTATUS WINAPI
wow64_NtUnmapViewOfSection( UINT
*args
)
659 HANDLE process
= get_handle( &args
);
660 void *addr
= get_ptr( &args
);
662 return NtUnmapViewOfSection( process
, addr
);
666 /**********************************************************************
667 * wow64_NtUnmapViewOfSectionEx
669 NTSTATUS WINAPI
wow64_NtUnmapViewOfSectionEx( UINT
*args
)
671 HANDLE process
= get_handle( &args
);
672 void *addr
= get_ptr( &args
);
673 ULONG flags
= get_ulong( &args
);
675 return NtUnmapViewOfSectionEx( process
, addr
, flags
);
679 /**********************************************************************
680 * wow64_NtWow64AllocateVirtualMemory64
682 NTSTATUS WINAPI
wow64_NtWow64AllocateVirtualMemory64( UINT
*args
)
684 HANDLE process
= get_handle( &args
);
685 void **addr
= get_ptr( &args
);
686 ULONG_PTR zero_bits
= get_ulong64( &args
);
687 SIZE_T
*size
= get_ptr( &args
);
688 ULONG type
= get_ulong( &args
);
689 ULONG protect
= get_ulong( &args
);
691 return NtAllocateVirtualMemory( process
, addr
, zero_bits
, size
, type
, protect
);
695 /**********************************************************************
696 * wow64_NtWow64ReadVirtualMemory64
698 NTSTATUS WINAPI
wow64_NtWow64ReadVirtualMemory64( UINT
*args
)
700 HANDLE process
= get_handle( &args
);
701 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
702 void *buffer
= get_ptr( &args
);
703 SIZE_T size
= get_ulong64( &args
);
704 SIZE_T
*ret_size
= get_ptr( &args
);
706 return NtReadVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
710 /**********************************************************************
711 * wow64_NtWow64WriteVirtualMemory64
713 NTSTATUS WINAPI
wow64_NtWow64WriteVirtualMemory64( UINT
*args
)
715 HANDLE process
= get_handle( &args
);
716 void *addr
= (void *)(ULONG_PTR
)get_ulong64( &args
);
717 const void *buffer
= get_ptr( &args
);
718 SIZE_T size
= get_ulong64( &args
);
719 SIZE_T
*ret_size
= get_ptr( &args
);
721 return NtWriteVirtualMemory( process
, addr
, buffer
, size
, ret_size
);
725 /**********************************************************************
726 * wow64_NtWriteVirtualMemory
728 NTSTATUS WINAPI
wow64_NtWriteVirtualMemory( UINT
*args
)
730 HANDLE process
= get_handle( &args
);
731 void *addr
= get_ptr( &args
);
732 const void *buffer
= get_ptr( &args
);
733 SIZE_T size
= get_ulong( &args
);
734 ULONG
*retlen
= get_ptr( &args
);
739 status
= NtWriteVirtualMemory( process
, addr
, buffer
, size
, &ret_size
);
740 put_size( retlen
, ret_size
);