[SERVMAN]

- Make a copy of the service list where service and display name strings are separately allocated. We need this to update the service names rather than reload the list when the display name is changed.
- Write the display name, description or binary path to the registry when the user changed them.
- Disable the Edit button after it has been clicked.
- Do not add the service name to the argument vector in the call to StartServiceW. Services.exe already add the service name to the vector.
CORE-12743

svn path=/trunk/; revision=74394
This commit is contained in:
Eric Kohl 2017-04-23 17:39:26 +00:00
parent ceaed9f1ec
commit f83d61cce0
6 changed files with 201 additions and 75 deletions

View file

@ -248,7 +248,6 @@ RefreshServiceList(PMAIN_WND_INFO Info)
{
ENUM_SERVICE_STATUS_PROCESS *pService;
LVITEMW lvItem;
DWORD NumServices;
DWORD Index;
SendMessage (Info->hListView,
@ -258,9 +257,9 @@ RefreshServiceList(PMAIN_WND_INFO Info)
(void)ListView_DeleteAllItems(Info->hListView);
if (GetServiceList(Info, &NumServices))
if (GetServiceList(Info))
{
for (Index = 0; Index < NumServices; Index++)
for (Index = 0; Index < Info->NumServices; Index++)
{
INT i;

View file

@ -880,10 +880,7 @@ MainWndProc(HWND hwnd,
case WM_CLOSE:
{
HeapFree(ProcessHeap,
0,
Info->pAllServices);
FreeServiceList(Info);
DestroyMenu(Info->hShortcutMenu);
DestroyWindow(hwnd);
}

View file

@ -54,6 +54,7 @@ typedef struct _MAIN_WND_INFO
ENUM_SERVICE_STATUS_PROCESS *pAllServices;
ENUM_SERVICE_STATUS_PROCESS *pCurrentService;
DWORD NumServices;
INT SelectedItem;/* selection number in the list view */
INT SortSelection;
@ -115,9 +116,10 @@ BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPWSTR lpServiceNam
LPWSTR GetServiceDescription(LPWSTR lpServiceName);
BOOL SetServiceDescription(LPWSTR lpServiceName, LPWSTR lpDescription);
LPWSTR GetExecutablePath(LPWSTR lpServiceName);
VOID FreeServiceList(PMAIN_WND_INFO Info);
BOOL RefreshServiceList(PMAIN_WND_INFO Info);
BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService);
BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices);
BOOL GetServiceList(PMAIN_WND_INFO Info);
/* propsheet.c */

View file

@ -13,7 +13,10 @@
typedef struct _PAGEDATA
{
PSERVICEPROPSHEET dlgInfo;
BOOL bPageChanged;
BOOL bDisplayNameChanged;
BOOL bDescriptionChanged;
BOOL bBinaryPathChanged;
BOOL bStartTypeChanged;
} PAGEDATA, *PPAGEDATA;
@ -53,11 +56,11 @@ SetButtonStates(PSERVICEPROPSHEET dlgInfo,
EnableWindow (hButton, TRUE);
}
if(lpServiceConfig)
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
hButton = GetDlgItem(hwndDlg, IDC_START_PARAM);
EnableWindow(hButton, (State == SERVICE_STOPPED));
EnableWindow(hButton, (State == SERVICE_STOPPED && lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED));
if (lpServiceConfig)
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
/* set the main toolbar */
SetMenuAndButtonStates(dlgInfo->Info);
@ -210,11 +213,13 @@ InitGeneralPage(PSERVICEPROPSHEET dlgInfo,
}
VOID
SaveDlgInfo(PSERVICEPROPSHEET dlgInfo,
SaveDlgInfo(PPAGEDATA pPageData,
HWND hwndDlg)
{
LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
HWND hList;
PWSTR pDisplayName = NULL;
PWSTR pDescription;
INT nLength;
DWORD StartUp;
pServiceConfig = HeapAlloc(ProcessHeap,
@ -224,31 +229,93 @@ SaveDlgInfo(PSERVICEPROPSHEET dlgInfo,
{
pServiceConfig->dwServiceType = SERVICE_NO_CHANGE;
pServiceConfig->dwErrorControl = SERVICE_NO_CHANGE;
pServiceConfig->dwStartType = SERVICE_NO_CHANGE;
hList = GetDlgItem(hwndDlg, IDC_START_TYPE);
StartUp = SendMessage(hList,
CB_GETCURSEL,
0,
0);
switch (StartUp)
if (pPageData->bStartTypeChanged)
{
case 0: pServiceConfig->dwStartType = SERVICE_AUTO_START; break;
case 1: pServiceConfig->dwStartType = SERVICE_DEMAND_START; break;
case 2: pServiceConfig->dwStartType = SERVICE_DISABLED; break;
StartUp = SendDlgItemMessageW(hwndDlg, IDC_START_TYPE, CB_GETCURSEL, 0, 0);
switch (StartUp)
{
case 0:
pServiceConfig->dwStartType = SERVICE_AUTO_START;
break;
case 1:
pServiceConfig->dwStartType = SERVICE_DEMAND_START;
break;
case 2:
pServiceConfig->dwStartType = SERVICE_DISABLED;
break;
}
}
if (pPageData->bBinaryPathChanged)
{
nLength = SendDlgItemMessageW(hwndDlg, IDC_EXEPATH, WM_GETTEXTLENGTH, 0, 0);
pServiceConfig->lpBinaryPathName = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
(nLength + 1) * sizeof(WCHAR));
if (pServiceConfig->lpBinaryPathName != NULL)
SendDlgItemMessageW(hwndDlg, IDC_EXEPATH, WM_GETTEXT, nLength + 1, (LPARAM)pServiceConfig->lpBinaryPathName);
}
if (pPageData->bDisplayNameChanged)
{
nLength = SendDlgItemMessageW(hwndDlg, IDC_DISP_NAME, WM_GETTEXTLENGTH, 0, 0);
pDisplayName = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
(nLength + 1) * sizeof(WCHAR));
if (pDisplayName != NULL)
{
SendDlgItemMessageW(hwndDlg, IDC_DISP_NAME, WM_GETTEXT, nLength + 1, (LPARAM)pDisplayName);
if (pPageData->dlgInfo->pService->lpDisplayName)
HeapFree(ProcessHeap, 0, pPageData->dlgInfo->pService->lpDisplayName);
pPageData->dlgInfo->pService->lpDisplayName = pDisplayName;
pServiceConfig->lpDisplayName = pDisplayName;
}
}
if (SetServiceConfig(pServiceConfig,
dlgInfo->pService->lpServiceName,
pPageData->dlgInfo->pService->lpServiceName,
NULL))
{
ChangeListViewText(dlgInfo->Info,
dlgInfo->pService,
LVSTARTUP);
if (pPageData->bDisplayNameChanged)
ChangeListViewText(pPageData->dlgInfo->Info,
pPageData->dlgInfo->pService,
LVNAME);
if (pPageData->bStartTypeChanged)
ChangeListViewText(pPageData->dlgInfo->Info,
pPageData->dlgInfo->pService,
LVSTARTUP);
}
HeapFree(ProcessHeap,
0,
pServiceConfig);
if (pServiceConfig->lpBinaryPathName != NULL)
HeapFree(ProcessHeap, 0, pServiceConfig->lpBinaryPathName);
HeapFree(ProcessHeap, 0, pServiceConfig);
}
if (pPageData->bDescriptionChanged)
{
nLength = SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0);
pDescription = HeapAlloc(ProcessHeap, HEAP_ZERO_MEMORY, (nLength + 1) * sizeof(WCHAR));
if (pDescription != NULL)
{
SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_GETTEXT, nLength + 1, (LPARAM)pDescription);
if (SetServiceDescription(pPageData->dlgInfo->pService->lpServiceName,
pDescription))
{
ChangeListViewText(pPageData->dlgInfo->Info,
pPageData->dlgInfo->pService,
LVDESC);
}
HeapFree(ProcessHeap, 0, pDescription);
}
}
}
@ -301,7 +368,31 @@ GeneralPageProc(HWND hwndDlg,
case IDC_START_TYPE:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
pPageData->bPageChanged = TRUE;
pPageData->bStartTypeChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_DISP_NAME:
if (HIWORD(wParam) == EN_CHANGE)
{
pPageData->bDisplayNameChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_DESCRIPTION:
if (HIWORD(wParam) == EN_CHANGE)
{
pPageData->bDescriptionChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case IDC_EXEPATH:
if (HIWORD(wParam) == EN_CHANGE)
{
pPageData->bBinaryPathChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
@ -314,6 +405,8 @@ GeneralPageProc(HWND hwndDlg,
if (GetDlgItemText(hwndDlg, IDC_START_PARAM, szStartParams, 256) > 0)
lpStartParams = szStartParams;
EnableWindow(GetDlgItem(hwndDlg, IDC_START_PARAM), FALSE);
RunActionWithProgress(hwndDlg,
pPageData->dlgInfo->pService->lpServiceName,
pPageData->dlgInfo->pService->lpDisplayName,
@ -370,17 +463,7 @@ GeneralPageProc(HWND hwndDlg,
SendDlgItemMessage(hwndDlg, IDC_DISP_NAME, EM_SETREADONLY, FALSE, 0);
SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION, EM_SETREADONLY, FALSE, 0);
SendDlgItemMessage(hwndDlg, IDC_EXEPATH, EM_SETREADONLY, FALSE, 0);
break;
case IDC_DISP_NAME:
case IDC_DESCRIPTION:
case IDC_EXEPATH:
case IDC_START_PARAM:
if (HIWORD(wParam) == EN_CHANGE)
{
pPageData->bPageChanged = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE);
break;
}
break;
@ -389,11 +472,17 @@ GeneralPageProc(HWND hwndDlg,
switch (((LPNMHDR)lParam)->code)
{
case PSN_APPLY:
if (pPageData->bPageChanged)
if (pPageData->bDisplayNameChanged ||
pPageData->bDescriptionChanged ||
pPageData->bBinaryPathChanged ||
pPageData->bStartTypeChanged)
{
SaveDlgInfo(pPageData->dlgInfo, hwndDlg);
SaveDlgInfo(pPageData, hwndDlg);
SetButtonStates(pPageData->dlgInfo, hwndDlg);
pPageData->bPageChanged = FALSE;
pPageData->bDisplayNameChanged = FALSE;
pPageData->bDescriptionChanged = FALSE;
pPageData->bBinaryPathChanged = FALSE;
pPageData->bStartTypeChanged = FALSE;
}
break;
}

View file

@ -253,25 +253,41 @@ SetServiceDescription(LPWSTR lpServiceName,
return bRet;
}
BOOL
GetServiceList(PMAIN_WND_INFO Info,
DWORD *NumServices)
VOID
FreeServiceList(PMAIN_WND_INFO Info)
{
DWORD i;
if (Info->pAllServices != NULL)
{
for (i = 0; i < Info->NumServices; i++)
{
if (Info->pAllServices[i].lpServiceName)
HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpServiceName);
if (Info->pAllServices[i].lpDisplayName)
HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpDisplayName);
}
HeapFree(ProcessHeap, 0, Info->pAllServices);
Info->pAllServices = NULL;
Info->NumServices = 0;
}
}
BOOL
GetServiceList(PMAIN_WND_INFO Info)
{
ENUM_SERVICE_STATUS_PROCESS *pServices = NULL;
SC_HANDLE ScHandle;
BOOL bRet = FALSE;
DWORD BytesNeeded = 0;
DWORD ResumeHandle = 0;
DWORD NumServices = 0;
DWORD i;
*NumServices = 0;
if (Info->pAllServices != NULL)
{
HeapFree(ProcessHeap,
0,
Info->pAllServices);
Info->pAllServices = NULL;
}
FreeServiceList(Info);
ScHandle = OpenSCManagerW(NULL,
NULL,
@ -285,7 +301,7 @@ GetServiceList(PMAIN_WND_INFO Info,
NULL,
0,
&BytesNeeded,
NumServices,
&NumServices,
&ResumeHandle,
0))
{
@ -293,20 +309,20 @@ GetServiceList(PMAIN_WND_INFO Info,
if (GetLastError() == ERROR_MORE_DATA)
{
/* reserve memory for service info array */
Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(ProcessHeap,
0,
BytesNeeded);
if (Info->pAllServices)
pServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
0,
BytesNeeded);
if (pServices)
{
/* fill array with service info */
if (EnumServicesStatusEx(ScHandle,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,
(LPBYTE)Info->pAllServices,
(LPBYTE)pServices,
BytesNeeded,
&BytesNeeded,
NumServices,
&NumServices,
&ResumeHandle,
0))
{
@ -320,13 +336,36 @@ GetServiceList(PMAIN_WND_INFO Info,
if (ScHandle)
CloseServiceHandle(ScHandle);
if (!bRet && Info->pAllServices)
Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
NumServices * sizeof(ENUM_SERVICE_STATUS_PROCESS));
if (Info->pAllServices != NULL)
{
HeapFree(ProcessHeap,
0,
Info->pAllServices);
Info->NumServices = NumServices;
for (i = 0; i < NumServices; i++)
{
Info->pAllServices[i].lpServiceName = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
(wcslen(pServices[i].lpServiceName) + 1) * sizeof(WCHAR));
if (Info->pAllServices[i].lpServiceName)
wcscpy(Info->pAllServices[i].lpServiceName, pServices[i].lpServiceName);
Info->pAllServices[i].lpDisplayName = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
(wcslen(pServices[i].lpDisplayName) + 1) * sizeof(WCHAR));
if (Info->pAllServices[i].lpDisplayName)
wcscpy(Info->pAllServices[i].lpDisplayName, pServices[i].lpDisplayName);
CopyMemory(&Info->pAllServices[i].ServiceStatusProcess,
&pServices[i].ServiceStatusProcess,
sizeof(SERVICE_STATUS_PROCESS));
}
}
if (pServices)
HeapFree(ProcessHeap, 0, pServices);
return bRet;
}

View file

@ -53,16 +53,16 @@ DoStartService(LPWSTR ServiceName,
lpChar++;
}
/* Allocate the arguments vector and add one for the service name */
lpArgsVector = LocalAlloc(LMEM_FIXED, (dwArgsCount + 1) * sizeof(LPCWSTR));
/*
* Allocate the arguments vector.
* Do not add the service name here because services.exe does it for us!
*/
lpArgsVector = LocalAlloc(LMEM_FIXED, dwArgsCount * sizeof(LPCWSTR));
if (!lpArgsVector)
return FALSE;
/* Make the service name the first argument */
lpArgsVector[0] = ServiceName;
/* Fill the arguments vector */
dwArgsCount = 1;
dwArgsCount = 0;
bWhiteSpace = TRUE;
lpChar = lpStartParams;
while (*lpChar != 0)