From 84d25135b3b2f9a30619f741d166fa1daa8298e5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 10 Jun 2020 09:37:01 +0200 Subject: [PATCH] ntdll: Implement NtCreateUserProcess(). Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/process.c | 192 ++++++++++++++++++++++++++++++++++++++++---------- include/winternl.h | 130 ++++++++++++++++++++++++++++++++-- 3 files changed, 281 insertions(+), 42 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index e054eabba3a..0b0d4587969 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -186,6 +186,7 @@ @ stdcall NtCreateThreadEx(ptr long ptr long ptr ptr long long long long ptr) @ stdcall NtCreateTimer(ptr long ptr long) @ stub NtCreateToken +@ stdcall NtCreateUserProcess(ptr ptr long long ptr ptr long long ptr ptr ptr) # @ stub NtCreateWaitablePort @ stdcall -arch=win32,arm64 NtCurrentTeb() # @ stub NtDebugActiveProcess diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 35937ce6026..5b9e5638ef3 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -1595,36 +1595,62 @@ NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) /********************************************************************** - * RtlCreateUserProcess (NTDLL.@) + * NtCreateUserProcess (NTDLL.@) */ -NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, - RTL_USER_PROCESS_PARAMETERS *params, - SECURITY_DESCRIPTOR *process_descr, - SECURITY_DESCRIPTOR *thread_descr, - HANDLE parent, BOOLEAN inherit, HANDLE debug, HANDLE exception, - RTL_USER_PROCESS_INFORMATION *info ) +NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_handle_ptr, + ACCESS_MASK process_access, ACCESS_MASK thread_access, + OBJECT_ATTRIBUTES *process_attr, OBJECT_ATTRIBUTES *thread_attr, + ULONG process_flags, ULONG thread_flags, + RTL_USER_PROCESS_PARAMETERS *params, PS_CREATE_INFO *info, + PS_ATTRIBUTE_LIST *attr ) { NTSTATUS status; BOOL success = FALSE; HANDLE file_handle, process_info = 0, process_handle = 0, thread_handle = 0; - ULONG process_id, thread_id; struct object_attributes *objattr; data_size_t attr_len; char *unixdir = NULL, *winedebug = NULL; startup_info_t *startup_info = NULL; ULONG startup_info_size, env_size; int socketfd[2] = { -1, -1 }; - OBJECT_ATTRIBUTES attr; pe_image_info_t pe_info; + CLIENT_ID id; + HANDLE parent = 0, debug = 0, token = 0; + UNICODE_STRING path = {0}; + SIZE_T i, attr_count = (attr->TotalLength - sizeof(attr->TotalLength)) / sizeof(PS_ATTRIBUTE); - RtlNormalizeProcessParams( params ); + for (i = 0; i < attr_count; i++) + { + switch (attr->Attributes[i].Attribute) + { + case PS_ATTRIBUTE_PARENT_PROCESS: + parent = attr->Attributes[i].ValuePtr; + break; + case PS_ATTRIBUTE_DEBUG_PORT: + debug = attr->Attributes[i].ValuePtr; + break; + case PS_ATTRIBUTE_IMAGE_NAME: + path.Length = attr->Attributes[i].Size; + path.Buffer = attr->Attributes[i].ValuePtr; + break; + case PS_ATTRIBUTE_TOKEN: + token = attr->Attributes[i].ValuePtr; + break; + default: + if (attr->Attributes[i].Attribute & PS_ATTRIBUTE_INPUT) + FIXME( "unhandled input attribute %lx\n", attr->Attributes[i].Attribute ); + break; + } + } - TRACE( "%s image %s cmdline %s\n", debugstr_us( path ), - debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine )); + TRACE( "%s image %s cmdline %s parent %p\n", debugstr_us( &path ), + debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ), parent ); + if (debug) FIXME( "debug port %p not supported yet\n", debug ); + if (token) FIXME( "token %p not supported yet\n", token ); - if ((status = get_pe_file_info( path, attributes, &file_handle, &pe_info ))) + if ((status = get_pe_file_info( &path, OBJ_CASE_INSENSITIVE, &file_handle, &pe_info ))) { - if (status == STATUS_INVALID_IMAGE_NOT_MZ && !fork_and_exec( path, params )) + if (status == STATUS_INVALID_IMAGE_NOT_MZ && !fork_and_exec( &path, params )) { memset( info, 0, sizeof(*info) ); return STATUS_SUCCESS; @@ -1635,8 +1661,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, env_size = get_env_size( params, &winedebug ); unixdir = get_unix_curdir( params ); - InitializeObjectAttributes( &attr, NULL, 0, NULL, process_descr ); - if ((status = alloc_object_attributes( &attr, &objattr, &attr_len ))) goto done; + if ((status = alloc_object_attributes( process_attr, &objattr, &attr_len ))) goto done; /* create the socket for the new process */ @@ -1661,12 +1686,12 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, SERVER_START_REQ( new_process ) { - req->parent_process = wine_server_obj_handle(parent); - req->inherit_all = inherit; + req->parent_process = wine_server_obj_handle( parent ); + req->inherit_all = !!(process_flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES); req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */ req->socket_fd = socketfd[1]; req->exe_file = wine_server_obj_handle( file_handle ); - req->access = PROCESS_ALL_ACCESS; + req->access = process_access; req->cpu = pe_info.cpu; req->info_size = startup_info_size; wine_server_add_data( req, objattr, attr_len ); @@ -1674,8 +1699,8 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, wine_server_add_data( req, params->Environment, env_size ); if (!(status = wine_server_call( req ))) { - process_id = reply->pid; process_handle = wine_server_ptr_handle( reply->handle ); + id.UniqueProcess = ULongToHandle( reply->pid ); } process_info = wine_server_ptr_handle( reply->info ); } @@ -1687,30 +1712,29 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, switch (status) { case STATUS_INVALID_IMAGE_WIN_64: - ERR( "64-bit application %s not supported in 32-bit prefix\n", debugstr_us(path) ); + ERR( "64-bit application %s not supported in 32-bit prefix\n", debugstr_us(&path) ); break; case STATUS_INVALID_IMAGE_FORMAT: ERR( "%s not supported on this installation (%s binary)\n", - debugstr_us(path), cpu_names[pe_info.cpu] ); + debugstr_us(&path), cpu_names[pe_info.cpu] ); break; } goto done; } - InitializeObjectAttributes( &attr, NULL, 0, NULL, thread_descr ); - if ((status = alloc_object_attributes( &attr, &objattr, &attr_len ))) goto done; + if ((status = alloc_object_attributes( thread_attr, &objattr, &attr_len ))) goto done; SERVER_START_REQ( new_thread ) { req->process = wine_server_obj_handle( process_handle ); - req->access = THREAD_ALL_ACCESS; - req->suspend = 1; + req->access = thread_access; + req->suspend = !!(thread_flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED); req->request_fd = -1; wine_server_add_data( req, objattr, attr_len ); if (!(status = wine_server_call( req ))) { thread_handle = wine_server_ptr_handle( reply->handle ); - thread_id = reply->tid; + id.UniqueThread = ULongToHandle( reply->tid ); } } SERVER_END_REQ; @@ -1736,19 +1760,49 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, } SERVER_END_REQ; - if (success) + if (!success) { - TRACE( "%s pid %04x tid %04x handles %p/%p\n", debugstr_us( path ), - process_id, thread_id, process_handle, thread_handle ); - info->Process = process_handle; - info->Thread = thread_handle; - info->ClientId.UniqueProcess = ULongToHandle( process_id ); - info->ClientId.UniqueThread = ULongToHandle( thread_id ); - virtual_fill_image_information( &pe_info, &info->ImageInformation ); - process_handle = thread_handle = 0; - status = STATUS_SUCCESS; + if (!status) status = STATUS_INTERNAL_ERROR; + goto done; } - else if (!status) status = STATUS_INTERNAL_ERROR; + + TRACE( "%s pid %04x tid %04x handles %p/%p\n", debugstr_us(&path), + HandleToULong(id.UniqueProcess), HandleToULong(id.UniqueThread), + process_handle, thread_handle ); + + /* update output attributes */ + + for (i = 0; i < attr_count; i++) + { + switch (attr->Attributes[i].Attribute) + { + case PS_ATTRIBUTE_CLIENT_ID: + { + SIZE_T size = min( attr->Attributes[i].Size, sizeof(id) ); + memcpy( attr->Attributes[i].ValuePtr, &id, size ); + if (attr->Attributes[i].ReturnLength) *attr->Attributes[i].ReturnLength = size; + break; + } + case PS_ATTRIBUTE_IMAGE_INFO: + { + SECTION_IMAGE_INFORMATION info; + SIZE_T size = min( attr->Attributes[i].Size, sizeof(info) ); + virtual_fill_image_information( &pe_info, &info ); + memcpy( attr->Attributes[i].ValuePtr, &info, size ); + if (attr->Attributes[i].ReturnLength) *attr->Attributes[i].ReturnLength = size; + break; + } + case PS_ATTRIBUTE_TEB_ADDRESS: + default: + if (!(attr->Attributes[i].Attribute & PS_ATTRIBUTE_INPUT)) + FIXME( "unhandled output attribute %lx\n", attr->Attributes[i].Attribute ); + break; + } + } + *process_handle_ptr = process_handle; + *thread_handle_ptr = thread_handle; + process_handle = thread_handle = 0; + status = STATUS_SUCCESS; done: if (file_handle) NtClose( file_handle ); @@ -1762,6 +1816,68 @@ done: return status; } + +/********************************************************************** + * RtlCreateUserProcess (NTDLL.@) + */ +NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes, + RTL_USER_PROCESS_PARAMETERS *params, + SECURITY_DESCRIPTOR *process_descr, + SECURITY_DESCRIPTOR *thread_descr, + HANDLE parent, BOOLEAN inherit, HANDLE debug, HANDLE exception, + RTL_USER_PROCESS_INFORMATION *info ) +{ + OBJECT_ATTRIBUTES process_attr, thread_attr; + PS_CREATE_INFO create_info; + ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[5] ) / sizeof(ULONG_PTR)]; + PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer; + UINT pos = 0; + + RtlNormalizeProcessParams( params ); + + attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME; + attr->Attributes[pos].Size = path->Length; + attr->Attributes[pos].ValuePtr = path->Buffer; + attr->Attributes[pos].ReturnLength = NULL; + pos++; + attr->Attributes[pos].Attribute = PS_ATTRIBUTE_CLIENT_ID; + attr->Attributes[pos].Size = sizeof(info->ClientId); + attr->Attributes[pos].ValuePtr = &info->ClientId; + attr->Attributes[pos].ReturnLength = NULL; + pos++; + attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_INFO; + attr->Attributes[pos].Size = sizeof(info->ImageInformation); + attr->Attributes[pos].ValuePtr = &info->ImageInformation; + attr->Attributes[pos].ReturnLength = NULL; + pos++; + if (parent) + { + attr->Attributes[pos].Attribute = PS_ATTRIBUTE_PARENT_PROCESS; + attr->Attributes[pos].Size = sizeof(parent); + attr->Attributes[pos].ValuePtr = parent; + attr->Attributes[pos].ReturnLength = NULL; + pos++; + } + if (debug) + { + attr->Attributes[pos].Attribute = PS_ATTRIBUTE_DEBUG_PORT; + attr->Attributes[pos].Size = sizeof(debug); + attr->Attributes[pos].ValuePtr = debug; + attr->Attributes[pos].ReturnLength = NULL; + pos++; + } + attr->TotalLength = offsetof( PS_ATTRIBUTE_LIST, Attributes[pos] ); + + InitializeObjectAttributes( &process_attr, NULL, 0, NULL, process_descr ); + InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, thread_descr ); + + return NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, + &process_attr, &thread_attr, + inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0, + THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params, + &create_info, attr ); +} + /*********************************************************************** * DbgUiRemoteBreakin (NTDLL.@) */ diff --git a/include/winternl.h b/include/winternl.h index acbce20c212..39776d36f92 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2442,6 +2442,18 @@ typedef struct _SYSTEM_MODULE_INFORMATION SYSTEM_MODULE Modules[1]; /* FIXME: should be Modules[0] */ } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 +#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020 +#define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040 +#define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080 +#define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100 +#define PROCESS_CREATE_FLAGS_SUSPENDED 0x00000200 +#define PROCESS_CREATE_FLAGS_EXTENDED_UNKNOWN 0x00000400 + #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 @@ -2453,9 +2465,9 @@ 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 +#define PS_ATTRIBUTE_THREAD 0x00010000 +#define PS_ATTRIBUTE_INPUT 0x00020000 +#define PS_ATTRIBUTE_ADDITIVE 0x00040000 typedef enum _PS_ATTRIBUTE_NUM { @@ -2479,10 +2491,41 @@ typedef enum _PS_ATTRIBUTE_NUM PsAttributeProtectionLevel, PsAttributeSecureProcess, PsAttributeJobList, + PsAttributeChildProcessPolicy, + PsAttributeAllApplicationPackagesPolicy, + PsAttributeWin32kFilter, + PsAttributeSafeOpenPromptOriginClaim, + PsAttributeBnoIsolation, + PsAttributeDesktopAppPolicy, + PsAttributeChpe, PsAttributeMax } PS_ATTRIBUTE_NUM; -#define PS_ATTRIBUTE_CLIENT_ID (PsAttributeClientId | PS_ATTRIBUTE_THREAD) +#define PS_ATTRIBUTE_PARENT_PROCESS (PsAttributeParentProcess | PS_ATTRIBUTE_INPUT | PS_ATTRIBUTE_ADDITIVE) +#define PS_ATTRIBUTE_DEBUG_PORT (PsAttributeDebugPort | PS_ATTRIBUTE_INPUT | PS_ATTRIBUTE_ADDITIVE) +#define PS_ATTRIBUTE_TOKEN (PsAttributeToken | PS_ATTRIBUTE_INPUT | PS_ATTRIBUTE_ADDITIVE) +#define PS_ATTRIBUTE_CLIENT_ID (PsAttributeClientId | PS_ATTRIBUTE_THREAD) +#define PS_ATTRIBUTE_TEB_ADDRESS (PsAttributeTebAddress | PS_ATTRIBUTE_THREAD) +#define PS_ATTRIBUTE_IMAGE_NAME (PsAttributeImageName | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_IMAGE_INFO (PsAttributeImageInfo) +#define PS_ATTRIBUTE_MEMORY_RESERVE (PsAttributeMemoryReserve | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_PRIORITY_CLASS (PsAttributePriorityClass | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_ERROR_MODE (PsAttributeErrorMode | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_STD_HANDLE_INFO (PsAttributeStdHandleInfo | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_HANDLE_LIST (PsAttributeHandleList | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_GROUP_AFFINITY (PsAttributeGroupAffinity | PS_ATTRIBUTE_THREAD | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_PREFERRED_NODE (PsAttributePreferredNode | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_IDEAL_PROCESSOR (PsAttributeIdealProcessor | PS_ATTRIBUTE_THREAD | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_MITIGATION_OPTIONS (PsAttributeMitigationOptions | PS_ATTRIBUTE_INPUT | PS_ATTRIBUTE_UNKNOWN) +#define PS_ATTRIBUTE_PROTECTION_LEVEL (PsAttributeProtectionLevel | PS_ATTRIBUTE_INPUT | PS_ATTRIBUTE_UNKNOWN) +#define PS_ATTRIBUTE_SECURE_PROCESS (PsAttributeSecureProcess | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_JOB_LIST (PsAttributeJobList | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_CHILD_PROCESS_POLICY (PsAttributeChildProcessPolicy | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY (PsAttributeAllApplicationPackagesPolicy | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_WIN32K_FILTER (PsAttributeWin32kFilter | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_SAFE_OPEN_PROMPT_ORIGIN_CLAIM (PsAttributeSafeOpenPromptOriginClaim | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_BNO_ISOLATION (PsAttributeBnoIsolation | PS_ATTRIBUTE_INPUT) +#define PS_ATTRIBUTE_DESKTOP_APP_POLICY (PsAttributeDesktopAppPolicy | PS_ATTRIBUTE_INPUT) typedef struct _PS_ATTRIBUTE { @@ -2502,6 +2545,84 @@ typedef struct _PS_ATTRIBUTE_LIST PS_ATTRIBUTE Attributes[1]; } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; +typedef enum _PS_CREATE_STATE +{ + PsCreateInitialState, + PsCreateFailOnFileOpen, + PsCreateFailOnSectionCreate, + PsCreateFailExeFormat, + PsCreateFailMachineMismatch, + PsCreateFailExeName, + PsCreateSuccess, + PsCreateMaximumStates +} PS_CREATE_STATE; + +typedef struct _PS_CREATE_INFO +{ + SIZE_T Size; + PS_CREATE_STATE State; + union + { + struct + { + union + { + ULONG InitFlags; + struct + { + UCHAR WriteOutputOnExit : 1; + UCHAR DetectManifest : 1; + UCHAR IFEOSkipDebugger : 1; + UCHAR IFEODoNotPropagateKeyState : 1; + UCHAR SpareBits1 : 4; + UCHAR SpareBits2 : 8; + USHORT ProhibitedImageCharacteristics : 16; + }; + }; + ACCESS_MASK AdditionalFileAccess; + } InitState; + struct + { + HANDLE FileHandle; + } FailSection; + struct + { + USHORT DllCharacteristics; + } ExeFormat; + struct + { + HANDLE IFEOKey; + } ExeName; + struct + { + union + { + ULONG OutputFlags; + struct + { + UCHAR ProtectedProcess : 1; + UCHAR AddressSpaceOverride : 1; + UCHAR DevOverrideEnabled : 1; + UCHAR ManifestDetected : 1; + UCHAR ProtectedProcessLight : 1; + UCHAR SpareBits1 : 3; + UCHAR SpareBits2 : 8; + USHORT SpareBits3 : 16; + }; + }; + HANDLE FileHandle; + HANDLE SectionHandle; + ULONGLONG UserProcessParametersNative; + ULONG UserProcessParametersWow64; + ULONG CurrentParameterFlags; + ULONGLONG PebAddressNative; + ULONG PebAddressWow64; + ULONGLONG ManifestAddress; + ULONG ManifestSize; + } SuccessState; + }; +} PS_CREATE_INFO, *PPS_CREATE_INFO; + /*********************************************************************** * Function declarations */ @@ -2585,6 +2706,7 @@ NTSYSAPI NTSTATUS WINAPI NtCreateThread(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES, NTSYSAPI NTSTATUS WINAPI NtCreateThreadEx(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES*,HANDLE,PRTL_THREAD_START_ROUTINE,void*,ULONG,SIZE_T,SIZE_T,SIZE_T,PS_ATTRIBUTE_LIST*); NTSYSAPI NTSTATUS WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE); NTSYSAPI NTSTATUS WINAPI NtCreateToken(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,TOKEN_TYPE,PLUID,PLARGE_INTEGER,PTOKEN_USER,PTOKEN_GROUPS,PTOKEN_PRIVILEGES,PTOKEN_OWNER,PTOKEN_PRIMARY_GROUP,PTOKEN_DEFAULT_DACL,PTOKEN_SOURCE); +NTSYSAPI NTSTATUS WINAPI NtCreateUserProcess(HANDLE*,HANDLE*,ACCESS_MASK,ACCESS_MASK,OBJECT_ATTRIBUTES*,OBJECT_ATTRIBUTES*,ULONG,ULONG,RTL_USER_PROCESS_PARAMETERS*,PS_CREATE_INFO*,PS_ATTRIBUTE_LIST*); NTSYSAPI NTSTATUS WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*); NTSYSAPI NTSTATUS WINAPI NtDeleteAtom(RTL_ATOM); NTSYSAPI NTSTATUS WINAPI NtDeleteFile(POBJECT_ATTRIBUTES); -- 2.11.4.GIT