- 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
This commit is contained in:
Ged Murphy 2006-01-20 17:29:50 +00:00
parent 42b0618579
commit 43744d9581
5 changed files with 206 additions and 88 deletions

View file

@ -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"

View file

@ -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;

View file

@ -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);
}
*/

View file

@ -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

View file

@ -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;
}