- list items alphabetically
[reactos.git] / reactos / subsys / system / servman / servman.c
index 393154d..4339af8 100644 (file)
-#include <windows.h>\r
-#include <stdio.h>\r
-#include <tchar.h>\r
-#include <commctrl.h>\r
-#include "resource.h"\r
+/*\r
+ * PROJECT:     ReactOS Services\r
+ * LICENSE:     GPL - See COPYING in the top level directory\r
+ * FILE:        subsys/system/servman/servman.c\r
+ * PURPOSE:     Main window message handler\r
+ * COPYRIGHT:   Copyright 2005 Ged Murphy <gedmurphy@gmail.com>\r
+ *               \r
+ */\r
+\r
+#include "servman.h"\r
 \r
 const TCHAR ClassName[] = _T("ServiceManager");\r
 \r
 HINSTANCE hInstance;\r
+HWND hMainWnd;\r
 HWND hListView;\r
 HWND hStatus;\r
 \r
 \r
-void\r
-GetServices ( void )\r
-{\r
-    LV_ITEM item;\r
-    WORD wCodePage;\r
-    WORD wLangID;\r
-    SC_HANDLE ScHandle;\r
-    SC_HANDLE hService;\r
-    DWORD BytesNeeded = 0;\r
-    DWORD ResumeHandle = 0;\r
-    DWORD NumServices = 0;\r
-    DWORD dwHandle, dwLen;\r
-    size_t Index;\r
-    UINT BufLen;\r
-    TCHAR szStatus[128];\r
-    TCHAR* lpData;\r
-    TCHAR* lpBuffer;\r
-    TCHAR szStrFileInfo[80];\r
-    TCHAR FileName[MAX_PATH];\r
-    TCHAR szNumServices[32];\r
-    LPVOID pvData;\r
-\r
-    LPSERVICE_FAILURE_ACTIONS pServiceFailureActions = NULL;\r
-    LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;\r
-    ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;\r
-\r
-    ScHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);\r
-    if (ScHandle != INVALID_HANDLE_VALUE)\r
-    {\r
-        if (EnumServicesStatusEx(ScHandle,\r
-                                 SC_ENUM_PROCESS_INFO,\r
-                                 SERVICE_WIN32,\r
-                                 SERVICE_STATE_ALL,\r
-                                 (LPBYTE)pServiceStatus,\r
-                                 0, &BytesNeeded,\r
-                                 &NumServices,\r
-                                 &ResumeHandle,\r
-                                 0) == 0)\r
-        {\r
-            /* Call function again if required size was returned */\r
-            if (GetLastError() == ERROR_MORE_DATA)\r
-            {\r
-                /* reserve memory for service info array */\r
-                pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, BytesNeeded);\r
-                if (pServiceStatus == NULL)\r
-                               return;\r
-\r
-                /* fill array with service info */\r
-                if (EnumServicesStatusEx(ScHandle,\r
-                                         SC_ENUM_PROCESS_INFO,\r
-                                         SERVICE_WIN32,\r
-                                         SERVICE_STATE_ALL,\r
-                                         (LPBYTE)pServiceStatus,\r
-                                         BytesNeeded,\r
-                                         &BytesNeeded,\r
-                                         &NumServices,\r
-                                         &ResumeHandle,\r
-                                         0) == 0)\r
-                {\r
-                    HeapFree(GetProcessHeap(), 0, pServiceStatus);\r
-                    return;\r
-                }\r
-            }\r
-            else /* exit on failure */\r
-            {\r
-                return;\r
-            }\r
-        }\r
-\r
-        if (NumServices)\r
-        {\r
-            HICON hiconItem;     // icon for list-view items\r
-            HIMAGELIST hSmall;   // image list for other views\r
-            TCHAR buf[40];\r
-\r
-            /* Create the icon image lists */\r
-            hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),\r
-                GetSystemMetrics(SM_CYSMICON), ILC_MASK, 1, 1);\r
-\r
-            /* Add an icon to each image list */\r
-            hiconItem = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SM_ICON));\r
-            ImageList_AddIcon(hSmall, hiconItem);\r
-            DestroyIcon(hiconItem);\r
-\r
-            ListView_SetImageList(hListView, hSmall, LVSIL_SMALL);\r
-\r
-            /* set the number of services in the status bar */\r
-            LoadString(hInstance, IDS_SERVICES_NUM_SERVICES, szNumServices, 32);\r
-            _stprintf(buf, szNumServices, NumServices);\r
-            SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)buf);\r
-\r
-            for (Index = 0; Index < NumServices; Index++)\r
-            {\r
-                memset(&item, 0, sizeof(LV_ITEM));\r
-                item.mask = LVIF_TEXT;\r
-                //item.iImage = 0;\r
-                item.pszText = pServiceStatus[Index].lpDisplayName;\r
-                item.iItem = ListView_GetItemCount(hListView);\r
-                item.lParam = 0;\r
-                item.iItem = ListView_InsertItem(hListView, &item);\r
-\r
-                BytesNeeded = 0;\r
-                hService = OpenService(ScHandle,\r
-                                       pServiceStatus[Index].lpServiceName,\r
-                                       SC_MANAGER_CONNECT);\r
-                if (hService != INVALID_HANDLE_VALUE)\r
-                {\r
-                    /* check if service is required by the system*/\r
-                    if (!QueryServiceConfig2(hService,\r
-                                             SERVICE_CONFIG_FAILURE_ACTIONS,\r
-                                             (LPBYTE)pServiceFailureActions,\r
-                                             0,\r
-                                             &BytesNeeded))\r
-                    {\r
-                        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\r
-                        {\r
-                            pServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS)\r
-                                HeapAlloc(GetProcessHeap(), 0, BytesNeeded);\r
-                            if (pServiceFailureActions == NULL)\r
-                                           return;\r
-\r
-                            if (!QueryServiceConfig2(hService,\r
-                                                     SERVICE_CONFIG_FAILURE_ACTIONS,\r
-                                                     (LPBYTE)pServiceFailureActions,\r
-                                                     BytesNeeded,\r
-                                                     &BytesNeeded))\r
-                            {\r
-                                HeapFree(GetProcessHeap(), 0, pServiceFailureActions);\r
-                                return;\r
-                            }\r
-                        }\r
-                        else /* exit on failure */\r
-                        {\r
-                            return;\r
-                        }\r
-                    }\r
-                    if (pServiceFailureActions->cActions)\r
-                    {\r
-                        if (pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)\r
-                        {\r
-                            LoadString(hInstance, IDS_SERVICES_YES, szStatus, 128);\r
-                            item.pszText = szStatus;\r
-                            item.iSubItem = 1;\r
-                            SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);\r
-                        }\r
-                    }\r
-\r
-                                       if (pServiceFailureActions != NULL)\r
-                                       {\r
-                                               HeapFree(GetProcessHeap(), 0, pServiceFailureActions);\r
-                                               pServiceFailureActions = NULL;\r
-                                       }\r
-\r
-                    /* get vendor of service binary */\r
-                    BytesNeeded = 0;\r
-                    if (!QueryServiceConfig(hService, pServiceConfig, 0, &BytesNeeded))\r
-                    {\r
-                        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\r
-                        {\r
-                            pServiceConfig = (LPQUERY_SERVICE_CONFIG)\r
-                                HeapAlloc(GetProcessHeap(), 0, BytesNeeded);\r
-                            if (pServiceConfig == NULL)\r
-                                           return;\r
-\r
-                            if (!QueryServiceConfig(hService,\r
-                                                    pServiceConfig,\r
-                                                    BytesNeeded,\r
-                                                    &BytesNeeded))\r
-                            {\r
-                                HeapFree(GetProcessHeap(), 0, pServiceConfig);\r
-                                return;\r
-                            }\r
-                        }\r
-                        else /* exit on failure */\r
-                        {\r
-                            return;\r
-                        }\r
-                    }\r
-\r
-                    memset(&FileName, 0, MAX_PATH);\r
-                    if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\"")))\r
-                    {\r
-                        _tcsncpy(FileName, pServiceConfig->lpBinaryPathName,\r
-                            _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) );\r
-                    }\r
-                    else\r
-                    {\r
-                        _tcscpy(FileName, pServiceConfig->lpBinaryPathName);\r
-                    }\r
-\r
-                                       HeapFree(GetProcessHeap(), 0, pServiceConfig);\r
-                                       pServiceConfig = NULL;\r
-\r
-                                       dwLen = GetFileVersionInfoSize(FileName, &dwHandle);\r
-                    if (dwLen)\r
-                    {\r
-                        lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen);\r
-                        if (lpData == NULL)\r
-                                       return;\r
-\r
-                        if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData)) {\r
-                                   HeapFree(GetProcessHeap(), 0, lpData);\r
-                                   return;\r
-                           }\r
-\r
-                        if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen))\r
-                        {\r
-                            wCodePage = LOWORD(*(DWORD*) pvData);\r
-                            wLangID = HIWORD(*(DWORD*) pvData);\r
-                            wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID);\r
-                        }\r
-\r
-                        if (VerQueryValue (lpData, szStrFileInfo, (LPVOID) &lpBuffer, (PUINT) &BufLen)) {\r
-                            item.pszText = lpBuffer;\r
-                            item.iSubItem = 2;\r
-                            SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);\r
-                        }\r
-                                               HeapFree(GetProcessHeap(), 0, lpData);\r
-                    }\r
-                    else\r
-                    {\r
-                        LoadString(hInstance, IDS_SERVICES_UNKNOWN, szStatus, 128);\r
-                        item.pszText = szStatus;\r
-                        item.iSubItem = 2;\r
-                        SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);\r
-                    }\r
-                    CloseServiceHandle(hService);\r
-                }\r
-\r
-                if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)\r
-                {\r
-                    LoadString(hInstance, IDS_SERVICES_STATUS_RUNNING, szStatus, 128);\r
-                    item.pszText = szStatus;\r
-                    item.iSubItem = 2;\r
-                    SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);\r
-                }\r
-                else\r
-                {\r
-                    item.pszText = '\0';\r
-                    item.iSubItem = 2;\r
-                    SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);\r
-                }\r
-\r
-            }\r
-        }\r
-\r
-        HeapFree(GetProcessHeap(), 0, pServiceStatus);\r
-        CloseServiceHandle(ScHandle);\r
-    }\r
-\r
-\r
-}\r
-\r
-\r
-\r
 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
 {\r
        switch(msg)\r
@@ -286,10 +37,10 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             LVCOLUMN lvc = { 0 };\r
             //LVITEM   lv  = { 0 };\r
 \r
-            //GetClientRect(hwnd, &rc);\r
             hListView = CreateWindow(WC_LISTVIEW,\r
                                      NULL,\r
-                                     WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER | LVS_EDITLABELS,\r
+                                     WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER | \r
+                                     LVS_EDITLABELS | LVS_SORTASCENDING,\r
                                      0, 0, 0, 0, /* sized via WM_SIZE */\r
                                      hwnd,\r
                                      (HMENU) IDC_SERVLIST,\r
@@ -310,13 +61,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             ListView_InsertColumn(hListView, 0, &lvc);\r
 \r
             lvc.iSubItem = 1;\r
-            lvc.cx       = 150;\r
+            lvc.cx       = 260;\r
             LoadString(hInstance, IDS_SECONDCOLUMN, szTemp, 256);\r
             lvc.pszText  = szTemp;\r
             ListView_InsertColumn(hListView, 1, &lvc);\r
 \r
             lvc.iSubItem = 2;\r
-            lvc.cx       = 80;\r
+            lvc.cx       = 75;\r
             LoadString(hInstance, IDS_THIRDCOLUMN, szTemp, 256);\r
             lvc.pszText  = szTemp;\r
             ListView_InsertColumn(hListView, 2, &lvc);\r
@@ -333,7 +84,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             lvc.pszText  = szTemp;\r
             ListView_InsertColumn(hListView, 4, &lvc);\r
 \r
-                       // Create Toolbar\r
+                       /* Create Toolbar */\r
                        hTool = CreateWindowEx(0,\r
                                    TOOLBARCLASSNAME,\r
                                    NULL,\r
@@ -397,12 +148,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                                      hInstance,\r
                                      NULL);\r
             if(hStatus == NULL)\r
-                               MessageBox(hwnd, _T("Could not create status bar."), _T("Error"), MB_OK | MB_ICONERROR);\r
+                               MessageBox(hwnd, _T("Could not create status bar."),\r
+                           _T("Error!"), MB_OK | MB_ICONERROR);\r
 \r
                        SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);\r
 \r
                        /* populate the list view with all services */\r
-                       GetServices();\r
+                       if (! RefreshServiceList() )\r
+                GetError();\r
                }\r
                break;\r
                case WM_SIZE:\r
