diff --git a/reactos/base/applications/mscutils/servman/dependencies.c b/reactos/base/applications/mscutils/servman/dependencies.c new file mode 100644 index 00000000000..976f69fa598 --- /dev/null +++ b/reactos/base/applications/mscutils/servman/dependencies.c @@ -0,0 +1,228 @@ +/* + * 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" + +LPENUM_SERVICE_STATUS +GetDependentServices(SC_HANDLE hService, + LPDWORD lpdwCount) +{ + LPENUM_SERVICE_STATUS lpDependencies; + DWORD dwBytesNeeded; + DWORD dwCount; + + if (EnumDependentServices(hService, + SERVICE_ACTIVE, + NULL, + 0, + &dwBytesNeeded, + &dwCount)) + { + /* 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) + { + if (EnumDependentServices(hService, + SERVICE_ACTIVE, + lpDependencies, + dwBytesNeeded, + &dwBytesNeeded, + &dwCount)) + { + *lpdwCount = dwCount; + } + else + { + HeapFree(ProcessHeap, + 0, + lpDependencies); + + lpDependencies = NULL; + } + } + } + + return lpDependencies; + +} + + +BOOL +HasDependentServices(SC_HANDLE hService) +{ + DWORD dwBytesNeeded, dwCount; + BOOL bRet = FALSE; + + if (hService) + { + if (!EnumDependentServices(hService, + SERVICE_ACTIVE, + NULL, + 0, + &dwBytesNeeded, + &dwCount)) + { + if (GetLastError() == ERROR_MORE_DATA) + bRet = TRUE; + } + } + + return bRet; +} + +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 */ + lpDependencies = GetDependentServices(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/lang/en-US.rc b/reactos/base/applications/mscutils/servman/lang/en-US.rc index f4175112dfc..eabb6adecd9 100644 --- a/reactos/base/applications/mscutils/servman/lang/en-US.rc +++ b/reactos/base/applications/mscutils/servman/lang/en-US.rc @@ -205,6 +205,7 @@ STRINGTABLE DISCARDABLE BEGIN IDS_NUM_SERVICES "Num Services: %d" IDS_STOP_DEPENDS "When %s stops, these other services will also stop" + IDS_NO_DEPENDS "" IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." END diff --git a/reactos/base/applications/mscutils/servman/mainwnd.c b/reactos/base/applications/mscutils/servman/mainwnd.c index 77d0bfa0739..6c72e0a91b5 100644 --- a/reactos/base/applications/mscutils/servman/mainwnd.c +++ b/reactos/base/applications/mscutils/servman/mainwnd.c @@ -288,8 +288,9 @@ pCreateToolbar(PMAIN_WND_INFO Info) hImageList = InitImageList(IDB_PROP, IDB_RESTART, - 16, - 16); + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CXSMICON), + IMAGE_BITMAP); if (hImageList == NULL) return FALSE; @@ -890,7 +891,7 @@ CreateMainWindow(LPCTSTR lpCaption, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, - 650, + 680, 450, NULL, NULL, diff --git a/reactos/base/applications/mscutils/servman/misc.c b/reactos/base/applications/mscutils/servman/misc.c index 6556df59bc8..3735eb76c9b 100644 --- a/reactos/base/applications/mscutils/servman/misc.c +++ b/reactos/base/applications/mscutils/servman/misc.c @@ -219,42 +219,59 @@ HIMAGELIST InitImageList(UINT StartResource, UINT EndResource, UINT Width, - UINT Height) + UINT Height, + ULONG type) { - HBITMAP hBitmap; - HIMAGELIST hImageList; + HANDLE hImage; + HIMAGELIST himl; UINT i; - INT Ret; + INT ret; /* Create the toolbar icon image list */ - hImageList = ImageList_Create(Width, - Height, - ILC_MASK | ILC_COLOR24, - EndResource - StartResource, - 0); - if (hImageList == NULL) + himl = ImageList_Create(Width, + Height, + ILC_MASK | ILC_COLOR32, + EndResource - StartResource, + 0); + if (himl == NULL) return NULL; - /* Add all icons to the image list */ - for (i = StartResource; i <= EndResource; i++) + ret = 0; + for (i = StartResource; i <= EndResource && ret != -1; i++) { - hBitmap = (HBITMAP) LoadImage(hInstance, - MAKEINTRESOURCE(i), - IMAGE_BITMAP, - Width, - Height, - LR_LOADTRANSPARENT); - if (hBitmap == NULL) - return NULL; + hImage = LoadImage(hInstance, + MAKEINTRESOURCE(i), + type, + Width, + Height, + LR_LOADTRANSPARENT); + if (hImage == NULL) + { + ImageList_Destroy(himl); + himl = NULL; + break; + } - Ret = ImageList_AddMasked(hImageList, - hBitmap, - RGB(255, 0, 128)); - if (Ret == -1) - return NULL; + if (type == IMAGE_BITMAP) + { + ret = ImageList_AddMasked(himl, + hImage, + RGB(255, 0, 128)); + } + else if (type == IMAGE_ICON) + { + ret = ImageList_AddIcon(himl, + hImage); + } - DeleteObject(hBitmap); + DeleteObject(hImage); } - return hImageList; + if (ret == -1) + { + ImageList_Destroy(himl); + himl = NULL; + } + + return himl; } diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index 796bb321167..6842de127f2 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -75,6 +75,14 @@ BOOL CreateListView(PMAIN_WND_INFO Info); /* start */ BOOL DoStart(PMAIN_WND_INFO Info); +/* 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 hProgDlg, DWORD Control); BOOL DoStop(PMAIN_WND_INFO Info); @@ -97,12 +105,31 @@ BOOL RefreshServiceList(PMAIN_WND_INFO Info); BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService); BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices); -/* reg */ -BOOL SetDescription(LPTSTR, LPTSTR); +/* dependencies */ +LPENUM_SERVICE_STATUS GetDependentServices(SC_HANDLE hService, LPDWORD lpdwCount); +BOOL HasDependentServices(SC_HANDLE hService); +INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); /* propsheet.c */ +typedef struct _SERVICEPROPSHEET +{ + PMAIN_WND_INFO Info; + ENUM_SERVICE_STATUS_PROCESS *pService; + HIMAGELIST hDependsImageList; +} SERVICEPROPSHEET, *PSERVICEPROPSHEET; + LONG APIENTRY OpenPropSheet(PMAIN_WND_INFO Info); +/* propsheet window procs */ +INT_PTR CALLBACK DependenciesPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + /* export.c */ VOID ExportFile(PMAIN_WND_INFO Info); @@ -128,9 +155,10 @@ INT GetTextFromEdit(OUT LPTSTR lpString, IN UINT Res); VOID GetError(VOID); VOID DisplayString(PTCHAR); -HIMAGELIST InitImageList(UINT NumButtons, - UINT StartResource, +HIMAGELIST InitImageList(UINT StartResource, + UINT EndResource, UINT Width, - UINT Height); + UINT Height, + ULONG type); #endif /* __SERVMAN_PRECOMP_H */ diff --git a/reactos/base/applications/mscutils/servman/propsheet.c b/reactos/base/applications/mscutils/servman/propsheet.c index bd52dd48ae0..17193cb4899 100644 --- a/reactos/base/applications/mscutils/servman/propsheet.c +++ b/reactos/base/applications/mscutils/servman/propsheet.c @@ -9,429 +9,6 @@ #include "precomp.h" -typedef struct _SERVICEPROPSHEET -{ - PMAIN_WND_INFO Info; - ENUM_SERVICE_STATUS_PROCESS *pService; -} SERVICEPROPSHEET, *PSERVICEPROPSHEET; - - -static VOID -SetButtonStates(PSERVICEPROPSHEET dlgInfo, - HWND hwndDlg) -{ - HWND hButton; - LPQUERY_SERVICE_CONFIG lpServiceConfig; - DWORD Flags, State; - UINT i; - - Flags = dlgInfo->pService->ServiceStatusProcess.dwControlsAccepted; - State = dlgInfo->pService->ServiceStatusProcess.dwCurrentState; - - for (i = IDC_START; i <= IDC_RESUME; i++) - { - hButton = GetDlgItem(hwndDlg, i); - EnableWindow (hButton, FALSE); - } - - lpServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName); - if (State == SERVICE_STOPPED && - lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED) - { - hButton = GetDlgItem(hwndDlg, IDC_START); - EnableWindow (hButton, TRUE); - HeapFree(GetProcessHeap(), 0, lpServiceConfig); - } - else if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) ) - { - hButton = GetDlgItem(hwndDlg, IDC_STOP); - EnableWindow (hButton, TRUE); - } - else if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) ) - { - hButton = GetDlgItem(hwndDlg, IDC_PAUSE); - EnableWindow (hButton, TRUE); - } - - /* set the main toolbar */ - SetMenuAndButtonStates(dlgInfo->Info); -} - - -static VOID -SetServiceStatusText(PSERVICEPROPSHEET dlgInfo, - HWND hwndDlg) -{ - LPTSTR lpStatus; - UINT id; - - if (dlgInfo->pService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) - { - id = IDS_SERVICES_STARTED; - } - else - { - id = IDS_SERVICES_STOPPED; - } - - if (AllocAndLoadString(&lpStatus, - hInstance, - id)) - { - SendDlgItemMessage(hwndDlg, - IDC_SERV_STATUS, - WM_SETTEXT, - 0, - (LPARAM)lpStatus); - LocalFree(lpStatus); - } -} - -/* - * Fills the 'startup type' combo box with possible - * values and sets it to value of the selected item - */ -static VOID -SetStartupType(LPTSTR lpServiceName, - HWND hwndDlg) -{ - HWND hList; - LPQUERY_SERVICE_CONFIG pServiceConfig; - LPTSTR lpBuf; - DWORD StartUp = 0; - UINT i; - - hList = GetDlgItem(hwndDlg, IDC_START_TYPE); - - for (i = IDS_SERVICES_AUTO; i <= IDS_SERVICES_DIS; i++) - { - if (AllocAndLoadString(&lpBuf, - hInstance, - i)) - { - SendMessage(hList, - CB_ADDSTRING, - 0, - (LPARAM)lpBuf); - LocalFree(lpBuf); - } - } - - pServiceConfig = GetServiceConfig(lpServiceName); - - if (pServiceConfig) - { - switch (pServiceConfig->dwStartType) - { - case SERVICE_AUTO_START: StartUp = 0; break; - case SERVICE_DEMAND_START: StartUp = 1; break; - case SERVICE_DISABLED: StartUp = 2; break; - } - - SendMessage(hList, - CB_SETCURSEL, - StartUp, - 0); - - HeapFree(ProcessHeap, - 0, - pServiceConfig); - } -} - - -/* - * Populates the General Properties dialog with - * the relevant service information - */ -static VOID -InitGeneralPage(PSERVICEPROPSHEET dlgInfo, - HWND hwndDlg) -{ - LPQUERY_SERVICE_CONFIG pServiceConfig; - LPTSTR lpDescription; - - /* set the service name */ - SendDlgItemMessage(hwndDlg, - IDC_SERV_NAME, - WM_SETTEXT, - 0, - (LPARAM)dlgInfo->pService->lpServiceName); - - /* set the display name */ - SendDlgItemMessage(hwndDlg, - IDC_DISP_NAME, - WM_SETTEXT, - 0, - (LPARAM)dlgInfo->pService->lpDisplayName); - - /* set the description */ - if ((lpDescription = GetServiceDescription(dlgInfo->pService->lpServiceName))) - { - SendDlgItemMessage(hwndDlg, - IDC_DESCRIPTION, - WM_SETTEXT, - 0, - (LPARAM)lpDescription); - - HeapFree(ProcessHeap, - 0, - lpDescription); - } - - pServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName); - if (pServiceConfig) - { - SendDlgItemMessage(hwndDlg, - IDC_EXEPATH, - WM_SETTEXT, - 0, - (LPARAM)pServiceConfig->lpBinaryPathName); - HeapFree(ProcessHeap, - 0, - pServiceConfig); - } - - - /* set startup type */ - SetStartupType(dlgInfo->pService->lpServiceName, hwndDlg); - - SetServiceStatusText(dlgInfo, - hwndDlg); - - if (dlgInfo->Info->bIsUserAnAdmin) - { - HWND hEdit = GetDlgItem(hwndDlg, - IDC_EDIT); - EnableWindow(hEdit, - TRUE); - } -} - - -VOID -SaveDlgInfo(PSERVICEPROPSHEET dlgInfo, - HWND hwndDlg) -{ - LPQUERY_SERVICE_CONFIG pServiceConfig = NULL; - HWND hList; - DWORD StartUp; - - pServiceConfig = HeapAlloc(ProcessHeap, - HEAP_ZERO_MEMORY, - sizeof(*pServiceConfig)); - if (pServiceConfig) - { - pServiceConfig->dwServiceType = SERVICE_NO_CHANGE; - pServiceConfig->dwErrorControl = SERVICE_NO_CHANGE; - - hList = GetDlgItem(hwndDlg, IDC_START_TYPE); - StartUp = SendMessage(hList, - 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 (SetServiceConfig(pServiceConfig, - dlgInfo->pService->lpServiceName, - NULL)) - { - ChangeListViewText(dlgInfo->Info, - dlgInfo->pService, - LVSTARTUP); - } - - HeapFree(ProcessHeap, - 0, - pServiceConfig); - } -} - - -/* - * General Property dialog callback. - * Controls messages to the General dialog - */ -static INT_PTR CALLBACK -GeneralPageProc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - PSERVICEPROPSHEET dlgInfo; - - /* Get the window context */ - dlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg, - GWLP_USERDATA); - if (dlgInfo == NULL && uMsg != WM_INITDIALOG) - { - return FALSE; - } - - switch (uMsg) - { - case WM_INITDIALOG: - { - dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam); - if (dlgInfo != NULL) - { - SetWindowLongPtr(hwndDlg, - GWLP_USERDATA, - (LONG_PTR)dlgInfo); - InitGeneralPage(dlgInfo, hwndDlg); - SetButtonStates(dlgInfo, hwndDlg); - } - } - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDC_START_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - PropSheet_Changed(GetParent(hwndDlg), hwndDlg); - break; - - case IDC_START: - if (DoStart(dlgInfo->Info)) - { - UpdateServiceStatus(dlgInfo->pService); - ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); - SetButtonStates(dlgInfo, hwndDlg); - SetServiceStatusText(dlgInfo, hwndDlg); - } - break; - - case IDC_STOP: - if (DoStop(dlgInfo->Info)) - { - UpdateServiceStatus(dlgInfo->pService); - ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); - SetButtonStates(dlgInfo, hwndDlg); - SetServiceStatusText(dlgInfo, hwndDlg); - } - break; - - case IDC_PAUSE: - if (DoPause(dlgInfo->Info)) - { - UpdateServiceStatus(dlgInfo->pService); - ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); - SetButtonStates(dlgInfo, hwndDlg); - SetServiceStatusText(dlgInfo, hwndDlg); - } - break; - - case IDC_RESUME: - if (DoResume(dlgInfo->Info)) - { - UpdateServiceStatus(dlgInfo->pService); - ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); - SetButtonStates(dlgInfo, hwndDlg); - SetServiceStatusText(dlgInfo, hwndDlg); - } - break; - - case IDC_EDIT: - { - HWND hName, hDesc, hExePath; - - hName = GetDlgItem(hwndDlg, IDC_DISP_NAME); - hDesc = GetDlgItem(hwndDlg, IDC_DESCRIPTION); - hExePath = GetDlgItem(hwndDlg, IDC_EXEPATH); - - SendMessage(hName, EM_SETREADONLY, FALSE, 0); - SendMessage(hDesc, EM_SETREADONLY, FALSE, 0); - SendMessage(hExePath, EM_SETREADONLY, FALSE, 0); - } - break; - - case IDC_START_PARAM: - PropSheet_Changed(GetParent(hwndDlg), hwndDlg); - break; - } - break; - - case WM_NOTIFY: - { - LPNMHDR lpnm = (LPNMHDR)lParam; - - switch (lpnm->code) - { - case PSN_APPLY: - SaveDlgInfo(dlgInfo, hwndDlg); - SetButtonStates(dlgInfo, hwndDlg); - break; - } - } - break; - } - - return FALSE; -} -/* -static VOID -InitDependPage(PSERVICEPROPSHEET dlgInfo, - HWND hwndDlg) -{ - - -} - - - -* - * Dependancies Property dialog callback. - * Controls messages to the Dependancies dialog - * -static INT_PTR CALLBACK -DependanciesPageProc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - PSERVICEPROPSHEET dlgInfo; - - dlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg, - GWLP_USERDATA); - - if (dlgInfo == NULL && uMsg != WM_INITDIALOG) - { - return FALSE; - } - - switch (uMsg) - { - case WM_INITDIALOG: - { - dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam); - if (dlgInfo != NULL) - { - SetWindowLongPtr(hwndDlg, - GWLP_USERDATA, - (LONG_PTR)dlgInfo); - - InitDependPage(dlgInfo, hwndDlg); - } - } - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - - } - break; - } - - return FALSE; -} -*/ static VOID InitPropSheetPage(PROPSHEETPAGE *psp, @@ -453,7 +30,7 @@ LONG APIENTRY OpenPropSheet(PMAIN_WND_INFO Info) { PROPSHEETHEADER psh; - PROPSHEETPAGE psp[1]; + PROPSHEETPAGE psp[2]; PSERVICEPROPSHEET pServicePropSheet; LONG Ret = 0; @@ -481,7 +58,7 @@ OpenPropSheet(PMAIN_WND_INFO Info) InitPropSheetPage(&psp[0], pServicePropSheet, IDD_DLG_GENERAL, GeneralPageProc); //InitPropSheetPage(&psp[1], Info, IDD_DLG_GENERAL, LogonPageProc); //InitPropSheetPage(&psp[2], Info, IDD_DLG_GENERAL, RecoveryPageProc); - //InitPropSheetPage(&psp[1], pServicePropSheet, IDD_DLG_DEPEND, DependanciesPageProc); + InitPropSheetPage(&psp[1], pServicePropSheet, IDD_DLG_DEPEND, DependenciesPageProc); Ret = (LONG)(PropertySheet(&psh) != -1); diff --git a/reactos/base/applications/mscutils/servman/propsheet_depends.c b/reactos/base/applications/mscutils/servman/propsheet_depends.c new file mode 100644 index 00000000000..69354dea2a1 --- /dev/null +++ b/reactos/base/applications/mscutils/servman/propsheet_depends.c @@ -0,0 +1,314 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/mscutils/servman/propsheet_depends.c + * PURPOSE: Property dialog box message handler + * COPYRIGHT: Copyright 2006-2009 Ged Murphy + * + */ + +#include "precomp.h" + + +static HTREEITEM +AddItemToTreeView(HWND hTreeView, + HTREEITEM hRoot, + LPTSTR lpLabel, + ULONG serviceType) +{ + TV_ITEM tvi; + TV_INSERTSTRUCT tvins; + + ZeroMemory(&tvi, sizeof(tvi)); + ZeroMemory(&tvins, sizeof(tvins)); + + tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE; + tvi.pszText = lpLabel; + tvi.cchTextMax = lstrlen(lpLabel); + + if (serviceType == SERVICE_WIN32_OWN_PROCESS || + serviceType == SERVICE_WIN32_SHARE_PROCESS) + { + tvi.iImage = 1; + tvi.iSelectedImage = 1; + } + else if (serviceType == SERVICE_KERNEL_DRIVER || + serviceType == SERVICE_FILE_SYSTEM_DRIVER) + { + tvi.iImage = 2; + tvi.iSelectedImage = 2; + } + else + { + tvi.iImage = 0; + tvi.iSelectedImage = 0; + } + + tvins.item = tvi; + tvins.hParent = hRoot; + + return TreeView_InsertItem(hTreeView, &tvins); +} + +static VOID +AddServiceDependency(PSERVICEPROPSHEET dlgInfo, + HWND hTreeView, + SC_HANDLE hSCManager, + LPTSTR lpServiceName, + HTREEITEM hParent, + HWND hwndDlg) +{ + LPQUERY_SERVICE_CONFIG lpServiceConfig; + SC_HANDLE hService; + HTREEITEM hChild; + DWORD bytesNeeded; + LPTSTR lpStr; + LPTSTR lpNoDepends; + + hService = OpenService(hSCManager, + lpServiceName, + SERVICE_QUERY_CONFIG); + if (hService) + { + + if (!QueryServiceConfig(hService, + NULL, + 0, + &bytesNeeded) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + lpServiceConfig = HeapAlloc(ProcessHeap, + 0, + bytesNeeded); + if (lpServiceConfig) + { + if (QueryServiceConfig(hService, + lpServiceConfig, + bytesNeeded, + &bytesNeeded)) + { + if (lpServiceConfig) + { + lpStr = lpServiceConfig->lpDependencies; + + if (*lpStr) + { + while (*lpStr) + { + hChild = AddItemToTreeView(hTreeView, + hParent, + lpServiceConfig->lpDisplayName, + lpServiceConfig->dwServiceType); + + AddServiceDependency(dlgInfo, + hTreeView, + hSCManager, + lpStr, + hChild, + hwndDlg); + + while (*lpStr++) + ; + } + } + else + { + if (TreeView_GetCount(hTreeView) == 0) + { + if (AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS)) + { + lpStr = lpNoDepends; + } + + AddItemToTreeView(hTreeView, + hParent, + lpStr, + 0); + + HeapFree(ProcessHeap, + 0, + lpNoDepends); + + EnableWindow(hTreeView, FALSE); + } + } + } + } + + HeapFree(ProcessHeap, + 0, + lpServiceConfig); + } + } + + CloseServiceHandle(hService); + } + +} + +static VOID +AddServiceDependent(PSERVICEPROPSHEET dlgInfo, + HWND hTreeView, + SC_HANDLE hSCManager, + LPTSTR lpServiceName, + HTREEITEM hParent, + HWND hwndDlg) +{ + LPENUM_SERVICE_STATUS lpServiceStatus; + SC_HANDLE hService; + HTREEITEM hChild; + LPTSTR lpNoDepends; + DWORD count; + INT i; + + hService = OpenService(hSCManager, + lpServiceName, + SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); + if (hService) + { + lpServiceStatus = GetDependentServices(hService, &count); + if (lpServiceStatus) + { + for (i = 0; i < count; i++) + { + hChild = AddItemToTreeView(hTreeView, + hParent, + lpServiceStatus[i].lpDisplayName, + SERVICE_WIN32); + + AddServiceDependent(dlgInfo, + hTreeView, + hSCManager, + lpServiceStatus[i].lpServiceName, + hChild, + hwndDlg); + } + + HeapFree(ProcessHeap, + 0, + lpServiceStatus); + } + else + { + if (TreeView_GetCount(hTreeView) == 0) + { + AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS); + + AddItemToTreeView(hTreeView, + hParent, + lpNoDepends, + 0); + + HeapFree(ProcessHeap, + 0, + lpNoDepends); + + EnableWindow(hTreeView, FALSE); + } + } + } +} + + +static VOID +InitDependPage(PSERVICEPROPSHEET dlgInfo, + HWND hwndDlg) +{ + HWND hTreeView1, hTreeView2; + SC_HANDLE hSCManager; + + dlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS, + IDI_DRIVER, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CXSMICON), + IMAGE_ICON); + + + hTreeView1 = GetDlgItem(hwndDlg, IDC_DEPEND_TREE1); + if (!hTreeView1) + return; + + (void)TreeView_SetImageList(hTreeView1, + dlgInfo->hDependsImageList, + TVSIL_NORMAL); + + hTreeView2 = GetDlgItem(hwndDlg, IDC_DEPEND_TREE2); + if (!hTreeView2) + return; + + (void)TreeView_SetImageList(hTreeView2, + dlgInfo->hDependsImageList, + TVSIL_NORMAL); + + hSCManager = OpenSCManager(NULL, + NULL, + SC_MANAGER_ALL_ACCESS); + if (hSCManager) + { + AddServiceDependency(dlgInfo, + hTreeView1, + hSCManager, + dlgInfo->pService->lpServiceName, + NULL, + hwndDlg); + + AddServiceDependent(dlgInfo, + hTreeView2, + hSCManager, + dlgInfo->pService->lpServiceName, + NULL, + hwndDlg); + + CloseServiceHandle(hSCManager); + } + +} + + + +/* + * Dependancies Property dialog callback. + * Controls messages to the Dependancies dialog + */ +INT_PTR CALLBACK +DependenciesPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PSERVICEPROPSHEET dlgInfo; + + /* Get the window context */ + dlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg, + GWLP_USERDATA); + if (dlgInfo == NULL && uMsg != WM_INITDIALOG) + { + return FALSE; + } + + switch (uMsg) + { + case WM_INITDIALOG: + { + dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam); + if (dlgInfo != NULL) + { + SetWindowLongPtr(hwndDlg, + GWLP_USERDATA, + (LONG_PTR)dlgInfo); + + InitDependPage(dlgInfo, hwndDlg); + } + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + + } + break; + } + + return FALSE; +} diff --git a/reactos/base/applications/mscutils/servman/propsheet_general.c b/reactos/base/applications/mscutils/servman/propsheet_general.c new file mode 100644 index 00000000000..0affae972fe --- /dev/null +++ b/reactos/base/applications/mscutils/servman/propsheet_general.c @@ -0,0 +1,371 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/mscutils/servman/propsheet_general.c + * PURPOSE: Property dialog box message handler + * COPYRIGHT: Copyright 2006-2009 Ged Murphy + * + */ + +#include "precomp.h" + + + +static VOID +SetButtonStates(PSERVICEPROPSHEET dlgInfo, + HWND hwndDlg) +{ + HWND hButton; + LPQUERY_SERVICE_CONFIG lpServiceConfig; + DWORD Flags, State; + UINT i; + + Flags = dlgInfo->pService->ServiceStatusProcess.dwControlsAccepted; + State = dlgInfo->pService->ServiceStatusProcess.dwCurrentState; + + for (i = IDC_START; i <= IDC_RESUME; i++) + { + hButton = GetDlgItem(hwndDlg, i); + EnableWindow (hButton, FALSE); + } + + lpServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName); + if (State == SERVICE_STOPPED && + lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED) + { + hButton = GetDlgItem(hwndDlg, IDC_START); + EnableWindow (hButton, TRUE); + HeapFree(GetProcessHeap(), 0, lpServiceConfig); + } + else if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) ) + { + hButton = GetDlgItem(hwndDlg, IDC_STOP); + EnableWindow (hButton, TRUE); + } + else if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) ) + { + hButton = GetDlgItem(hwndDlg, IDC_PAUSE); + EnableWindow (hButton, TRUE); + } + + /* set the main toolbar */ + SetMenuAndButtonStates(dlgInfo->Info); +} + + +static VOID +SetServiceStatusText(PSERVICEPROPSHEET dlgInfo, + HWND hwndDlg) +{ + LPTSTR lpStatus; + UINT id; + + if (dlgInfo->pService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) + { + id = IDS_SERVICES_STARTED; + } + else + { + id = IDS_SERVICES_STOPPED; + } + + if (AllocAndLoadString(&lpStatus, + hInstance, + id)) + { + SendDlgItemMessage(hwndDlg, + IDC_SERV_STATUS, + WM_SETTEXT, + 0, + (LPARAM)lpStatus); + LocalFree(lpStatus); + } +} + +/* + * Fills the 'startup type' combo box with possible + * values and sets it to value of the selected item + */ +static VOID +SetStartupType(LPTSTR lpServiceName, + HWND hwndDlg) +{ + HWND hList; + LPQUERY_SERVICE_CONFIG pServiceConfig; + LPTSTR lpBuf; + DWORD StartUp = 0; + UINT i; + + hList = GetDlgItem(hwndDlg, IDC_START_TYPE); + + for (i = IDS_SERVICES_AUTO; i <= IDS_SERVICES_DIS; i++) + { + if (AllocAndLoadString(&lpBuf, + hInstance, + i)) + { + SendMessage(hList, + CB_ADDSTRING, + 0, + (LPARAM)lpBuf); + LocalFree(lpBuf); + } + } + + pServiceConfig = GetServiceConfig(lpServiceName); + + if (pServiceConfig) + { + switch (pServiceConfig->dwStartType) + { + case SERVICE_AUTO_START: StartUp = 0; break; + case SERVICE_DEMAND_START: StartUp = 1; break; + case SERVICE_DISABLED: StartUp = 2; break; + } + + SendMessage(hList, + CB_SETCURSEL, + StartUp, + 0); + + HeapFree(ProcessHeap, + 0, + pServiceConfig); + } +} + + +/* + * Populates the General Properties dialog with + * the relevant service information + */ +static VOID +InitGeneralPage(PSERVICEPROPSHEET dlgInfo, + HWND hwndDlg) +{ + LPQUERY_SERVICE_CONFIG pServiceConfig; + LPTSTR lpDescription; + + /* set the service name */ + SendDlgItemMessage(hwndDlg, + IDC_SERV_NAME, + WM_SETTEXT, + 0, + (LPARAM)dlgInfo->pService->lpServiceName); + + /* set the display name */ + SendDlgItemMessage(hwndDlg, + IDC_DISP_NAME, + WM_SETTEXT, + 0, + (LPARAM)dlgInfo->pService->lpDisplayName); + + /* set the description */ + if ((lpDescription = GetServiceDescription(dlgInfo->pService->lpServiceName))) + { + SendDlgItemMessage(hwndDlg, + IDC_DESCRIPTION, + WM_SETTEXT, + 0, + (LPARAM)lpDescription); + + HeapFree(ProcessHeap, + 0, + lpDescription); + } + + pServiceConfig = GetServiceConfig(dlgInfo->pService->lpServiceName); + if (pServiceConfig) + { + SendDlgItemMessage(hwndDlg, + IDC_EXEPATH, + WM_SETTEXT, + 0, + (LPARAM)pServiceConfig->lpBinaryPathName); + HeapFree(ProcessHeap, + 0, + pServiceConfig); + } + + + /* set startup type */ + SetStartupType(dlgInfo->pService->lpServiceName, hwndDlg); + + SetServiceStatusText(dlgInfo, + hwndDlg); + + if (dlgInfo->Info->bIsUserAnAdmin) + { + HWND hEdit = GetDlgItem(hwndDlg, + IDC_EDIT); + EnableWindow(hEdit, + TRUE); + } +} + + +VOID +SaveDlgInfo(PSERVICEPROPSHEET dlgInfo, + HWND hwndDlg) +{ + LPQUERY_SERVICE_CONFIG pServiceConfig = NULL; + HWND hList; + DWORD StartUp; + + pServiceConfig = HeapAlloc(ProcessHeap, + HEAP_ZERO_MEMORY, + sizeof(*pServiceConfig)); + if (pServiceConfig) + { + pServiceConfig->dwServiceType = SERVICE_NO_CHANGE; + pServiceConfig->dwErrorControl = SERVICE_NO_CHANGE; + + hList = GetDlgItem(hwndDlg, IDC_START_TYPE); + StartUp = SendMessage(hList, + 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 (SetServiceConfig(pServiceConfig, + dlgInfo->pService->lpServiceName, + NULL)) + { + ChangeListViewText(dlgInfo->Info, + dlgInfo->pService, + LVSTARTUP); + } + + HeapFree(ProcessHeap, + 0, + pServiceConfig); + } +} + + +/* + * General Property dialog callback. + * Controls messages to the General dialog + */ +INT_PTR CALLBACK +GeneralPageProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PSERVICEPROPSHEET dlgInfo; + + /* Get the window context */ + dlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg, + GWLP_USERDATA); + if (dlgInfo == NULL && uMsg != WM_INITDIALOG) + { + return FALSE; + } + + switch (uMsg) + { + case WM_INITDIALOG: + { + dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam); + if (dlgInfo != NULL) + { + SetWindowLongPtr(hwndDlg, + GWLP_USERDATA, + (LONG_PTR)dlgInfo); + InitGeneralPage(dlgInfo, hwndDlg); + SetButtonStates(dlgInfo, hwndDlg); + } + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_START_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + break; + + case IDC_START: + if (DoStart(dlgInfo->Info)) + { + UpdateServiceStatus(dlgInfo->pService); + ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); + SetButtonStates(dlgInfo, hwndDlg); + SetServiceStatusText(dlgInfo, hwndDlg); + } + break; + + case IDC_STOP: + if (DoStop(dlgInfo->Info)) + { + UpdateServiceStatus(dlgInfo->pService); + ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); + SetButtonStates(dlgInfo, hwndDlg); + SetServiceStatusText(dlgInfo, hwndDlg); + } + break; + + case IDC_PAUSE: + if (DoPause(dlgInfo->Info)) + { + UpdateServiceStatus(dlgInfo->pService); + ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); + SetButtonStates(dlgInfo, hwndDlg); + SetServiceStatusText(dlgInfo, hwndDlg); + } + break; + + case IDC_RESUME: + if (DoResume(dlgInfo->Info)) + { + UpdateServiceStatus(dlgInfo->pService); + ChangeListViewText(dlgInfo->Info, dlgInfo->pService, LVSTATUS); + SetButtonStates(dlgInfo, hwndDlg); + SetServiceStatusText(dlgInfo, hwndDlg); + } + break; + + case IDC_EDIT: + { + HWND hName, hDesc, hExePath; + + hName = GetDlgItem(hwndDlg, IDC_DISP_NAME); + hDesc = GetDlgItem(hwndDlg, IDC_DESCRIPTION); + hExePath = GetDlgItem(hwndDlg, IDC_EXEPATH); + + SendMessage(hName, EM_SETREADONLY, FALSE, 0); + SendMessage(hDesc, EM_SETREADONLY, FALSE, 0); + SendMessage(hExePath, EM_SETREADONLY, FALSE, 0); + } + break; + + case IDC_START_PARAM: + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + break; + } + break; + + case WM_NOTIFY: + { + LPNMHDR lpnm = (LPNMHDR)lParam; + + switch (lpnm->code) + { + case PSN_APPLY: + SaveDlgInfo(dlgInfo, hwndDlg); + SetButtonStates(dlgInfo, hwndDlg); + break; + } + } + break; + } + + return FALSE; +} diff --git a/reactos/base/applications/mscutils/servman/res/driver.ico b/reactos/base/applications/mscutils/servman/res/driver.ico new file mode 100644 index 00000000000..5e86a5895dd Binary files /dev/null and b/reactos/base/applications/mscutils/servman/res/driver.ico differ diff --git a/reactos/base/applications/mscutils/servman/res/nodepends.ico b/reactos/base/applications/mscutils/servman/res/nodepends.ico new file mode 100644 index 00000000000..9fb370ebd4c Binary files /dev/null and b/reactos/base/applications/mscutils/servman/res/nodepends.ico differ diff --git a/reactos/base/applications/mscutils/servman/resource.h b/reactos/base/applications/mscutils/servman/resource.h index 2f97ad64964..e8d3cb65645 100644 --- a/reactos/base/applications/mscutils/servman/resource.h +++ b/reactos/base/applications/mscutils/servman/resource.h @@ -61,6 +61,9 @@ #define IDI_SM_ICON 50 #define IDB_BUTTONS 51 +#define IDI_NODEPENDS 52 +#define IDI_SERVICE 53 +#define IDI_DRIVER 54 #define IDB_PROP 10000 #define IDB_REFRESH 10001 @@ -139,6 +142,7 @@ #define IDC_DEPEND_TREE1 20002 #define IDC_DEPEND_TREE2 20003 #define IDC_DEPEND_SERVICE 20004 +#define IDS_NO_DEPENDS 20005 /* create service dialog */ diff --git a/reactos/base/applications/mscutils/servman/rsrc.rc b/reactos/base/applications/mscutils/servman/rsrc.rc index 63da59b385f..2e39de626ae 100644 --- a/reactos/base/applications/mscutils/servman/rsrc.rc +++ b/reactos/base/applications/mscutils/servman/rsrc.rc @@ -16,6 +16,10 @@ IDB_STOP BITMAP DISCARDABLE "res/stop.bmp" IDB_PAUSE BITMAP DISCARDABLE "res/pause.bmp" IDB_RESTART BITMAP DISCARDABLE "res/restart.bmp" +IDI_NODEPENDS ICON "res/nodepends.ico" +IDI_SERVICE ICON "res/system.ico" +IDI_DRIVER ICON "res/driver.ico" + #include "lang/bg-BG.rc" #include "lang/de-DE.rc" #include "lang/el-GR.rc" diff --git a/reactos/base/applications/mscutils/servman/servman.rbuild b/reactos/base/applications/mscutils/servman/servman.rbuild index 8e0bd284811..d8f0c174ee3 100644 --- a/reactos/base/applications/mscutils/servman/servman.rbuild +++ b/reactos/base/applications/mscutils/servman/servman.rbuild @@ -15,12 +15,15 @@ control.c create.c delete.c + dependencies.c export.c listview.c mainwnd.c misc.c progress.c propsheet.c + propsheet_depends.c + propsheet_general.c query.c servman.c start.c diff --git a/reactos/base/applications/mscutils/servman/stop.c b/reactos/base/applications/mscutils/servman/stop.c index a2ff4713ff6..6a5f5c88a6d 100644 --- a/reactos/base/applications/mscutils/servman/stop.c +++ b/reactos/base/applications/mscutils/servman/stop.c @@ -9,13 +9,6 @@ #include "precomp.h" -typedef struct _STOP_INFO -{ - PMAIN_WND_INFO pInfo; - SC_HANDLE hSCManager; - SC_HANDLE hMainService; -} STOP_INFO, *PSTOP_INFO; - static BOOL StopService(PSTOP_INFO pStopInfo, @@ -74,58 +67,6 @@ StopService(PSTOP_INFO pStopInfo, return bRet; } -static LPENUM_SERVICE_STATUS -GetDependentServices(SC_HANDLE hService, - LPDWORD lpdwCount) -{ - LPENUM_SERVICE_STATUS lpDependencies; - DWORD dwBytesNeeded; - DWORD dwCount; - - if (EnumDependentServices(hService, - SERVICE_ACTIVE, - NULL, - 0, - &dwBytesNeeded, - &dwCount)) - { - /* 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) - { - if (EnumDependentServices(hService, - SERVICE_ACTIVE, - lpDependencies, - dwBytesNeeded, - &dwBytesNeeded, - &dwCount)) - { - *lpdwCount = dwCount; - } - else - { - HeapFree(ProcessHeap, - 0, - lpDependencies); - - lpDependencies = NULL; - } - } - } - - return lpDependencies; - -} - static BOOL StopDependentServices(PSTOP_INFO pStopInfo, SC_HANDLE hService) @@ -170,171 +111,6 @@ StopDependentServices(PSTOP_INFO pStopInfo, return bRet; } -static BOOL -HasDependentServices(SC_HANDLE hService) -{ - DWORD dwBytesNeeded, dwCount; - BOOL bRet = FALSE; - - if (hService) - { - if (!EnumDependentServices(hService, - SERVICE_ACTIVE, - NULL, - 0, - &dwBytesNeeded, - &dwCount)) - { - if (GetLastError() == ERROR_MORE_DATA) - bRet = TRUE; - } - } - - return bRet; -} - -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 */ - lpDependencies = GetDependentServices(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; -} - BOOL DoStop(PMAIN_WND_INFO pInfo)