📄 create.c
字号:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/process/create.c
* PURPOSE: Process functions
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
* Ariadne ( ariadne@xs4all.nl)
*/
/* INCLUDES ****************************************************************/
#include <k32.h>
#define NDEBUG
#include "../include/debug.h"
#define CMD_STRING L"cmd /c "
extern __declspec(noreturn)
VOID
CALLBACK
ConsoleControlDispatcher(DWORD CodeAndFlag);
/* INTERNAL FUNCTIONS *******************************************************/
_SEH_FILTER(BaseExceptionFilter)
{
EXCEPTION_POINTERS *ExceptionInfo = _SEH_GetExceptionPointers();
LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
if (GlobalTopLevelExceptionFilter != NULL)
{
_SEH_TRY
{
ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
}
_SEH_HANDLE
{
}
_SEH_END;
}
if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
GlobalTopLevelExceptionFilter != UnhandledExceptionFilter)
{
ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
}
return ExceptionDisposition;
}
VOID
STDCALL
BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
{
UINT uExitCode = 0;
DPRINT("BaseProcessStartup(..) - setting up exception frame.\n");
_SEH_TRY
{
/* Set our Start Address */
NtSetInformationThread(NtCurrentThread(),
ThreadQuerySetWin32StartAddress,
&lpStartAddress,
sizeof(PPROCESS_START_ROUTINE));
/* Call the Start Routine */
uExitCode = (lpStartAddress)();
}
_SEH_EXCEPT(BaseExceptionFilter)
{
/* Get the SEH Error */
uExitCode = _SEH_GetExceptionCode();
}
_SEH_END;
/* Exit the Process with our error */
ExitProcess(uExitCode);
}
/*
* Tells CSR that a new process was created
*/
NTSTATUS
STDCALL
BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
IN HANDLE ProcessId,
IN BOOL InheritHandles)
{
ULONG Request = CREATE_PROCESS;
CSR_API_MESSAGE CsrRequest;
NTSTATUS Status;
DPRINT("BasepNotifyCsrOfCreation: Process: %lx, Flags %lx\n",
ProcessId, dwCreationFlags);
/* Fill out the request */
CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId;
CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles;
/* Call CSR */
Status = CsrClientCallServer(&CsrRequest,
NULL,
MAKE_CSR_API(Request, CSR_NATIVE),
sizeof(CSR_API_MESSAGE));
if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
{
DPRINT1("Failed to tell csrss about new process\n");
return CsrRequest.Status;
}
/* REturn Success */
return STATUS_SUCCESS;
}
/*
* Creates the first Thread in a Proces
*/
HANDLE
STDCALL
BasepCreateFirstThread(HANDLE ProcessHandle,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
PSECTION_IMAGE_INFORMATION SectionImageInfo,
PCLIENT_ID ClientId)
{
OBJECT_ATTRIBUTES LocalObjectAttributes;
POBJECT_ATTRIBUTES ObjectAttributes;
CONTEXT Context;
INITIAL_TEB InitialTeb;
NTSTATUS Status;
HANDLE hThread;
DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle);
/* Create the Thread's Stack */
BasepCreateStack(ProcessHandle,
SectionImageInfo->MaximumStackSize,
SectionImageInfo->CommittedStackSize,
&InitialTeb);
/* Create the Thread's Context */
BasepInitializeContext(&Context,
NtCurrentPeb(),
SectionImageInfo->TransferAddress,
InitialTeb.StackBase,
0);
/* Convert the thread attributes */
ObjectAttributes = BasepConvertObjectAttributes(&LocalObjectAttributes,
lpThreadAttributes,
NULL);
/* Create the Kernel Thread Object */
Status = NtCreateThread(&hThread,
THREAD_ALL_ACCESS,
ObjectAttributes,
ProcessHandle,
ClientId,
&Context,
&InitialTeb,
TRUE);
if (!NT_SUCCESS(Status))
{
return NULL;
}
/* Success */
return hThread;
}
/*
* Converts ANSI to Unicode Environment
*/
PVOID
STDCALL
BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize,
IN PVOID lpEnvironment)
{
PCHAR pcScan;
ANSI_STRING AnsiEnv;
UNICODE_STRING UnicodeEnv;
NTSTATUS Status;
DPRINT("BasepConvertUnicodeEnvironment\n");
/* Scan the environment to calculate its Unicode size */
AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
while (*pcScan)
{
pcScan += strlen(pcScan) + 1;
}
/* Create our ANSI String */
if (pcScan == (PCHAR)lpEnvironment)
{
AnsiEnv.Length = 2 * sizeof(CHAR);
}
else
{
AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR);
}
AnsiEnv.MaximumLength = AnsiEnv.Length + 1;
/* Allocate memory for the Unicode Environment */
UnicodeEnv.Buffer = NULL;
*EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
(PVOID)&UnicodeEnv.Buffer,
0,
EnvSize,
MEM_COMMIT,
PAGE_READWRITE);
/* Failure */
if (!NT_SUCCESS(Status))
{
SetLastError(Status);
*EnvSize = 0;
return NULL;
}
/* Use the allocated size */
UnicodeEnv.MaximumLength = *EnvSize;
/* Convert */
RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
return UnicodeEnv.Buffer;
}
/*
* Converts a Win32 Priority Class to NT
*/
ULONG
STDCALL
BasepConvertPriorityClass(IN ULONG dwCreationFlags)
{
ULONG ReturnClass;
if(dwCreationFlags & IDLE_PRIORITY_CLASS)
{
ReturnClass = PROCESS_PRIORITY_CLASS_IDLE;
}
else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
{
ReturnClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
}
else if(dwCreationFlags & NORMAL_PRIORITY_CLASS)
{
ReturnClass = PROCESS_PRIORITY_CLASS_NORMAL;
}
else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
{
ReturnClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
}
else if(dwCreationFlags & HIGH_PRIORITY_CLASS)
{
ReturnClass = PROCESS_PRIORITY_CLASS_HIGH;
}
else if(dwCreationFlags & REALTIME_PRIORITY_CLASS)
{
/* Check for Privilege First */
if (BasepCheckRealTimePrivilege())
{
ReturnClass = PROCESS_PRIORITY_CLASS_REALTIME;
}
else
{
ReturnClass = PROCESS_PRIORITY_CLASS_HIGH;
}
}
else
{
ReturnClass = PROCESS_PRIORITY_CLASS_INVALID;
}
return ReturnClass;
}
/*
* Duplicates a standard handle and writes it where requested.
*/
VOID
STDCALL
BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle,
IN HANDLE StandardHandle,
IN PHANDLE Address)
{
NTSTATUS Status;
HANDLE DuplicatedHandle;
ULONG Dummy;
DPRINT("BasepDuplicateAndWriteHandle. hProcess: %lx, Handle: %lx,"
"Address: %p\n", ProcessHandle, StandardHandle, Address);
/* Don't touch Console Handles */
if (IsConsoleHandle(StandardHandle)) return;
/* Duplicate the handle */
Status = NtDuplicateObject(NtCurrentProcess(),
StandardHandle,
ProcessHandle,
&DuplicatedHandle,
DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES,
0,
0);
if (NT_SUCCESS(Status))
{
/* Write it */
NtWriteVirtualMemory(ProcessHandle,
Address,
&DuplicatedHandle,
sizeof(HANDLE),
&Dummy);
}
}
LPWSTR
STDCALL
BasepGetDllPath(LPWSTR FullPath,
PVOID Environment)
{
/* FIXME: Not yet implemented */
return NULL;
}
VOID
STDCALL
BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
IN PRTL_USER_PROCESS_PARAMETERS PebParams,
IN BOOL InheritHandles)
{
DPRINT("BasepCopyHandles %p %p, %d\n", Params, PebParams, InheritHandles);
/* Copy the handle if we are inheriting or if it's a console handle */
if (InheritHandles || IsConsoleHandle(PebParams->StandardInput))
{
Params->StandardInput = PebParams->StandardInput;
}
if (InheritHandles || IsConsoleHandle(PebParams->StandardOutput))
{
Params->StandardOutput = PebParams->StandardOutput;
}
if (InheritHandles || IsConsoleHandle(PebParams->StandardError))
{
Params->StandardError = PebParams->StandardError;
}
}
NTSTATUS
STDCALL
BasepInitializeEnvironment(HANDLE ProcessHandle,
PPEB Peb,
LPWSTR ApplicationPathName,
LPWSTR lpCurrentDirectory,
LPWSTR lpCommandLine,
LPVOID lpEnvironment,
SIZE_T EnvSize,
LPSTARTUPINFOW StartupInfo,
DWORD CreationFlags,
BOOL InheritHandles)
{
WCHAR FullPath[MAX_PATH];
LPWSTR Remaining;
LPWSTR DllPathString;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PRTL_USER_PROCESS_PARAMETERS RemoteParameters = NULL;
UNICODE_STRING DllPath, ImageName, CommandLine, CurrentDirectory;
UINT RetVal;
NTSTATUS Status;
PWCHAR ScanChar;
ULONG EnviroSize;
SIZE_T Size;
UNICODE_STRING Desktop, Shell, Runtime, Title;
PPEB OurPeb = NtCurrentPeb();
LPVOID Environment = lpEnvironment;
DPRINT("BasepInitializeEnvironment\n");
/* Get the full path name */
RetVal = GetFullPathNameW(ApplicationPathName,
MAX_PATH,
FullPath,
&Remaining);
DPRINT("ApplicationPathName: %S, FullPath: %S\n", ApplicationPathName,
FullPath);
/* Get the DLL Path */
DllPathString = BasepGetDllPath(FullPath, Environment);
/* Initialize Strings */
RtlInitUnicodeString(&DllPath, DllPathString);
RtlInitUnicodeString(&ImageName, FullPath);
RtlInitUnicodeString(&CommandLine, lpCommandLine);
RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
/* Initialize more Strings from the Startup Info */
if (StartupInfo->lpDesktop)
{
RtlInitUnicodeString(&Desktop, StartupInfo->lpDesktop);
}
else
{
RtlInitUnicodeString(&Desktop, L"");
}
if (StartupInfo->lpReserved)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -