- Merge from trunk up to r45543
[reactos.git] / base / applications / mscutils / servman / propsheet_depends.c
index e18f10b..fd5a5d3 100644 (file)
 #include "precomp.h"
 
 
-static HTREEITEM
+HTREEITEM
 AddItemToTreeView(HWND hTreeView,
-                  HTREEITEM hRoot,
-                  LPTSTR lpLabel,
-                  ULONG serviceType)
+                  HTREEITEM hParent,
+                  LPTSTR lpDisplayName,
+                  LPTSTR lpServiceName,
+                  ULONG ServiceType,
+                  BOOL bHasChildren)
 {
     TV_ITEM tvi;
     TV_INSERTSTRUCT tvins;
+    LPTSTR lpName;
+    DWORD dwSize;
 
     ZeroMemory(&tvi, sizeof(tvi));
     ZeroMemory(&tvins, sizeof(tvins));
 
-    tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE;
-    tvi.pszText = lpLabel;
-    tvi.cchTextMax = lstrlen(lpLabel);
+    tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_CHILDREN;
+    tvi.pszText = lpDisplayName;
+    tvi.cchTextMax = _tcslen(lpDisplayName);
+    tvi.cChildren = bHasChildren;
 
-    if (serviceType == SERVICE_WIN32_OWN_PROCESS ||
-        serviceType == SERVICE_WIN32_SHARE_PROCESS)
+    /* Select the image for this service */
+    switch (ServiceType)
     {
-        tvi.iImage = 1;
-        tvi.iSelectedImage = 1;
-    }
-    else if (serviceType == SERVICE_KERNEL_DRIVER ||
-             serviceType == SERVICE_FILE_SYSTEM_DRIVER)
-    {
-        tvi.iImage = 2;
-        tvi.iSelectedImage = 2;
+        case SERVICE_WIN32_OWN_PROCESS:
+        case SERVICE_WIN32_SHARE_PROCESS:
+            tvi.iImage = IMAGE_SERVICE;
+            tvi.iSelectedImage = IMAGE_SERVICE;
+            break;
+
+        case SERVICE_KERNEL_DRIVER:
+        case SERVICE_FILE_SYSTEM_DRIVER:
+            tvi.iImage = IMAGE_DRIVER;
+            tvi.iSelectedImage = IMAGE_DRIVER;
+            break;
+
+        default:
+            tvi.iImage = IMAGE_UNKNOWN;
+            tvi.iSelectedImage = IMAGE_UNKNOWN;
+            break;
     }
-    else
+
+    if (lpServiceName)
     {
-        tvi.iImage = 0;
-        tvi.iSelectedImage = 0;
+        dwSize = _tcslen(lpServiceName) + 1;
+        /* Attach the service name */
+        lpName = (LPTSTR)HeapAlloc(GetProcessHeap(),
+                                   0,
+                                   dwSize * sizeof(TCHAR));
+        if (lpName)
+        {
+            _tcscpy_s(lpName, dwSize, lpServiceName);
+            tvi.lParam = (LPARAM)lpName;
+        }
     }
 
     tvins.item = tvi;
-    tvins.hParent = hRoot;
+    tvins.hParent = hParent;
 
     return TreeView_InsertItem(hTreeView, &tvins);
 }
 
-#if 0
-static VOID
-AddServiceDependency(PSERVICEPROPSHEET dlgInfo,
-                     HWND hTreeView,
-                     SC_HANDLE hSCManager,
-                     LPTSTR lpServiceName,
-                     HTREEITEM hParent,
-                     HWND hwndDlg)
+static LPARAM
+TreeView_GetItemParam(HWND hTreeView,
+                      HTREEITEM hItem)
 {
-    LPQUERY_SERVICE_CONFIG lpServiceConfig;
-    SC_HANDLE hService;
-    HTREEITEM hChild;
-    LPTSTR lpStr;
-    LPTSTR lpNoDepends;
-
-    hService = OpenService(hSCManager,
-                           lpServiceName,
-                           SERVICE_QUERY_CONFIG);
-    if (hService)
-    {
-
-        lpStr = GetDependentServices(hService);
-        if (lpStr)
-        {
-            while (*lpStr)
-            {
-                hChild = AddItemToTreeView(hTreeView,
-                                           hParent,
-                                           lpServiceConfig->lpDisplayName,
-                                           lpServiceConfig->dwServiceType);
-
-
-                AddServiceDependency(dlgInfo,
-                                     hTreeView,
-                                     hSCManager,
-                                     lpStr,
-                                     hChild,
-                                     hwndDlg);
-
-                while (*lpStr++)
-                    ;
-            }
-        }
-        else
-        {
-            if (TreeView_GetCount(hTreeView) == 0)
-            {
-                if (AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS))
-                {
-                    lpStr = lpNoDepends;
-                }
-
-                AddItemToTreeView(hTreeView,
-                                  hParent,
-                                  lpStr,
-                                  0);
-
-                HeapFree(ProcessHeap,
-                         0,
-                         lpNoDepends);
-
-                EnableWindow(hTreeView, FALSE);
-            }
-        }
-
+    LPARAM lParam = 0;
+    TVITEM tv = {0};
 
-        HeapFree(ProcessHeap,
-                 0,
-                 lpStr);
+    tv.mask = TVIF_PARAM | TVIF_HANDLE;
+    tv.hItem = hItem;
 
-        CloseServiceHandle(hService);
+    if (TreeView_GetItem(hTreeView, &tv))
+    {
+        lParam = tv.lParam;
     }
 
+    return lParam;
 }
