From: Eric Kohl Date: Sun, 23 Apr 2017 17:39:26 +0000 (+0000) Subject: [SERVMAN] X-Git-Tag: ReactOS-0.4.5~40 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=f83d61cce0fa130fd6bcd78140502d2186dc5168 [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 --- diff --git a/reactos/base/applications/mscutils/servman/listview.c b/reactos/base/applications/mscutils/servman/listview.c index a9f6dcf7caf..0ccf76b6852 100644 --- a/reactos/base/applications/mscutils/servman/listview.c +++ b/reactos/base/applications/mscutils/servman/listview.c @@ -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; diff --git a/reactos/base/applications/mscutils/servman/mainwnd.c b/reactos/base/applications/mscutils/servman/mainwnd.c index c1e659f4ed7..a28e9c8833b 100644 --- a/reactos/base/applications/mscutils/servman/mainwnd.c +++ b/reactos/base/applications/mscutils/servman/mainwnd.c @@ -880,10 +880,7 @@ MainWndProc(HWND hwnd, case WM_CLOSE: { - HeapFree(ProcessHeap, - 0, - Info->pAllServices); - + FreeServiceList(Info); DestroyMenu(Info->hShortcutMenu); DestroyWindow(hwnd); } diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index a4cf5551141..661772ffb4e 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -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 */ diff --git a/reactos/base/applications/mscutils/servman/propsheet_general.c b/reactos/base/applications/mscutils/servman/propsheet_general.c index 5575edd6d53..42b5f9abd67 100644 --- a/reactos/base/applications/mscutils/servman/propsheet_general.c +++ b/reactos/base/applications/mscutils/servman/propsheet_general.c @@ -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; } diff --git a/reactos/base/applications/mscutils/servman/query.c b/reactos/base/applications/mscutils/servman/query.c index ff9f3a57fa7..e95038f0a03 100644 --- a/reactos/base/applications/mscutils/servman/query.c +++ b/reactos/base/applications/mscutils/servman/query.c @@ -253,25 +253,41 @@ SetServiceDescription(LPWSTR lpServiceName, return bRet; } +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, - DWORD *NumServices) +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; } diff --git a/reactos/base/applications/mscutils/servman/start.c b/reactos/base/applications/mscutils/servman/start.c index c73c1a6544e..5251fb3b6fe 100644 --- a/reactos/base/applications/mscutils/servman/start.c +++ b/reactos/base/applications/mscutils/servman/start.c @@ -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)