winegstreamer: Move the "flip" field to struct wg_parser_stream.
[wine/zf.git] / dlls / ntdll / process.c
bloba86eb80e0cc42b986876b28a89c834bcb5fec106
1 /*
2 * NT process handling
4 * Copyright 1996-1998 Marcus Meissner
5 * Copyright 2018 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <sys/types.h>
31 #include "ntstatus.h"
32 #define WIN32_NO_STATUS
33 #include "wine/debug.h"
34 #include "windef.h"
35 #include "winternl.h"
36 #include "ntdll_misc.h"
37 #include "wine/exception.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(process);
42 /******************************************************************************
43 * RtlGetCurrentPeb [NTDLL.@]
46 PEB * WINAPI RtlGetCurrentPeb(void)
48 return NtCurrentTeb()->Peb;
52 /**********************************************************************
53 * RtlCreateUserProcess (NTDLL.@)
55 NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
56 RTL_USER_PROCESS_PARAMETERS *params,
57 SECURITY_DESCRIPTOR *process_descr,
58 SECURITY_DESCRIPTOR *thread_descr,
59 HANDLE parent, BOOLEAN inherit, HANDLE debug, HANDLE token,
60 RTL_USER_PROCESS_INFORMATION *info )
62 OBJECT_ATTRIBUTES process_attr, thread_attr;
63 PS_CREATE_INFO create_info;
64 ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[6] ) / sizeof(ULONG_PTR)];
65 PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
66 UINT pos = 0;
68 RtlNormalizeProcessParams( params );
70 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
71 attr->Attributes[pos].Size = path->Length;
72 attr->Attributes[pos].ValuePtr = path->Buffer;
73 attr->Attributes[pos].ReturnLength = NULL;
74 pos++;
75 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_CLIENT_ID;
76 attr->Attributes[pos].Size = sizeof(info->ClientId);
77 attr->Attributes[pos].ValuePtr = &info->ClientId;
78 attr->Attributes[pos].ReturnLength = NULL;
79 pos++;
80 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_INFO;
81 attr->Attributes[pos].Size = sizeof(info->ImageInformation);
82 attr->Attributes[pos].ValuePtr = &info->ImageInformation;
83 attr->Attributes[pos].ReturnLength = NULL;
84 pos++;
85 if (parent)
87 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_PARENT_PROCESS;
88 attr->Attributes[pos].Size = sizeof(parent);
89 attr->Attributes[pos].ValuePtr = parent;
90 attr->Attributes[pos].ReturnLength = NULL;
91 pos++;
93 if (debug)
95 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_DEBUG_PORT;
96 attr->Attributes[pos].Size = sizeof(debug);
97 attr->Attributes[pos].ValuePtr = debug;
98 attr->Attributes[pos].ReturnLength = NULL;
99 pos++;
101 if (token)
103 attr->Attributes[pos].Attribute = PS_ATTRIBUTE_TOKEN;
104 attr->Attributes[pos].Size = sizeof(token);
105 attr->Attributes[pos].ValuePtr = token;
106 attr->Attributes[pos].ReturnLength = NULL;
107 pos++;
109 attr->TotalLength = offsetof( PS_ATTRIBUTE_LIST, Attributes[pos] );
111 InitializeObjectAttributes( &process_attr, NULL, 0, NULL, process_descr );
112 InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, thread_descr );
114 return NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
115 &process_attr, &thread_attr,
116 inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
117 THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
118 &create_info, attr );
121 /***********************************************************************
122 * DbgUiGetThreadDebugObject (NTDLL.@)
124 HANDLE WINAPI DbgUiGetThreadDebugObject(void)
126 return NtCurrentTeb()->DbgSsReserved[1];
129 /***********************************************************************
130 * DbgUiSetThreadDebugObject (NTDLL.@)
132 void WINAPI DbgUiSetThreadDebugObject( HANDLE handle )
134 NtCurrentTeb()->DbgSsReserved[1] = handle;
137 /***********************************************************************
138 * DbgUiConnectToDbg (NTDLL.@)
140 NTSTATUS WINAPI DbgUiConnectToDbg(void)
142 HANDLE handle;
143 NTSTATUS status;
144 OBJECT_ATTRIBUTES attr = { sizeof(attr) };
146 if (DbgUiGetThreadDebugObject()) return STATUS_SUCCESS; /* already connected */
148 status = NtCreateDebugObject( &handle, DEBUG_ALL_ACCESS, &attr, DEBUG_KILL_ON_CLOSE );
149 if (!status) DbgUiSetThreadDebugObject( handle );
150 return status;
153 /***********************************************************************
154 * DbgUiDebugActiveProcess (NTDLL.@)
156 NTSTATUS WINAPI DbgUiDebugActiveProcess( HANDLE process )
158 NTSTATUS status;
160 if ((status = NtDebugActiveProcess( process, DbgUiGetThreadDebugObject() ))) return status;
161 if ((status = DbgUiIssueRemoteBreakin( process ))) DbgUiStopDebugging( process );
162 return status;
165 /***********************************************************************
166 * DbgUiStopDebugging (NTDLL.@)
168 NTSTATUS WINAPI DbgUiStopDebugging( HANDLE process )
170 return NtRemoveProcessDebug( process, DbgUiGetThreadDebugObject() );
173 /***********************************************************************
174 * DbgUiContinue (NTDLL.@)
176 NTSTATUS WINAPI DbgUiContinue( CLIENT_ID *client, NTSTATUS status )
178 return NtDebugContinue( DbgUiGetThreadDebugObject(), client, status );
181 /***********************************************************************
182 * DbgUiWaitStateChange (NTDLL.@)
184 NTSTATUS WINAPI DbgUiWaitStateChange( DBGUI_WAIT_STATE_CHANGE *state, LARGE_INTEGER *timeout )
186 return NtWaitForDebugEvent( DbgUiGetThreadDebugObject(), TRUE, timeout, state );
189 /* helper for DbgUiConvertStateChangeStructure */
190 static inline void *get_thread_teb( HANDLE thread )
192 THREAD_BASIC_INFORMATION info;
194 if (NtQueryInformationThread( thread, ThreadBasicInformation, &info, sizeof(info), NULL )) return NULL;
195 return info.TebBaseAddress;
198 /***********************************************************************
199 * DbgUiConvertStateChangeStructure (NTDLL.@)
201 NTSTATUS WINAPI DbgUiConvertStateChangeStructure( DBGUI_WAIT_STATE_CHANGE *state, DEBUG_EVENT *event )
203 event->dwProcessId = HandleToULong( state->AppClientId.UniqueProcess );
204 event->dwThreadId = HandleToULong( state->AppClientId.UniqueThread );
205 switch (state->NewState)
207 case DbgCreateThreadStateChange:
209 DBGUI_CREATE_THREAD *info = &state->StateInfo.CreateThread;
210 event->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT;
211 event->u.CreateThread.hThread = info->HandleToThread;
212 event->u.CreateThread.lpThreadLocalBase = get_thread_teb( info->HandleToThread );
213 event->u.CreateThread.lpStartAddress = info->NewThread.StartAddress;
214 break;
216 case DbgCreateProcessStateChange:
218 DBGUI_CREATE_PROCESS *info = &state->StateInfo.CreateProcessInfo;
219 event->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT;
220 event->u.CreateProcessInfo.hFile = info->NewProcess.FileHandle;
221 event->u.CreateProcessInfo.hProcess = info->HandleToProcess;
222 event->u.CreateProcessInfo.hThread = info->HandleToThread;
223 event->u.CreateProcessInfo.lpBaseOfImage = info->NewProcess.BaseOfImage;
224 event->u.CreateProcessInfo.dwDebugInfoFileOffset = info->NewProcess.DebugInfoFileOffset;
225 event->u.CreateProcessInfo.nDebugInfoSize = info->NewProcess.DebugInfoSize;
226 event->u.CreateProcessInfo.lpThreadLocalBase = get_thread_teb( info->HandleToThread );
227 event->u.CreateProcessInfo.lpStartAddress = info->NewProcess.InitialThread.StartAddress;
228 event->u.CreateProcessInfo.lpImageName = NULL;
229 event->u.CreateProcessInfo.fUnicode = TRUE;
230 break;
232 case DbgExitThreadStateChange:
234 DBGKM_EXIT_THREAD *info = &state->StateInfo.ExitThread;
235 event->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT;
236 event->u.ExitThread.dwExitCode = info->ExitStatus;
237 break;
239 case DbgExitProcessStateChange:
241 DBGKM_EXIT_PROCESS *info = &state->StateInfo.ExitProcess;
242 event->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT;
243 event->u.ExitProcess.dwExitCode = info->ExitStatus;
244 break;
246 case DbgExceptionStateChange:
247 case DbgBreakpointStateChange:
248 case DbgSingleStepStateChange:
250 DBGKM_EXCEPTION *info = &state->StateInfo.Exception;
251 DWORD code = info->ExceptionRecord.ExceptionCode;
252 if (code == DBG_PRINTEXCEPTION_C && info->ExceptionRecord.NumberParameters >= 2)
254 event->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;
255 event->u.DebugString.lpDebugStringData = (void *)info->ExceptionRecord.ExceptionInformation[1];
256 event->u.DebugString.fUnicode = FALSE;
257 event->u.DebugString.nDebugStringLength = info->ExceptionRecord.ExceptionInformation[0];
259 else if (code == DBG_RIPEXCEPTION && info->ExceptionRecord.NumberParameters >= 2)
261 event->dwDebugEventCode = RIP_EVENT;
262 event->u.RipInfo.dwError = info->ExceptionRecord.ExceptionInformation[0];
263 event->u.RipInfo.dwType = info->ExceptionRecord.ExceptionInformation[1];
265 else
267 event->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
268 event->u.Exception.ExceptionRecord = info->ExceptionRecord;
269 event->u.Exception.dwFirstChance = info->FirstChance;
271 break;
273 case DbgLoadDllStateChange:
275 DBGKM_LOAD_DLL *info = &state->StateInfo.LoadDll;
276 event->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT;
277 event->u.LoadDll.hFile = info->FileHandle;
278 event->u.LoadDll.lpBaseOfDll = info->BaseOfDll;
279 event->u.LoadDll.dwDebugInfoFileOffset = info->DebugInfoFileOffset;
280 event->u.LoadDll.nDebugInfoSize = info->DebugInfoSize;
281 event->u.LoadDll.lpImageName = info->NamePointer;
282 event->u.LoadDll.fUnicode = TRUE;
283 break;
285 case DbgUnloadDllStateChange:
287 DBGKM_UNLOAD_DLL *info = &state->StateInfo.UnloadDll;
288 event->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT;
289 event->u.UnloadDll.lpBaseOfDll = info->BaseAddress;
290 break;
292 default:
293 return STATUS_UNSUCCESSFUL;
295 return STATUS_SUCCESS;
298 /***********************************************************************
299 * DbgUiRemoteBreakin (NTDLL.@)
301 void WINAPI DbgUiRemoteBreakin( void *arg )
303 TRACE( "\n" );
304 if (NtCurrentTeb()->Peb->BeingDebugged)
306 __TRY
308 DbgBreakPoint();
310 __EXCEPT_ALL
312 /* do nothing */
314 __ENDTRY
316 RtlExitUserThread( STATUS_SUCCESS );
319 /***********************************************************************
320 * DbgUiIssueRemoteBreakin (NTDLL.@)
322 NTSTATUS WINAPI DbgUiIssueRemoteBreakin( HANDLE process )
324 return unix_funcs->DbgUiIssueRemoteBreakin( process );