[SERVICES]

... and for 61001st commit: Fix the ANSI version of the server-side of ChangeServiceConfig2A API, which broke at converting SERVICE_FAILURE_ACTIONS ANSI structures into UNICODE ones.
Fixes the VMWare Tools Installer; blame Sylvain if it doesn't ;)
Based on a patch by Sylvain Petreolle.
CORE-7539 #comment Fixed in revision 61001, thanks !

svn path=/trunk/; revision=61001
This commit is contained in:
Hermès Bélusca-Maïto 2013-11-15 21:03:01 +00:00
parent ccf756f902
commit f6762917ee

View file

@ -4712,9 +4712,6 @@ Done:
}
//
// WARNING: This function is untested
//
/* Function 36 */
DWORD RChangeServiceConfig2A(
SC_RPC_HANDLE hService,
@ -4731,48 +4728,57 @@ DWORD RChangeServiceConfig2A(
if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
{
LPSERVICE_DESCRIPTIONW lpServiceDescriptonW;
//LPSERVICE_DESCRIPTIONA lpServiceDescriptonA;
LPSERVICE_DESCRIPTIONW lpServiceDescriptionW;
//LPSERVICE_DESCRIPTIONA lpServiceDescriptionA;
//lpServiceDescriptonA = Info.psd;
//lpServiceDescriptionA = Info.psd;
///if (lpServiceDescriptonA &&
///lpServiceDescriptonA->lpDescription)
///if (lpServiceDescriptionA &&
///lpServiceDescriptionA->lpDescription)
///{
dwLength = (DWORD)((strlen(Info.lpDescription) + 1) * sizeof(WCHAR));
lpServiceDescriptonW = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwLength + sizeof(SERVICE_DESCRIPTIONW));
if (!lpServiceDescriptonW)
lpServiceDescriptionW = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwLength + sizeof(SERVICE_DESCRIPTIONW));
if (!lpServiceDescriptionW)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1);
lpServiceDescriptionW->lpDescription = (LPWSTR)(lpServiceDescriptionW + 1);
MultiByteToWideChar(CP_ACP,
0,
Info.lpDescription,
-1,
lpServiceDescriptonW->lpDescription,
lpServiceDescriptionW->lpDescription,
dwLength);
ptr = lpServiceDescriptonW;
InfoW.psd = lpServiceDescriptonW;
ptr = lpServiceDescriptionW;
InfoW.psd = lpServiceDescriptionW;
///}
}
else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
{
LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
DWORD dwRebootLen = 0;
DWORD dwRebootLen = 0;
DWORD dwCommandLen = 0;
DWORD dwActionArrayLen = 0;
LPWSTR lpStr = NULL;
lpServiceFailureActionsA = Info.psfa;
if (lpServiceFailureActionsA)
{
/*
* The following code is inspired by the
* SERVICE_CONFIG_FAILURE_ACTIONS case of
* the RQueryServiceConfig2W function.
*/
/* Retrieve the needed length for the two data strings */
if (lpServiceFailureActionsA->lpRebootMsg)
{
dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
@ -4781,8 +4787,22 @@ DWORD RChangeServiceConfig2A(
{
dwCommandLen = (DWORD)((strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR));
}
dwLength = dwRebootLen + dwCommandLen + sizeof(SERVICE_FAILURE_ACTIONSW);
/*
* Retrieve the size of the lpsaActions array if needed.
* We will copy the lpsaActions array only if there is at
* least one action AND that the original array is valid.
*/
if (lpServiceFailureActionsA->cActions > 0 && lpServiceFailureActionsA->lpsaActions)
{
dwActionArrayLen = lpServiceFailureActionsA->cActions * sizeof(SC_ACTION);
}
/* Compute the total length for the UNICODE structure, including data */
dwLength = sizeof(SERVICE_FAILURE_ACTIONSW) +
dwActionArrayLen + dwRebootLen + dwCommandLen;
/* Allocate the structure */
lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
dwLength);
@ -4791,22 +4811,56 @@ DWORD RChangeServiceConfig2A(
return ERROR_NOT_ENOUGH_MEMORY;
}
lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
/* Copy the members */
lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
CopyMemory(lpServiceFailureActionsW->lpsaActions, lpServiceFailureActionsA->lpsaActions, sizeof(SC_ACTION));
lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
if (lpServiceFailureActionsA->lpRebootMsg)
/* Copy the lpsaActions array if needed */
if (dwActionArrayLen > 0)
{
/* The storage zone is just after the end of the SERVICE_FAILURE_ACTIONSW structure */
lpServiceFailureActionsW->lpsaActions = (LPSC_ACTION)((ULONG_PTR)(lpServiceFailureActionsW + 1));
/* dwActionArrayLen == lpServiceFailureActionsW->cActions * sizeof(SC_ACTION) */
RtlCopyMemory(lpServiceFailureActionsW->lpsaActions,
lpServiceFailureActionsA->lpsaActions,
dwActionArrayLen);
}
else
{
/* No lpsaActions array */
lpServiceFailureActionsW->lpsaActions = NULL;
}
/* The data strings are stored just after the lpsaActions array */
lpStr = (LPWSTR)((ULONG_PTR)(lpServiceFailureActionsW + 1) + dwActionArrayLen);
/*
* Convert the data strings to UNICODE
*/
lpServiceFailureActionsW->lpRebootMsg = NULL;
lpServiceFailureActionsW->lpCommand = NULL;
if (dwRebootLen)
{
/* lpRebootMsg points just after the lpsaActions array */
lpServiceFailureActionsW->lpRebootMsg = lpStr;
MultiByteToWideChar(CP_ACP,
0,
lpServiceFailureActionsA->lpRebootMsg,
-1,
lpServiceFailureActionsW->lpRebootMsg,
dwRebootLen);
lpStr += dwRebootLen / sizeof(WCHAR);
}
if (lpServiceFailureActionsA->lpCommand)
if (dwCommandLen)
{
/* lpRebootMsg points just after the lpRebootMsg data string */
lpServiceFailureActionsW->lpCommand = lpStr;
MultiByteToWideChar(CP_ACP,
0,
lpServiceFailureActionsA->lpCommand,
@ -4815,7 +4869,9 @@ DWORD RChangeServiceConfig2A(
dwCommandLen);
}
/* Set the pointers */
ptr = lpServiceFailureActionsW;
InfoW.psfa = lpServiceFailureActionsW;
}
}