-#endif
 
 static VOID
-AddServiceDependent(HWND hTreeView,
-                    HTREEITEM hParent,
-                    SC_HANDLE hSCManager,
-                    LPTSTR lpServiceName,
-                    LPTSTR lpDisplayName,
-                    DWORD dwServiceType)
+DestroyItem(HWND hTreeView,
+            HTREEITEM hItem)
 {
-    LPENUM_SERVICE_STATUS lpServiceStatus;
-    SC_HANDLE hChildService;
-    HTREEITEM hChildNode;
-    DWORD count;
-    INT i;
-
-
-    hChildNode = AddItemToTreeView(hTreeView,
-                                   hParent,
-                                   lpDisplayName,
-                                   dwServiceType);
-
-    hChildService = OpenService(hSCManager,
-                                lpServiceName,
-                                SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
-    if (hChildService)
-    {
-        lpServiceStatus = GetServiceDependents(hChildService, &count);
-        if (lpServiceStatus)
-        {
-            for (i = 0; i < count; i++)
-            {
-                AddServiceDependent(hTreeView,
-                                    hChildNode,
-                                    hSCManager,
-                                    lpServiceStatus[i].lpServiceName,
-                                    lpServiceStatus[i].lpDisplayName,
-                                    lpServiceStatus[i].ServiceStatus.dwServiceType);
-            }
+    HTREEITEM hChildItem;
+    LPTSTR lpServiceName;
 
-            HeapFree(ProcessHeap,
-                     0,
-                     lpServiceStatus);
-        }
+    /* Does this item have any children */
+    hChildItem = TreeView_GetChild(hTreeView, hItem);
+    if (hChildItem)
+    {
+        /* It does, recurse to that one */
+        DestroyItem(hTreeView, hChildItem);
+    }
 
-        CloseServiceHandle(hChildService);
+    /* Get the string and free it */
+    lpServiceName = (LPTSTR)TreeView_GetItemParam(hTreeView, hItem);
+    if (lpServiceName)
+    {
+        HeapFree(GetProcessHeap(),
+                 0,
+                 lpServiceName);
     }
 }
 
 static VOID
-SetServiceDependents(HWND hTreeView,
-                     SC_HANDLE hSCManager,
-                     SC_HANDLE hService)
+DestroyTreeView(HWND hTreeView)
 {
-    LPENUM_SERVICE_STATUS lpServiceStatus;
-    LPTSTR lpNoDepends;
-    DWORD count, i;
+    HTREEITEM hItem;
 
-    lpServiceStatus = GetServiceDependents(hService, &count);
-    if (lpServiceStatus)
+    /* Get the first item in the top level */
+    hItem = TreeView_GetFirstVisible(hTreeView);
+    if (hItem)
     {
-        for (i = 0; i < count; i++)
+        /* Kill it and all children */
+        DestroyItem(hTreeView, hItem);
+
+        /* Kill all remaining top level items */
+        while (hItem)
         {
-            AddServiceDependent(hTreeView,
-                                NULL,
-                                hSCManager,
-                                lpServiceStatus[i].lpServiceName,
-                                lpServiceStatus[i].lpDisplayName,
-                                lpServiceStatus[i].ServiceStatus.dwServiceType);
+            /* Are there any more items at the top level */
+            hItem = TreeView_GetNextSibling(hTreeView, hItem);
+            if (hItem)
+            {
+                /*  Kill it and all children */
+                DestroyItem(hTreeView, hItem);
+            }
         }
     }
-    else
-    {
-            AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
-
-            AddItemToTreeView(hTreeView,
-                              NULL,
-                              lpNoDepends,
-                              0);
-
-            HeapFree(ProcessHeap,
-                     0,
-                     lpNoDepends);
-
-            EnableWindow(hTreeView, FALSE);
-    }
 }
 
-static VOID
-SetDependentServices(SC_HANDLE hService)
+/*
+static BOOL
+TreeView_GetItemText(HWND hTreeView,
+                     HTREEITEM hItem,
+                     LPTSTR lpBuffer,
+                     DWORD cbBuffer)
 {
+    TVITEM tv = {0};
+
+    tv.mask = TVIF_TEXT | TVIF_HANDLE;
+    tv.hItem = hItem;
+    tv.pszText = lpBuffer;
+    tv.cchTextMax = (int)cbBuffer;
+
+    return TreeView_GetItem(hTreeView, &tv);
 }
+*/
 
 static VOID
-InitDependPage(PSERVICEPROPSHEET dlgInfo,
-               HWND hwndDlg)
+InitDependPage(PSERVICEPROPSHEET pDlgInfo)
 {
-    HWND hTreeView1, hTreeView2;
-    SC_HANDLE hSCManager;
-    SC_HANDLE hService;
-
-    dlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS,
-                                               IDI_DRIVER,
-                                               GetSystemMetrics(SM_CXSMICON),
-                                               GetSystemMetrics(SM_CXSMICON),
-                                               IMAGE_ICON);
-
-
-    hTreeView1 = GetDlgItem(hwndDlg, IDC_DEPEND_TREE1);
-    if (!hTreeView1)
-        return;
-
-    (void)TreeView_SetImageList(hTreeView1,
-                                dlgInfo->hDependsImageList,
-                                TVSIL_NORMAL);
-
-    hTreeView2 = GetDlgItem(hwndDlg, IDC_DEPEND_TREE2);
-    if (!hTreeView2)
-        return;
-
-    (void)TreeView_SetImageList(hTreeView2,
-                                dlgInfo->hDependsImageList,
-                                TVSIL_NORMAL);
-
-    hSCManager = OpenSCManager(NULL,
-                               NULL,
-                               SC_MANAGER_ALL_ACCESS);
-    if (hSCManager)
-    {
-        hService = OpenService(hSCManager,
-                               dlgInfo->pService->lpServiceName,
-                               SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
-        if (hService)
-        {
-            /* Set the first tree view */
-            SetServiceDependents(hTreeView1,
-                                 hSCManager,
-                                 hService);
-
-            /* Set the second tree view */
-            SetDependentServices(hService);
-
-            CloseServiceHandle(hService);
-        }
-
-        CloseServiceHandle(hSCManager);
-    }
-
+    /* Initialize the image list */
+    pDlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS,
+                                                IDI_DRIVER,
+                                                GetSystemMetrics(SM_CXSMICON),
+                                                GetSystemMetrics(SM_CXSMICON),
+                                                IMAGE_ICON);
+
+    /* Set the first tree view */
+    TV1_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
+
+    /* Set the second tree view */
+    TV2_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
 }
 
 
-
 /*
  * Dependancies Property dialog callback.
  * Controls messages to the Dependancies dialog
@@ -286,12 +187,12 @@ DependenciesPageProc(HWND hwndDlg,
                      WPARAM wParam,
                      LPARAM lParam)
 {
-    PSERVICEPROPSHEET dlgInfo;
+    PSERVICEPROPSHEET pDlgInfo;
 
     /* Get the window context */
-    dlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg,
-                                                  GWLP_USERDATA);
-    if (dlgInfo == NULL && uMsg != WM_INITDIALOG)
+    pDlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg,
+                                                   GWLP_USERDATA);
+    if (pDlgInfo == NULL && uMsg != WM_INITDIALOG)
     {
         return FALSE;
     }
