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 
189     PDEPENDDATA pDependData;
190 
191     /* Get the window context */
192     pDependData = (PDEPENDDATA)GetWindowLongPtr(hwndDlg,
193                                                 GWLP_USERDATA);
194     if (pDependData == NULL && uMsg != WM_INITDIALOG)
195     {
196         return FALSE;
197     }
198 
199     switch (uMsg)
200     {
201         case WM_INITDIALOG:
202         {
203             pDependData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEPENDDATA));
204             if (pDependData != NULL)
205             {
206                 SetWindowLongPtr(hwndDlg,
207                                  GWLP_USERDATA,
208                                  (LONG_PTR)pDependData);
209 
210                 pDependData->pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
211                 pDependData->hDependsWnd = hwndDlg;
212 
213                 InitDependPage(pDependData);
214             }
215         }
216         break;
217 
218         case WM_NOTIFY:
219         {
220             switch (((LPNMHDR)lParam)->code)
221             {
222                 case TVN_ITEMEXPANDING:
223                 {
224                     LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam;
225 
226                     if (lpnmtv->action == TVE_EXPAND)
227                     {
228                         if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE1)
229                         {
230                             /* Has this node been expanded before */
231                             if (!TreeView_GetChild(pDependData->hDependsTreeView1, lpnmtv->itemNew.hItem))
232                             {
233                                 /* It's not, add the children */
234                                 TV1_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
235                             }
236                         }
237                         else if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE2)
238                         {
239                             /* Has this node been expanded before */
240                             if (!TreeView_GetChild(pDependData->hDependsTreeView2, lpnmtv->itemNew.hItem))
241                             {
242                                 /* It's not, add the children */
243                                 TV2_AddDependantsToTree(pDependData, lpnmtv->itemNew.hItem, (LPWSTR)lpnmtv->itemNew.lParam);
244                             }
245                         }
246                     }
247                     break;
248                 }
249             }
250             break;
251         }
252 
253         case WM_COMMAND:
254             switch(LOWORD(wParam))
255             {
256 
257             }
258             break;
259 
260         case WM_DESTROY:
261             DestroyTreeView(pDependData->hDependsTreeView1);
262             DestroyTreeView(pDependData->hDependsTreeView2);
263 
264             if (pDependData->hDependsImageList)
265                 ImageList_Destroy(pDependData->hDependsImageList);
266 
267             HeapFree(GetProcessHeap(), 0, pDependData);
268     }
269 
270     return FALSE;
271 }
272