X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fbase%2Fsystem%2Fservices%2Frpcserver.c;h=4dea07affbcb43e90cce02512c5885c4b3113021;hp=a42bc8f4387cc387e7a8e580d0722bd9a883379e;hb=cd7c0bf1da818c4d86a5bd8cbb60ac03b6ab9f27;hpb=4ee63d0e0b546b44a10be3ef0cac469ce6200f14 diff --git a/reactos/base/system/services/rpcserver.c b/reactos/base/system/services/rpcserver.c index a42bc8f4387..4dea07affbc 100644 --- a/reactos/base/system/services/rpcserver.c +++ b/reactos/base/system/services/rpcserver.c @@ -4961,34 +4961,31 @@ DWORD RQueryServiceConfig2A( else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { LPSERVICE_FAILURE_ACTIONSA lpFailureActions = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer; - LPSTR lpStr; + LPSTR lpStr = NULL; /* Query value length */ - dwRequiredSize = 0; dwError = RegQueryValueExW(hServiceKey, L"FailureActions", NULL, &dwType, NULL, &dwRequiredSize); - if (dwError != ERROR_SUCCESS && dwError != ERROR_MORE_DATA) - goto done; - - if (dwType != REG_BINARY) - { - dwError = ERROR_UNSUPPORTED_TYPE; + if (dwError != ERROR_SUCCESS && + dwError != ERROR_MORE_DATA && + dwError != ERROR_FILE_NOT_FOUND) goto done; - } - dwRequiredSize = max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize); + dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSA), dwRequiredSize) + : sizeof(SERVICE_FAILURE_ACTIONSA); - dwError = ScmReadString(hServiceKey, - L"FailureCommand", - &lpFailureCommandW); + /* Get the strings */ + ScmReadString(hServiceKey, + L"FailureCommand", + &lpFailureCommandW); - dwError = ScmReadString(hServiceKey, - L"RebootMessage", - &lpRebootMessageW); + ScmReadString(hServiceKey, + L"RebootMessage", + &lpRebootMessageW); if (lpRebootMessageW) dwRequiredSize += (wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR); @@ -5004,26 +5001,32 @@ DWORD RQueryServiceConfig2A( } /* Now we can fill the buffer */ - dwError = RegQueryValueExW(hServiceKey, - L"FailureActions", - NULL, - NULL, - (LPBYTE)lpFailureActions, - &dwRequiredSize); - if (dwError != ERROR_SUCCESS) - goto done; + if (dwType == REG_BINARY) + { + dwError = RegQueryValueExW(hServiceKey, + 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 > cbBufSize)) + if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSA)) + dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSA); + } + else { - dwError = ERROR_BUFFER_OVERFLOW; - goto done; + dwError = ERROR_UNSUPPORTED_TYPE; } if (dwError == ERROR_SUCCESS) { - lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - FIELD_OFFSET(SERVICE_FAILURE_ACTIONSA, lpsaActions)) / sizeof(SC_ACTION)); - lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0) ? (LPSC_ACTION)(lpFailureActions + 1) : NULL; + lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSA)) / sizeof(SC_ACTION)); + + /* 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)); } else @@ -5182,34 +5185,31 @@ DWORD RQueryServiceConfig2W( else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer; - LPWSTR lpStr; + LPWSTR lpStr = NULL; /* Query value length */ - dwRequiredSize = 0; dwError = RegQueryValueExW(hServiceKey, L"FailureActions", NULL, &dwType, NULL, &dwRequiredSize); - if (dwError != ERROR_SUCCESS && dwError != ERROR_MORE_DATA) - goto done; - - if (dwType != REG_BINARY) - { - dwError = ERROR_UNSUPPORTED_TYPE; + if (dwError != ERROR_SUCCESS && + dwError != ERROR_MORE_DATA && + dwError != ERROR_FILE_NOT_FOUND) goto done; - } - dwRequiredSize = max(sizeof(SERVICE_FAILURE_ACTIONSW), dwRequiredSize); + dwRequiredSize = (dwType == REG_BINARY) ? max(sizeof(SERVICE_FAILURE_ACTIONSW), dwRequiredSize) + : sizeof(SERVICE_FAILURE_ACTIONSW); - dwError = ScmReadString(hServiceKey, - L"FailureCommand", - &lpFailureCommand); + /* Get the strings */ + ScmReadString(hServiceKey, + L"FailureCommand", + &lpFailureCommand); - dwError = ScmReadString(hServiceKey, - L"RebootMessage", - &lpRebootMessage); + ScmReadString(hServiceKey, + L"RebootMessage", + &lpRebootMessage); if (lpRebootMessage) dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR); @@ -5225,26 +5225,32 @@ DWORD RQueryServiceConfig2W( } /* Now we can fill the buffer */ - dwError = RegQueryValueExW(hServiceKey, - L"FailureActions", - NULL, - NULL, - (LPBYTE)lpFailureActions, - &dwRequiredSize); - if (dwError != ERROR_SUCCESS) - goto done; + if (dwType == REG_BINARY) + { + dwError = RegQueryValueExW(hServiceKey, + 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 > cbBufSize)) + if (dwRequiredSize < sizeof(SERVICE_FAILURE_ACTIONSW)) + dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSW); + } + else { - dwError = ERROR_BUFFER_OVERFLOW; - goto done; + dwError = ERROR_UNSUPPORTED_TYPE; } if (dwError == ERROR_SUCCESS) { - lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - FIELD_OFFSET(SERVICE_FAILURE_ACTIONSW, lpsaActions)) / sizeof(SC_ACTION)); - lpFailureActions->lpsaActions = (lpFailureActions->cActions > 0 ? (LPSC_ACTION)(lpFailureActions + 1) : NULL); + lpFailureActions->cActions = min(lpFailureActions->cActions, (dwRequiredSize - sizeof(SERVICE_FAILURE_ACTIONSW)) / sizeof(SC_ACTION)); + + /* 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)); } else