From 43744d9581812ac215842fe7323139cd3a3bfd05 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Fri, 20 Jan 2006 17:29:50 +0000 Subject: [PATCH] - Resource added for creating a service - Allow the prop sheet to control services - Add exe path to prop sheet - Only update the listview item itself when changing a service state svn path=/trunk/; revision=20953 --- reactos/subsys/system/servman/En.rc | 25 +++- reactos/subsys/system/servman/propsheet.c | 23 ++- reactos/subsys/system/servman/query.c | 169 ++++++++++++++-------- reactos/subsys/system/servman/resource.h | 9 ++ reactos/subsys/system/servman/servman.c | 68 ++++++--- 5 files changed, 206 insertions(+), 88 deletions(-) diff --git a/reactos/subsys/system/servman/En.rc b/reactos/subsys/system/servman/En.rc index 102f036012f..24f7275d692 100644 --- a/reactos/subsys/system/servman/En.rc +++ b/reactos/subsys/system/servman/En.rc @@ -57,7 +57,7 @@ CAPTION "About Service Manager" 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",WS_VISIBLE|0x0002000C,48,7,130,26 + CONTROL "Service Manager v0.1\nCopyright (C) 2006\nby Ged Murphy (gedmurphy@gmail.com)",IDC_STATIC,"Static",0x1002000C,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 @@ -67,7 +67,6 @@ CAPTION "General" FONT 8,"MS Sans Serif",0,0 STYLE 0x10CF0000 BEGIN - CONTROL "Service name:",IDC_STATIC,"Static",0x50000000,4,11,53,11 CONTROL "",IDC_DISP_NAME,"Static",0x50001000,70,29,176,12 CONTROL "",IDC_DESCRIPTION,"Static",0x50201000,70,46,176,22 CONTROL "",IDC_EXEPATH,"Static",0x50001000,6,86,238,12 @@ -76,6 +75,7 @@ BEGIN 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 "Service name:",IDC_STATIC,"Static",0x50000000,4,11,53,11 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 @@ -98,7 +98,28 @@ 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 +IDD_DLG_CREATE DIALOGEX 6,6,225,209 +CAPTION "Create a service" +FONT 8,"MS Sans Serif",0,0 +STYLE 0x10CF0000 +BEGIN + CONTROL "",IDC_CREATE_SERVNAME,"Edit",0x50010000,72,12,150,11,0x00000200 + CONTROL "",IDC_CREATE_DISPNAME,"Edit",0x50010000,72,31,150,11,0x00000200 + CONTROL "",IDC_CREATE_PATH,"Edit",0x50010000,8,62,214,13,0x00000200 + CONTROL "",IDC_CREATE_DESC,"Edit",0x50010000,10,97,210,48,0x00000200 + CONTROL "",IDC_CREATE_OPTIONS,"Edit",0x50010000,10,162,210,13,0x00000200 + CONTROL "Service Name :",IDC_STATIC,"Static",0x50000202,12,12,54,9 + CONTROL "Display Name :",IDC_STATIC,"Static",0x50000202,12,33,54,9 + CONTROL "Path to executable :",IDC_STATIC,"Static",0x50000000,10,51,68,9 + CONTROL "Description :",IDC_STATIC,"Static",0x50000000,12,86,44,9 + CONTROL "OK",IDOK,"Button",0x50010000,126,192,44,13 + CONTROL "Cancel",IDCANCEL,"Button",0x50010000,176,192,46,13 + CONTROL "Additional options (click help for details)",IDC_STATIC,"Static",0x50000000,10,151,134,9 + CONTROL "Help",ID_CREATE_HELP,"Button",0x50010000,6,192,44,13 +END + IDB_BUTTONS BITMAP DISCARDABLE "res/toolbar.bmp" + STRINGTABLE DISCARDABLE BEGIN IDS_FIRSTCOLUMN "Name" diff --git a/reactos/subsys/system/servman/propsheet.c b/reactos/subsys/system/servman/propsheet.c index 89df57cc15d..aea45151958 100644 --- a/reactos/subsys/system/servman/propsheet.c +++ b/reactos/subsys/system/servman/propsheet.c @@ -90,7 +90,7 @@ VOID GetDlgInfo(HWND hwndDlg) Service = (ENUM_SERVICE_STATUS_PROCESS *)item.lParam; /* open the registry key for the service */ - _sntprintf(buf, 300, Path, Service->lpServiceName); + _sntprintf(buf, sizeof(buf) / sizeof(TCHAR), Path, Service->lpServiceName); RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, @@ -99,23 +99,26 @@ VOID GetDlgInfo(HWND hwndDlg) /* set the service name */ DlgInfo.lpServiceName = Service->lpServiceName; - SendDlgItemMessageW(hwndDlg, IDC_SERV_NAME, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpServiceName); + SendDlgItemMessage(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); + SendDlgItemMessage(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); + SendDlgItemMessage(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); + SendDlgItemMessage(hwndDlg, IDC_EXEPATH, WM_SETTEXT, 0, (LPARAM)DlgInfo.lpPathToExe); /* set startup type */ @@ -163,17 +166,25 @@ GeneralPageProc(HWND hwndDlg, { case WM_INITDIALOG: GetDlgInfo(hwndDlg); - break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_START: + SendMessage(hMainWnd, WM_COMMAND, ID_START, 0); break; case IDC_STOP: + SendMessage(hMainWnd, WM_COMMAND, ID_STOP, 0); + break; + case IDC_PAUSE: + SendMessage(hMainWnd, WM_COMMAND, ID_PAUSE, 0); + break; + + case IDC_RESUME: + SendMessage(hMainWnd, WM_COMMAND, ID_RESUME, 0); break; } break; diff --git a/reactos/subsys/system/servman/query.c b/reactos/subsys/system/servman/query.c index 875e5563a3d..fcd3ee4dbe9 100644 --- a/reactos/subsys/system/servman/query.c +++ b/reactos/subsys/system/servman/query.c @@ -74,44 +74,64 @@ BOOL GetDescription(HKEY hKey, LPTSTR *retDescription) /* get vendor of service binary */ BOOL GetExecutablePath(LPTSTR *ExePath) { + SC_HANDLE hSCManager = NULL; + SC_HANDLE hSc = NULL; LPQUERY_SERVICE_CONFIG pServiceConfig = NULL; - SC_HANDLE hService = NULL; + ENUM_SERVICE_STATUS_PROCESS *Service = NULL; LVITEM item; - WORD wCodePage, wLangID; - DWORD BytesNeeded = 0, dwHandle, dwLen; + DWORD BytesNeeded = 0; TCHAR FileName[MAX_PATH]; - LPTSTR lpData; - LPTSTR lpBuffer; - TCHAR szStrFileInfo[80]; - LPVOID pvData; - UINT BufLen; - if (!QueryServiceConfig(hService, pServiceConfig, 0, &BytesNeeded)) + 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_ENUMERATE_SERVICE); + if (hSCManager == NULL) + { + GetError(0); + return FALSE; + } + + /* get a handle to the service requested for starting */ + hSc = OpenService(hSCManager, Service->lpServiceName, SERVICE_QUERY_CONFIG); + if (hSc == NULL) + { + GetError(0); + goto cleanup; + } + + + if (!QueryServiceConfig(hSc, pServiceConfig, 0, &BytesNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { pServiceConfig = (LPQUERY_SERVICE_CONFIG) HeapAlloc(GetProcessHeap(), 0, BytesNeeded); if (pServiceConfig == NULL) - return FALSE; + goto cleanup; - if (!QueryServiceConfig(hService, + if (!QueryServiceConfig(hSc, pServiceConfig, BytesNeeded, &BytesNeeded)) { HeapFree(GetProcessHeap(), 0, pServiceConfig); - return FALSE; + goto cleanup; } } else /* exit on failure */ { - return FALSE; + goto cleanup; } } - memset(&FileName, 0, MAX_PATH); + ZeroMemory(&FileName, MAX_PATH); if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\""))) { _tcsncpy(FileName, pServiceConfig->lpBinaryPathName, @@ -122,46 +142,19 @@ BOOL GetExecutablePath(LPTSTR *ExePath) _tcscpy(FileName, pServiceConfig->lpBinaryPathName); } - HeapFree(GetProcessHeap(), 0, pServiceConfig); - pServiceConfig = NULL; + *ExePath = FileName; - 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); + CloseServiceHandle(hSCManager); + CloseServiceHandle(hSc); return TRUE; + +cleanup: + if (hSCManager != NULL) + CloseServiceHandle(hSCManager); + if (hSc != NULL) + CloseServiceHandle(hSc); + return FALSE; } @@ -172,7 +165,7 @@ RefreshServiceList(VOID) { LVITEM item; TCHAR szNumServices[32]; - TCHAR szStatus[128]; + TCHAR szStatus[64]; DWORD NumServices = 0; DWORD Index; LPCTSTR Path = _T("System\\CurrentControlSet\\Services\\%s"); @@ -193,7 +186,8 @@ RefreshServiceList(VOID) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR16, 1, 1); /* Add an icon to each image list */ - hiconItem = LoadImage(hInstance, MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0); + hiconItem = LoadImage(hInstance, MAKEINTRESOURCE(IDI_SM_ICON), + IMAGE_ICON, 16, 16, 0); ImageList_AddIcon(hSmall, hiconItem); /* assign the image to the list view */ @@ -249,9 +243,11 @@ RefreshServiceList(VOID) /* set the status */ - if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) + if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState + == SERVICE_RUNNING) { - LoadString(hInstance, IDS_SERVICES_STARTED, szStatus, 128); + LoadString(hInstance, IDS_SERVICES_STARTED, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); item.pszText = szStatus; item.iSubItem = 2; SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); @@ -275,21 +271,24 @@ RefreshServiceList(VOID) if (StartUp == 0x02) { - LoadString(hInstance, IDS_SERVICES_AUTO, szStatus, 128); + LoadString(hInstance, IDS_SERVICES_AUTO, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); item.pszText = szStatus; item.iSubItem = 3; SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); } else if (StartUp == 0x03) { - LoadString(hInstance, IDS_SERVICES_MAN, szStatus, 128); + LoadString(hInstance, IDS_SERVICES_MAN, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); item.pszText = szStatus; item.iSubItem = 3; SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); } else if (StartUp == 0x04) { - LoadString(hInstance, IDS_SERVICES_DIS, szStatus, 128); + LoadString(hInstance, IDS_SERVICES_DIS, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); item.pszText = szStatus; item.iSubItem = 3; SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); @@ -342,7 +341,8 @@ RefreshServiceList(VOID) NumListedServ = ListView_GetItemCount(hListView); /* set the number of listed services in the status bar */ - LoadString(hInstance, IDS_NUM_SERVICES, szNumServices, 32); + LoadString(hInstance, IDS_NUM_SERVICES, szNumServices, + sizeof(szNumServices) / sizeof(TCHAR)); _sntprintf(buf, 300, szNumServices, NumListedServ); SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)buf); } @@ -382,7 +382,8 @@ GetServiceList(VOID) if (GetLastError() == ERROR_MORE_DATA) { /* reserve memory for service info array */ - pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, BytesNeeded); + pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) + HeapAlloc(GetProcessHeap(), 0, BytesNeeded); if (pServiceStatus == NULL) return FALSE; @@ -566,5 +567,53 @@ GetServiceList(VOID) } CloseServiceHandle(hService); } + + + + + + + + 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); + } + + */ diff --git a/reactos/subsys/system/servman/resource.h b/reactos/subsys/system/servman/resource.h index fd55c641fdf..ff5ec2716ac 100644 --- a/reactos/subsys/system/servman/resource.h +++ b/reactos/subsys/system/servman/resource.h @@ -87,3 +87,12 @@ #define IDC_DEPEND_TREE2 20003 #define IDC_DEPEND_SERVICE 20004 + +/* create service dialog */ +#define IDD_DLG_CREATE 8000 +#define IDC_CREATE_SERVNAME 8001 +#define IDC_CREATE_DISPNAME 8002 +#define IDC_CREATE_PATH 8003 +#define IDC_CREATE_DESC 8004 +#define IDC_CREATE_OPTIONS 8005 +#define ID_CREATE_HELP 8006 diff --git a/reactos/subsys/system/servman/servman.c b/reactos/subsys/system/servman/servman.c index 55aa961d6c8..c36fd61224f 100644 --- a/reactos/subsys/system/servman/servman.c +++ b/reactos/subsys/system/servman/servman.c @@ -332,6 +332,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { case ID_PROP: OpenPropSheet(hwnd); + break; case ID_REFRESH: @@ -342,29 +343,63 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case ID_START: - DoStartService(); - RefreshServiceList(); + if ( DoStartService() ) + { + LVITEM item; + TCHAR szStatus[64]; + + LoadString(hInstance, IDS_SERVICES_STARTED, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); + item.pszText = szStatus; + item.iItem = GetSelectedItem(); + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + } break; case ID_STOP: - Control(SERVICE_CONTROL_STOP); - RefreshServiceList(); + if( Control(SERVICE_CONTROL_STOP) ) + { + LVITEM item; + + item.pszText = '\0'; + item.iItem = GetSelectedItem(); + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + } 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(); + if( Control(SERVICE_CONTROL_STOP) ) + { + LVITEM item; + + item.pszText = '\0'; + item.iItem = GetSelectedItem(); + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + + if ( DoStartService() ) + { + LVITEM item; + TCHAR szStatus[64]; + + LoadString(hInstance, IDS_SERVICES_STARTED, szStatus, + sizeof(szStatus) / sizeof(TCHAR)); + item.pszText = szStatus; + item.iItem = GetSelectedItem(); + item.iSubItem = 2; + SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item); + } + } break; case ID_NEW: @@ -416,7 +451,6 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, { WNDCLASSEX wc; MSG Msg; - BOOL bRet; hInstance = hThisInstance; @@ -461,17 +495,11 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, ShowWindow(hMainWnd, nCmdShow); UpdateWindow(hMainWnd); - while( (bRet = GetMessage( &Msg, NULL, 0, 0 )) != 0) + while( GetMessage( &Msg, NULL, 0, 0 ) ) { - if (bRet == -1) - { - /* handle the error and possibly exit */ - } - else - { - TranslateMessage(&Msg); - DispatchMessage(&Msg); - } + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } return (int)Msg.wParam; }