mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 23:48:12 +00:00
[SERVICES]
This new patch corrects bugs introduced in the implementation of SERVICE_CONFIG_FAILURE_ACTIONS case in RQueryServiceConfig2W() and RQueryServiceConfig2A(). Patch by Hermès Bélusca. See issue #7101 for more details. svn path=/trunk/; revision=56725
This commit is contained in:
parent
4ee63d0e0b
commit
cd7c0bf1da
1 changed files with 68 additions and 62 deletions
|
@ -4961,34 +4961,31 @@ DWORD RQueryServiceConfig2A(
|
||||||
else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||||
{
|
{
|
||||||
LPSERVICE_FAILURE_ACTIONSA lpFailureActions = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
|
LPSERVICE_FAILURE_ACTIONSA lpFailureActions = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer;
|
||||||
LPSTR lpStr;
|
LPSTR lpStr = NULL;
|
||||||
|
|
||||||
/* Query value length */
|
/* Query value length */
|
||||||
dwRequiredSize = 0;
|
|
||||||
dwError = RegQueryValueExW(hServiceKey,
|
dwError = RegQueryValueExW(hServiceKey,
|
||||||
L"FailureActions",
|
L"FailureActions",
|
||||||
NULL,
|
NULL,
|
||||||
&dwType,
|
&dwType,
|
||||||
NULL,
|
NULL,
|
||||||
&dwRequiredSize);
|
&dwRequiredSize);
|
||||||
if (dwError != ERROR_SUCCESS && dwError != ERROR_MORE_DATA)
|
if (dwError != ERROR_SUCCESS &&
|
||||||
|
dwError != ERROR_MORE_DATA &&
|
||||||
|
dwError != ERROR_FILE_NOT_FOUND)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (dwType != REG_BINARY)
|
dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize)
|
||||||
{
|
: sizeof(SERVICE_FAILURE_ACTIONSA);
|
||||||
dwError = ERROR_UNSUPPORTED_TYPE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwRequiredSize = max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize);
|
/* Get the strings */
|
||||||
|
ScmReadString(hServiceKey,
|
||||||
|
L"FailureCommand",
|
||||||
|
&lpFailureCommandW);
|
||||||
|
|
||||||
dwError = ScmReadString(hServiceKey,
|
ScmReadString(hServiceKey,
|
||||||
L"FailureCommand",
|
L"RebootMessage",
|
||||||
&lpFailureCommandW);
|
&lpRebootMessageW);
|
||||||
|
|
||||||
dwError = ScmReadString(hServiceKey,
|
|
||||||
L"RebootMessage",
|
|
||||||
&lpRebootMessageW);
|
|
||||||
|
|
||||||
if (lpRebootMessageW)
|
if (lpRebootMessageW)
|
||||||
dwRequiredSize += (wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR);
|
dwRequiredSize += (wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR);
|
||||||
|
@ -5004,26 +5001,32 @@ DWORD RQueryServiceConfig2A(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we can fill the buffer */
|
/* Now we can fill the buffer */
|
||||||
dwError = RegQueryValueExW(hServiceKey,
|
if (dwType == REG_BINARY)
|
||||||
L"FailureActions",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
(LPBYTE)lpFailureActions,
|
|
||||||
&dwRequiredSize);
|
|
||||||
if (dwError != ERROR_SUCCESS)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if ((dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSA)) ||
|
|
||||||
(dwRequiredSize > cbBufSize))
|
|
||||||
{
|
{
|
||||||
dwError = ERROR_BUFFER_OVERFLOW;
|
dwError = RegQueryValueExW(hServiceKey,
|
||||||
goto done;
|
L"FailureActions",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(LPBYTE)lpFailureActions,
|
||||||
|
&dwRequiredSize);
|
||||||
|
if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSA))
|
||||||
|
dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSA);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwError = ERROR_UNSUPPORTED_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwError == ERROR_SUCCESS)
|
if (dwError == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - FIELD_OFFSET(SERVICE_FAILURE_ACTIONSA, lpsaActions)) / sizeof(SC_ACTION));
|
lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSA)) / sizeof(SC_ACTION));
|
||||||
lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0) ? (LPSC_ACTION)(lpFailureActions + 1) : NULL;
|
|
||||||
|
/* Here lpFailureActions->lpsaActions contains an offset. The conversion is done by the caller. */
|
||||||
|
lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(ULONG_PTR)sizeof(SERVICE_FAILURE_ACTIONSA) : NULL);
|
||||||
|
|
||||||
lpStr = (LPSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
|
lpStr = (LPSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5182,34 +5185,31 @@ DWORD RQueryServiceConfig2W(
|
||||||
else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||||
{
|
{
|
||||||
LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
|
LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
|
||||||
LPWSTR lpStr;
|
LPWSTR lpStr = NULL;
|
||||||
|
|
||||||
/* Query value length */
|
/* Query value length */
|
||||||
dwRequiredSize = 0;
|
|
||||||
dwError = RegQueryValueExW(hServiceKey,
|
dwError = RegQueryValueExW(hServiceKey,
|
||||||
L"FailureActions",
|
L"FailureActions",
|
||||||
NULL,
|
NULL,
|
||||||
&dwType,
|
&dwType,
|
||||||
NULL,
|
NULL,
|
||||||
&dwRequiredSize);
|
&dwRequiredSize);
|
||||||
if (dwError != ERROR_SUCCESS && dwError != ERROR_MORE_DATA)
|
if (dwError != ERROR_SUCCESS &&
|
||||||
|
dwError != ERROR_MORE_DATA &&
|
||||||
|
dwError != ERROR_FILE_NOT_FOUND)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (dwType != REG_BINARY)
|
dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSW), dwRequiredSize)
|
||||||
{
|
: sizeof(SERVICE_FAILURE_ACTIONSW);
|
||||||
dwError = ERROR_UNSUPPORTED_TYPE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dwRequiredSize = max(sizeof(SERVICE_FAILURE_ACTIONSW), dwRequiredSize);
|
/* Get the strings */
|
||||||
|
ScmReadString(hServiceKey,
|
||||||
|
L"FailureCommand",
|
||||||
|
&lpFailureCommand);
|
||||||
|
|
||||||
dwError = ScmReadString(hServiceKey,
|
ScmReadString(hServiceKey,
|
||||||
L"FailureCommand",
|
L"RebootMessage",
|
||||||
&lpFailureCommand);
|
&lpRebootMessage);
|
||||||
|
|
||||||
dwError = ScmReadString(hServiceKey,
|
|
||||||
L"RebootMessage",
|
|
||||||
&lpRebootMessage);
|
|
||||||
|
|
||||||
if (lpRebootMessage)
|
if (lpRebootMessage)
|
||||||
dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR);
|
dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR);
|
||||||
|
@ -5225,26 +5225,32 @@ DWORD RQueryServiceConfig2W(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we can fill the buffer */
|
/* Now we can fill the buffer */
|
||||||
dwError = RegQueryValueExW(hServiceKey,
|
if (dwType == REG_BINARY)
|
||||||
L"FailureActions",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
(LPBYTE)lpFailureActions,
|
|
||||||
&dwRequiredSize);
|
|
||||||
if (dwError != ERROR_SUCCESS)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if ((dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSW)) ||
|
|
||||||
(dwRequiredSize > cbBufSize))
|
|
||||||
{
|
{
|
||||||
dwError = ERROR_BUFFER_OVERFLOW;
|
dwError = RegQueryValueExW(hServiceKey,
|
||||||
goto done;
|
L"FailureActions",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(LPBYTE)lpFailureActions,
|
||||||
|
&dwRequiredSize);
|
||||||
|
if (dwError != ERROR_SUCCESS && dwError != ERROR_FILE_NOT_FOUND)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSW))
|
||||||
|
dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwError = ERROR_UNSUPPORTED_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwError == ERROR_SUCCESS)
|
if (dwError == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - FIELD_OFFSET(SERVICE_FAILURE_ACTIONSW, lpsaActions)) / sizeof(SC_ACTION));
|
lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSW)) / sizeof(SC_ACTION));
|
||||||
lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(lpFailureActions + 1) : NULL);
|
|
||||||
|
/* Here lpFailureActions->lpsaActions contains an offset. The conversion is done by the caller. */
|
||||||
|
lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(ULONG_PTR)sizeof(SERVICE_FAILURE_ACTIONSW) : NULL);
|
||||||
|
|
||||||
lpStr = (LPWSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
|
lpStr = (LPWSTR)((ULONG_PTR)(lpFailureActions + 1) + lpFailureActions->cActions * sizeof(SC_ACTION));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue