mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:32:56 +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 */
|
/* Function 36 */
|
||||||
DWORD RChangeServiceConfig2A(
|
DWORD RChangeServiceConfig2A(
|
||||||
SC_RPC_HANDLE hService,
|
SC_RPC_HANDLE hService,
|
||||||
|
@ -4731,48 +4728,57 @@ DWORD RChangeServiceConfig2A(
|
||||||
|
|
||||||
if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
|
if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
|
||||||
{
|
{
|
||||||
LPSERVICE_DESCRIPTIONW lpServiceDescriptonW;
|
LPSERVICE_DESCRIPTIONW lpServiceDescriptionW;
|
||||||
//LPSERVICE_DESCRIPTIONA lpServiceDescriptonA;
|
//LPSERVICE_DESCRIPTIONA lpServiceDescriptionA;
|
||||||
|
|
||||||
//lpServiceDescriptonA = Info.psd;
|
//lpServiceDescriptionA = Info.psd;
|
||||||
|
|
||||||
///if (lpServiceDescriptonA &&
|
///if (lpServiceDescriptionA &&
|
||||||
///lpServiceDescriptonA->lpDescription)
|
///lpServiceDescriptionA->lpDescription)
|
||||||
///{
|
///{
|
||||||
dwLength = (DWORD)((strlen(Info.lpDescription) + 1) * sizeof(WCHAR));
|
dwLength = (DWORD)((strlen(Info.lpDescription) + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
lpServiceDescriptonW = HeapAlloc(GetProcessHeap(),
|
lpServiceDescriptionW = HeapAlloc(GetProcessHeap(),
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
dwLength + sizeof(SERVICE_DESCRIPTIONW));
|
dwLength + sizeof(SERVICE_DESCRIPTIONW));
|
||||||
if (!lpServiceDescriptonW)
|
if (!lpServiceDescriptionW)
|
||||||
{
|
{
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1);
|
lpServiceDescriptionW->lpDescription = (LPWSTR)(lpServiceDescriptionW + 1);
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP,
|
MultiByteToWideChar(CP_ACP,
|
||||||
0,
|
0,
|
||||||
Info.lpDescription,
|
Info.lpDescription,
|
||||||
-1,
|
-1,
|
||||||
lpServiceDescriptonW->lpDescription,
|
lpServiceDescriptionW->lpDescription,
|
||||||
dwLength);
|
dwLength);
|
||||||
|
|
||||||
ptr = lpServiceDescriptonW;
|
ptr = lpServiceDescriptionW;
|
||||||
InfoW.psd = lpServiceDescriptonW;
|
InfoW.psd = lpServiceDescriptionW;
|
||||||
///}
|
///}
|
||||||
}
|
}
|
||||||
else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||||
{
|
{
|
||||||
LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
|
LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
|
||||||
LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
|
LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
|
||||||
DWORD dwRebootLen = 0;
|
DWORD dwRebootLen = 0;
|
||||||
DWORD dwCommandLen = 0;
|
DWORD dwCommandLen = 0;
|
||||||
|
DWORD dwActionArrayLen = 0;
|
||||||
|
LPWSTR lpStr = NULL;
|
||||||
|
|
||||||
lpServiceFailureActionsA = Info.psfa;
|
lpServiceFailureActionsA = Info.psfa;
|
||||||
|
|
||||||
if (lpServiceFailureActionsA)
|
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)
|
if (lpServiceFailureActionsA->lpRebootMsg)
|
||||||
{
|
{
|
||||||
dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
|
dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
|
||||||
|
@ -4781,8 +4787,22 @@ DWORD RChangeServiceConfig2A(
|
||||||
{
|
{
|
||||||
dwCommandLen = (DWORD)((strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR));
|
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(),
|
lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
dwLength);
|
dwLength);
|
||||||
|
@ -4791,22 +4811,56 @@ DWORD RChangeServiceConfig2A(
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
|
/* Copy the members */
|
||||||
lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
|
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,
|
MultiByteToWideChar(CP_ACP,
|
||||||
0,
|
0,
|
||||||
lpServiceFailureActionsA->lpRebootMsg,
|
lpServiceFailureActionsA->lpRebootMsg,
|
||||||
-1,
|
-1,
|
||||||
lpServiceFailureActionsW->lpRebootMsg,
|
lpServiceFailureActionsW->lpRebootMsg,
|
||||||
dwRebootLen);
|
dwRebootLen);
|
||||||
|
|
||||||
|
lpStr += dwRebootLen / sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpServiceFailureActionsA->lpCommand)
|
if (dwCommandLen)
|
||||||
{
|
{
|
||||||
|
/* lpRebootMsg points just after the lpRebootMsg data string */
|
||||||
|
lpServiceFailureActionsW->lpCommand = lpStr;
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP,
|
MultiByteToWideChar(CP_ACP,
|
||||||
0,
|
0,
|
||||||
lpServiceFailureActionsA->lpCommand,
|
lpServiceFailureActionsA->lpCommand,
|
||||||
|
@ -4815,7 +4869,9 @@ DWORD RChangeServiceConfig2A(
|
||||||
dwCommandLen);
|
dwCommandLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the pointers */
|
||||||
ptr = lpServiceFailureActionsW;
|
ptr = lpServiceFailureActionsW;
|
||||||
|
InfoW.psfa = lpServiceFailureActionsW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue