go my file uploader
This commit is contained in:
344
plugins/ExtendedServices/depend.c
Normal file
344
plugins/ExtendedServices/depend.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Process Hacker Extended Services -
|
||||
* dependencies and dependents
|
||||
*
|
||||
* Copyright (C) 2010 wj32
|
||||
*
|
||||
* This file is part of Process Hacker.
|
||||
*
|
||||
* Process Hacker is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Process Hacker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "extsrv.h"
|
||||
|
||||
typedef struct _SERVICE_LIST_CONTEXT
|
||||
{
|
||||
HWND ServiceListHandle;
|
||||
PH_LAYOUT_MANAGER LayoutManager;
|
||||
} SERVICE_LIST_CONTEXT, *PSERVICE_LIST_CONTEXT;
|
||||
|
||||
LPENUM_SERVICE_STATUS EsEnumDependentServices(
|
||||
_In_ SC_HANDLE ServiceHandle,
|
||||
_In_opt_ ULONG State,
|
||||
_Out_ PULONG Count
|
||||
)
|
||||
{
|
||||
LOGICAL result;
|
||||
PVOID buffer;
|
||||
ULONG bufferSize;
|
||||
ULONG returnLength;
|
||||
ULONG servicesReturned;
|
||||
|
||||
if (!State)
|
||||
State = SERVICE_STATE_ALL;
|
||||
|
||||
bufferSize = 0x800;
|
||||
buffer = PhAllocate(bufferSize);
|
||||
|
||||
if (!(result = EnumDependentServices(
|
||||
ServiceHandle,
|
||||
State,
|
||||
buffer,
|
||||
bufferSize,
|
||||
&returnLength,
|
||||
&servicesReturned
|
||||
)))
|
||||
{
|
||||
if (GetLastError() == ERROR_MORE_DATA)
|
||||
{
|
||||
PhFree(buffer);
|
||||
bufferSize = returnLength;
|
||||
buffer = PhAllocate(bufferSize);
|
||||
|
||||
result = EnumDependentServices(
|
||||
ServiceHandle,
|
||||
State,
|
||||
buffer,
|
||||
bufferSize,
|
||||
&returnLength,
|
||||
&servicesReturned
|
||||
);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
PhFree(buffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*Count = servicesReturned;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VOID EspLayoutServiceListControl(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ HWND ServiceListHandle
|
||||
)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
GetWindowRect(GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), &rect);
|
||||
MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2);
|
||||
|
||||
MoveWindow(
|
||||
ServiceListHandle,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK EspServiceDependenciesDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PSERVICE_LIST_CONTEXT context;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = PhAllocate(sizeof(SERVICE_LIST_CONTEXT));
|
||||
memset(context, 0, sizeof(SERVICE_LIST_CONTEXT));
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PSERVICE_LIST_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
|
||||
PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam;
|
||||
HWND serviceListHandle;
|
||||
PPH_LIST serviceList;
|
||||
SC_HANDLE serviceHandle;
|
||||
ULONG win32Result = 0;
|
||||
BOOLEAN success = FALSE;
|
||||
PPH_SERVICE_ITEM *services;
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_MESSAGE, L"This service depends on the following services:");
|
||||
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
|
||||
if (serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_QUERY_CONFIG))
|
||||
{
|
||||
LPQUERY_SERVICE_CONFIG serviceConfig;
|
||||
|
||||
if (serviceConfig = PhGetServiceConfig(serviceHandle))
|
||||
{
|
||||
PWSTR dependency;
|
||||
PPH_SERVICE_ITEM dependencyService;
|
||||
|
||||
dependency = serviceConfig->lpDependencies;
|
||||
serviceList = PH_AUTO(PhCreateList(8));
|
||||
success = TRUE;
|
||||
|
||||
if (dependency)
|
||||
{
|
||||
ULONG dependencyLength;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
dependencyLength = (ULONG)PhCountStringZ(dependency);
|
||||
|
||||
if (dependencyLength == 0)
|
||||
break;
|
||||
|
||||
if (dependency[0] == SC_GROUP_IDENTIFIER)
|
||||
goto ContinueLoop;
|
||||
|
||||
if (dependencyService = PhReferenceServiceItem(dependency))
|
||||
PhAddItemList(serviceList, dependencyService);
|
||||
|
||||
ContinueLoop:
|
||||
dependency += dependencyLength + 1;
|
||||
}
|
||||
}
|
||||
|
||||
services = PhAllocateCopy(serviceList->Items, sizeof(PPH_SERVICE_ITEM) * serviceList->Count);
|
||||
|
||||
serviceListHandle = PhCreateServiceListControl(hwndDlg, services, serviceList->Count);
|
||||
context->ServiceListHandle = serviceListHandle;
|
||||
EspLayoutServiceListControl(hwndDlg, serviceListHandle);
|
||||
ShowWindow(serviceListHandle, SW_SHOW);
|
||||
|
||||
PhFree(serviceConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
win32Result = GetLastError();
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
win32Result = GetLastError();
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
SetDlgItemText(hwndDlg, IDC_SERVICES_LAYOUT, PhaConcatStrings2(L"Unable to enumerate dependencies: ",
|
||||
((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer)->Buffer);
|
||||
ShowWindow(GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), SW_SHOW);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
PhFree(context);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
|
||||
if (context->ServiceListHandle)
|
||||
EspLayoutServiceListControl(hwndDlg, context->ServiceListHandle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK EspServiceDependentsDlgProc(
|
||||
_In_ HWND hwndDlg,
|
||||
_In_ UINT uMsg,
|
||||
_In_ WPARAM wParam,
|
||||
_In_ LPARAM lParam
|
||||
)
|
||||
{
|
||||
PSERVICE_LIST_CONTEXT context;
|
||||
|
||||
if (uMsg == WM_INITDIALOG)
|
||||
{
|
||||
context = PhAllocate(sizeof(SERVICE_LIST_CONTEXT));
|
||||
memset(context, 0, sizeof(SERVICE_LIST_CONTEXT));
|
||||
|
||||
SetProp(hwndDlg, L"Context", (HANDLE)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context = (PSERVICE_LIST_CONTEXT)GetProp(hwndDlg, L"Context");
|
||||
|
||||
if (uMsg == WM_DESTROY)
|
||||
RemoveProp(hwndDlg, L"Context");
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
|
||||
PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam;
|
||||
HWND serviceListHandle;
|
||||
PPH_LIST serviceList;
|
||||
SC_HANDLE serviceHandle;
|
||||
ULONG win32Result = 0;
|
||||
BOOLEAN success = FALSE;
|
||||
PPH_SERVICE_ITEM *services;
|
||||
|
||||
SetDlgItemText(hwndDlg, IDC_MESSAGE, L"The following services depend on this service:");
|
||||
|
||||
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), NULL, PH_ANCHOR_ALL);
|
||||
|
||||
if (serviceHandle = PhOpenService(serviceItem->Name->Buffer, SERVICE_ENUMERATE_DEPENDENTS))
|
||||
{
|
||||
LPENUM_SERVICE_STATUS dependentServices;
|
||||
ULONG numberOfDependentServices;
|
||||
|
||||
if (dependentServices = EsEnumDependentServices(serviceHandle, 0, &numberOfDependentServices))
|
||||
{
|
||||
ULONG i;
|
||||
PPH_SERVICE_ITEM dependentService;
|
||||
|
||||
serviceList = PH_AUTO(PhCreateList(8));
|
||||
success = TRUE;
|
||||
|
||||
for (i = 0; i < numberOfDependentServices; i++)
|
||||
{
|
||||
if (dependentService = PhReferenceServiceItem(dependentServices[i].lpServiceName))
|
||||
PhAddItemList(serviceList, dependentService);
|
||||
}
|
||||
|
||||
services = PhAllocateCopy(serviceList->Items, sizeof(PPH_SERVICE_ITEM) * serviceList->Count);
|
||||
|
||||
serviceListHandle = PhCreateServiceListControl(hwndDlg, services, serviceList->Count);
|
||||
context->ServiceListHandle = serviceListHandle;
|
||||
EspLayoutServiceListControl(hwndDlg, serviceListHandle);
|
||||
ShowWindow(serviceListHandle, SW_SHOW);
|
||||
|
||||
PhFree(dependentServices);
|
||||
}
|
||||
else
|
||||
{
|
||||
win32Result = GetLastError();
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
win32Result = GetLastError();
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
SetDlgItemText(hwndDlg, IDC_SERVICES_LAYOUT, PhaConcatStrings2(L"Unable to enumerate dependents: ",
|
||||
((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer)->Buffer);
|
||||
ShowWindow(GetDlgItem(hwndDlg, IDC_SERVICES_LAYOUT), SW_SHOW);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PhDeleteLayoutManager(&context->LayoutManager);
|
||||
PhFree(context);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
PhLayoutManagerLayout(&context->LayoutManager);
|
||||
|
||||
if (context->ServiceListHandle)
|
||||
EspLayoutServiceListControl(hwndDlg, context->ServiceListHandle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
Reference in New Issue
Block a user