ReactOS 0.4.16-dev-2274-gc61d98f
procansi.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/procansi.c
5 * PURPOSE: Process functions
6 * PROGRAMMERS: Ariadne (ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11/* INCLUDES ****************************************************************/
12
13#include <k32.h>
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS *******************************************************************/
18
21
22/* FUNCTIONS ******************************************************************/
23
24/*
25 * @implemented
26 */
27VOID
30{
31 /* Write the global function pointer */
32 UserWaitForInputIdleRoutine = lpfnRegisterWaitForInputIdle;
33}
34
35#if (NTDDI_VERSION < NTDDI_WIN8)
36/*
37 * @implemented
38 */
39BOOL
42 IN LPCWSTR lpApplicationName,
43 IN LPWSTR lpCommandLine,
44 IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
45 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
46 IN BOOL bInheritHandles,
47 IN DWORD dwCreationFlags,
48 IN LPVOID lpEnvironment,
49 IN LPCWSTR lpCurrentDirectory,
50 IN LPSTARTUPINFOW lpStartupInfo,
51 IN LPPROCESS_INFORMATION lpProcessInformation,
52 OUT PHANDLE hNewToken);
53
54/*
55 * @implemented
56 */
57BOOL
60 LPCSTR lpApplicationName,
61 LPSTR lpCommandLine,
62 LPSECURITY_ATTRIBUTES lpProcessAttributes,
63 LPSECURITY_ATTRIBUTES lpThreadAttributes,
64 BOOL bInheritHandles,
65 DWORD dwCreationFlags,
66 LPVOID lpEnvironment,
67 LPCSTR lpCurrentDirectory,
68 LPSTARTUPINFOA lpStartupInfo,
69 LPPROCESS_INFORMATION lpProcessInformation,
70 PHANDLE hNewToken)
71{
72 UNICODE_STRING CommandLine;
75 BOOL bRetVal;
76 STARTUPINFOW StartupInfo;
77
78 DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
79 "lpStartupInfo %p, lpProcessInformation %p\n",
80 dwCreationFlags, lpEnvironment, lpCurrentDirectory,
81 lpStartupInfo, lpProcessInformation);
82
83 /* Copy Startup Info */
84 RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
85
86 /* Initialize all strings to nothing */
87 CommandLine.Buffer = NULL;
88 ApplicationName.Buffer = NULL;
89 CurrentDirectory.Buffer = NULL;
90 StartupInfo.lpDesktop = NULL;
91 StartupInfo.lpReserved = NULL;
92 StartupInfo.lpTitle = NULL;
93
94 /* Convert the Command line */
95 if (lpCommandLine)
96 {
98 lpCommandLine);
99 }
100
101 /* Convert the Name and Directory */
102 if (lpApplicationName)
103 {
105 lpApplicationName);
106 }
107 if (lpCurrentDirectory)
108 {
110 lpCurrentDirectory);
111 }
112
113 /* Now convert Startup Strings */
114 if (lpStartupInfo->lpReserved)
115 {
117 &StartupInfo.lpReserved);
118 }
119 if (lpStartupInfo->lpDesktop)
120 {
122 &StartupInfo.lpDesktop);
123 }
124 if (lpStartupInfo->lpTitle)
125 {
127 &StartupInfo.lpTitle);
128 }
129
130 /* Call the Unicode function */
131 bRetVal = CreateProcessInternalW(hToken,
132 ApplicationName.Buffer,
133 CommandLine.Buffer,
134 lpProcessAttributes,
135 lpThreadAttributes,
136 bInheritHandles,
137 dwCreationFlags,
138 lpEnvironment,
139 CurrentDirectory.Buffer,
140 &StartupInfo,
141 lpProcessInformation,
142 hNewToken);
143
144 /* Clean up */
146 RtlFreeUnicodeString(&CommandLine);
148 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
149 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
150 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
151
152 /* Return what Unicode did */
153 return bRetVal;
154}
155
156/*
157 * FUNCTION: The CreateProcess function creates a new process and its
158 * primary thread. The new process executes the specified executable file
159 * ARGUMENTS:
160 *
161 * lpApplicationName = Pointer to name of executable module
162 * lpCommandLine = Pointer to command line string
163 * lpProcessAttributes = Process security attributes
164 * lpThreadAttributes = Thread security attributes
165 * bInheritHandles = Handle inheritance flag
166 * dwCreationFlags = Creation flags
167 * lpEnvironment = Pointer to new environment block
168 * lpCurrentDirectory = Pointer to current directory name
169 * lpStartupInfo = Pointer to startup info
170 * lpProcessInformation = Pointer to process information
171 *
172 * @implemented
173 */
174BOOL
175WINAPI
177CreateProcessA(LPCSTR lpApplicationName,
178 LPSTR lpCommandLine,
179 LPSECURITY_ATTRIBUTES lpProcessAttributes,
180 LPSECURITY_ATTRIBUTES lpThreadAttributes,
181 BOOL bInheritHandles,
182 DWORD dwCreationFlags,
183 LPVOID lpEnvironment,
184 LPCSTR lpCurrentDirectory,
185 LPSTARTUPINFOA lpStartupInfo,
186 LPPROCESS_INFORMATION lpProcessInformation)
187{
188 /* Call the internal (but exported) version */
190 lpApplicationName,
191 lpCommandLine,
192 lpProcessAttributes,
193 lpThreadAttributes,
194 bInheritHandles,
195 dwCreationFlags,
196 lpEnvironment,
197 lpCurrentDirectory,
198 lpStartupInfo,
199 lpProcessInformation,
200 NULL);
201}
202#endif // NTDDI_VERSION < NTDDI_WIN8
203
204/*
205 * @implemented
206 */
207VOID
208WINAPI
210{
212 ANSI_STRING TitleString, ShellString, DesktopString;
213 LPSTARTUPINFOA StartupInfo;
215
216 /* Get the cached information as well as the PEB parameters */
217 StartupInfo = BaseAnsiStartupInfo;
218 Params = NtCurrentPeb()->ProcessParameters;
219
220 /* Check if this is the first time we have to get the cached version */
221 while (!StartupInfo)
222 {
223 /* Create new ANSI startup info */
224 StartupInfo = RtlAllocateHeap(RtlGetProcessHeap(),
225 0,
226 sizeof(*StartupInfo));
227 if (StartupInfo)
228 {
229 /* Zero out string pointers in case we fail to create them */
230 StartupInfo->lpReserved = NULL;
231 StartupInfo->lpDesktop = NULL;
232 StartupInfo->lpTitle = NULL;
233
234 /* Set the size */
235 StartupInfo->cb = sizeof(*StartupInfo);
236
237 /* Copy what's already stored in the PEB */
238 StartupInfo->dwX = Params->StartingX;
239 StartupInfo->dwY = Params->StartingY;
240 StartupInfo->dwXSize = Params->CountX;
241 StartupInfo->dwYSize = Params->CountY;
242 StartupInfo->dwXCountChars = Params->CountCharsX;
243 StartupInfo->dwYCountChars = Params->CountCharsY;
244 StartupInfo->dwFillAttribute = Params->FillAttribute;
245 StartupInfo->dwFlags = Params->WindowFlags;
246 StartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
247 StartupInfo->cbReserved2 = Params->RuntimeData.Length;
248 StartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
249 StartupInfo->hStdInput = Params->StandardInput;
250 StartupInfo->hStdOutput = Params->StandardOutput;
251 StartupInfo->hStdError = Params->StandardError;
252
253 /* Copy shell info string */
255 &Params->ShellInfo,
256 TRUE);
257 if (NT_SUCCESS(Status))
258 {
259 /* Save it */
260 StartupInfo->lpReserved = ShellString.Buffer;
261
262 /* Copy desktop info string */
263 Status = RtlUnicodeStringToAnsiString(&DesktopString,
264 &Params->DesktopInfo,
265 TRUE);
266 if (NT_SUCCESS(Status))
267 {
268 /* Save it */
269 StartupInfo->lpDesktop = DesktopString.Buffer;
270
271 /* Copy window title string */
273 &Params->WindowTitle,
274 TRUE);
275 if (NT_SUCCESS(Status))
276 {
277 /* Save it */
278 StartupInfo->lpTitle = TitleString.Buffer;
279
280 /* We finished with the ANSI version, try to cache it */
282 StartupInfo,
283 NULL))
284 {
285 /* We were the first thread through, use the data */
286 break;
287 }
288
289 /* Someone beat us to it, we will use their data instead */
291
292 /* We're going to free our own stuff, but not raise */
293 RtlFreeAnsiString(&TitleString);
294 }
295 RtlFreeAnsiString(&DesktopString);
296 }
297 RtlFreeAnsiString(&ShellString);
298 }
299 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo);
300
301 /* Get the cached information again: either still NULL or set by another thread */
302 StartupInfo = BaseAnsiStartupInfo;
303 }
304 else
305 {
306 /* No memory, fail */
308 }
309
310 /* Raise an error unless we got here due to the race condition */
311 if (!StartupInfo) RtlRaiseStatus(Status);
312 }
313
314 /* Now copy from the cached ANSI version */
315 lpStartupInfo->cb = StartupInfo->cb;
316 lpStartupInfo->lpReserved = StartupInfo->lpReserved;
317 lpStartupInfo->lpDesktop = StartupInfo->lpDesktop;
318 lpStartupInfo->lpTitle = StartupInfo->lpTitle;
319 lpStartupInfo->dwX = StartupInfo->dwX;
320 lpStartupInfo->dwY = StartupInfo->dwY;
321 lpStartupInfo->dwXSize = StartupInfo->dwXSize;
322 lpStartupInfo->dwYSize = StartupInfo->dwYSize;
323 lpStartupInfo->dwXCountChars = StartupInfo->dwXCountChars;
324 lpStartupInfo->dwYCountChars = StartupInfo->dwYCountChars;
325 lpStartupInfo->dwFillAttribute = StartupInfo->dwFillAttribute;
326 lpStartupInfo->dwFlags = StartupInfo->dwFlags;
327 lpStartupInfo->wShowWindow = StartupInfo->wShowWindow;
328 lpStartupInfo->cbReserved2 = StartupInfo->cbReserved2;
329 lpStartupInfo->lpReserved2 = StartupInfo->lpReserved2;
330
331 /* Check if the shell is hijacking the handles for other features */
332 if (lpStartupInfo->dwFlags &
333 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
334 {
335 /* It isn't, so we can return the raw values */
336 lpStartupInfo->hStdInput = StartupInfo->hStdInput;
337 lpStartupInfo->hStdOutput = StartupInfo->hStdOutput;
338 lpStartupInfo->hStdError = StartupInfo->hStdError;
339 }
340 else
341 {
342 /* It is, so make sure nobody uses these as console handles */
343 lpStartupInfo->hStdInput = INVALID_HANDLE_VALUE;
344 lpStartupInfo->hStdOutput = INVALID_HANDLE_VALUE;
345 lpStartupInfo->hStdError = INVALID_HANDLE_VALUE;
346 }
347}
348
349/*
350 * @implemented
351 */
352UINT
353WINAPI
355WinExec(LPCSTR lpCmdLine,
356 UINT uCmdShow)
357{
358 STARTUPINFOA StartupInfo;
359 PROCESS_INFORMATION ProcessInformation;
360 DWORD dosErr;
361
362 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
363 StartupInfo.cb = sizeof(STARTUPINFOA);
364 StartupInfo.wShowWindow = (WORD)uCmdShow;
365 StartupInfo.dwFlags = 0;
366
367 if (!CreateProcessA(NULL,
368 (PVOID)lpCmdLine,
369 NULL,
370 NULL,
371 FALSE,
372 0,
373 NULL,
374 NULL,
375 &StartupInfo,
376 &ProcessInformation))
377 {
378 dosErr = GetLastError();
379 return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
380 }
381
383 {
384 UserWaitForInputIdleRoutine(ProcessInformation.hProcess,
385 10000);
386 }
387
388 NtClose(ProcessInformation.hProcess);
389 NtClose(ProcessInformation.hThread);
390
391 return 33; /* Something bigger than 31 means success. */
392}
393
394/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
LONG NTSTATUS
Definition: precomp.h:26
HANDLE hUserToken
Definition: install.c:39
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
SIZE_T LPSTARTUPINFOW
Definition: cordebug.idl:85
SIZE_T LPPROCESS_INFORMATION
Definition: cordebug.idl:86
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI CreateProcessInternalW(IN HANDLE hUserToken, IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, IN LPPROCESS_INFORMATION lpProcessInformation, OUT PHANDLE hNewToken)
Definition: proc.c:2084
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:226
VOID WINAPI BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString, OUT LPWSTR *UnicodeString)
Definition: utils.c:264
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA(HANDLE token, const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info, HANDLE *new_token)
Definition: process.c:466
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
DWORD(* WaitForInputIdleType)(HANDLE hProcess, DWORD dwMilliseconds)
Definition: kernel32.h:112
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:47
unsigned int UINT
Definition: ndis.h:50
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STARTF_USEHOTKEY
Definition: pch.h:41
VOID WINAPI RegisterWaitForInputIdle(IN WaitForInputIdleType lpfnRegisterWaitForInputIdle)
Definition: procansi.c:29
WaitForInputIdleType UserWaitForInputIdleRoutine
Definition: procansi.c:20
VOID WINAPI GetStartupInfoA(IN LPSTARTUPINFOA lpStartupInfo)
Definition: procansi.c:209
LPSTARTUPINFOA BaseAnsiStartupInfo
Definition: procansi.c:19
UINT WINAPI DECLSPEC_HOTPATCH WinExec(LPCSTR lpCmdLine, UINT uCmdShow)
Definition: procansi.c:355
struct _STARTUPINFOA STARTUPINFOA
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
unsigned char * LPBYTE
Definition: typedefs.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define OUT
Definition: typedefs.h:40
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESTDHANDLES
Definition: winbase.h:476
#define WINAPI
Definition: msvc.h:6
#define ERROR_BAD_FORMAT
Definition: winerror.h:236
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182