ntdll: Implement RtlCreateUserThread() on top of NtCreateThreadEx().
Based on a patch by Andrew Wesie. Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ca3ca7b046
commit
39e7f25e09
|
@ -326,16 +326,33 @@ static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *
|
|||
* NtCreateThreadEx (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle_ptr, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
|
||||
HANDLE process, LPTHREAD_START_ROUTINE start, void *param,
|
||||
ULONG flags, ULONG zero_bits, ULONG stack_commit,
|
||||
ULONG stack_reserve, void *attribute_list )
|
||||
HANDLE process, PRTL_THREAD_START_ROUTINE start, void *param,
|
||||
ULONG flags, SIZE_T zero_bits, SIZE_T stack_commit,
|
||||
SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list )
|
||||
{
|
||||
FIXME( "%p, %x, %p, %p, %p, %p, %x, %x, %x, %x, %p semi-stub!\n", handle_ptr, access, attr,
|
||||
process, start, param, flags, zero_bits, stack_commit, stack_reserve, attribute_list );
|
||||
NTSTATUS status;
|
||||
CLIENT_ID client_id;
|
||||
|
||||
return RtlCreateUserThread( process, NULL, flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED,
|
||||
NULL, stack_reserve, stack_commit, (PRTL_THREAD_START_ROUTINE)start,
|
||||
param, handle_ptr, NULL );
|
||||
if (!access) access = THREAD_ALL_ACCESS;
|
||||
|
||||
status = unix_funcs->create_thread( handle_ptr, access, attr, process,
|
||||
start, param, call_thread_entry_point, flags,
|
||||
stack_commit, stack_reserve, &client_id );
|
||||
if (!status && attr_list)
|
||||
{
|
||||
SIZE_T i, count = (attr_list->TotalLength - sizeof(attr_list->TotalLength)) / sizeof(PS_ATTRIBUTE);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (attr_list->Attributes[i].Attribute == PS_ATTRIBUTE_CLIENT_ID)
|
||||
{
|
||||
SIZE_T size = min( attr_list->Attributes[i].Size, sizeof(client_id) );
|
||||
memcpy( attr_list->Attributes[i].ValuePtr, &client_id, size );
|
||||
if (attr_list->Attributes[i].ReturnLength) *attr_list->Attributes[i].ReturnLength = size;
|
||||
}
|
||||
else FIXME( "Unsupported attribute %08lx\n", attr_list->Attributes[i].Attribute );
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,12 +370,16 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
|||
NTSTATUS status;
|
||||
CLIENT_ID client_id;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
PS_ATTRIBUTE_LIST attr_list = { sizeof(attr_list) };
|
||||
|
||||
attr_list.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID;
|
||||
attr_list.Attributes[0].Size = sizeof(client_id);
|
||||
attr_list.Attributes[0].ValuePtr = &client_id;
|
||||
|
||||
InitializeObjectAttributes( &attr, NULL, 0, NULL, descr );
|
||||
|
||||
status = unix_funcs->create_thread( &handle, THREAD_ALL_ACCESS, &attr, process,
|
||||
start, param, call_thread_entry_point, flags,
|
||||
stack_commit, stack_reserve, &client_id );
|
||||
status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, &attr, process, start, param,
|
||||
flags, 0, stack_commit, stack_reserve, &attr_list );
|
||||
if (!status)
|
||||
{
|
||||
if (id) *id = client_id;
|
||||
|
|
|
@ -2453,6 +2453,55 @@ typedef LONG (CALLBACK *PRTL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS);
|
|||
|
||||
typedef void (CALLBACK *PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_STATUS_BLOCK*,PTP_IO);
|
||||
|
||||
#define PS_ATTRIBUTE_THREAD 0x00010000
|
||||
#define PS_ATTRIBUTE_INPUT 0x00020000
|
||||
#define PS_ATTRIBUTE_UNKNOWN 0x00040000
|
||||
|
||||
typedef enum _PS_ATTRIBUTE_NUM
|
||||
{
|
||||
PsAttributeParentProcess,
|
||||
PsAttributeDebugPort,
|
||||
PsAttributeToken,
|
||||
PsAttributeClientId,
|
||||
PsAttributeTebAddress,
|
||||
PsAttributeImageName,
|
||||
PsAttributeImageInfo,
|
||||
PsAttributeMemoryReserve,
|
||||
PsAttributePriorityClass,
|
||||
PsAttributeErrorMode,
|
||||
PsAttributeStdHandleInfo,
|
||||
PsAttributeHandleList,
|
||||
PsAttributeGroupAffinity,
|
||||
PsAttributePreferredNode,
|
||||
PsAttributeIdealProcessor,
|
||||
PsAttributeUmsThread,
|
||||
PsAttributeMitigationOptions,
|
||||
PsAttributeProtectionLevel,
|
||||
PsAttributeSecureProcess,
|
||||
PsAttributeJobList,
|
||||
PsAttributeMax
|
||||
} PS_ATTRIBUTE_NUM;
|
||||
|
||||
#define PS_ATTRIBUTE_CLIENT_ID (PsAttributeClientId | PS_ATTRIBUTE_THREAD)
|
||||
|
||||
typedef struct _PS_ATTRIBUTE
|
||||
{
|
||||
ULONG_PTR Attribute;
|
||||
SIZE_T Size;
|
||||
union
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
void *ValuePtr;
|
||||
};
|
||||
SIZE_T *ReturnLength;
|
||||
} PS_ATTRIBUTE;
|
||||
|
||||
typedef struct _PS_ATTRIBUTE_LIST
|
||||
{
|
||||
SIZE_T TotalLength;
|
||||
PS_ATTRIBUTE Attributes[1];
|
||||
} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;
|
||||
|
||||
/***********************************************************************
|
||||
* Function declarations
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue