Rolled in various changes from others
[reactos.git] / reactos / lib / kernel32 / process / proc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/proc/proc.c
5 * PURPOSE: Process functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10 #define UNICODE
11 #include <windows.h>
12 #include <kernel32/proc.h>
13 #include <kernel32/thread.h>
14 #include <wstring.h>
15 #include <string.h>
16 #include <ddk/rtl.h>
17 #include <ddk/li.h>
18
19 extern NT_PEB *CurrentPeb;
20 extern NT_PEB Peb;
21
22 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
23
24 VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
25
26 WINBOOL
27 STDCALL
28 GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
29
30
31 NT_PEB *GetCurrentPeb(VOID)
32 {
33 if ( CurrentPeb != NULL )
34 return CurrentPeb;
35 else // hack to be able to return a process environment any time.
36 return &Peb;
37 }
38
39 HANDLE STDCALL GetCurrentProcess(VOID)
40 {
41 return (HANDLE)NtCurrentProcess();
42 }
43
44 HANDLE STDCALL GetCurrentThread(VOID)
45 {
46 return (HANDLE)NtCurrentThread();
47 }
48
49 DWORD
50 STDCALL
51 GetCurrentProcessId(VOID)
52 {
53
54 return (DWORD)(GetTeb()->Cid).UniqueProcess;
55
56
57 }
58
59 unsigned char CommandLineA[MAX_PATH];
60
61 LPSTR
62 STDCALL
63 GetCommandLineA(
64 VOID
65 )
66 {
67 WCHAR *CommandLineW;
68 ULONG i = 0;
69
70 CommandLineW = GetCommandLineW();
71 while ((CommandLineW[i])!=0 && i < MAX_PATH)
72 {
73 CommandLineA[i] = (unsigned char)CommandLineW[i];
74 i++;
75 }
76 CommandLineA[i] = 0;
77 return CommandLineA;
78 }
79 LPWSTR
80 STDCALL
81 GetCommandLineW(
82 VOID
83 )
84 {
85 return GetCurrentPeb()->StartupInfo->CommandLine;
86 }
87
88
89 WINBOOL
90 STDCALL
91 GetExitCodeProcess(
92 HANDLE hProcess,
93 LPDWORD lpExitCode
94 )
95 {
96 NTSTATUS errCode;
97 PROCESS_BASIC_INFORMATION ProcessBasic;
98 ULONG BytesWritten;
99
100 errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
101 if ( !NT_SUCCESS(errCode) ) {
102 SetLastError(RtlNtStatusToDosError(errCode));
103 return FALSE;
104 }
105 memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
106 return TRUE;
107
108 }
109
110 WINBOOL
111 STDCALL
112 GetProcessId(
113 HANDLE hProcess,
114 LPDWORD lpProcessId
115 )
116 {
117 NTSTATUS errCode;
118 PROCESS_BASIC_INFORMATION ProcessBasic;
119 ULONG BytesWritten;
120
121 errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
122 if ( !NT_SUCCESS(errCode) ) {
123 SetLastError(RtlNtStatusToDosError(errCode));
124 return FALSE;
125 }
126 memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
127 return TRUE;
128
129 }
130
131 WINBOOL
132 STDCALL
133 CreateProcessA(
134 LPCSTR lpApplicationName,
135 LPSTR lpCommandLine,
136 LPSECURITY_ATTRIBUTES lpProcessAttributes,
137 LPSECURITY_ATTRIBUTES lpThreadAttributes,
138 WINBOOL bInheritHandles,
139 DWORD dwCreationFlags,
140 LPVOID lpEnvironment,
141 LPCSTR lpCurrentDirectory,
142 LPSTARTUPINFO lpStartupInfo,
143 LPPROCESS_INFORMATION lpProcessInformation
144 )
145 {
146 WCHAR ApplicationNameW[MAX_PATH];
147 WCHAR CommandLineW[MAX_PATH];
148 WCHAR CurrentDirectoryW[MAX_PATH];
149
150
151 ULONG i;
152
153 i = 0;
154 while ((*lpApplicationName)!=0 && i < MAX_PATH)
155 {
156 ApplicationNameW[i] = *lpApplicationName;
157 lpApplicationName++;
158 i++;
159 }
160 ApplicationNameW[i] = 0;
161
162
163 i = 0;
164 while ((*lpCommandLine)!=0 && i < MAX_PATH)
165 {
166 CommandLineW[i] = *lpCommandLine;
167 lpCommandLine++;
168 i++;
169 }
170 CommandLineW[i] = 0;
171
172 i = 0;
173 while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
174 {
175 CurrentDirectoryW[i] = *lpCurrentDirectory;
176 lpCurrentDirectory++;
177 i++;
178 }
179 CurrentDirectoryW[i] = 0;
180
181 return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
182 bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
183 lpProcessInformation);
184
185
186 }
187
188
189 WINBOOL
190 STDCALL
191 CreateProcessW(
192 LPCWSTR lpApplicationName,
193 LPWSTR lpCommandLine,
194 LPSECURITY_ATTRIBUTES lpProcessAttributes,
195 LPSECURITY_ATTRIBUTES lpThreadAttributes,
196 WINBOOL bInheritHandles,
197 DWORD dwCreationFlags,
198 LPVOID lpEnvironment,
199 LPCWSTR lpCurrentDirectory,
200 LPSTARTUPINFO lpStartupInfo,
201 LPPROCESS_INFORMATION lpProcessInformation
202 )
203 {
204 HANDLE hFile, hSection, hProcess, hThread;
205 KPRIORITY PriorityClass;
206 OBJECT_ATTRIBUTES ObjectAttributes;
207 IO_STATUS_BLOCK IoStatusBlock;
208 BOOLEAN CreateSuspended;
209
210 NTSTATUS errCode;
211
212 UNICODE_STRING ApplicationNameString;
213
214
215
216 LPTHREAD_START_ROUTINE lpStartAddress = NULL;
217 LPVOID lpParameter = NULL;
218
219 hFile = NULL;
220
221 ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
222
223 ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
224 ApplicationNameString.MaximumLength = ApplicationNameString.Length;
225
226
227 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
228 ObjectAttributes.RootDirectory = NULL;
229
230
231
232 if ( lpProcessAttributes != NULL ) {
233 if ( lpProcessAttributes->bInheritHandle )
234 ObjectAttributes.Attributes = OBJ_INHERIT;
235 else
236 ObjectAttributes.Attributes = 0;
237 ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
238 }
239 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
240
241 errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
242 &IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
243
244 if ( !NT_SUCCESS(errCode) ) {
245 SetLastError(RtlNtStatusToDosError(errCode));
246 return FALSE;
247 }
248
249 errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
250 NtClose(hFile);
251
252 if ( !NT_SUCCESS(errCode) ) {
253 SetLastError(RtlNtStatusToDosError(errCode));
254 return FALSE;
255 }
256
257
258 if ( lpProcessAttributes != NULL ) {
259 if ( lpProcessAttributes->bInheritHandle )
260 ObjectAttributes.Attributes = OBJ_INHERIT;
261 else
262 ObjectAttributes.Attributes = 0;
263 ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
264 }
265
266 errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
267 NtClose(hSection);
268
269 if ( !NT_SUCCESS(errCode) ) {
270 SetLastError(RtlNtStatusToDosError(errCode));
271 return FALSE;
272 }
273
274 PriorityClass = NORMAL_PRIORITY_CLASS;
275 NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
276
277 if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED)
278 CreateSuspended = TRUE;
279 else
280 CreateSuspended = FALSE;
281
282 hThread = CreateRemoteThread(
283 hProcess,
284 lpThreadAttributes,
285 4096, // 1 page ??
286 lpStartAddress,
287 lpParameter,
288 CREATE_SUSPENDED,
289 &lpProcessInformation->dwThreadId
290 );
291
292
293 if ( hThread == NULL )
294 return FALSE;
295
296
297
298 lpProcessInformation->hProcess = hProcess;
299 lpProcessInformation->hThread = hThread;
300
301
302
303
304 GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
305
306
307
308 return TRUE;
309
310
311 }
312
313
314
315 HANDLE
316 STDCALL
317 OpenProcess(
318 DWORD dwDesiredAccess,
319 WINBOOL bInheritHandle,
320 DWORD dwProcessId
321 )
322 {
323
324
325 NTSTATUS errCode;
326 HANDLE ProcessHandle;
327 OBJECT_ATTRIBUTES ObjectAttributes;
328 CLIENT_ID ClientId ;
329
330 ClientId.UniqueProcess = (HANDLE)dwProcessId;
331 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
332 ObjectAttributes.RootDirectory = (HANDLE)NULL;
333 ObjectAttributes.SecurityDescriptor = NULL;
334 ObjectAttributes.SecurityQualityOfService = NULL;
335
336 if ( bInheritHandle == TRUE )
337 ObjectAttributes.Attributes = OBJ_INHERIT;
338 else
339 ObjectAttributes.Attributes = 0;
340
341 errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
342 if ( !NT_SUCCESS(errCode) ) {
343 SetLastError(RtlNtStatusToDosError(errCode));
344 return NULL;
345 }
346 return ProcessHandle;
347 }
348
349
350
351
352
353
354
355
356
357
358
359
360
361 UINT WinExec ( LPCSTR lpCmdLine, UINT uCmdShow )
362 {
363 STARTUPINFO StartupInfo;
364 PROCESS_INFORMATION ProcessInformation;
365
366 HINSTANCE hInst;
367 DWORD dosErr;
368
369
370
371 StartupInfo.cb = sizeof(STARTUPINFO);
372 StartupInfo.wShowWindow = uCmdShow ;
373 StartupInfo.dwFlags = 0;
374
375 hInst = (HINSTANCE)CreateProcessA(NULL,(PVOID)lpCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo, &ProcessInformation);
376 if ( hInst == NULL ) {
377 dosErr = GetLastError();
378 return dosErr;
379 }
380 if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
381 lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
382 NtClose(ProcessInformation.hProcess);
383 NtClose(ProcessInformation.hThread);
384 return 0;
385
386 }
387
388
389
390 VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
391 {
392 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
393 return;
394 }
395
396 DWORD
397 STDCALL
398 WaitForInputIdle(
399 HANDLE hProcess,
400 DWORD dwMilliseconds
401 )
402 {
403 return 0;
404 }
405
406 VOID
407 STDCALL
408 Sleep(
409 DWORD dwMilliseconds
410 )
411 {
412 SleepEx(dwMilliseconds,FALSE);
413 return;
414 }
415
416 DWORD
417 STDCALL
418 SleepEx(
419 DWORD dwMilliseconds,
420 BOOL bAlertable
421 )
422 {
423 TIME Interval;
424 NTSTATUS errCode;
425 SET_LARGE_INTEGER_LOW_PART(Interval,dwMilliseconds*1000);
426
427 errCode = NtDelayExecution(bAlertable,&Interval);
428 if ( !NT_SUCCESS(errCode) ) {
429 SetLastError(RtlNtStatusToDosError(errCode));
430 return -1;
431 }
432 return 0;
433 }
434
435
436
437
438
439 VOID
440 STDCALL
441 GetStartupInfoW(
442 LPSTARTUPINFO lpStartupInfo
443 )
444 {
445 NT_PEB *pPeb = GetCurrentPeb();
446
447 if (lpStartupInfo == NULL ) {
448 SetLastError(ERROR_INVALID_PARAMETER);
449 return;
450 }
451
452 lpStartupInfo->cb = sizeof(STARTUPINFO);
453 lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
454 lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
455 lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
456 lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
457 lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
458 lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
459 lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
460 lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
461 lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
462 lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
463 lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
464 //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
465 //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
466 //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
467
468 lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
469 lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
470 lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
471
472
473
474 return;
475
476
477
478 }
479
480
481 VOID
482 STDCALL
483 GetStartupInfoA(
484 LPSTARTUPINFO lpStartupInfo
485 )
486 {
487 NT_PEB *pPeb = GetCurrentPeb();
488 ULONG i = 0;
489 if (lpStartupInfo == NULL ) {
490 SetLastError(ERROR_INVALID_PARAMETER);
491 return;
492 }
493
494
495 lpStartupInfo->cb = sizeof(STARTUPINFO);
496 i = 0;
497
498 while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
499 {
500 lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
501 i++;
502 }
503 lpStartupInfo->lpDesktop[i] = 0;
504
505 i = 0;
506 while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
507 {
508 lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
509 i++;
510 }
511 lpStartupInfo->lpTitle[i] = 0;
512
513 lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
514 lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
515 lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
516 lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
517 lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
518 lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
519 lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
520 lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
521 lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
522 //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
523 //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
524 //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
525
526 lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
527 lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
528 lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
529
530 return;
531 }
532
533 BOOL
534 STDCALL
535 FlushInstructionCache(
536
537
538 HANDLE hProcess,
539 LPCVOID lpBaseAddress,
540 DWORD dwSize
541 )
542 {
543 NTSTATUS errCode;
544 errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
545 if ( !NT_SUCCESS(errCode) ) {
546 SetLastError(RtlNtStatusToDosError(errCode));
547 return FALSE;
548 }
549 return TRUE;
550 }
551
552 VOID
553 STDCALL
554 ExitProcess(
555 UINT uExitCode
556 )
557 {
558
559 NtTerminateProcess(
560 NtCurrentProcess() ,
561 uExitCode
562 );
563
564
565 }
566
567 VOID
568 STDCALL
569 FatalAppExitA(
570 UINT uAction,
571 LPCSTR lpMessageText
572 )
573 {
574 WCHAR MessageTextW[MAX_PATH];
575 UINT i;
576 i = 0;
577 while ((*lpMessageText)!=0 && i < 35)
578 {
579 MessageTextW[i] = *lpMessageText;
580 lpMessageText++;
581 i++;
582 }
583 MessageTextW[i] = 0;
584
585 return FatalAppExitW(uAction,MessageTextW);
586 }
587
588
589
590 VOID
591 STDCALL
592 FatalAppExitW(
593 UINT uAction,
594 LPCWSTR lpMessageText
595 )
596 {
597 return;
598 }
599
600