1 /* 2 * PROJECT: ReactOS Services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/applications/mscutils/servman/dependencies_tv2.c 5 * PURPOSE: Helper functions for service dependents 6 * COPYRIGHT: Copyright 2009 Ged Murphy <gedmurphy@reactos.org> 7 * 8 */ 9 10 #include "precomp.h" 11 12 BOOL 13 TV2_HasDependantServices(LPWSTR lpServiceName) 14 { 15 HANDLE hSCManager; 16 HANDLE hService; 17 DWORD dwBytesNeeded, dwCount; 18 BOOL bRet = FALSE; 19 20 hSCManager = OpenSCManagerW(NULL, 21 NULL, 22 SC_MANAGER_ALL_ACCESS); 23 if (hSCManager) 24 { 25 hService = OpenServiceW(hSCManager, 26 lpServiceName, 27 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); 28 if (hService) 29 { 30 /* Does this have any dependencies? */ 31 if (!EnumDependentServices(hService, 32 SERVICE_STATE_ALL, 33 NULL, 34 0, 35 &dwBytesNeeded, 36 &dwCount)) 37 { 38 if (GetLastError() == ERROR_MORE_DATA) 39 { 40 /* It does, return TRUE */ 41 bRet = TRUE; 42 } 43 } 44 45 CloseServiceHandle(hService); 46 } 47 48 CloseServiceHandle(hSCManager); 49 } 50 51 return bRet; 52 } 53 54 LPENUM_SERVICE_STATUS 55 TV2_GetDependants(LPWSTR lpServiceName, 56 LPDWORD lpdwCount) 57 { 58 SC_HANDLE hSCManager; 59 SC_HANDLE hService; 60 LPENUM_SERVICE_STATUSW lpDependencies = NULL; 61 DWORD dwBytesNeeded; 62 DWORD dwCount; 63 64 /* Set the first items in each tree view */ 65 hSCManager = OpenSCManagerW(NULL, 66 NULL, 67 SC_MANAGER_ALL_ACCESS); 68 if (hSCManager) 69 { 70 hService = OpenServiceW(hSCManager, 71 lpServiceName, 72 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG); 73 if (hService) 74 { 75 /* Does this have any dependencies? */ 76 if (!EnumDependentServicesW(hService, 77 SERVICE_STATE_ALL, 78 NULL, 79 0, 80 &dwBytesNeeded, 81 &dwCount) && 82 GetLastError() == ERROR_MORE_DATA) 83 { 84 lpDependencies = (LPENUM_SERVICE_STATUSW)HeapAlloc(GetProcessHeap(), 85 0, 86 dwBytesNeeded); 87 if (lpDependencies) 88 { 89 /* Get the list of dependents */ 90 if (EnumDependentServicesW(hService, 91 SERVICE_STATE_ALL, 92 lpDependencies, 93 dwBytesNeeded, 94 &dwBytesNeeded, 95 &dwCount)) 96 { 97 /* Set the count */ 98 *lpdwCount = dwCount; 99 } 100 else 101 { 102 HeapFree(ProcessHeap, 103 0, 104 lpDependencies); 105 106 lpDependencies = NULL; 107 } 108 } 109 } 110 111 CloseServiceHandle(hService); 112 } 113 114 CloseServiceHandle(hSCManager); 115 } 116 117 return lpDependencies; 118 } 119 120 VOID 121 TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, 122 HTREEITEM hParent, 123 LPWSTR lpServiceName) 124 { 125 126 LPENUM_SERVICE_STATUSW lpServiceStatus; 127 LPWSTR lpNoDepends; 128 DWORD count, i; 129 BOOL bHasChildren; 130 131 /* Get a list of service dependents */ 132 lpServiceStatus = TV2_GetDependants(lpServiceName, &count); 133 if (lpServiceStatus) 134 { 135 for (i = 0; i < count; i++) 136 { 137 /* Does this item need a +/- box? */ 138 bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName); 139 140 /* Add it */ 141 AddItemToTreeView(pDlgInfo->hDependsTreeView2, 142 hParent, 143 lpServiceStatus[i].lpDisplayName, 144 lpServiceStatus[i].lpServiceName, 145 lpServiceStatus[i].ServiceStatus.dwServiceType, 146 bHasChildren); 147 } 148 149 HeapFree(GetProcessHeap(), 150 0, 151 lpServiceStatus); 152 } 153 else 154 { 155 /* If there is no parent, set the tree to 'no dependencies' */ 156 if (!hParent) 157 { 158 /* Load the 'No dependencies' string */ 159 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS); 160 161 AddItemToTreeView(pDlgInfo->hDependsTreeView2, 162 NULL, 163 lpNoDepends, 164 NULL, 165 0, 166 FALSE); 167 168 LocalFree(lpNoDepends); 169 170 /* Disable the window */ 171 EnableWindow(pDlgInfo->hDependsTreeView2, FALSE); 172 } 173 } 174 } 175 176 BOOL 177 TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, 178 LPWSTR lpServiceName) 179 { 180 BOOL bRet = FALSE; 181 182 /* Associate the imagelist with TV2 */ 183 pDlgInfo->hDependsTreeView2 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE2); 184 if (!pDlgInfo->hDependsTreeView2) 185 { 186 ImageList_Destroy(pDlgInfo->hDependsImageList); 187 pDlgInfo->hDependsImageList = NULL; 188 return FALSE; 189 } 190 (void)TreeView_SetImageList(pDlgInfo->hDependsTreeView2, 191 pDlgInfo->hDependsImageList, 192 TVSIL_NORMAL); 193 194 /* Set the first items in the control */ 195 TV2_AddDependantsToTree(pDlgInfo, NULL, lpServiceName); 196 197 return bRet; 198 } 199