@@ -300,24 +201,68 @@ DependenciesPageProc(HWND hwndDlg,
     {
         case WM_INITDIALOG:
         {
-            dlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
-            if (dlgInfo != NULL)
+            pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
+            if (pDlgInfo != NULL)
             {
                 SetWindowLongPtr(hwndDlg,
                                  GWLP_USERDATA,
-                                 (LONG_PTR)dlgInfo);
+                                 (LONG_PTR)pDlgInfo);
+
+                pDlgInfo->hDependsWnd = hwndDlg;
 
-                InitDependPage(dlgInfo, hwndDlg);
+                InitDependPage(pDlgInfo);
             }
         }
         break;
 
+        case WM_NOTIFY:
+        {
+            switch (((LPNMHDR)lParam)->code)
+            {
+                case TVN_ITEMEXPANDING:
+                {
+                    LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam;
+
+                    if (lpnmtv->action == TVE_EXPAND)
+                    {
+                        if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE1)
+                        {
+                            /* Has this node been expanded before */
+                            if (!TreeView_GetChild(pDlgInfo->hDependsTreeView1, lpnmtv->itemNew.hItem))
+                            {
+                                /* It's not, add the children */
+                                TV1_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPTSTR)lpnmtv->itemNew.lParam);
+                            }
+                        }
+                        else if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE2)
+                        {
+                            /* Has this node been expanded before */
+                            if (!TreeView_GetChild(pDlgInfo->hDependsTreeView2, lpnmtv->itemNew.hItem))
+                            {
+                                /* It's not, add the children */
+                                TV2_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPTSTR)lpnmtv->itemNew.lParam);
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+            break;
+        }
+
         case WM_COMMAND:
             switch(LOWORD(wParam))
             {
 
             }
             break;
+
+        case WM_DESTROY:
+            DestroyTreeView(pDlgInfo->hDependsTreeView1);
+            DestroyTreeView(pDlgInfo->hDependsTreeView2);
+
+            if (pDlgInfo->hDependsImageList)
+                ImageList_Destroy(pDlgInfo->hDependsImageList);
     }
 
     return FALSE;