sapi: Add SpMMAudioOut stub.
[wine.git] / dlls / wow64 / process.c
blob2182491bbfb0dbed0580dc40c099cee2c7b28e3d
1 /*
2 * WoW64 process (and thread) 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 "wow64_private.h"
30 #include "wine/asm.h"
31 #include "wine/exception.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(wow);
37 static BOOL is_process_wow64( HANDLE handle )
39 ULONG_PTR info;
41 if (handle == GetCurrentProcess()) return TRUE;
42 if (NtQueryInformationProcess( handle, ProcessWow64Information, &info, sizeof(info), NULL ))
43 return FALSE;
44 return !!info;
48 static BOOL is_process_id_wow64( const CLIENT_ID *id )
50 HANDLE handle;
51 BOOL ret = FALSE;
53 if (id->UniqueProcess == ULongToHandle(GetCurrentProcessId())) return TRUE;
54 if (!NtOpenProcess( &handle, PROCESS_QUERY_LIMITED_INFORMATION, NULL, id ))
56 ret = is_process_wow64( handle );
57 NtClose( handle );
59 return ret;
63 static RTL_USER_PROCESS_PARAMETERS *process_params_32to64( RTL_USER_PROCESS_PARAMETERS **params,
64 RTL_USER_PROCESS_PARAMETERS32 *params32 )
66 UNICODE_STRING image, dllpath, curdir, cmdline, title, desktop, shell, runtime;
67 RTL_USER_PROCESS_PARAMETERS *ret;
69 *params = NULL;
70 if (RtlCreateProcessParametersEx( &ret, unicode_str_32to64( &image, &params32->ImagePathName ),
71 unicode_str_32to64( &dllpath, &params32->DllPath ),
72 unicode_str_32to64( &curdir, &params32->CurrentDirectory.DosPath ),
73 unicode_str_32to64( &cmdline, &params32->CommandLine ),
74 ULongToPtr( params32->Environment ),
75 unicode_str_32to64( &title, &params32->WindowTitle ),
76 unicode_str_32to64( &desktop, &params32->Desktop ),
77 unicode_str_32to64( &shell, &params32->ShellInfo ),
78 unicode_str_32to64( &runtime, &params32->RuntimeInfo ),
79 PROCESS_PARAMS_FLAG_NORMALIZED ))
80 return NULL;
82 ret->DebugFlags = params32->DebugFlags;
83 ret->ConsoleHandle = LongToHandle( params32->ConsoleHandle );
84 ret->ConsoleFlags = params32->ConsoleFlags;
85 ret->hStdInput = LongToHandle( params32->hStdInput );
86 ret->hStdOutput = LongToHandle( params32->hStdOutput );
87 ret->hStdError = LongToHandle( params32->hStdError );
88 ret->dwX = params32->dwX;
89 ret->dwY = params32->dwY;
90 ret->dwXSize = params32->dwXSize;
91 ret->dwYSize = params32->dwYSize;
92 ret->dwXCountChars = params32->dwXCountChars;
93 ret->dwYCountChars = params32->dwYCountChars;
94 ret->dwFillAttribute = params32->dwFillAttribute;
95 ret->dwFlags = params32->dwFlags;
96 ret->wShowWindow = params32->wShowWindow;
97 ret->EnvironmentVersion = params32->EnvironmentVersion;
98 ret->PackageDependencyData = ULongToPtr( params32->PackageDependencyData );
99 ret->ProcessGroupId = params32->ProcessGroupId;
100 ret->LoaderThreads = params32->LoaderThreads;
101 *params = ret;
102 return ret;
106 static void put_ps_create_info( PS_CREATE_INFO32 *info32, const PS_CREATE_INFO *info )
108 info32->State = info->State;
109 switch (info->State)
111 case PsCreateInitialState:
112 info32->InitState.InitFlags = info->InitState.InitFlags;
113 info32->InitState.AdditionalFileAccess = info->InitState.AdditionalFileAccess;
114 break;
115 case PsCreateFailOnSectionCreate:
116 info32->FailSection.FileHandle = HandleToLong( info->FailSection.FileHandle );
117 break;
118 case PsCreateFailExeFormat:
119 info32->ExeFormat.DllCharacteristics = info->ExeFormat.DllCharacteristics;
120 break;
121 case PsCreateFailExeName:
122 info32->ExeName.IFEOKey = HandleToLong( info->ExeName.IFEOKey );
123 break;
124 case PsCreateSuccess:
125 info32->SuccessState.OutputFlags = info->SuccessState.OutputFlags;
126 info32->SuccessState.FileHandle = HandleToLong( info->SuccessState.FileHandle );
127 info32->SuccessState.SectionHandle = HandleToLong( info->SuccessState.SectionHandle );
128 info32->SuccessState.UserProcessParametersNative = info->SuccessState.UserProcessParametersNative;
129 info32->SuccessState.UserProcessParametersWow64 = info->SuccessState.UserProcessParametersWow64;
130 info32->SuccessState.CurrentParameterFlags = info->SuccessState.CurrentParameterFlags;
131 info32->SuccessState.PebAddressNative = info->SuccessState.PebAddressNative;
132 info32->SuccessState.PebAddressWow64 = info->SuccessState.PebAddressWow64;
133 info32->SuccessState.ManifestAddress = info->SuccessState.ManifestAddress;
134 info32->SuccessState.ManifestSize = info->SuccessState.ManifestSize;
135 break;
136 default:
137 break;
142 static PS_ATTRIBUTE_LIST *ps_attributes_32to64( PS_ATTRIBUTE_LIST **attr, const PS_ATTRIBUTE_LIST32 *attr32 )
144 PS_ATTRIBUTE_LIST *ret;
145 ULONG i, count;
147 if (!attr32) return NULL;
148 count = (attr32->TotalLength - sizeof(attr32->TotalLength)) / sizeof(PS_ATTRIBUTE32);
149 ret = Wow64AllocateTemp( offsetof(PS_ATTRIBUTE_LIST, Attributes[count]) );
150 ret->TotalLength = offsetof( PS_ATTRIBUTE_LIST, Attributes[count] );
151 for (i = 0; i < count; i++)
153 ret->Attributes[i].Attribute = attr32->Attributes[i].Attribute;
154 ret->Attributes[i].Size = attr32->Attributes[i].Size;
155 ret->Attributes[i].Value = attr32->Attributes[i].Value;
156 ret->Attributes[i].ReturnLength = NULL;
157 switch (ret->Attributes[i].Attribute)
159 case PS_ATTRIBUTE_IMAGE_NAME:
161 OBJECT_ATTRIBUTES attr;
162 UNICODE_STRING path;
164 path.Length = ret->Attributes[i].Size;
165 path.Buffer = ret->Attributes[i].ValuePtr;
166 InitializeObjectAttributes( &attr, &path, OBJ_CASE_INSENSITIVE, 0, 0 );
167 if (get_file_redirect( &attr ))
169 ret->Attributes[i].Size = attr.ObjectName->Length;
170 ret->Attributes[i].ValuePtr = attr.ObjectName->Buffer;
173 break;
174 case PS_ATTRIBUTE_HANDLE_LIST:
175 case PS_ATTRIBUTE_JOB_LIST:
177 ULONG j, handles_count = attr32->Attributes[i].Size / sizeof(ULONG);
179 ret->Attributes[i].Size = handles_count * sizeof(HANDLE);
180 ret->Attributes[i].ValuePtr = Wow64AllocateTemp( ret->Attributes[i].Size );
181 for (j = 0; j < handles_count; j++)
182 ((HANDLE *)ret->Attributes[i].ValuePtr)[j] =
183 LongToHandle( ((LONG *)ULongToPtr(attr32->Attributes[i].Value))[j] );
185 break;
186 case PS_ATTRIBUTE_PARENT_PROCESS:
187 case PS_ATTRIBUTE_DEBUG_PORT:
188 case PS_ATTRIBUTE_TOKEN:
189 ret->Attributes[i].Size = sizeof(HANDLE);
190 ret->Attributes[i].ValuePtr = LongToHandle( attr32->Attributes[i].Value );
191 break;
192 case PS_ATTRIBUTE_CLIENT_ID:
193 ret->Attributes[i].Size = sizeof(CLIENT_ID);
194 ret->Attributes[i].ValuePtr = Wow64AllocateTemp( ret->Attributes[i].Size );
195 break;
196 case PS_ATTRIBUTE_IMAGE_INFO:
197 ret->Attributes[i].Size = sizeof(SECTION_IMAGE_INFORMATION);
198 ret->Attributes[i].ValuePtr = Wow64AllocateTemp( ret->Attributes[i].Size );
199 break;
200 case PS_ATTRIBUTE_TEB_ADDRESS:
201 ret->Attributes[i].Size = sizeof(TEB *);
202 ret->Attributes[i].ValuePtr = Wow64AllocateTemp( ret->Attributes[i].Size );
203 break;
206 *attr = ret;
207 return ret;
211 static void put_ps_attributes( PS_ATTRIBUTE_LIST32 *attr32, const PS_ATTRIBUTE_LIST *attr )
213 ULONG i;
215 if (!attr32) return;
216 for (i = 0; i < (attr32->TotalLength - sizeof(attr32->TotalLength)) / sizeof(PS_ATTRIBUTE32); i++)
218 switch (attr->Attributes[i].Attribute)
220 case PS_ATTRIBUTE_CLIENT_ID:
222 CLIENT_ID32 id32;
223 ULONG size = min( attr32->Attributes[i].Size, sizeof(id32) );
224 put_client_id( &id32, attr->Attributes[i].ValuePtr );
225 memcpy( ULongToPtr( attr32->Attributes[i].Value ), &id32, size );
226 if (attr32->Attributes[i].ReturnLength)
227 *(ULONG *)ULongToPtr(attr32->Attributes[i].ReturnLength) = size;
228 break;
230 case PS_ATTRIBUTE_IMAGE_INFO:
232 SECTION_IMAGE_INFORMATION32 info32;
233 ULONG size = min( attr32->Attributes[i].Size, sizeof(info32) );
234 put_section_image_info( &info32, attr->Attributes[i].ValuePtr );
235 memcpy( ULongToPtr( attr32->Attributes[i].Value ), &info32, size );
236 if (attr32->Attributes[i].ReturnLength)
237 *(ULONG *)ULongToPtr(attr32->Attributes[i].ReturnLength) = size;
238 break;
240 case PS_ATTRIBUTE_TEB_ADDRESS:
242 TEB **teb = attr->Attributes[i].ValuePtr;
243 ULONG teb32 = PtrToUlong( *teb ) + 0x2000;
244 ULONG size = min( attr->Attributes[i].Size, sizeof(teb32) );
245 memcpy( ULongToPtr( attr32->Attributes[i].Value ), &teb32, size );
246 if (attr32->Attributes[i].ReturnLength)
247 *(ULONG *)ULongToPtr(attr32->Attributes[i].ReturnLength) = size;
248 break;
255 void put_vm_counters( VM_COUNTERS_EX32 *info32, const VM_COUNTERS_EX *info, ULONG size )
257 info32->PeakVirtualSize = info->PeakVirtualSize;
258 info32->VirtualSize = info->VirtualSize;
259 info32->PageFaultCount = info->PageFaultCount;
260 info32->PeakWorkingSetSize = info->PeakWorkingSetSize;
261 info32->WorkingSetSize = info->WorkingSetSize;
262 info32->QuotaPeakPagedPoolUsage = info->QuotaPeakPagedPoolUsage;
263 info32->QuotaPagedPoolUsage = info->QuotaPagedPoolUsage;
264 info32->QuotaPeakNonPagedPoolUsage = info->QuotaPeakNonPagedPoolUsage;
265 info32->QuotaNonPagedPoolUsage = info->QuotaNonPagedPoolUsage;
266 info32->PagefileUsage = info->PagefileUsage;
267 info32->PeakPagefileUsage = info->PeakPagefileUsage;
268 if (size == sizeof(VM_COUNTERS_EX32)) info32->PrivateUsage = info->PrivateUsage;
272 /**********************************************************************
273 * wow64_NtAlertResumeThread
275 NTSTATUS WINAPI wow64_NtAlertResumeThread( UINT *args )
277 HANDLE handle = get_handle( &args );
278 ULONG *count = get_ptr( &args );
280 return NtAlertResumeThread( handle, count );
284 /**********************************************************************
285 * wow64_NtAlertThread
287 NTSTATUS WINAPI wow64_NtAlertThread( UINT *args )
289 HANDLE handle = get_handle( &args );
291 return NtAlertThread( handle );
295 /**********************************************************************
296 * wow64_NtAlertThreadByThreadId
298 NTSTATUS WINAPI wow64_NtAlertThreadByThreadId( UINT *args )
300 HANDLE tid = get_handle( &args );
302 return NtAlertThreadByThreadId( tid );
306 /**********************************************************************
307 * wow64_NtAssignProcessToJobObject
309 NTSTATUS WINAPI wow64_NtAssignProcessToJobObject( UINT *args )
311 HANDLE job = get_handle( &args );
312 HANDLE process = get_handle( &args );
314 return NtAssignProcessToJobObject( job, process );
318 /**********************************************************************
319 * wow64_NtCreateThread
321 NTSTATUS WINAPI wow64_NtCreateThread( UINT *args )
323 ULONG *handle_ptr = get_ptr( &args );
324 ACCESS_MASK access = get_ulong( &args );
325 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
326 HANDLE process = get_handle( &args );
327 CLIENT_ID32 *id32 = get_ptr( &args );
328 I386_CONTEXT *context = get_ptr( &args );
329 void *initial_teb = get_ptr( &args );
330 BOOLEAN suspended = get_ulong( &args );
332 FIXME( "%p %lx %p %p %p %p %p %u: stub\n", handle_ptr, access, attr32, process,
333 id32, context, initial_teb, suspended );
334 return STATUS_NOT_IMPLEMENTED;
338 /**********************************************************************
339 * wow64_NtCreateThreadEx
341 NTSTATUS WINAPI wow64_NtCreateThreadEx( UINT *args )
343 ULONG *handle_ptr = get_ptr( &args );
344 ACCESS_MASK access = get_ulong( &args );
345 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
346 HANDLE process = get_handle( &args );
347 PRTL_THREAD_START_ROUTINE start = get_ptr( &args );
348 void *param = get_ptr( &args );
349 ULONG flags = get_ulong( &args );
350 ULONG_PTR zero_bits = get_ulong( &args );
351 SIZE_T stack_commit = get_ulong( &args );
352 SIZE_T stack_reserve = get_ulong( &args );
353 PS_ATTRIBUTE_LIST32 *attr_list32 = get_ptr( &args );
355 struct object_attr64 attr;
356 PS_ATTRIBUTE_LIST *attr_list;
357 HANDLE handle = 0;
358 NTSTATUS status;
360 *handle_ptr = 0;
361 if (is_process_wow64( process ))
363 status = NtCreateThreadEx( &handle, access, objattr_32to64( &attr, attr32 ), process,
364 start, param, flags, get_zero_bits( zero_bits ),
365 stack_commit, stack_reserve,
366 ps_attributes_32to64( &attr_list, attr_list32 ));
367 put_ps_attributes( attr_list32, attr_list );
369 else status = STATUS_ACCESS_DENIED;
371 put_handle( handle_ptr, handle );
372 return status;
376 /**********************************************************************
377 * wow64_NtCreateUserProcess
379 NTSTATUS WINAPI wow64_NtCreateUserProcess( UINT *args )
381 ULONG *process_handle_ptr = get_ptr( &args );
382 ULONG *thread_handle_ptr = get_ptr( &args );
383 ACCESS_MASK process_access = get_ulong( &args );
384 ACCESS_MASK thread_access = get_ulong( &args );
385 OBJECT_ATTRIBUTES32 *process_attr32 = get_ptr( &args );
386 OBJECT_ATTRIBUTES32 *thread_attr32 = get_ptr( &args );
387 ULONG process_flags = get_ulong( &args );
388 ULONG thread_flags = get_ulong( &args );
389 RTL_USER_PROCESS_PARAMETERS32 *params32 = get_ptr( &args );
390 PS_CREATE_INFO32 *info32 = get_ptr( &args );
391 PS_ATTRIBUTE_LIST32 *attr32 = get_ptr( &args );
393 struct object_attr64 process_attr, thread_attr;
394 RTL_USER_PROCESS_PARAMETERS *params;
395 PS_CREATE_INFO info;
396 PS_ATTRIBUTE_LIST *attr;
397 HANDLE process_handle = 0, thread_handle = 0;
399 NTSTATUS status;
401 *process_handle_ptr = *thread_handle_ptr = 0;
402 status = NtCreateUserProcess( &process_handle, &thread_handle, process_access, thread_access,
403 objattr_32to64( &process_attr, process_attr32 ),
404 objattr_32to64( &thread_attr, thread_attr32 ),
405 process_flags, thread_flags,
406 process_params_32to64( &params, params32),
407 &info, ps_attributes_32to64( &attr, attr32 ));
408 put_handle( process_handle_ptr, process_handle );
409 put_handle( thread_handle_ptr, thread_handle );
410 put_ps_create_info( info32, &info );
411 put_ps_attributes( attr32, attr );
412 RtlDestroyProcessParameters( params );
413 return status;
417 /**********************************************************************
418 * wow64_NtDebugActiveProcess
420 NTSTATUS WINAPI wow64_NtDebugActiveProcess( UINT *args )
422 HANDLE process = get_handle( &args );
423 HANDLE debug = get_handle( &args );
425 return NtDebugActiveProcess( process, debug );
429 /**********************************************************************
430 * wow64_NtFlushInstructionCache
432 NTSTATUS WINAPI wow64_NtFlushInstructionCache( UINT *args )
434 HANDLE process = get_handle( &args );
435 const void *addr = get_ptr( &args );
436 SIZE_T size = get_ulong( &args );
438 return NtFlushInstructionCache( process, addr, size );
442 /**********************************************************************
443 * wow64_NtFlushProcessWriteBuffers
445 NTSTATUS WINAPI wow64_NtFlushProcessWriteBuffers( UINT *args )
447 NtFlushProcessWriteBuffers();
448 return STATUS_SUCCESS;
452 /**********************************************************************
453 * wow64_NtGetNextThread
455 NTSTATUS WINAPI wow64_NtGetNextThread( UINT *args )
457 HANDLE process = get_handle( &args );
458 HANDLE thread = get_handle( &args );
459 ACCESS_MASK access = get_ulong( &args );
460 ULONG attributes = get_ulong( &args );
461 ULONG flags = get_ulong( &args );
462 ULONG *handle_ptr = get_ptr( &args );
464 HANDLE handle = 0;
465 NTSTATUS status;
467 *handle_ptr = 0;
468 status = NtGetNextThread( process, thread, access, attributes, flags, &handle );
469 put_handle( handle_ptr, handle );
470 return status;
474 /**********************************************************************
475 * wow64_NtIsProcessInJob
477 NTSTATUS WINAPI wow64_NtIsProcessInJob( UINT *args )
479 HANDLE process = get_handle( &args );
480 HANDLE job = get_handle( &args );
482 return NtIsProcessInJob( process, job );
486 /**********************************************************************
487 * wow64_NtOpenProcess
489 NTSTATUS WINAPI wow64_NtOpenProcess( UINT *args )
491 ULONG *handle_ptr = get_ptr( &args );
492 ACCESS_MASK access = get_ulong( &args );
493 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
494 CLIENT_ID32 *id32 = get_ptr( &args );
496 struct object_attr64 attr;
497 HANDLE handle = 0;
498 CLIENT_ID id;
499 NTSTATUS status;
501 *handle_ptr = 0;
502 status = NtOpenProcess( &handle, access, objattr_32to64( &attr, attr32 ), client_id_32to64( &id, id32 ));
503 put_handle( handle_ptr, handle );
504 return status;
508 /**********************************************************************
509 * wow64_NtOpenThread
511 NTSTATUS WINAPI wow64_NtOpenThread( UINT *args )
513 ULONG *handle_ptr = get_ptr( &args );
514 ACCESS_MASK access = get_ulong( &args );
515 OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args );
516 CLIENT_ID32 *id32 = get_ptr( &args );
518 struct object_attr64 attr;
519 HANDLE handle = 0;
520 CLIENT_ID id;
521 NTSTATUS status;
523 *handle_ptr = 0;
524 status = NtOpenThread( &handle, access, objattr_32to64( &attr, attr32 ), client_id_32to64( &id, id32 ));
525 put_handle( handle_ptr, handle );
526 return status;
530 /**********************************************************************
531 * wow64_NtQueryInformationProcess
533 NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args )
535 HANDLE handle = get_handle( &args );
536 PROCESSINFOCLASS class = get_ulong( &args );
537 void *ptr = get_ptr( &args );
538 ULONG len = get_ulong( &args );
539 ULONG *retlen = get_ptr( &args );
541 NTSTATUS status;
543 switch (class)
545 case ProcessBasicInformation: /* PROCESS_BASIC_INFORMATION */
546 if (len == sizeof(PROCESS_BASIC_INFORMATION32))
548 PROCESS_BASIC_INFORMATION info;
549 PROCESS_BASIC_INFORMATION32 *info32 = ptr;
551 if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL )))
553 if (is_process_wow64( handle ))
554 info32->PebBaseAddress = PtrToUlong( info.PebBaseAddress ) + 0x1000;
555 else
556 info32->PebBaseAddress = 0;
557 info32->ExitStatus = info.ExitStatus;
558 info32->AffinityMask = info.AffinityMask;
559 info32->BasePriority = info.BasePriority;
560 info32->UniqueProcessId = info.UniqueProcessId;
561 info32->InheritedFromUniqueProcessId = info.InheritedFromUniqueProcessId;
562 if (retlen) *retlen = sizeof(*info32);
564 return status;
566 if (retlen) *retlen = sizeof(PROCESS_BASIC_INFORMATION32);
567 return STATUS_INFO_LENGTH_MISMATCH;
569 case ProcessIoCounters: /* IO_COUNTERS */
570 case ProcessTimes: /* KERNEL_USER_TIMES */
571 case ProcessDefaultHardErrorMode: /* ULONG */
572 case ProcessPriorityClass: /* PROCESS_PRIORITY_CLASS */
573 case ProcessHandleCount: /* ULONG */
574 case ProcessSessionInformation: /* ULONG */
575 case ProcessDebugFlags: /* ULONG */
576 case ProcessExecuteFlags: /* ULONG */
577 case ProcessCookie: /* ULONG */
578 case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */
579 /* FIXME: check buffer alignment */
580 return NtQueryInformationProcess( handle, class, ptr, len, retlen );
582 case ProcessVmCounters: /* VM_COUNTERS_EX */
583 if (len == sizeof(VM_COUNTERS32) || len == sizeof(VM_COUNTERS_EX32))
585 VM_COUNTERS_EX info;
586 VM_COUNTERS_EX32 *info32 = ptr;
588 if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL )))
590 put_vm_counters( info32, &info, len );
591 if (retlen) *retlen = len;
593 return status;
595 if (retlen) *retlen = sizeof(VM_COUNTERS_EX32);
596 return STATUS_INFO_LENGTH_MISMATCH;
598 case ProcessDebugPort: /* ULONG_PTR */
599 case ProcessAffinityMask: /* ULONG_PTR */
600 case ProcessWow64Information: /* ULONG_PTR */
601 case ProcessDebugObjectHandle: /* HANDLE */
602 if (len == sizeof(ULONG))
604 ULONG_PTR data;
606 if (!(status = NtQueryInformationProcess( handle, class, &data, sizeof(data), NULL )))
608 *(ULONG *)ptr = data;
609 if (retlen) *retlen = sizeof(ULONG);
611 else if (status == STATUS_PORT_NOT_SET) *(ULONG *)ptr = 0;
612 return status;
614 if (retlen) *retlen = sizeof(ULONG);
615 return STATUS_INFO_LENGTH_MISMATCH;
617 case ProcessImageFileName:
618 case ProcessImageFileNameWin32: /* UNICODE_STRING + string */
620 ULONG retsize, size = len + sizeof(UNICODE_STRING) - sizeof(UNICODE_STRING32);
621 UNICODE_STRING *str = Wow64AllocateTemp( size );
622 UNICODE_STRING32 *str32 = ptr;
624 if (!(status = NtQueryInformationProcess( handle, class, str, size, &retsize )))
626 str32->Length = str->Length;
627 str32->MaximumLength = str->MaximumLength;
628 str32->Buffer = PtrToUlong( str32 + 1 );
629 memcpy( str32 + 1, str->Buffer, str->MaximumLength );
631 if (retlen) *retlen = retsize + sizeof(UNICODE_STRING32) - sizeof(UNICODE_STRING);
632 return status;
635 case ProcessImageInformation: /* SECTION_IMAGE_INFORMATION */
636 if (len == sizeof(SECTION_IMAGE_INFORMATION32))
638 SECTION_IMAGE_INFORMATION info;
639 SECTION_IMAGE_INFORMATION32 *info32 = ptr;
641 if (!(status = NtQueryInformationProcess( handle, class, &info, sizeof(info), NULL )))
643 put_section_image_info( info32, &info );
644 if (retlen) *retlen = sizeof(*info32);
646 return status;
648 if (retlen) *retlen = sizeof(SECTION_IMAGE_INFORMATION32);
649 return STATUS_INFO_LENGTH_MISMATCH;
651 case ProcessWineLdtCopy:
652 return STATUS_NOT_IMPLEMENTED;
654 default:
655 FIXME( "unsupported class %u\n", class );
656 return STATUS_INVALID_INFO_CLASS;
661 /**********************************************************************
662 * wow64_NtQueryInformationThread
664 NTSTATUS WINAPI wow64_NtQueryInformationThread( UINT *args )
666 HANDLE handle = get_handle( &args );
667 THREADINFOCLASS class = get_ulong( &args );
668 void *ptr = get_ptr( &args );
669 ULONG len = get_ulong( &args );
670 ULONG *retlen = get_ptr( &args );
672 NTSTATUS status;
674 switch (class)
676 case ThreadBasicInformation: /* THREAD_BASIC_INFORMATION */
678 THREAD_BASIC_INFORMATION32 info32;
679 THREAD_BASIC_INFORMATION info;
681 status = NtQueryInformationThread( handle, class, &info, sizeof(info), NULL );
682 if (!status)
684 info32.ExitStatus = info.ExitStatus;
685 info32.TebBaseAddress = is_process_id_wow64( &info.ClientId ) ?
686 PtrToUlong(info.TebBaseAddress) + 0x2000 : 0;
687 info32.ClientId.UniqueProcess = HandleToULong( info.ClientId.UniqueProcess );
688 info32.ClientId.UniqueThread = HandleToULong( info.ClientId.UniqueThread );
689 info32.AffinityMask = info.AffinityMask;
690 info32.Priority = info.Priority;
691 info32.BasePriority = info.BasePriority;
692 memcpy( ptr, &info32, min( len, sizeof(info32) ));
693 if (retlen) *retlen = min( len, sizeof(info32) );
695 return status;
698 case ThreadTimes: /* KERNEL_USER_TIMES */
699 case ThreadEnableAlignmentFaultFixup: /* set only */
700 case ThreadAmILastThread: /* ULONG */
701 case ThreadIsIoPending: /* ULONG */
702 case ThreadHideFromDebugger: /* BOOLEAN */
703 case ThreadSuspendCount: /* ULONG */
704 case ThreadPriorityBoost: /* ULONG */
705 /* FIXME: check buffer alignment */
706 return NtQueryInformationThread( handle, class, ptr, len, retlen );
708 case ThreadAffinityMask: /* ULONG_PTR */
709 case ThreadQuerySetWin32StartAddress: /* PRTL_THREAD_START_ROUTINE */
711 ULONG_PTR data;
713 status = NtQueryInformationThread( handle, class, &data, sizeof(data), NULL );
714 if (!status)
716 memcpy( ptr, &data, min( len, sizeof(ULONG) ));
717 if (retlen) *retlen = min( len, sizeof(ULONG) );
719 return status;
722 case ThreadDescriptorTableEntry: /* THREAD_DESCRIPTOR_INFORMATION */
723 return RtlWow64GetThreadSelectorEntry( handle, ptr, len, retlen );
725 case ThreadWow64Context: /* WOW64_CONTEXT* */
726 return STATUS_INVALID_INFO_CLASS;
728 case ThreadGroupInformation: /* GROUP_AFFINITY */
730 GROUP_AFFINITY info;
732 status = NtQueryInformationThread( handle, class, &info, sizeof(info), NULL );
733 if (!status)
735 GROUP_AFFINITY32 info32 = { info.Mask, info.Group };
736 memcpy( ptr, &info32, min( len, sizeof(info32) ));
737 if (retlen) *retlen = min( len, sizeof(info32) );
739 return status;
742 case ThreadNameInformation: /* THREAD_NAME_INFORMATION */
744 THREAD_NAME_INFORMATION *info;
745 THREAD_NAME_INFORMATION32 *info32 = ptr;
746 ULONG size, ret_size;
748 if (len >= sizeof(*info32))
750 size = sizeof(*info) + len - sizeof(*info32);
751 info = Wow64AllocateTemp( size );
752 status = NtQueryInformationThread( handle, class, info, size, &ret_size );
753 if (!status)
755 info32->ThreadName.Length = info->ThreadName.Length;
756 info32->ThreadName.MaximumLength = info->ThreadName.MaximumLength;
757 info32->ThreadName.Buffer = PtrToUlong( info32 + 1 );
758 memcpy( info32 + 1, info + 1, min( len, info->ThreadName.MaximumLength ));
761 else status = NtQueryInformationThread( handle, class, NULL, 0, &ret_size );
763 if (retlen && (status == STATUS_SUCCESS || status == STATUS_BUFFER_TOO_SMALL))
764 *retlen = sizeof(*info32) + ret_size - sizeof(*info);
765 return status;
768 default:
769 FIXME( "unsupported class %u\n", class );
770 return STATUS_INVALID_INFO_CLASS;
775 /**********************************************************************
776 * wow64_NtQueueApcThread
778 NTSTATUS WINAPI wow64_NtQueueApcThread( UINT *args )
780 HANDLE handle = get_handle( &args );
781 ULONG func = get_ulong( &args );
782 ULONG arg1 = get_ulong( &args );
783 ULONG arg2 = get_ulong( &args );
784 ULONG arg3 = get_ulong( &args );
786 return NtQueueApcThread( handle, apc_32to64( func ),
787 (ULONG_PTR)apc_param_32to64( func, arg1 ), arg2, arg3 );
791 /**********************************************************************
792 * wow64_NtRemoveProcessDebug
794 NTSTATUS WINAPI wow64_NtRemoveProcessDebug( UINT *args )
796 HANDLE process = get_handle( &args );
797 HANDLE debug = get_handle( &args );
799 return NtRemoveProcessDebug( process, debug );
803 /**********************************************************************
804 * wow64_NtResumeProcess
806 NTSTATUS WINAPI wow64_NtResumeProcess( UINT *args )
808 HANDLE handle = get_handle( &args );
810 return NtResumeProcess( handle );
814 /**********************************************************************
815 * wow64_NtResumeThread
817 NTSTATUS WINAPI wow64_NtResumeThread( UINT *args )
819 HANDLE handle = get_handle( &args );
820 ULONG *count = get_ptr( &args );
822 return NtResumeThread( handle, count );
826 /**********************************************************************
827 * wow64_NtSetInformationProcess
829 NTSTATUS WINAPI wow64_NtSetInformationProcess( UINT *args )
831 HANDLE handle = get_handle( &args );
832 PROCESSINFOCLASS class = get_ulong( &args );
833 void *ptr = get_ptr( &args );
834 ULONG len = get_ulong( &args );
836 NTSTATUS status;
838 switch (class)
840 case ProcessDefaultHardErrorMode: /* ULONG */
841 case ProcessPriorityClass: /* PROCESS_PRIORITY_CLASS */
842 case ProcessExecuteFlags: /* ULONG */
843 case ProcessPagePriority: /* MEMORY_PRIORITY_INFORMATION */
844 case ProcessPowerThrottlingState: /* PROCESS_POWER_THROTTLING_STATE */
845 case ProcessLeapSecondInformation: /* PROCESS_LEAP_SECOND_INFO */
846 return NtSetInformationProcess( handle, class, ptr, len );
848 case ProcessAffinityMask: /* ULONG_PTR */
849 if (len == sizeof(ULONG))
851 ULONG_PTR mask = *(ULONG *)ptr;
852 return NtSetInformationProcess( handle, class, &mask, sizeof(mask) );
854 else return STATUS_INVALID_PARAMETER;
856 case ProcessInstrumentationCallback: /* PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION */
857 if (len == sizeof(PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION32))
859 FIXME( "ProcessInstrumentationCallback stub\n" );
860 return STATUS_SUCCESS;
862 else return STATUS_INFO_LENGTH_MISMATCH;
864 case ProcessThreadStackAllocation: /* PROCESS_STACK_ALLOCATION_INFORMATION(_EX) */
865 if (len == sizeof(PROCESS_STACK_ALLOCATION_INFORMATION_EX32))
867 PROCESS_STACK_ALLOCATION_INFORMATION_EX32 *stack = ptr;
868 PROCESS_STACK_ALLOCATION_INFORMATION_EX info;
870 info.PreferredNode = stack->PreferredNode;
871 info.Reserved0 = stack->Reserved0;
872 info.Reserved1 = stack->Reserved1;
873 info.Reserved2 = stack->Reserved2;
874 info.AllocInfo.ReserveSize = stack->AllocInfo.ReserveSize;
875 info.AllocInfo.ZeroBits = get_zero_bits( stack->AllocInfo.ZeroBits );
876 if (!(status = NtSetInformationProcess( handle, class, &info, sizeof(info) )))
877 stack->AllocInfo.StackBase = PtrToUlong( info.AllocInfo.StackBase );
878 return status;
880 else if (len == sizeof(PROCESS_STACK_ALLOCATION_INFORMATION32))
882 PROCESS_STACK_ALLOCATION_INFORMATION32 *stack = ptr;
883 PROCESS_STACK_ALLOCATION_INFORMATION info;
885 info.ReserveSize = stack->ReserveSize;
886 info.ZeroBits = get_zero_bits( stack->ZeroBits );
887 if (!(status = NtSetInformationProcess( handle, class, &info, sizeof(info) )))
888 stack->StackBase = PtrToUlong( info.StackBase );
889 return status;
891 else return STATUS_INFO_LENGTH_MISMATCH;
893 case ProcessWineMakeProcessSystem: /* HANDLE* */
894 if (len == sizeof(ULONG))
896 HANDLE event = 0;
897 status = NtSetInformationProcess( handle, class, &event, sizeof(HANDLE *) );
898 put_handle( ptr, event );
899 return status;
901 else return STATUS_INFO_LENGTH_MISMATCH;
903 default:
904 FIXME( "unsupported class %u\n", class );
905 return STATUS_INVALID_INFO_CLASS;
910 /**********************************************************************
911 * wow64_NtSetInformationThread
913 NTSTATUS WINAPI wow64_NtSetInformationThread( UINT *args )
915 HANDLE handle = get_handle( &args );
916 THREADINFOCLASS class = get_ulong( &args );
917 void *ptr = get_ptr( &args );
918 ULONG len = get_ulong( &args );
920 switch (class)
922 case ThreadZeroTlsCell: /* ULONG */
923 case ThreadBasePriority: /* ULONG */
924 case ThreadHideFromDebugger: /* void */
925 case ThreadEnableAlignmentFaultFixup: /* BOOLEAN */
926 case ThreadPowerThrottlingState: /* THREAD_POWER_THROTTLING_STATE */
927 case ThreadIdealProcessor: /* ULONG */
928 case ThreadPriorityBoost: /* ULONG */
929 return NtSetInformationThread( handle, class, ptr, len );
931 case ThreadImpersonationToken: /* HANDLE */
932 if (len == sizeof(ULONG))
934 HANDLE token = LongToHandle( *(ULONG *)ptr );
935 return NtSetInformationThread( handle, class, &token, sizeof(token) );
937 else return STATUS_INVALID_PARAMETER;
939 case ThreadAffinityMask: /* ULONG_PTR */
940 case ThreadQuerySetWin32StartAddress: /* PRTL_THREAD_START_ROUTINE */
941 if (len == sizeof(ULONG))
943 ULONG_PTR mask = *(ULONG *)ptr;
944 return NtSetInformationThread( handle, class, &mask, sizeof(mask) );
946 else return STATUS_INVALID_PARAMETER;
948 case ThreadWow64Context: /* WOW64_CONTEXT* */
949 return STATUS_INVALID_INFO_CLASS;
951 case ThreadGroupInformation: /* GROUP_AFFINITY */
952 if (len == sizeof(GROUP_AFFINITY32))
954 GROUP_AFFINITY32 *info32 = ptr;
955 GROUP_AFFINITY info = { info32->Mask, info32->Group };
957 return NtSetInformationThread( handle, class, &info, sizeof(info) );
959 else return STATUS_INVALID_PARAMETER;
961 case ThreadNameInformation: /* THREAD_NAME_INFORMATION */
962 case ThreadWineNativeThreadName:
963 if (len == sizeof(THREAD_NAME_INFORMATION32))
965 THREAD_NAME_INFORMATION32 *info32 = ptr;
966 THREAD_NAME_INFORMATION info;
968 if (!unicode_str_32to64( &info.ThreadName, &info32->ThreadName ))
969 return STATUS_ACCESS_VIOLATION;
970 return NtSetInformationThread( handle, class, &info, sizeof(info) );
972 else return STATUS_INFO_LENGTH_MISMATCH;
974 default:
975 FIXME( "unsupported class %u\n", class );
976 return STATUS_INVALID_INFO_CLASS;
981 /**********************************************************************
982 * wow64_NtSetThreadExecutionState
984 NTSTATUS WINAPI wow64_NtSetThreadExecutionState( UINT *args )
986 EXECUTION_STATE new_state = get_ulong( &args );
987 EXECUTION_STATE *old_state = get_ptr( &args );
989 return NtSetThreadExecutionState( new_state, old_state );
993 /**********************************************************************
994 * wow64_NtSuspendProcess
996 NTSTATUS WINAPI wow64_NtSuspendProcess( UINT *args )
998 HANDLE handle = get_handle( &args );
1000 return NtSuspendProcess( handle );
1004 /**********************************************************************
1005 * wow64_NtSuspendThread
1007 NTSTATUS WINAPI wow64_NtSuspendThread( UINT *args )
1009 HANDLE handle = get_handle( &args );
1010 ULONG *count = get_ptr( &args );
1012 return NtSuspendThread( handle, count );
1016 /**********************************************************************
1017 * wow64_NtTerminateProcess
1019 NTSTATUS WINAPI wow64_NtTerminateProcess( UINT *args )
1021 HANDLE handle = get_handle( &args );
1022 LONG exit_code = get_ulong( &args );
1024 return NtTerminateProcess( handle, exit_code );
1028 /**********************************************************************
1029 * wow64_NtTerminateThread
1031 NTSTATUS WINAPI wow64_NtTerminateThread( UINT *args )
1033 HANDLE handle = get_handle( &args );
1034 LONG exit_code = get_ulong( &args );
1036 return NtTerminateThread( handle, exit_code );