Index: base/system/services/rpcserver.c =================================================================== --- base/system/services/rpcserver.c (révision 56717) +++ base/system/services/rpcserver.c (copie de travail) @@ -4869,11 +4869,9 @@ LPBOUNDED_DWORD_8K pcbBytesNeeded) { DWORD dwError = ERROR_SUCCESS; - PSERVICE_HANDLE hSvc; + PSERVICE_HANDLE hSvc = NULL; PSERVICE lpService = NULL; HKEY hServiceKey = NULL; - DWORD dwRequiredSize = 0; - DWORD dwType = 0; LPWSTR lpDescriptionW = NULL; LPWSTR lpRebootMessageW = NULL; LPWSTR lpFailureCommandW = NULL; @@ -4920,7 +4918,7 @@ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) { LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer; - LPSTR lpStr; + LPSTR lpStr = NULL; dwError = ScmReadString(hServiceKey, L"Description", @@ -4961,34 +4959,35 @@ else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { LPSERVICE_FAILURE_ACTIONSA lpFailureActions = (LPSERVICE_FAILURE_ACTIONSA)lpBuffer; - LPSTR lpStr; + DWORD dwRequiredSize = 0; + DWORD dwType = 0; + 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) + if ( dwError != ERROR_SUCCESS && + dwError != ERROR_MORE_DATA && + dwError != ERROR_FILE_NOT_FOUND ) { - dwError = ERROR_UNSUPPORTED_TYPE; 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"RebootMessage", + &lpRebootMessageW); - dwError = ScmReadString(hServiceKey, - L"RebootMessage", - &lpRebootMessageW); + ScmReadString(hServiceKey, + L"FailureCommand", + &lpFailureCommandW); if (lpRebootMessageW) dwRequiredSize += (wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR); @@ -5004,38 +5003,44 @@ } /* 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)); + + /* lpFailureActions->lpsaActions contains here the offset. The conversion is done on the client-side */ + 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 { lpFailureActions->dwResetPeriod = 0; - lpFailureActions->cActions = 0; - lpFailureActions->lpsaActions = NULL; + lpFailureActions->cActions = 0; + lpFailureActions->lpsaActions = NULL; lpStr = (LPSTR)(lpFailureActions + 1); } lpFailureActions->lpRebootMsg = NULL; - lpFailureActions->lpCommand = NULL; + lpFailureActions->lpCommand = NULL; if (lpRebootMessageW) { @@ -5099,11 +5104,9 @@ LPBOUNDED_DWORD_8K pcbBytesNeeded) { DWORD dwError = ERROR_SUCCESS; - PSERVICE_HANDLE hSvc; + PSERVICE_HANDLE hSvc = NULL; PSERVICE lpService = NULL; HKEY hServiceKey = NULL; - DWORD dwRequiredSize = 0; - DWORD dwType = 0; LPWSTR lpDescription = NULL; LPWSTR lpRebootMessage = NULL; LPWSTR lpFailureCommand = NULL; @@ -5149,7 +5152,7 @@ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) { LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer; - LPWSTR lpStr; + LPWSTR lpStr = NULL; dwError = ScmReadString(hServiceKey, L"Description", @@ -5182,34 +5185,35 @@ else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS) { LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer; - LPWSTR lpStr; + DWORD dwRequiredSize = 0; + DWORD dwType = 0; + 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) + if ( dwError != ERROR_SUCCESS && + dwError != ERROR_MORE_DATA && + dwError != ERROR_FILE_NOT_FOUND ) { - dwError = ERROR_UNSUPPORTED_TYPE; 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"RebootMessage", + &lpRebootMessage); - dwError = ScmReadString(hServiceKey, - L"RebootMessage", - &lpRebootMessage); + ScmReadString(hServiceKey, + L"FailureCommand", + &lpFailureCommand); if (lpRebootMessage) dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR); @@ -5225,33 +5229,39 @@ } /* 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)); + + /* lpFailureActions->lpsaActions contains here the offset. The conversion is done on the client-side */ + 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 { lpFailureActions->dwResetPeriod = 0; - lpFailureActions->cActions = 0; - lpFailureActions->lpsaActions = NULL; + lpFailureActions->cActions = 0; + lpFailureActions->lpsaActions = NULL; lpStr = (LPWSTR)(lpFailureActions + 1); }