mf/tests: Test AAC decoder MFT presence and media types.
[wine.git] / dlls / wow64 / virtual.c
blob8b7d022301f1ab9aee54fec80a9a6ebdff40a813
1 /*
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
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnt.h"
28 #include "winternl.h"
29 #include "winioctl.h"
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,
37 ULONG count )
39 MEMORY_RANGE_ENTRY *addresses = Wow64AllocateTemp( sizeof(MEMORY_RANGE_ENTRY) * count );
40 ULONG i;
42 for (i = 0; i < count; i++)
44 addresses[i].VirtualAddress = ULongToPtr( addresses32[i].VirtualAddress );
45 addresses[i].NumberOfBytes = addresses32[i].NumberOfBytes;
48 return addresses;
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 );
63 void *addr;
64 SIZE_T size;
65 NTSTATUS status;
67 status = NtAllocateVirtualMemory( process, addr_32to64( &addr, addr32 ), get_zero_bits( zero_bits ),
68 size_32to64( &size, size32 ), type, protect );
69 if (!status)
71 put_addr( addr32, addr );
72 put_size( size32, size );
74 return status;
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 );
91 void *addr;
92 SIZE_T size;
93 NTSTATUS status;
95 if (count) FIXME( "%ld extended parameters %p\n", count, params );
96 status = NtAllocateVirtualMemoryEx( process, addr_32to64( &addr, addr32 ), size_32to64( &size, size32 ),
97 type, protect, params, count );
98 if (!status)
100 put_addr( addr32, addr );
101 put_size( size32, size );
103 return status;
107 /**********************************************************************
108 * wow64_NtAreMappedFilesTheSame
110 NTSTATUS WINAPI wow64_NtAreMappedFilesTheSame( UINT *args )
112 void *ptr1 = get_ptr( &args );
113 void *ptr2 = get_ptr( &args );
115 return NtAreMappedFilesTheSame( ptr1, ptr2 );
119 /**********************************************************************
120 * wow64_NtFlushVirtualMemory
122 NTSTATUS WINAPI wow64_NtFlushVirtualMemory( UINT *args )
124 HANDLE process = get_handle( &args );
125 ULONG *addr32 = get_ptr( &args );
126 ULONG *size32 = get_ptr( &args );
127 ULONG unknown = get_ulong( &args );
129 void *addr;
130 SIZE_T size;
131 NTSTATUS status;
133 status = NtFlushVirtualMemory( process, (const void **)addr_32to64( &addr, addr32 ),
134 size_32to64( &size, size32 ), unknown );
135 if (!status)
137 put_addr( addr32, addr );
138 put_size( size32, size );
140 return status;
144 /**********************************************************************
145 * wow64_NtFreeVirtualMemory
147 NTSTATUS WINAPI wow64_NtFreeVirtualMemory( UINT *args )
149 HANDLE process = get_handle( &args );
150 ULONG *addr32 = get_ptr( &args );
151 ULONG *size32 = get_ptr( &args );
152 ULONG type = get_ulong( &args );
154 void *addr;
155 SIZE_T size;
156 NTSTATUS status;
158 status = NtFreeVirtualMemory( process, addr_32to64( &addr, addr32 ),
159 size_32to64( &size, size32 ), type );
160 if (!status)
162 put_addr( addr32, addr );
163 put_size( size32, size );
165 return status;
169 /**********************************************************************
170 * wow64_NtGetNlsSectionPtr
172 NTSTATUS WINAPI wow64_NtGetNlsSectionPtr( UINT *args )
174 ULONG type = get_ulong( &args );
175 ULONG id = get_ulong( &args );
176 void *unknown = get_ptr( &args );
177 ULONG *addr32 = get_ptr( &args );
178 ULONG *size32 = get_ptr( &args );
180 void *addr;
181 SIZE_T size;
182 NTSTATUS status;
184 status = NtGetNlsSectionPtr( type, id, unknown, addr_32to64( &addr, addr32 ),
185 size_32to64( &size, size32 ));
186 if (!status)
188 put_addr( addr32, addr );
189 put_size( size32, size );
191 return status;
195 /**********************************************************************
196 * wow64_NtGetWriteWatch
198 NTSTATUS WINAPI wow64_NtGetWriteWatch( UINT *args )
200 HANDLE handle = get_handle( &args );
201 ULONG flags = get_ulong( &args );
202 void *base = get_ptr( &args );
203 SIZE_T size = get_ulong( &args );
204 ULONG *addr_ptr = get_ptr( &args );
205 ULONG *count_ptr = get_ptr( &args );
206 ULONG *granularity = get_ptr( &args );
208 ULONG_PTR i, count = *count_ptr;
209 void **addresses;
210 NTSTATUS status;
212 if (!count || !size) return STATUS_INVALID_PARAMETER;
213 if (flags & ~WRITE_WATCH_FLAG_RESET) return STATUS_INVALID_PARAMETER;
214 if (!addr_ptr) return STATUS_ACCESS_VIOLATION;
216 addresses = Wow64AllocateTemp( count * sizeof(*addresses) );
217 if (!(status = NtGetWriteWatch( handle, flags, base, size, addresses, &count, granularity )))
219 for (i = 0; i < count; i++) addr_ptr[i] = PtrToUlong( addresses[i] );
220 *count_ptr = count;
222 return status;
226 /**********************************************************************
227 * wow64_NtInitializeNlsFiles
229 NTSTATUS WINAPI wow64_NtInitializeNlsFiles( UINT *args )
231 ULONG *addr32 = get_ptr( &args );
232 LCID *lcid = get_ptr( &args );
233 LARGE_INTEGER *size = get_ptr( &args );
235 void *addr;
236 NTSTATUS status;
238 status = NtInitializeNlsFiles( addr_32to64( &addr, addr32 ), lcid, size );
239 if (!status) put_addr( addr32, addr );
240 return status;
244 /**********************************************************************
245 * wow64_NtLockVirtualMemory
247 NTSTATUS WINAPI wow64_NtLockVirtualMemory( UINT *args )
249 HANDLE process = get_handle( &args );
250 ULONG *addr32 = get_ptr( &args );
251 ULONG *size32 = get_ptr( &args );
252 ULONG unknown = get_ulong( &args );
254 void *addr;
255 SIZE_T size;
256 NTSTATUS status;
258 status = NtLockVirtualMemory( process, addr_32to64( &addr, addr32 ),
259 size_32to64( &size, size32 ), unknown );
260 if (!status)
262 put_addr( addr32, addr );
263 put_size( size32, size );
265 return status;
269 /**********************************************************************
270 * wow64_NtMapViewOfSection
272 NTSTATUS WINAPI wow64_NtMapViewOfSection( UINT *args )
274 HANDLE handle = get_handle( &args );
275 HANDLE process = get_handle( &args );
276 ULONG *addr32 = get_ptr( &args );
277 ULONG_PTR zero_bits = get_ulong( &args );
278 SIZE_T commit = get_ulong( &args );
279 const LARGE_INTEGER *offset = get_ptr( &args );
280 ULONG *size32 = get_ptr( &args );
281 SECTION_INHERIT inherit = get_ulong( &args );
282 ULONG alloc = get_ulong( &args );
283 ULONG protect = get_ulong( &args );
285 void *addr;
286 SIZE_T size;
287 NTSTATUS status;
289 status = NtMapViewOfSection( handle, process, addr_32to64( &addr, addr32 ), get_zero_bits( zero_bits ),
290 commit, offset, size_32to64( &size, size32 ), inherit, alloc, protect );
291 if (NT_SUCCESS(status))
293 SECTION_IMAGE_INFORMATION info;
295 if (!NtQuerySection( handle, SectionImageInformation, &info, sizeof(info), NULL ))
297 if (info.Machine == current_machine) init_image_mapping( addr );
299 put_addr( addr32, addr );
300 put_size( size32, size );
302 return status;
305 /**********************************************************************
306 * wow64_NtMapViewOfSectionEx
308 NTSTATUS WINAPI wow64_NtMapViewOfSectionEx( UINT *args )
310 HANDLE handle = get_handle( &args );
311 HANDLE process = get_handle( &args );
312 ULONG *addr32 = get_ptr( &args );
313 const LARGE_INTEGER *offset = get_ptr( &args );
314 ULONG *size32 = get_ptr( &args );
315 ULONG alloc = get_ulong( &args );
316 ULONG protect = get_ulong( &args );
317 MEM_EXTENDED_PARAMETER *params = get_ptr( &args );
318 ULONG params_count = get_ulong( &args );
320 void *addr;
321 SIZE_T size;
322 NTSTATUS status;
324 status = NtMapViewOfSectionEx( handle, process, addr_32to64( &addr, addr32 ), offset, size_32to64( &size, size32 ), alloc,
325 protect, params, params_count );
326 if (NT_SUCCESS(status))
328 SECTION_IMAGE_INFORMATION info;
330 if (!NtQuerySection( handle, SectionImageInformation, &info, sizeof(info), NULL ))
332 if (info.Machine == current_machine) init_image_mapping( addr );
334 put_addr( addr32, addr );
335 put_size( size32, size );
337 return status;
340 /**********************************************************************
341 * wow64_NtProtectVirtualMemory
343 NTSTATUS WINAPI wow64_NtProtectVirtualMemory( UINT *args )
345 HANDLE process = get_handle( &args );
346 ULONG *addr32 = get_ptr( &args );
347 ULONG *size32 = get_ptr( &args );
348 ULONG new_prot = get_ulong( &args );
349 ULONG *old_prot = get_ptr( &args );
351 void *addr;
352 SIZE_T size;
353 NTSTATUS status;
355 status = NtProtectVirtualMemory( process, addr_32to64( &addr, addr32 ),
356 size_32to64( &size, size32 ), new_prot, old_prot );
357 if (!status)
359 put_addr( addr32, addr );
360 put_size( size32, size );
362 return status;
366 /**********************************************************************
367 * wow64_NtQueryVirtualMemory
369 NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
371 HANDLE handle = get_handle( &args );
372 void *addr = get_ptr( &args );
373 MEMORY_INFORMATION_CLASS class = get_ulong( &args );
374 void *ptr = get_ptr( &args );
375 ULONG len = get_ulong( &args );
376 ULONG *retlen = get_ptr( &args );
378 SIZE_T res_len = 0;
379 NTSTATUS status;
381 switch (class)
383 case MemoryBasicInformation: /* MEMORY_BASIC_INFORMATION */
384 if (len < sizeof(MEMORY_BASIC_INFORMATION32))
385 status = STATUS_INFO_LENGTH_MISMATCH;
386 else if ((ULONG_PTR)addr > highest_user_address)
387 status = STATUS_INVALID_PARAMETER;
388 else
390 MEMORY_BASIC_INFORMATION info;
391 MEMORY_BASIC_INFORMATION32 *info32 = ptr;
393 if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len )))
395 info32->BaseAddress = PtrToUlong( info.BaseAddress );
396 info32->AllocationBase = PtrToUlong( info.AllocationBase );
397 info32->AllocationProtect = info.AllocationProtect;
398 info32->RegionSize = info.RegionSize;
399 info32->State = info.State;
400 info32->Protect = info.Protect;
401 info32->Type = info.Type;
404 res_len = sizeof(MEMORY_BASIC_INFORMATION32);
405 break;
407 case MemoryMappedFilenameInformation: /* MEMORY_SECTION_NAME */
409 MEMORY_SECTION_NAME *info;
410 MEMORY_SECTION_NAME32 *info32 = ptr;
411 SIZE_T size = len + sizeof(*info) - sizeof(*info32);
413 info = Wow64AllocateTemp( size );
414 if (!(status = NtQueryVirtualMemory( handle, addr, class, info, size, &res_len )))
416 info32->SectionFileName.Length = info->SectionFileName.Length;
417 info32->SectionFileName.MaximumLength = info->SectionFileName.MaximumLength;
418 info32->SectionFileName.Buffer = PtrToUlong( info32 + 1 );
419 memcpy( info32 + 1, info->SectionFileName.Buffer, info->SectionFileName.MaximumLength );
421 res_len += sizeof(*info32) - sizeof(*info);
422 break;
425 case MemoryWorkingSetExInformation: /* MEMORY_WORKING_SET_EX_INFORMATION */
427 MEMORY_WORKING_SET_EX_INFORMATION32 *info32 = ptr;
428 MEMORY_WORKING_SET_EX_INFORMATION *info;
429 ULONG i, count = len / sizeof(*info32);
431 info = Wow64AllocateTemp( count * sizeof(*info) );
432 for (i = 0; i < count; i++) info[i].VirtualAddress = ULongToPtr( info32[i].VirtualAddress );
433 if (!(status = NtQueryVirtualMemory( handle, addr, class, info, count * sizeof(*info), &res_len )))
435 count = res_len / sizeof(*info);
436 for (i = 0; i < count; i++) info32[i].VirtualAttributes.Flags = info[i].VirtualAttributes.Flags;
437 res_len = count * sizeof(*info32);
439 break;
442 case MemoryWineUnixWow64Funcs:
443 return STATUS_INVALID_INFO_CLASS;
445 case MemoryWineUnixFuncs:
446 status = NtQueryVirtualMemory( handle, addr, MemoryWineUnixWow64Funcs, ptr, len, &res_len );
447 break;
449 default:
450 FIXME( "unsupported class %u\n", class );
451 return STATUS_INVALID_INFO_CLASS;
453 if (!status || status == STATUS_INFO_LENGTH_MISMATCH) put_size( retlen, res_len );
454 return status;
458 /**********************************************************************
459 * wow64_NtReadVirtualMemory
461 NTSTATUS WINAPI wow64_NtReadVirtualMemory( UINT *args )
463 HANDLE process = get_handle( &args );
464 const void *addr = get_ptr( &args );
465 void *buffer = get_ptr( &args );
466 SIZE_T size = get_ulong( &args );
467 ULONG *retlen = get_ptr( &args );
469 SIZE_T ret_size;
470 NTSTATUS status;
472 status = NtReadVirtualMemory( process, addr, buffer, size, &ret_size );
473 put_size( retlen, ret_size );
474 return status;
478 /**********************************************************************
479 * wow64_NtResetWriteWatch
481 NTSTATUS WINAPI wow64_NtResetWriteWatch( UINT *args )
483 HANDLE process = get_handle( &args );
484 void *base = get_ptr( &args );
485 SIZE_T size = get_ulong( &args );
487 return NtResetWriteWatch( process, base, size );
491 /**********************************************************************
492 * wow64_NtSetInformationVirtualMemory
494 NTSTATUS WINAPI wow64_NtSetInformationVirtualMemory( UINT *args )
496 HANDLE process = get_handle( &args );
497 VIRTUAL_MEMORY_INFORMATION_CLASS info_class = get_ulong( &args );
498 ULONG count = get_ulong( &args );
499 MEMORY_RANGE_ENTRY32 *addresses32 = get_ptr( &args );
500 PVOID ptr = get_ptr( &args );
501 ULONG len = get_ulong( &args );
503 MEMORY_RANGE_ENTRY *addresses;
505 if (!count) return STATUS_INVALID_PARAMETER_3;
506 addresses = memory_range_entry_array_32to64( addresses32, count );
508 switch (info_class)
510 case VmPrefetchInformation:
511 break;
512 default:
513 FIXME( "(%p,info_class=%u,%lu,%p,%p,%lu): not implemented\n",
514 process, info_class, count, addresses32, ptr, len );
515 return STATUS_INVALID_PARAMETER_2;
518 return NtSetInformationVirtualMemory( process, info_class, count, addresses, ptr, len );
522 /**********************************************************************
523 * wow64_NtSetLdtEntries
525 NTSTATUS WINAPI wow64_NtSetLdtEntries( UINT *args )
527 ULONG sel1 = get_ulong( &args );
528 ULONG entry1_low = get_ulong( &args );
529 ULONG entry1_high = get_ulong( &args );
530 ULONG sel2 = get_ulong( &args );
531 ULONG entry2_low = get_ulong( &args );
532 ULONG entry2_high = get_ulong( &args );
534 FIXME( "%04lx %08lx %08lx %04lx %08lx %08lx: stub\n",
535 sel1, entry1_low, entry1_high, sel2, entry2_low, entry2_high );
536 return STATUS_NOT_IMPLEMENTED;
540 /**********************************************************************
541 * wow64_NtUnlockVirtualMemory
543 NTSTATUS WINAPI wow64_NtUnlockVirtualMemory( UINT *args )
545 HANDLE process = get_handle( &args );
546 ULONG *addr32 = get_ptr( &args );
547 ULONG *size32 = get_ptr( &args );
548 ULONG unknown = get_ulong( &args );
550 void *addr;
551 SIZE_T size;
552 NTSTATUS status;
554 status = NtUnlockVirtualMemory( process, addr_32to64( &addr, addr32 ),
555 size_32to64( &size, size32 ), unknown );
556 if (!status)
558 put_addr( addr32, addr );
559 put_size( size32, size );
561 return status;
565 /**********************************************************************
566 * wow64_NtUnmapViewOfSection
568 NTSTATUS WINAPI wow64_NtUnmapViewOfSection( UINT *args )
570 HANDLE process = get_handle( &args );
571 void *addr = get_ptr( &args );
573 return NtUnmapViewOfSection( process, addr );
577 /**********************************************************************
578 * wow64_NtUnmapViewOfSectionEx
580 NTSTATUS WINAPI wow64_NtUnmapViewOfSectionEx( UINT *args )
582 HANDLE process = get_handle( &args );
583 void *addr = get_ptr( &args );
584 ULONG flags = get_ulong( &args );
586 return NtUnmapViewOfSectionEx( process, addr, flags );
590 /**********************************************************************
591 * wow64_NtWow64AllocateVirtualMemory64
593 NTSTATUS WINAPI wow64_NtWow64AllocateVirtualMemory64( UINT *args )
595 HANDLE process = get_handle( &args );
596 void **addr = get_ptr( &args );
597 ULONG_PTR zero_bits = get_ulong64( &args );
598 SIZE_T *size = get_ptr( &args );
599 ULONG type = get_ulong( &args );
600 ULONG protect = get_ulong( &args );
602 return NtAllocateVirtualMemory( process, addr, zero_bits, size, type, protect );
606 /**********************************************************************
607 * wow64_NtWow64ReadVirtualMemory64
609 NTSTATUS WINAPI wow64_NtWow64ReadVirtualMemory64( UINT *args )
611 HANDLE process = get_handle( &args );
612 void *addr = (void *)(ULONG_PTR)get_ulong64( &args );
613 void *buffer = get_ptr( &args );
614 SIZE_T size = get_ulong64( &args );
615 SIZE_T *ret_size = get_ptr( &args );
617 return NtReadVirtualMemory( process, addr, buffer, size, ret_size );
621 /**********************************************************************
622 * wow64_NtWow64WriteVirtualMemory64
624 NTSTATUS WINAPI wow64_NtWow64WriteVirtualMemory64( UINT *args )
626 HANDLE process = get_handle( &args );
627 void *addr = (void *)(ULONG_PTR)get_ulong64( &args );
628 const void *buffer = get_ptr( &args );
629 SIZE_T size = get_ulong64( &args );
630 SIZE_T *ret_size = get_ptr( &args );
632 return NtWriteVirtualMemory( process, addr, buffer, size, ret_size );
636 /**********************************************************************
637 * wow64_NtWriteVirtualMemory
639 NTSTATUS WINAPI wow64_NtWriteVirtualMemory( UINT *args )
641 HANDLE process = get_handle( &args );
642 void *addr = get_ptr( &args );
643 const void *buffer = get_ptr( &args );
644 SIZE_T size = get_ulong( &args );
645 ULONG *retlen = get_ptr( &args );
647 SIZE_T ret_size;
648 NTSTATUS status;
650 status = NtWriteVirtualMemory( process, addr, buffer, size, &ret_size );
651 put_size( retlen, ret_size );
652 return status;