@@ -411,11 +164,11 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                        RECT rcTool;\r
                        int iToolHeight;\r
 \r
-                       HWND hStatus;\r
+                       //HWND hStatus;\r
                        RECT rcStatus;\r
                        int iStatusHeight;\r
 \r
-                       HWND hListView;\r
+                       //HWND hListView;\r
                        int lvHeight;\r
                        RECT rcClient;\r
 \r
@@ -444,8 +197,18 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                break;\r
 \r
                case WM_NOTIFY:\r
+        {\r
+            LPNMITEMACTIVATE item;\r
+\r
             switch (((LPNMHDR) lParam)->code)\r
             {\r
+\r
+                       case NM_DBLCLK:\r
+                               item = (LPNMITEMACTIVATE) lParam;\r
+                               PropSheets(hwnd);\r
+\r
+                               break;\r
+            \r
                 case TTN_GETDISPINFO:\r
                 {\r
                     LPTOOLTIPTEXT lpttt;\r
@@ -491,14 +254,15 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 }\r
                 break;\r
 \r
-                // Process other notifications here.\r
-\r
                 default:\r
                 break;\r
             }\r
+        }\r
         break;\r
 \r
                case WM_CLOSE:\r
+            /* free the service array */\r
+            FreeMemory();\r
                        DestroyWindow(hwnd);\r
                break;\r
                case WM_DESTROY:\r
