From d74beaf81f6035ef0bc507b43ed835f2cdafa88f Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 20 Jan 2006 00:24:34 +0000 Subject: [PATCH] - Add some more info to the properties dialog - Preliminary starting and stopping of services - Other jiggling about of the code ;) - still untested (I should get really round to this sometime :) ) svn path=/trunk/; revision=20948 --- reactos/subsys/system/servman/En.rc | 134 ++++++++++------------ reactos/subsys/system/servman/about.c | 11 +- reactos/subsys/system/servman/control.c | 59 ++++++++++ reactos/subsys/system/servman/geterror.c | 3 +- reactos/subsys/system/servman/propsheet.c | 93 +++++++++++++-- reactos/subsys/system/servman/query.c | 95 ++++++++++++++- reactos/subsys/system/servman/resource.h | 1 + reactos/subsys/system/servman/servman.c | 20 +++- reactos/subsys/system/servman/servman.h | 7 +- reactos/subsys/system/servman/servman.xml | 2 + reactos/subsys/system/servman/start.c | 96 ++++++++++++++++ 11 files changed, 429 insertions(+), 92 deletions(-) create mode 100644 reactos/subsys/system/servman/control.c create mode 100644 reactos/subsys/system/servman/start.c diff --git a/reactos/subsys/system/servman/En.rc b/reactos/subsys/system/servman/En.rc index 521d2e77c54..102f036012f 100644 --- a/reactos/subsys/system/servman/En.rc +++ b/reactos/subsys/system/servman/En.rc @@ -1,102 +1,92 @@ - IDR_MAINMENU MENU BEGIN POPUP "&File" BEGIN - MENUITEM "E&xit", ID_EXIT + MENUITEM "E&xit",ID_EXIT END POPUP "Action" BEGIN - MENUITEM "Start", ID_START - MENUITEM "Stop", ID_STOP - MENUITEM "Pause", ID_PAUSE - MENUITEM "Resume", ID_RESUME - MENUITEM "Restart", ID_RESTART + MENUITEM "Start",ID_START + MENUITEM "Stop",ID_STOP + MENUITEM "Pause",ID_PAUSE + MENUITEM "Resume",ID_RESUME + MENUITEM "Restart",ID_RESTART MENUITEM SEPARATOR - MENUITEM "Refresh", ID_REFRESH + MENUITEM "Refresh",ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Properties", ID_PROP + MENUITEM "Properties",ID_PROP END POPUP "View" BEGIN - MENUITEM "Customize", ID_VIEW_CUSTOMIZE + MENUITEM "Customize",ID_VIEW_CUSTOMIZE END POPUP "Help" BEGIN - MENUITEM "About", ID_ABOUT + MENUITEM "About",ID_ABOUT END END - - IDR_POPUP MENU BEGIN POPUP "popup" BEGIN - MENUITEM "Start", ID_START - MENUITEM "Stop", ID_STOP - MENUITEM "Pause", ID_PAUSE - MENUITEM "Resume", ID_RESUME - MENUITEM "Restart", ID_RESTART + MENUITEM "Start",ID_START + MENUITEM "Stop",ID_STOP + MENUITEM "Pause",ID_PAUSE + MENUITEM "Resume",ID_RESUME + MENUITEM "Restart",ID_RESTART MENUITEM SEPARATOR POPUP "All tasks" BEGIN - MENUITEM "Start", ID_START - MENUITEM "Stop", ID_STOP - MENUITEM "Pause", ID_PAUSE - MENUITEM "Resume", ID_RESUME - MENUITEM "Restart", ID_RESTART - MENUITEM "Refresh", ID_REFRESH + MENUITEM "Start",ID_START + MENUITEM "Stop",ID_STOP + MENUITEM "Pause",ID_PAUSE + MENUITEM "Resume",ID_RESUME + MENUITEM "Restart",ID_RESTART + MENUITEM "Refresh",ID_REFRESH END MENUITEM SEPARATOR - MENUITEM "Refresh", ID_REFRESH + MENUITEM "Refresh",ID_REFRESH MENUITEM SEPARATOR - MENUITEM "Properties", ID_PROP + MENUITEM "Properties",ID_PROP MENUITEM SEPARATOR - MENUITEM "Help", ID_HELP + MENUITEM "Help",ID_HELP END END - - -IDD_ABOUTBOX DIALOG DISCARDABLE 22,16,190,182 -STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +IDD_ABOUTBOX DIALOGEX 22,16,190,182 CAPTION "About Service Manager" -FONT 8, "Tahoma" +FONT 8,"Tahoma",0,0 +STYLE 0x00C80080 BEGIN - CONTROL "Service Manager v0.1\nCopyright (C) 2006\nby Ged Murphy (gedmurphy@gmail.com)", - IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,48,7,130,26 - DEFPUSHBUTTON "Close",IDOK,75,162,44,15,WS_GROUP - ICON IDI_SM_ICON,IDC_STATIC,12,7,30,20 - EDITTEXT IDC_LICENSE_EDIT,8,44,174,107,ES_MULTILINE | - ES_READONLY | WS_VSCROLL + CONTROL "Service Manager v0.1\nCopyright (C) 2006\nby Ged Murphy (gedmurphy@gmail.com)",IDC_STATIC,"Static",WS_VISIBLE|0x0002000C,48,7,130,26 + CONTROL "Close",IDOK,"Button",0x50030001,75,162,44,15 + CONTROL "",IDI_SM_ICON,"Static",0x50000203,0,12,7,30 + CONTROL "",IDC_LICENSE_EDIT,"Edit",0x50210804,8,44,174,107,0x00000200 END - - IDD_DLG_GENERAL DIALOGEX 6,6,253,225 CAPTION "General" FONT 8,"MS Sans Serif",0,0 STYLE 0x10CF0000 BEGIN CONTROL "Service name:",IDC_STATIC,"Static",0x50000000,4,11,53,11 - CONTROL "Display name:",IDC_STATIC,"Static",0x50000000,4,29,53,11 - CONTROL "Description",IDC_STATIC,"Static",0x50000000,4,51,53,11 - CONTROL "",IDC_SERV_NAME,"Static",0x50000000,70,11,176,11 CONTROL "",IDC_DISP_NAME,"Static",0x50001000,70,29,176,12 CONTROL "",IDC_DESCRIPTION,"Static",0x50201000,70,46,176,22 - CONTROL "Path to executable:",IDC_STATIC,"Static",0x50000000,6,73,82,9 CONTROL "",IDC_EXEPATH,"Static",0x50001000,6,86,238,12 - CONTROL "Startup type:",IDC_STATIC,"Static",0x50000000,6,108,53,11 CONTROL "",IDC_START_TYPE,"ComboBox",0x50010003,70,107,176,11 - CONTROL "Service status:",IDC_STATIC,"Static",0x50000000,4,138,53,11 - CONTROL "",IDC_SERV_STATUS,"Static",0x50000000,70,138,176,11 CONTROL "Start",IDC_START,"Button",0x50010000,6,155,54,15 CONTROL "Stop",IDC_STOP,"Button",0x50010000,68,155,54,15 CONTROL "Pause",IDC_PAUSE,"Button",0x50010000,130,155,54,15 CONTROL "Resume",IDC_RESUME,"Button",0x50010000,192,155,54,15 + CONTROL "",IDC_START_PARAM,"Static",0x50001000,70,199,176,11 + CONTROL "Display name:",IDC_STATIC,"Static",0x50000000,4,29,53,11 + CONTROL "Description",IDC_STATIC,"Static",0x50000000,4,51,53,11 + CONTROL "",IDC_SERV_NAME,"Static",0x50000000,70,11,176,11 + CONTROL "Path to executable:",IDC_STATIC,"Static",0x50000000,6,73,82,9 + CONTROL "Startup type:",IDC_STATIC,"Static",0x50000000,6,108,53,11 + CONTROL "Service status:",IDC_STATIC,"Static",0x50000000,4,138,53,11 + CONTROL "",IDC_SERV_STATUS,"Static",0x50000000,70,138,176,11 CONTROL "You can specify the start parameters that apply when you start the service from here.",IDC_STATIC,"Static",0x50000000,6,177,240,15 CONTROL "Start parameters",IDC_STATIC,"Static",0x50000000,6,199,53,11 - CONTROL "",IDC_START_PARAM,"Static",0x50001000,70,199,176,11 END - IDD_DLG_DEPEND DIALOGEX 6,6,253,225 CAPTION "Dependencies" FONT 8,"MS Sans Serif",0,0 @@ -108,44 +98,38 @@ BEGIN CONTROL "This service depends on the following components",IDC_STATIC,"Static",0x50000000,8,57,236,9 CONTROL "",IDC_DEPEND_SERVICE,"Static",0x50000000,8,38,236,13 END - - - -IDB_BUTTONS BITMAP "res/toolbar.bmp" - +IDB_BUTTONS BITMAP DISCARDABLE "res/toolbar.bmp" STRINGTABLE DISCARDABLE BEGIN - IDS_FIRSTCOLUMN "Name" + IDS_FIRSTCOLUMN "Name" IDS_SECONDCOLUMN "Description" - IDS_THIRDCOLUMN "Status" + IDS_THIRDCOLUMN "Status" IDS_FOURTHCOLUMN "Startup Type" - IDS_FITHCOLUMN "Log On As" + IDS_FITHCOLUMN "Log On As" END - STRINGTABLE DISCARDABLE BEGIN - IDS_SERVICES_STARTED "Started" - IDS_SERVICES_AUTO "Automatic" - IDS_SERVICES_MAN "Manual" - IDS_SERVICES_DIS "Disabled" + IDS_SERVICES_STARTED "Started" + IDS_SERVICES_STOPPED "Stopped" + IDS_SERVICES_AUTO "Automatic" + IDS_SERVICES_MAN "Manual" + IDS_SERVICES_DIS "Disabled" END - STRINGTABLE DISCARDABLE BEGIN IDS_NUM_SERVICES "Num Services: %d" - 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." + 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 receive" END - STRINGTABLE DISCARDABLE BEGIN - IDS_TOOLTIP_PROP "Properties" - IDS_TOOLTIP_REFRESH "Refresh" - IDS_TOOLTIP_EXPORT "Export list" - IDS_TOOLTIP_START "Start service" - IDS_TOOLTIP_STOP "Stop service" - IDS_TOOLTIP_PAUSE "Pause service" - IDS_TOOLTIP_RESTART "Restart service" - IDS_TOOLTIP_NEW "Create a service" - IDS_TOOLTIP_HELP "Help" - IDS_TOOLTIP_EXIT "Exit" + IDS_TOOLTIP_PROP "Properties" + IDS_TOOLTIP_REFRESH "Refresh" + IDS_TOOLTIP_EXPORT "Export list" + IDS_TOOLTIP_START "Start service" + IDS_TOOLTIP_STOP "Stop service" + IDS_TOOLTIP_PAUSE "Pause service" + IDS_TOOLTIP_RESTART "Restart service" + IDS_TOOLTIP_NEW "Create new a service" + IDS_TOOLTIP_HELP "Help" + IDS_TOOLTIP_EXIT "Exit" END diff --git a/reactos/subsys/system/servman/about.c b/reactos/subsys/system/servman/about.c index 0d7a86e7529..be975ca51b8 100644 --- a/reactos/subsys/system/servman/about.c +++ b/reactos/subsys/system/servman/about.c @@ -4,7 +4,7 @@ * FILE: subsys/system/servman/about.c * PURPOSE: About dialog box message handler * COPYRIGHT: Copyright 2005 Ged Murphy - * + * */ //ShellAbout(hwnd, _T("test"), _T("test2"), MAKEINTRESOURCE(IDI_SM_ICON)); @@ -19,13 +19,17 @@ extern HINSTANCE hInstance; BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND hLicenseEditWnd; - TCHAR strLicense[0x1000]; + HWND hLicenseEditWnd; + HICON hIcon = NULL; + TCHAR strLicense[0x1000]; switch (message) { case WM_INITDIALOG: + hIcon = LoadImage(hInstance, MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0); + SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + hLicenseEditWnd = GetDlgItem(hDlg, IDC_LICENSE_EDIT); LoadString(hInstance, IDS_LICENSE, strLicense, 0x1000); @@ -38,6 +42,7 @@ AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) { + DestroyIcon(hIcon); EndDialog(hDlg, LOWORD(wParam)); return TRUE; } diff --git a/reactos/subsys/system/servman/control.c b/reactos/subsys/system/servman/control.c new file mode 100644 index 00000000000..c4202cac2f7 --- /dev/null +++ b/reactos/subsys/system/servman/control.c @@ -0,0 +1,59 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsys/system/servman/control + * PURPOSE: Stops, pauses and resumes a service + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy + * + */ + +#include "servman.h" + +extern HWND hListView; + + +BOOL Control(DWORD Control) +{ + SC_HANDLE hSCManager; + SC_HANDLE hSc; + ENUM_SERVICE_STATUS_PROCESS *Service = NULL; + SERVICE_STATUS Status; + LVITEM item; + + item.mask = LVIF_PARAM; + item.iItem = GetSelectedItem(); + SendMessage(hListView, LVM_GETITEM, 0, (LPARAM)&item); + + /* copy pointer to selected service */ + Service = (ENUM_SERVICE_STATUS_PROCESS *)item.lParam; + + /* open handle to the SCM */ + hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hSCManager == NULL) + { + GetError(0); + return FALSE; + } + + /* open handle to the service */ + hSc = OpenService(hSCManager, Service->lpServiceName, + SERVICE_PAUSE_CONTINUE | SERVICE_STOP); + if (hSc == NULL) + { + GetError(0); + return FALSE; + } + + /* process requested action */ + if (! ControlService(hSc, Control, &Status)) + { + GetError(0); + CloseServiceHandle(hSc); + return FALSE; + } + + CloseServiceHandle(hSc); + + return TRUE; + +} diff --git a/reactos/subsys/system/servman/geterror.c b/reactos/subsys/system/servman/geterror.c index 55f395c0285..29c28f4ace1 100644 --- a/reactos/subsys/system/servman/geterror.c +++ b/reactos/subsys/system/servman/geterror.c @@ -1,4 +1,4 @@ - +//#include #include "servman.h" /* temp file for debugging */ @@ -27,6 +27,7 @@ VOID GetError(DWORD err) VOID DisplayString(PTCHAR Msg) { + MessageBox(NULL, Msg, _T("Error!"), MB_OK | MB_ICONERROR); } diff --git a/reactos/subsys/system/servman/propsheet.c b/reactos/subsys/system/servman/propsheet.c index 01caadb0f91..89df57cc15d 100644 --- a/reactos/subsys/system/servman/propsheet.c +++ b/reactos/subsys/system/servman/propsheet.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: subsys/system/servman/propsheet.c * PURPOSE: Property dialog box message handler - * COPYRIGHT: Copyright 2005 Ged Murphy + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy * */ @@ -12,7 +12,7 @@ extern ENUM_SERVICE_STATUS_PROCESS *pServiceStatus; extern HINSTANCE hInstance; extern HWND hListView; -extern INT SelectedItem; +extern HWND hMainWnd; typedef struct _PROP_DLG_INFO @@ -21,14 +21,58 @@ typedef struct _PROP_DLG_INFO LPTSTR lpDisplayName; LPTSTR lpDescription; LPTSTR lpPathToExe; - DWORD dwStartupType; - DWORD dwServiceStatus; + TCHAR szStartupType; + TCHAR szServiceStatus[25]; LPTSTR lpStartParams; } PROP_DLG_INFO, *PPROP_DLG_INFO; +/* + * Fills the 'startup type' combo box with possible + * values and sets it to value of the selected item + */ +VOID SetStartupType(HKEY hKey, HWND hwndDlg) +{ + HWND hList; + TCHAR buf[25]; + DWORD dwValueSize = 0; + DWORD StartUp = 0; + + hList = GetDlgItem(hwndDlg, IDC_START_TYPE); + + LoadString(hInstance, IDS_SERVICES_AUTO, buf, sizeof(buf) / sizeof(TCHAR)); + SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)buf); + LoadString(hInstance, IDS_SERVICES_MAN, buf, sizeof(buf) / sizeof(TCHAR)); + SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)buf); + LoadString(hInstance, IDS_SERVICES_DIS, buf, sizeof(buf) / sizeof(TCHAR)); + SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)buf); + + dwValueSize = sizeof(DWORD); + if (RegQueryValueEx(hKey, + _T("Start"), + NULL, + NULL, + (LPBYTE)&StartUp, + &dwValueSize)) + { + RegCloseKey(hKey); + return; + } + + if (StartUp == 0x02) + SendMessage(hList, CB_SETCURSEL, 0, 0); + else if (StartUp == 0x03) + SendMessage(hList, CB_SETCURSEL, 1, 0); + else if (StartUp == 0x04) + SendMessage(hList, CB_SETCURSEL, 2, 0); + +} +/* + * Populates the General Properties dialog with + * the relevant service information + */ VOID GetDlgInfo(HWND hwndDlg) { HKEY hKey; @@ -39,7 +83,7 @@ VOID GetDlgInfo(HWND hwndDlg) TCHAR buf[300]; item.mask = LVIF_PARAM; - item.iItem = SelectedItem; + item.iItem = GetSelectedItem(); SendMessage(hListView, LVM_GETITEM, 0, (LPARAM)&item); /* copy pointer to selected service */ @@ -57,19 +101,43 @@ VOID GetDlgInfo(HWND hwndDlg) DlgInfo.lpServiceName = Service->lpServiceName; SendDlgItemMessageW(hwndDlg, IDC_SERV_NAME, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpServiceName); + /* set the display name */ DlgInfo.lpDisplayName = Service->lpDisplayName; SendDlgItemMessageW(hwndDlg, IDC_DISP_NAME, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpDisplayName); + /* set the description */ if (GetDescription(hKey, &DlgInfo.lpDescription)) SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpDescription); + + /* FIXME: needs implementing. Use code base at bottom of query.c */ /* set the executable path */ if (GetExecutablePath(&DlgInfo.lpPathToExe)) SendDlgItemMessageW(hwndDlg, IDC_EXEPATH, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpPathToExe); + /* set startup type */ + SetStartupType(hKey, hwndDlg); + + + + /* set service status */ + if (Service->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) + { + LoadString(hInstance, IDS_SERVICES_STARTED, DlgInfo.szServiceStatus, + sizeof(DlgInfo.szServiceStatus) / sizeof(TCHAR)); + SendDlgItemMessageW(hwndDlg, IDC_SERV_STATUS, WM_SETTEXT, 0, (LPARAM)DlgInfo.szServiceStatus); + } + else + { + LoadString(hInstance, IDS_SERVICES_STOPPED, DlgInfo.szServiceStatus, + sizeof(DlgInfo.szServiceStatus) / sizeof(TCHAR)); + SendDlgItemMessageW(hwndDlg, IDC_SERV_STATUS, WM_SETTEXT, 0, (LPARAM)DlgInfo.szServiceStatus); + } + + } @@ -78,7 +146,12 @@ VOID GetDlgInfo(HWND hwndDlg) #ifdef _MSC_VER #pragma warning(disable : 4100) #endif -/* Property page dialog callback */ + +/* + * General Property dialog callback. + * Controls messages to the General dialog + */ +/* FIXME: this may be better as a modeless dialog */ INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, @@ -125,8 +198,11 @@ GeneralPageProc(HWND hwndDlg, - - +/* + * Dependancies Property dialog callback. + * Controls messages to the Dependancies dialog + */ +/* FIXME: this may be better as a modeless dialog */ INT_PTR CALLBACK DependanciesPageProc(HWND hwndDlg, UINT uMsg, @@ -211,3 +287,4 @@ OpenPropSheet(HWND hwnd) return (LONG)(PropertySheet(&psh) != -1); } + diff --git a/reactos/subsys/system/servman/query.c b/reactos/subsys/system/servman/query.c index b5d1e15ed55..875e5563a3d 100644 --- a/reactos/subsys/system/servman/query.c +++ b/reactos/subsys/system/servman/query.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: subsys/system/servman/query.c * PURPOSE: Query service information - * COPYRIGHT: Copyright 2005 Ged Murphy + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy * */ @@ -23,6 +23,7 @@ VOID FreeMemory(VOID) HeapFree(GetProcessHeap(), 0, pServiceStatus); } + /* Retrives the service description from the registry */ BOOL GetDescription(HKEY hKey, LPTSTR *retDescription) { @@ -70,13 +71,102 @@ BOOL GetDescription(HKEY hKey, LPTSTR *retDescription) } +/* get vendor of service binary */ BOOL GetExecutablePath(LPTSTR *ExePath) { + LPQUERY_SERVICE_CONFIG pServiceConfig = NULL; + SC_HANDLE hService = NULL; + LVITEM item; + WORD wCodePage, wLangID; + DWORD BytesNeeded = 0, dwHandle, dwLen; + TCHAR FileName[MAX_PATH]; + LPTSTR lpData; + LPTSTR lpBuffer; + TCHAR szStrFileInfo[80]; + LPVOID pvData; + UINT BufLen; - return FALSE; + + if (!QueryServiceConfig(hService, pServiceConfig, 0, &BytesNeeded)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + pServiceConfig = (LPQUERY_SERVICE_CONFIG) + HeapAlloc(GetProcessHeap(), 0, BytesNeeded); + if (pServiceConfig == NULL) + return FALSE; + + if (!QueryServiceConfig(hService, + pServiceConfig, + BytesNeeded, + &BytesNeeded)) + { + HeapFree(GetProcessHeap(), 0, pServiceConfig); + return FALSE; + } + } + else /* exit on failure */ + { + return FALSE; + } + } + + memset(&FileName, 0, MAX_PATH); + if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\""))) + { + _tcsncpy(FileName, pServiceConfig->lpBinaryPathName, + _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) ); + } + else + { + _tcscpy(FileName, pServiceConfig->lpBinaryPathName); + } + + HeapFree(GetProcessHeap(), 0, pServiceConfig); + pServiceConfig = NULL; + + dwLen = GetFileVersionInfoSize(FileName, &dwHandle); + if (dwLen) + { + lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen); + if (lpData == NULL) + return FALSE; + + if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData)) { + HeapFree(GetProcessHeap(), 0, lpData); + return FALSE; + } + + if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen)) + { + wCodePage = LOWORD(*(DWORD*) pvData); + wLangID = HIWORD(*(DWORD*) pvData); + wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID); + } + + if (VerQueryValue (lpData, szStrFileInfo, (LPVOID) &lpBuffer, (PUINT) &BufLen)) { + item.pszText = lpBuffer; + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + } + HeapFree(GetProcessHeap(), 0, lpData); + } + /*else + { + LoadString(hInstance, IDS_SERVICES_UNKNOWN, szStatus, 128); + item.pszText = szStatus; + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + }*/ + + CloseServiceHandle(hService); + + return TRUE; } + + BOOL RefreshServiceList(VOID) { @@ -477,3 +567,4 @@ GetServiceList(VOID) CloseServiceHandle(hService); } */ + diff --git a/reactos/subsys/system/servman/resource.h b/reactos/subsys/system/servman/resource.h index 4a245f9120b..fd55c641fdf 100644 --- a/reactos/subsys/system/servman/resource.h +++ b/reactos/subsys/system/servman/resource.h @@ -46,6 +46,7 @@ #define IDS_TOOLTIP_EXIT 6009 #define IDS_SERVICES_STARTED 5000 +#define IDS_SERVICES_STOPPED 5001 #define IDS_SERVICES_AUTO 5004 #define IDS_SERVICES_MAN 5005 #define IDS_SERVICES_DIS 5006 diff --git a/reactos/subsys/system/servman/servman.c b/reactos/subsys/system/servman/servman.c index 386e357d658..55aa961d6c8 100644 --- a/reactos/subsys/system/servman/servman.c +++ b/reactos/subsys/system/servman/servman.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: subsys/system/servman/servman.c * PURPOSE: Main window message handler - * COPYRIGHT: Copyright 2005 Ged Murphy + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy * */ @@ -20,6 +20,12 @@ HMENU hShortcutMenu; INT SelectedItem; +INT GetSelectedItem(VOID) +{ + return SelectedItem; +} + + LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) @@ -336,18 +342,29 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case ID_START: + DoStartService(); + RefreshServiceList(); break; case ID_STOP: + Control(SERVICE_CONTROL_STOP); + RefreshServiceList(); break; case ID_PAUSE: + Control(SERVICE_CONTROL_PAUSE); + RefreshServiceList(); break; case ID_RESUME: + Control(SERVICE_CONTROL_CONTINUE ); + RefreshServiceList(); break; case ID_RESTART: + Control(SERVICE_CONTROL_STOP); + DoStartService(); + RefreshServiceList(); break; case ID_NEW: @@ -460,3 +477,4 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, } + diff --git a/reactos/subsys/system/servman/servman.h b/reactos/subsys/system/servman/servman.h index bbb84ee9c59..8cd33861d30 100644 --- a/reactos/subsys/system/servman/servman.h +++ b/reactos/subsys/system/servman/servman.h @@ -3,7 +3,7 @@ #define WIN32_LEAN_AND_MEAN #include -#include +#include /* GET_X/Y_LPARAM */ #include #include #include @@ -16,7 +16,10 @@ BOOL RefreshServiceList(VOID); BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -BOOL Start(LPCTSTR, LPCTSTR, INT); +BOOL DoStartService(VOID); +BOOL Control(DWORD Control); + +INT GetSelectedItem(VOID); VOID GetError(DWORD); VOID FreeMemory(VOID); diff --git a/reactos/subsys/system/servman/servman.xml b/reactos/subsys/system/servman/servman.xml index 72b73d2ff51..37822ca2aa8 100644 --- a/reactos/subsys/system/servman/servman.xml +++ b/reactos/subsys/system/servman/servman.xml @@ -14,10 +14,12 @@ shell32 about.c + control.c geterror.c propsheet.c query.c servman.c + start.c servman.rc servman.h diff --git a/reactos/subsys/system/servman/start.c b/reactos/subsys/system/servman/start.c new file mode 100644 index 00000000000..b7710da2b9d --- /dev/null +++ b/reactos/subsys/system/servman/start.c @@ -0,0 +1,96 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: subsys/system/servman/start.c + * PURPOSE: Start a service + * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy + * + */ + +#include "servman.h" + +extern HWND hListView; + +BOOL DoStartService(VOID) +{ + SC_HANDLE hSCManager; + SC_HANDLE hSc; + SERVICE_STATUS_PROCESS ServiceStatus; + ENUM_SERVICE_STATUS_PROCESS *Service = NULL; + LVITEM item; + DWORD BytesNeeded; + INT ArgCount = 0; + BOOL Loop = 10; //FIXME: testing value. needs better control + + item.mask = LVIF_PARAM; + item.iItem = GetSelectedItem(); + SendMessage(hListView, LVM_GETITEM, 0, (LPARAM)&item); + + /* copy pointer to selected service */ + Service = (ENUM_SERVICE_STATUS_PROCESS *)item.lParam; + + /* open handle to the SCM */ + hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hSCManager == NULL) + { + GetError(0); + return FALSE; + } + + /* get a handle to the service requested for starting */ + hSc = OpenService(hSCManager, Service->lpServiceName, SERVICE_ALL_ACCESS); + if (hSc == NULL) + { + GetError(0); + return FALSE; + } + + /* start the service opened */ + if (! StartService(hSc, ArgCount, NULL)) + { + GetError(0); + return FALSE; + } + + /* query the state of the service */ + if (! QueryServiceStatusEx( + hSc, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) + { + GetError(0); + return FALSE; + } + + /* loop whilst service is not running */ + /* FIXME: needs more control adding. 'Loop' is temparary */ + while (ServiceStatus.dwCurrentState == SERVICE_START_PENDING || !Loop) + { + /* wait before checking status */ + Sleep(ServiceStatus.dwWaitHint); + + /* check status again */ + if (! QueryServiceStatusEx( + hSc, + SC_STATUS_PROCESS_INFO, + (LPBYTE)&ServiceStatus, + sizeof(SERVICE_STATUS_PROCESS), + &BytesNeeded)) + { + GetError(0); + return FALSE; + } + Loop--; + } + + CloseServiceHandle(hSc); + + if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) + return TRUE; + else + return FALSE; + +} +