📄 create.c
字号:
/* Insert quotes if needed */
if (QuotesNeeded || CmdLineIsAppName)
{
/* Allocate a buffer */
QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
0,
(wcslen(lpCommandLine) + 2 + 1) *
sizeof(WCHAR));
if (QuotedCmdLine == NULL)
{
DPRINT1("Cannot allocate memory for quoted command line\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
/* Copy the first quote */
wcscpy(QuotedCmdLine, L"\"");
/* Save a null char */
if (QuotesNeeded)
{
SaveChar = *NullBuffer;
*NullBuffer = UNICODE_NULL;
}
/* Add the command line and the finishing quote */
wcscat(QuotedCmdLine, lpCommandLine);
wcscat(QuotedCmdLine, L"\"");
/* Add the null char */
if (QuotesNeeded)
{
*NullBuffer = SaveChar;
wcscat(QuotedCmdLine, NullBuffer);
}
DPRINT("Quoted CmdLine: %S\n", QuotedCmdLine);
}
if (Escape)
{
if (QuotedCmdLine == NULL)
{
QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
0,
(wcslen(lpCommandLine) + 1) * sizeof(WCHAR));
if (QuotedCmdLine == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
wcscpy(QuotedCmdLine, lpCommandLine);
}
ScanString = QuotedCmdLine;
while (NULL != (ScanString = wcschr(ScanString, L'^')))
{
ScanString++;
if (*ScanString == L'\"' || *ScanString == L'^' || *ScanString == L'\\')
{
memmove(ScanString-1, ScanString, wcslen(ScanString) * sizeof(WCHAR) + sizeof(WCHAR));
}
}
}
/* Get the Process Information */
Status = NtQueryInformationProcess(hProcess,
ProcessBasicInformation,
&ProcessBasicInfo,
sizeof(ProcessBasicInfo),
NULL);
/* Convert the environment */
if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment);
if (!lpEnvironment) goto Cleanup;
}
/* Create Process Environment */
RemotePeb = ProcessBasicInfo.PebBaseAddress;
Status = BasepInitializeEnvironment(hProcess,
RemotePeb,
(LPWSTR)lpApplicationName,
CurrentDirectory,
(QuotesNeeded || CmdLineIsAppName || Escape) ?
QuotedCmdLine : lpCommandLine,
lpEnvironment,
EnvSize,
&StartupInfo,
dwCreationFlags,
bInheritHandles);
/* Cleanup Environment */
if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
RtlDestroyEnvironment(lpEnvironment);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Could not initialize Process Environment\n");
SetLastErrorByStatus(Status);
goto Cleanup;
}
/* Close the section */
NtClose(hSection);
hSection = NULL;
/* Duplicate the handles if needed */
if (!bInheritHandles && !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
SectionImageInfo.SubsystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI)
{
PRTL_USER_PROCESS_PARAMETERS RemoteParameters;
/* Get the remote parameters */
Status = NtReadVirtualMemory(hProcess,
&RemotePeb->ProcessParameters,
&RemoteParameters,
sizeof(PVOID),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to read memory\n");
goto Cleanup;
}
/* Duplicate and write the handles */
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardInput,
&RemoteParameters->StandardInput);
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardOutput,
&RemoteParameters->StandardOutput);
BasepDuplicateAndWriteHandle(hProcess,
OurPeb->ProcessParameters->StandardError,
&RemoteParameters->StandardError);
}
/* Create the first thread */
DPRINT("Creating thread for process (EntryPoint = 0x%p)\n",
SectionImageInfo.TransferAddress);
hThread = BasepCreateFirstThread(hProcess,
lpThreadAttributes,
&SectionImageInfo,
&ClientId);
if (hThread == NULL)
{
DPRINT1("Could not create Initial Thread\n");
/* FIXME - set last error code */
goto Cleanup;
}
/* Notify CSRSS */
Status = BasepNotifyCsrOfCreation(dwCreationFlags,
(HANDLE)ProcessBasicInfo.UniqueProcessId,
bInheritHandles);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSR Notification Failed");
SetLastErrorByStatus(Status);
goto Cleanup;
}
if (!(dwCreationFlags & CREATE_SUSPENDED))
{
NtResumeThread(hThread, &Dummy);
}
/* Return Data */
lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess;
lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread;
lpProcessInformation->hProcess = hProcess;
lpProcessInformation->hThread = hThread;
DPRINT("hThread[%p]: %p inside hProcess[%p]: %p\n", hThread,
ClientId.UniqueThread, ClientId.UniqueProcess, hProcess);
hProcess = hThread = NULL;
Ret = TRUE;
Cleanup:
/* De-allocate heap strings */
if (NameBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
if (ApplicationName.Buffer)
RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
if (CurrentDirectory) RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
if (QuotedCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
/* Kill any handles still alive */
if (hSection) NtClose(hSection);
if (hThread)
{
/* We don't know any more details then this */
NtTerminateProcess(hProcess, STATUS_UNSUCCESSFUL);
NtClose(hThread);
}
if (hProcess) NtClose(hProcess);
/* Return Success */
return Ret;
}
/*
* @implemented
*/
BOOL
STDCALL
CreateProcessW(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
/* Call the internal (but exported) version */
return CreateProcessInternalW(0,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation,
NULL);
}
/*
* @implemented
*/
BOOL
STDCALL
CreateProcessInternalA(HANDLE hToken,
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation,
PHANDLE hNewToken)
{
PUNICODE_STRING CommandLine = NULL;
UNICODE_STRING DummyString;
UNICODE_STRING LiveCommandLine;
UNICODE_STRING ApplicationName;
UNICODE_STRING CurrentDirectory;
BOOL bRetVal;
STARTUPINFOW StartupInfo;
DPRINT("dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, "
"lpStartupInfo %x, lpProcessInformation %x\n",
dwCreationFlags, lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation);
/* Copy Startup Info */
RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
/* Initialize all strings to nothing */
LiveCommandLine.Buffer = NULL;
DummyString.Buffer = NULL;
ApplicationName.Buffer = NULL;
CurrentDirectory.Buffer = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpReserved = NULL;
StartupInfo.lpTitle = NULL;
/* Convert the Command line */
if (lpCommandLine)
{
/* If it's too long, then we'll have a problem */
if ((strlen(lpCommandLine) + 1) * sizeof(WCHAR) <
NtCurrentTeb()->StaticUnicodeString.MaximumLength)
{
/* Cache it in the TEB */
CommandLine = Basep8BitStringToCachedUnicodeString(lpCommandLine);
}
else
{
/* Use a dynamic version */
Basep8BitStringToHeapUnicodeString(&LiveCommandLine,
lpCommandLine);
}
}
else
{
/* The logic below will use CommandLine, so we must make it valid */
CommandLine = &DummyString;
}
/* Convert the Name and Directory */
if (lpApplicationName)
{
Basep8BitStringToHeapUnicodeString(&ApplicationName,
lpApplicationName);
}
if (lpCurrentDirectory)
{
Basep8BitStringToHeapUnicodeString(&CurrentDirectory,
lpCurrentDirectory);
}
/* Now convert Startup Strings */
if (lpStartupInfo->lpReserved)
{
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpReserved,
&StartupInfo.lpReserved);
}
if (lpStartupInfo->lpDesktop)
{
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpDesktop,
&StartupInfo.lpDesktop);
}
if (lpStartupInfo->lpTitle)
{
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpTitle,
&StartupInfo.lpTitle);
}
/* Call the Unicode function */
bRetVal = CreateProcessInternalW(hToken,
ApplicationName.Buffer,
LiveCommandLine.Buffer ?
LiveCommandLine.Buffer : CommandLine->Buffer,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
CurrentDirectory.Buffer,
&StartupInfo,
lpProcessInformation,
hNewToken);
/* Clean up */
RtlFreeUnicodeString(&ApplicationName);
RtlFreeUnicodeString(&LiveCommandLine);
RtlFreeUnicodeString(&CurrentDirectory);
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
/* Return what Unicode did */
return bRetVal;
}
/*
* FUNCTION: The CreateProcess function creates a new process and its
* primary thread. The new process executes the specified executable file
* ARGUMENTS:
*
* lpApplicationName = Pointer to name of executable module
* lpCommandLine = Pointer to command line string
* lpProcessAttributes = Process security attributes
* lpThreadAttributes = Thread security attributes
* bInheritHandles = Handle inheritance flag
* dwCreationFlags = Creation flags
* lpEnvironment = Pointer to new environment block
* lpCurrentDirectory = Pointer to current directory name
* lpStartupInfo = Pointer to startup info
* lpProcessInformation = Pointer to process information
*
* @implemented
*/
BOOL
STDCALL
CreateProcessA(LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
/* Call the internal (but exported) version */
return CreateProcessInternalA(0,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation,
NULL);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -