1 /*
2  * PROJECT:     ReactOS Services
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        base/applications/mscutils/servman/propsheet_depends.c
5  * PURPOSE:     Property dialog box message handler
6  * COPYRIGHT:   Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include "precomp.h"
11 
12 HTREEITEM
13 AddItemToTreeView(HWND hTreeView,
14                   HTREEITEM hParent,
15                   LPWSTR lpDisplayName,
16                   LPWSTR lpServiceName,
17                   ULONG ServiceType,
18                   BOOL bHasChildren)
19 {
20     TV_ITEM tvi;
21     TV_INSERTSTRUCT tvins;
22     LPWSTR lpName;
23     DWORD dwSize;
24 
25     ZeroMemory(&tvi, sizeof(tvi));
26     ZeroMemory(&tvins, sizeof(tvins));
27 
28     tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_CHILDREN;
29     tvi.pszText = lpDisplayName;
30     tvi.cchTextMax = wcslen(lpDisplayName);
31     tvi.cChildren = bHasChildren;
32 
33     /* Select the image for this service */
34     switch (ServiceType)
35     {
36         case SERVICE_WIN32_OWN_PROCESS:
37         case SERVICE_WIN32_SHARE_PROCESS:
38             tvi.iImage = IMAGE_SERVICE;
39             tvi.iSelectedImage = IMAGE_SERVICE;
40             break;
41 
42         case SERVICE_KERNEL_DRIVER:
43         case SERVICE_FILE_SYSTEM_DRIVER:
44             tvi.iImage = IMAGE_DRIVER;
45             tvi.iSelectedImage = IMAGE_DRIVER;
46             break;
47 
48         default:
49             tvi.iImage = IMAGE_UNKNOWN;
50             tvi.iSelectedImage = IMAGE_UNKNOWN;
51             break;
52     }
53 
54     if (lpServiceName)
55     {
56         dwSize = wcslen(lpServiceName) + 1;
57         /* Attach the service name */
58         lpName = (LPWSTR)HeapAlloc(GetProcessHeap(),
59                                    0,
60                                    dwSize * sizeof(WCHAR));
61         if (lpName)
62         {
63             StringCchCopyW(lpName, dwSize, lpServiceName);
64             tvi.lParam = (LPARAM)lpName;
65         }
66     }
67 
68     tvins.item = tvi;
69     tvins.hParent = hParent;
70 
71     return TreeView_InsertItem(hTreeView, &tvins);
72 }
73 
74 static LPARAM
75 TreeView_GetItemParam(HWND hTreeView,
76                       HTREEITEM hItem)
77 {
78     LPARAM lParam = 0;
79     TVITEMW tv = {0};
80 
81     tv.mask = TVIF_PARAM | TVIF_HANDLE;
82     tv.hItem = hItem;
83 
84     if (TreeView_GetItem(hTreeView, &tv))
85     {
86         lParam = tv.lParam;
87     }
88 
89     return lParam;
90 }
91 
92 static VOID
93 DestroyItem(HWND hTreeView,
94             HTREEITEM hItem)
95 {
96     HTREEITEM hChildItem;
97     LPWSTR lpServiceName;
98 
99     /* Does this item have any children */
100     hChildItem = TreeView_GetChild(hTreeView, hItem);
101     if (hChildItem)
102     {
103         /* It does, recurse to that one */
104         DestroyItem(hTreeView, hChildItem);
105     }
106 
107     /* Get the string and free it */
108     lpServiceName = (LPWSTR)TreeView_GetItemParam(hTreeView, hItem);
109     if (lpServiceName)
110     {
111         HeapFree(GetProcessHeap(),
112                  0,
113                  lpServiceName);
114     }
115 }
116 
117 static VOID
118 DestroyTreeView(HWND hTreeView)
119 {
120     HTREEITEM hItem;
121 
122     /* Get the first item in the top level */
123     hItem = TreeView_GetFirstVisible(hTreeView);
124     if (hItem)
125     {
126         /* Kill it and all children */
127         DestroyItem(hTreeView, hItem);
128 
129         /* Kill all remaining top level items */
130         while (hItem)
131         {
132             /* Are there any more items at the top level */
133             hItem = TreeView_GetNextSibling(hTreeView, hItem);
134             if (hItem)
135             {
136                 /*  Kill it and all children */
137                 DestroyItem(hTreeView, hItem);
138             }
139         }
140     }
141 }
142 
143 /*
144 static BOOL
145 TreeView_GetItemText(HWND hTreeView,
146                      HTREEITEM hItem,
147                      LPTSTR lpBuffer,
148                      DWORD cbBuffer)
149 {
150     TVITEM tv = {0};
151 
152     tv.mask = TVIF_TEXT | TVIF_HANDLE;
153     tv.hItem = hItem;
154     tv.pszText = lpBuffer;
155     tv.cchTextMax = (int)cbBuffer;
156 
157     return TreeView_GetItem(hTreeView, &tv);
158 }
159 */
160 
161 static VOID
162 InitDependPage(PDEPENDDATA pDependData)
163 {
164     /* Initialize the image list */
165     pDependData->hDependsImageList = InitImageList(IDI_NODEPENDS,
166                                                    IDI_DRIVER,
167                                                    GetSystemMetrics(SM_CXSMICON),
168                                                    GetSystemMetrics(SM_CXSMICON),
169                                                    IMAGE_ICON);
170 
171     /* Set the first tree view */
172     TV1_Initialize(pDependData, pDependData->pDlgInfo->pService->lpServiceName);
173 
174     /* Set the second tree view */
175     TV2_Initialize(pDependData, pDependData->pDlgInfo->pService->lpServiceName);
176 }
177 
178 /*
179  * Dependancies Property dialog callback.
180  * Controls messages to the Dependancies dialog
181  */
182 INT_PTR CALLBACK
183 DependenciesPageProc(HWND hwndDlg,
184                      UINT uMsg,
185                      WPARAM wParam,
186                      LPARAM lParam)
187 {
188     PDEPENDDATA pDependData;
189 
190     /* Get the window context */
191     pDependData = (PDEPENDDATA)GetWindowLongPtr(hwndDlg,
192                                                 GWLP_USERDATA);
193     if (pDependData == NULL && uMsg != WM_INITDIALOG)
194     {
195         return FALSE;
196     }
197 
198     switch (uMsg)
199     {
200         case WM_INITDIALOG:
201         {
202             pDependData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEPENDDATA));
203             if (pDependData != NULL)
204             {
205                 SetWindowLongPtr(hwndDlg,
206                                  GWLP_USERDATA,
207                                  (LONG_PTR)pDependData);
208 
209                 pDependData->pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
210                 pDependData->hDependsWnd = hwndDlg;
211 
212                 InitDependPage(pDependData);
213             }
214         }
215         break;
216 
217         case WM_NOTIFY:
218         {
219             switch (((LPNMHDR)lParam)->code)
220             {
221                 case TVN_ITEMEXPANDING:
222                 {
223                     LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam;
224 
225                     if (lpnmtv->action == TVE_EXPAND)
226                     {
227                         if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE1)
228                         {
229                             /* Has this node been expanded before */
230                             if (!TreeView_GetChild(pDependData->hDependsTreeView1, lpnmtv->itemNew.hItem))
231                             {
232                                 /* It's not, add the children */
233                                 TV1_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
234                             }
235                         }
236                         else if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE2)
237                         {
238                             /* Has this node been expanded before */
239                             if (!TreeView_GetChild(pDependData->hDependsTreeView2, lpnmtv->itemNew.hItem))
240                             {
241                                 /* It's not, add the children */
242                                 TV2_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
243                             }
244                         }
245                     }
246                     break;
247                 }
248             }
249             break;
250         }
251 
252         case WM_COMMAND:
253             switch(LOWORD(wParam))
254             {
255 
256             }
257             break;
258 
259         case WM_DESTROY:
260             DestroyTreeView(pDependData->hDependsTreeView1);
261             DestroyTreeView(pDependData->hDependsTreeView2);
262 
263             if (pDependData->hDependsImageList)
264                 ImageList_Destroy(pDependData->hDependsImageList);
265 
266             HeapFree(GetProcessHeap(), 0, pDependData);
267     }
268 
269     return FALSE;
270 }
271