From bbf8c31b3508fda056f3819d50f6df8f786af720 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 5 Jan 2010 17:14:08 +0000 Subject: [PATCH] More code towards getting servman to stop services again, etc... (clearly not a message for the changelog) svn path=/trunk/; revision=44949 --- .../mscutils/servman/dependencies.c | 153 ----------- .../mscutils/servman/dependencies_tv2.c | 184 +++++++------ .../applications/mscutils/servman/precomp.h | 4 +- .../mscutils/servman/servman.rbuild | 2 +- .../base/applications/mscutils/servman/stop.c | 28 +- .../mscutils/servman/stop_dependencies.c | 254 ++++++++++++++++++ 6 files changed, 366 insertions(+), 259 deletions(-) delete mode 100644 reactos/base/applications/mscutils/servman/dependencies.c create mode 100644 reactos/base/applications/mscutils/servman/stop_dependencies.c diff --git a/reactos/base/applications/mscutils/servman/dependencies.c b/reactos/base/applications/mscutils/servman/dependencies.c deleted file mode 100644 index 4977f63ba5c..00000000000 --- a/reactos/base/applications/mscutils/servman/dependencies.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * PROJECT: ReactOS Services - * LICENSE: GPL - See COPYING in the top level directory - * FILE: base/applications/mscutils/servman/dependencies.c - * PURPOSE: Helper functions for service dependents - * COPYRIGHT: Copyright 2006-2009 Ged Murphy - * - */ - -#include "precomp.h" - -//FIXME: reimplement this -static BOOL -DoInitDependsDialog(PSTOP_INFO pStopInfo, - HWND hDlg) -{ - //LPENUM_SERVICE_STATUS lpDependencies; - //DWORD dwCount; - LPTSTR lpPartialStr, lpStr; - DWORD fullLen; - HICON hIcon = NULL; - BOOL bRet = FALSE; - - if (pStopInfo) - { - SetWindowLongPtr(hDlg, - GWLP_USERDATA, - (LONG_PTR)pStopInfo); - - hIcon = (HICON)LoadImage(hInstance, - MAKEINTRESOURCE(IDI_SM_ICON), - IMAGE_ICON, - 16, - 16, - 0); - if (hIcon) - { - SendMessage(hDlg, - WM_SETICON, - ICON_SMALL, - (LPARAM)hIcon); - DestroyIcon(hIcon); - } - - /* Add the label */ - if (AllocAndLoadString(&lpPartialStr, - hInstance, - IDS_STOP_DEPENDS)) - { - fullLen = _tcslen(lpPartialStr) + _tcslen(pStopInfo->pInfo->pCurrentService->lpDisplayName) + 1; - - lpStr = HeapAlloc(ProcessHeap, - 0, - fullLen * sizeof(TCHAR)); - if (lpStr) - { - _sntprintf(lpStr, fullLen, lpPartialStr, pStopInfo->pInfo->pCurrentService->lpDisplayName); - - SendDlgItemMessage(hDlg, - IDC_STOP_DEPENDS, - WM_SETTEXT, - 0, - (LPARAM)lpStr); - - bRet = TRUE; - - HeapFree(ProcessHeap, - 0, - lpStr); - } - - HeapFree(ProcessHeap, - 0, - lpPartialStr); - } - - /* Get the list of dependencies - GetServiceDependents(pStopInfo->hMainService, &dwCount); - if (lpDependencies) - { - LPENUM_SERVICE_STATUS lpEnumServiceStatus; - DWORD i; - - for (i = 0; i < dwCount; i++) - { - lpEnumServiceStatus = &lpDependencies[i]; - - Add the service to the listbox - SendDlgItemMessage(hDlg, - IDC_STOP_DEPENDS_LB, - LB_ADDSTRING, - 0, - (LPARAM)lpEnumServiceStatus->lpDisplayName); - } - - HeapFree(ProcessHeap, - 0, - lpDependencies); - }*/ - } - - return bRet; -} - - -INT_PTR CALLBACK -StopDependsDialogProc(HWND hDlg, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - PSTOP_INFO pStopInfo = NULL; - - /* Get the window context */ - pStopInfo = (PSTOP_INFO)GetWindowLongPtr(hDlg, - GWLP_USERDATA); - if (pStopInfo == NULL && message != WM_INITDIALOG) - { - return FALSE; - } - - switch (message) - { - case WM_INITDIALOG: - { - BOOL bRet = FALSE; - - pStopInfo = (PSTOP_INFO)lParam; - if (pStopInfo != NULL) - { - bRet = DoInitDependsDialog(pStopInfo, hDlg); - } - - return bRet; - } - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - case IDCANCEL: - { - EndDialog(hDlg, - LOWORD(wParam)); - return TRUE; - } - } - } - } - - return FALSE; -} diff --git a/reactos/base/applications/mscutils/servman/dependencies_tv2.c b/reactos/base/applications/mscutils/servman/dependencies_tv2.c index 2cd1bcadc84..65a1e758528 100644 --- a/reactos/base/applications/mscutils/servman/dependencies_tv2.c +++ b/reactos/base/applications/mscutils/servman/dependencies_tv2.c @@ -51,55 +51,67 @@ TV2_HasDependantServices(LPWSTR lpServiceName) } -static LPENUM_SERVICE_STATUS -TV2_GetDependants(SC_HANDLE hService, +LPENUM_SERVICE_STATUS +TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount) { - LPENUM_SERVICE_STATUS lpDependencies; + SC_HANDLE hSCManager; + SC_HANDLE hService; + LPENUM_SERVICE_STATUSW lpDependencies = NULL; DWORD dwBytesNeeded; DWORD dwCount; - /* Does this have any dependencies? */ - if (EnumDependentServices(hService, - SERVICE_STATE_ALL, - NULL, - 0, - &dwBytesNeeded, - &dwCount)) + /* Set the first items in each tree view */ + hSCManager = OpenSCManagerW(NULL, + NULL, + SC_MANAGER_ALL_ACCESS); + if (hSCManager) { - /* There are no dependent services */ - return NULL; - } - else - { - if (GetLastError() != ERROR_MORE_DATA) - return NULL; /* Unexpected error */ - - lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(), - 0, - dwBytesNeeded); - if (lpDependencies) + hService = OpenServiceW(hSCManager, + lpServiceName, + SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG); + if (hService) { - /* Get the list of dependents */ - if (EnumDependentServices(hService, - SERVICE_STATE_ALL, - lpDependencies, - dwBytesNeeded, - &dwBytesNeeded, - &dwCount)) + /* Does this have any dependencies? */ + if (!EnumDependentServicesW(hService, + SERVICE_STATE_ALL, + NULL, + 0, + &dwBytesNeeded, + &dwCount) && + GetLastError() == ERROR_MORE_DATA) { - /* Set the count */ - *lpdwCount = dwCount; - } - else - { - HeapFree(ProcessHeap, - 0, - lpDependencies); + lpDependencies = (LPENUM_SERVICE_STATUSW)HeapAlloc(GetProcessHeap(), + 0, + dwBytesNeeded); + if (lpDependencies) + { + /* Get the list of dependents */ + if (EnumDependentServicesW(hService, + SERVICE_STATE_ALL, + lpDependencies, + dwBytesNeeded, + &dwBytesNeeded, + &dwCount)) + { + /* Set the count */ + *lpdwCount = dwCount; + } + else + { + HeapFree(ProcessHeap, + 0, + lpDependencies); - lpDependencies = NULL; + lpDependencies = NULL; + } + } } + + CloseServiceHandle(hService); } + + CloseServiceHandle(hSCManager); } return lpDependencies; @@ -111,70 +123,56 @@ TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName) { - SC_HANDLE hSCManager; - SC_HANDLE hService; - LPENUM_SERVICE_STATUS lpServiceStatus; + + LPENUM_SERVICE_STATUSW lpServiceStatus; LPTSTR lpNoDepends; DWORD count, i; BOOL bHasChildren; - /* Set the first items in each tree view */ - hSCManager = OpenSCManager(NULL, - NULL, - SC_MANAGER_ALL_ACCESS); - if (hSCManager) + /* Get a list of service dependents */ + lpServiceStatus = TV2_GetDependants(lpServiceName, &count); + if (lpServiceStatus) { - hService = OpenService(hSCManager, - lpServiceName, - SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG); - if (hService) + for (i = 0; i < count; i++) { - /* Get a list of service dependents */ - lpServiceStatus = TV2_GetDependants(hService, &count); - if (lpServiceStatus) - { - for (i = 0; i < count; i++) - { - /* Does this item need a +/- box? */ - bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName); + /* Does this item need a +/- box? */ + bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName); - /* Add it */ - AddItemToTreeView(pDlgInfo->hDependsTreeView2, - hParent, - lpServiceStatus[i].lpDisplayName, - lpServiceStatus[i].lpServiceName, - lpServiceStatus[i].ServiceStatus.dwServiceType, - bHasChildren); - } - } - else - { - /* If there is no parent, set the tree to 'no dependencies' */ - if (!hParent) - { - /* Load the 'No dependencies' string */ - AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS); - - AddItemToTreeView(pDlgInfo->hDependsTreeView2, - NULL, - lpNoDepends, - NULL, - 0, - FALSE); - - HeapFree(ProcessHeap, - 0, - lpNoDepends); - - /* Disable the window */ - EnableWindow(pDlgInfo->hDependsTreeView2, FALSE); - } - } - - CloseServiceHandle(hService); + /* Add it */ + AddItemToTreeView(pDlgInfo->hDependsTreeView2, + hParent, + lpServiceStatus[i].lpDisplayName, + lpServiceStatus[i].lpServiceName, + lpServiceStatus[i].ServiceStatus.dwServiceType, + bHasChildren); } - CloseServiceHandle(hSCManager); + HeapFree(GetProcessHeap(), + 0, + lpServiceStatus); + } + else + { + /* If there is no parent, set the tree to 'no dependencies' */ + if (!hParent) + { + /* Load the 'No dependencies' string */ + AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS); + + AddItemToTreeView(pDlgInfo->hDependsTreeView2, + NULL, + lpNoDepends, + NULL, + 0, + FALSE); + + HeapFree(ProcessHeap, + 0, + lpNoDepends); + + /* Disable the window */ + EnableWindow(pDlgInfo->hDependsTreeView2, FALSE); + } } } diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index b50e566c0b1..062cd2daa62 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -124,8 +124,9 @@ typedef struct _SERVICEPROPSHEET HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPTSTR lpDisplayName, LPTSTR lpServiceName, ULONG serviceType, BOOL bHasChildren); -/* dependencies */ +/* stop_dependencies */ INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName); /* tv1_dependencies */ BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName); @@ -135,6 +136,7 @@ VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTS BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName); VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName); BOOL TV2_HasDependantServices(LPWSTR lpServiceName); +LPENUM_SERVICE_STATUS TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount); LONG APIENTRY OpenPropSheet(PMAIN_WND_INFO Info); diff --git a/reactos/base/applications/mscutils/servman/servman.rbuild b/reactos/base/applications/mscutils/servman/servman.rbuild index f150ced85ac..1d4951f89c7 100644 --- a/reactos/base/applications/mscutils/servman/servman.rbuild +++ b/reactos/base/applications/mscutils/servman/servman.rbuild @@ -14,7 +14,6 @@ control.c create.c delete.c - dependencies.c dependencies_tv1.c dependencies_tv2.c export.c @@ -29,6 +28,7 @@ servman.c start.c stop.c + stop_dependencies.c servman.rc precomp.h diff --git a/reactos/base/applications/mscutils/servman/stop.c b/reactos/base/applications/mscutils/servman/stop.c index 412ccae20b0..1a97d5f5749 100644 --- a/reactos/base/applications/mscutils/servman/stop.c +++ b/reactos/base/applications/mscutils/servman/stop.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/stop.c * PURPOSE: Stops running a service - * COPYRIGHT: Copyright 2006-2009 Ged Murphy + * COPYRIGHT: Copyright 2006-2010 Ged Murphy * */ @@ -118,6 +118,7 @@ StopDependantServices(PMAIN_WND_INFO pInfo, BOOL DoStop(PMAIN_WND_INFO pInfo) { + LPWSTR lpServiceList; BOOL bRet = FALSE; if (pInfo) @@ -125,18 +126,23 @@ DoStop(PMAIN_WND_INFO pInfo) /* Does this service have anything which depends on it? */ if (TV2_HasDependantServices(pInfo->pCurrentService->lpServiceName)) { - /* It does, list them and ask the user if they want to stop them as well */ - if (DialogBoxParam(hInstance, - MAKEINTRESOURCE(IDD_DLG_DEPEND_STOP), - pInfo->hMainWnd, - StopDependsDialogProc, - (LPARAM)&pInfo) == IDOK) + /* It does, get a list of all the services which need stopping */ + lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName); + if (lpServiceList) { - /* Stop all the dependany services */ - if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName)) + /* List them and ask the user if they want to stop them */ + if (DialogBoxParamW(hInstance, + MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP), + pInfo->hMainWnd, + StopDependsDialogProc, + (LPARAM)lpServiceList) == IDOK) { - /* Finally stop the requested service */ - bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName); + /* Stop all the dependant services */ + if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName)) + { + /* Finally stop the requested service */ + bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName); + } } } } diff --git a/reactos/base/applications/mscutils/servman/stop_dependencies.c b/reactos/base/applications/mscutils/servman/stop_dependencies.c new file mode 100644 index 00000000000..5820a34d9bf --- /dev/null +++ b/reactos/base/applications/mscutils/servman/stop_dependencies.c @@ -0,0 +1,254 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/mscutils/servman/stop_dependencies.c + * PURPOSE: Routines related to stopping dependent services + * COPYRIGHT: Copyright 2006-2010 Ged Murphy + * + */ + +#include "precomp.h" + + +static LPWSTR +AddServiceToList(LPWSTR *lpServiceList, + LPWSTR lpServiceToAdd) +{ + LPWSTR lpNewList = NULL; + LPWSTR ptr; + DWORD dwToAddSize; + DWORD dwCurSize; + + dwToAddSize = wcslen(lpServiceToAdd) + 1; + + /* Is this is the first in the list? */ + if (!*lpServiceList) + { + /* Add another char for double null */ + dwToAddSize++; + + lpNewList = HeapAlloc(GetProcessHeap(), + 0, + dwToAddSize * sizeof(WCHAR)); + if (lpNewList) + { + /* Copy the service name */ + wcscpy_s(lpNewList, + dwToAddSize, + lpServiceToAdd); + + /* Add the double null char */ + lpNewList[dwToAddSize - 1] = L'\0'; + } + } + else + { + ptr = *lpServiceList; + dwCurSize = 0; + + /* Get the list size */ + while (*ptr != L'\0' || *(ptr + 1) != L'\0') + { + ptr++; + dwCurSize++; + } + dwCurSize++; + + /* Add another char for double null */ + dwCurSize++; + + /* Extend the list size */ + lpNewList = HeapReAlloc(GetProcessHeap(), + 0, + *lpServiceList, + (dwCurSize + dwToAddSize) * sizeof(WCHAR)); + if (lpNewList) + { + /* Copy the service name */ + wcscpy_s(&lpNewList[dwCurSize - 1], + dwToAddSize, + lpServiceToAdd); + + /* Add the double null char */ + lpNewList[dwCurSize + dwToAddSize - 1] = L'\0'; + } + } + + return lpNewList; +} + +static BOOL +BuildListOfServicesToStop(LPWSTR *lpServiceList, + LPWSTR lpServiceName) +{ + LPENUM_SERVICE_STATUS lpServiceStatus; + DWORD dwCount, i; + BOOL bRet = FALSE; + + /* Get a list of service dependents */ + lpServiceStatus = TV2_GetDependants(lpServiceName, &dwCount); + if (lpServiceStatus) + { + for (i = 0; i < dwCount; i++) + { + /* Does this service have any dependents? */ + if (TV2_HasDependantServices(lpServiceStatus[i].lpServiceName)) + { + /* recall this function with the dependent */ + BuildListOfServicesToStop(lpServiceList, lpServiceStatus[i].lpServiceName); + } + + /* Add the service to the list */ + *lpServiceList = AddServiceToList(lpServiceList, lpServiceStatus[i].lpServiceName); + } + + bRet = TRUE; + + HeapFree(GetProcessHeap(), + 0, + lpServiceStatus); + } + + return bRet; +} + +LPWSTR +GetListOfServicesToStop(LPWSTR lpServiceName) +{ + LPWSTR lpServiceList = NULL; + + /* Call recursive function to get our list */ + if (BuildListOfServicesToStop(&lpServiceList, lpServiceName)) + return lpServiceList; + else + return NULL; +} + + +static BOOL +DoInitDependsDialog(PMAIN_WND_INFO pInfo, + HWND hDlg) +{ + LPWSTR lpPartialStr, lpStr; + DWORD fullLen; + HICON hIcon = NULL; + BOOL bRet = FALSE; + + if (pInfo) + { + /* Tag the info to the window */ + SetWindowLongPtrW(hDlg, + GWLP_USERDATA, + (LONG_PTR)pInfo); + + /* Load the icon for the window */ + hIcon = (HICON)LoadImageW(hInstance, + MAKEINTRESOURCE(IDI_SM_ICON), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CXSMICON), + 0); + if (hIcon) + { + /* Set it */ + SendMessageW(hDlg, + WM_SETICON, + ICON_SMALL, + (LPARAM)hIcon); + DestroyIcon(hIcon); + } + + /* Load the stop depends note */ + if (AllocAndLoadString(&lpPartialStr, + hInstance, + IDS_STOP_DEPENDS)) + { + /* Get the length required */ + fullLen = wcslen(lpPartialStr) + wcslen(pInfo->pCurrentService->lpDisplayName) + 1; + + lpStr = HeapAlloc(ProcessHeap, + 0, + fullLen * sizeof(WCHAR)); + if (lpStr) + { + /* Add the service name to the depends note */ + _snwprintf(lpStr, + fullLen, + lpPartialStr, + pInfo->pCurrentService->lpDisplayName); + + /* Add the string to the dialog */ + SendDlgItemMessageW(hDlg, + IDC_STOP_DEPENDS, + WM_SETTEXT, + 0, + (LPARAM)lpStr); + + HeapFree(ProcessHeap, + 0, + lpStr); + + bRet = TRUE; + } + + HeapFree(ProcessHeap, + 0, + lpPartialStr); + } + + /* FIXME: Load the list of services which need stopping */ + + } + + return bRet; +} + + +INT_PTR CALLBACK +StopDependsDialogProc(HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + PMAIN_WND_INFO pInfo = NULL; + + /* Get the window context */ + pInfo = (PMAIN_WND_INFO)GetWindowLongPtrW(hDlg, + GWLP_USERDATA); + if (pInfo == NULL && message != WM_INITDIALOG) + { + return FALSE; + } + + switch (message) + { + case WM_INITDIALOG: + { + BOOL bRet = FALSE; + + pInfo = (PMAIN_WND_INFO)lParam; + if (pInfo != NULL) + { + bRet = DoInitDependsDialog(pInfo, hDlg); + } + + return bRet; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + { + EndDialog(hDlg, + LOWORD(wParam)); + return TRUE; + } + } + } + } + + return FALSE; +}