Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427/* * PROJECT: ReactOS Services * 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-2015 Ged Murphy <gedmurphy@reactos.org> * */
#include "precomp.h"
#include <process.h>
#define PROGRESS_RANGE 20#define PROGRESS_STEP_MAX 15
typedef struct _PROGRESS_DATA{ HWND hDlg; HWND hProgress; LPWSTR ServiceName; ULONG Action; BOOL StopDepends; LPWSTR ServiceList; PVOID Param;
} PROGRESS_DATA, *PPROGRESS_DATA;
VOID ShowError(DWORD dwLastError){ LPWSTR lpMsg;
if (!FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwLastError, LANG_USER_DEFAULT, (LPWSTR)&lpMsg, 0, NULL)) { return; }
MessageBoxW(NULL, lpMsg, NULL, MB_OK | MB_ICONERROR); LocalFree(lpMsg);}
static VOIDResetProgressDialog(HWND hDlg, LPWSTR ServiceName, ULONG LabelId){ LPWSTR lpProgStr;
/* Load the label Id */ if (AllocAndLoadString(&lpProgStr, hInstance, LabelId)) { /* Write it to the dialog */ SendDlgItemMessageW(hDlg, IDC_SERVCON_INFO, WM_SETTEXT, 0, (LPARAM)lpProgStr);
LocalFree(lpProgStr); }
/* Write the service name to the dialog */ SendDlgItemMessageW(hDlg, IDC_SERVCON_NAME, WM_SETTEXT, 0, (LPARAM)ServiceName);
/* Set the progress bar to the start */ SendDlgItemMessageW(hDlg, IDC_SERVCON_PROGRESS, PBM_SETPOS, 0, 0);}
unsigned int __stdcall ActionThread(void* Param){ PPROGRESS_DATA ProgressData = (PPROGRESS_DATA)Param; DWORD dwResult;
if (ProgressData->Action == ACTION_START) { /* Setup the progress dialog for this action */ ResetProgressDialog(ProgressData->hDlg, ProgressData->ServiceName, IDS_PROGRESS_INFO_START);
/* Start the service */ dwResult = DoStartService(ProgressData->ServiceName, ProgressData->hProgress, ProgressData->Param); if (dwResult == ERROR_SUCCESS) { /* We're done, slide the progress bar up to the top */ CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); } } 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 */ dwResult = DoStopService(ProgressData->ServiceName, ProgressData->hProgress); if (dwResult == ERROR_SUCCESS) { CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); }
/* Move onto the next string */ while (*lpStr != L'\0') lpStr++; } }
ResetProgressDialog(ProgressData->hDlg, ProgressData->ServiceName, IDS_PROGRESS_INFO_STOP);
dwResult = DoStopService(ProgressData->ServiceName, ProgressData->hProgress); if (dwResult == ERROR_SUCCESS) { CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); }
/* 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 */ dwResult = DoStartService(ProgressData->ServiceName, ProgressData->hProgress, NULL); if (dwResult == ERROR_SUCCESS) { /* We're done, slide the progress bar up to the top */ CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); } } } 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 */ dwResult = DoControlService(ProgressData->ServiceName, ProgressData->hProgress, SERVICE_CONTROL_PAUSE); if (dwResult == ERROR_SUCCESS) { /* We're done, slide the progress bar up to the top */ CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); } } 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 */ dwResult = DoControlService(ProgressData->ServiceName, ProgressData->hProgress, SERVICE_CONTROL_CONTINUE); if (dwResult == ERROR_SUCCESS) { /* We're done, slide the progress bar up to the top */ CompleteProgressBar(ProgressData->hProgress); } else { ShowError(dwResult); } }
EndDialog(ProgressData->hDlg, IDOK);
_endthreadex(0); return 0;}
static BOOLInitProgressDialog(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 CALLBACKProgressDialogProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam){ switch(Message) { case WM_INITDIALOG: { return InitProgressDialog(hDlg, Message, wParam, lParam); }
case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: EndDialog(hDlg, wParam); break;
} break;
default: return FALSE; }
return TRUE;}
VOIDCompleteProgressBar(HANDLE hProgress){ HWND hProgBar = (HWND)hProgress; UINT Pos = 0;
/* Get the current position */ Pos = SendMessageW(hProgBar, PBM_GETPOS, 0, 0);
/* Loop until we hit the max */ while (Pos <= PROGRESS_RANGE) { /* Increment the progress bar */ SendMessageW(hProgBar, PBM_DELTAPOS, Pos, 0);
/* Wait for 15ms to give it a smooth feel */ Sleep(15); Pos++; }}
VOIDIncrementProgressBar(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); } }}
BOOLRunActionWithProgress(HWND hParent, LPWSTR ServiceName, LPWSTR DisplayName, UINT Action, PVOID Param){ PROGRESS_DATA ProgressData; LPWSTR ServiceList; BOOL StopDepends; INT_PTR Result;
StopDepends = FALSE; ServiceList = NULL;
/* Check if we'll be stopping the service */ if (Action == ACTION_STOP || Action == ACTION_RESTART) { /* Does the service have any dependent services which need stopping first */ ServiceList = GetListOfServicesToStop(ServiceName); if (ServiceList) { /* Ask the user if they want to stop the dependants */ StopDepends = CreateStopDependsDialog(hParent, ServiceName, DisplayName, ServiceList);
/* Exit early if the user decided not to stop the dependants */ if (StopDepends == FALSE) { HeapFree(GetProcessHeap(), 0, ServiceList); return FALSE; } } }
ProgressData.hDlg = NULL; ProgressData.ServiceName = ServiceName; ProgressData.Action = Action; ProgressData.StopDepends = StopDepends; ProgressData.ServiceList = ServiceList; ProgressData.Param = Param;
Result = DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_DLG_PROGRESS), hParent, ProgressDialogProc, (LPARAM)&ProgressData);
if (ServiceList) HeapFree(GetProcessHeap(), 0, ServiceList);
return (Result == IDOK);}