1 /* 2 * PROJECT: ReactOS Services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/applications/mscutils/servman/dependencies_tv1.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 LPWSTR 13 TV1_GetDependants(SC_HANDLE hService) 14 { 15 LPQUERY_SERVICE_CONFIG lpServiceConfig; 16 LPWSTR lpStr = NULL; 17 DWORD bytesNeeded; 18 DWORD bytes; 19 20 /* Get the info for this service */ 21 if (!QueryServiceConfigW(hService, 22 NULL, 23 0, 24 &bytesNeeded) && 25 GetLastError() == ERROR_INSUFFICIENT_BUFFER) 26 { 27 lpServiceConfig = HeapAlloc(ProcessHeap, 28 0, 29 bytesNeeded); 30 if (lpServiceConfig) 31 { 32 if (QueryServiceConfigW(hService, 33 lpServiceConfig, 34 bytesNeeded, 35 &bytesNeeded)) 36 { 37 /* Does this service have any dependencies? */ 38 if (lpServiceConfig->lpDependencies && 39 *lpServiceConfig->lpDependencies != '\0') 40 { 41 lpStr = lpServiceConfig->lpDependencies; 42 bytes = 0; 43 44 /* Work out how many bytes we need to hold the list */ 45 for (;;) 46 { 47 bytes++; 48 49 if (!*lpStr && !*(lpStr + 1)) 50 { 51 bytes++; 52 break; 53 } 54 55 lpStr++; 56 } 57 58 /* Allocate and copy the list */ 59 bytes *= sizeof(WCHAR); 60 lpStr = HeapAlloc(ProcessHeap, 61 0, 62 bytes); 63 if (lpStr) 64 { 65 CopyMemory(lpStr, 66 lpServiceConfig->lpDependencies, 67 bytes); 68 } 69 } 70 } 71 72 HeapFree(GetProcessHeap(), 73 0, 74 lpServiceConfig); 75 } 76 } 77 78 return lpStr; 79 } 80 81 VOID 82 TV1_AddDependantsToTree(PDEPENDDATA pDependData, 83 HTREEITEM hParent, 84 LPWSTR lpServiceName) 85 { 86 SC_HANDLE hSCManager; 87 SC_HANDLE hService; 88 LPQUERY_SERVICE_CONFIG lpServiceConfig; 89 LPWSTR lpDependants; 90 LPWSTR lpStr; 91 LPWSTR lpNoDepends; 92 BOOL bHasChildren; 93 94 hSCManager = OpenSCManagerW(NULL, 95 NULL, 96 SC_MANAGER_ALL_ACCESS); 97 if (hSCManager) 98 { 99 hService = OpenServiceW(hSCManager, 100 lpServiceName, 101 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG); 102 if (hService) 103 { 104 /* Get a list of service dependents */ 105 lpDependants = TV1_GetDependants(hService); 106 if (lpDependants) 107 { 108 lpStr = lpDependants; 109 110 /* Make sure this isn't the end of the list */ 111 while (*lpStr) 112 { 113 /* Get the info for this service */ 114 lpServiceConfig = GetServiceConfig(lpStr); 115 if (lpServiceConfig) 116 { 117 /* Does this item need a +/- box? */ 118 if (lpServiceConfig->lpDependencies && 119 *lpServiceConfig->lpDependencies != '\0') 120 { 121 bHasChildren = TRUE; 122 } 123 else 124 { 125 bHasChildren = FALSE; 126 } 127 128 /* Add it */ 129 AddItemToTreeView(pDependData->hDependsTreeView1, 130 hParent, 131 lpServiceConfig->lpDisplayName, 132 lpStr, 133 lpServiceConfig->dwServiceType, 134 bHasChildren); 135 136 HeapFree(GetProcessHeap(), 137 0, 138 lpServiceConfig); 139 } 140 141 /* Move to the end of the string */ 142 while (*lpStr++) 143 ; 144 } 145 146 HeapFree(GetProcessHeap(), 147 0, 148 lpDependants); 149 } 150 else 151 { 152 /* If there is no parent, set the tree to 'no dependencies' */ 153 if (!hParent) 154 { 155 /* Load the 'No dependencies' string */ 156 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS); 157 158 AddItemToTreeView(pDependData->hDependsTreeView1, 159 NULL, 160 lpNoDepends, 161 NULL, 162 0, 163 FALSE); 164 165 LocalFree(lpNoDepends); 166 167 /* Disable the window */ 168 EnableWindow(pDependData->hDependsTreeView1, FALSE); 169 } 170 } 171 172 CloseServiceHandle(hService); 173 } 174 175 CloseServiceHandle(hSCManager); 176 } 177 } 178 179 BOOL 180 TV1_Initialize(PDEPENDDATA pDependData, 181 LPWSTR lpServiceName) 182 { 183 BOOL bRet = FALSE; 184 185 /* Associate the imagelist with TV1 */ 186 pDependData->hDependsTreeView1 = GetDlgItem(pDependData->hDependsWnd, IDC_DEPEND_TREE1); 187 if (!pDependData->hDependsTreeView1) 188 { 189 ImageList_Destroy(pDependData->hDependsImageList); 190 pDependData->hDependsImageList = NULL; 191 return FALSE; 192 } 193 (void)TreeView_SetImageList(pDependData->hDependsTreeView1, 194 pDependData->hDependsImageList, 195 TVSIL_NORMAL); 196 197 /* Set the first items in the control */ 198 TV1_AddDependantsToTree(pDependData, NULL, lpServiceName); 199 200 return bRet; 201 } 202