2 * WoW64 synchronization objects and 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
29 #include "wow64_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wow
);
35 static void put_object_type_info( OBJECT_TYPE_INFORMATION32
*info32
, const OBJECT_TYPE_INFORMATION
*info
)
37 if (info
->TypeName
.Length
)
39 memcpy( info32
+ 1, info
->TypeName
.Buffer
, info
->TypeName
.Length
+ sizeof(WCHAR
) );
40 info32
->TypeName
.Length
= info
->TypeName
.Length
;
41 info32
->TypeName
.MaximumLength
= info
->TypeName
.Length
+ sizeof(WCHAR
);
42 info32
->TypeName
.Buffer
= PtrToUlong( info32
+ 1 );
44 else memset( &info32
->TypeName
, 0, sizeof(info32
->TypeName
) );
45 info32
->TotalNumberOfObjects
= info
->TotalNumberOfObjects
;
46 info32
->TotalNumberOfHandles
= info
->TotalNumberOfHandles
;
47 info32
->TotalPagedPoolUsage
= info
->TotalPagedPoolUsage
;
48 info32
->TotalNonPagedPoolUsage
= info
->TotalNonPagedPoolUsage
;
49 info32
->TotalNamePoolUsage
= info
->TotalNamePoolUsage
;
50 info32
->TotalHandleTableUsage
= info
->TotalHandleTableUsage
;
51 info32
->HighWaterNumberOfObjects
= info
->HighWaterNumberOfObjects
;
52 info32
->HighWaterNumberOfHandles
= info
->HighWaterNumberOfHandles
;
53 info32
->HighWaterPagedPoolUsage
= info
->HighWaterPagedPoolUsage
;
54 info32
->HighWaterNonPagedPoolUsage
= info
->HighWaterNonPagedPoolUsage
;
55 info32
->HighWaterNamePoolUsage
= info
->HighWaterNamePoolUsage
;
56 info32
->HighWaterHandleTableUsage
= info
->HighWaterHandleTableUsage
;
57 info32
->InvalidAttributes
= info
->InvalidAttributes
;
58 info32
->GenericMapping
= info
->GenericMapping
;
59 info32
->ValidAccessMask
= info
->ValidAccessMask
;
60 info32
->SecurityRequired
= info
->SecurityRequired
;
61 info32
->MaintainHandleCount
= info
->MaintainHandleCount
;
62 info32
->TypeIndex
= info
->TypeIndex
;
63 info32
->ReservedByte
= info
->ReservedByte
;
64 info32
->PoolType
= info
->PoolType
;
65 info32
->DefaultPagedPoolCharge
= info
->DefaultPagedPoolCharge
;
66 info32
->DefaultNonPagedPoolCharge
= info
->DefaultNonPagedPoolCharge
;
70 static JOBOBJECT_BASIC_LIMIT_INFORMATION
*job_basic_limit_info_32to64( JOBOBJECT_BASIC_LIMIT_INFORMATION
*out
,
71 const JOBOBJECT_BASIC_LIMIT_INFORMATION32
*in
)
73 out
->PerProcessUserTimeLimit
= in
->PerProcessUserTimeLimit
;
74 out
->PerJobUserTimeLimit
= in
->PerJobUserTimeLimit
;
75 out
->LimitFlags
= in
->LimitFlags
;
76 out
->MinimumWorkingSetSize
= in
->MinimumWorkingSetSize
;
77 out
->MaximumWorkingSetSize
= in
->MaximumWorkingSetSize
;
78 out
->ActiveProcessLimit
= in
->ActiveProcessLimit
;
79 out
->Affinity
= in
->Affinity
;
80 out
->PriorityClass
= in
->PriorityClass
;
81 out
->SchedulingClass
= in
->SchedulingClass
;
86 static void put_job_basic_limit_info( JOBOBJECT_BASIC_LIMIT_INFORMATION32
*info32
,
87 const JOBOBJECT_BASIC_LIMIT_INFORMATION
*info
)
89 info32
->PerProcessUserTimeLimit
= info
->PerProcessUserTimeLimit
;
90 info32
->PerJobUserTimeLimit
= info
->PerJobUserTimeLimit
;
91 info32
->LimitFlags
= info
->LimitFlags
;
92 info32
->MinimumWorkingSetSize
= info
->MinimumWorkingSetSize
;
93 info32
->MaximumWorkingSetSize
= info
->MaximumWorkingSetSize
;
94 info32
->ActiveProcessLimit
= info
->ActiveProcessLimit
;
95 info32
->Affinity
= info
->Affinity
;
96 info32
->PriorityClass
= info
->PriorityClass
;
97 info32
->SchedulingClass
= info
->SchedulingClass
;
101 void put_section_image_info( SECTION_IMAGE_INFORMATION32
*info32
, const SECTION_IMAGE_INFORMATION
*info
)
103 if (info
->Machine
== IMAGE_FILE_MACHINE_AMD64
|| info
->Machine
== IMAGE_FILE_MACHINE_ARM64
)
105 info32
->TransferAddress
= 0x81231234; /* sic */
106 info32
->MaximumStackSize
= 0x100000;
107 info32
->CommittedStackSize
= 0x10000;
111 info32
->TransferAddress
= PtrToUlong( info
->TransferAddress
);
112 info32
->MaximumStackSize
= info
->MaximumStackSize
;
113 info32
->CommittedStackSize
= info
->CommittedStackSize
;
115 info32
->ZeroBits
= info
->ZeroBits
;
116 info32
->SubSystemType
= info
->SubSystemType
;
117 info32
->MinorSubsystemVersion
= info
->MinorSubsystemVersion
;
118 info32
->MajorSubsystemVersion
= info
->MajorSubsystemVersion
;
119 info32
->MajorOperatingSystemVersion
= info
->MajorOperatingSystemVersion
;
120 info32
->MinorOperatingSystemVersion
= info
->MinorOperatingSystemVersion
;
121 info32
->ImageCharacteristics
= info
->ImageCharacteristics
;
122 info32
->DllCharacteristics
= info
->DllCharacteristics
;
123 info32
->Machine
= info
->Machine
;
124 info32
->ImageContainsCode
= info
->ImageContainsCode
;
125 info32
->ImageFlags
= info
->ImageFlags
;
126 info32
->LoaderFlags
= info
->LoaderFlags
;
127 info32
->ImageFileSize
= info
->ImageFileSize
;
128 info32
->CheckSum
= info
->CheckSum
;
132 /**********************************************************************
133 * wow64_NtAcceptConnectPort
135 NTSTATUS WINAPI
wow64_NtAcceptConnectPort( UINT
*args
)
137 ULONG
*handle_ptr
= get_ptr( &args
);
138 ULONG id
= get_ulong( &args
);
139 LPC_MESSAGE
*msg
= get_ptr( &args
);
140 BOOLEAN accept
= get_ulong( &args
);
141 LPC_SECTION_WRITE
*write
= get_ptr( &args
);
142 LPC_SECTION_READ
*read
= get_ptr( &args
);
144 FIXME( "%p %lu %p %u %p %p: stub\n", handle_ptr
, id
, msg
, accept
, write
, read
);
145 return STATUS_NOT_IMPLEMENTED
;
149 /**********************************************************************
150 * wow64_NtCancelTimer
152 NTSTATUS WINAPI
wow64_NtCancelTimer( UINT
*args
)
154 HANDLE handle
= get_handle( &args
);
155 BOOLEAN
*state
= get_ptr( &args
);
157 return NtCancelTimer( handle
, state
);
161 /**********************************************************************
164 NTSTATUS WINAPI
wow64_NtClearEvent( UINT
*args
)
166 HANDLE handle
= get_handle( &args
);
168 return NtClearEvent( handle
);
172 /**********************************************************************
173 * wow64_NtCompareObjects
175 NTSTATUS WINAPI
wow64_NtCompareObjects( UINT
*args
)
177 HANDLE first
= get_handle( &args
);
178 HANDLE second
= get_handle( &args
);
180 return NtCompareObjects( first
, second
);
184 /**********************************************************************
185 * wow64_NtCompleteConnectPort
187 NTSTATUS WINAPI
wow64_NtCompleteConnectPort( UINT
*args
)
189 HANDLE handle
= get_handle( &args
);
191 return NtCompleteConnectPort( handle
);
195 /**********************************************************************
196 * wow64_NtConnectPort
198 NTSTATUS WINAPI
wow64_NtConnectPort( UINT
*args
)
200 ULONG
*handle_ptr
= get_ptr( &args
);
201 UNICODE_STRING32
*name32
= get_ptr( &args
);
202 SECURITY_QUALITY_OF_SERVICE
*qos
= get_ptr( &args
);
203 LPC_SECTION_WRITE
*write
= get_ptr( &args
);
204 LPC_SECTION_READ
*read
= get_ptr( &args
);
205 ULONG
*max_len
= get_ptr( &args
);
206 void *info
= get_ptr( &args
);
207 ULONG
*info_len
= get_ptr( &args
);
209 FIXME( "%p %p %p %p %p %p %p %p: stub\n",
210 handle_ptr
, name32
, qos
, write
, read
, max_len
, info
, info_len
);
211 return STATUS_NOT_IMPLEMENTED
;
215 /**********************************************************************
216 * wow64_NtCreateDebugObject
218 NTSTATUS WINAPI
wow64_NtCreateDebugObject( UINT
*args
)
220 ULONG
*handle_ptr
= get_ptr( &args
);
221 ACCESS_MASK access
= get_ulong( &args
);
222 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
223 ULONG flags
= get_ulong( &args
);
225 struct object_attr64 attr
;
230 status
= NtCreateDebugObject( &handle
, access
, objattr_32to64( &attr
, attr32
), flags
);
231 put_handle( handle_ptr
, handle
);
236 /**********************************************************************
237 * wow64_NtCreateDirectoryObject
239 NTSTATUS WINAPI
wow64_NtCreateDirectoryObject( UINT
*args
)
241 ULONG
*handle_ptr
= get_ptr( &args
);
242 ACCESS_MASK access
= get_ulong( &args
);
243 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
245 struct object_attr64 attr
;
250 status
= NtCreateDirectoryObject( &handle
, access
, objattr_32to64( &attr
, attr32
));
251 put_handle( handle_ptr
, handle
);
256 /**********************************************************************
257 * wow64_NtCreateEvent
259 NTSTATUS WINAPI
wow64_NtCreateEvent( UINT
*args
)
261 ULONG
*handle_ptr
= get_ptr( &args
);
262 ACCESS_MASK access
= get_ulong( &args
);
263 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
264 EVENT_TYPE type
= get_ulong( &args
);
265 BOOLEAN state
= get_ulong( &args
);
267 struct object_attr64 attr
;
272 status
= NtCreateEvent( &handle
, access
, objattr_32to64( &attr
, attr32
), type
, state
);
273 put_handle( handle_ptr
, handle
);
278 /**********************************************************************
279 * wow64_NtCreateIoCompletion
281 NTSTATUS WINAPI
wow64_NtCreateIoCompletion( UINT
*args
)
283 ULONG
*handle_ptr
= get_ptr( &args
);
284 ACCESS_MASK access
= get_ulong( &args
);
285 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
286 ULONG threads
= get_ulong( &args
);
288 struct object_attr64 attr
;
293 status
= NtCreateIoCompletion( &handle
, access
, objattr_32to64( &attr
, attr32
), threads
);
294 put_handle( handle_ptr
, handle
);
299 /**********************************************************************
300 * wow64_NtCreateJobObject
302 NTSTATUS WINAPI
wow64_NtCreateJobObject( UINT
*args
)
304 ULONG
*handle_ptr
= get_ptr( &args
);
305 ACCESS_MASK access
= get_ulong( &args
);
306 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
308 struct object_attr64 attr
;
313 status
= NtCreateJobObject( &handle
, access
, objattr_32to64( &attr
, attr32
));
314 put_handle( handle_ptr
, handle
);
319 /**********************************************************************
320 * wow64_NtCreateKeyedEvent
322 NTSTATUS WINAPI
wow64_NtCreateKeyedEvent( UINT
*args
)
324 ULONG
*handle_ptr
= get_ptr( &args
);
325 ACCESS_MASK access
= get_ulong( &args
);
326 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
327 ULONG flags
= get_ulong( &args
);
329 struct object_attr64 attr
;
334 status
= NtCreateKeyedEvent( &handle
, access
, objattr_32to64( &attr
, attr32
), flags
);
335 put_handle( handle_ptr
, handle
);
340 /**********************************************************************
341 * wow64_NtCreateMutant
343 NTSTATUS WINAPI
wow64_NtCreateMutant( UINT
*args
)
345 ULONG
*handle_ptr
= get_ptr( &args
);
346 ACCESS_MASK access
= get_ulong( &args
);
347 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
348 BOOLEAN owned
= get_ulong( &args
);
350 struct object_attr64 attr
;
355 status
= NtCreateMutant( &handle
, access
, objattr_32to64( &attr
, attr32
), owned
);
356 put_handle( handle_ptr
, handle
);
361 /**********************************************************************
364 NTSTATUS WINAPI
wow64_NtCreatePort( UINT
*args
)
366 ULONG
*handle_ptr
= get_ptr( &args
);
367 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
368 ULONG info_len
= get_ulong( &args
);
369 ULONG data_len
= get_ulong( &args
);
370 ULONG
*reserved
= get_ptr( &args
);
372 struct object_attr64 attr
;
377 status
= NtCreatePort( &handle
, objattr_32to64( &attr
, attr32
), info_len
, data_len
, reserved
);
378 put_handle( handle_ptr
, handle
);
383 /**********************************************************************
384 * wow64_NtCreateSection
386 NTSTATUS WINAPI
wow64_NtCreateSection( UINT
*args
)
388 ULONG
*handle_ptr
= get_ptr( &args
);
389 ACCESS_MASK access
= get_ulong( &args
);
390 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
391 const LARGE_INTEGER
*size
= get_ptr( &args
);
392 ULONG protect
= get_ulong( &args
);
393 ULONG flags
= get_ulong( &args
);
394 HANDLE file
= get_handle( &args
);
396 struct object_attr64 attr
;
401 status
= NtCreateSection( &handle
, access
, objattr_32to64( &attr
, attr32
), size
, protect
, flags
, file
);
402 put_handle( handle_ptr
, handle
);
407 /**********************************************************************
408 * wow64_NtCreateSemaphore
410 NTSTATUS WINAPI
wow64_NtCreateSemaphore( UINT
*args
)
412 ULONG
*handle_ptr
= get_ptr( &args
);
413 ACCESS_MASK access
= get_ulong( &args
);
414 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
415 LONG initial
= get_ulong( &args
);
416 LONG max
= get_ulong( &args
);
418 struct object_attr64 attr
;
423 status
= NtCreateSemaphore( &handle
, access
, objattr_32to64( &attr
, attr32
), initial
, max
);
424 put_handle( handle_ptr
, handle
);
429 /**********************************************************************
430 * wow64_NtCreateSymbolicLinkObject
432 NTSTATUS WINAPI
wow64_NtCreateSymbolicLinkObject( UINT
*args
)
434 ULONG
*handle_ptr
= get_ptr( &args
);
435 ACCESS_MASK access
= get_ulong( &args
);
436 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
437 UNICODE_STRING32
*target32
= get_ptr( &args
);
439 struct object_attr64 attr
;
440 UNICODE_STRING target
;
445 status
= NtCreateSymbolicLinkObject( &handle
, access
, objattr_32to64( &attr
, attr32
),
446 unicode_str_32to64( &target
, target32
));
447 put_handle( handle_ptr
, handle
);
452 /**********************************************************************
453 * wow64_NtCreateTimer
455 NTSTATUS WINAPI
wow64_NtCreateTimer( UINT
*args
)
457 ULONG
*handle_ptr
= get_ptr( &args
);
458 ACCESS_MASK access
= get_ulong( &args
);
459 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
460 TIMER_TYPE type
= get_ulong( &args
);
462 struct object_attr64 attr
;
467 status
= NtCreateTimer( &handle
, access
, objattr_32to64( &attr
, attr32
), type
);
468 put_handle( handle_ptr
, handle
);
473 /**********************************************************************
474 * wow64_NtDebugContinue
476 NTSTATUS WINAPI
wow64_NtDebugContinue( UINT
*args
)
478 HANDLE handle
= get_handle( &args
);
479 CLIENT_ID32
*id32
= get_ptr( &args
);
480 NTSTATUS status
= get_ulong( &args
);
484 return NtDebugContinue( handle
, client_id_32to64( &id
, id32
), status
);
488 /**********************************************************************
489 * wow64_NtDelayExecution
491 NTSTATUS WINAPI
wow64_NtDelayExecution( UINT
*args
)
493 BOOLEAN alertable
= get_ulong( &args
);
494 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
496 return NtDelayExecution( alertable
, timeout
);
500 /**********************************************************************
501 * wow64_NtDuplicateObject
503 NTSTATUS WINAPI
wow64_NtDuplicateObject( UINT
*args
)
505 HANDLE source_process
= get_handle( &args
);
506 HANDLE source_handle
= get_handle( &args
);
507 HANDLE dest_process
= get_handle( &args
);
508 ULONG
*handle_ptr
= get_ptr( &args
);
509 ACCESS_MASK access
= get_ulong( &args
);
510 ULONG attributes
= get_ulong( &args
);
511 ULONG options
= get_ulong( &args
);
516 if (handle_ptr
) *handle_ptr
= 0;
517 status
= NtDuplicateObject( source_process
, source_handle
, dest_process
, &handle
,
518 access
, attributes
, options
);
519 if (handle_ptr
) put_handle( handle_ptr
, handle
);
524 /**********************************************************************
527 NTSTATUS WINAPI
wow64_NtListenPort( UINT
*args
)
529 HANDLE handle
= get_handle( &args
);
530 LPC_MESSAGE
*msg
= get_ptr( &args
);
532 FIXME( "%p %p: stub\n", handle
, msg
);
533 return STATUS_NOT_IMPLEMENTED
;
537 /**********************************************************************
538 * wow64_NtMakeTemporaryObject
540 NTSTATUS WINAPI
wow64_NtMakeTemporaryObject( UINT
*args
)
542 HANDLE handle
= get_handle( &args
);
544 return NtMakeTemporaryObject( handle
);
548 /**********************************************************************
549 * wow64_NtOpenDirectoryObject
551 NTSTATUS WINAPI
wow64_NtOpenDirectoryObject( UINT
*args
)
553 ULONG
*handle_ptr
= get_ptr( &args
);
554 ACCESS_MASK access
= get_ulong( &args
);
555 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
557 struct object_attr64 attr
;
562 status
= NtOpenDirectoryObject( &handle
, access
, objattr_32to64( &attr
, attr32
));
563 put_handle( handle_ptr
, handle
);
568 /**********************************************************************
571 NTSTATUS WINAPI
wow64_NtOpenEvent( UINT
*args
)
573 ULONG
*handle_ptr
= get_ptr( &args
);
574 ACCESS_MASK access
= get_ulong( &args
);
575 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
577 struct object_attr64 attr
;
582 status
= NtOpenEvent( &handle
, access
, objattr_32to64( &attr
, attr32
));
583 put_handle( handle_ptr
, handle
);
588 /**********************************************************************
589 * wow64_NtOpenIoCompletion
591 NTSTATUS WINAPI
wow64_NtOpenIoCompletion( UINT
*args
)
593 ULONG
*handle_ptr
= get_ptr( &args
);
594 ACCESS_MASK access
= get_ulong( &args
);
595 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
597 struct object_attr64 attr
;
602 status
= NtOpenIoCompletion( &handle
, access
, objattr_32to64( &attr
, attr32
));
603 put_handle( handle_ptr
, handle
);
608 /**********************************************************************
609 * wow64_NtOpenJobObject
611 NTSTATUS WINAPI
wow64_NtOpenJobObject( UINT
*args
)
613 ULONG
*handle_ptr
= get_ptr( &args
);
614 ACCESS_MASK access
= get_ulong( &args
);
615 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
617 struct object_attr64 attr
;
622 status
= NtOpenJobObject( &handle
, access
, objattr_32to64( &attr
, attr32
));
623 put_handle( handle_ptr
, handle
);
628 /**********************************************************************
629 * wow64_NtOpenKeyedEvent
631 NTSTATUS WINAPI
wow64_NtOpenKeyedEvent( UINT
*args
)
633 ULONG
*handle_ptr
= get_ptr( &args
);
634 ACCESS_MASK access
= get_ulong( &args
);
635 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
637 struct object_attr64 attr
;
642 status
= NtOpenKeyedEvent( &handle
, access
, objattr_32to64( &attr
, attr32
));
643 put_handle( handle_ptr
, handle
);
648 /**********************************************************************
651 NTSTATUS WINAPI
wow64_NtOpenMutant( UINT
*args
)
653 ULONG
*handle_ptr
= get_ptr( &args
);
654 ACCESS_MASK access
= get_ulong( &args
);
655 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
657 struct object_attr64 attr
;
662 status
= NtOpenMutant( &handle
, access
, objattr_32to64( &attr
, attr32
));
663 put_handle( handle_ptr
, handle
);
668 /**********************************************************************
669 * wow64_NtOpenSection
671 NTSTATUS WINAPI
wow64_NtOpenSection( UINT
*args
)
673 ULONG
*handle_ptr
= get_ptr( &args
);
674 ACCESS_MASK access
= get_ulong( &args
);
675 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
677 struct object_attr64 attr
;
682 status
= NtOpenSection( &handle
, access
, objattr_32to64( &attr
, attr32
));
683 put_handle( handle_ptr
, handle
);
688 /**********************************************************************
689 * wow64_NtOpenSemaphore
691 NTSTATUS WINAPI
wow64_NtOpenSemaphore( UINT
*args
)
693 ULONG
*handle_ptr
= get_ptr( &args
);
694 ACCESS_MASK access
= get_ulong( &args
);
695 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
697 struct object_attr64 attr
;
702 status
= NtOpenSemaphore( &handle
, access
, objattr_32to64( &attr
, attr32
));
703 put_handle( handle_ptr
, handle
);
708 /**********************************************************************
709 * wow64_NtOpenSymbolicLinkObject
711 NTSTATUS WINAPI
wow64_NtOpenSymbolicLinkObject( UINT
*args
)
713 ULONG
*handle_ptr
= get_ptr( &args
);
714 ACCESS_MASK access
= get_ulong( &args
);
715 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
717 struct object_attr64 attr
;
722 status
= NtOpenSymbolicLinkObject( &handle
, access
, objattr_32to64( &attr
, attr32
));
723 put_handle( handle_ptr
, handle
);
728 /**********************************************************************
731 NTSTATUS WINAPI
wow64_NtOpenTimer( UINT
*args
)
733 ULONG
*handle_ptr
= get_ptr( &args
);
734 ACCESS_MASK access
= get_ulong( &args
);
735 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
737 struct object_attr64 attr
;
742 status
= NtOpenTimer( &handle
, access
, objattr_32to64( &attr
, attr32
));
743 put_handle( handle_ptr
, handle
);
748 /**********************************************************************
751 NTSTATUS WINAPI
wow64_NtPulseEvent( UINT
*args
)
753 HANDLE handle
= get_handle( &args
);
754 LONG
*prev_state
= get_ptr( &args
);
756 return NtPulseEvent( handle
, prev_state
);
760 /**********************************************************************
761 * wow64_NtQueryDirectoryObject
763 NTSTATUS WINAPI
wow64_NtQueryDirectoryObject( UINT
*args
)
765 HANDLE handle
= get_handle( &args
);
766 DIRECTORY_BASIC_INFORMATION32
*info32
= get_ptr( &args
);
767 ULONG size32
= get_ulong( &args
);
768 BOOLEAN single_entry
= get_ulong( &args
);
769 BOOLEAN restart
= get_ulong( &args
);
770 ULONG
*context
= get_ptr( &args
);
771 ULONG
*retlen
= get_ptr( &args
);
775 DIRECTORY_BASIC_INFORMATION
*info
;
776 ULONG size
= size32
+ 2 * sizeof(*info
) - 2 * sizeof(*info32
);
778 if (!single_entry
) FIXME( "not implemented\n" );
779 info
= Wow64AllocateTemp( size
);
780 status
= NtQueryDirectoryObject( handle
, info
, size
, single_entry
, restart
, context
, &retsize
);
783 info32
->ObjectName
.Buffer
= PtrToUlong( info32
+ 2 );
784 info32
->ObjectName
.Length
= info
->ObjectName
.Length
;
785 info32
->ObjectName
.MaximumLength
= info
->ObjectName
.MaximumLength
;
786 info32
->ObjectTypeName
.Buffer
= info32
->ObjectName
.Buffer
+ info
->ObjectName
.MaximumLength
;
787 info32
->ObjectTypeName
.Length
= info
->ObjectTypeName
.Length
;
788 info32
->ObjectTypeName
.MaximumLength
= info
->ObjectTypeName
.MaximumLength
;
789 memset( info32
+ 1, 0, sizeof(*info32
) );
790 size
= info
->ObjectName
.MaximumLength
+ info
->ObjectTypeName
.MaximumLength
;
791 memcpy( info32
+ 2, info
+ 2, size
);
792 if (retlen
) *retlen
= 2 * sizeof(*info32
) + size
;
794 else if (retlen
&& status
== STATUS_BUFFER_TOO_SMALL
)
795 *retlen
= retsize
- 2 * sizeof(*info
) + 2 * sizeof(*info32
);
796 else if (retlen
&& status
== STATUS_NO_MORE_ENTRIES
)
802 /**********************************************************************
805 NTSTATUS WINAPI
wow64_NtQueryEvent( UINT
*args
)
807 HANDLE handle
= get_handle( &args
);
808 EVENT_INFORMATION_CLASS
class = get_ulong( &args
);
809 void *info
= get_ptr( &args
);
810 ULONG len
= get_ulong( &args
);
811 ULONG
*retlen
= get_ptr( &args
);
813 return NtQueryEvent( handle
, class, info
, len
, retlen
);
817 /**********************************************************************
818 * wow64_NtQueryInformationJobObject
820 NTSTATUS WINAPI
wow64_NtQueryInformationJobObject( UINT
*args
)
822 HANDLE handle
= get_handle( &args
);
823 JOBOBJECTINFOCLASS
class = get_ulong( &args
);
824 void *ptr
= get_ptr( &args
);
825 ULONG len
= get_ulong( &args
);
826 ULONG
*retlen
= get_ptr( &args
);
832 case JobObjectBasicAccountingInformation
: /* JOBOBJECT_BASIC_ACCOUNTING_INFORMATION */
833 return NtQueryInformationJobObject( handle
, class, ptr
, len
, retlen
);
835 case JobObjectBasicLimitInformation
: /* JOBOBJECT_BASIC_LIMIT_INFORMATION */
836 if (len
>= sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION32
))
838 JOBOBJECT_BASIC_LIMIT_INFORMATION32
*info32
= ptr
;
839 JOBOBJECT_BASIC_LIMIT_INFORMATION info
;
841 status
= NtQueryInformationJobObject( handle
, class, &info
, sizeof(info
), NULL
);
842 if (!status
) put_job_basic_limit_info( info32
, &info
);
843 if (retlen
) *retlen
= sizeof(*info32
);
846 else return STATUS_INFO_LENGTH_MISMATCH
;
848 case JobObjectBasicProcessIdList
: /* JOBOBJECT_BASIC_PROCESS_ID_LIST */
849 if (len
>= sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST32
))
851 JOBOBJECT_BASIC_PROCESS_ID_LIST32
*info32
= ptr
;
852 JOBOBJECT_BASIC_PROCESS_ID_LIST
*info
;
853 ULONG i
, count
, size
;
855 count
= (len
- offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST32
, ProcessIdList
)) / sizeof(info32
->ProcessIdList
[0]);
856 size
= offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST
, ProcessIdList
[count
] );
857 info
= Wow64AllocateTemp( size
);
858 status
= NtQueryInformationJobObject( handle
, class, info
, size
, NULL
);
861 info32
->NumberOfAssignedProcesses
= info
->NumberOfAssignedProcesses
;
862 info32
->NumberOfProcessIdsInList
= info
->NumberOfProcessIdsInList
;
863 for (i
= 0; i
< info
->NumberOfProcessIdsInList
; i
++)
864 info32
->ProcessIdList
[i
] = info
->ProcessIdList
[i
];
865 if (retlen
) *retlen
= offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST32
, ProcessIdList
[i
] );
869 else return STATUS_INFO_LENGTH_MISMATCH
;
871 case JobObjectExtendedLimitInformation
: /* JOBOBJECT_EXTENDED_LIMIT_INFORMATION */
872 if (len
>= sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION32
))
874 JOBOBJECT_EXTENDED_LIMIT_INFORMATION32
*info32
= ptr
;
875 JOBOBJECT_EXTENDED_LIMIT_INFORMATION info
;
877 status
= NtQueryInformationJobObject( handle
, class, &info
, sizeof(info
), NULL
);
880 put_job_basic_limit_info( &info32
->BasicLimitInformation
, &info
.BasicLimitInformation
);
881 info32
->IoInfo
= info
.IoInfo
;
882 info32
->ProcessMemoryLimit
= info
.ProcessMemoryLimit
;
883 info32
->JobMemoryLimit
= info
.JobMemoryLimit
;
884 info32
->PeakProcessMemoryUsed
= info
.PeakProcessMemoryUsed
;
885 info32
->PeakJobMemoryUsed
= info
.PeakJobMemoryUsed
;
887 if (retlen
) *retlen
= sizeof(*info32
);
890 else return STATUS_INFO_LENGTH_MISMATCH
;
893 if (class >= MaxJobObjectInfoClass
) return STATUS_INVALID_PARAMETER
;
894 FIXME( "unsupported class %u\n", class );
895 return STATUS_NOT_IMPLEMENTED
;
900 /**********************************************************************
901 * wow64_NtQueryIoCompletion
903 NTSTATUS WINAPI
wow64_NtQueryIoCompletion( UINT
*args
)
905 HANDLE handle
= get_handle( &args
);
906 IO_COMPLETION_INFORMATION_CLASS
class = get_ulong( &args
);
907 void *info
= get_ptr( &args
);
908 ULONG len
= get_ulong( &args
);
909 ULONG
*retlen
= get_ptr( &args
);
911 return NtQueryIoCompletion( handle
, class, info
, len
, retlen
);
915 /**********************************************************************
916 * wow64_NtQueryMutant
918 NTSTATUS WINAPI
wow64_NtQueryMutant( UINT
*args
)
920 HANDLE handle
= get_handle( &args
);
921 MUTANT_INFORMATION_CLASS
class = get_ulong( &args
);
922 void *info
= get_ptr( &args
);
923 ULONG len
= get_ulong( &args
);
924 ULONG
*retlen
= get_ptr( &args
);
926 return NtQueryMutant( handle
, class, info
, len
, retlen
);
930 /**********************************************************************
931 * wow64_NtQueryObject
933 NTSTATUS WINAPI
wow64_NtQueryObject( UINT
*args
)
935 HANDLE handle
= get_handle( &args
);
936 OBJECT_INFORMATION_CLASS
class = get_ulong( &args
);
937 void *ptr
= get_ptr( &args
);
938 ULONG len
= get_ulong( &args
);
939 ULONG
*retlen
= get_ptr( &args
);
946 case ObjectBasicInformation
: /* OBJECT_BASIC_INFORMATION */
947 case ObjectHandleFlagInformation
: /* OBJECT_HANDLE_FLAG_INFORMATION */
948 return NtQueryObject( handle
, class, ptr
, len
, retlen
);
950 case ObjectNameInformation
: /* OBJECT_NAME_INFORMATION */
952 ULONG size
= len
+ sizeof(OBJECT_NAME_INFORMATION
) - sizeof(OBJECT_NAME_INFORMATION32
);
953 OBJECT_NAME_INFORMATION32
*info32
= ptr
;
954 OBJECT_NAME_INFORMATION
*info
= Wow64AllocateTemp( size
);
956 if (!(status
= NtQueryObject( handle
, class, info
, size
, &ret_size
)))
958 if (len
>= sizeof(*info32
) + info
->Name
.MaximumLength
)
960 if (info
->Name
.Length
)
962 memcpy( info32
+ 1, info
->Name
.Buffer
, info
->Name
.Length
+ sizeof(WCHAR
) );
963 info32
->Name
.Length
= info
->Name
.Length
;
964 info32
->Name
.MaximumLength
= info
->Name
.Length
+ sizeof(WCHAR
);
965 info32
->Name
.Buffer
= PtrToUlong( info32
+ 1 );
967 else memset( &info32
->Name
, 0, sizeof(info32
->Name
) );
969 else status
= STATUS_INFO_LENGTH_MISMATCH
;
970 if (retlen
) *retlen
= sizeof(*info32
) + info
->Name
.MaximumLength
;
972 else if (status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_BUFFER_OVERFLOW
)
974 if (retlen
) *retlen
= ret_size
- sizeof(*info
) + sizeof(*info32
);
979 case ObjectTypeInformation
: /* OBJECT_TYPE_INFORMATION */
981 ULONG_PTR buffer
[(sizeof(OBJECT_TYPE_INFORMATION
) + 64) / sizeof(ULONG_PTR
)];
982 OBJECT_TYPE_INFORMATION
*info
= (OBJECT_TYPE_INFORMATION
*)buffer
;
983 OBJECT_TYPE_INFORMATION32
*info32
= ptr
;
985 if (!(status
= NtQueryObject( handle
, class, info
, sizeof(buffer
), NULL
)))
987 if (len
>= sizeof(*info32
) + info
->TypeName
.MaximumLength
)
988 put_object_type_info( info32
, info
);
990 status
= STATUS_INFO_LENGTH_MISMATCH
;
991 if (retlen
) *retlen
= sizeof(*info32
) + info
->TypeName
.Length
+ sizeof(WCHAR
);
996 case ObjectTypesInformation
: /* OBJECT_TYPES_INFORMATION */
998 OBJECT_TYPES_INFORMATION
*info
, *info32
= ptr
;
999 /* assume at most 32 types, with an average 16-char name */
1000 ULONG ret_size
, size
= 32 * (sizeof(OBJECT_TYPE_INFORMATION
) + 16 * sizeof(WCHAR
));
1002 info
= Wow64AllocateTemp( size
);
1003 if (!(status
= NtQueryObject( handle
, class, info
, size
, &ret_size
)))
1005 OBJECT_TYPE_INFORMATION
*type
;
1006 OBJECT_TYPE_INFORMATION32
*type32
;
1007 ULONG align
= TYPE_ALIGNMENT( OBJECT_TYPE_INFORMATION
) - 1;
1008 ULONG align32
= TYPE_ALIGNMENT( OBJECT_TYPE_INFORMATION32
) - 1;
1009 ULONG i
, pos
= (sizeof(*info
) + align
) & ~align
, pos32
= (sizeof(*info32
) + align32
) & ~align32
;
1011 if (pos32
<= len
) info32
->NumberOfTypes
= info
->NumberOfTypes
;
1012 for (i
= 0; i
< info
->NumberOfTypes
; i
++)
1014 type
= (OBJECT_TYPE_INFORMATION
*)((char *)info
+ pos
);
1015 type32
= (OBJECT_TYPE_INFORMATION32
*)((char *)ptr
+ pos32
);
1016 pos
+= sizeof(*type
) + ((type
->TypeName
.MaximumLength
+ align
) & ~align
);
1017 pos32
+= sizeof(*type32
) + ((type
->TypeName
.MaximumLength
+ align32
) & ~align32
);
1018 if (pos32
<= len
) put_object_type_info( type32
, type
);
1020 if (pos32
> len
) status
= STATUS_INFO_LENGTH_MISMATCH
;
1021 if (retlen
) *retlen
= pos32
;
1027 FIXME( "unsupported class %u\n", class );
1028 return STATUS_NOT_IMPLEMENTED
;
1033 /**********************************************************************
1034 * wow64_NtQueryPerformanceCounter
1036 NTSTATUS WINAPI
wow64_NtQueryPerformanceCounter( UINT
*args
)
1038 LARGE_INTEGER
*counter
= get_ptr( &args
);
1039 LARGE_INTEGER
*frequency
= get_ptr( &args
);
1041 return NtQueryPerformanceCounter( counter
, frequency
);
1045 /**********************************************************************
1046 * wow64_NtQuerySection
1048 NTSTATUS WINAPI
wow64_NtQuerySection( UINT
*args
)
1050 HANDLE handle
= get_handle( &args
);
1051 SECTION_INFORMATION_CLASS
class = get_ulong( &args
);
1052 void *ptr
= get_ptr( &args
);
1053 SIZE_T size
= get_ulong( &args
);
1054 ULONG
*ret_ptr
= get_ptr( &args
);
1057 SIZE_T ret_size
= 0;
1061 case SectionBasicInformation
:
1063 SECTION_BASIC_INFORMATION info
;
1064 SECTION_BASIC_INFORMATION32
*info32
= ptr
;
1066 if (size
< sizeof(*info32
)) return STATUS_INFO_LENGTH_MISMATCH
;
1067 if (!(status
= NtQuerySection( handle
, class, &info
, sizeof(info
), &ret_size
)))
1069 info32
->BaseAddress
= PtrToUlong( info
.BaseAddress
);
1070 info32
->Attributes
= info
.Attributes
;
1071 info32
->Size
= info
.Size
;
1072 ret_size
= sizeof(*info32
);
1076 case SectionImageInformation
:
1078 SECTION_IMAGE_INFORMATION info
;
1079 SECTION_IMAGE_INFORMATION32
*info32
= ptr
;
1081 if (size
< sizeof(*info32
)) return STATUS_INFO_LENGTH_MISMATCH
;
1082 if (!(status
= NtQuerySection( handle
, class, &info
, sizeof(info
), &ret_size
)))
1084 put_section_image_info( info32
, &info
);
1085 ret_size
= sizeof(*info32
);
1090 FIXME( "class %u not implemented\n", class );
1091 return STATUS_NOT_IMPLEMENTED
;
1093 put_size( ret_ptr
, ret_size
);
1098 /**********************************************************************
1099 * wow64_NtQuerySemaphore
1101 NTSTATUS WINAPI
wow64_NtQuerySemaphore( UINT
*args
)
1103 HANDLE handle
= get_handle( &args
);
1104 SEMAPHORE_INFORMATION_CLASS
class = get_ulong( &args
);
1105 void *info
= get_ptr( &args
);
1106 ULONG len
= get_ulong( &args
);
1107 ULONG
*retlen
= get_ptr( &args
);
1109 return NtQuerySemaphore( handle
, class, info
, len
, retlen
);
1113 /**********************************************************************
1114 * wow64_NtQuerySymbolicLinkObject
1116 NTSTATUS WINAPI
wow64_NtQuerySymbolicLinkObject( UINT
*args
)
1118 HANDLE handle
= get_handle( &args
);
1119 UNICODE_STRING32
*target32
= get_ptr( &args
);
1120 ULONG
*retlen
= get_ptr( &args
);
1122 UNICODE_STRING target
;
1125 status
= NtQuerySymbolicLinkObject( handle
, unicode_str_32to64( &target
, target32
), retlen
);
1126 if (!status
) target32
->Length
= target
.Length
;
1131 /**********************************************************************
1132 * wow64_NtQueryTimer
1134 NTSTATUS WINAPI
wow64_NtQueryTimer( UINT
*args
)
1136 HANDLE handle
= get_handle( &args
);
1137 TIMER_INFORMATION_CLASS
class = get_ulong( &args
);
1138 void *info
= get_ptr( &args
);
1139 ULONG len
= get_ulong( &args
);
1140 ULONG
*retlen
= get_ptr( &args
);
1142 return NtQueryTimer( handle
, class, info
, len
, retlen
);
1146 /**********************************************************************
1147 * wow64_NtQueryTimerResolution
1149 NTSTATUS WINAPI
wow64_NtQueryTimerResolution( UINT
*args
)
1151 ULONG
*min_res
= get_ptr( &args
);
1152 ULONG
*max_res
= get_ptr( &args
);
1153 ULONG
*current_res
= get_ptr( &args
);
1155 return NtQueryTimerResolution( min_res
, max_res
, current_res
);
1159 /**********************************************************************
1160 * wow64_NtRegisterThreadTerminatePort
1162 NTSTATUS WINAPI
wow64_NtRegisterThreadTerminatePort( UINT
*args
)
1164 HANDLE handle
= get_handle( &args
);
1166 return NtRegisterThreadTerminatePort( handle
);
1170 /**********************************************************************
1171 * wow64_NtReleaseKeyedEvent
1173 NTSTATUS WINAPI
wow64_NtReleaseKeyedEvent( UINT
*args
)
1175 HANDLE handle
= get_handle( &args
);
1176 void *key
= get_ptr( &args
);
1177 BOOLEAN alertable
= get_ulong( &args
);
1178 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1180 return NtReleaseKeyedEvent( handle
, key
, alertable
, timeout
);
1184 /**********************************************************************
1185 * wow64_NtReleaseMutant
1187 NTSTATUS WINAPI
wow64_NtReleaseMutant( UINT
*args
)
1189 HANDLE handle
= get_handle( &args
);
1190 LONG
*prev_count
= get_ptr( &args
);
1192 return NtReleaseMutant( handle
, prev_count
);
1196 /**********************************************************************
1197 * wow64_NtReleaseSemaphore
1199 NTSTATUS WINAPI
wow64_NtReleaseSemaphore( UINT
*args
)
1201 HANDLE handle
= get_handle( &args
);
1202 ULONG count
= get_ulong( &args
);
1203 ULONG
*previous
= get_ptr( &args
);
1205 return NtReleaseSemaphore( handle
, count
, previous
);
1209 /**********************************************************************
1210 * wow64_NtReplyWaitReceivePort
1212 NTSTATUS WINAPI
wow64_NtReplyWaitReceivePort( UINT
*args
)
1214 HANDLE handle
= get_handle( &args
);
1215 ULONG
*id
= get_ptr( &args
);
1216 LPC_MESSAGE
*reply
= get_ptr( &args
);
1217 LPC_MESSAGE
*msg
= get_ptr( &args
);
1219 FIXME( "%p %p %p %p: stub\n", handle
, id
, reply
, msg
);
1220 return STATUS_NOT_IMPLEMENTED
;
1224 /**********************************************************************
1225 * wow64_NtRequestWaitReplyPort
1227 NTSTATUS WINAPI
wow64_NtRequestWaitReplyPort( UINT
*args
)
1229 HANDLE handle
= get_handle( &args
);
1230 LPC_MESSAGE
*msg_in
= get_ptr( &args
);
1231 LPC_MESSAGE
*msg_out
= get_ptr( &args
);
1233 FIXME( "%p %p %p: stub\n", handle
, msg_in
, msg_out
);
1234 return STATUS_NOT_IMPLEMENTED
;
1238 /**********************************************************************
1239 * wow64_NtResetEvent
1241 NTSTATUS WINAPI
wow64_NtResetEvent( UINT
*args
)
1243 HANDLE handle
= get_handle( &args
);
1244 LONG
*prev_state
= get_ptr( &args
);
1246 return NtResetEvent( handle
, prev_state
);
1250 /**********************************************************************
1251 * wow64_NtSecureConnectPort
1253 NTSTATUS WINAPI
wow64_NtSecureConnectPort( UINT
*args
)
1255 ULONG
*handle_ptr
= get_ptr( &args
);
1256 UNICODE_STRING32
*name32
= get_ptr( &args
);
1257 SECURITY_QUALITY_OF_SERVICE
*qos
= get_ptr( &args
);
1258 LPC_SECTION_WRITE
*write
= get_ptr( &args
);
1259 SID
*sid
= get_ptr( &args
);
1260 LPC_SECTION_READ
*read
= get_ptr( &args
);
1261 ULONG
*max_len
= get_ptr( &args
);
1262 void *info
= get_ptr( &args
);
1263 ULONG
*info_len
= get_ptr( &args
);
1265 FIXME( "%p %p %p %p %p %p %p %p %p: stub\n",
1266 handle_ptr
, name32
, qos
, write
, sid
, read
, max_len
, info
, info_len
);
1267 return STATUS_NOT_IMPLEMENTED
;
1271 /**********************************************************************
1274 NTSTATUS WINAPI
wow64_NtSetEvent( UINT
*args
)
1276 HANDLE handle
= get_handle( &args
);
1277 LONG
*prev_state
= get_ptr( &args
);
1279 return NtSetEvent( handle
, prev_state
);
1283 /**********************************************************************
1284 * wow64_NtSetInformationDebugObject
1286 NTSTATUS WINAPI
wow64_NtSetInformationDebugObject( UINT
*args
)
1288 HANDLE handle
= get_handle( &args
);
1289 DEBUGOBJECTINFOCLASS
class = get_ulong( &args
);
1290 void *ptr
= get_ptr( &args
);
1291 ULONG len
= get_ulong( &args
);
1292 ULONG
*retlen
= get_ptr( &args
);
1294 return NtSetInformationDebugObject( handle
, class, ptr
, len
, retlen
);
1298 /**********************************************************************
1299 * wow64_NtSetInformationJobObject
1301 NTSTATUS WINAPI
wow64_NtSetInformationJobObject( UINT
*args
)
1303 HANDLE handle
= get_handle( &args
);
1304 JOBOBJECTINFOCLASS
class = get_ulong( &args
);
1305 void *ptr
= get_ptr( &args
);
1306 ULONG len
= get_ulong( &args
);
1310 case JobObjectBasicLimitInformation
: /* JOBOBJECT_BASIC_LIMIT_INFORMATION */
1311 if (len
== sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION32
))
1313 JOBOBJECT_BASIC_LIMIT_INFORMATION info
;
1315 return NtSetInformationJobObject( handle
, class, job_basic_limit_info_32to64( &info
, ptr
),
1318 else return STATUS_INVALID_PARAMETER
;
1320 case JobObjectBasicUIRestrictions
:
1321 FIXME( "unsupported class JobObjectBasicUIRestrictions\n" );
1322 return STATUS_SUCCESS
;
1324 case JobObjectAssociateCompletionPortInformation
: /* JOBOBJECT_ASSOCIATE_COMPLETION_PORT */
1325 if (len
== sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT32
))
1327 JOBOBJECT_ASSOCIATE_COMPLETION_PORT32
*info32
= ptr
;
1328 JOBOBJECT_ASSOCIATE_COMPLETION_PORT info
;
1330 info
.CompletionKey
= ULongToPtr( info32
->CompletionKey
);
1331 info
.CompletionPort
= LongToHandle( info32
->CompletionPort
);
1332 return NtSetInformationJobObject( handle
, class, &info
, sizeof(info
) );
1334 else return STATUS_INVALID_PARAMETER
;
1336 case JobObjectExtendedLimitInformation
: /* JOBOBJECT_EXTENDED_LIMIT_INFORMATION */
1337 if (len
== sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION32
))
1339 JOBOBJECT_EXTENDED_LIMIT_INFORMATION32
*info32
= ptr
;
1340 JOBOBJECT_EXTENDED_LIMIT_INFORMATION info
;
1342 info
.IoInfo
= info32
->IoInfo
;
1343 info
.ProcessMemoryLimit
= info32
->ProcessMemoryLimit
;
1344 info
.JobMemoryLimit
= info32
->JobMemoryLimit
;
1345 info
.PeakProcessMemoryUsed
= info32
->PeakProcessMemoryUsed
;
1346 info
.PeakJobMemoryUsed
= info32
->PeakJobMemoryUsed
;
1347 return NtSetInformationJobObject( handle
, class,
1348 job_basic_limit_info_32to64( &info
.BasicLimitInformation
,
1349 &info32
->BasicLimitInformation
),
1352 else return STATUS_INVALID_PARAMETER
;
1355 if (class >= MaxJobObjectInfoClass
) return STATUS_INVALID_PARAMETER
;
1356 FIXME( "unsupported class %u\n", class );
1357 return STATUS_NOT_IMPLEMENTED
;
1362 /**********************************************************************
1363 * wow64_NtSetInformationObject
1365 NTSTATUS WINAPI
wow64_NtSetInformationObject( UINT
*args
)
1367 HANDLE handle
= get_handle( &args
);
1368 OBJECT_INFORMATION_CLASS
class = get_ulong( &args
);
1369 void *ptr
= get_ptr( &args
);
1370 ULONG len
= get_ulong( &args
);
1374 case ObjectHandleFlagInformation
: /* OBJECT_HANDLE_FLAG_INFORMATION */
1375 return NtSetInformationObject( handle
, class, ptr
, len
);
1378 FIXME( "unsupported class %u\n", class );
1379 return STATUS_NOT_IMPLEMENTED
;
1384 /**********************************************************************
1385 * wow64_NtSetIoCompletion
1387 NTSTATUS WINAPI
wow64_NtSetIoCompletion( UINT
*args
)
1389 HANDLE handle
= get_handle( &args
);
1390 ULONG_PTR key
= get_ulong( &args
);
1391 ULONG_PTR value
= get_ulong( &args
);
1392 NTSTATUS status
= get_ulong( &args
);
1393 SIZE_T count
= get_ulong( &args
);
1395 return NtSetIoCompletion( handle
, key
, value
, status
, count
);
1399 /**********************************************************************
1402 NTSTATUS WINAPI
wow64_NtSetTimer( UINT
*args
)
1404 HANDLE handle
= get_handle( &args
);
1405 LARGE_INTEGER
*when
= get_ptr( &args
);
1406 ULONG apc
= get_ulong( &args
);
1407 ULONG apc_param
= get_ulong( &args
);
1408 BOOLEAN resume
= get_ulong( &args
);
1409 ULONG period
= get_ulong( &args
);
1410 BOOLEAN
*state
= get_ptr( &args
);
1412 return NtSetTimer( handle
, when
, apc_32to64( apc
), apc_param_32to64( apc
, apc_param
),
1413 resume
, period
, state
);
1417 /**********************************************************************
1418 * wow64_NtSetTimerResolution
1420 NTSTATUS WINAPI
wow64_NtSetTimerResolution( UINT
*args
)
1422 ULONG res
= get_ulong( &args
);
1423 BOOLEAN set
= get_ulong( &args
);
1424 ULONG
*current_res
= get_ptr( &args
);
1426 return NtSetTimerResolution( res
, set
, current_res
);
1430 /**********************************************************************
1431 * wow64_NtSignalAndWaitForSingleObject
1433 NTSTATUS WINAPI
wow64_NtSignalAndWaitForSingleObject( UINT
*args
)
1435 HANDLE signal
= get_handle( &args
);
1436 HANDLE wait
= get_handle( &args
);
1437 BOOLEAN alertable
= get_ulong( &args
);
1438 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1440 return NtSignalAndWaitForSingleObject( signal
, wait
, alertable
, timeout
);
1444 /**********************************************************************
1445 * wow64_NtTerminateJobObject
1447 NTSTATUS WINAPI
wow64_NtTerminateJobObject( UINT
*args
)
1449 HANDLE handle
= get_handle( &args
);
1450 NTSTATUS status
= get_ulong( &args
);
1452 return NtTerminateJobObject( handle
, status
);
1456 /**********************************************************************
1459 NTSTATUS WINAPI
wow64_NtTestAlert( UINT
*args
)
1461 return NtTestAlert();
1465 /**********************************************************************
1466 * wow64_NtTraceControl
1468 NTSTATUS WINAPI
wow64_NtTraceControl( UINT
*args
)
1470 ULONG code
= get_ulong( &args
);
1471 void *inbuf
= get_ptr( &args
);
1472 ULONG inbuf_len
= get_ulong( &args
);
1473 void *outbuf
= get_ptr( &args
);
1474 ULONG outbuf_len
= get_ulong( &args
);
1475 ULONG
*size
= get_ptr( &args
);
1477 return NtTraceControl( code
, inbuf
, inbuf_len
, outbuf
, outbuf_len
, size
);
1481 /**********************************************************************
1482 * wow64_NtWaitForAlertByThreadId
1484 NTSTATUS WINAPI
wow64_NtWaitForAlertByThreadId( UINT
*args
)
1486 const void *address
= get_ptr( &args
);
1487 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1489 return NtWaitForAlertByThreadId( address
, timeout
);
1493 /* helper to wow64_NtWaitForDebugEvent; retrieve machine from PE image */
1494 static NTSTATUS
get_image_machine( HANDLE handle
, USHORT
*machine
)
1496 IMAGE_DOS_HEADER dos_hdr
;
1497 IMAGE_NT_HEADERS nt_hdr
;
1498 IO_STATUS_BLOCK iosb
;
1499 LARGE_INTEGER offset
;
1500 FILE_POSITION_INFORMATION pos_info
;
1503 offset
.QuadPart
= 0;
1504 status
= NtReadFile( handle
, NULL
, NULL
, NULL
,
1505 &iosb
, &dos_hdr
, sizeof(dos_hdr
), &offset
, NULL
);
1508 offset
.QuadPart
= dos_hdr
.e_lfanew
;
1509 status
= NtReadFile( handle
, NULL
, NULL
, NULL
, &iosb
,
1510 &nt_hdr
, FIELD_OFFSET(IMAGE_NT_HEADERS
, OptionalHeader
), &offset
, NULL
);
1512 *machine
= nt_hdr
.FileHeader
.Machine
;
1513 /* Reset file pos at beginning of file */
1514 pos_info
.CurrentByteOffset
.QuadPart
= 0;
1515 NtSetInformationFile( handle
, &iosb
, &pos_info
, sizeof(pos_info
), FilePositionInformation
);
1520 /* helper to wow64_NtWaitForDebugEvent; only pass debug events for current machine */
1521 static BOOL
filter_out_state_change( HANDLE handle
, DBGUI_WAIT_STATE_CHANGE
*state
)
1525 switch (state
->NewState
)
1527 case DbgLoadDllStateChange
:
1528 filter_out
= ((ULONG64
)state
->StateInfo
.LoadDll
.BaseOfDll
>> 32) != 0;
1532 filter_out
= !get_image_machine( state
->StateInfo
.LoadDll
.FileHandle
, &machine
) && machine
!= current_machine
;
1535 case DbgUnloadDllStateChange
:
1536 filter_out
= ((ULONG_PTR
)state
->StateInfo
.UnloadDll
.BaseAddress
>> 32) != 0;
1544 if (state
->NewState
== DbgLoadDllStateChange
)
1545 NtClose( state
->StateInfo
.LoadDll
.FileHandle
);
1546 NtDebugContinue( handle
, &state
->AppClientId
, DBG_CONTINUE
);
1552 /**********************************************************************
1553 * wow64_NtWaitForDebugEvent
1555 NTSTATUS WINAPI
wow64_NtWaitForDebugEvent( UINT
*args
)
1557 HANDLE handle
= get_handle( &args
);
1558 BOOLEAN alertable
= get_ulong( &args
);
1559 LARGE_INTEGER
*timeout
= get_ptr( &args
);
1560 DBGUI_WAIT_STATE_CHANGE32
*state32
= get_ptr( &args
);
1563 DBGUI_WAIT_STATE_CHANGE state
;
1568 status
= NtWaitForDebugEvent( handle
, alertable
, timeout
, &state
);
1569 } while (!status
&& filter_out_state_change( handle
, &state
));
1573 state32
->NewState
= state
.NewState
;
1574 state32
->AppClientId
.UniqueProcess
= HandleToULong( state
.AppClientId
.UniqueProcess
);
1575 state32
->AppClientId
.UniqueThread
= HandleToULong( state
.AppClientId
.UniqueThread
);
1576 switch (state
.NewState
)
1578 #define COPY_ULONG(field) state32->StateInfo.field = state.StateInfo.field
1579 #define COPY_PTR(field) state32->StateInfo.field = PtrToUlong( state.StateInfo.field )
1580 case DbgCreateThreadStateChange
:
1581 COPY_PTR( CreateThread
.HandleToThread
);
1582 COPY_PTR( CreateThread
.NewThread
.StartAddress
);
1583 COPY_ULONG( CreateThread
.NewThread
.SubSystemKey
);
1585 case DbgCreateProcessStateChange
:
1586 COPY_PTR( CreateProcessInfo
.HandleToProcess
);
1587 COPY_PTR( CreateProcessInfo
.HandleToThread
);
1588 COPY_PTR( CreateProcessInfo
.NewProcess
.FileHandle
);
1589 COPY_PTR( CreateProcessInfo
.NewProcess
.BaseOfImage
);
1590 COPY_PTR( CreateProcessInfo
.NewProcess
.InitialThread
.StartAddress
);
1591 COPY_ULONG( CreateProcessInfo
.NewProcess
.InitialThread
.SubSystemKey
);
1592 COPY_ULONG( CreateProcessInfo
.NewProcess
.DebugInfoFileOffset
);
1593 COPY_ULONG( CreateProcessInfo
.NewProcess
.DebugInfoSize
);
1595 case DbgExitThreadStateChange
:
1596 case DbgExitProcessStateChange
:
1597 COPY_ULONG( ExitThread
.ExitStatus
);
1599 case DbgExceptionStateChange
:
1600 case DbgBreakpointStateChange
:
1601 case DbgSingleStepStateChange
:
1602 COPY_ULONG( Exception
.FirstChance
);
1603 COPY_ULONG( Exception
.ExceptionRecord
.ExceptionCode
);
1604 COPY_ULONG( Exception
.ExceptionRecord
.ExceptionFlags
);
1605 COPY_ULONG( Exception
.ExceptionRecord
.NumberParameters
);
1606 COPY_PTR( Exception
.ExceptionRecord
.ExceptionRecord
);
1607 COPY_PTR( Exception
.ExceptionRecord
.ExceptionAddress
);
1608 for (i
= 0; i
< state
.StateInfo
.Exception
.ExceptionRecord
.NumberParameters
; i
++)
1609 COPY_ULONG( Exception
.ExceptionRecord
.ExceptionInformation
[i
] );
1611 case DbgLoadDllStateChange
:
1612 COPY_PTR( LoadDll
.FileHandle
);
1613 COPY_PTR( LoadDll
.BaseOfDll
);
1614 COPY_ULONG( LoadDll
.DebugInfoFileOffset
);
1615 COPY_ULONG( LoadDll
.DebugInfoSize
);
1616 COPY_PTR( LoadDll
.NamePointer
);
1618 case DbgUnloadDllStateChange
:
1619 COPY_PTR( UnloadDll
.BaseAddress
);
1631 /**********************************************************************
1632 * wow64_NtWaitForKeyedEvent
1634 NTSTATUS WINAPI
wow64_NtWaitForKeyedEvent( UINT
*args
)
1636 HANDLE handle
= get_handle( &args
);
1637 const void *key
= get_ptr( &args
);
1638 BOOLEAN alertable
= get_ulong( &args
);
1639 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1641 return NtWaitForKeyedEvent( handle
, key
, alertable
, timeout
);
1645 /**********************************************************************
1646 * wow64_NtWaitForMultipleObjects
1648 NTSTATUS WINAPI
wow64_NtWaitForMultipleObjects( UINT
*args
)
1650 DWORD count
= get_ulong( &args
);
1651 LONG
*handles_ptr
= get_ptr( &args
);
1652 BOOLEAN wait_any
= get_ulong( &args
);
1653 BOOLEAN alertable
= get_ulong( &args
);
1654 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1656 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
1659 for (i
= 0; i
< count
&& i
< MAXIMUM_WAIT_OBJECTS
; i
++) handles
[i
] = LongToHandle( handles_ptr
[i
] );
1660 return NtWaitForMultipleObjects( count
, handles
, wait_any
, alertable
, timeout
);
1664 /**********************************************************************
1665 * wow64_NtWaitForSingleObject
1667 NTSTATUS WINAPI
wow64_NtWaitForSingleObject( UINT
*args
)
1669 HANDLE handle
= get_handle( &args
);
1670 BOOLEAN alertable
= get_ulong( &args
);
1671 const LARGE_INTEGER
*timeout
= get_ptr( &args
);
1673 return NtWaitForSingleObject( handle
, alertable
, timeout
);
1677 /**********************************************************************
1678 * wow64_NtYieldExecution
1680 NTSTATUS WINAPI
wow64_NtYieldExecution( UINT
*args
)
1682 return NtYieldExecution();
1686 /**********************************************************************
1687 * wow64_NtCreateTransaction
1689 NTSTATUS WINAPI
wow64_NtCreateTransaction( UINT
*args
)
1691 ULONG
*handle_ptr
= get_ptr( &args
);
1692 ACCESS_MASK access
= get_ulong( &args
);
1693 OBJECT_ATTRIBUTES32
*attr32
= get_ptr( &args
);
1694 GUID
*guid
= get_ptr( &args
);
1695 HANDLE tm
= get_handle( &args
);
1696 ULONG options
= get_ulong( &args
);
1697 ULONG isol_level
= get_ulong( &args
);
1698 ULONG isol_flags
= get_ulong( &args
);
1699 LARGE_INTEGER
*timeout
= get_ptr( &args
);
1700 UNICODE_STRING32
*desc32
= get_ptr( &args
);
1702 struct object_attr64 attr
;
1703 UNICODE_STRING desc
;
1708 status
= NtCreateTransaction( &handle
, access
, objattr_32to64( &attr
, attr32
), guid
, tm
, options
,
1709 isol_level
, isol_flags
, timeout
, unicode_str_32to64( &desc
, desc32
));
1710 put_handle( handle_ptr
, handle
);
1716 /**********************************************************************
1717 * wow64_NtCommitTransaction
1719 NTSTATUS WINAPI
wow64_NtCommitTransaction( UINT
*args
)
1721 HANDLE handle
= get_handle( &args
);
1722 BOOLEAN wait
= get_ulong( &args
);
1724 return NtCommitTransaction( handle
, wait
);
1728 /**********************************************************************
1729 * wow64_NtRollbackTransaction
1731 NTSTATUS WINAPI
wow64_NtRollbackTransaction( UINT
*args
)
1733 HANDLE handle
= get_handle( &args
);
1734 BOOLEAN wait
= get_ulong( &args
);
1736 return NtRollbackTransaction( handle
, wait
);