From: Eric Kohl Date: Sat, 24 Sep 2011 15:12:52 +0000 (+0000) Subject: [SMSS] X-Git-Tag: backups/icu4ros-bringup@60647~157 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=388f99e67e066892ffab49818f57011d474c1143 [SMSS] 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 --- diff --git a/reactos/base/system/smss/initrun.c b/reactos/base/system/smss/initrun.c index ff35e576a8f..e656bd22fa6 100644 --- a/reactos/base/system/smss/initrun.c +++ b/reactos/base/system/smss/initrun.c @@ -26,69 +26,161 @@ SmpRunBootAppsQueryRoutine(PWSTR ValueName, PVOID Context, PVOID EntryContext) { - WCHAR Description [MAX_PATH]; - WCHAR ImageName [MAX_PATH]; - WCHAR ImagePath [MAX_PATH]; - WCHAR CommandLine [MAX_PATH]; - PWSTR p1, p2; - ULONG len; - NTSTATUS Status; + PCWSTR DefaultPath = L"\\SystemRoot\\system32\\"; + PCWSTR DefaultExtension = L".exe"; + PWSTR ImageName = NULL; + PWSTR ImagePath = NULL; + PWSTR CommandLine = NULL; + PWSTR p1 = (PWSTR)ValueData; + 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("ValueData '%S'\n", (PWSTR)ValueData); + + if (ValueType != REG_SZ) + return STATUS_SUCCESS; + + /* Skip leading spaces */ + while (*p1 == L' ') + p1++; + + /* Get the next token */ + p2 = wcschr(p1, L' '); + if (p2 == NULL) + p2 = p1 + wcslen(p1); + len = p2 - p1; - DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength); - DPRINT("ValueData '%S'\n", (PWSTR)ValueData); + /* Check whether or not we have the 'autocheck' token */ + HasAutocheckToken = ((len == 9) && (_wcsnicmp(p1, L"autocheck", 9) == 0)); - if (ValueType != REG_SZ) + if (HasAutocheckToken) { - return(STATUS_SUCCESS); + /* 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; } - /* Extract the description */ - p1 = wcschr((PWSTR)ValueData, L' '); - len = p1 - (PWSTR)ValueData; - memcpy(Description,ValueData, len * sizeof(WCHAR)); - Description[len] = 0; + /* + * 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 */ - p1++; - p2 = wcschr(p1, L' '); - if (p2 != NULL) - len = p2 - p1; - else + /* 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); - memcpy(ImageName, p1, len * sizeof(WCHAR)); - ImageName[len] = 0; - /* Extract the command line */ - if (p2 == NULL) + /* Allocate the command line buffer */ + CommandLine = RtlAllocateHeap(SmpHeap, HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR)); + if (CommandLine == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Done; + } + + /* Extract the command line. */ + memmove(CommandLine, p1, len * sizeof(WCHAR)); + + /* Determine the image path length */ + HasDefaultPath = (_wcsnicmp(ImageName, DefaultPath, wcslen(DefaultPath)) == 0); + HasNoExtension = (wcsrchr(ImageName, L'.') == NULL); + + len = wcslen(ImageName); + + if (!HasDefaultPath) + len += wcslen(DefaultPath); + + if (HasNoExtension) + len += wcslen(DefaultExtension); + + /* Allocate the image path buffer */ + ImagePath = RtlAllocateHeap(SmpHeap, HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR)); + if (ImagePath == NULL) { - CommandLine[0] = 0; + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Done; } - else + + /* Build the image path */ + if (HasDefaultPath) { - p2++; - wcscpy(CommandLine, p2); + wcscpy(ImagePath, ImageName); + } + else + { + wcscpy(ImagePath, DefaultPath); + wcscat(ImagePath, ImageName); } - DPRINT("Running %S...\n", Description); - DPRINT("ImageName: '%S'\n", ImageName); - DPRINT("CommandLine: '%S'\n", CommandLine); + if (HasNoExtension) + wcscat(ImagePath, DefaultExtension); - /* initialize executable path */ - wcscpy(ImagePath, L"\\SystemRoot\\system32\\"); - wcscat(ImagePath, ImageName); - wcscat(ImagePath, L".exe"); + 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__, ImagePath, Status); - } - return(STATUS_SUCCESS); + /* 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; }