Fix wrong behavior of the "native applications startup at boot time" feature in SMSS.

Modifications:
- Added missing buffer allocation checks.
- Check for presence of default path.
- Minor clean-ups.
- Fix bad indentation/coding style.

Original patch by Hermès BÉLUSCA.
See issue #6180 for more details.

svn path=/trunk/; revision=53839
This commit is contained in:
Eric Kohl 2011-09-24 15:12:52 +00:00
parent adaa2b8e63
commit 388f99e67e

View file

@ -26,69 +26,161 @@ SmpRunBootAppsQueryRoutine(PWSTR ValueName,
PVOID Context, PVOID Context,
PVOID EntryContext) PVOID EntryContext)
{ {
WCHAR Description [MAX_PATH]; PCWSTR DefaultPath = L"\\SystemRoot\\system32\\";
WCHAR ImageName [MAX_PATH]; PCWSTR DefaultExtension = L".exe";
WCHAR ImagePath [MAX_PATH]; PWSTR ImageName = NULL;
WCHAR CommandLine [MAX_PATH]; PWSTR ImagePath = NULL;
PWSTR p1, p2; PWSTR CommandLine = NULL;
ULONG len; PWSTR p1 = (PWSTR)ValueData;
NTSTATUS Status; PWSTR p2 = (PWSTR)ValueData;
ULONG len = 0;
BOOLEAN HasAutocheckToken;
BOOLEAN HasNoExtension;
BOOLEAN HasDefaultPath;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength); DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
DPRINT("ValueData '%S'\n", (PWSTR)ValueData); DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
if (ValueType != REG_SZ) if (ValueType != REG_SZ)
{ return STATUS_SUCCESS;
return(STATUS_SUCCESS);
}
/* Extract the description */ /* Skip leading spaces */
p1 = wcschr((PWSTR)ValueData, L' '); while (*p1 == L' ')
len = p1 - (PWSTR)ValueData; p1++;
memcpy(Description,ValueData, len * sizeof(WCHAR));
Description[len] = 0;
/* Extract the image name */ /* Get the next token */
p1++; p2 = wcschr(p1, L' ');
p2 = wcschr(p1, L' '); if (p2 == NULL)
if (p2 != NULL) p2 = p1 + wcslen(p1);
len = p2 - p1; len = p2 - p1;
else
/* Check whether or not we have the 'autocheck' token */
HasAutocheckToken = ((len == 9) && (_wcsnicmp(p1, L"autocheck", 9) == 0));
if (HasAutocheckToken)
{
/* Skip the current (autocheck) token */
p1 = p2;
/* Skip spaces */
while (*p1 == L' ')
p1++;
/* Get the next token */
p2 = wcschr(p1, L' ');
if (p2 == NULL)
p2 = p1 + wcslen(p1);
len = p2 - p1;
}
/*
* Now, p1-->p2 is the image name and len is its length.
* If the image name is "" (empty string), then we stop
* here, we don't execute anything and return STATUS_SUCCESS.
*/
if (len == 0)
return STATUS_SUCCESS;
/* Allocate the image name buffer */
ImageName = RtlAllocateHeap(SmpHeap, HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR));
if (ImageName == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Done;
}
/* Extract the image name */
memmove(ImageName, p1, len * sizeof(WCHAR));
/* Skip the current token */
p1 = p2;
/* Skip spaces */
while (*p1 == L' ')
p1++;
/* Get the length of the command line */
len = wcslen(p1); len = wcslen(p1);
memcpy(ImageName, p1, len * sizeof(WCHAR));
ImageName[len] = 0;
/* Extract the command line */ /* Allocate the command line buffer */
if (p2 == NULL) CommandLine = RtlAllocateHeap(SmpHeap, HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR));
if (CommandLine == NULL)
{ {
CommandLine[0] = 0; Status = STATUS_INSUFFICIENT_RESOURCES;
} goto Done;
else
{
p2++;
wcscpy(CommandLine, p2);
} }
DPRINT("Running %S...\n", Description); /* Extract the command line. */
DPRINT("ImageName: '%S'\n", ImageName); memmove(CommandLine, p1, len * sizeof(WCHAR));
DPRINT("CommandLine: '%S'\n", CommandLine);
/* initialize executable path */ /* Determine the image path length */
wcscpy(ImagePath, L"\\SystemRoot\\system32\\"); HasDefaultPath = (_wcsnicmp(ImageName, DefaultPath, wcslen(DefaultPath)) == 0);
wcscat(ImagePath, ImageName); HasNoExtension = (wcsrchr(ImageName, L'.') == NULL);
wcscat(ImagePath, L".exe");
/* Create NT process */ len = wcslen(ImageName);
Status = SmCreateUserProcess (ImagePath,
CommandLine, if (!HasDefaultPath)
SM_CREATE_FLAG_WAIT, len += wcslen(DefaultPath);
NULL, NULL);
if (!NT_SUCCESS(Status)) if (HasNoExtension)
{ len += wcslen(DefaultExtension);
DPRINT1("SM: %s: running '%S' failed (Status=0x%08lx)\n",
__FUNCTION__, ImagePath, Status); /* Allocate the image path buffer */
} ImagePath = RtlAllocateHeap(SmpHeap, HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR));
return(STATUS_SUCCESS); if (ImagePath == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Done;
}
/* Build the image path */
if (HasDefaultPath)
{
wcscpy(ImagePath, ImageName);
}
else
{
wcscpy(ImagePath, DefaultPath);
wcscat(ImagePath, ImageName);
}
if (HasNoExtension)
wcscat(ImagePath, DefaultExtension);
DPRINT("ImageName : '%S'\n", ImageName);
DPRINT("ImagePath : '%S'\n", ImagePath);
DPRINT("CommandLine: '%S'\n", CommandLine);
/* Create NT process */
Status = SmCreateUserProcess(ImagePath,
CommandLine,
SM_CREATE_FLAG_WAIT,
NULL, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: running '%S' failed (Status=0x%08lx)\n",
__FUNCTION__, ImageName, Status);
if (HasAutocheckToken)
PrintString("%S program not found - skipping AUTOCHECK\n", ImageName);
/* No need to return an error */
Status = STATUS_SUCCESS;
}
Done:
/* Free the buffers */
if (ImagePath != NULL)
RtlFreeHeap(SmpHeap, 0, ImagePath);
if (CommandLine != NULL)
RtlFreeHeap(SmpHeap, 0, CommandLine);
if (ImageName != NULL)
RtlFreeHeap(SmpHeap, 0, ImageName);
return Status;
} }