📄 create.c
字号:
FoundQuotes = TRUE;
break;
}
/* Keep looking */
ScanString++;
NullBuffer = ScanString;
}
}
else
{
/* No quotes, so we'll be looking for white space */
WhiteScan:
/* Reset the pointer */
lpApplicationName = lpCommandLine;
/* Find whitespace of Tab */
while (*ScanString)
{
if (*ScanString == ' ' || *ScanString == '\t')
{
/* Found it */
NullBuffer = ScanString;
break;
}
/* Keep looking */
ScanString++;
NullBuffer = ScanString;
}
}
/* Set the Null Buffer */
SaveChar = *NullBuffer;
*NullBuffer = UNICODE_NULL;
/* Do a search for the file */
DPRINT("Ready for SearchPathW: %S\n", lpApplicationName);
RetVal = SearchPathW(NULL,
lpApplicationName,
L".exe",
MAX_PATH,
NameBuffer,
NULL) * sizeof(WCHAR);
/* Did it find something? */
if (RetVal)
{
/* Get file attributes */
ULONG Attributes = GetFileAttributesW(NameBuffer);
if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
/* Give it a length of 0 to fail, this was a directory. */
RetVal = 0;
}
else
{
/* It's a file! */
RetVal += sizeof(WCHAR);
}
}
/* Now check if we have a file, and if the path size is OK */
if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR)))
{
ULONG PathType;
HANDLE hFile;
/* We failed, try to get the Path Type */
DPRINT("SearchPathW failed. Retval: %ld\n", RetVal);
PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
/* If it's not relative, try to get the error */
if (PathType != RtlPathTypeRelative)
{
/* This should fail, and give us a detailed LastError */
hFile = CreateFileW(lpApplicationName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
/* Did it actually NOT fail? */
if (hFile != INVALID_HANDLE_VALUE)
{
/* Fake the error */
CloseHandle(hFile);
SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
}
}
else
{
/* Immediately set the error */
SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
}
/* Did we already fail once? */
if (Error)
{
SetLastError(Error);
}
else
{
/* Not yet, cache it */
Error = GetLastError();
}
/* Put back the command line */
*NullBuffer = SaveChar;
lpApplicationName = NameBuffer;
/*
* If the search isn't done and we still have cmdline
* then start over. Ex: c:\ha ha ha\haha.exe
*/
if (*ScanString && !SearchDone)
{
/* Move in the buffer */
ScanString++;
NullBuffer = ScanString;
/* We will have to add a quote, since there is a space*/
QuotesNeeded = TRUE;
/* And we will also fake the fact we found one */
FoundQuotes = TRUE;
/* Start over */
goto WhiteScan;
}
/* We totally failed */
goto Cleanup;
}
/* Put back the command line */
*NullBuffer = SaveChar;
lpApplicationName = NameBuffer;
DPRINT("SearchPathW suceeded (%ld): %S\n", RetVal, NameBuffer);
}
else if (!lpCommandLine || *lpCommandLine == UNICODE_NULL)
{
/* We have an app name (good!) but no command line */
CmdLineIsAppName = TRUE;
lpCommandLine = (LPWSTR)lpApplicationName;
}
/* At this point the name has been toyed with enough to be openable */
Status = BasepMapFile(lpApplicationName, &hSection, &ApplicationName);
/* Check for failure */
if (!NT_SUCCESS(Status))
{
/* Could be a non-PE File */
switch (Status)
{
/* Check if the Kernel tells us it's not even valid MZ */
case STATUS_INVALID_IMAGE_NE_FORMAT:
case STATUS_INVALID_IMAGE_PROTECT:
case STATUS_INVALID_IMAGE_NOT_MZ:
#if 0
/* If it's a DOS app, use VDM */
if ((BasepCheckDosApp(&ApplicationName)))
{
DPRINT1("Launching VDM...\n");
RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
return CreateProcessW(L"ntvdm.exe",
(LPWSTR)lpApplicationName,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
&StartupInfo,
lpProcessInformation);
}
#endif
/* It's a batch file */
Extension = &ApplicationName.Buffer[ApplicationName.Length /
sizeof(WCHAR) - 4];
/* Make sure the extensions are correct */
if (_wcsnicmp(Extension, L".bat", 4) && _wcsnicmp(Extension, L".cmd", 4))
{
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}
/* Calculate the length of the command line */
CmdLineLength = wcslen(CMD_STRING) + wcslen(lpCommandLine) + 1;
/* If we found quotes, then add them into the length size */
if (CmdLineIsAppName || FoundQuotes) CmdLineLength += 2;
CmdLineLength *= sizeof(WCHAR);
/* Allocate space for the new command line */
BatchCommandLine = RtlAllocateHeap(RtlGetProcessHeap(),
0,
CmdLineLength);
if (BatchCommandLine == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
/* Build it */
wcscpy(BatchCommandLine, CMD_STRING);
if (CmdLineIsAppName || FoundQuotes)
{
wcscat(BatchCommandLine, L"\"");
}
wcscat(BatchCommandLine, lpCommandLine);
if (CmdLineIsAppName || FoundQuotes)
{
wcscat(BatchCommandLine, L"\"");
}
/* Create it as a Unicode String */
RtlInitUnicodeString(&CommandLineString, BatchCommandLine);
/* Set the command line to this */
lpCommandLine = CommandLineString.Buffer;
lpApplicationName = NULL;
/* Free memory */
RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
ApplicationName.Buffer = NULL;
goto GetAppName;
break;
case STATUS_INVALID_IMAGE_WIN_16:
/* It's a Win16 Image, use VDM */
DPRINT1("Launching VDM...\n");
RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
return CreateProcessW(L"ntvdm.exe",
(LPWSTR)lpApplicationName,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
&StartupInfo,
lpProcessInformation);
default:
/* Invalid Image Type */
SetLastError(ERROR_BAD_EXE_FORMAT);
goto Cleanup;
}
}
/* Use our desktop if we didn't get any */
if (!StartupInfo.lpDesktop)
{
StartupInfo.lpDesktop = OurPeb->ProcessParameters->DesktopInfo.Buffer;
}
/* FIXME: Check if Application is allowed to run */
/* FIXME: Allow CREATE_SEPARATE only for WOW Apps, once we have that. */
/* Get some information about the executable */
Status = ZwQuerySection(hSection,
SectionImageInformation,
&SectionImageInfo,
sizeof(SectionImageInfo),
NULL);
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to get SectionImageInformation, status 0x%x\n", Status);
SetLastErrorByStatus(Status);
goto Cleanup;
}
/* Don't execute DLLs */
if (SectionImageInfo.ImageCharacteristics & IMAGE_FILE_DLL)
{
DPRINT1("Can't execute a DLL\n");
SetLastError(ERROR_BAD_EXE_FORMAT);
goto Cleanup;
}
/* FIXME: Check for Debugger */
/* FIXME: Check if Machine Type and SubSys Version Match */
/* We don't support POSIX or anything else for now */
if (IMAGE_SUBSYSTEM_WINDOWS_GUI != SectionImageInfo.SubsystemType &&
IMAGE_SUBSYSTEM_WINDOWS_CUI != SectionImageInfo.SubsystemType)
{
DPRINT1("Invalid subsystem %d\n", SectionImageInfo.SubsystemType);
SetLastError(ERROR_BAD_EXE_FORMAT);
goto Cleanup;
}
if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo.SubsystemType)
{
/* Do not create a console for GUI applications */
dwCreationFlags &= ~CREATE_NEW_CONSOLE;
dwCreationFlags |= DETACHED_PROCESS;
}
/* Initialize the process object attributes */
ObjectAttributes = BasepConvertObjectAttributes(&LocalObjectAttributes,
lpProcessAttributes,
NULL);
/* Check if we're going to be debugged */
if (dwCreationFlags & DEBUG_PROCESS)
{
/* FIXME: Set process flag */
}
/* Check if we're going to be debugged */
if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
{
/* Connect to DbgUi */
Status = DbgUiConnectToDbg();
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to connect to DbgUI!\n");
SetLastErrorByStatus(Status);
goto Cleanup;
}
/* Get the debug object */
hDebug = DbgUiGetThreadDebugObject();
/* Check if only this process will be debugged */
if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
{
/* FIXME: Set process flag */
}
}
/* Create the Process */
Status = NtCreateProcess(&hProcess,
PROCESS_ALL_ACCESS,
ObjectAttributes,
NtCurrentProcess(),
bInheritHandles,
hSection,
hDebug,
NULL);
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to create process, status 0x%x\n", Status);
SetLastErrorByStatus(Status);
goto Cleanup;
}
/* Set new class */
Status = NtSetInformationProcess(hProcess,
ProcessPriorityClass,
&PriorityClass,
sizeof(PROCESS_PRIORITY_CLASS));
if(!NT_SUCCESS(Status))
{
DPRINT1("Unable to set new process priority, status 0x%x\n", Status);
SetLastErrorByStatus(Status);
goto Cleanup;
}
/* Set Error Mode */
if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
{
ULONG ErrorMode = SEM_FAILCRITICALERRORS;
NtSetInformationProcess(hProcess,
ProcessDefaultHardErrorMode,
&ErrorMode,
sizeof(ULONG));
}
/* Convert the directory to a full path */
if (lpCurrentDirectory)
{
/* Allocate a buffer */
CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
0,
(MAX_PATH + 1) * sizeof(WCHAR));
if (CurrentDirectory == NULL)
{
DPRINT1("Cannot allocate memory for directory name\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
/* Get the length */
if (GetFullPathNameW(lpCurrentDirectory,
MAX_PATH,
CurrentDirectory,
&CurrentDirectoryPart) > MAX_PATH)
{
DPRINT1("Directory name too long\n");
SetLastError(ERROR_DIRECTORY);
goto Cleanup;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -