Process Hacker
extmgr.c
Go to the documentation of this file.
1 /*
2  * Process Hacker -
3  * extension manager
4  *
5  * Copyright (C) 2011 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 /*
24  * The extension manager provides support for generic extensions. It sits directly
25  * underneath the plugin manager, and has no knowledge of plugin details (how they are
26  * loaded, plugin information, etc.).
27  */
28 
29 #include <phapp.h>
30 #include <extmgri.h>
31 
35 
40  VOID
41  )
42 {
43  ULONG i;
44 
45  for (i = 0; i < EmMaximumObjectType; i++)
46  {
47  InitializeListHead(&PhEmObjectTypeState[i].ExtensionListHead);
48  }
49 }
50 
58  _Out_ PPH_EM_APP_CONTEXT AppContext,
59  _In_ PPH_STRINGREF AppName
60  )
61 {
62  AppContext->AppName = *AppName;
63  memset(AppContext->Extensions, 0, sizeof(AppContext->Extensions));
64 
65  InsertTailList(&PhEmAppContextListHead, &AppContext->ListEntry);
67 }
68 
79  _Inout_ PPH_EM_APP_CONTEXT AppContext,
80  _In_ PH_EM_OBJECT_TYPE ObjectType,
81  _In_ SIZE_T ExtensionSize,
82  _In_opt_ PPH_EM_OBJECT_CALLBACK CreateCallback,
83  _In_opt_ PPH_EM_OBJECT_CALLBACK DeleteCallback
84  )
85 {
86  PPH_EM_OBJECT_TYPE_STATE objectTypeState;
87  PPH_EM_OBJECT_EXTENSION objectExtension;
88 
89  objectTypeState = &PhEmObjectTypeState[ObjectType];
90  objectExtension = AppContext->Extensions[ObjectType];
91 
92  if (!objectExtension)
93  {
94  objectExtension = PhAllocate(sizeof(PH_EM_OBJECT_EXTENSION));
95  memset(objectExtension, 0, sizeof(PH_EM_OBJECT_EXTENSION));
96  InsertTailList(&objectTypeState->ExtensionListHead, &objectExtension->ListEntry);
97  AppContext->Extensions[ObjectType] = objectExtension;
98 
99  objectExtension->ExtensionSize = ExtensionSize;
100  objectExtension->ExtensionOffset = objectTypeState->ExtensionOffset;
101 
102  objectTypeState->ExtensionOffset += ExtensionSize;
103  }
104 
105  objectExtension->Callbacks[EmObjectCreate] = CreateCallback;
106  objectExtension->Callbacks[EmObjectDelete] = DeleteCallback;
107 }
108 
117  _In_ PPH_EM_APP_CONTEXT AppContext,
118  _In_ PH_EM_OBJECT_TYPE ObjectType,
119  _In_ PVOID Object
120  )
121 {
122  PPH_EM_OBJECT_EXTENSION objectExtension;
123 
124  objectExtension = AppContext->Extensions[ObjectType];
125 
126  if (!objectExtension)
127  return NULL;
128 
129  return (PCHAR)Object + PhEmObjectTypeState[ObjectType].InitialSize + objectExtension->ExtensionOffset;
130 }
131 
139  _In_ PH_EM_OBJECT_TYPE ObjectType,
140  _In_ SIZE_T InitialSize
141  )
142 {
143  PhEmObjectTypeState[ObjectType].InitialSize = InitialSize;
144 
145  return InitialSize + PhEmObjectTypeState[ObjectType].ExtensionOffset;
146 }
147 
156  _In_ PH_EM_OBJECT_TYPE ObjectType,
157  _In_ PVOID Object,
158  _In_ PH_EM_OBJECT_OPERATION Operation
159  )
160 {
161  PPH_EM_OBJECT_TYPE_STATE objectTypeState;
162  PLIST_ENTRY listEntry;
163  PPH_EM_OBJECT_EXTENSION objectExtension;
164 
165  if (PhEmAppContextCount == 0)
166  return;
167 
168  objectTypeState = &PhEmObjectTypeState[ObjectType];
169 
170  listEntry = objectTypeState->ExtensionListHead.Flink;
171 
172  while (listEntry != &objectTypeState->ExtensionListHead)
173  {
174  objectExtension = CONTAINING_RECORD(listEntry, PH_EM_OBJECT_EXTENSION, ListEntry);
175 
176  if (objectExtension->Callbacks[Operation])
177  {
178  objectExtension->Callbacks[Operation](
179  Object,
180  ObjectType,
181  (PCHAR)Object + objectTypeState->InitialSize + objectExtension->ExtensionOffset
182  );
183  }
184 
185  listEntry = listEntry->Flink;
186  }
187 }
188 
197  _In_ PPH_STRINGREF CompoundId,
198  _Out_ PPH_STRINGREF AppName,
199  _Out_ PULONG SubId
200  )
201 {
202  PH_STRINGREF firstPart;
203  PH_STRINGREF secondPart;
204  ULONG64 integer;
205 
206  firstPart = *CompoundId;
207 
208  if (firstPart.Length == 0)
209  return FALSE;
210  if (firstPart.Buffer[0] != '+')
211  return FALSE;
212 
213  PhSkipStringRef(&firstPart, sizeof(WCHAR));
214  PhSplitStringRefAtChar(&firstPart, '+', &firstPart, &secondPart);
215 
216  if (firstPart.Length == 0 || secondPart.Length == 0)
217  return FALSE;
218 
219  if (!PhStringToInteger64(&secondPart, 10, &integer))
220  return FALSE;
221 
222  *AppName = firstPart;
223  *SubId = (ULONG)integer;
224 
225  return TRUE;
226 }