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; } -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; } 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)