@@ -530,13 +294,18 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                 break;\r
 \r
                 case ID_PROP:\r
+                    PropSheets(hwnd);\r
                 break;\r
 \r
                 case ID_VIEW_CUSTOMIZE:\r
                 break;\r
 \r
                 case ID_HELP_ABOUT:\r
-                break;\r
+                    DialogBox(GetModuleHandle(NULL),\r
+                              MAKEINTRESOURCE(IDD_ABOUTBOX),\r
+                              hwnd,\r
+                              AboutDialogProc);\r
+                 break;\r
 \r
                 case ID_EXPORT:\r
                 break;\r
@@ -555,7 +324,6 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)\r
 {\r
        WNDCLASSEX wc;\r
-       HWND hwnd;\r
        MSG Msg;\r
        BOOL bRet;\r
 \r
@@ -569,12 +337,12 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
        wc.cbClsExtra    = 0;\r
        wc.cbWndExtra    = 0;\r
        wc.hInstance     = hInstance;\r
-       wc.hIcon                 = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SM_ICON));\r
+       wc.hIcon                 = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SM_ICON));\r
        wc.hCursor               = LoadCursor(NULL, IDC_ARROW);\r
-       wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);\r
+       wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);\r
        wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAINMENU);\r
        wc.lpszClassName = ClassName;\r
-       wc.hIconSm               = (HICON)LoadImage(GetModuleHandle(NULL),\r
+       wc.hIconSm               = (HICON)LoadImage(hInstance,\r
                         MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0);\r
 \r
        if(!RegisterClassEx(&wc))\r
@@ -584,7 +352,7 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
                return 0;\r
        }\r
 \r
-       hwnd = CreateWindowEx(\r
+       hMainWnd = CreateWindowEx(\r
                0,\r
                ClassName,\r
                _T("ReactOS Service Manager"),\r
@@ -592,15 +360,15 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
                CW_USEDEFAULT, CW_USEDEFAULT, 700, 500,\r
                NULL, NULL, hInstance, NULL);\r
 \r
-       if(hwnd == NULL)\r
+       if(hMainWnd == NULL)\r
        {\r
                MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"),\r
                        MB_ICONEXCLAMATION | MB_OK);\r
                return 0;\r
        }\r
 \r
-       ShowWindow(hwnd, nCmdShow);\r
-       UpdateWindow(hwnd);\r
+       ShowWindow(hMainWnd, nCmdShow);\r
+       UpdateWindow(hMainWnd);\r
 \r
     while( (bRet = GetMessage( &Msg, NULL, 0, 0 )) != 0)\r
     {\r