7 const TCHAR ClassName
[] = _T("ServiceManager");
22 DWORD BytesNeeded
= 0;
23 DWORD ResumeHandle
= 0;
24 DWORD NumServices
= 0;
25 DWORD dwHandle
, dwLen
;
31 TCHAR szStrFileInfo
[80];
32 TCHAR FileName
[MAX_PATH
];
33 TCHAR szNumServices
[32];
36 LPSERVICE_FAILURE_ACTIONS pServiceFailureActions
= NULL
;
37 LPQUERY_SERVICE_CONFIG pServiceConfig
= NULL
;
38 ENUM_SERVICE_STATUS_PROCESS
*pServiceStatus
= NULL
;
40 ScHandle
= OpenSCManager(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
41 if (ScHandle
!= INVALID_HANDLE_VALUE
)
43 if (EnumServicesStatusEx(ScHandle
,
47 (LPBYTE
)pServiceStatus
,
53 /* Call function again if required size was returned */
54 if (GetLastError() == ERROR_MORE_DATA
)
56 /* reserve memory for service info array */
57 pServiceStatus
= (ENUM_SERVICE_STATUS_PROCESS
*) HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
58 if (pServiceStatus
== NULL
)
61 /* fill array with service info */
62 if (EnumServicesStatusEx(ScHandle
,
66 (LPBYTE
)pServiceStatus
,
73 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
77 else /* exit on failure */
85 HICON hiconItem
; // icon for list-view items
86 HIMAGELIST hSmall
; // image list for other views
89 /* Create the icon image lists */
90 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
91 GetSystemMetrics(SM_CYSMICON
), ILC_MASK
, 1, 1);
93 /* Add an icon to each image list */
94 hiconItem
= LoadIcon(hInstance
, MAKEINTRESOURCE(IDI_SM_ICON
));
95 ImageList_AddIcon(hSmall
, hiconItem
);
96 DestroyIcon(hiconItem
);
98 ListView_SetImageList(hListView
, hSmall
, LVSIL_SMALL
);
100 /* set the number of services in the status bar */
101 LoadString(hInstance
, IDS_SERVICES_NUM_SERVICES
, szNumServices
, 32);
102 _stprintf(buf
, szNumServices
, NumServices
);
103 SendMessage(hStatus
, SB_SETTEXT
, 0, (LPARAM
)buf
);
105 for (Index
= 0; Index
< NumServices
; Index
++)
107 memset(&item
, 0, sizeof(LV_ITEM
));
108 item
.mask
= LVIF_TEXT
;
110 item
.pszText
= pServiceStatus
[Index
].lpDisplayName
;
111 item
.iItem
= ListView_GetItemCount(hListView
);
113 item
.iItem
= ListView_InsertItem(hListView
, &item
);
116 hService
= OpenService(ScHandle
,
117 pServiceStatus
[Index
].lpServiceName
,
119 if (hService
!= INVALID_HANDLE_VALUE
)
121 /* check if service is required by the system*/
122 if (!QueryServiceConfig2(hService
,
123 SERVICE_CONFIG_FAILURE_ACTIONS
,
124 (LPBYTE
)pServiceFailureActions
,
128 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
130 pServiceFailureActions
= (LPSERVICE_FAILURE_ACTIONS
)
131 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
132 if (pServiceFailureActions
== NULL
)
135 if (!QueryServiceConfig2(hService
,
136 SERVICE_CONFIG_FAILURE_ACTIONS
,
137 (LPBYTE
)pServiceFailureActions
,
141 HeapFree(GetProcessHeap(), 0, pServiceFailureActions
);
145 else /* exit on failure */
150 if (pServiceFailureActions
->cActions
)
152 if (pServiceFailureActions
->lpsaActions
[0].Type
== SC_ACTION_REBOOT
)
154 LoadString(hInstance
, IDS_SERVICES_YES
, szStatus
, 128);
155 item
.pszText
= szStatus
;
157 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
161 if (pServiceFailureActions
!= NULL
)
163 HeapFree(GetProcessHeap(), 0, pServiceFailureActions
);
164 pServiceFailureActions
= NULL
;
167 /* get vendor of service binary */
169 if (!QueryServiceConfig(hService
, pServiceConfig
, 0, &BytesNeeded
))
171 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
173 pServiceConfig
= (LPQUERY_SERVICE_CONFIG
)
174 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
175 if (pServiceConfig
== NULL
)
178 if (!QueryServiceConfig(hService
,
183 HeapFree(GetProcessHeap(), 0, pServiceConfig
);
187 else /* exit on failure */
193 memset(&FileName
, 0, MAX_PATH
);
194 if (_tcscspn(pServiceConfig
->lpBinaryPathName
, _T("\"")))
196 _tcsncpy(FileName
, pServiceConfig
->lpBinaryPathName
,
197 _tcscspn(pServiceConfig
->lpBinaryPathName
, _T(" ")) );
201 _tcscpy(FileName
, pServiceConfig
->lpBinaryPathName
);
204 HeapFree(GetProcessHeap(), 0, pServiceConfig
);
205 pServiceConfig
= NULL
;
207 dwLen
= GetFileVersionInfoSize(FileName
, &dwHandle
);
210 lpData
= (TCHAR
*) HeapAlloc(GetProcessHeap(), 0, dwLen
);
214 if (!GetFileVersionInfo (FileName
, dwHandle
, dwLen
, lpData
)) {
215 HeapFree(GetProcessHeap(), 0, lpData
);
219 if (VerQueryValue(lpData
, _T("\\VarFileInfo\\Translation"), &pvData
, (PUINT
) &BufLen
))
221 wCodePage
= LOWORD(*(DWORD
*) pvData
);
222 wLangID
= HIWORD(*(DWORD
*) pvData
);
223 wsprintf(szStrFileInfo
, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage
, wLangID
);
226 if (VerQueryValue (lpData
, szStrFileInfo
, (LPVOID
) &lpBuffer
, (PUINT
) &BufLen
)) {
227 item
.pszText
= lpBuffer
;
229 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
231 HeapFree(GetProcessHeap(), 0, lpData
);
235 LoadString(hInstance
, IDS_SERVICES_UNKNOWN
, szStatus
, 128);
236 item
.pszText
= szStatus
;
238 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
240 CloseServiceHandle(hService
);
243 if (pServiceStatus
[Index
].ServiceStatusProcess
.dwCurrentState
== SERVICE_RUNNING
)
245 LoadString(hInstance
, IDS_SERVICES_STATUS_RUNNING
, szStatus
, 128);
246 item
.pszText
= szStatus
;
248 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
254 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
260 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
261 CloseServiceHandle(ScHandle
);
269 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
281 int statwidths
[] = {110, -1};
285 /* Create List View */
286 LVCOLUMN lvc
= { 0 };
289 //GetClientRect(hwnd, &rc);
290 hListView
= CreateWindow(WC_LISTVIEW
,
292 WS_CHILD
| WS_VISIBLE
| LVS_REPORT
| WS_BORDER
| LVS_EDITLABELS
,
293 0, 0, 0, 0, /* sized via WM_SIZE */
295 (HMENU
) IDC_SERVLIST
,
299 ListView_SetExtendedListViewStyle(hListView
, LVS_EX_FULLROWSELECT
|
300 /*LVS_EX_GRIDLINES |*/ LVS_EX_HEADERDRAGDROP
);
302 lvc
.mask
= LVCF_TEXT
| LVCF_SUBITEM
| LVCF_WIDTH
| LVCF_FMT
;
303 lvc
.fmt
= LVCFMT_LEFT
;
305 /* Add columns to the list-view (first column contains check box). */
308 LoadString(hInstance
, IDS_FIRSTCOLUMN
, szTemp
, 256);
309 lvc
.pszText
= szTemp
;
310 ListView_InsertColumn(hListView
, 0, &lvc
);
314 LoadString(hInstance
, IDS_SECONDCOLUMN
, szTemp
, 256);
315 lvc
.pszText
= szTemp
;
316 ListView_InsertColumn(hListView
, 1, &lvc
);
320 LoadString(hInstance
, IDS_THIRDCOLUMN
, szTemp
, 256);
321 lvc
.pszText
= szTemp
;
322 ListView_InsertColumn(hListView
, 2, &lvc
);
326 LoadString(hInstance
, IDS_FOURTHCOLUMN
, szTemp
, 256);
327 lvc
.pszText
= szTemp
;
328 ListView_InsertColumn(hListView
, 3, &lvc
);
332 LoadString(hInstance
, IDS_FITHCOLUMN
, szTemp
, 256);
333 lvc
.pszText
= szTemp
;
334 ListView_InsertColumn(hListView
, 4, &lvc
);
337 hTool
= CreateWindowEx(0,
340 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
347 MessageBox(hwnd
, _T("Could not create tool bar."), _T("Error"), MB_OK
| MB_ICONERROR
);
349 // Send the TB_BUTTONSTRUCTSIZE message, which is required for
350 // backward compatibility.
351 SendMessage(hTool
, TB_BUTTONSTRUCTSIZE
, (WPARAM
)sizeof(TBBUTTON
), 0);
353 tbab
.hInst
= HINST_COMMCTRL
;
354 tbab
.nID
= IDB_STD_SMALL_COLOR
;
355 SendMessage(hTool
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
357 ZeroMemory(tbb
, sizeof(tbb
));
358 tbb
[0].iBitmap
= STD_PROPERTIES
;
359 tbb
[0].fsState
= TBSTATE_ENABLED
;
360 tbb
[0].fsStyle
= TBSTYLE_BUTTON
;
361 tbb
[0].idCommand
= ID_PROP
;
362 tbb
[1].iBitmap
= STD_FILENEW
;
363 tbb
[1].fsState
= TBSTATE_ENABLED
;
364 tbb
[1].fsStyle
= TBSTYLE_BUTTON
;
365 tbb
[1].idCommand
= ID_REFRESH
;
366 tbb
[2].iBitmap
= STD_FILENEW
;
367 tbb
[2].fsState
= TBSTATE_ENABLED
;
368 tbb
[2].fsStyle
= TBSTYLE_BUTTON
;
369 tbb
[2].idCommand
= ID_EXPORT
;
371 tbb
[3].iBitmap
= STD_FILENEW
;
372 tbb
[3].fsState
= TBSTATE_ENABLED
;
373 tbb
[3].fsStyle
= TBSTYLE_BUTTON
;
374 tbb
[3].idCommand
= ID_START
;
375 tbb
[4].iBitmap
= STD_FILENEW
;
376 tbb
[4].fsState
= TBSTATE_ENABLED
;
377 tbb
[4].fsStyle
= TBSTYLE_BUTTON
;
378 tbb
[4].idCommand
= ID_STOP
;
379 tbb
[5].iBitmap
= STD_FILENEW
;
380 tbb
[5].fsState
= TBSTATE_ENABLED
;
381 tbb
[5].fsStyle
= TBSTYLE_BUTTON
;
382 tbb
[5].idCommand
= ID_PAUSE
;
383 tbb
[6].iBitmap
= STD_FILENEW
;
384 tbb
[6].fsState
= TBSTATE_ENABLED
;
385 tbb
[6].fsStyle
= TBSTYLE_BUTTON
;
386 tbb
[6].idCommand
= ID_RESTART
;
387 SendMessage(hTool
, TB_ADDBUTTONS
, sizeof(tbb
)/sizeof(TBBUTTON
), (LPARAM
)&tbb
);
389 /* Create Status bar */
390 hStatus
= CreateWindowEx(0,
393 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
396 (HMENU
)IDC_STATUSBAR
,
400 MessageBox(hwnd
, _T("Could not create status bar."), _T("Error"), MB_OK
| MB_ICONERROR
);
402 SendMessage(hStatus
, SB_SETPARTS
, sizeof(statwidths
)/sizeof(int), (LPARAM
)statwidths
);
404 /* populate the list view with all services */
422 /* Size toolbar and get height */
423 hTool
= GetDlgItem(hwnd
, IDC_TOOLBAR
);
424 SendMessage(hTool
, TB_AUTOSIZE
, 0, 0);
426 GetWindowRect(hTool
, &rcTool
);
427 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
429 /* Size status bar and get height */
430 hStatus
= GetDlgItem(hwnd
, IDC_STATUSBAR
);
431 SendMessage(hStatus
, WM_SIZE
, 0, 0);
433 GetWindowRect(hStatus
, &rcStatus
);
434 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
436 /* Calculate remaining height and size list view */
437 GetClientRect(hwnd
, &rcClient
);
439 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
441 hListView
= GetDlgItem(hwnd
, IDC_SERVLIST
);
442 SetWindowPos(hListView
, NULL
, 0, iToolHeight
, rcClient
.right
, lvHeight
, SWP_NOZORDER
);
447 switch (((LPNMHDR
) lParam
)->code
)
449 case TTN_GETDISPINFO
:
454 lpttt
= (LPTOOLTIPTEXT
) lParam
;
455 lpttt
->hinst
= hInstance
;
457 // Specify the resource identifier of the descriptive
458 // text for the given button.
459 idButton
= lpttt
->hdr
.idFrom
;
463 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PROP
);
467 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
471 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT
);
475 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_START
);
479 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_STOP
);
483 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE
);
487 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_RESTART
);
494 // Process other notifications here.
508 switch(LOWORD(wParam
))
511 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
535 case ID_VIEW_CUSTOMIZE
:
547 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
554 int WINAPI
WinMain(HINSTANCE hThisInstance
, HINSTANCE hPrevInstance
,
555 LPSTR lpCmdLine
, int nCmdShow
)
562 hInstance
= hThisInstance
;
564 InitCommonControls();
566 wc
.cbSize
= sizeof(WNDCLASSEX
);
568 wc
.lpfnWndProc
= WndProc
;
571 wc
.hInstance
= hInstance
;
572 wc
.hIcon
= LoadIcon(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDI_SM_ICON
));
573 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
574 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
);
575 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
576 wc
.lpszClassName
= ClassName
;
577 wc
.hIconSm
= (HICON
)LoadImage(GetModuleHandle(NULL
),
578 MAKEINTRESOURCE(IDI_SM_ICON
), IMAGE_ICON
, 16, 16, 0);
580 if(!RegisterClassEx(&wc
))
582 MessageBox(NULL
, _T("Window Registration Failed!"), _T("Error!"),
583 MB_ICONEXCLAMATION
| MB_OK
);
587 hwnd
= CreateWindowEx(
590 _T("ReactOS Service Manager"),
591 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
592 CW_USEDEFAULT
, CW_USEDEFAULT
, 700, 500,
593 NULL
, NULL
, hInstance
, NULL
);
597 MessageBox(NULL
, _T("Window Creation Failed!"), _T("Error!"),
598 MB_ICONEXCLAMATION
| MB_OK
);
602 ShowWindow(hwnd
, nCmdShow
);
605 while( (bRet
= GetMessage( &Msg
, NULL
, 0, 0 )) != 0)
609 /* handle the error and possibly exit */
613 TranslateMessage(&Msg
);
614 DispatchMessage(&Msg
);