[KERNEL32]: Parsing fixes

svn path=/trunk/; revision=59647
This commit is contained in:
Alex Ionescu 2013-08-05 18:33:52 +00:00
parent ce6c0a9ea5
commit f9c1de4baa

View file

@ -2291,7 +2291,7 @@ CreateProcessInternalW(IN HANDLE hUserToken,
SECTION_IMAGE_INFORMATION ImageInformation; SECTION_IMAGE_INFORMATION ImageInformation;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
CLIENT_ID ClientId; CLIENT_ID ClientId;
ULONG NoWindow, RegionSize, StackSize, ImageMachine, dwErrCode, Flags; ULONG NoWindow, RegionSize, StackSize, ImageMachine, ErrorCode, Flags;
ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse; ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
ULONG_PTR ErrorParameters[2]; ULONG_PTR ErrorParameters[2];
BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege; BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
@ -2320,14 +2320,14 @@ CreateProcessInternalW(IN HANDLE hUserToken,
// //
PCHAR pcScan; PCHAR pcScan;
SIZE_T n; SIZE_T n;
WCHAR TempChar; WCHAR SaveChar;
ULONG Length, CurdirLength, CmdQuoteLength; ULONG Length, CurdirLength, CmdQuoteLength;
ULONG CmdLineLength, ResultSize; ULONG CmdLineLength, ResultSize;
PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory; PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
PWCHAR TempNull, WhiteScan, NameBuffer, SearchPath, DebuggerCmdLine; PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
ANSI_STRING AnsiEnv; ANSI_STRING AnsiEnv;
UNICODE_STRING UnicodeEnv, PathName; UNICODE_STRING UnicodeEnv, PathName;
BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName; BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
// //
// Variables used for Fusion/SxS (Side-by-Side Assemblies) // Variables used for Fusion/SxS (Side-by-Side Assemblies)
@ -2405,13 +2405,13 @@ CreateProcessInternalW(IN HANDLE hUserToken,
DebuggerCmdLine = NULL; DebuggerCmdLine = NULL;
PathBuffer = NULL; PathBuffer = NULL;
SearchPath = NULL; SearchPath = NULL;
TempNull = 0; NullBuffer = 0;
FreeBuffer = NULL; FreeBuffer = NULL;
NameBuffer = NULL; NameBuffer = NULL;
CurrentDirectory = NULL; CurrentDirectory = NULL;
FilePart = NULL; FilePart = NULL;
DebuggerString.Buffer = NULL; DebuggerString.Buffer = NULL;
QuotesNeeded = FALSE; HasQuotes = FALSE;
QuotedCmdLine = NULL; QuotedCmdLine = NULL;
/* Zero out initial VDM state */ /* Zero out initial VDM state */
@ -2624,7 +2624,7 @@ AppNameRetry:
} }
/* Set the initial parsing state. This code can loop -- don't move this! */ /* Set the initial parsing state. This code can loop -- don't move this! */
dwErrCode = FALSE; ErrorCode = 0;
SearchRetry = TRUE; SearchRetry = TRUE;
QuotesNeeded = FALSE; QuotesNeeded = FALSE;
CmdLineIsAppName = FALSE; CmdLineIsAppName = FALSE;
@ -2647,29 +2647,29 @@ AppNameRetry:
} }
/* Initialize the application name and our parsing parameters */ /* Initialize the application name and our parsing parameters */
lpApplicationName = TempNull = WhiteScan = lpCommandLine; lpApplicationName = NullBuffer = ScanString = lpCommandLine;
/* Check for an initial quote*/ /* Check for an initial quote*/
if (*lpCommandLine == L'\"') if (*lpCommandLine == L'\"')
{ {
/* We found a quote, keep searching for another one */ /* We found a quote, keep searching for another one */
SearchRetry = FALSE; SearchRetry = FALSE;
WhiteScan++; ScanString++;
lpApplicationName = TempNull = WhiteScan; lpApplicationName = ScanString;
while (*WhiteScan) while (*ScanString)
{ {
/* Have we found the terminating quote? */ /* Have we found the terminating quote? */
if (*WhiteScan == L'\"') if (*ScanString == L'\"')
{ {
/* We're done, get out of here */ /* We're done, get out of here */
TempNull = WhiteScan; NullBuffer = ScanString;
QuotesNeeded = TRUE; HasQuotes = TRUE;
break; break;
} }
/* Keep searching for the quote */ /* Keep searching for the quote */
WhiteScan++; ScanString++;
TempNull = WhiteScan; NullBuffer = ScanString;
} }
} }
else else
@ -2677,25 +2677,25 @@ AppNameRetry:
StartScan: StartScan:
/* We simply make the application name be the command line*/ /* We simply make the application name be the command line*/
lpApplicationName = lpCommandLine; lpApplicationName = lpCommandLine;
while (*WhiteScan) while (*ScanString)
{ {
/* Check if it starts with a space or tab */ /* Check if it starts with a space or tab */
if ((*WhiteScan == L' ') || (*WhiteScan == '\t')) if ((*ScanString == L' ') || (*ScanString == L'\t'))
{ {
/* Break out of the search loop */ /* Break out of the search loop */
TempNull = WhiteScan; NullBuffer = ScanString;
break; break;
} }
/* Keep searching for a space or tab */ /* Keep searching for a space or tab */
WhiteScan++; ScanString++;
TempNull = WhiteScan; NullBuffer = ScanString;
} }
} }
/* We have found the end of the application name, terminate it */ /* We have found the end of the application name, terminate it */
TempChar = *TempNull; SaveChar = *NullBuffer;
*TempNull = UNICODE_NULL; *NullBuffer = UNICODE_NULL;
/* New iteration -- free any existing saved path */ /* New iteration -- free any existing saved path */
if (SearchPath) if (SearchPath)
@ -2746,7 +2746,7 @@ StartScan:
if ((Length) && (Length < MAX_PATH)) if ((Length) && (Length < MAX_PATH))
{ {
/* Everything looks good, restore the name */ /* Everything looks good, restore the name */
*TempNull = TempChar; *NullBuffer = SaveChar;
lpApplicationName = NameBuffer; lpApplicationName = NameBuffer;
} }
else else
@ -2779,23 +2779,23 @@ StartScan:
} }
/* Did we already fail once? */ /* Did we already fail once? */
if (dwErrCode) if (ErrorCode)
{ {
/* Set the error code */ /* Set the error code */
SetLastError(dwErrCode); SetLastError(ErrorCode);
} }
else else
{ {
/* Not yet, cache it */ /* Not yet, cache it */
dwErrCode = GetLastError(); ErrorCode = GetLastError();
} }
/* Put back the command line */ /* Put back the command line */
*TempNull = TempChar; *NullBuffer = SaveChar;
lpApplicationName = NameBuffer; lpApplicationName = NameBuffer;
/* It's possible there's whitespace in the directory name */ /* It's possible there's whitespace in the directory name */
if (!(*WhiteScan) || !(SearchRetry)) if (!(*ScanString) || !(SearchRetry))
{ {
/* Not the case, give up completely */ /* Not the case, give up completely */
Result = FALSE; Result = FALSE;
@ -2803,11 +2803,12 @@ StartScan:
} }
/* There are spaces, so keep trying the next possibility */ /* There are spaces, so keep trying the next possibility */
WhiteScan++; ScanString++;
TempNull = WhiteScan; NullBuffer = ScanString;
/* We will have to add a quote, since there is a space */ /* We will have to add a quote, since there is a space */
QuotesNeeded = TRUE; QuotesNeeded = TRUE;
HasQuotes = TRUE;
goto StartScan; goto StartScan;
} }
} }
@ -3437,10 +3438,10 @@ StartScan:
} }
/* Check if we need to account for quotes around the path */ /* Check if we need to account for quotes around the path */
CmdQuoteLength = CmdLineIsAppName || QuotesNeeded; CmdQuoteLength = CmdLineIsAppName || HasQuotes;
if (!CmdLineIsAppName) if (!CmdLineIsAppName)
{ {
if (QuotesNeeded) CmdQuoteLength++; if (HasQuotes) CmdQuoteLength++;
} }
else else
{ {
@ -3466,12 +3467,12 @@ StartScan:
/* Build it */ /* Build it */
wcscpy(AnsiCmdCommand, CMD_STRING); wcscpy(AnsiCmdCommand, CMD_STRING);
if ((CmdLineIsAppName) || (QuotesNeeded)) if ((CmdLineIsAppName) || (HasQuotes))
{ {
wcscat(AnsiCmdCommand, L"\""); wcscat(AnsiCmdCommand, L"\"");
} }
wcscat(AnsiCmdCommand, lpCommandLine); wcscat(AnsiCmdCommand, lpCommandLine);
if ((CmdLineIsAppName) || (QuotesNeeded)) if ((CmdLineIsAppName) || (HasQuotes))
{ {
wcscat(AnsiCmdCommand, L"\""); wcscat(AnsiCmdCommand, L"\"");
} }
@ -4062,8 +4063,8 @@ StartScan:
/* Allocate our buffer, plus enough space for quotes and a NULL */ /* Allocate our buffer, plus enough space for quotes and a NULL */
QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(), QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
0, 0,
wcslen(lpCommandLine) * sizeof(WCHAR) + (wcslen(lpCommandLine) * sizeof(WCHAR)) +
2 * sizeof(L'\"') + sizeof(UNICODE_NULL)); (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
if (QuotedCmdLine) if (QuotedCmdLine)
{ {
/* Copy the first quote */ /* Copy the first quote */
@ -4072,8 +4073,8 @@ StartScan:
/* Save the current null-character */ /* Save the current null-character */
if (QuotesNeeded) if (QuotesNeeded)
{ {
TempChar = *TempNull; SaveChar = *NullBuffer;
*TempNull = UNICODE_NULL; *NullBuffer = UNICODE_NULL;
} }
/* Copy the command line and the final quote */ /* Copy the command line and the final quote */
@ -4083,8 +4084,8 @@ StartScan:
/* Copy the null-char back */ /* Copy the null-char back */
if (QuotesNeeded) if (QuotesNeeded)
{ {
*TempNull = TempChar; *NullBuffer = SaveChar;
wcscat(QuotedCmdLine, TempNull); wcscat(QuotedCmdLine, NullBuffer);
} }
} }
else else
@ -4095,17 +4096,19 @@ StartScan:
} }
} }
/* Reserve the first 1MB if needed */ /* Use isolation if needed */
if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1; if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
/* Set the new command-line if needed */
if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
/* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */ /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
Result = BasePushProcessParameters(ParameterFlags, Result = BasePushProcessParameters(ParameterFlags,
ProcessHandle, ProcessHandle,
RemotePeb, RemotePeb,
lpApplicationName, lpApplicationName,
CurrentDirectory, CurrentDirectory,
((QuotesNeeded) || (CmdLineIsAppName)) ? lpCommandLine,
QuotedCmdLine : lpCommandLine,
lpEnvironment, lpEnvironment,
&StartupInfo, &StartupInfo,
dwCreationFlags | NoWindow, dwCreationFlags | NoWindow,