more changes to support the loader
[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
426 Interval.LowPart = dwMilliseconds * 1000;
427 Interval.HighPart = 0;
428 errCode = NtDelayExecution(bAlertable,&Interval);
429 if ( !NT_SUCCESS(errCode) ) {
430 SetLastError(RtlNtStatusToDosError(errCode));
431 return -1;
432 }
433 return 0;
434 }
435
436
437
438
439
440 VOID
441 STDCALL
442 GetStartupInfoW(
443 LPSTARTUPINFO lpStartupInfo
444 )
445 {
446 NT_PEB *pPeb = GetCurrentPeb();
447
448 if (lpStartupInfo == NULL ) {
449 SetLastError(ERROR_INVALID_PARAMETER);
450 return;
451 }
452
453 lpStartupInfo->cb = sizeof(STARTUPINFO);
454 lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
455 lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
456 lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
457 lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
458 lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
459 lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
460 lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
461 lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
462 lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
463 lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
464 lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
465 //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
466 //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
467 //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
468
469 lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
470 lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
471 lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
472
473
474
475 return;
476
477
478
479 }
480
481
482 VOID
483 STDCALL
484 GetStartupInfoA(
485 LPSTARTUPINFO lpStartupInfo
486 )
487 {
488 NT_PEB *pPeb = GetCurrentPeb();
489 ULONG i = 0;
490 if (lpStartupInfo == NULL ) {
491 SetLastError(ERROR_INVALID_PARAMETER);
492 return;
493 }
494
495
496 lpStartupInfo->cb = sizeof(STARTUPINFO);
497 i = 0;
498
499 while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
500 {
501 lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
502 i++;
503 }
504 lpStartupInfo->lpDesktop[i] = 0;
505
506 i = 0;
507 while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
508 {
509 lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
510 i++;
511 }
512 lpStartupInfo->lpTitle[i] = 0;
513
514 lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
515 lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
516 lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
517 lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
518 lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
519 lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
520 lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
521 lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
522 lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
523 //lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
524 //lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
525 //lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
526
527 lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
528 lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
529 lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
530
531 return;
532 }
533
534 BOOL
535 STDCALL
536 FlushInstructionCache(
537
538
539 HANDLE hProcess,
540 LPCVOID lpBaseAddress,
541 DWORD dwSize
542 )
543 {
544 NTSTATUS errCode;
545 errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
546 if ( !NT_SUCCESS(errCode) ) {
547 SetLastError(RtlNtStatusToDosError(errCode));
548 return FALSE;
549 }
550 return TRUE;
551 }
552
553 VOID
554 STDCALL
555 ExitProcess(
556 UINT uExitCode
557 )
558 {
559
560 NtTerminateProcess(
561 NtCurrentProcess() ,
562 uExitCode
563 );
564
565
566 }
567
568 VOID
569 STDCALL
570 FatalAppExitA(
571 UINT uAction,
572 LPCSTR lpMessageText
573 )
574 {
575 WCHAR MessageTextW[MAX_PATH];
576 UINT i;
577 i = 0;
578 while ((*lpMessageText)!=0 && i < 35)
579 {
580 MessageTextW[i] = *lpMessageText;
581 lpMessageText++;
582 i++;
583 }
584 MessageTextW[i] = 0;
585
586 return FatalAppExitW(uAction,MessageTextW);
587 }
588
589
590
591 VOID
592 STDCALL
593 FatalAppExitW(
594 UINT uAction,
595 LPCWSTR lpMessageText
596 )
597 {
598 return;
599 }
600
601