mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
* fixed command line handling
* refreshed fixlib.exe and libs git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3442 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -9,6 +9,7 @@ Process Hacker
|
||||
* Relative start times
|
||||
* FIXED:
|
||||
* Run and Run As shortcuts
|
||||
* Command line handling
|
||||
|
||||
2.1
|
||||
* NEW/IMPROVED:
|
||||
|
||||
@@ -597,22 +597,19 @@ BOOLEAN NTAPI PhpCommandLineOptionCallback(
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Value)
|
||||
PPH_STRING lowerValue;
|
||||
|
||||
lowerValue = PhDuplicateString(Value);
|
||||
PhLowerString(lowerValue);
|
||||
|
||||
if (PhStringIndexOfString(lowerValue, 0, L"taskmgr.exe") != -1)
|
||||
{
|
||||
PPH_STRING lowerValue;
|
||||
|
||||
lowerValue = PhDuplicateString(Value);
|
||||
PhLowerString(lowerValue);
|
||||
|
||||
if (PhStringIndexOfString(lowerValue, 0, L"taskmgr.exe") != -1)
|
||||
{
|
||||
// User probably has Process Hacker replacing Task Manager. Force
|
||||
// the main window to start visible.
|
||||
PhStartupParameters.ShowVisible = TRUE;
|
||||
}
|
||||
|
||||
PhDereferenceObject(lowerValue);
|
||||
// User probably has Process Hacker replacing Task Manager. Force
|
||||
// the main window to start visible.
|
||||
PhStartupParameters.ShowVisible = TRUE;
|
||||
}
|
||||
|
||||
PhDereferenceObject(lowerValue);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -649,7 +646,7 @@ VOID PhpProcessStartupParameters()
|
||||
&commandLine,
|
||||
options,
|
||||
sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
|
||||
PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS | PH_COMMAND_LINE_IGNORE_FIRST_PART | PH_COMMAND_LINE_CALLBACK_ALL_MAIN,
|
||||
PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS | PH_COMMAND_LINE_IGNORE_FIRST_PART,
|
||||
PhpCommandLineOptionCallback,
|
||||
NULL
|
||||
))
|
||||
|
||||
@@ -635,6 +635,8 @@ VOID PhSetDesktopWinStaAccess()
|
||||
HDESK desktopHandle;
|
||||
SECURITY_DESCRIPTOR securityDescriptor;
|
||||
|
||||
// TODO: Set security on the correct window station and desktop.
|
||||
|
||||
// Create a security descriptor with a NULL DACL,
|
||||
// thereby allowing everyone to access the object.
|
||||
RtlCreateSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
||||
@@ -661,53 +663,6 @@ VOID PhSetDesktopWinStaAccess()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string C-style for use in a command line.
|
||||
*
|
||||
* \param String The string to escape.
|
||||
*
|
||||
* \return The escaped string.
|
||||
*
|
||||
* \remarks Only backslash (\\) and quote characters (", ') are
|
||||
* escaped.
|
||||
*/
|
||||
PPH_STRING PhpCEscapeString(
|
||||
__in PPH_STRINGREF String
|
||||
)
|
||||
{
|
||||
PPH_STRING string;
|
||||
PH_STRING_BUILDER stringBuilder;
|
||||
ULONG length;
|
||||
ULONG i;
|
||||
WCHAR temp[2];
|
||||
|
||||
length = String->Length / 2;
|
||||
PhInitializeStringBuilder(&stringBuilder, String->Length / 2 * 3);
|
||||
|
||||
temp[0] = '\\';
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
switch (String->Buffer[i])
|
||||
{
|
||||
case '\\':
|
||||
case '\"':
|
||||
case '\'':
|
||||
temp[1] = String->Buffer[i];
|
||||
PhStringBuilderAppendEx(&stringBuilder, temp, 4);
|
||||
break;
|
||||
default:
|
||||
PhStringBuilderAppendChar(&stringBuilder, String->Buffer[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string = PhReferenceStringBuilderString(&stringBuilder);
|
||||
PhDeleteStringBuilder(&stringBuilder);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
PPH_STRING PhpBuildRunAsServiceCommandLine(
|
||||
__in PWSTR Program,
|
||||
__in_opt PWSTR UserName,
|
||||
@@ -734,14 +689,14 @@ PPH_STRING PhpBuildRunAsServiceCommandLine(
|
||||
PhStringBuilderAppend2(&commandLineBuilder, L"\" -ras");
|
||||
|
||||
PhInitializeStringRef(&stringRef, Program);
|
||||
string = PhpCEscapeString(&stringRef);
|
||||
string = PhEscapeCommandLinePart(&stringRef);
|
||||
PhStringBuilderAppend2(&commandLineBuilder, L" -c \"");
|
||||
PhStringBuilderAppend(&commandLineBuilder, string);
|
||||
PhStringBuilderAppendChar(&commandLineBuilder, '\"');
|
||||
PhDereferenceObject(string);
|
||||
|
||||
PhInitializeStringRef(&stringRef, DesktopName);
|
||||
string = PhpCEscapeString(&stringRef);
|
||||
string = PhEscapeCommandLinePart(&stringRef);
|
||||
PhStringBuilderAppend2(&commandLineBuilder, L" -D \"");
|
||||
PhStringBuilderAppend(&commandLineBuilder, string);
|
||||
PhStringBuilderAppendChar(&commandLineBuilder, '\"');
|
||||
@@ -750,14 +705,14 @@ PPH_STRING PhpBuildRunAsServiceCommandLine(
|
||||
if (!ProcessIdWithToken)
|
||||
{
|
||||
PhInitializeStringRef(&stringRef, UserName);
|
||||
string = PhpCEscapeString(&stringRef);
|
||||
string = PhEscapeCommandLinePart(&stringRef);
|
||||
PhStringBuilderAppend2(&commandLineBuilder, L" -u \"");
|
||||
PhStringBuilderAppend(&commandLineBuilder, string);
|
||||
PhStringBuilderAppendChar(&commandLineBuilder, '\"');
|
||||
PhDereferenceObject(string);
|
||||
|
||||
PhInitializeStringRef(&stringRef, Password);
|
||||
string = PhpCEscapeString(&stringRef);
|
||||
string = PhEscapeCommandLinePart(&stringRef);
|
||||
PhStringBuilderAppend2(&commandLineBuilder, L" -p \"");
|
||||
PhStringBuilderAppend(&commandLineBuilder, string);
|
||||
PhStringBuilderAppendChar(&commandLineBuilder, '\"');
|
||||
@@ -979,7 +934,7 @@ NTSTATUS PhRunAsCommandStart2(
|
||||
L"-c -ctype processhacker -caction runas -cobject \""
|
||||
);
|
||||
|
||||
string = PhpCEscapeString(&commandLine->sr);
|
||||
string = PhEscapeCommandLinePart(&commandLine->sr);
|
||||
PhStringBuilderAppend(&argumentsBuilder, string);
|
||||
PhDereferenceObject(string);
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+98
-22
@@ -1364,12 +1364,13 @@ VOID PhFullStringAppend2(
|
||||
* Appends a string to the end of a string.
|
||||
*
|
||||
* \param String A string object.
|
||||
* \param Buffer The string to append.
|
||||
* \param Buffer The string to append. Specify NULL
|
||||
* to simply reserve \a Length bytes.
|
||||
* \param Length The number of bytes to append.
|
||||
*/
|
||||
VOID PhFullStringAppendEx(
|
||||
__inout PPH_FULL_STRING String,
|
||||
__in PWSTR Buffer,
|
||||
__in_opt PWSTR Buffer,
|
||||
__in SIZE_T Length
|
||||
)
|
||||
{
|
||||
@@ -1380,11 +1381,15 @@ VOID PhFullStringAppendEx(
|
||||
if (String->AllocatedLength < String->Length + Length)
|
||||
PhResizeFullString(String, String->Length + Length, TRUE);
|
||||
|
||||
memcpy(
|
||||
&String->Buffer[String->Length / sizeof(WCHAR)],
|
||||
Buffer,
|
||||
Length
|
||||
);
|
||||
if (Buffer)
|
||||
{
|
||||
memcpy(
|
||||
&String->Buffer[String->Length / sizeof(WCHAR)],
|
||||
Buffer,
|
||||
Length
|
||||
);
|
||||
}
|
||||
|
||||
String->Length += Length;
|
||||
PhpWriteFullStringNullTerminator(String);
|
||||
}
|
||||
@@ -1408,6 +1413,35 @@ VOID PhFullStringAppendChar(
|
||||
PhpWriteFullStringNullTerminator(String);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a number of characters to the end of a string.
|
||||
*
|
||||
* \param String A string object.
|
||||
* \param Character The character to append.
|
||||
* \param Count The number of times to append the character.
|
||||
*/
|
||||
VOID PhFullStringAppendChar2(
|
||||
__inout PPH_FULL_STRING String,
|
||||
__in WCHAR Character,
|
||||
__in SIZE_T Count
|
||||
)
|
||||
{
|
||||
if (Count == 0)
|
||||
return;
|
||||
|
||||
if (String->AllocatedLength < String->Length + Count * sizeof(WCHAR))
|
||||
PhResizeFullString(String, String->Length + Count * sizeof(WCHAR), TRUE);
|
||||
|
||||
wmemset(
|
||||
&String->Buffer[String->Length / sizeof(WCHAR)],
|
||||
Character,
|
||||
Count
|
||||
);
|
||||
|
||||
String->Length += Count * sizeof(WCHAR);
|
||||
PhpWriteFullStringNullTerminator(String);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a formatted string to the end of a string.
|
||||
*
|
||||
@@ -1603,12 +1637,13 @@ VOID PhStringBuilderAppend2(
|
||||
* string.
|
||||
*
|
||||
* \param StringBuilder A string builder object.
|
||||
* \param String The string to append.
|
||||
* \param String The string to append. Specify NULL to
|
||||
* simply reserve \a Length bytes.
|
||||
* \param Length The number of bytes to append.
|
||||
*/
|
||||
VOID PhStringBuilderAppendEx(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in PWSTR String,
|
||||
__in_opt PWSTR String,
|
||||
__in ULONG Length
|
||||
)
|
||||
{
|
||||
@@ -1623,11 +1658,15 @@ VOID PhStringBuilderAppendEx(
|
||||
|
||||
// Copy the string, add the length, then write the null terminator.
|
||||
|
||||
memcpy(
|
||||
&StringBuilder->String->Buffer[StringBuilder->String->Length / sizeof(WCHAR)],
|
||||
String,
|
||||
Length
|
||||
);
|
||||
if (String)
|
||||
{
|
||||
memcpy(
|
||||
&StringBuilder->String->Buffer[StringBuilder->String->Length / sizeof(WCHAR)],
|
||||
String,
|
||||
Length
|
||||
);
|
||||
}
|
||||
|
||||
StringBuilder->String->Length += (USHORT)Length;
|
||||
PhpWriteStringBuilderNullTerminator(StringBuilder);
|
||||
}
|
||||
@@ -1654,6 +1693,39 @@ VOID PhStringBuilderAppendChar(
|
||||
PhpWriteStringBuilderNullTerminator(StringBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a number of characters to the end of a string
|
||||
* builder string.
|
||||
*
|
||||
* \param StringBuilder A string builder object.
|
||||
* \param Character The character to append.
|
||||
* \param Count The number of times to append the character.
|
||||
*/
|
||||
VOID PhStringBuilderAppendChar2(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in WCHAR Character,
|
||||
__in ULONG Count
|
||||
)
|
||||
{
|
||||
if (Count == 0)
|
||||
return;
|
||||
|
||||
// See if we need to re-allocate the string.
|
||||
if (StringBuilder->AllocatedLength < StringBuilder->String->Length + Count * sizeof(WCHAR))
|
||||
{
|
||||
PhpResizeStringBuilder(StringBuilder, StringBuilder->String->Length + Count * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
wmemset(
|
||||
&StringBuilder->String->Buffer[StringBuilder->String->Length / sizeof(WCHAR)],
|
||||
Character,
|
||||
Count
|
||||
);
|
||||
|
||||
StringBuilder->String->Length += (USHORT)(Count * sizeof(WCHAR));
|
||||
PhpWriteStringBuilderNullTerminator(StringBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a formatted string to the end of a string builder
|
||||
* string.
|
||||
@@ -1726,13 +1798,14 @@ VOID PhStringBuilderInsert2(
|
||||
* \param StringBuilder A string builder object.
|
||||
* \param Index The index, in characters, at which to
|
||||
* insert the string.
|
||||
* \param String The string to insert.
|
||||
* \param String The string to insert. Specify NULL to
|
||||
* simply reserve \a Length bytes.
|
||||
* \param Length The number of bytes to insert.
|
||||
*/
|
||||
VOID PhStringBuilderInsertEx(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in ULONG Index,
|
||||
__in PWSTR String,
|
||||
__in_opt PWSTR String,
|
||||
__in ULONG Length
|
||||
)
|
||||
{
|
||||
@@ -1755,12 +1828,15 @@ VOID PhStringBuilderInsertEx(
|
||||
);
|
||||
}
|
||||
|
||||
// Copy the new string.
|
||||
memcpy(
|
||||
&StringBuilder->String->Buffer[Index],
|
||||
String,
|
||||
Length
|
||||
);
|
||||
if (String)
|
||||
{
|
||||
// Copy the new string.
|
||||
memcpy(
|
||||
&StringBuilder->String->Buffer[Index],
|
||||
String,
|
||||
Length
|
||||
);
|
||||
}
|
||||
|
||||
StringBuilder->String->Length += (USHORT)Length;
|
||||
PhpWriteStringBuilderNullTerminator(StringBuilder);
|
||||
|
||||
@@ -2532,7 +2532,6 @@ typedef BOOLEAN (NTAPI *PPH_COMMAND_LINE_CALLBACK)(
|
||||
|
||||
#define PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS 0x1
|
||||
#define PH_COMMAND_LINE_IGNORE_FIRST_PART 0x2
|
||||
#define PH_COMMAND_LINE_CALLBACK_ALL_MAIN 0x4
|
||||
|
||||
PHLIBAPI
|
||||
PPH_STRING PhParseCommandLinePart(
|
||||
@@ -2543,11 +2542,16 @@ PPH_STRING PhParseCommandLinePart(
|
||||
PHLIBAPI
|
||||
BOOLEAN PhParseCommandLine(
|
||||
__in PPH_STRINGREF CommandLine,
|
||||
__in PPH_COMMAND_LINE_OPTION Options,
|
||||
__in_opt PPH_COMMAND_LINE_OPTION Options,
|
||||
__in ULONG NumberOfOptions,
|
||||
__in ULONG Flags,
|
||||
__in PPH_COMMAND_LINE_CALLBACK Callback,
|
||||
__in PVOID Context
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
PPH_STRING PhEscapeCommandLinePart(
|
||||
__in PPH_STRINGREF String
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1539,7 +1539,7 @@ VOID
|
||||
NTAPI
|
||||
PhFullStringAppendEx(
|
||||
__inout PPH_FULL_STRING String,
|
||||
__in PWSTR Buffer,
|
||||
__in_opt PWSTR Buffer,
|
||||
__in SIZE_T Length
|
||||
);
|
||||
|
||||
@@ -1551,6 +1551,15 @@ PhFullStringAppendChar(
|
||||
__in WCHAR Character
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
VOID
|
||||
NTAPI
|
||||
PhFullStringAppendChar2(
|
||||
__inout PPH_FULL_STRING String,
|
||||
__in WCHAR Character,
|
||||
__in SIZE_T Count
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
VOID
|
||||
NTAPI
|
||||
@@ -1633,7 +1642,7 @@ VOID
|
||||
NTAPI
|
||||
PhStringBuilderAppendEx(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in PWSTR String,
|
||||
__in_opt PWSTR String,
|
||||
__in ULONG Length
|
||||
);
|
||||
|
||||
@@ -1645,6 +1654,15 @@ PhStringBuilderAppendChar(
|
||||
__in WCHAR Character
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
VOID
|
||||
NTAPI
|
||||
PhStringBuilderAppendChar2(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in WCHAR Character,
|
||||
__in ULONG Count
|
||||
);
|
||||
|
||||
PHLIBAPI
|
||||
VOID
|
||||
NTAPI
|
||||
@@ -1678,7 +1696,7 @@ NTAPI
|
||||
PhStringBuilderInsertEx(
|
||||
__inout PPH_STRING_BUILDER StringBuilder,
|
||||
__in ULONG Index,
|
||||
__in PWSTR String,
|
||||
__in_opt PWSTR String,
|
||||
__in ULONG Length
|
||||
);
|
||||
|
||||
|
||||
+131
-81
@@ -2996,69 +2996,79 @@ PPH_STRING PhParseCommandLinePart(
|
||||
ULONG length;
|
||||
ULONG i;
|
||||
|
||||
BOOLEAN inEscape;
|
||||
ULONG numberOfBackslashes;
|
||||
BOOLEAN inQuote;
|
||||
BOOLEAN endOfValue;
|
||||
|
||||
length = CommandLine->Length / 2;
|
||||
i = *Index;
|
||||
|
||||
// This function follows the rules used by CommandLineToArgvW:
|
||||
//
|
||||
// * 2n backslashes and a quotation mark produces n backslashes and a quotation mark (non-literal).
|
||||
// * 2n + 1 backslashes and a quotation mark produces n and a quotation mark (literal).
|
||||
// * n backslashes and no quotation mark produces n backslashes.
|
||||
|
||||
PhInitializeStringBuilder(&stringBuilder, 10);
|
||||
inEscape = FALSE;
|
||||
numberOfBackslashes = 0;
|
||||
inQuote = FALSE;
|
||||
endOfValue = FALSE;
|
||||
|
||||
for (; i < length; i++)
|
||||
{
|
||||
if (inEscape)
|
||||
switch (CommandLine->Buffer[i])
|
||||
{
|
||||
switch (CommandLine->Buffer[i])
|
||||
case '\\':
|
||||
numberOfBackslashes++;
|
||||
break;
|
||||
case '\"':
|
||||
if (numberOfBackslashes != 0)
|
||||
{
|
||||
if (numberOfBackslashes & 1)
|
||||
{
|
||||
numberOfBackslashes /= 2;
|
||||
|
||||
if (numberOfBackslashes != 0)
|
||||
{
|
||||
PhStringBuilderAppendChar2(&stringBuilder, '\\', numberOfBackslashes);
|
||||
numberOfBackslashes = 0;
|
||||
}
|
||||
|
||||
PhStringBuilderAppendChar(&stringBuilder, '\"');
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
numberOfBackslashes /= 2;
|
||||
PhStringBuilderAppendChar2(&stringBuilder, '\\', numberOfBackslashes);
|
||||
numberOfBackslashes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inQuote)
|
||||
inQuote = TRUE;
|
||||
else
|
||||
inQuote = FALSE;
|
||||
|
||||
break;
|
||||
default:
|
||||
if (numberOfBackslashes != 0)
|
||||
{
|
||||
PhStringBuilderAppendChar2(&stringBuilder, '\\', numberOfBackslashes);
|
||||
numberOfBackslashes = 0;
|
||||
}
|
||||
|
||||
if (CommandLine->Buffer[i] == ' ' && !inQuote)
|
||||
{
|
||||
endOfValue = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
case '\\':
|
||||
case '\"':
|
||||
case '\'':
|
||||
PhStringBuilderAppendChar(&stringBuilder, CommandLine->Buffer[i]);
|
||||
break;
|
||||
default:
|
||||
// Unknown escape. Append both the backslash and
|
||||
// escape character.
|
||||
PhStringBuilderAppendEx(
|
||||
&stringBuilder,
|
||||
&CommandLine->Buffer[i - 1],
|
||||
4
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
inEscape = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (CommandLine->Buffer[i])
|
||||
{
|
||||
case '\\':
|
||||
inEscape = TRUE;
|
||||
break;
|
||||
case '\"':
|
||||
case '\'':
|
||||
if (!inQuote)
|
||||
inQuote = TRUE;
|
||||
else
|
||||
inQuote = FALSE;
|
||||
|
||||
break;
|
||||
default:
|
||||
if (CommandLine->Buffer[i] == ' ' && !inQuote)
|
||||
{
|
||||
endOfValue = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PhStringBuilderAppendChar(&stringBuilder, CommandLine->Buffer[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (endOfValue)
|
||||
@@ -3075,7 +3085,7 @@ PPH_STRING PhParseCommandLinePart(
|
||||
|
||||
BOOLEAN PhParseCommandLine(
|
||||
__in PPH_STRINGREF CommandLine,
|
||||
__in PPH_COMMAND_LINE_OPTION Options,
|
||||
__in_opt PPH_COMMAND_LINE_OPTION Options,
|
||||
__in ULONG NumberOfOptions,
|
||||
__in ULONG Flags,
|
||||
__in PPH_COMMAND_LINE_CALLBACK Callback,
|
||||
@@ -3092,8 +3102,6 @@ BOOLEAN PhParseCommandLine(
|
||||
PPH_COMMAND_LINE_OPTION option = NULL;
|
||||
PPH_STRING optionValue;
|
||||
|
||||
PPH_STRING mainArgumentValue = NULL;
|
||||
|
||||
if (CommandLine->Length == 0)
|
||||
return TRUE;
|
||||
|
||||
@@ -3178,51 +3186,93 @@ BOOLEAN PhParseCommandLine(
|
||||
}
|
||||
else
|
||||
{
|
||||
// If PH_COMMAND_LINE_CALLBACK_ALL_MAIN was not specified:
|
||||
// Value with no option. This becomes our "main argument".
|
||||
// If we had a previous "main argument", replace it with
|
||||
// this one.
|
||||
PPH_STRING value;
|
||||
|
||||
if (mainArgumentValue)
|
||||
PhDereferenceObject(mainArgumentValue);
|
||||
|
||||
mainArgumentValue = PhParseCommandLinePart(CommandLine, &i);
|
||||
value = PhParseCommandLinePart(CommandLine, &i);
|
||||
|
||||
if ((Flags & PH_COMMAND_LINE_IGNORE_FIRST_PART) && wasFirst)
|
||||
{
|
||||
if (mainArgumentValue)
|
||||
{
|
||||
PhDereferenceObject(mainArgumentValue);
|
||||
mainArgumentValue = NULL;
|
||||
}
|
||||
PhDereferenceObject(value);
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
if (Flags & PH_COMMAND_LINE_CALLBACK_ALL_MAIN)
|
||||
if (value)
|
||||
{
|
||||
// This makes PH_COMMAND_LINE_CALLBACK_ALL_MAIN cooperate with
|
||||
// PH_COMMAND_LINE_IGNORE_FIRST_PART.
|
||||
if (mainArgumentValue)
|
||||
{
|
||||
cont = Callback(NULL, mainArgumentValue, Context);
|
||||
PhDereferenceObject(mainArgumentValue);
|
||||
mainArgumentValue = NULL;
|
||||
cont = Callback(NULL, value, Context);
|
||||
PhDereferenceObject(value);
|
||||
|
||||
if (!cont)
|
||||
break;
|
||||
}
|
||||
if (!cont)
|
||||
break;
|
||||
}
|
||||
|
||||
wasFirst = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// If PH_COMMAND_LINE_CALLBACK_ALL_MAIN is enabled this won't run
|
||||
// because mainArgumentValue is set to NULL after processing.
|
||||
if (mainArgumentValue)
|
||||
{
|
||||
Callback(NULL, mainArgumentValue, Context);
|
||||
PhDereferenceObject(mainArgumentValue);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string for use in a command line.
|
||||
*
|
||||
* \param String The string to escape.
|
||||
*
|
||||
* \return The escaped string.
|
||||
*
|
||||
* \remarks Only the double quotation mark is escaped.
|
||||
*/
|
||||
PPH_STRING PhEscapeCommandLinePart(
|
||||
__in PPH_STRINGREF String
|
||||
)
|
||||
{
|
||||
static WCHAR backslashAndQuote[2] = { '\\', '\"' };
|
||||
|
||||
PPH_STRING string;
|
||||
PH_STRING_BUILDER stringBuilder;
|
||||
ULONG length;
|
||||
ULONG i;
|
||||
|
||||
ULONG numberOfBackslashes;
|
||||
|
||||
length = String->Length / 2;
|
||||
PhInitializeStringBuilder(&stringBuilder, String->Length / 2 * 3);
|
||||
numberOfBackslashes = 0;
|
||||
|
||||
// Simply replacing " with \" won't work here. See PhParseCommandLinePart
|
||||
// for the quoting rules.
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
switch (String->Buffer[i])
|
||||
{
|
||||
case '\\':
|
||||
numberOfBackslashes++;
|
||||
break;
|
||||
case '\"':
|
||||
if (numberOfBackslashes != 0)
|
||||
{
|
||||
PhStringBuilderAppendChar2(&stringBuilder, '\\', numberOfBackslashes * 2);
|
||||
numberOfBackslashes = 0;
|
||||
}
|
||||
|
||||
PhStringBuilderAppendEx(&stringBuilder, backslashAndQuote, sizeof(backslashAndQuote));
|
||||
|
||||
break;
|
||||
default:
|
||||
if (numberOfBackslashes != 0)
|
||||
{
|
||||
PhStringBuilderAppendChar2(&stringBuilder, '\\', numberOfBackslashes);
|
||||
numberOfBackslashes = 0;
|
||||
}
|
||||
|
||||
PhStringBuilderAppendChar(&stringBuilder, String->Buffer[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string = PhReferenceStringBuilderString(&stringBuilder);
|
||||
PhDeleteStringBuilder(&stringBuilder);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ int __cdecl main(int argc, char *argv[])
|
||||
&commandLine,
|
||||
options,
|
||||
sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
|
||||
PH_COMMAND_LINE_IGNORE_FIRST_PART | PH_COMMAND_LINE_CALLBACK_ALL_MAIN,
|
||||
PH_COMMAND_LINE_IGNORE_FIRST_PART,
|
||||
FiCommandLineCallback,
|
||||
NULL
|
||||
) || FiArgHelp)
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user