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
= LoadImage(hInstance
, MAKEINTRESOURCE(IDI_SM_ICON
), IMAGE_ICON
, 16, 16, 0);
95 ImageList_AddIcon(hSmall
, hiconItem
);
97 ListView_SetImageList(hListView
, hSmall
, LVSIL_SMALL
);
99 /* set the number of services in the status bar */
100 LoadString(hInstance
, IDS_SERVICES_NUM_SERVICES
, szNumServices
, 32);
101 _stprintf(buf
, szNumServices
, NumServices
);
102 SendMessage(hStatus
, SB_SETTEXT
, 0, (LPARAM
)buf
);
104 for (Index
= 0; Index
< NumServices
; Index
++)
106 memset(&item
, 0, sizeof(LV_ITEM
));
107 item
.mask
= LVIF_TEXT
;
109 item
.pszText
= pServiceStatus
[Index
].lpDisplayName
;
110 item
.iItem
= ListView_GetItemCount(hListView
);
112 item
.iItem
= ListView_InsertItem(hListView
, &item
);
115 hService
= OpenService(ScHandle
,
116 pServiceStatus
[Index
].lpServiceName
,
118 if (hService
!= INVALID_HANDLE_VALUE
)
120 /* check if service is required by the system*/
121 if (!QueryServiceConfig2(hService
,
122 SERVICE_CONFIG_FAILURE_ACTIONS
,
123 (LPBYTE
)pServiceFailureActions
,
127 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
129 pServiceFailureActions
= (LPSERVICE_FAILURE_ACTIONS
)
130 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
131 if (pServiceFailureActions
== NULL
)
134 if (!QueryServiceConfig2(hService
,
135 SERVICE_CONFIG_FAILURE_ACTIONS
,
136 (LPBYTE
)pServiceFailureActions
,
140 HeapFree(GetProcessHeap(), 0, pServiceFailureActions
);
144 else /* exit on failure */
149 if (pServiceFailureActions
->cActions
)
151 if (pServiceFailureActions
->lpsaActions
[0].Type
== SC_ACTION_REBOOT
)
153 LoadString(hInstance
, IDS_SERVICES_YES
, szStatus
, 128);
154 item
.pszText
= szStatus
;
156 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
160 if (pServiceFailureActions
!= NULL
)
162 HeapFree(GetProcessHeap(), 0, pServiceFailureActions
);
163 pServiceFailureActions
= NULL
;
166 /* get vendor of service binary */
168 if (!QueryServiceConfig(hService
, pServiceConfig
, 0, &BytesNeeded
))
170 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
172 pServiceConfig
= (LPQUERY_SERVICE_CONFIG
)
173 HeapAlloc(GetProcessHeap(), 0, BytesNeeded
);
174 if (pServiceConfig
== NULL
)
177 if (!QueryServiceConfig(hService
,
182 HeapFree(GetProcessHeap(), 0, pServiceConfig
);
186 else /* exit on failure */
192 memset(&FileName
, 0, MAX_PATH
);
193 if (_tcscspn(pServiceConfig
->lpBinaryPathName
, _T("\"")))
195 _tcsncpy(FileName
, pServiceConfig
->lpBinaryPathName
,
196 _tcscspn(pServiceConfig
->lpBinaryPathName
, _T(" ")) );
200 _tcscpy(FileName
, pServiceConfig
->lpBinaryPathName
);
203 HeapFree(GetProcessHeap(), 0, pServiceConfig
);
204 pServiceConfig
= NULL
;
206 dwLen
= GetFileVersionInfoSize(FileName
, &dwHandle
);
209 lpData
= (TCHAR
*) HeapAlloc(GetProcessHeap(), 0, dwLen
);
213 if (!GetFileVersionInfo (FileName
, dwHandle
, dwLen
, lpData
)) {
214 HeapFree(GetProcessHeap(), 0, lpData
);
218 if (VerQueryValue(lpData
, _T("\\VarFileInfo\\Translation"), &pvData
, (PUINT
) &BufLen
))
220 wCodePage
= LOWORD(*(DWORD
*) pvData
);
221 wLangID
= HIWORD(*(DWORD
*) pvData
);
222 wsprintf(szStrFileInfo
, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage
, wLangID
);
225 if (VerQueryValue (lpData
, szStrFileInfo
, (LPVOID
) &lpBuffer
, (PUINT
) &BufLen
)) {
226 item
.pszText
= lpBuffer
;
228 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
230 HeapFree(GetProcessHeap(), 0, lpData
);
234 LoadString(hInstance
, IDS_SERVICES_UNKNOWN
, szStatus
, 128);
235 item
.pszText
= szStatus
;
237 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
239 CloseServiceHandle(hService
);
242 if (pServiceStatus
[Index
].ServiceStatusProcess
.dwCurrentState
== SERVICE_RUNNING
)
244 LoadString(hInstance
, IDS_SERVICES_STATUS_RUNNING
, szStatus
, 128);
245 item
.pszText
= szStatus
;
247 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
253 SendMessage(hListView
, LVM_SETITEMTEXT
, item
.iItem
, (LPARAM
) &item
);
259 HeapFree(GetProcessHeap(), 0, pServiceStatus
);
260 CloseServiceHandle(ScHandle
);
268 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
280 int statwidths
[] = {110, -1};
284 /* Create List View */
285 LVCOLUMN lvc
= { 0 };
288 //GetClientRect(hwnd, &rc);
289 hListView
= CreateWindow(WC_LISTVIEW
,
291 WS_CHILD
| WS_VISIBLE
| LVS_REPORT
| WS_BORDER
| LVS_EDITLABELS
,
292 0, 0, 0, 0, /* sized via WM_SIZE */
294 (HMENU
) IDC_SERVLIST
,
298 ListView_SetExtendedListViewStyle(hListView
, LVS_EX_FULLROWSELECT
|
299 /*LVS_EX_GRIDLINES |*/ LVS_EX_HEADERDRAGDROP
);
301 lvc
.mask
= LVCF_TEXT
| LVCF_SUBITEM
| LVCF_WIDTH
| LVCF_FMT
;
302 lvc
.fmt
= LVCFMT_LEFT
;
304 /* Add columns to the list-view (first column contains check box). */
307 LoadString(hInstance
, IDS_FIRSTCOLUMN
, szTemp
, 256);
308 lvc
.pszText
= szTemp
;
309 ListView_InsertColumn(hListView
, 0, &lvc
);
313 LoadString(hInstance
, IDS_SECONDCOLUMN
, szTemp
, 256);
314 lvc
.pszText
= szTemp
;
315 ListView_InsertColumn(hListView
, 1, &lvc
);
319 LoadString(hInstance
, IDS_THIRDCOLUMN
, szTemp
, 256);
320 lvc
.pszText
= szTemp
;
321 ListView_InsertColumn(hListView
, 2, &lvc
);
325 LoadString(hInstance
, IDS_FOURTHCOLUMN
, szTemp
, 256);
326 lvc
.pszText
= szTemp
;
327 ListView_InsertColumn(hListView
, 3, &lvc
);
331 LoadString(hInstance
, IDS_FITHCOLUMN
, szTemp
, 256);
332 lvc
.pszText
= szTemp
;
333 ListView_InsertColumn(hListView
, 4, &lvc
);
336 hTool
= CreateWindowEx(0,
339 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
346 MessageBox(hwnd
, _T("Could not create tool bar."), _T("Error"), MB_OK
| MB_ICONERROR
);
348 // Send the TB_BUTTONSTRUCTSIZE message, which is required for
349 // backward compatibility.
350 SendMessage(hTool
, TB_BUTTONSTRUCTSIZE
, (WPARAM
)sizeof(TBBUTTON
), 0);
352 tbab
.hInst
= HINST_COMMCTRL
;
353 tbab
.nID
= IDB_STD_SMALL_COLOR
;
354 SendMessage(hTool
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
356 ZeroMemory(tbb
, sizeof(tbb
));
357 tbb
[0].iBitmap
= STD_PROPERTIES
;
358 tbb
[0].fsState
= TBSTATE_ENABLED
;
359 tbb
[0].fsStyle
= TBSTYLE_BUTTON
;
360 tbb
[0].idCommand
= ID_PROP
;
361 tbb
[1].iBitmap
= STD_FILENEW
;
362 tbb
[1].fsState
= TBSTATE_ENABLED
;
363 tbb
[1].fsStyle
= TBSTYLE_BUTTON
;
364 tbb
[1].idCommand
= ID_REFRESH
;
365 tbb
[2].iBitmap
= STD_FILENEW
;
366 tbb
[2].fsState
= TBSTATE_ENABLED
;
367 tbb
[2].fsStyle
= TBSTYLE_BUTTON
;
368 tbb
[2].idCommand
= ID_EXPORT
;
370 tbb
[3].iBitmap
= STD_FILENEW
;
371 tbb
[3].fsState
= TBSTATE_ENABLED
;
372 tbb
[3].fsStyle
= TBSTYLE_BUTTON
;
373 tbb
[3].idCommand
= ID_START
;
374 tbb
[4].iBitmap
= STD_FILENEW
;
375 tbb
[4].fsState
= TBSTATE_ENABLED
;
376 tbb
[4].fsStyle
= TBSTYLE_BUTTON
;
377 tbb
[4].idCommand
= ID_STOP
;
378 tbb
[5].iBitmap
= STD_FILENEW
;
379 tbb
[5].fsState
= TBSTATE_ENABLED
;
380 tbb
[5].fsStyle
= TBSTYLE_BUTTON
;
381 tbb
[5].idCommand
= ID_PAUSE
;
382 tbb
[6].iBitmap
= STD_FILENEW
;
383 tbb
[6].fsState
= TBSTATE_ENABLED
;
384 tbb
[6].fsStyle
= TBSTYLE_BUTTON
;
385 tbb
[6].idCommand
= ID_RESTART
;
386 SendMessage(hTool
, TB_ADDBUTTONS
, sizeof(tbb
)/sizeof(TBBUTTON
), (LPARAM
)&tbb
);
388 /* Create Status bar */
389 hStatus
= CreateWindowEx(0,
392 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
395 (HMENU
)IDC_STATUSBAR
,
399 MessageBox(hwnd
, _T("Could not create status bar."), _T("Error"), MB_OK
| MB_ICONERROR
);
401 SendMessage(hStatus
, SB_SETPARTS
, sizeof(statwidths
)/sizeof(int), (LPARAM
)statwidths
);
403 /* populate the list view with all services */
421 /* Size toolbar and get height */
422 hTool
= GetDlgItem(hwnd
, IDC_TOOLBAR
);
423 SendMessage(hTool
, TB_AUTOSIZE
, 0, 0);
425 GetWindowRect(hTool
, &rcTool
);
426 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
428 /* Size status bar and get height */
429 hStatus
= GetDlgItem(hwnd
, IDC_STATUSBAR
);
430 SendMessage(hStatus
, WM_SIZE
, 0, 0);
432 GetWindowRect(hStatus
, &rcStatus
);
433 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
435 /* Calculate remaining height and size list view */
436 GetClientRect(hwnd
, &rcClient
);
438 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
440 hListView
= GetDlgItem(hwnd
, IDC_SERVLIST
);
441 SetWindowPos(hListView
, NULL
, 0, iToolHeight
, rcClient
.right
, lvHeight
, SWP_NOZORDER
);
446 switch (((LPNMHDR
) lParam
)->code
)
448 case TTN_GETDISPINFO
:
453 lpttt
= (LPTOOLTIPTEXT
) lParam
;
454 lpttt
->hinst
= hInstance
;
456 // Specify the resource identifier of the descriptive
457 // text for the given button.
458 idButton
= lpttt
->hdr
.idFrom
;
462 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PROP
);
466 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
470 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT
);
474 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_START
);
478 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_STOP
);
482 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE
);
486 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_RESTART
);
493 // Process other notifications here.
507 switch(LOWORD(wParam
))
510 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
534 case ID_VIEW_CUSTOMIZE
:
546 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
553 int WINAPI
WinMain(HINSTANCE hThisInstance
, HINSTANCE hPrevInstance
,
554 LPSTR lpCmdLine
, int nCmdShow
)
561 hInstance
= hThisInstance
;
563 InitCommonControls();
565 wc
.cbSize
= sizeof(WNDCLASSEX
);
567 wc
.lpfnWndProc
= WndProc
;
570 wc
.hInstance
= hInstance
;
571 wc
.hIcon
= LoadIcon(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDI_SM_ICON
));
572 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
573 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
574 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
575 wc
.lpszClassName
= ClassName
;
576 wc
.hIconSm
= (HICON
)LoadImage(hInstance
,
577 MAKEINTRESOURCE(IDI_SM_ICON
), IMAGE_ICON
, 16, 16, 0);
579 if(!RegisterClassEx(&wc
))
581 MessageBox(NULL
, _T("Window Registration Failed!"), _T("Error!"),
582 MB_ICONEXCLAMATION
| MB_OK
);
586 hwnd
= CreateWindowEx(
589 _T("ReactOS Service Manager"),
590 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
591 CW_USEDEFAULT
, CW_USEDEFAULT
, 700, 500,
592 NULL
, NULL
, hInstance
, NULL
);
596 MessageBox(NULL
, _T("Window Creation Failed!"), _T("Error!"),
597 MB_ICONEXCLAMATION
| MB_OK
);
601 ShowWindow(hwnd
, nCmdShow
);
604 while( (bRet
= GetMessage( &Msg
, NULL
, 0, 0 )) != 0)
608 /* handle the error and possibly exit */
612 TranslateMessage(&Msg
);
613 DispatchMessage(&Msg
);