ExtendedServices: added support for editing triggers

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@4229 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2011-06-12 10:29:58 +00:00
parent 60143069e4
commit 3ed6df0eff
9 changed files with 1809 additions and 181 deletions
+1
View File
@@ -2,6 +2,7 @@ Process Hacker
2.17
* NEW/IMPROVED:
* Updated ExtendedServices plugin
* Updated WindowExplorer plugin
* FIXED:
@@ -1,3 +1,6 @@
1.5
* Added support for editing triggers
1.4
* Improved Services submenu when there is only one service
@@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,0,0
PRODUCTVERSION 1,4,0,0
FILEVERSION 1,5,0,0
PRODUCTVERSION 1,5,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "wj32"
VALUE "FileDescription", "Extended Services for Process Hacker"
VALUE "FileVersion", "1.4"
VALUE "FileVersion", "1.5"
VALUE "InternalName", "ExtendedServices"
VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
VALUE "OriginalFilename", "ExtendedServices.dll"
VALUE "ProductName", "Extended Services for Process Hacker"
VALUE "ProductVersion", "1.4"
VALUE "ProductVersion", "1.5"
END
END
BLOCK "VarFileInfo"
@@ -159,7 +159,7 @@ BEGIN
CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,21,190,14
END
IDD_SRVOTHER DIALOGEX 0, 0, 282, 183
IDD_SRVOTHER DIALOGEX 0, 0, 282, 204
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Other"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -170,7 +170,10 @@ BEGIN
LTEXT "Required privileges:",IDC_STATIC,7,21,64,8
CONTROL "",IDC_PRIVILEGES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,268,59
LTEXT "Triggers:",IDC_TRIGGERS_LABEL,7,95,30,8
CONTROL "",IDC_TRIGGERS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,106,268,70
CONTROL "",IDC_TRIGGERS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,106,268,73
PUSHBUTTON "New...",IDC_NEW,117,183,50,14
PUSHBUTTON "Edit...",IDC_EDIT,171,183,50,14
PUSHBUTTON "Delete",IDC_DELETE,225,183,50,14
END
IDD_OPTIONS DIALOGEX 0, 0, 215, 54
@@ -184,6 +187,38 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,142,10
END
IDD_SRVTRIGGER DIALOGEX 0, 0, 330, 196
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Trigger"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,219,175,50,14
PUSHBUTTON "Cancel",IDCANCEL,273,175,50,14
LTEXT "Type:",IDC_STATIC,7,9,20,8
COMBOBOX IDC_TYPE,52,7,271,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Subtype:",IDC_STATIC,7,26,30,8
COMBOBOX IDC_SUBTYPE,52,24,271,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_SUBTYPECUSTOM,52,41,271,12,ES_AUTOHSCROLL
LTEXT "Action:",IDC_STATIC,7,59,24,8
COMBOBOX IDC_ACTION,52,58,72,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Data items:",IDC_STATIC,7,76,38,8
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,52,79,217,90
PUSHBUTTON "New...",IDC_NEW,273,79,50,14
PUSHBUTTON "Edit...",IDC_EDIT,273,96,50,14
PUSHBUTTON "Delete",IDC_DELETE,273,113,50,14
END
IDD_VALUE DIALOGEX 0, 0, 267, 167
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Edit Data"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,156,146,50,14
PUSHBUTTON "Cancel",IDCANCEL,210,146,50,14
LTEXT "Values (one per line):",IDC_STATIC,7,7,69,8
EDITTEXT IDC_VALUES,7,18,253,124,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
@@ -238,7 +273,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 275
TOPMARGIN, 7
BOTTOMMARGIN, 176
BOTTOMMARGIN, 197
END
IDD_OPTIONS, DIALOG
@@ -248,6 +283,22 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 47
END
IDD_SRVTRIGGER, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 323
TOPMARGIN, 7
BOTTOMMARGIN, 189
END
IDD_VALUE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 260
TOPMARGIN, 7
BOTTOMMARGIN, 160
END
END
#endif // APSTUDIO_INVOKED
@@ -182,6 +182,7 @@
<ClCompile Include="other.c" />
<ClCompile Include="srvprgrs.c" />
<ClCompile Include="recovery.c" />
<ClCompile Include="trigger.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="extsrv.h" />
@@ -33,6 +33,9 @@
<ClCompile Include="options.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="trigger.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="extsrv.h">
@@ -71,4 +71,38 @@ VOID EsRestartServiceWithProgress(
__in SC_HANDLE ServiceHandle
);
// trigger
struct _ES_TRIGGER_CONTEXT;
struct _ES_TRIGGER_CONTEXT *EsCreateServiceTriggerContext(
__in PPH_SERVICE_ITEM ServiceItem,
__in HWND WindowHandle,
__in HWND TriggersLv
);
VOID EsDestroyServiceTriggerContext(
__in struct _ES_TRIGGER_CONTEXT *Context
);
VOID EsLoadServiceTriggerInfo(
__in struct _ES_TRIGGER_CONTEXT *Context,
__in SC_HANDLE ServiceHandle
);
BOOLEAN EsSaveServiceTriggerInfo(
__in struct _ES_TRIGGER_CONTEXT *Context,
__out PULONG Win32Result
);
#define ES_TRIGGER_EVENT_NEW 1
#define ES_TRIGGER_EVENT_EDIT 2
#define ES_TRIGGER_EVENT_DELETE 3
#define ES_TRIGGER_EVENT_SELECTIONCHANGED 4
VOID EsHandleEventServiceTrigger(
__in struct _ES_TRIGGER_CONTEXT *Context,
__in ULONG Event
);
#endif
+90 -172
View File
@@ -31,6 +31,7 @@ typedef struct _SERVICE_OTHER_CONTEXT
HWND PrivilegesLv;
HWND TriggersLv;
struct _ES_TRIGGER_CONTEXT *TriggerContext;
} SERVICE_OTHER_CONTEXT, *PSERVICE_OTHER_CONTEXT;
NTSTATUS EspLoadOtherInfo(
@@ -42,9 +43,7 @@ NTSTATUS EspLoadOtherInfo(
SC_HANDLE serviceHandle;
SERVICE_PRESHUTDOWN_INFO preshutdownInfo;
LPSERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivileges;
PSERVICE_TRIGGER_INFO triggerInfo;
ULONG returnLength;
ULONG i;
if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG)))
return NTSTATUS_FROM_WIN32(GetLastError());
@@ -103,171 +102,9 @@ NTSTATUS EspLoadOtherInfo(
// Triggers
if (WindowsVersion >= WINDOWS_7 && (triggerInfo = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_TRIGGER_INFO)))
if (Context->TriggerContext)
{
for (i = 0; i < triggerInfo->cTriggers; i++)
{
static GUID networkManagerFirstIpAddressArrivalGuid = { 0x4f27f2de, 0x14e2, 0x430b, { 0xa5, 0x49, 0x7c, 0xd4, 0x8c, 0xbc, 0x82, 0x45 } };
static GUID networkManagerLastIpAddressRemovalGuid = { 0xcc4ba62a, 0x162e, 0x4648, { 0x84, 0x7a, 0xb6, 0xbd, 0xf9, 0x93, 0xe3, 0x35 } };
static GUID domainJoinGuid = { 0x1ce20aba, 0x9851, 0x4421, { 0x94, 0x30, 0x1d, 0xde, 0xb7, 0x66, 0xe8, 0x09 } };
static GUID domainLeaveGuid = { 0xddaf516e, 0x58c2, 0x4866, { 0x95, 0x74, 0xc3, 0xb6, 0x15, 0xd4, 0x2e, 0xa1 } };
static GUID firewallPortOpenGuid = { 0xb7569e07, 0x8421, 0x4ee0, { 0xad, 0x10, 0x86, 0x91, 0x5a, 0xfd, 0xad, 0x09 } };
static GUID firewallPortCloseGuid = { 0xa144ed38, 0x8e12, 0x4de4, { 0x9d, 0x96, 0xe6, 0x47, 0x40, 0xb1, 0xa5, 0x24 } };
static GUID machinePolicyPresentGuid = { 0x659fcae6, 0x5bdb, 0x4da9, { 0xb1, 0xff, 0xca, 0x2a, 0x17, 0x8d, 0x46, 0xe0 } };
static GUID userPolicyPresentGuid = { 0x54fb46c8, 0xf089, 0x464c, { 0xb1, 0xfd, 0x59, 0xd1, 0xb6, 0x2c, 0x3b, 0x50 } };
PSERVICE_TRIGGER trigger = &triggerInfo->pTriggers[i];
PPH_STRING stringUsed = NULL;
PWSTR triggerString;
PWSTR actionString;
INT lvItemIndex;
switch (trigger->dwTriggerType)
{
case SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL:
{
PPH_STRING guidString;
if (!trigger->pTriggerSubtype)
{
triggerString = L"Device interface arrival";
}
else
{
guidString = PhFormatGuid(trigger->pTriggerSubtype);
stringUsed = PhConcatStrings2(L"Device interface arrival: ", guidString->Buffer);
triggerString = stringUsed->Buffer;
}
}
break;
case SERVICE_TRIGGER_TYPE_IP_ADDRESS_AVAILABILITY:
if (!trigger->pTriggerSubtype)
triggerString = L"IP address";
else if (memcmp(trigger->pTriggerSubtype, &networkManagerFirstIpAddressArrivalGuid, sizeof(GUID)) == 0)
triggerString = L"IP address: First arrival";
else if (memcmp(trigger->pTriggerSubtype, &networkManagerLastIpAddressRemovalGuid, sizeof(GUID)) == 0)
triggerString = L"IP address: Last removal";
else
triggerString = L"IP address: Unknown";
break;
case SERVICE_TRIGGER_TYPE_DOMAIN_JOIN:
if (!trigger->pTriggerSubtype)
triggerString = L"Domain";
else if (memcmp(trigger->pTriggerSubtype, &domainJoinGuid, sizeof(GUID)) == 0)
triggerString = L"Domain: Join";
else if (memcmp(trigger->pTriggerSubtype, &domainLeaveGuid, sizeof(GUID)) == 0)
triggerString = L"Domain: Leave";
else
triggerString = L"Domain: Unknown";
break;
case SERVICE_TRIGGER_TYPE_FIREWALL_PORT_EVENT:
if (!trigger->pTriggerSubtype)
triggerString = L"Firewall port";
else if (memcmp(trigger->pTriggerSubtype, &firewallPortOpenGuid, sizeof(GUID)) == 0)
triggerString = L"Firewall port: Open";
else if (memcmp(trigger->pTriggerSubtype, &firewallPortCloseGuid, sizeof(GUID)) == 0)
triggerString = L"Firewall port: Close";
else
triggerString = L"Firewall port: Unknown";
break;
case SERVICE_TRIGGER_TYPE_GROUP_POLICY:
if (!trigger->pTriggerSubtype)
triggerString = L"Group policy change";
else if (memcmp(trigger->pTriggerSubtype, &machinePolicyPresentGuid, sizeof(GUID)) == 0)
triggerString = L"Group policy change: Machine";
else if (memcmp(trigger->pTriggerSubtype, &userPolicyPresentGuid, sizeof(GUID)) == 0)
triggerString = L"Group policy change: User";
else
triggerString = L"Group policy change: Unknown";
break;
case SERVICE_TRIGGER_TYPE_CUSTOM:
{
PPH_STRING guidString;
PPH_STRING keyName;
HKEY keyHandle;
PPH_STRING publisherName = NULL;
if (trigger->pTriggerSubtype)
{
// Try to lookup the publisher name from the GUID.
// Copied from ProcessHacker\hndlinfo.c.
guidString = PhFormatGuid(trigger->pTriggerSubtype);
keyName = PhConcatStrings2(
L"Software\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Publishers\\",
guidString->Buffer
);
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
keyName->Buffer,
0,
KEY_READ,
&keyHandle
) == ERROR_SUCCESS)
{
publisherName = PhQueryRegistryString(keyHandle, NULL);
if (publisherName && publisherName->Length == 0)
{
PhDereferenceObject(publisherName);
publisherName = NULL;
}
RegCloseKey(keyHandle);
}
PhDereferenceObject(keyName);
if (publisherName)
{
stringUsed = PhFormatString(L"Custom: %s", publisherName->Buffer);
PhDereferenceObject(publisherName);
}
else
{
stringUsed = PhFormatString(L"Custom: %s", guidString->Buffer);
}
PhDereferenceObject(guidString);
triggerString = stringUsed->Buffer;
}
else
{
triggerString = L"Custom";
}
}
break;
default:
triggerString = L"Unknown";
break;
}
switch (trigger->dwAction)
{
case SERVICE_TRIGGER_ACTION_SERVICE_START:
actionString = L"Start";
break;
case SERVICE_TRIGGER_ACTION_SERVICE_STOP:
actionString = L"Stop";
break;
default:
actionString = L"Unknown";
break;
}
lvItemIndex = PhAddListViewItem(Context->TriggersLv, MAXINT, triggerString, NULL);
PhSetListViewSubItem(Context->TriggersLv, lvItemIndex, 1, actionString);
if (stringUsed)
PhDereferenceObject(stringUsed);
}
ExtendedListView_SortItems(Context->TriggersLv);
PhFree(triggerInfo);
EsLoadServiceTriggerInfo(Context->TriggerContext, serviceHandle);
}
CloseServiceHandle(serviceHandle);
@@ -322,16 +159,22 @@ INT_PTR CALLBACK EspServiceOtherDlgProc(
PhSetExtendedListView(privilegesLv);
context->TriggersLv = triggersLv = GetDlgItem(hwndDlg, IDC_TRIGGERS);
PhSetListViewStyle(triggersLv, FALSE, TRUE);
PhSetControlTheme(triggersLv, L"explorer");
PhAddListViewColumn(triggersLv, 0, 0, 0, LVCFMT_LEFT, 300, L"Trigger");
PhAddListViewColumn(triggersLv, 1, 1, 1, LVCFMT_LEFT, 60, L"Action");
PhSetExtendedListView(triggersLv);
if (WindowsVersion < WINDOWS_7)
if (WindowsVersion >= WINDOWS_7)
{
context->TriggerContext = EsCreateServiceTriggerContext(
context->ServiceItem,
hwndDlg,
triggersLv
);
}
else
{
EnableWindow(GetDlgItem(hwndDlg, IDC_TRIGGERS_LABEL), FALSE);
EnableWindow(triggersLv, FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_NEW), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE);
}
status = EspLoadOtherInfo(hwndDlg, context);
@@ -345,9 +188,84 @@ INT_PTR CALLBACK EspServiceOtherDlgProc(
break;
case WM_DESTROY:
{
if (context->TriggerContext)
EsDestroyServiceTriggerContext(context->TriggerContext);
PhFree(context);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_NEW:
if (context->TriggerContext)
EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_NEW);
break;
case IDC_EDIT:
if (context->TriggerContext)
EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT);
break;
case IDC_DELETE:
if (context->TriggerContext)
EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_DELETE);
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
switch (header->code)
{
case PSN_KILLACTIVE:
{
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
}
return TRUE;
case PSN_APPLY:
{
ULONG win32Result;
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
if (context->TriggerContext)
{
if (!EsSaveServiceTriggerInfo(context->TriggerContext, &win32Result))
{
if (PhShowMessage(
hwndDlg,
MB_ICONERROR | MB_RETRYCANCEL,
L"Unable to change service trigger information: %s",
((PPH_STRING)PHA_DEREFERENCE(PhGetWin32Message(win32Result)))->Buffer
) == IDRETRY)
{
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
}
}
}
}
return TRUE;
case LVN_ITEMCHANGED:
{
if (header->hwndFrom == context->TriggersLv && context->TriggerContext)
{
EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_SELECTIONCHANGED);
}
}
break;
case NM_DBLCLK:
{
if (header->hwndFrom == context->TriggersLv && context->TriggerContext)
{
EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT);
}
}
break;
}
}
break;
}
return FALSE;
+14 -2
View File
@@ -16,6 +16,8 @@
#define IDD_SRVOTHER 106
#define ID_SERVICE_PAUSE 106
#define IDD_OPTIONS 107
#define IDD_SRVTRIGGER 108
#define IDD_VALUE 109
#define IDC_SERVICES_LAYOUT 1001
#define IDC_MESSAGE 1002
#define IDC_FIRSTFAILURE 1003
@@ -42,14 +44,24 @@
#define IDC_TRIGGERS 1026
#define IDC_TRIGGERS_LABEL 1027
#define IDC_ENABLESERVICESMENU 1028
#define IDC_TYPE 1029
#define IDC_SUBTYPE 1030
#define IDC_SUBTYPECUSTOM 1031
#define IDC_ACTION 1032
#define IDC_LIST1 1033
#define IDC_LIST 1033
#define IDC_NEW 1034
#define IDC_EDIT 1035
#define IDC_DELETE 1037
#define IDC_VALUES 1038
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1029
#define _APS_NEXT_CONTROL_VALUE 1042
#define _APS_NEXT_SYMED_VALUE 107
#endif
#endif
File diff suppressed because it is too large Load Diff