mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[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:
parent
ccf756f902
commit
f6762917ee
1 changed files with 78 additions and 22 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue