diff --git a/reactos/base/applications/mscutils/servman/control.c b/reactos/base/applications/mscutils/servman/control.c index b90727ced5c..e1270e2fd60 100644 --- a/reactos/base/applications/mscutils/servman/control.c +++ b/reactos/base/applications/mscutils/servman/control.c @@ -3,180 +3,143 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/control.c * PURPOSE: Pauses and resumes a service - * COPYRIGHT: Copyright 2006-2010 Ged Murphy + * COPYRIGHT: Copyright 2006-2015 Ged Murphy * */ #include "precomp.h" -static BOOL -DoControl(PMAIN_WND_INFO Info, - HWND hProgress, - DWORD Control) +#define MAX_WAIT_TIME 30000 + +BOOL +DoControlService(LPWSTR ServiceName, + HWND hProgress, + DWORD Control) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus = {0}; SERVICE_STATUS Status; DWORD BytesNeeded = 0; - DWORD dwStartTickCount; - DWORD dwOldCheckPoint; - DWORD dwWaitTime; - DWORD dwMaxWait; - DWORD dwReqState; - BOOL bRet = FALSE; + DWORD StartTickCount; + DWORD OldCheckPoint; + DWORD WaitTime; + DWORD MaxWait; + DWORD ReqState; + BOOL Result; /* Set the state we're interested in */ switch (Control) { case SERVICE_CONTROL_PAUSE: - dwReqState = SERVICE_PAUSED; + ReqState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: - dwReqState = SERVICE_RUNNING; + ReqState = SERVICE_RUNNING; break; default: /* Unhandled control code */ return FALSE; } - hSCManager = OpenSCManager(NULL, - NULL, - SC_MANAGER_CONNECT); - if (hSCManager) + hSCManager = OpenSCManagerW(NULL, + NULL, + SC_MANAGER_CONNECT); + if (!hSCManager) return FALSE; + + hService = OpenServiceW(hSCManager, + ServiceName, + SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS); + if (!hService) { - hService = OpenService(hSCManager, - Info->pCurrentService->lpServiceName, - SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS); - if (hService) + CloseServiceHandle(hSCManager); + return FALSE; + } + + /* Send the control message to the service */ + Result = ControlService(hService, + Control, + &Status); + if (Result) + { + if (hProgress) { - if (hProgress) - { - /* Increment the progress bar */ - IncrementProgressBar(hProgress, DEFAULT_STEP); - } + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } - /* Send the control message to the service */ - if (ControlService(hService, - Control, - &Status)) + /* Get the service status */ + Result = QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded); + if (Result) + { + Result = FALSE; + MaxWait = MAX_WAIT_TIME; + OldCheckPoint = ServiceStatus.dwCheckPoint; + StartTickCount = GetTickCount(); + + /* Loop until it's at the correct state */ + while (ServiceStatus.dwCurrentState != ReqState) { - /* Get the service status */ - if (QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &BytesNeeded)) + /* Fixup the wait time */ + WaitTime = ServiceStatus.dwWaitHint / 10; + + if (WaitTime < 1000) WaitTime = 1000; + else if (WaitTime > 10000) WaitTime = 10000; + + /* We don't wanna wait for up to 10 secs without incrementing */ + for (int i = WaitTime / 1000; i > 0; i--) { - /* We don't want to wait for more than 30 seconds */ - dwMaxWait = 30000; - dwStartTickCount = GetTickCount(); - - /* Loop until it's at the correct state */ - while (ServiceStatus.dwCurrentState != dwReqState) + Sleep(1000); + if (hProgress) { - dwOldCheckPoint = ServiceStatus.dwCheckPoint; - dwWaitTime = ServiceStatus.dwWaitHint / 10; - - /* Get the latest status info */ - if (!QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &BytesNeeded)) - { - /* Something went wrong... */ - break; - } - - /* Is the service making progress? */ - if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) - { - /* It is, get the latest tickcount to reset the max wait time */ - dwStartTickCount = GetTickCount(); - dwOldCheckPoint = ServiceStatus.dwCheckPoint; - IncrementProgressBar(hProgress, DEFAULT_STEP); - } - else - { - /* It's not, make sure we haven't exceeded our wait time */ - if(GetTickCount() >= dwStartTickCount + dwMaxWait) - { - /* We have, give up */ - break; - } - } - - /* Adjust the wait hint times */ - if (dwWaitTime < 200) - dwWaitTime = 200; - else if (dwWaitTime > 10000) - dwWaitTime = 10000; - - /* Wait before trying again */ - Sleep(dwWaitTime); + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); } } - if (ServiceStatus.dwCurrentState == dwReqState) + /* Get the latest status info */ + if (!QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) { - bRet = TRUE; + /* Something went wrong... */ + break; + } + + /* Is the service making progress? */ + if (ServiceStatus.dwCheckPoint > OldCheckPoint) + { + /* It is, get the latest tickcount to reset the max wait time */ + StartTickCount = GetTickCount(); + OldCheckPoint = ServiceStatus.dwCheckPoint; + IncrementProgressBar(hProgress, DEFAULT_STEP); + } + else + { + /* It's not, make sure we haven't exceeded our wait time */ + if(GetTickCount() >= StartTickCount + MaxWait) + { + /* We have, give up */ + break; + } } } - - CloseServiceHandle(hService); } - CloseServiceHandle(hSCManager); + if (ServiceStatus.dwCurrentState == ReqState) + { + Result = TRUE; + } } - return bRet; -} - -BOOL -DoPause(PMAIN_WND_INFO Info) -{ - HWND hProgress; - BOOL bRet = FALSE; - - /* Create a progress window to track the progress of the pausing service */ - hProgress = CreateProgressDialog(Info->hMainWnd, - IDS_PROGRESS_INFO_PAUSE); - if (hProgress) - { - /* Set the service name and reset the progress bag */ - InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName); - - /* Resume the requested service */ - bRet = DoControl(Info, hProgress, SERVICE_CONTROL_PAUSE); - - /* Complete and destroy the progress bar */ - DestroyProgressDialog(hProgress, bRet); - } - - return bRet; -} - -BOOL -DoResume(PMAIN_WND_INFO Info) -{ - HWND hProgress; - BOOL bRet = FALSE; - - /* Create a progress window to track the progress of the resuming service */ - hProgress = CreateProgressDialog(Info->hMainWnd, - IDS_PROGRESS_INFO_RESUME); - if (hProgress) - { - /* Set the service name and reset the progress bag */ - InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName); - - /* Resume the requested service */ - bRet = DoControl(Info, hProgress, SERVICE_CONTROL_CONTINUE); - - /* Complete and destroy the progress bar */ - DestroyProgressDialog(hProgress, bRet); - } - - return bRet; + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + + return Result; } diff --git a/reactos/base/applications/mscutils/servman/mainwnd.c b/reactos/base/applications/mscutils/servman/mainwnd.c index 829148185de..8d0ba98be68 100644 --- a/reactos/base/applications/mscutils/servman/mainwnd.c +++ b/reactos/base/applications/mscutils/servman/mainwnd.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/mainwnd.c * PURPOSE: Main window message handler - * COPYRIGHT: Copyright 2006-2007 Ged Murphy + * COPYRIGHT: Copyright 2006-20015 Ged Murphy * */ @@ -11,7 +11,7 @@ #include -static const TCHAR szMainWndClass[] = TEXT("ServManWndClass"); +static const WCHAR szMainWndClass[] = L"ServManWndClass"; BOOL bSortAscending = TRUE; @@ -126,17 +126,17 @@ UpdateMainStatusBar(PMAIN_WND_INFO Info) VOID UpdateServiceCount(PMAIN_WND_INFO Info) { - LPTSTR lpNumServices; + LPWSTR lpNumServices; if (AllocAndLoadString(&lpNumServices, hInstance, IDS_NUM_SERVICES)) { - TCHAR szNumServices[32]; + WCHAR szNumServices[32]; INT NumListedServ = ListView_GetItemCount(Info->hListView); - _sntprintf(szNumServices, + _snwprintf(szNumServices, 31, lpNumServices, NumListedServ); @@ -257,7 +257,7 @@ CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) Param1 = (ENUM_SERVICE_STATUS_PROCESS *)lParam2; Param2 = (ENUM_SERVICE_STATUS_PROCESS *)lParam1; } - return _tcsicmp(Param1->lpDisplayName, Param2->lpDisplayName); + return _wcsicmp(Param1->lpDisplayName, Param2->lpDisplayName); } @@ -344,24 +344,24 @@ InitMainWnd(PMAIN_WND_INFO Info) { if (!pCreateToolbar(Info)) { - DisplayString(_T("error creating toolbar")); + DisplayString(L"error creating toolbar"); return FALSE; } if (!CreateListView(Info)) { - DisplayString(_T("error creating list view")); + DisplayString(L"error creating list view"); return FALSE; } if (!CreateStatusBar(Info)) - DisplayString(_T("error creating status bar")); + DisplayString(L"error creating status bar"); /* Create Popup Menu */ Info->hShortcutMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_POPUP)); - Info->bIsUserAnAdmin = IsUserAnAdmin(); + Info->bIsUserAnAdmin = TRUE;// IsUserAnAdmin(); if (Info->bIsUserAnAdmin) { HMENU hMainMenu = GetMenu(Info->hMainWnd); @@ -418,7 +418,7 @@ MainWndCommand(PMAIN_WND_INFO Info, SendMessage(Info->hStatus, SB_SETTEXT, 1, - _T('\0')); + L'\0'); } break; @@ -457,11 +457,11 @@ MainWndCommand(PMAIN_WND_INFO Info, } else { - TCHAR Buf[60]; + WCHAR Buf[60]; LoadString(hInstance, IDS_DELETE_STOP, Buf, - sizeof(Buf) / sizeof(TCHAR)); + sizeof(Buf) / sizeof(WCHAR)); DisplayString(Buf); } @@ -472,50 +472,73 @@ MainWndCommand(PMAIN_WND_INFO Info, case ID_START: { - if (DoStart(Info, NULL)) - { - UpdateServiceStatus(Info->pCurrentService); - ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); - SetMenuAndButtonStates(Info); - SetFocus(Info->hListView); - } + RunActionWithProgress(Info->hMainWnd, + Info->pCurrentService->lpServiceName, + Info->pCurrentService->lpDisplayName, + ACTION_START); + + UpdateServiceStatus(Info->pCurrentService); + ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); + SetMenuAndButtonStates(Info); + SetFocus(Info->hListView); + } break; case ID_STOP: - if (DoStop(Info)) - { - UpdateServiceStatus(Info->pCurrentService); - ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); - SetMenuAndButtonStates(Info); - SetFocus(Info->hListView); - } + RunActionWithProgress(Info->hMainWnd, + Info->pCurrentService->lpServiceName, + Info->pCurrentService->lpDisplayName, + ACTION_STOP); + + UpdateServiceStatus(Info->pCurrentService); + ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); + SetMenuAndButtonStates(Info); + SetFocus(Info->hListView); + break; case ID_PAUSE: - DoPause(Info); + RunActionWithProgress(Info->hMainWnd, + Info->pCurrentService->lpServiceName, + Info->pCurrentService->lpDisplayName, + ACTION_PAUSE); + + UpdateServiceStatus(Info->pCurrentService); + ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); + SetMenuAndButtonStates(Info); + SetFocus(Info->hListView); break; case ID_RESUME: - DoResume(Info); + RunActionWithProgress(Info->hMainWnd, + Info->pCurrentService->lpServiceName, + Info->pCurrentService->lpDisplayName, + ACTION_RESUME); + + UpdateServiceStatus(Info->pCurrentService); + ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); + SetMenuAndButtonStates(Info); + SetFocus(Info->hListView); break; case ID_RESTART: - if (DoStop(Info)) - { - DoStart(Info, NULL); - UpdateServiceStatus(Info->pCurrentService); - ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); - SetMenuAndButtonStates(Info); - SetFocus(Info->hListView); - } + RunActionWithProgress(Info->hMainWnd, + Info->pCurrentService->lpServiceName, + Info->pCurrentService->lpDisplayName, + ACTION_RESTART); + + UpdateServiceStatus(Info->pCurrentService); + ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); + SetMenuAndButtonStates(Info); + SetFocus(Info->hListView); break; case ID_HELP: - MessageBox(NULL, - _T("Help is not yet implemented\n"), - _T("Note!"), - MB_OK | MB_ICONINFORMATION); + MessageBoxW(NULL, + L"Help is not yet implemented\n", + L"Note!", + MB_OK | MB_ICONINFORMATION); SetFocus(Info->hListView); break; diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index 73ec61583b1..43516c04928 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -1,6 +1,7 @@ #ifndef __SERVMAN_PRECOMP_H #define __SERVMAN_PRECOMP_H +#if 0 #include #define WIN32_NO_STATUS @@ -12,10 +13,14 @@ #include #include #include -#include #include #include - +#else +#include +#include +#include +#include +#endif #include "resource.h" #ifdef _MSC_VER @@ -23,17 +28,23 @@ #endif #define NO_ITEM_SELECTED -1 -#define MAX_KEY_LENGTH 256 +#define MAX_KEY_LENGTH 256 -#define LVNAME 0 -#define LVDESC 1 -#define LVSTATUS 2 -#define LVSTARTUP 3 -#define LVLOGONAS 4 +#define LVNAME 0 +#define LVDESC 1 +#define LVSTATUS 2 +#define LVSTARTUP 3 +#define LVLOGONAS 4 -#define IMAGE_UNKNOWN 0 -#define IMAGE_SERVICE 1 -#define IMAGE_DRIVER 2 +#define IMAGE_UNKNOWN 0 +#define IMAGE_SERVICE 1 +#define IMAGE_DRIVER 2 + +#define ACTION_START 1 +#define ACTION_STOP 2 +#define ACTION_PAUSE 3 +#define ACTION_RESUME 4 +#define ACTION_RESTART 5 typedef struct _MAIN_WND_INFO { @@ -86,38 +97,24 @@ VOID SetListViewStyle(HWND hListView, DWORD View); VOID ListViewSelectionChanged(PMAIN_WND_INFO Info, LPNMLISTVIEW pnmv); BOOL CreateListView(PMAIN_WND_INFO Info); -/* start */ -BOOL DoStart(PMAIN_WND_INFO Info, LPWSTR lpStartParams); - -/* stop */ -typedef struct _STOP_INFO -{ - PMAIN_WND_INFO pInfo; - SC_HANDLE hSCManager; - SC_HANDLE hMainService; -} STOP_INFO, *PSTOP_INFO; - -/* control */ -BOOL Control(PMAIN_WND_INFO Info, HWND hProgress, DWORD Control); -BOOL DoStop(PMAIN_WND_INFO Info); -BOOL DoPause(PMAIN_WND_INFO Info); -BOOL DoResume(PMAIN_WND_INFO Info); +/* start / stop / control */ +BOOL DoStartService(LPWSTR ServiceName, HANDLE hProgress, LPWSTR lpStartParams); +BOOL DoStopService(LPWSTR ServiceName, HANDLE hProgress); +BOOL DoControlService(LPWSTR ServiceName, HWND hProgress, DWORD Control); /* progress.c */ #define DEFAULT_STEP 0 -HWND CreateProgressDialog(HWND hParent, UINT LabelId); -BOOL DestroyProgressDialog(HWND hProgress, BOOL bComplete); -VOID InitializeProgressDialog(HWND hProgress, LPWSTR lpServiceName); -VOID IncrementProgressBar(HWND hProgress, UINT NewPos); -VOID CompleteProgressBar(HWND hProgress); +BOOL RunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action); +VOID IncrementProgressBar(HANDLE hProgress, UINT NewPos); +VOID CompleteProgressBar(HANDLE hProgress); /* query.c */ ENUM_SERVICE_STATUS_PROCESS* GetSelectedService(PMAIN_WND_INFO Info); -LPQUERY_SERVICE_CONFIG GetServiceConfig(LPTSTR lpServiceName); -BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPTSTR lpServiceName, LPTSTR lpPassword); -LPTSTR GetServiceDescription(LPTSTR lpServiceName); -BOOL SetServiceDescription(LPTSTR lpServiceName, LPTSTR lpDescription); -LPTSTR GetExecutablePath(LPTSTR lpServiceName); +LPQUERY_SERVICE_CONFIG GetServiceConfig(LPWSTR lpServiceName); +BOOL SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, LPWSTR lpServiceName, LPWSTR lpPassword); +LPWSTR GetServiceDescription(LPWSTR lpServiceName); +BOOL SetServiceDescription(LPWSTR lpServiceName, LPWSTR lpDescription); +LPWSTR GetExecutablePath(LPWSTR lpServiceName); BOOL RefreshServiceList(PMAIN_WND_INFO Info); BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService); BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices); @@ -135,19 +132,24 @@ typedef struct _SERVICEPROPSHEET } SERVICEPROPSHEET, *PSERVICEPROPSHEET; -HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPTSTR lpDisplayName, LPTSTR lpServiceName, ULONG serviceType, BOOL bHasChildren); +HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPWSTR lpDisplayName, LPWSTR lpServiceName, ULONG serviceType, BOOL bHasChildren); /* stop_dependencies */ INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName); +BOOL +CreateStopDependsDialog(HWND hParent, +LPWSTR ServiceName, +LPWSTR DisplayName, +LPWSTR ServiceList); /* tv1_dependencies */ -BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName); -VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName); +BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName); +VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName); /* tv2_dependencies */ -BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName); -VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName); +BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPWSTR lpServiceName); +VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPWSTR lpServiceName); BOOL TV2_HasDependantServices(LPWSTR lpServiceName); LPENUM_SERVICE_STATUS TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount); @@ -167,12 +169,12 @@ INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, VOID ExportFile(PMAIN_WND_INFO Info); /* misc.c */ -INT AllocAndLoadString(OUT LPTSTR *lpTarget, +INT AllocAndLoadString(OUT LPWSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID); DWORD LoadAndFormatString(IN HINSTANCE hInstance, IN UINT uID, - OUT LPTSTR *lpTarget, + OUT LPWSTR *lpTarget, ...); BOOL StatusBarLoadAndFormatString(IN HWND hStatusBar, IN INT PartId, @@ -183,11 +185,11 @@ BOOL StatusBarLoadString(IN HWND hStatusBar, IN INT PartId, IN HINSTANCE hInstance, IN UINT uID); -INT GetTextFromEdit(OUT LPTSTR lpString, +INT GetTextFromEdit(OUT LPWSTR lpString, IN HWND hDlg, IN UINT Res); VOID GetError(VOID); -VOID DisplayString(PTCHAR); +VOID DisplayString(PWCHAR); HIMAGELIST InitImageList(UINT StartResource, UINT EndResource, UINT Width, diff --git a/reactos/base/applications/mscutils/servman/progress.c b/reactos/base/applications/mscutils/servman/progress.c index 8c9c843525e..74b944a256a 100644 --- a/reactos/base/applications/mscutils/servman/progress.c +++ b/reactos/base/applications/mscutils/servman/progress.c @@ -3,97 +3,227 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/progress.c * PURPOSE: Progress dialog box message handler - * COPYRIGHT: Copyright 2006-2010 Ged Murphy + * COPYRIGHT: Copyright 2006-2015 Ged Murphy * */ #include "precomp.h" -#define PROGRESSRANGE 20 +#define PROGRESS_RANGE 20 +#define PROGRESS_STEP_MAX 15 -VOID -CompleteProgressBar(HWND hProgDlg) +typedef struct _PROGRESS_DATA { - HWND hProgBar; - UINT Pos = 0; + HWND hDlg; + HWND hProgress; + LPWSTR ServiceName; + ULONG Action; + BOOL StopDepends; + LPWSTR ServiceList; - /* Get a handle to the progress bar */ - hProgBar = GetDlgItem(hProgDlg, - IDC_SERVCON_PROGRESS); - if (hProgBar) +} PROGRESS_DATA, *PPROGRESS_DATA; + + +static VOID +ResetProgressDialog(HWND hDlg, + LPWSTR ServiceName, + ULONG LabelId) +{ + LPWSTR lpProgStr; + + /* Load the label Id */ + if (AllocAndLoadString(&lpProgStr, + hInstance, + LabelId)) { - /* Get the current position */ - Pos = SendMessageW(hProgBar, - PBM_GETPOS, - 0, - 0); + /* Write it to the dialog */ + SendDlgItemMessageW(hDlg, + IDC_SERVCON_INFO, + WM_SETTEXT, + 0, + (LPARAM)lpProgStr); - /* Loop until we hit the max */ - while (Pos <= PROGRESSRANGE) - { - /* Increment the progress bar */ - SendMessageW(hProgBar, - PBM_DELTAPOS, - Pos, - 0); - - /* Wait for 15ms, it gives it a smooth feel */ - Sleep(15); - Pos++; - } + LocalFree(lpProgStr); } -} -VOID -IncrementProgressBar(HWND hProgDlg, - UINT NewPos) -{ - HWND hProgBar; - - /* Get a handle to the progress bar */ - hProgBar = GetDlgItem(hProgDlg, - IDC_SERVCON_PROGRESS); - if (hProgBar) - { - /* Do we want to increment the default amount? */ - if (NewPos == DEFAULT_STEP) - { - /* Yes, use the step value we set on create */ - SendMessageW(hProgBar, - PBM_STEPIT, - 0, - 0); - } - else - { - /* No, use the value passed */ - SendMessageW(hProgBar, - PBM_SETPOS, - NewPos, - 0); - } - } -} - -VOID -InitializeProgressDialog(HWND hProgDlg, - LPWSTR lpServiceName) -{ /* Write the service name to the dialog */ - SendDlgItemMessageW(hProgDlg, + SendDlgItemMessageW(hDlg, IDC_SERVCON_NAME, WM_SETTEXT, 0, - (LPARAM)lpServiceName); + (LPARAM)ServiceName); /* Set the progress bar to the start */ - SendDlgItemMessageW(hProgDlg, + SendDlgItemMessageW(hDlg, IDC_SERVCON_PROGRESS, PBM_SETPOS, 0, 0); } +unsigned int __stdcall ActionThread(void* Param) +{ + PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)Param; + + if (ProgressData->Action == ACTION_START) + { + /* Setup the progress dialog for this action */ + ResetProgressDialog(ProgressData->hDlg, + ProgressData->ServiceName, + IDS_PROGRESS_INFO_START); + + /* Start the service */ + if (DoStartService(ProgressData->ServiceName, + ProgressData->hProgress, + NULL)) + { + /* We're done, slide the progress bar up to the top */ + CompleteProgressBar(ProgressData->hProgress); + } + } + else if (ProgressData->Action == ACTION_STOP || ProgressData->Action == ACTION_RESTART) + { + /* Check if there are and dependants to stop */ + if (ProgressData->StopDepends && ProgressData->ServiceList) + { + LPWSTR lpStr = ProgressData->ServiceList; + + /* Loop through all the services in the list */ + for (;;) + { + /* Break when we hit the double null */ + if (*lpStr == L'\0' && *(lpStr + 1) == L'\0') + break; + + /* If this isn't our first time in the loop we'll + have been left on a null char */ + if (*lpStr == L'\0') + lpStr++; + + ResetProgressDialog(ProgressData->hDlg, + lpStr, + IDS_PROGRESS_INFO_STOP); + + /* Stop the requested service */ + if (DoStopService(ProgressData->ServiceName, + ProgressData->hProgress)) + { + CompleteProgressBar(ProgressData->hProgress); + } + + /* Move onto the next string */ + while (*lpStr != L'\0') + lpStr++; + } + } + + ResetProgressDialog(ProgressData->hDlg, + ProgressData->ServiceName, + IDS_PROGRESS_INFO_STOP); + + if (DoStopService(ProgressData->ServiceName, + ProgressData->hProgress)) + { + CompleteProgressBar(ProgressData->hProgress); + } + + + /* If this was a restart, we'll need to start the service back up */ + if (ProgressData->Action == ACTION_RESTART) + { + /* Setup the progress dialog for this action */ + ResetProgressDialog(ProgressData->hDlg, + ProgressData->ServiceName, + IDS_PROGRESS_INFO_START); + + /* Start the service */ + if (DoStartService(ProgressData->ServiceName, + ProgressData->hProgress, + NULL)) + { + /* We're done, slide the progress bar up to the top */ + CompleteProgressBar(ProgressData->hProgress); + } + } + } + else if (ProgressData->Action == ACTION_PAUSE) + { + /* Setup the progress dialog for this action */ + ResetProgressDialog(ProgressData->hDlg, + ProgressData->ServiceName, + IDS_PROGRESS_INFO_PAUSE); + + /* Pause the service */ + if (DoControlService(ProgressData->ServiceName, + ProgressData->hProgress, + SERVICE_CONTROL_PAUSE)) + { + /* We're done, slide the progress bar up to the top */ + CompleteProgressBar(ProgressData->hProgress); + } + } + else if (ProgressData->Action == ACTION_RESUME) + { + /* Setup the progress dialog for this action */ + ResetProgressDialog(ProgressData->hDlg, + ProgressData->ServiceName, + IDS_PROGRESS_INFO_RESUME); + + /* resume the service */ + if (DoControlService(ProgressData->ServiceName, + ProgressData->hProgress, + SERVICE_CONTROL_CONTINUE)) + { + /* We're done, slide the progress bar up to the top */ + CompleteProgressBar(ProgressData->hProgress); + } + } + + + EndDialog(ProgressData->hDlg, IDOK); + + _endthreadex(0); + return 0; +} + +static BOOL +InitDialog(HWND hDlg, + UINT Message, + WPARAM wParam, + LPARAM lParam) +{ + PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)lParam; + HANDLE hThread; + + ProgressData->hDlg = hDlg; + + /* Get a handle to the progress bar */ + ProgressData->hProgress = GetDlgItem(hDlg, + IDC_SERVCON_PROGRESS); + if (!ProgressData->hProgress) + return FALSE; + + /* Set the progress bar range */ + SendMessageW(ProgressData->hProgress, + PBM_SETRANGE, + 0, + MAKELPARAM(0, PROGRESS_RANGE)); + + /* Set the progress bar step */ + SendMessageW(ProgressData->hProgress, + PBM_SETSTEP, + (WPARAM)1, + 0); + + /* Create a thread to handle the service control */ + hThread = (HANDLE)_beginthreadex(NULL, 0, &ActionThread, ProgressData, 0, NULL); + if (!hThread) return FALSE; + + CloseHandle(hThread); + + return TRUE; +} + INT_PTR CALLBACK ProgressDialogProc(HWND hDlg, UINT Message, @@ -104,35 +234,21 @@ ProgressDialogProc(HWND hDlg, { case WM_INITDIALOG: { - HWND hProgBar; - - /* Get a handle to the progress bar */ - hProgBar = GetDlgItem(hDlg, - IDC_SERVCON_PROGRESS); - - /* Set the progress bar range */ - SendMessageW(hProgBar, - PBM_SETRANGE, - 0, - MAKELPARAM(0, PROGRESSRANGE)); - - /* Set the progress bar step */ - SendMessageW(hProgBar, - PBM_SETSTEP, - (WPARAM)1, - 0); + return InitDialog(hDlg, + Message, + wParam, + lParam); } - break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: - DestroyWindow(hDlg); - break; + EndDialog(hDlg, wParam); + break; } - break; + break; default: return FALSE; @@ -141,64 +257,115 @@ ProgressDialogProc(HWND hDlg, return TRUE; } -HWND -CreateProgressDialog(HWND hParent, - UINT LabelId) +VOID +CompleteProgressBar(HANDLE hProgress) { - HWND hProgDlg; - LPWSTR lpProgStr; + HWND hProgBar = (HWND)hProgress; + UINT Pos = 0; - /* open the progress dialog */ - hProgDlg = CreateDialogW(hInstance, - MAKEINTRESOURCEW(IDD_DLG_PROGRESS), - hParent, - ProgressDialogProc); - if (hProgDlg != NULL) + /* Get the current position */ + Pos = SendMessageW(hProgBar, + PBM_GETPOS, + 0, + 0); + + /* Loop until we hit the max */ + while (Pos <= PROGRESS_RANGE) { - /* Load the label Id */ - if (AllocAndLoadString(&lpProgStr, - hInstance, - LabelId)) - { - /* Write it to the dialog */ - SendDlgItemMessageW(hProgDlg, - IDC_SERVCON_INFO, - WM_SETTEXT, - 0, - (LPARAM)lpProgStr); + /* Increment the progress bar */ + SendMessageW(hProgBar, + PBM_DELTAPOS, + Pos, + 0); - LocalFree(lpProgStr); - } - - /* Finally, show and update the progress dialog */ - ShowWindow(hProgDlg, SW_SHOWNORMAL); - UpdateWindow(hProgDlg); - - // TODO: Add a message loop for it ? + /* Wait for 15ms to give it a smooth feel */ + Sleep(15); + Pos++; } +} - return hProgDlg; +VOID +IncrementProgressBar(HANDLE hProgress, + UINT Step) +{ + HWND hProgBar = (HWND)hProgress; + UINT Position; + + /* Don't allow the progress to reach to complete*/ + Position = SendMessageW(hProgBar, + PBM_GETPOS, + 0, + 0); + if (Position < PROGRESS_STEP_MAX) + { + /* Do we want to increment the default amount? */ + if (Step == DEFAULT_STEP) + { + /* Use the step value we set on create */ + SendMessageW(hProgBar, + PBM_STEPIT, + 0, + 0); + } + else + { + /* Use the value passed */ + SendMessageW(hProgBar, + PBM_SETPOS, + Step, + 0); + } + } } BOOL -DestroyProgressDialog(HWND hwnd, - BOOL bComplete) +RunActionWithProgress(HWND hParent, + LPWSTR ServiceName, + LPWSTR DisplayName, + UINT Action) { - BOOL bRet = FALSE; + PROGRESS_DATA ProgressData; + LPWSTR ServiceList; + BOOL StopDepends; + INT_PTR Result; - if (hwnd) + StopDepends = FALSE; + ServiceList = NULL; + + + /* Check if we'll be stopping the service */ + if (Action == ACTION_STOP || Action == ACTION_RESTART) { - if (bComplete) + /* Does the service have any dependent services which need stopping first */ + ServiceList = GetListOfServicesToStop(ServiceName); + if (ServiceList) { - /* Complete the progress bar */ - CompleteProgressBar(hwnd); + /* Ask the user if they want to stop the dependants */ + StopDepends = CreateStopDependsDialog(hParent, + ServiceName, + DisplayName, + ServiceList); - /* Wait, for asthetics */ - Sleep(500); + /* Exit early if the user decided not to stop the dependants */ + if (StopDepends == FALSE) + return FALSE; } - - bRet = DestroyWindow(hwnd); } - return bRet; + ProgressData.hDlg = NULL; + ProgressData.ServiceName = ServiceName; + ProgressData.Action = Action; + ProgressData.StopDepends = StopDepends; + ProgressData.ServiceList = ServiceList; + + Result = DialogBoxParamW(hInstance, + MAKEINTRESOURCEW(IDD_DLG_PROGRESS), + hParent, + ProgressDialogProc, + (LPARAM)&ProgressData); + + if (ServiceList) + HeapFree(GetProcessHeap(), 0, ServiceList); + + return (Result == IDOK); } diff --git a/reactos/base/applications/mscutils/servman/start.c b/reactos/base/applications/mscutils/servman/start.c index 1af77144bbd..51449a8bc36 100644 --- a/reactos/base/applications/mscutils/servman/start.c +++ b/reactos/base/applications/mscutils/servman/start.c @@ -3,26 +3,28 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/start.c * PURPOSE: Start a service - * COPYRIGHT: Copyright 2005-2010 Ged Murphy + * COPYRIGHT: Copyright 2005-2015 Ged Murphy * */ #include "precomp.h" -static BOOL -DoStartService(PMAIN_WND_INFO Info, - HWND hProgress, +#define MAX_WAIT_TIME 30000 + +BOOL +DoStartService(LPWSTR ServiceName, + HANDLE hProgress, LPWSTR lpStartParams) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus; DWORD BytesNeeded = 0; - DWORD dwStartTickCount; - DWORD dwOldCheckPoint; - DWORD dwWaitTime; - DWORD dwMaxWait; - BOOL bRet = FALSE; + DWORD StartTickCount; + DWORD OldCheckPoint; + DWORD WaitTime; + DWORD MaxWait; + BOOL Result = FALSE; BOOL bWhiteSpace = TRUE; LPWSTR lpChar; @@ -57,7 +59,7 @@ DoStartService(PMAIN_WND_INFO Info, return FALSE; /* Make the service name the first argument */ - lpArgsVector[0] = Info->pCurrentService->lpServiceName; + lpArgsVector[0] = ServiceName; /* Fill the arguments vector */ dwArgsCount = 1; @@ -84,130 +86,120 @@ DoStartService(PMAIN_WND_INFO Info, } } - hSCManager = OpenSCManager(NULL, - NULL, - SC_MANAGER_CONNECT); - if (hSCManager) + hSCManager = OpenSCManagerW(NULL, + NULL, + SC_MANAGER_CONNECT); + if (!hSCManager) { - hService = OpenService(hSCManager, - Info->pCurrentService->lpServiceName, - SERVICE_START | SERVICE_QUERY_STATUS); - if (hService) + if (lpArgsVector) + LocalFree((LPVOID)lpArgsVector); + return FALSE; + } + + hService = OpenServiceW(hSCManager, + ServiceName, + SERVICE_START | SERVICE_QUERY_STATUS); + if (!hService) + { + CloseServiceHandle(hSCManager); + if (lpArgsVector) + LocalFree((LPVOID)lpArgsVector); + return FALSE; + } + + /* Start the service */ + Result = StartServiceW(hService, + dwArgsCount, + lpArgsVector); + if (!Result && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) + { + /* If it's already running, just return TRUE */ + Result = TRUE; + } + else if (Result) + { + if (hProgress) { - if (hProgress) - { - /* Increment the progress bar */ - IncrementProgressBar(hProgress, DEFAULT_STEP); - } + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } - /* Start the service */ - bRet = StartService(hService, - dwArgsCount, - lpArgsVector); - if (!bRet && GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) - { - /* If it's already running, just return TRUE */ - bRet = TRUE; - } - else if (bRet) - { - bRet = FALSE; + /* Get the service status to check if it's running */ + Result = QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded); + if (Result) + { + Result = FALSE; + MaxWait = MAX_WAIT_TIME; + OldCheckPoint = ServiceStatus.dwCheckPoint; + StartTickCount = GetTickCount(); - /* Get the service status to check if it's running */ - if (QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &BytesNeeded)) + /* Loop until it's running */ + while (ServiceStatus.dwCurrentState != SERVICE_RUNNING) + { + /* Fixup the wait time */ + WaitTime = ServiceStatus.dwWaitHint / 10; + + if (WaitTime < 1000) WaitTime = 1000; + else if (WaitTime > 10000) WaitTime = 10000; + + /* We don't wanna wait for up to 10 secs without incrementing */ + for (int i = WaitTime / 1000; i > 0; i--) { - /* We don't want to wait for more than 30 seconds */ - dwMaxWait = 30000; - dwStartTickCount = GetTickCount(); - - /* Loop until it's running */ - while (ServiceStatus.dwCurrentState != SERVICE_RUNNING) + Sleep(1000); + if (hProgress) { - dwOldCheckPoint = ServiceStatus.dwCheckPoint; - dwWaitTime = ServiceStatus.dwWaitHint / 10; - - /* Get the latest status info */ - if (!QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &BytesNeeded)) - { - /* Something went wrong... */ - break; - } - - /* Is the service making progress? */ - if (ServiceStatus.dwCheckPoint > dwOldCheckPoint) - { - /* It is, get the latest tickcount to reset the max wait time */ - dwStartTickCount = GetTickCount(); - dwOldCheckPoint = ServiceStatus.dwCheckPoint; - IncrementProgressBar(hProgress, DEFAULT_STEP); - } - else - { - /* It's not, make sure we haven't exceeded our wait time */ - if (GetTickCount() >= dwStartTickCount + dwMaxWait) - { - /* We have, give up */ - break; - } - } - - /* Adjust the wait hint times */ - if (dwWaitTime < 200) - dwWaitTime = 200; - else if (dwWaitTime > 10000) - dwWaitTime = 10000; - - /* Wait before trying again */ - Sleep(dwWaitTime); + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); } } - if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) + + /* Get the latest status info */ + if (!QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) { - bRet = TRUE; + /* Something went wrong... */ + break; + } + + /* Is the service making progress? */ + if (ServiceStatus.dwCheckPoint > OldCheckPoint) + { + /* It is, get the latest tickcount to reset the max wait time */ + StartTickCount = GetTickCount(); + OldCheckPoint = ServiceStatus.dwCheckPoint; + } + else + { + /* It's not, make sure we haven't exceeded our wait time */ + if (GetTickCount() >= StartTickCount + MaxWait) + { + /* We have, give up */ + break; + } } } - - CloseServiceHandle(hService); } - CloseServiceHandle(hSCManager); + if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) + { + Result = TRUE; + } } + CloseServiceHandle(hService); + + CloseServiceHandle(hSCManager); + if (lpArgsVector) LocalFree((LPVOID)lpArgsVector); - return bRet; -} - -BOOL -DoStart(PMAIN_WND_INFO Info, LPWSTR lpStartParams) -{ - HWND hProgress; - BOOL bRet = FALSE; - - /* Create a progress window to track the progress of the stopping service */ - hProgress = CreateProgressDialog(Info->hMainWnd, - IDS_PROGRESS_INFO_START); - if (hProgress) - { - /* Set the service name and reset the progress bag */ - InitializeProgressDialog(hProgress, Info->pCurrentService->lpServiceName); - - /* Start the requested service */ - bRet = DoStartService(Info, hProgress, lpStartParams); - - /* Complete and destroy the progress bar */ - DestroyProgressDialog(hProgress, bRet); - } - - return bRet; + return Result; } diff --git a/reactos/base/applications/mscutils/servman/stop.c b/reactos/base/applications/mscutils/servman/stop.c index 980150958b6..9bad5b59a00 100644 --- a/reactos/base/applications/mscutils/servman/stop.c +++ b/reactos/base/applications/mscutils/servman/stop.c @@ -3,223 +3,107 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/mscutils/servman/stop.c * PURPOSE: Stops running a service - * COPYRIGHT: Copyright 2006-2010 Ged Murphy + * COPYRIGHT: Copyright 2006-2015 Ged Murphy * */ #include "precomp.h" -static BOOL -StopService(PMAIN_WND_INFO pInfo, - LPWSTR lpServiceName, - HWND hProgress OPTIONAL) +#define MAX_WAIT_TIME 30000 + +BOOL +DoStopService(_In_z_ LPWSTR ServiceName, + _In_opt_ HANDLE hProgress) { SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS_PROCESS ServiceStatus; - DWORD dwBytesNeeded; - DWORD dwStartTime; - DWORD dwTimeout; + DWORD BytesNeeded; + DWORD StartTime; + DWORD WaitTime; + DWORD Timeout; BOOL bRet = FALSE; + + hSCManager = OpenSCManagerW(NULL, + NULL, + SC_MANAGER_CONNECT); + if (!hSCManager) return FALSE; + + hService = OpenServiceW(hSCManager, + ServiceName, + SERVICE_STOP | SERVICE_QUERY_STATUS); + if (!hService) + { + CloseServiceHandle(hSCManager); + return FALSE; + } + if (hProgress) { - /* Set the service name and reset the progress bag */ - InitializeProgressDialog(hProgress, lpServiceName); + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); } - hSCManager = OpenSCManager(NULL, - NULL, - SC_MANAGER_CONNECT); - if (hSCManager) + /* Set the start and max wait times */ + StartTime = GetTickCount(); + Timeout = MAX_WAIT_TIME; + + /* Send the service the stop code */ + if (ControlService(hService, + SERVICE_CONTROL_STOP, + (LPSERVICE_STATUS)&ServiceStatus)) { - hService = OpenService(hSCManager, - lpServiceName, - SERVICE_STOP | SERVICE_QUERY_STATUS); - if (hService) + if (hProgress) { - if (hProgress) - { - /* Increment the progress bar */ - IncrementProgressBar(hProgress, DEFAULT_STEP); - } + /* Increment the progress bar */ + IncrementProgressBar(hProgress, DEFAULT_STEP); + } - /* Set the wait time to 30 secs */ - dwStartTime = GetTickCount(); - dwTimeout = 30000; + while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) + { + /* Fixup the wait time */ + WaitTime = ServiceStatus.dwWaitHint / 10; - /* Send the service the stop code */ - if (ControlService(hService, - SERVICE_CONTROL_STOP, - (LPSERVICE_STATUS)&ServiceStatus)) + if (WaitTime < 1000) WaitTime = 1000; + else if (WaitTime > 10000) WaitTime = 10000; + + /* We don't wanna wait for up to 10 secs without incrementing */ + for (int i = WaitTime / 1000; i > 0; i--) { + Sleep(1000); if (hProgress) { /* Increment the progress bar */ IncrementProgressBar(hProgress, DEFAULT_STEP); } + } - while (ServiceStatus.dwCurrentState != SERVICE_STOPPED) + if (QueryServiceStatusEx(hService, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) + { + /* Have we exceeded our wait time? */ + if (GetTickCount() - StartTime > Timeout) { - /* Don't sleep for more than 3 seconds */ - if (ServiceStatus.dwWaitHint > 3000) - ServiceStatus.dwWaitHint = 3000; - - Sleep(ServiceStatus.dwWaitHint); - - if (hProgress) - { - /* Increment the progress bar */ - IncrementProgressBar(hProgress, DEFAULT_STEP); - } - - if (QueryServiceStatusEx(hService, - SC_STATUS_PROCESS_INFO, - (LPBYTE)&ServiceStatus, - sizeof(SERVICE_STATUS_PROCESS), - &dwBytesNeeded)) - { - /* Have we exceeded our wait time? */ - if (GetTickCount() - dwStartTime > dwTimeout) - { - /* Yep, give up */ - break; - } - } - } - - /* If the service is stopped, return TRUE */ - if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) - { - bRet = TRUE; + /* Yep, give up */ + break; } } - - CloseServiceHandle(hService); } - CloseServiceHandle(hSCManager); - } - - return bRet; -} - -static BOOL -StopDependantServices(PMAIN_WND_INFO pInfo, - LPWSTR lpServiceList, - HWND hProgress OPTIONAL) -{ - LPWSTR lpStr; - BOOL bRet = FALSE; - - lpStr = lpServiceList; - - /* Loop through all the services in the list */ - while (TRUE) - { - /* Break when we hit the double null */ - if (*lpStr == L'\0' && *(lpStr + 1) == L'\0') - break; - - /* If this isn't our first time in the loop we'll - have been left on a null char */ - if (*lpStr == L'\0') - lpStr++; - - /* Stop the requested service */ - bRet = StopService(pInfo, - lpStr, - hProgress); - - /* Complete the progress bar if we succeeded */ - if (bRet) + /* If the service is stopped, return TRUE */ + if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) { - CompleteProgressBar(hProgress); - } - - /* Move onto the next string */ - while (*lpStr != L'\0') - lpStr++; - } - - return bRet; -} - -BOOL -DoStop(PMAIN_WND_INFO pInfo) -{ - HWND hProgress; - LPWSTR lpServiceList; - BOOL bRet = FALSE; - BOOL bStopMainService = TRUE; - - if (pInfo) - { - /* Does the service have any dependent services which need stopping first */ - lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName); - if (lpServiceList) - { - /* Tag the service list to the main wnd info */ - pInfo->pTag = (PVOID)lpServiceList; - - /* List them and ask the user if they want to stop them */ - if (DialogBoxParamW(hInstance, - MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP), - pInfo->hMainWnd, - StopDependsDialogProc, - (LPARAM)pInfo) == IDOK) - { - /* Create a progress window to track the progress of the stopping services */ - hProgress = CreateProgressDialog(pInfo->hMainWnd, - IDS_PROGRESS_INFO_STOP); - - /* Stop all the dependant services */ - StopDependantServices(pInfo, lpServiceList, hProgress); - - /* Now stop the requested one */ - bRet = StopService(pInfo, - pInfo->pCurrentService->lpServiceName, - hProgress); - - /* We've already stopped the main service, don't try to stop it again */ - bStopMainService = FALSE; - - if (hProgress) - { - /* Complete and destroy the progress bar */ - DestroyProgressDialog(hProgress, TRUE); - } - } - else - { - /* Don't stop the main service if the user selected not to */ - bStopMainService = FALSE; - } - - HeapFree(GetProcessHeap(), - 0, - lpServiceList); - } - - /* If the service has no running dependents, then we stop it here */ - if (bStopMainService) - { - /* Create a progress window to track the progress of the stopping service */ - hProgress = CreateProgressDialog(pInfo->hMainWnd, - IDS_PROGRESS_INFO_STOP); - - /* Stop the requested service */ - bRet = StopService(pInfo, - pInfo->pCurrentService->lpServiceName, - hProgress); - - if (hProgress) - { - /* Complete and destroy the progress bar */ - DestroyProgressDialog(hProgress, TRUE); - } + bRet = TRUE; } } + CloseServiceHandle(hService); + + CloseServiceHandle(hSCManager); + return bRet; } diff --git a/reactos/base/applications/mscutils/servman/stop_dependencies.c b/reactos/base/applications/mscutils/servman/stop_dependencies.c index 99b60bbffe9..31588388dcd 100644 --- a/reactos/base/applications/mscutils/servman/stop_dependencies.c +++ b/reactos/base/applications/mscutils/servman/stop_dependencies.c @@ -3,12 +3,20 @@ * 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 + * COPYRIGHT: Copyright 2006-2015 Ged Murphy * */ #include "precomp.h" +typedef struct _STOP_DATA +{ + LPWSTR ServiceName; + LPWSTR DisplayName; + LPWSTR ServiceList; + +} STOP_DATA, *PSTOP_DATA; + static LPWSTR AddServiceToList(LPWSTR *lpServiceList, LPWSTR lpServiceToAdd) @@ -46,7 +54,7 @@ AddServiceToList(LPWSTR *lpServiceList, dwCurSize = 0; /* Get the list size */ - while (TRUE) + for (;;) { /* Break when we hit the double null */ if (*ptr == L'\0' && *(ptr + 1) == L'\0') @@ -98,13 +106,6 @@ BuildListOfServicesToStop(LPWSTR *lpServiceList, if (lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOPPED && lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING) { - /* 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); @@ -143,7 +144,7 @@ AddServiceNamesToStop(HWND hServiceListBox, lpStr = lpServiceList; /* Loop through all the services in the list */ - while (TRUE) + for (;;) { /* Break when we hit the double null */ if (*lpStr == L'\0' && *(lpStr + 1) == L'\0') @@ -174,117 +175,100 @@ AddServiceNamesToStop(HWND hServiceListBox, } static BOOL -DoInitDependsDialog(PMAIN_WND_INFO pInfo, - HWND hDlg) +InitDialog(HWND hDlg, + UINT Message, + WPARAM wParam, + LPARAM lParam) { + PSTOP_DATA StopData; HWND hServiceListBox; LPWSTR lpPartialStr, lpStr; DWORD fullLen; HICON hIcon = NULL; BOOL bRet = FALSE; - if (pInfo) + StopData = (PSTOP_DATA)lParam; + + + /* 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) { - /* 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; - } - - LocalFree(lpPartialStr); - } - - /* Display the list of services which need stopping */ - hServiceListBox = GetDlgItem(hDlg, - IDC_STOP_DEPENDS_LB); - if (hServiceListBox) - { - AddServiceNamesToStop(hServiceListBox, - (LPWSTR)pInfo->pTag); - } + /* 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(StopData->DisplayName) + 1; + + lpStr = HeapAlloc(ProcessHeap, + 0, + fullLen * sizeof(WCHAR)); + if (lpStr) + { + /* Add the service name to the depends note */ + _snwprintf(lpStr, + fullLen, + lpPartialStr, + StopData->DisplayName); + + /* Add the string to the dialog */ + SendDlgItemMessageW(hDlg, + IDC_STOP_DEPENDS, + WM_SETTEXT, + 0, + (LPARAM)lpStr); + + HeapFree(ProcessHeap, + 0, + lpStr); + + bRet = TRUE; + } + + LocalFree(lpPartialStr); + } + + /* Display the list of services which need stopping */ + hServiceListBox = GetDlgItem(hDlg, IDC_STOP_DEPENDS_LB); + if (hServiceListBox) + { + AddServiceNamesToStop(hServiceListBox, + (LPWSTR)StopData->ServiceList); + } + return bRet; } INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, - UINT message, + 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) + switch (Message) { case WM_INITDIALOG: { - BOOL bRet = FALSE; - - pInfo = (PMAIN_WND_INFO)lParam; - if (pInfo != NULL) - { - bRet = DoInitDependsDialog(pInfo, hDlg); - } - - return bRet; + return InitDialog(hDlg, + Message, + wParam, + lParam); } case WM_COMMAND: @@ -304,3 +288,27 @@ StopDependsDialogProc(HWND hDlg, return FALSE; } + +BOOL +CreateStopDependsDialog(HWND hParent, + LPWSTR ServiceName, + LPWSTR DisplayName, + LPWSTR ServiceList) +{ + STOP_DATA StopData; + INT_PTR Result; + + StopData.ServiceName = ServiceName; + StopData.DisplayName = DisplayName; + StopData.ServiceList = ServiceList; + + Result = DialogBoxParamW(hInstance, + MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP), + hParent, + StopDependsDialogProc, + (LPARAM)&StopData); + if (Result == IDOK) + return TRUE; + + return FALSE; +} \ No newline at end of file