diff --git a/2.x/trunk/plugins/FirewallMonitor/CHANGELOG.txt b/2.x/trunk/plugins/FirewallMonitor/CHANGELOG.txt
new file mode 100644
index 000000000..85c482e99
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.rc b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.rc
new file mode 100644
index 000000000..e405c541a
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.rc
@@ -0,0 +1,114 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Firewall Monitor plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "FirewallMonitor"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "FirewallMonitor.dll"
+ VALUE "ProductName", "Firewall Monitor plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_FW MENU
+BEGIN
+ POPUP "Event"
+ BEGIN
+ MENUITEM "&Copy\aCtrl+C", ID_EVENT_COPY
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj
new file mode 100644
index 000000000..471e250b7
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj
@@ -0,0 +1,191 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}
+ FirewallMonitor
+ Win32Proj
+
+
+
+ DynamicLibrary
+ Unicode
+ true
+ Windows7.1SDK
+
+
+ DynamicLibrary
+ Unicode
+ Windows7.1SDK
+
+
+ DynamicLibrary
+ Unicode
+ true
+ Windows7.1SDK
+
+
+ DynamicLibrary
+ Unicode
+ Windows7.1SDK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\plugins\
+ $(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\
+ true
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\plugins\
+ $(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\
+ true
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\plugins\
+ $(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\
+ false
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\plugins\
+ $(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\
+ false
+
+
+
+ Disabled
+ ../../sdk/include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+ StdCall
+ true
+ true
+
+
+ ProcessHacker.lib;ntdll.lib;fwpuclnt.lib;%(AdditionalDependencies)
+ ../../sdk/lib/i386;%(AdditionalLibraryDirectories)
+ true
+ Windows
+ MachineX86
+
+
+
+
+ Disabled
+ ../../sdk/include;%(AdditionalIncludeDirectories)
+ WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ ProgramDatabase
+ StdCall
+ true
+ true
+
+
+ ProcessHacker.lib;ntdll.lib;fwpuclnt.lib;%(AdditionalDependencies)
+ ../../sdk/lib/amd64;%(AdditionalLibraryDirectories)
+ true
+ Windows
+ MachineX64
+
+
+
+
+ MaxSpeed
+ true
+ ../../sdk/include;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+ Level3
+ ProgramDatabase
+ StdCall
+ true
+ true
+
+
+ ProcessHacker.lib;ntdll.lib;fwpuclnt.lib;%(AdditionalDependencies)
+ ../../sdk/lib/i386;%(AdditionalLibraryDirectories)
+ true
+ Windows
+ true
+ true
+ MachineX86
+ true
+
+
+
+
+ MaxSpeed
+ true
+ ../../sdk/include;%(AdditionalIncludeDirectories)
+ WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+ Level3
+ ProgramDatabase
+ StdCall
+ true
+ true
+
+
+ ProcessHacker.lib;ntdll.lib;fwpuclnt.lib;%(AdditionalDependencies)
+ ../../sdk/lib/amd64;%(AdditionalLibraryDirectories)
+ true
+ Windows
+ true
+ true
+ MachineX64
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj.filters b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj.filters
new file mode 100644
index 000000000..da2cd0ce0
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/FirewallMonitor.vcxproj.filters
@@ -0,0 +1,47 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/2.x/trunk/plugins/FirewallMonitor/fwmon.h b/2.x/trunk/plugins/FirewallMonitor/fwmon.h
new file mode 100644
index 000000000..56bf93636
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/fwmon.h
@@ -0,0 +1,67 @@
+#ifndef FWMON_H
+#define FWMON_H
+
+#include
+
+extern PPH_PLUGIN PluginInstance;
+
+#define SETTING_PREFIX L"ProcessHacker.FirewallMonitor."
+#define SETTING_NAME_FW_TREE_LIST_COLUMNS (SETTING_PREFIX L"FwTreeListColumns")
+#define SETTING_NAME_FW_TREE_LIST_SORT (SETTING_PREFIX L"FwTreeListSort")
+
+typedef struct _FW_EVENT_ITEM
+{
+ LARGE_INTEGER Time;
+} FW_EVENT_ITEM, *PFW_EVENT_ITEM;
+
+#define FWTNC_TIME 0
+#define FWTNC_PROCESS 1
+#define FWTNC_USER 2
+#define FWTNC_LOCALADDRESS 3
+#define FWTNC_LOCALPORT 4
+#define FWTNC_REMOTEADDRESS 5
+#define FWTNC_REMOTEPORT 6
+#define FWTNC_PROTOCOL 7
+#define FWTNC_MAXIMUM 8
+
+typedef struct _FW_EVENT_NODE
+{
+ PH_TREENEW_NODE Node;
+
+ PH_STRINGREF TextCache[FWTNC_MAXIMUM];
+
+ PFW_EVENT_ITEM EventItem;
+
+ PPH_STRING TooltipText;
+} FW_EVENT_NODE, *PFW_EVENT_NODE;
+
+// monitor
+
+extern PH_CALLBACK FwItemAddedEvent;
+extern PH_CALLBACK FwItemModifiedEvent;
+extern PH_CALLBACK FwItemRemovedEvent;
+extern PH_CALLBACK FwItemsUpdatedEvent;
+
+ULONG StartFwMonitor(
+ VOID
+ );
+
+VOID StopFwMonitor(
+ VOID
+ );
+
+// fwtab
+
+VOID InitializeFwTab(
+ VOID
+ );
+
+VOID LoadSettingsFwTreeList(
+ VOID
+ );
+
+VOID SaveSettingsFwTreeList(
+ VOID
+ );
+
+#endif
diff --git a/2.x/trunk/plugins/FirewallMonitor/fwtab.c b/2.x/trunk/plugins/FirewallMonitor/fwtab.c
new file mode 100644
index 000000000..ede1b190b
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/fwtab.c
@@ -0,0 +1,864 @@
+/*
+ * Process Hacker Firewall Monitor -
+ * firewall events tab
+ *
+ * Copyright (C) 2012 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 .
+ */
+
+#include "fwmon.h"
+#include "resource.h"
+#include
+#include "fwtabp.h"
+
+static BOOLEAN FwTreeNewCreated = FALSE;
+static HWND FwTreeNewHandle;
+static ULONG FwTreeNewSortColumn;
+static PH_SORT_ORDER FwTreeNewSortOrder;
+
+static PPH_HASHTABLE FwNodeHashtable; // hashtable of all nodes
+static PPH_LIST FwNodeList; // list of all nodes
+
+static PH_CALLBACK_REGISTRATION FwItemAddedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemModifiedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemRemovedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemsUpdatedRegistration;
+static BOOLEAN FwNeedsRedraw = FALSE;
+
+VOID InitializeFwTab(
+ VOID
+ )
+{
+ PH_ADDITIONAL_TAB_PAGE tabPage;
+
+ memset(&tabPage, 0, sizeof(PH_ADDITIONAL_TAB_PAGE));
+ tabPage.Text = L"Firewall";
+ tabPage.CreateFunction = FwTabCreateFunction;
+ tabPage.Index = MAXINT;
+ tabPage.SelectionChangedCallback = FwTabSelectionChangedCallback;
+ tabPage.SaveContentCallback = FwTabSaveContentCallback;
+ tabPage.FontChangedCallback = FwTabFontChangedCallback;
+ ProcessHacker_AddTabPage(PhMainWndHandle, &tabPage);
+}
+
+HWND NTAPI FwTabCreateFunction(
+ __in PVOID Context
+ )
+{
+ HWND hwnd;
+
+ hwnd = CreateWindow(
+ PH_TREENEW_CLASSNAME,
+ NULL,
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_BORDER | TN_STYLE_ICONS | TN_STYLE_DOUBLE_BUFFERED,
+ 0,
+ 0,
+ 3,
+ 3,
+ PhMainWndHandle,
+ (HMENU)PhPluginReserveIds(1),
+ PluginInstance->DllBase,
+ NULL
+ );
+
+ if (!hwnd)
+ return NULL;
+
+ FwTreeNewCreated = TRUE;
+
+ FwNodeHashtable = PhCreateHashtable(
+ sizeof(PFW_EVENT_NODE),
+ FwNodeHashtableCompareFunction,
+ FwNodeHashtableHashFunction,
+ 100
+ );
+ FwNodeList = PhCreateList(100);
+
+ InitializeFwTreeList(hwnd);
+
+ PhRegisterCallback(
+ &FwItemAddedEvent,
+ FwItemAddedHandler,
+ NULL,
+ &FwItemAddedRegistration
+ );
+ PhRegisterCallback(
+ &FwItemModifiedEvent,
+ FwItemModifiedHandler,
+ NULL,
+ &FwItemModifiedRegistration
+ );
+ PhRegisterCallback(
+ &FwItemRemovedEvent,
+ FwItemRemovedHandler,
+ NULL,
+ &FwItemRemovedRegistration
+ );
+ PhRegisterCallback(
+ &FwItemsUpdatedEvent,
+ FwItemsUpdatedHandler,
+ NULL,
+ &FwItemsUpdatedRegistration
+ );
+
+ return hwnd;
+}
+
+VOID NTAPI FwTabSelectionChangedCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ )
+{
+ if ((BOOLEAN)Parameter1)
+ {
+ SetFocus(FwTreeNewHandle);
+ }
+}
+
+VOID NTAPI FwTabSaveContentCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ )
+{
+ PPH_FILE_STREAM fileStream = Parameter1;
+ ULONG mode = PtrToUlong(Parameter2);
+
+ WriteFwList(fileStream, mode);
+}
+
+VOID NTAPI FwTabFontChangedCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ )
+{
+ if (FwTreeNewHandle)
+ SendMessage(FwTreeNewHandle, WM_SETFONT, (WPARAM)Parameter1, TRUE);
+}
+
+BOOLEAN FwNodeHashtableCompareFunction(
+ __in PVOID Entry1,
+ __in PVOID Entry2
+ )
+{
+ PFW_EVENT_NODE FwNode1 = *(PFW_EVENT_NODE *)Entry1;
+ PFW_EVENT_NODE FwNode2 = *(PFW_EVENT_NODE *)Entry2;
+
+ return FwNode1->EventItem == FwNode2->EventItem;
+}
+
+ULONG FwNodeHashtableHashFunction(
+ __in PVOID Entry
+ )
+{
+#ifdef _M_IX86
+ return PhHashInt32((ULONG)(*(PFW_EVENT_NODE *)Entry)->EventItem);
+#else
+ return PhHashInt64((ULONG64)(*(PFW_EVENT_NODE *)Entry)->EventItem);
+#endif
+}
+
+VOID InitializeFwTreeList(
+ __in HWND hwnd
+ )
+{
+ FwTreeNewHandle = hwnd;
+ PhSetControlTheme(FwTreeNewHandle, L"explorer");
+ SendMessage(TreeNew_GetTooltips(FwTreeNewHandle), TTM_SETDELAYTIME, TTDT_AUTOPOP, 0x7fff);
+
+ TreeNew_SetCallback(hwnd, FwTreeNewCallback, NULL);
+
+ TreeNew_SetRedraw(hwnd, FALSE);
+
+ // Default columns
+ PhAddTreeNewColumnEx(hwnd, FWTNC_TIME, TRUE, L"Time", 100, PH_ALIGN_LEFT, 0, 0, TRUE);
+ PhAddTreeNewColumn(hwnd, FWTNC_PROCESS, TRUE, L"Process", 200, PH_ALIGN_LEFT, 1, DT_PATH_ELLIPSIS);
+ PhAddTreeNewColumn(hwnd, FWTNC_USER, TRUE, L"User", 120, PH_ALIGN_LEFT, 2, DT_PATH_ELLIPSIS);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_LOCALADDRESS, TRUE, L"Local Address", 140, PH_ALIGN_RIGHT, 3, DT_RIGHT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_LOCALPORT, TRUE, L"Local Address", 70, PH_ALIGN_RIGHT, 4, DT_RIGHT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_REMOTEADDRESS, TRUE, L"Local Address", 140, PH_ALIGN_RIGHT, 5, DT_RIGHT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_REMOTEPORT, TRUE, L"Local Address", 70, PH_ALIGN_RIGHT, 6, DT_RIGHT, TRUE);
+ PhAddTreeNewColumn(hwnd, FWTNC_PROTOCOL, TRUE, L"Protocol", 100, PH_ALIGN_LEFT, 7, 0);
+
+ TreeNew_SetRedraw(hwnd, TRUE);
+
+ TreeNew_SetSort(hwnd, FWTNC_TIME, DescendingSortOrder);
+
+ LoadSettingsFwTreeList();
+}
+
+VOID LoadSettingsFwTreeList(
+ VOID
+ )
+{
+ PPH_STRING settings;
+ PH_INTEGER_PAIR sortSettings;
+
+ settings = PhGetStringSetting(SETTING_NAME_FW_TREE_LIST_COLUMNS);
+ PhCmLoadSettings(FwTreeNewHandle, &settings->sr);
+ PhDereferenceObject(settings);
+
+ sortSettings = PhGetIntegerPairSetting(SETTING_NAME_FW_TREE_LIST_SORT);
+ TreeNew_SetSort(FwTreeNewHandle, (ULONG)sortSettings.X, (PH_SORT_ORDER)sortSettings.Y);
+}
+
+VOID SaveSettingsFwTreeList(
+ VOID
+ )
+{
+ PPH_STRING settings;
+ PH_INTEGER_PAIR sortSettings;
+ ULONG sortColumn;
+ PH_SORT_ORDER sortOrder;
+
+ if (!FwTreeNewCreated)
+ return;
+
+ settings = PhCmSaveSettings(FwTreeNewHandle);
+ PhSetStringSetting2(SETTING_NAME_FW_TREE_LIST_COLUMNS, &settings->sr);
+ PhDereferenceObject(settings);
+
+ TreeNew_GetSort(FwTreeNewHandle, &sortColumn, &sortOrder);
+ sortSettings.X = sortColumn;
+ sortSettings.Y = sortOrder;
+ PhSetIntegerPairSetting(SETTING_NAME_FW_TREE_LIST_SORT, sortSettings);
+}
+
+PFW_EVENT_NODE AddFwNode(
+ __in PFW_EVENT_ITEM FwItem
+ )
+{
+ PFW_EVENT_NODE FwNode;
+
+ FwNode = PhAllocate(sizeof(FW_EVENT_NODE));
+ memset(FwNode, 0, sizeof(FW_EVENT_NODE));
+ PhInitializeTreeNewNode(&FwNode->Node);
+
+ FwNode->EventItem = FwItem;
+ PhReferenceObject(FwItem);
+
+ memset(FwNode->TextCache, 0, sizeof(PH_STRINGREF) * FWTNC_MAXIMUM);
+ FwNode->Node.TextCache = FwNode->TextCache;
+ FwNode->Node.TextCacheSize = FWTNC_MAXIMUM;
+
+ PhAddEntryHashtable(FwNodeHashtable, &FwNode);
+ PhAddItemList(FwNodeList, FwNode);
+
+ TreeNew_NodesStructured(FwTreeNewHandle);
+
+ return FwNode;
+}
+
+PFW_EVENT_NODE FindFwNode(
+ __in PFW_EVENT_ITEM FwItem
+ )
+{
+ FW_EVENT_NODE lookupFwNode;
+ PFW_EVENT_NODE lookupFwNodePtr = &lookupFwNode;
+ PFW_EVENT_NODE *FwNode;
+
+ lookupFwNode.EventItem = FwItem;
+
+ FwNode = (PFW_EVENT_NODE *)PhFindEntryHashtable(
+ FwNodeHashtable,
+ &lookupFwNodePtr
+ );
+
+ if (FwNode)
+ return *FwNode;
+ else
+ return NULL;
+}
+
+VOID RemoveFwNode(
+ __in PFW_EVENT_NODE FwNode
+ )
+{
+ ULONG index;
+
+ // Remove from the hashtable/list and cleanup.
+
+ PhRemoveEntryHashtable(FwNodeHashtable, &FwNode);
+
+ if ((index = PhFindItemList(FwNodeList, FwNode)) != -1)
+ PhRemoveItemList(FwNodeList, index);
+
+ if (FwNode->TooltipText) PhDereferenceObject(FwNode->TooltipText);
+
+ PhDereferenceObject(FwNode->EventItem);
+
+ PhFree(FwNode);
+
+ TreeNew_NodesStructured(FwTreeNewHandle);
+}
+
+VOID UpdateFwNode(
+ __in PFW_EVENT_NODE FwNode
+ )
+{
+ memset(FwNode->TextCache, 0, sizeof(PH_STRINGREF) * FWTNC_MAXIMUM);
+
+ PhInvalidateTreeNewNode(&FwNode->Node, TN_CACHE_ICON);
+ TreeNew_NodesStructured(FwTreeNewHandle);
+}
+
+#define SORT_FUNCTION(Column) FwTreeNewCompare##Column
+
+#define BEGIN_SORT_FUNCTION(Column) static int __cdecl FwTreeNewCompare##Column( \
+ __in const void *_elem1, \
+ __in const void *_elem2 \
+ ) \
+{ \
+ PFW_EVENT_NODE node1 = *(PFW_EVENT_NODE *)_elem1; \
+ PFW_EVENT_NODE node2 = *(PFW_EVENT_NODE *)_elem2; \
+ PFW_EVENT_ITEM fwItem1 = node1->EventItem; \
+ PFW_EVENT_ITEM fwItem2 = node2->EventItem; \
+ int sortResult = 0;
+
+#define END_SORT_FUNCTION \
+ if (sortResult == 0) \
+ sortResult = uint64cmp(fwItem1->Time.QuadPart, fwItem2->Time.QuadPart); \
+ \
+ return PhModifySort(sortResult, FwTreeNewSortOrder); \
+}
+
+BEGIN_SORT_FUNCTION(Time)
+{
+ sortResult = uint64cmp(fwItem1->Time.QuadPart, fwItem2->Time.QuadPart);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Process)
+{
+ //sortResult = PhCompareString(node1->?, node2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(User)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(LocalAddress)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(LocalPort)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(RemoteAddress)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(RemotePort)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Protocol)
+{
+ //sortResult = PhCompareString(fwItem1->?, fwItem2->?, TRUE);
+}
+END_SORT_FUNCTION
+
+BOOLEAN NTAPI FwTreeNewCallback(
+ __in HWND hwnd,
+ __in PH_TREENEW_MESSAGE Message,
+ __in_opt PVOID Parameter1,
+ __in_opt PVOID Parameter2,
+ __in_opt PVOID Context
+ )
+{
+ PFW_EVENT_NODE node;
+
+ switch (Message)
+ {
+ case TreeNewGetChildren:
+ {
+ PPH_TREENEW_GET_CHILDREN getChildren = Parameter1;
+
+ if (!getChildren->Node)
+ {
+ static PVOID sortFunctions[] =
+ {
+ SORT_FUNCTION(Time),
+ SORT_FUNCTION(Process),
+ SORT_FUNCTION(User),
+ SORT_FUNCTION(LocalAddress),
+ SORT_FUNCTION(LocalPort),
+ SORT_FUNCTION(RemoteAddress),
+ SORT_FUNCTION(RemotePort),
+ SORT_FUNCTION(Protocol)
+ };
+ int (__cdecl *sortFunction)(const void *, const void *);
+
+ if (FwTreeNewSortColumn < FWTNC_MAXIMUM)
+ sortFunction = sortFunctions[FwTreeNewSortColumn];
+ else
+ sortFunction = NULL;
+
+ if (sortFunction)
+ {
+ qsort(FwNodeList->Items, FwNodeList->Count, sizeof(PVOID), sortFunction);
+ }
+
+ getChildren->Children = (PPH_TREENEW_NODE *)FwNodeList->Items;
+ getChildren->NumberOfChildren = FwNodeList->Count;
+ }
+ }
+ return TRUE;
+ case TreeNewIsLeaf:
+ {
+ PPH_TREENEW_IS_LEAF isLeaf = Parameter1;
+
+ isLeaf->IsLeaf = TRUE;
+ }
+ return TRUE;
+ case TreeNewGetCellText:
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = Parameter1;
+ PFW_EVENT_ITEM fwItem;
+
+ node = (PFW_EVENT_NODE)getCellText->Node;
+ fwItem = node->EventItem;
+
+ switch (getCellText->Id)
+ {
+ case FWTNC_TIME:
+ //getCellText->Text = node->Time?;
+ break;
+ case FWTNC_PROCESS:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_USER:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_LOCALADDRESS:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_LOCALPORT:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_REMOTEADDRESS:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_REMOTEPORT:
+ //getCellText->Text = ??;
+ break;
+ case FWTNC_PROTOCOL:
+ //getCellText->Text = ??;
+ break;
+ default:
+ return FALSE;
+ }
+
+ getCellText->Flags = TN_CACHE;
+ }
+ return TRUE;
+ //case TreeNewGetNodeIcon:
+ // {
+ // PPH_TREENEW_GET_NODE_ICON getNodeIcon = Parameter1;
+
+ // node = (PFW_EVENT_NODE)getNodeIcon->Node;
+
+ // if (node->FwItem->ProcessIcon)
+ // {
+ // getNodeIcon->Icon = node->FwItem->ProcessIcon->Icon;
+ // }
+ // else
+ // {
+ // PhGetStockApplicationIcon(&getNodeIcon->Icon, NULL);
+ // }
+
+ // getNodeIcon->Flags = TN_CACHE;
+ // }
+ // return TRUE;
+ case TreeNewGetCellTooltip:
+ {
+ PPH_TREENEW_GET_CELL_TOOLTIP getCellTooltip = Parameter1;
+
+ node = (PFW_EVENT_NODE)getCellTooltip->Node;
+
+ if (getCellTooltip->Column->Id != 0)
+ return FALSE;
+
+ if (!node->TooltipText)
+ {
+ // TODO
+ }
+ }
+ return TRUE;
+ case TreeNewSortChanged:
+ {
+ TreeNew_GetSort(hwnd, &FwTreeNewSortColumn, &FwTreeNewSortOrder);
+ // Force a rebuild to sort the items.
+ TreeNew_NodesStructured(hwnd);
+ }
+ return TRUE;
+ case TreeNewKeyDown:
+ {
+ PPH_TREENEW_KEY_EVENT keyEvent = Parameter1;
+
+ switch (keyEvent->VirtualKey)
+ {
+ case 'C':
+ if (GetKeyState(VK_CONTROL) < 0)
+ HandleFwCommand(ID_EVENT_COPY);
+ break;
+ case 'A':
+ TreeNew_SelectRange(FwTreeNewHandle, 0, -1);
+ break;
+ case VK_RETURN:
+ //EtHandleDiskCommand(ID_EVENT_?);
+ break;
+ }
+ }
+ return TRUE;
+ case TreeNewHeaderRightClick:
+ {
+ PH_TN_COLUMN_MENU_DATA data;
+
+ data.TreeNewHandle = hwnd;
+ data.MouseEvent = Parameter1;
+ data.DefaultSortColumn = 0;
+ data.DefaultSortOrder = AscendingSortOrder;
+ PhInitializeTreeNewColumnMenu(&data);
+
+ data.Selection = PhShowEMenu(data.Menu, hwnd, PH_EMENU_SHOW_LEFTRIGHT | PH_EMENU_SHOW_NONOTIFY,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP, data.MouseEvent->ScreenLocation.x, data.MouseEvent->ScreenLocation.y);
+ PhHandleTreeNewColumnMenu(&data);
+ PhDeleteTreeNewColumnMenu(&data);
+ }
+ return TRUE;
+ case TreeNewLeftDoubleClick:
+ {
+ //HandleFwCommand(ID_EVENT_?);
+ }
+ return TRUE;
+ case TreeNewContextMenu:
+ {
+ PPH_TREENEW_MOUSE_EVENT mouseEvent = Parameter1;
+
+ ShowFwContextMenu(mouseEvent->Location);
+ }
+ return TRUE;
+ case TreeNewDestroying:
+ {
+ SaveSettingsFwTreeList();
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+PFW_EVENT_ITEM GetSelectedFwItem(
+ VOID
+ )
+{
+ PFW_EVENT_ITEM FwItem = NULL;
+ ULONG i;
+
+ for (i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = FwNodeList->Items[i];
+
+ if (node->Node.Selected)
+ {
+ FwItem = node->EventItem;
+ break;
+ }
+ }
+
+ return FwItem;
+}
+
+VOID GetSelectedFwItems(
+ __out PFW_EVENT_ITEM **FwItems,
+ __out PULONG NumberOfFwItems
+ )
+{
+ PPH_LIST list;
+ ULONG i;
+
+ list = PhCreateList(2);
+
+ for (i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = FwNodeList->Items[i];
+
+ if (node->Node.Selected)
+ {
+ PhAddItemList(list, node->EventItem);
+ }
+ }
+
+ *FwItems = PhAllocateCopy(list->Items, sizeof(PVOID) * list->Count);
+ *NumberOfFwItems = list->Count;
+
+ PhDereferenceObject(list);
+}
+
+VOID DeselectAllFwNodes(
+ VOID
+ )
+{
+ TreeNew_DeselectRange(FwTreeNewHandle, 0, -1);
+}
+
+VOID SelectAndEnsureVisibleFwNode(
+ __in PFW_EVENT_NODE FwNode
+ )
+{
+ DeselectAllFwNodes();
+
+ if (!FwNode->Node.Visible)
+ return;
+
+ TreeNew_SetFocusNode(FwTreeNewHandle, &FwNode->Node);
+ TreeNew_SetMarkNode(FwTreeNewHandle, &FwNode->Node);
+ TreeNew_SelectRange(FwTreeNewHandle, FwNode->Node.Index, FwNode->Node.Index);
+ TreeNew_EnsureVisible(FwTreeNewHandle, &FwNode->Node);
+}
+
+VOID CopyFwList(
+ VOID
+ )
+{
+ PPH_STRING text;
+
+ text = PhGetTreeNewText(FwTreeNewHandle, 0);
+ PhSetClipboardStringEx(FwTreeNewHandle, text->Buffer, text->Length);
+ PhDereferenceObject(text);
+}
+
+VOID WriteFwList(
+ __inout PPH_FILE_STREAM FileStream,
+ __in ULONG Mode
+ )
+{
+ PPH_LIST lines;
+ ULONG i;
+
+ lines = PhGetGenericTreeNewLines(FwTreeNewHandle, Mode);
+
+ for (i = 0; i < lines->Count; i++)
+ {
+ PPH_STRING line;
+
+ line = lines->Items[i];
+ PhWriteStringAsAnsiFileStream(FileStream, &line->sr);
+ PhDereferenceObject(line);
+ PhWriteStringAsAnsiFileStream2(FileStream, L"\r\n");
+ }
+
+ PhDereferenceObject(lines);
+}
+
+VOID HandleFwCommand(
+ __in ULONG Id
+ )
+{
+ switch (Id)
+ {
+ // Handle commands
+ }
+}
+
+VOID InitializeFwMenu(
+ __in PPH_EMENU Menu,
+ __in PFW_EVENT_ITEM *FwItems,
+ __in ULONG NumberOfFwItems
+ )
+{
+ PPH_EMENU_ITEM item;
+
+ if (NumberOfFwItems == 0)
+ {
+ PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED);
+ }
+ else if (NumberOfFwItems == 1)
+ {
+ // Stuff
+ item = PhFindEMenuItem(Menu, 0, L"?", 0);
+
+ // Stuff
+ item->Flags |= 0;
+ }
+ else
+ {
+ PhSetFlagsAllEMenuItems(Menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED);
+ PhEnableEMenuItem(Menu, ID_EVENT_COPY, TRUE);
+ }
+}
+
+VOID ShowFwContextMenu(
+ __in POINT Location
+ )
+{
+ PFW_EVENT_ITEM *fwItems;
+ ULONG numberOfFwItems;
+
+ GetSelectedFwItems(&fwItems, &numberOfFwItems);
+
+ if (numberOfFwItems != 0)
+ {
+ PPH_EMENU menu;
+ PPH_EMENU_ITEM item;
+
+ menu = PhCreateEMenu();
+ PhLoadResourceEMenuItem(menu, PluginInstance->DllBase, MAKEINTRESOURCE(IDR_FW), 0);
+ //PhSetFlagsEMenuItem(menu, ID_EVENT_?, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT);
+
+ InitializeFwMenu(menu, fwItems, numberOfFwItems);
+
+ item = PhShowEMenu(
+ menu,
+ PhMainWndHandle,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ Location.x,
+ Location.y
+ );
+
+ if (item)
+ {
+ HandleFwCommand(item->Id);
+ }
+
+ PhDestroyEMenu(menu);
+ }
+
+ PhFree(fwItems);
+}
+
+static VOID NTAPI FwItemAddedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ PFW_EVENT_ITEM fwItem = (PFW_EVENT_ITEM)Parameter;
+
+ PhReferenceObject(fwItem);
+ ProcessHacker_Invoke(PhMainWndHandle, OnFwItemAdded, fwItem);
+}
+
+static VOID NTAPI FwItemModifiedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ ProcessHacker_Invoke(PhMainWndHandle, OnFwItemModified, (PFW_EVENT_ITEM)Parameter);
+}
+
+static VOID NTAPI FwItemRemovedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ ProcessHacker_Invoke(PhMainWndHandle, OnFwItemRemoved, (PFW_EVENT_ITEM)Parameter);
+}
+
+static VOID NTAPI FwItemsUpdatedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ ProcessHacker_Invoke(PhMainWndHandle, OnFwItemsUpdated, NULL);
+}
+
+static VOID NTAPI OnFwItemAdded(
+ __in PVOID Parameter
+ )
+{
+ PFW_EVENT_ITEM fwItem = Parameter;
+ PFW_EVENT_NODE fwNode;
+
+ if (!FwNeedsRedraw)
+ {
+ TreeNew_SetRedraw(FwTreeNewHandle, FALSE);
+ FwNeedsRedraw = TRUE;
+ }
+
+ fwNode = AddFwNode(fwItem);
+ PhDereferenceObject(fwItem);
+}
+
+static VOID NTAPI OnFwItemModified(
+ __in PVOID Parameter
+ )
+{
+ PFW_EVENT_ITEM fwItem = Parameter;
+
+ UpdateFwNode(FindFwNode(fwItem));
+}
+
+static VOID NTAPI OnFwItemRemoved(
+ __in PVOID Parameter
+ )
+{
+ PFW_EVENT_ITEM fwItem = Parameter;
+
+ if (!FwNeedsRedraw)
+ {
+ TreeNew_SetRedraw(FwTreeNewHandle, FALSE);
+ FwNeedsRedraw = TRUE;
+ }
+
+ RemoveFwNode(FindFwNode(fwItem));
+}
+
+static VOID NTAPI OnFwItemsUpdated(
+ __in PVOID Parameter
+ )
+{
+ ULONG i;
+
+ if (FwNeedsRedraw)
+ {
+ TreeNew_SetRedraw(FwTreeNewHandle, TRUE);
+ FwNeedsRedraw = FALSE;
+ }
+
+ // Text invalidation
+
+ for (i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = FwNodeList->Items[i];
+
+ // The ??? never change, so we don't invalidate that.
+ // memset(&node->TextCache[2], 0, sizeof(PH_STRINGREF) * (FWTNC_MAXIMUM - 2));
+ // Always get the newest tooltip text from the process tree.
+ PhSwapReference(&node->TooltipText, NULL);
+ }
+
+ InvalidateRect(FwTreeNewHandle, NULL, FALSE);
+}
diff --git a/2.x/trunk/plugins/FirewallMonitor/fwtabp.h b/2.x/trunk/plugins/FirewallMonitor/fwtabp.h
new file mode 100644
index 000000000..63750b63b
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/fwtabp.h
@@ -0,0 +1,142 @@
+#ifndef FWTABP_H
+#define FWTABP_H
+
+HWND NTAPI FwTabCreateFunction(
+ __in PVOID Context
+ );
+
+VOID NTAPI FwTabSelectionChangedCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ );
+
+VOID NTAPI FwTabSaveContentCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ );
+
+VOID NTAPI FwTabFontChangedCallback(
+ __in PVOID Parameter1,
+ __in PVOID Parameter2,
+ __in PVOID Parameter3,
+ __in PVOID Context
+ );
+
+BOOLEAN FwNodeHashtableCompareFunction(
+ __in PVOID Entry1,
+ __in PVOID Entry2
+ );
+
+ULONG FwNodeHashtableHashFunction(
+ __in PVOID Entry
+ );
+
+VOID InitializeFwTreeList(
+ __in HWND hwnd
+ );
+
+PFW_EVENT_NODE AddFwNode(
+ __in PFW_EVENT_ITEM FwItem
+ );
+
+PFW_EVENT_NODE FindFwNode(
+ __in PFW_EVENT_ITEM FwItem
+ );
+
+VOID RemoveFwNode(
+ __in PFW_EVENT_NODE FwNode
+ );
+
+VOID UpdateFwNode(
+ __in PFW_EVENT_NODE FwNode
+ );
+
+BOOLEAN NTAPI FwTreeNewCallback(
+ __in HWND hwnd,
+ __in PH_TREENEW_MESSAGE Message,
+ __in_opt PVOID Parameter1,
+ __in_opt PVOID Parameter2,
+ __in_opt PVOID Context
+ );
+
+PFW_EVENT_ITEM GetSelectedFwItem(
+ VOID
+ );
+
+VOID GetSelectedFwItems(
+ __out PFW_EVENT_ITEM **FwItems,
+ __out PULONG NumberOfFwItems
+ );
+
+VOID DeselectAllFwNodes(
+ VOID
+ );
+
+VOID SelectAndEnsureVisibleFwNode(
+ __in PFW_EVENT_NODE FwNode
+ );
+
+VOID CopyFwList(
+ VOID
+ );
+
+VOID WriteFwList(
+ __inout PPH_FILE_STREAM FileStream,
+ __in ULONG Mode
+ );
+
+VOID HandleFwCommand(
+ __in ULONG Id
+ );
+
+VOID InitializeFwMenu(
+ __in PPH_EMENU Menu,
+ __in PFW_EVENT_ITEM *FwItems,
+ __in ULONG NumberOfFwItems
+ );
+
+VOID ShowFwContextMenu(
+ __in POINT Location
+ );
+
+VOID NTAPI FwItemAddedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI FwItemModifiedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI FwItemRemovedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI FwItemsUpdatedHandler(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI OnFwItemAdded(
+ __in PVOID Parameter
+ );
+
+VOID NTAPI OnFwItemModified(
+ __in PVOID Parameter
+ );
+
+VOID NTAPI OnFwItemRemoved(
+ __in PVOID Parameter
+ );
+
+VOID NTAPI OnFwItemsUpdated(
+ __in PVOID Parameter
+ );
+
+#endif
diff --git a/2.x/trunk/plugins/FirewallMonitor/main.c b/2.x/trunk/plugins/FirewallMonitor/main.c
new file mode 100644
index 000000000..55b2bdd85
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/main.c
@@ -0,0 +1,147 @@
+/*
+ * Process Hacker Firewall Monitor -
+ * main program
+ *
+ * Copyright (C) 2012 dmex
+ * Copyright (C) 2012 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 .
+ */
+
+#include "fwmon.h"
+#include "resource.h"
+
+VOID NTAPI LoadCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI UnloadCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI ShowOptionsCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+VOID NTAPI MainWindowShowingCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ );
+
+PPH_PLUGIN PluginInstance;
+PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
+PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+PH_CALLBACK_REGISTRATION MainWindowShowingCallbackRegistration;
+
+LOGICAL DllMain(
+ __in HINSTANCE Instance,
+ __in ULONG Reason,
+ __reserved PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+
+ PluginInstance = PhRegisterPlugin(L"ProcessHacker.FirewallMonitor", Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Firewall Monitor";
+ info->Author = L"dmex";
+ info->Description = L"Monitors firewall events.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
+ LoadCallback,
+ NULL,
+ &PluginLoadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
+ UnloadCallback,
+ NULL,
+ &PluginUnloadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
+ ShowOptionsCallback,
+ NULL,
+ &PluginShowOptionsCallbackRegistration
+ );
+
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainWindowShowing),
+ MainWindowShowingCallback,
+ NULL,
+ &MainWindowShowingCallbackRegistration
+ );
+
+ {
+ static PH_SETTING_CREATE settings[] =
+ {
+ { StringSettingType, SETTING_NAME_FW_TREE_LIST_COLUMNS, L"" },
+ { IntegerPairSettingType, SETTING_NAME_FW_TREE_LIST_SORT, L"0,2" }
+ };
+
+ PhAddSettings(settings, sizeof(settings) / sizeof(PH_SETTING_CREATE));
+ }
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+VOID NTAPI LoadCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ NOTHING;
+}
+
+VOID NTAPI UnloadCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ StopFwMonitor();
+}
+
+VOID NTAPI ShowOptionsCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ // Options?
+}
+
+VOID NTAPI MainWindowShowingCallback(
+ __in_opt PVOID Parameter,
+ __in_opt PVOID Context
+ )
+{
+ InitializeFwTab();
+}
diff --git a/2.x/trunk/plugins/FirewallMonitor/monitor.c b/2.x/trunk/plugins/FirewallMonitor/monitor.c
new file mode 100644
index 000000000..e7ce7d931
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/monitor.c
@@ -0,0 +1,340 @@
+/*
+ * Process Hacker Firewall Monitor -
+ * firewall monitor
+ *
+ * Copyright (C) 2012 dmex
+ *
+ * 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 .
+ */
+
+#include "fwmon.h"
+#include
+#ifndef INCLUDED_FWPMU
+#define INCLUDED_FWPMU
+#include
+#endif
+
+PH_CALLBACK_DECLARE(FwItemAddedEvent);
+PH_CALLBACK_DECLARE(FwItemModifiedEvent);
+PH_CALLBACK_DECLARE(FwItemRemovedEvent);
+PH_CALLBACK_DECLARE(FwItemsUpdatedEvent);
+
+HANDLE EngineHandle;
+HANDLE EventHandle;
+
+VOID CALLBACK DropEventCallback(__inout VOID* pContext, __in const FWPM_NET_EVENT* pEvent)
+{
+ SYSTEMTIME st;
+ FILETIME ft;
+ USHORT localPort;
+ USHORT remotePort;
+
+ //SID_NAME_USE name;
+ //DWORD length;
+ //WCHAR szSidName[MAX_PATH];
+
+ WCHAR szLocalDate[255], szLocalTime[255], szProtoType[255], szPacketType[255], szPacketSrcDst[255], szPacketinOut[255];
+
+ FileTimeToLocalFileTime(&pEvent->header.timeStamp, &ft);
+ FileTimeToSystemTime(&ft, &st);
+
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, szLocalDate, _countof(szLocalDate));
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szLocalTime, _countof(szLocalTime));
+
+ localPort = _byteswap_ushort(pEvent->header.localPort);
+ remotePort = _byteswap_ushort(pEvent->header.remotePort);
+
+ switch (pEvent->header.ipProtocol)
+ {
+ case IPPROTO_ICMP:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"ICMP"
+ );
+ }
+ break;
+ case IPPROTO_IGMP:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"ICMP"
+ );
+ }
+ break;
+ case IPPROTO_TCP:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"TCP"
+ );
+ }
+ break;
+ case IPPROTO_UDP:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"UDP"
+ );
+ }
+ break;
+ default:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"",
+ pEvent->header.ipProtocol
+ );
+ }
+ break;
+ /*case IPPROTO_ICMPV6:
+ {
+ swprintf_s(
+ szProtoType,
+ _countof(szProtoType),
+ L"ICMPV6"
+ );
+ }
+ break;*/
+ }
+
+ switch(pEvent->ipsecDrop->direction)
+ {
+ case FWP_DIRECTION_INBOUND:
+ {
+ swprintf_s(
+ szPacketinOut,
+ _countof(szPacketinOut),
+ L"Inbound"
+ );
+ }
+ break;
+ case FWP_DIRECTION_OUTBOUND:
+ {
+ swprintf_s(
+ szPacketinOut,
+ _countof(szPacketinOut),
+ L"Outbound"
+ );
+ }
+ break;
+ }
+
+ switch (pEvent->header.ipVersion)
+ {
+ case FWP_IP_VERSION_V4:
+ {
+ swprintf_s(
+ szPacketType,
+ _countof(szPacketType),
+ L"IPv4"
+ );
+
+ swprintf_s(
+ szPacketSrcDst,
+ _countof(szPacketSrcDst),
+ L"SRC: %ld.%ld.%ld.%ld:%ld \nDST: %ld.%ld.%ld.%ld:%ld",
+ ((byte*)&pEvent->header.localAddrV4)[3],
+ ((byte*)&pEvent->header.localAddrV4)[2],
+ ((byte*)&pEvent->header.localAddrV4)[1],
+ ((byte*)&pEvent->header.localAddrV4)[0],
+ localPort,
+ ((byte*)&pEvent->header.remoteAddrV4)[3],
+ ((byte*)&pEvent->header.remoteAddrV4)[2],
+ ((byte*)&pEvent->header.remoteAddrV4)[1],
+ ((byte*)&pEvent->header.remoteAddrV4)[0],
+ remotePort
+ );
+ }
+ break;
+ case FWP_IP_VERSION_V6:
+ {
+ swprintf_s(
+ szPacketType,
+ _countof(szPacketType),
+ L"IPv6"
+ );
+
+ swprintf_s(
+ szPacketSrcDst,
+ _countof(szPacketSrcDst),
+ L"SRC: [%x:%x:%x:%x%x:%x:%x:%x]:%ld \nDST: [%x:%x:%x:%x%x:%x:%x:%x]:%ld",
+ ((WORD*)&pEvent->header.localAddrV6)[7],
+ ((WORD*)&pEvent->header.localAddrV6)[6],
+ ((WORD*)&pEvent->header.localAddrV6)[5],
+ ((WORD*)&pEvent->header.localAddrV6)[4],
+ ((WORD*)&pEvent->header.localAddrV6)[3],
+ ((WORD*)&pEvent->header.localAddrV6)[2],
+ ((WORD*)&pEvent->header.localAddrV6)[1],
+ ((WORD*)&pEvent->header.localAddrV6)[0],
+ localPort,
+ ((WORD*)&pEvent->header.remoteAddrV6)[7],
+ ((WORD*)&pEvent->header.remoteAddrV6)[6],
+ ((WORD*)&pEvent->header.remoteAddrV6)[5],
+ ((WORD*)&pEvent->header.remoteAddrV6)[4],
+ ((WORD*)&pEvent->header.remoteAddrV6)[3],
+ ((WORD*)&pEvent->header.remoteAddrV6)[2],
+ ((WORD*)&pEvent->header.remoteAddrV6)[1],
+ ((WORD*)&pEvent->header.remoteAddrV6)[0],
+ remotePort);
+ }
+ break;
+ }
+
+
+ if (IsValidSid(pEvent->header.userId))
+ {
+ SID_NAME_USE eUse = SidTypeUnknown;
+ DWORD dwAcctName = 256, dwDomainName = 256;
+ WCHAR AcctName[256];
+ WCHAR DomainName[256];
+
+ LookupAccountSidW(NULL, pEvent->header.userId, AcctName, (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &eUse);
+
+ wprintf(
+ L"%s %s %s Packet dropped: \nUser: %s \nAppID: %s \n%s \n%s %s\n\n",
+ szPacketType,
+ szProtoType,
+ szPacketinOut,
+ AcctName,
+ pEvent->header.appId.data,
+ szPacketSrcDst,
+ szLocalDate,
+ szLocalTime
+ );
+ }
+ else
+ {
+ wprintf(
+ L"%s %s %s Packet dropped: \nAppID: %s \n%s \n%s %s\n\n",
+ szPacketType,
+ szProtoType,
+ szPacketinOut,
+ pEvent->header.appId.data,
+ szPacketSrcDst,
+ szLocalDate,
+ szLocalTime
+ );
+ }
+
+ // Do whatever you need for the event
+}
+
+ULONG StartFwMonitor(
+ VOID
+ )
+{
+ HANDLE engineHandle = 0, eventHandle = 0;
+ FWPM_SESSION session = { 0 };
+ FWP_VALUE0 value = { 0 };
+ FWPM_NET_EVENT_ENUM_TEMPLATE enumTemplate = { 0 };
+ FWPM_NET_EVENT_SUBSCRIPTION subscription = { 0 };
+ DWORD result = 0;
+
+ session.flags = 0;
+ session.displayData.name = L"PhFirewallMonitoringSession";
+ session.displayData.description = L"Non-Dynamic session for Process Hacker";
+
+ // Create a non-dynamic BFE session
+ result = FwpmEngineOpen0(
+ NULL,
+ RPC_C_AUTHN_WINNT,
+ NULL,
+ &session,
+ &engineHandle
+ );
+
+ if (result != ERROR_SUCCESS)
+ {
+ StopFwMonitor();
+ return result;
+ }
+
+ value.type = FWP_UINT32;
+ value.uint32 = 1;
+
+ // Enable collection of NetEvents
+ result = FwpmEngineSetOption(
+ engineHandle,
+ FWPM_ENGINE_COLLECT_NET_EVENTS,
+ &value
+ );
+
+ if (result != ERROR_SUCCESS)
+ {
+ StopFwMonitor();
+ return result;
+ }
+
+ enumTemplate.numFilterConditions = 0; // get events for all conditions
+
+ subscription.sessionKey = session.sessionKey;
+ subscription.enumTemplate = &enumTemplate;
+
+ // Subscribe to the events
+ result = FwpmNetEventSubscribe(
+ engineHandle,
+ &subscription,
+ DropEventCallback,
+ 0,
+ &eventHandle
+ );
+
+ if (result != ERROR_SUCCESS)
+ {
+ StopFwMonitor();
+ return result;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+VOID StopFwMonitor(
+ VOID
+ )
+{
+ FWP_VALUE0 value = { 0 };
+
+ if (EventHandle)
+ {
+ FwpmNetEventUnsubscribe(
+ EngineHandle,
+ EventHandle
+ );
+
+ EventHandle = 0;
+ }
+
+ if (EngineHandle)
+ {
+ value.type = FWP_UINT32;
+ value.uint32 = 0;
+
+ // Disable collection of NetEvents
+ FwpmEngineSetOption(EngineHandle,
+ FWPM_ENGINE_COLLECT_NET_EVENTS,
+ &value);
+
+ FwpmEngineClose(EngineHandle);
+
+ EngineHandle = 0;
+ }
+}
diff --git a/2.x/trunk/plugins/FirewallMonitor/resource.h b/2.x/trunk/plugins/FirewallMonitor/resource.h
new file mode 100644
index 000000000..3d33397d3
--- /dev/null
+++ b/2.x/trunk/plugins/FirewallMonitor/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by FirewallMonitor.rc
+//
+#define IDR_MENU1 101
+#define IDR_FW 101
+#define ID_EVENT_COPY 40001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40002
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/2.x/trunk/plugins/Plugins.sln b/2.x/trunk/plugins/Plugins.sln
index 9453a8980..d152a09c3 100644
--- a/2.x/trunk/plugins/Plugins.sln
+++ b/2.x/trunk/plugins/Plugins.sln
@@ -23,6 +23,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updater", "Updater\Updater.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UserNotes", "UserNotes\UserNotes.vcxproj", "{7C38D0AA-572C-4D75-8E4E-D68AF3C051AF}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FirewallMonitor", "FirewallMonitor\FirewallMonitor.vcxproj", "{44A7C3BA-BAD5-40F3-AB70-442D44539053}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -119,6 +121,14 @@ Global
{7C38D0AA-572C-4D75-8E4E-D68AF3C051AF}.Release|Win32.Build.0 = Release|Win32
{7C38D0AA-572C-4D75-8E4E-D68AF3C051AF}.Release|x64.ActiveCfg = Release|x64
{7C38D0AA-572C-4D75-8E4E-D68AF3C051AF}.Release|x64.Build.0 = Release|x64
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Debug|Win32.ActiveCfg = Debug|Win32
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Debug|Win32.Build.0 = Debug|Win32
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Debug|x64.ActiveCfg = Debug|x64
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Debug|x64.Build.0 = Debug|x64
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Release|Win32.ActiveCfg = Release|Win32
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Release|Win32.Build.0 = Release|Win32
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Release|x64.ActiveCfg = Release|x64
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE