Process Hacker
triggpg.c
Go to the documentation of this file.
1 /*
2  * Process Hacker Extended Services -
3  * triggers page
4  *
5  * Copyright (C) 2015 wj32
6  *
7  * This file is part of Process Hacker.
8  *
9  * Process Hacker is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Process Hacker is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <phdk.h>
24 #include <windowsx.h>
25 #include "extsrv.h"
26 #include "resource.h"
27 
28 typedef struct _SERVICE_TRIGGERS_CONTEXT
29 {
30  PPH_SERVICE_ITEM ServiceItem;
31  HWND TriggersLv;
32  struct _ES_TRIGGER_CONTEXT *TriggerContext;
34 
36  _In_ HWND hwndDlg,
37  _In_ PSERVICE_TRIGGERS_CONTEXT Context
38  )
39 {
40  NTSTATUS status = STATUS_SUCCESS;
41  SC_HANDLE serviceHandle;
42 
43  if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG)))
44  return NTSTATUS_FROM_WIN32(GetLastError());
45 
46  EsLoadServiceTriggerInfo(Context->TriggerContext, serviceHandle);
47  CloseServiceHandle(serviceHandle);
48 
49  return status;
50 }
51 
52 INT_PTR CALLBACK EspServiceTriggersDlgProc(
53  _In_ HWND hwndDlg,
54  _In_ UINT uMsg,
55  _In_ WPARAM wParam,
56  _In_ LPARAM lParam
57  )
58 {
60 
61  if (uMsg == WM_INITDIALOG)
62  {
63  context = PhAllocate(sizeof(SERVICE_TRIGGERS_CONTEXT));
64  memset(context, 0, sizeof(SERVICE_TRIGGERS_CONTEXT));
65 
66  SetProp(hwndDlg, L"Context", (HANDLE)context);
67  }
68  else
69  {
70  context = (PSERVICE_TRIGGERS_CONTEXT)GetProp(hwndDlg, L"Context");
71 
72  if (uMsg == WM_DESTROY)
73  RemoveProp(hwndDlg, L"Context");
74  }
75 
76  if (!context)
77  return FALSE;
78 
79  switch (uMsg)
80  {
81  case WM_INITDIALOG:
82  {
83  NTSTATUS status;
84  LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
85  PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam;
86  HWND triggersLv;
87 
88  context->ServiceItem = serviceItem;
89  context->TriggersLv = triggersLv = GetDlgItem(hwndDlg, IDC_TRIGGERS);
90  context->TriggerContext = EsCreateServiceTriggerContext(
91  context->ServiceItem,
92  hwndDlg,
93  triggersLv
94  );
95 
96  status = EspLoadTriggerInfo(hwndDlg, context);
97 
98  if (!NT_SUCCESS(status))
99  {
100  PhShowWarning(hwndDlg, L"Unable to query service trigger information: %s",
102  }
103  }
104  break;
105  case WM_DESTROY:
106  {
107  EsDestroyServiceTriggerContext(context->TriggerContext);
108  PhFree(context);
109  }
110  break;
111  case WM_COMMAND:
112  {
113  switch (LOWORD(wParam))
114  {
115  case IDC_NEW:
116  if (context->TriggerContext)
117  EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_NEW);
118  break;
119  case IDC_EDIT:
120  if (context->TriggerContext)
121  EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT);
122  break;
123  case IDC_DELETE:
124  if (context->TriggerContext)
125  EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_DELETE);
126  break;
127  }
128  }
129  break;
130  case WM_NOTIFY:
131  {
132  LPNMHDR header = (LPNMHDR)lParam;
133 
134  switch (header->code)
135  {
136  case PSN_KILLACTIVE:
137  {
138  SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
139  }
140  return TRUE;
141  case PSN_APPLY:
142  {
143  ULONG win32Result = 0;
144 
145  SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
146 
147  if (!EsSaveServiceTriggerInfo(context->TriggerContext, &win32Result))
148  {
149  if (win32Result == ERROR_CANCELLED || (PhShowMessage(
150  hwndDlg,
151  MB_ICONERROR | MB_RETRYCANCEL,
152  L"Unable to change service trigger information: %s",
153  ((PPH_STRING)PhAutoDereferenceObject(PhGetWin32Message(win32Result)))->Buffer
154  ) == IDRETRY))
155  {
156  SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
157  }
158  }
159 
160  return TRUE;
161  }
162  break;
163  case LVN_ITEMCHANGED:
164  {
165  if (header->hwndFrom == context->TriggersLv && context->TriggerContext)
166  {
168  }
169  }
170  break;
171  case NM_DBLCLK:
172  {
173  if (header->hwndFrom == context->TriggersLv && context->TriggerContext)
174  {
175  EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT);
176  }
177  }
178  break;
179  }
180  }
181  break;
182  }
183 
184  return FALSE;
185 }