diff --git a/.gitignore b/.gitignore
index 5fa2415..10e69e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,7 +105,6 @@ Desktop.ini
build/Installer/*.exe
ProcessHacker/include/phapprev.h
ProcessHacker/sdk/phapppub.h
-plugins-extra/
sdk/
KProcessHacker/*.log
diff --git a/plugins-extra/AtomTablePlugin/AtomTablePlugin.rc b/plugins-extra/AtomTablePlugin/AtomTablePlugin.rc
new file mode 100644
index 0000000..e480de1
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/AtomTablePlugin.rc
@@ -0,0 +1,122 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Atom Table Plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "dmex.AtomTablePlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "AtomTablePlugin.dll"
+ VALUE "ProductName", "Atom Table plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ATOMDIALOG DIALOGEX 0, 0, 325, 180
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Global Atom Table"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,269,160,50,14
+ CONTROL "",IDC_ATOMLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,5,312,152
+ PUSHBUTTON "Refresh",IDRETRY,7,160,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ATOMDIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 318
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 174
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj b/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj
new file mode 100644
index 0000000..5e1abb9
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj
@@ -0,0 +1,108 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {12390643-F40D-411F-A2E8-BF85F90223DF}
+ AtomTablePlugin
+ Win32Proj
+ AtomTablePlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj.filters b/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj.filters
new file mode 100644
index 0000000..8c5de90
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/AtomTablePlugin.vcxproj.filters
@@ -0,0 +1,32 @@
+
+
+
+
+ Header Files
+
+
+
+
+
+
+
+ {802108be-ae96-47c3-8d93-884ed6dd096a}
+
+
+ {3e65ffb8-3f3e-40d7-b3ca-d55cae8edb16}
+
+
+ {b98dd849-bbfe-4b41-8c48-f65680da5c00}
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/AtomTablePlugin/CHANGELOG.txt b/plugins-extra/AtomTablePlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/AtomTablePlugin/main.c b/plugins-extra/AtomTablePlugin/main.c
new file mode 100644
index 0000000..59ada91
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/main.c
@@ -0,0 +1,455 @@
+/*
+ * Process Hacker Extra Plugins -
+ * NT Atom Table Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include "resource.h"
+
+#define ATOM_TABLE_MENUITEM 1000
+#define PLUGIN_NAME L"dmex.AtomTablePlugin"
+#define SETTING_NAME_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
+#define SETTING_NAME_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
+#define SETTING_NAME_LISTVIEW_COLUMNS (PLUGIN_NAME L".ListViewColumns")
+
+static PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
+static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+static HWND ListViewWndHandle;
+static PH_LAYOUT_MANAGER LayoutManager;
+static PPH_PLUGIN PluginInstance;
+
+NTSTATUS PhEnumAtomTable(
+ _Out_ PATOM_TABLE_INFORMATION* AtomTable
+ )
+{
+ NTSTATUS status;
+ PVOID buffer;
+ ULONG bufferSize = 0x1000;
+
+ buffer = PhAllocate(bufferSize);
+ memset(buffer, 0, bufferSize);
+
+ status = NtQueryInformationAtom(
+ RTL_ATOM_INVALID_ATOM,
+ AtomTableInformation,
+ buffer,
+ bufferSize,
+ &bufferSize // Not used...
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ PhFree(buffer);
+ return status;
+ }
+
+ *AtomTable = buffer;
+
+ return status;
+}
+
+NTSTATUS PhQueryAtomTableEntry(
+ _In_ RTL_ATOM Atom,
+ _Out_ PATOM_BASIC_INFORMATION* AtomInfo
+ )
+{
+ NTSTATUS status;
+ PVOID buffer;
+ ULONG bufferSize = 0x1000;
+
+ buffer = PhAllocate(bufferSize);
+ memset(buffer, 0, bufferSize);
+
+ status = NtQueryInformationAtom(
+ Atom,
+ AtomBasicInformation,
+ buffer,
+ bufferSize,
+ &bufferSize // Not used...
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ PhFree(buffer);
+ return status;
+ }
+
+ *AtomInfo = buffer;
+
+ return status;
+}
+
+VOID LoadAtomTable(VOID)
+{
+ PATOM_TABLE_INFORMATION atomTable = NULL;
+
+ if (!NT_SUCCESS(PhEnumAtomTable(&atomTable)))
+ return;
+
+ ExtendedListView_SetRedraw(ListViewWndHandle, FALSE);
+ ListView_DeleteAllItems(ListViewWndHandle);
+
+ for (ULONG i = 0; i < atomTable->NumberOfAtoms; i++)
+ {
+ PATOM_BASIC_INFORMATION atomInfo = NULL;
+
+ if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo)))
+ {
+ PhAddListViewItem(ListViewWndHandle, MAXINT, PhaFormatString(L"(Error) #%lu", i)->Buffer, NULL);
+ continue;
+ }
+
+ if ((atomInfo->Flags & RTL_ATOM_PINNED) == RTL_ATOM_PINNED)
+ {
+ INT index = PhAddListViewItem(
+ ListViewWndHandle,
+ MAXINT,
+ PhaFormatString(L"%s (Pinned)", atomInfo->Name)->Buffer,
+ NULL
+ );
+ PhSetListViewSubItem(
+ ListViewWndHandle,
+ index,
+ 1,
+ PhaFormatString(L"%u", atomInfo->UsageCount)->Buffer
+ );
+ }
+ else
+ {
+ INT index = PhAddListViewItem(
+ ListViewWndHandle,
+ MAXINT,
+ atomInfo->Name,
+ NULL
+ );
+ PhSetListViewSubItem(
+ ListViewWndHandle,
+ index,
+ 1,
+ PhaFormatString(L"%u", atomInfo->UsageCount)->Buffer
+ );
+ }
+
+ PhFree(atomInfo);
+ }
+
+ ExtendedListView_SetRedraw(ListViewWndHandle, TRUE);
+
+ PhFree(atomTable);
+}
+
+PPH_STRING PhGetSelectedListViewItemText(
+ _In_ HWND hWnd
+ )
+{
+ INT index = PhFindListViewItemByFlags(
+ hWnd,
+ -1,
+ LVNI_SELECTED
+ );
+
+ if (index != -1)
+ {
+ WCHAR textBuffer[MAX_PATH] = L"";
+
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.iSubItem = 0;
+ item.pszText = textBuffer;
+ item.cchTextMax = MAX_PATH;
+
+ if (ListView_GetItem(hWnd, &item))
+ return PhCreateString(textBuffer);
+ }
+
+ return NULL;
+}
+
+VOID ShowStatusMenu(
+ _In_ HWND hwndDlg
+ )
+{
+ PPH_STRING cacheEntryName;
+
+ cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle);
+
+ if (cacheEntryName)
+ {
+ POINT cursorPos;
+ PPH_EMENU menu;
+ PPH_EMENU_ITEM selectedItem;
+
+ GetCursorPos(&cursorPos);
+
+ menu = PhCreateEMenu();
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1);
+
+ selectedItem = PhShowEMenu(
+ menu,
+ ListViewWndHandle,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ cursorPos.x,
+ cursorPos.y
+ );
+
+ if (selectedItem && selectedItem->Id != -1)
+ {
+ switch (selectedItem->Id)
+ {
+ case 1:
+ {
+ INT lvItemIndex = PhFindListViewItemByFlags(
+ ListViewWndHandle,
+ -1,
+ LVNI_SELECTED
+ );
+
+ if (lvItemIndex != -1)
+ {
+ if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage(
+ hwndDlg,
+ L"remove",
+ cacheEntryName->Buffer,
+ NULL,
+ FALSE
+ ))
+ {
+ PATOM_TABLE_INFORMATION atomTable = NULL;
+
+ if (!NT_SUCCESS(PhEnumAtomTable(&atomTable)))
+ return;
+
+ for (ULONG i = 0; i < atomTable->NumberOfAtoms; i++)
+ {
+ PATOM_BASIC_INFORMATION atomInfo = NULL;
+
+ if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo)))
+ continue;
+
+ if (!PhEqualStringZ(atomInfo->Name, cacheEntryName->Buffer, TRUE))
+ continue;
+
+ do
+ {
+ if (!NT_SUCCESS(NtDeleteAtom(atomTable->Atoms[i])))
+ {
+ break;
+ }
+
+ PhFree(atomInfo);
+ atomInfo = NULL;
+
+ if (!NT_SUCCESS(PhQueryAtomTableEntry(atomTable->Atoms[i], &atomInfo)))
+ break;
+
+ } while (atomInfo->UsageCount >= 1);
+
+ ListView_DeleteItem(ListViewWndHandle, lvItemIndex);
+
+ if (atomInfo)
+ {
+ PhFree(atomInfo);
+ }
+ }
+
+ PhFree(atomTable);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ PhDestroyEMenu(menu);
+ PhDereferenceObject(cacheEntryName);
+ }
+}
+
+INT_PTR CALLBACK MainWindowDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ PhCenterWindow(hwndDlg, PhMainWndHandle);
+ ListViewWndHandle = GetDlgItem(hwndDlg, IDC_ATOMLIST);
+
+ PhInitializeLayoutManager(&LayoutManager, hwndDlg);
+ PhAddLayoutItem(&LayoutManager, ListViewWndHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDRETRY), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+
+ PhRegisterDialog(hwndDlg);
+ PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+
+ PhSetListViewStyle(ListViewWndHandle, FALSE, TRUE);
+ PhSetControlTheme(ListViewWndHandle, L"explorer");
+ PhAddListViewColumn(ListViewWndHandle, 0, 0, 0, LVCFMT_LEFT, 370, L"Atom Name");
+ PhAddListViewColumn(ListViewWndHandle, 1, 1, 1, LVCFMT_LEFT, 70, L"Ref Count");
+ PhSetExtendedListView(ListViewWndHandle);
+ PhLoadListViewColumnsFromSetting(SETTING_NAME_LISTVIEW_COLUMNS, ListViewWndHandle);
+
+ LoadAtomTable();
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&LayoutManager);
+ break;
+ case WM_DESTROY:
+ PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhSaveListViewColumnsToSetting(SETTING_NAME_LISTVIEW_COLUMNS, ListViewWndHandle);
+ PhDeleteLayoutManager(&LayoutManager);
+ PhUnregisterDialog(hwndDlg);
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ case IDRETRY:
+ LoadAtomTable();
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR hdr = (LPNMHDR)lParam;
+
+ switch (hdr->code)
+ {
+ case NM_RCLICK:
+ {
+ if (hdr->hwndFrom == ListViewWndHandle)
+ ShowStatusMenu(hwndDlg);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID NTAPI MainMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM systemMenu;
+
+ if (menuInfo->u.MainMenu.SubMenuIndex != PH_MENU_ITEM_LOCATION_TOOLS)
+ return;
+
+ if (!(systemMenu = PhFindEMenuItem(menuInfo->Menu, 0, L"System", 0)))
+ {
+ PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, PH_EMENU_SEPARATOR, 0, L"", NULL), -1);
+ PhInsertEMenuItem(menuInfo->Menu, systemMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"System", NULL), -1);
+ }
+
+ PhInsertEMenuItem(systemMenu, PhPluginCreateEMenuItem(PluginInstance, 0, ATOM_TABLE_MENUITEM, L"Atom Table", NULL), -1);
+}
+
+VOID NTAPI MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
+
+ switch (menuItem->Id)
+ {
+ case ATOM_TABLE_MENUITEM:
+ {
+ DialogBox(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_ATOMDIALOG),
+ NULL,
+ MainWindowDlgProc
+ );
+ }
+ break;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"350,350" },
+ { ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|510,380" },
+ { StringSettingType, SETTING_NAME_LISTVIEW_COLUMNS, L"" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->Author = L"dmex";
+ info->DisplayName = L"Global Atom Table";
+ info->Description = L"Plugin for viewing the Global Atom Table via the Tools menu.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
+ MainMenuInitializingCallback,
+ NULL,
+ &MainMenuInitializingCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &PluginMenuItemCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/AtomTablePlugin/resource.h b/plugins-extra/AtomTablePlugin/resource.h
new file mode 100644
index 0000000..9b5de34
--- /dev/null
+++ b/plugins-extra/AtomTablePlugin/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AtomTablePlugin.rc
+//
+#define IDD_ATOMDIALOG 101
+#define IDC_ATOMLIST 1001
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 103
+#endif
+#endif
diff --git a/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.rc b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.rc
new file mode 100644
index 0000000..ae35cac
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.rc
@@ -0,0 +1,100 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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 ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "wj32"
+ VALUE "FileDescription", "Average CPU plugin for Process Hacker"
+ VALUE "FileVersion", "1.1"
+ VALUE "InternalName", "wj32.AvgCpuPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "AvgCpuPlugin.dll"
+ VALUE "ProductName", "Average CPU plugin for Process Hacker"
+ VALUE "ProductVersion", "1.1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj
new file mode 100644
index 0000000..70bb8c0
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj
@@ -0,0 +1,108 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}
+ AvgCpuPlugin
+ Win32Proj
+ AvgCpuPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj.filters b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj.filters
new file mode 100644
index 0000000..a9ee981
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/AvgCpuPlugin.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {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;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/AvgCpuPlugin/CHANGELOG.txt b/plugins-extra/AvgCpuPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..d56c942
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/CHANGELOG.txt
@@ -0,0 +1,5 @@
+1.1
+ * Fixed calculation bug
+
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/AvgCpuPlugin/main.c b/plugins-extra/AvgCpuPlugin/main.c
new file mode 100644
index 0000000..62e7dd9
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/main.c
@@ -0,0 +1,315 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Average CPU Plugin
+ *
+ * Copyright (C) 2011 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
+#include "resource.h"
+
+#define COLUMN_ID_AVGCPU10 1
+#define COLUMN_ID_AVGCPU60 2
+#define HISTORY_SIZE 60
+
+typedef struct _PROCESS_EXTENSION
+{
+ LIST_ENTRY ListEntry;
+ PPH_PROCESS_ITEM ProcessItem;
+
+ FLOAT CpuHistory[HISTORY_SIZE];
+ ULONG CpuHistoryCount;
+ ULONG CpuHistoryPosition;
+
+ FLOAT Avg10CpuUsage;
+ FLOAT Avg60CpuUsage;
+ WCHAR Avg10CpuUsageText[PH_INT32_STR_LEN_1];
+ WCHAR Avg60CpuUsageText[PH_INT32_STR_LEN_1];
+} PROCESS_EXTENSION, *PPROCESS_EXTENSION;
+
+PPH_PLUGIN PluginInstance;
+PH_CALLBACK_REGISTRATION TreeNewMessageCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessTreeNewInitializingCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessAddedCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessRemovedCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
+
+LIST_ENTRY ProcessListHead = { &ProcessListHead, &ProcessListHead };
+
+VOID TreeNewMessageCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
+
+ switch (message->Message)
+ {
+ case TreeNewGetCellText:
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
+ PPH_PROCESS_NODE node;
+ PPROCESS_EXTENSION extension;
+
+ node = (PPH_PROCESS_NODE)getCellText->Node;
+ extension = PhPluginGetObjectExtension(PluginInstance, node->ProcessItem, EmProcessItemType);
+
+ switch (message->SubId)
+ {
+ case COLUMN_ID_AVGCPU10:
+ case COLUMN_ID_AVGCPU60:
+ {
+ FLOAT cpuUsage;
+ PWCHAR buffer;
+
+ if (message->SubId == COLUMN_ID_AVGCPU10)
+ {
+ cpuUsage = extension->Avg10CpuUsage * 100;
+ buffer = extension->Avg10CpuUsageText;
+ }
+ else
+ {
+ cpuUsage = extension->Avg60CpuUsage * 100;
+ buffer = extension->Avg60CpuUsageText;
+ }
+
+ if (cpuUsage >= 0.01)
+ {
+ PH_FORMAT format;
+ SIZE_T returnLength;
+
+ PhInitFormatF(&format, cpuUsage, 2);
+
+ if (PhFormatToBuffer(&format, 1, buffer, PH_INT32_STR_LEN_1 * sizeof(WCHAR), &returnLength))
+ {
+ getCellText->Text.Buffer = buffer;
+ getCellText->Text.Length = (USHORT)(returnLength - sizeof(WCHAR)); // minus null terminator
+ }
+ }
+ else if (cpuUsage != 0 && PhGetIntegerSetting(L"ShowCpuBelow001"))
+ {
+ PhInitializeStringRef(&getCellText->Text, L"< 0.01");
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+}
+
+LONG NTAPI AvgCpuSortFunction(
+ _In_ PVOID Node1,
+ _In_ PVOID Node2,
+ _In_ ULONG SubId,
+ _In_ PVOID Context
+ )
+{
+ PPH_PROCESS_NODE node1 = Node1;
+ PPH_PROCESS_NODE node2 = Node2;
+ PPROCESS_EXTENSION extension1 = PhPluginGetObjectExtension(PluginInstance, node1->ProcessItem, EmProcessItemType);
+ PPROCESS_EXTENSION extension2 = PhPluginGetObjectExtension(PluginInstance, node2->ProcessItem, EmProcessItemType);
+
+ switch (SubId)
+ {
+ case COLUMN_ID_AVGCPU10:
+ return singlecmp(extension1->Avg10CpuUsage, extension2->Avg10CpuUsage);
+ case COLUMN_ID_AVGCPU60:
+ return singlecmp(extension1->Avg60CpuUsage, extension2->Avg60CpuUsage);
+ }
+
+ return 0;
+}
+
+VOID ProcessTreeNewInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_INFORMATION info = Parameter;
+ PH_TREENEW_COLUMN column;
+
+ memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
+ column.SortDescending = TRUE;
+ column.Text = L"CPU Average (10)";
+ column.Width = 45;
+ column.Alignment = PH_ALIGN_RIGHT;
+ column.TextFlags = DT_RIGHT;
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, COLUMN_ID_AVGCPU10, NULL, AvgCpuSortFunction);
+
+ column.Text = L"CPU Average (60)";
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, COLUMN_ID_AVGCPU60, NULL, AvgCpuSortFunction);
+}
+
+VOID ProcessItemCreateCallback(
+ _In_ PVOID Object,
+ _In_ PH_EM_OBJECT_TYPE ObjectType,
+ _In_ PVOID Extension
+ )
+{
+ PPH_PROCESS_ITEM processItem = Object;
+ PPROCESS_EXTENSION extension = Extension;
+
+ memset(extension, 0, sizeof(PROCESS_EXTENSION));
+ extension->ProcessItem = processItem;
+}
+
+VOID ProcessAddedHandler(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PROCESS_ITEM processItem = Parameter;
+ PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, processItem, EmProcessItemType);
+
+ InsertTailList(&ProcessListHead, &extension->ListEntry);
+}
+
+VOID ProcessRemovedHandler(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PROCESS_ITEM processItem = Parameter;
+ PPROCESS_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, processItem, EmProcessItemType);
+
+ RemoveEntryList(&extension->ListEntry);
+}
+
+VOID ProcessesUpdatedHandler(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ static ULONG runCount = 0;
+
+ if (runCount != 0)
+ {
+ PLIST_ENTRY listEntry;
+
+ listEntry = ProcessListHead.Flink;
+
+ while (listEntry != &ProcessListHead)
+ {
+ PPROCESS_EXTENSION extension = CONTAINING_RECORD(listEntry, PROCESS_EXTENSION, ListEntry);
+ PPH_PROCESS_ITEM processItem = extension->ProcessItem;
+ FLOAT sum;
+ ULONG i;
+ ULONG total;
+ ULONG count;
+
+ if (extension->CpuHistoryPosition != 0)
+ extension->CpuHistoryPosition--;
+ else
+ extension->CpuHistoryPosition = HISTORY_SIZE - 1;
+
+ extension->CpuHistory[extension->CpuHistoryPosition] = processItem->CpuUsage;
+
+ if (extension->CpuHistoryCount < HISTORY_SIZE)
+ extension->CpuHistoryCount++;
+
+ // Calculate the 10 interval average.
+
+ sum = 0;
+ i = extension->CpuHistoryPosition;
+ total = 10;
+
+ if (total > extension->CpuHistoryCount)
+ total = extension->CpuHistoryCount;
+
+ count = total;
+
+ do
+ {
+ sum += extension->CpuHistory[i];
+ i++;
+
+ if (i == HISTORY_SIZE)
+ i = 0;
+ } while (--count != 0);
+
+ extension->Avg10CpuUsage = sum / total;
+
+ // Calculate the 60 interval average.
+
+ if (extension->CpuHistoryCount > 10)
+ {
+ total = 50;
+
+ if (total > extension->CpuHistoryCount - 10)
+ total = extension->CpuHistoryCount - 10;
+
+ count = total;
+
+ do
+ {
+ sum += extension->CpuHistory[i];
+ i++;
+
+ if (i == HISTORY_SIZE)
+ i = 0;
+ } while (--count != 0);
+
+ extension->Avg60CpuUsage = sum / (total + 10);
+ }
+ else
+ {
+ // Not enough samples.
+ extension->Avg60CpuUsage = extension->Avg10CpuUsage;
+ }
+
+ listEntry = listEntry->Flink;
+ }
+ }
+
+ runCount++;
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ if (Reason == DLL_PROCESS_ATTACH)
+ {
+ PPH_PLUGIN_INFORMATION info;
+
+ PluginInstance = PhRegisterPlugin(L"wj32.AvgCpuPlugin", Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Average CPU";
+ info->Description = L"Adds a column to display average CPU times.";
+ info->Author = L"wj32";
+
+ PhRegisterCallback(PhGetPluginCallback(PluginInstance, PluginCallbackTreeNewMessage),
+ TreeNewMessageCallback, NULL, &TreeNewMessageCallbackRegistration);
+ PhRegisterCallback(PhGetGeneralCallback(GeneralCallbackProcessTreeNewInitializing),
+ ProcessTreeNewInitializingCallback, NULL, &ProcessTreeNewInitializingCallbackRegistration);
+ PhRegisterCallback(&PhProcessAddedEvent, ProcessAddedHandler, NULL, &ProcessAddedCallbackRegistration);
+ PhRegisterCallback(&PhProcessRemovedEvent, ProcessRemovedHandler, NULL, &ProcessRemovedCallbackRegistration);
+ PhRegisterCallback(&PhProcessesUpdatedEvent, ProcessesUpdatedHandler, NULL, &ProcessesUpdatedCallbackRegistration);
+
+ PhPluginSetObjectExtension(PluginInstance, EmProcessItemType, sizeof(PROCESS_EXTENSION),
+ ProcessItemCreateCallback, NULL);
+ }
+
+ return TRUE;
+}
diff --git a/plugins-extra/AvgCpuPlugin/resource.h b/plugins-extra/AvgCpuPlugin/resource.h
new file mode 100644
index 0000000..823c936
--- /dev/null
+++ b/plugins-extra/AvgCpuPlugin/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AvgCpuPlugin.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins-extra/DbgViewPlugin/CHANGELOG.txt b/plugins-extra/DbgViewPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/DbgViewPlugin.rc b/plugins-extra/DbgViewPlugin/DbgViewPlugin.rc
new file mode 100644
index 0000000..64538c5
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/DbgViewPlugin.rc
@@ -0,0 +1,141 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 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", "DbgView plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "dmex.DbgView"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "DbgViewPlugin.dll"
+ VALUE "ProductName", "DbgView plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DBGVIEW_DIALOG DIALOGEX 0, 0, 343, 181
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Debug View"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "Close",IDCLOSE,286,160,50,14
+ CONTROL "",IDC_DEBUGLISTVIEW,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,5,329,152
+ PUSHBUTTON "Options",IDC_OPTIONS,7,160,50,14
+ CONTROL "Auto-scroll",IDC_AUTOSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,164,50,10
+ CONTROL "Always on Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,219,164,63,10
+END
+
+IDD_MESSAGE_DIALOG DIALOGEX 0, 0, 309, 176
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "Message"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDCLOSE,252,155,50,14
+ EDITTEXT IDC_MESSAGE,7,7,295,145,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL,WS_EX_CLIENTEDGE
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DBGVIEW_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 336
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 174
+ END
+
+ IDD_MESSAGE_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 302
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 169
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj b/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj
new file mode 100644
index 0000000..0478468
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj
@@ -0,0 +1,113 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {AAD42A11-92A7-4918-A76A-862528185199}
+ DbgViewPlugin
+ Win32Proj
+ DbgViewPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj.filters b/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj.filters
new file mode 100644
index 0000000..92b5c51
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/DbgViewPlugin.vcxproj.filters
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+ {f52999d5-d374-492f-b42c-0baf337ae22b}
+
+
+ {b028ae70-b630-49a5-95b3-d9196126eb9a}
+
+
+ {d760553d-e87a-480a-9cbd-4e69599125b8}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/dialog.c b/plugins-extra/DbgViewPlugin/dialog.c
new file mode 100644
index 0000000..39d0279
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/dialog.c
@@ -0,0 +1,694 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+static HANDLE DbgDialogThreadHandle = NULL;
+static HWND DbgDialogHandle = NULL;
+static PH_EVENT InitializedEvent = PH_EVENT_INIT;
+
+VOID NTAPI DbgLoggedEventCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Context;
+
+ if (context->DialogHandle)
+ {
+ PostMessage(context->DialogHandle, WM_DEBUG_LOG_UPDATED, 0, 0);
+ }
+}
+
+VOID DbgUpdateLogList(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ Context->ListViewCount = Context->LogMessageList->Count;
+ ListView_SetItemCountEx(Context->ListViewHandle, Context->ListViewCount, LVSICF_NOSCROLL);
+
+ if (Context->ListViewCount >= 2 && Button_GetCheck(Context->AutoScrollHandle) == BST_CHECKED)
+ {
+ if (ListView_IsItemVisible(Context->ListViewHandle, Context->ListViewCount - 2))
+ {
+ ListView_EnsureVisible(Context->ListViewHandle, Context->ListViewCount - 1, FALSE);
+ }
+ }
+}
+
+PPH_STRING DbgGetStringForSelectedLogEntries(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN All
+ )
+{
+ PH_STRING_BUILDER stringBuilder;
+ ULONG i;
+
+ if (Context->ListViewCount == 0)
+ return PhReferenceEmptyString();
+
+ PhInitializeStringBuilder(&stringBuilder, 0x100);
+
+ i = Context->ListViewCount - 1;
+
+ while (TRUE)
+ {
+ PDEBUG_LOG_ENTRY entry;
+ SYSTEMTIME systemTime;
+ PPH_STRING temp;
+
+ if (!All)
+ {
+ if (!(ListView_GetItemState(Context->ListViewHandle, i, LVIS_SELECTED) & LVIS_SELECTED))
+ {
+ goto ContinueLoop;
+ }
+ }
+
+ entry = Context->LogMessageList->Items[i];
+
+ if (!entry)
+ goto ContinueLoop;
+
+ PhLargeIntegerToLocalSystemTime(&systemTime, &entry->Time);
+ temp = PhFormatDateTime(&systemTime);
+ PhAppendStringBuilder(&stringBuilder, &temp->sr);
+ PhDereferenceObject(temp);
+ PhAppendStringBuilder2(&stringBuilder, L": ");
+
+ temp = PhFormatString(
+ L"%s (%lu): %s",
+ entry->ProcessName->Buffer, // entry->FilePath->Buffer;
+ HandleToUlong(entry->ProcessId),
+ entry->Message->Buffer
+ );
+ PhAppendStringBuilder(&stringBuilder, &temp->sr);
+ PhDereferenceObject(temp);
+ PhAppendStringBuilder2(&stringBuilder, L"\r\n");
+
+ContinueLoop:
+
+ if (i == 0)
+ break;
+
+ i--;
+ }
+
+ return PhFinalStringBuilderString(&stringBuilder);
+}
+
+VOID ShowListViewMenu(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ INT index;
+ PDEBUG_LOG_ENTRY entry;
+
+ index = PhFindListViewItemByFlags(Context->ListViewHandle, -1, LVNI_SELECTED);
+
+ if (index == -1)
+ return;
+
+ entry = Context->LogMessageList->Items[index];
+
+ if (entry)
+ {
+ POINT cursorPos;
+ PPH_EMENU menu;
+ PPH_EMENU_ITEM selectedItem;
+
+ GetCursorPos(&cursorPos);
+
+ menu = PhCreateEMenu();
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"View Message", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 2, L"Go to Owning &Process", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, selectedItem = PhCreateEMenuItem(0, 0, L"E&xclude Process", NULL, NULL), -1);
+ PhInsertEMenuItem(selectedItem, PhCreateEMenuItem(0, 3, L"By PID", NULL, NULL), -1);
+ PhInsertEMenuItem(selectedItem, PhCreateEMenuItem(0, 4, L"By Name", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 5, L"&Copy", NULL, NULL), -1);
+
+ selectedItem = PhShowEMenu(
+ menu,
+ Context->ListViewHandle,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ cursorPos.x,
+ cursorPos.y
+ );
+
+ if (selectedItem && selectedItem->Id != -1)
+ {
+ switch (selectedItem->Id)
+ {
+ case 1:
+ {
+ DialogBoxParam(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_MESSAGE_DIALOG),
+ Context->DialogHandle,
+ DbgPropDlgProc,
+ (LPARAM)entry
+ );
+ }
+ break;
+ case 2:
+ {
+ PPH_PROCESS_NODE processNode;
+
+ if (processNode = PhFindProcessNode(entry->ProcessId))
+ {
+ ProcessHacker_ToggleVisible(PhMainWndHandle, TRUE);
+ ProcessHacker_SelectTabPage(PhMainWndHandle, 0);
+ ProcessHacker_SelectProcessNode(PhMainWndHandle, processNode);
+ }
+ }
+ break;
+ case 3:
+ {
+ AddFilterType(Context, FilterByPid, entry->ProcessId, entry->ProcessName);
+ DbgUpdateLogList(Context);
+ }
+ break;
+ case 4:
+ {
+ AddFilterType(Context, FilterByName, entry->ProcessId, entry->ProcessName);
+ DbgUpdateLogList(Context);
+ }
+ break;
+ case 5:
+ {
+ PPH_STRING string;
+
+ string = DbgGetStringForSelectedLogEntries(Context, FALSE);
+
+ PhSetClipboardString(Context->DialogHandle, &string->sr);
+ PhDereferenceObject(string);
+
+ SetFocus(Context->ListViewHandle);
+ }
+ break;
+ }
+ }
+
+ PhDestroyEMenu(menu);
+ }
+}
+
+VOID ShowDropdownMenu(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ RECT rect;
+ PPH_EMENU menu = NULL;
+ PPH_EMENU_ITEM selectedItem = NULL;
+ PPH_EMENU_ITEM resetMenuItem = NULL;
+ PPH_EMENU_ITEM captureMenuItem = NULL;
+ PPH_EMENU_ITEM captureGlobalMenuItem = NULL;
+
+ GetWindowRect(Context->OptionsHandle, &rect);
+
+ menu = PhCreateEMenu();
+ PhInsertEMenuItem(menu, captureMenuItem = PhCreateEMenuItem(0, ID_CAPTURE_WIN32, L"Capture Win32", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, captureGlobalMenuItem = PhCreateEMenuItem(0, ID_CAPTURE_WIN32_GLOBAL, L"Capture Global Win32", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, resetMenuItem = PhCreateEMenuItem(PH_EMENU_DISABLED, ID_RESET_FILTERS, L"Reset Filters", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_CLEAR_EVENTS, L"Clear", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_SAVE_EVENTS, L"Save", NULL, NULL), -1);
+
+ if (Context->ExcludeList->Count > 0)
+ {
+ resetMenuItem->Text = PhaFormatString(L"Reset Filters [%lu]", Context->ExcludeList->Count)->Buffer;
+ resetMenuItem->Flags &= ~PH_EMENU_DISABLED;
+ }
+
+ if (Context->CaptureLocalEnabled)
+ {
+ captureMenuItem->Flags |= PH_EMENU_CHECKED;
+ }
+
+ if (Context->CaptureGlobalEnabled)
+ {
+ captureGlobalMenuItem->Flags |= PH_EMENU_CHECKED;
+ }
+
+ selectedItem = PhShowEMenu(
+ menu,
+ Context->DialogHandle,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ rect.left,
+ rect.bottom
+ );
+
+ if (selectedItem && selectedItem->Id != -1)
+ {
+ switch (selectedItem->Id)
+ {
+ case ID_CAPTURE_WIN32:
+ {
+ if (!Context->CaptureLocalEnabled)
+ DbgEventsCreate(Context, FALSE);
+ else
+ DbgEventsCleanup(Context, FALSE);
+ }
+ break;
+ case ID_CAPTURE_WIN32_GLOBAL:
+ {
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ PhShowInformation(Context->DialogHandle, L"This option requires elevation.");
+ break;
+ }
+
+ if (!Context->CaptureGlobalEnabled)
+ DbgEventsCreate(Context, TRUE);
+ else
+ DbgEventsCleanup(Context, TRUE);
+ }
+ break;
+ case ID_RESET_FILTERS:
+ {
+ ResetFilters(Context);
+ }
+ break;
+ case ID_CLEAR_EVENTS:
+ {
+ DbgClearLogEntries(Context);
+ DbgUpdateLogList(Context);
+ }
+ break;
+ case ID_SAVE_EVENTS:
+ {
+ static PH_FILETYPE_FILTER filters[] =
+ {
+ { L"Text files (*.txt)", L"*.txt" },
+ { L"All files (*.*)", L"*.*" }
+ };
+
+ PVOID fileDialog = PhCreateSaveFileDialog();
+
+ PhSetFileDialogFilter(fileDialog, filters, ARRAYSIZE(filters));
+ PhSetFileDialogFileName(fileDialog, L"DbgView.txt");
+
+ if (PhShowFileDialog(Context->DialogHandle, fileDialog))
+ {
+ NTSTATUS status;
+ PPH_STRING fileName;
+ PPH_FILE_STREAM fileStream;
+ PPH_STRING string;
+
+ fileName = PhGetFileDialogFileName(fileDialog);
+ PhAutoDereferenceObject(fileName);
+
+ if (NT_SUCCESS(status = PhCreateFileStream(
+ &fileStream,
+ fileName->Buffer,
+ FILE_GENERIC_WRITE,
+ FILE_SHARE_READ,
+ FILE_OVERWRITE_IF,
+ 0
+ )))
+ {
+ PhWritePhTextHeader(fileStream);
+
+ string = DbgGetStringForSelectedLogEntries(Context, TRUE);
+ PhWriteStringAsUtf8FileStreamEx(fileStream, string->Buffer, string->Length);
+ PhDereferenceObject(string);
+
+ PhDereferenceObject(fileStream);
+ }
+
+ if (!NT_SUCCESS(status))
+ PhShowStatus(PhMainWndHandle, L"Unable to create the file", status, 0);
+ }
+
+ PhFreeFileDialog(fileDialog);
+ }
+ break;
+ }
+ }
+
+ PhDestroyEMenu(menu);
+}
+
+INT_PTR CALLBACK DbgViewDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PPH_DBGEVENTS_CONTEXT context;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PPH_DBGEVENTS_CONTEXT)PhAllocate(sizeof(PH_DBGEVENTS_CONTEXT));
+ memset(context, 0, sizeof(PH_DBGEVENTS_CONTEXT));
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PPH_DBGEVENTS_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_NCDESTROY)
+ {
+ RemoveProp(hwndDlg, L"Context");
+ PhFree(context);
+ }
+ }
+
+ if (!context)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ PhCenterWindow(hwndDlg, PhMainWndHandle);
+
+ context->DialogHandle = hwndDlg;
+ context->ListViewHandle = GetDlgItem(hwndDlg, IDC_DEBUGLISTVIEW);
+ context->AutoScrollHandle = GetDlgItem(hwndDlg, IDC_AUTOSCROLL);
+ context->OptionsHandle = GetDlgItem(hwndDlg, IDC_OPTIONS);
+
+ context->LogMessageList = PhCreateList(1);
+ context->ExcludeList = PhCreateList(1);
+
+ PhRegisterDialog(hwndDlg);
+ PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
+ PhSetControlTheme(context->ListViewHandle, L"explorer");
+ PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 140, L"Process");
+ PhAddListViewColumn(context->ListViewHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Timestamp");
+ PhAddListViewColumn(context->ListViewHandle, 2, 2, 2, LVCFMT_LEFT, 220, L"Message");
+ //PhSetExtendedListView(context->ListViewHandle);
+
+ if (context->ListViewImageList = ImageList_Create(19, 19, ILC_COLOR32 | ILC_MASK, 0, 40))
+ {
+ HICON defaultIcon = PhGetFileShellIcon(NULL, L".exe", TRUE);
+ ListView_SetImageList(context->ListViewHandle, context->ListViewImageList, LVSIL_SMALL);
+ ImageList_AddIcon(context->ListViewImageList, defaultIcon);
+ DestroyIcon(defaultIcon);
+ }
+
+ PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
+ PhAddLayoutItem(&context->LayoutManager, context->ListViewHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&context->LayoutManager, context->OptionsHandle, NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&context->LayoutManager, context->AutoScrollHandle, NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDCLOSE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+ PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhLoadListViewColumnsFromSetting(SETTING_NAME_COLUMNS, context->ListViewHandle);
+
+ if (PhGetIntegerSetting(SETTING_NAME_ALWAYSONTOP))
+ {
+ context->AlwaysOnTop = TRUE;
+ SetFocus(hwndDlg);
+ SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);
+ Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALWAYSONTOP), BST_CHECKED);
+ }
+
+ if (PhGetIntegerSetting(SETTING_NAME_AUTOSCROLL))
+ {
+ context->AutoScroll = TRUE;
+ Button_SetCheck(context->AutoScrollHandle, BST_CHECKED);
+ }
+
+ DbgCreateSecurityAttributes(context);
+ DbgUpdateLogList(context);
+
+ PhRegisterCallback(&DbgLoggedCallback, DbgLoggedEventCallback, context, &context->DebugLoggedRegistration);
+ }
+ return TRUE;
+ case WM_DESTROY:
+ {
+ DbgEventsCleanup(context, FALSE);
+ DbgEventsCleanup(context, TRUE);
+ DbgCleanupSecurityAttributes(context);
+
+ if (context->ListViewImageList)
+ ImageList_Destroy(context->ListViewImageList);
+
+ if (context->ExcludeList)
+ {
+ ResetFilters(context);
+ PhDereferenceObject(context->ExcludeList);
+ }
+
+ if (context->LogMessageList)
+ {
+ DbgClearLogEntries(context);
+ PhDereferenceObject(context->LogMessageList);
+ }
+
+ PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhSaveListViewColumnsToSetting(SETTING_NAME_COLUMNS, context->ListViewHandle);
+
+ PhDeleteLayoutManager(&context->LayoutManager);
+
+ PhUnregisterCallback(&DbgLoggedCallback, &context->DebugLoggedRegistration);
+ PhUnregisterDialog(hwndDlg);
+
+ PostQuitMessage(0);
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&context->LayoutManager);
+ break;
+ case WM_SHOWDIALOG:
+ {
+ if (IsMinimized(hwndDlg))
+ ShowWindow(hwndDlg, SW_RESTORE);
+ else
+ ShowWindow(hwndDlg, SW_SHOW);
+
+ SetForegroundWindow(hwndDlg);
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_OPTIONS:
+ ShowDropdownMenu(context);
+ break;
+ case IDCLOSE:
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ case IDC_AUTOSCROLL:
+ {
+ context->AutoScroll = !context->AutoScroll;
+ PhSetIntegerSetting(SETTING_NAME_AUTOSCROLL, context->AutoScroll);
+ Button_SetCheck(context->AutoScrollHandle, context->AutoScroll ? BST_CHECKED : BST_UNCHECKED);
+ }
+ break;
+ case IDC_ALWAYSONTOP:
+ {
+ context->AlwaysOnTop = !context->AlwaysOnTop;
+ SetWindowPos(hwndDlg, context->AlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+ 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ PhSetIntegerSetting(SETTING_NAME_ALWAYSONTOP, context->AlwaysOnTop);
+ }
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR hdr = (LPNMHDR)lParam;
+
+ switch (hdr->code)
+ {
+ case NM_RCLICK:
+ {
+ if (hdr->hwndFrom == context->ListViewHandle)
+ {
+ ShowListViewMenu(context);
+ }
+ }
+ break;
+ case NM_DBLCLK:
+ {
+ PDEBUG_LOG_ENTRY entry;
+ INT index;
+
+ index = PhFindListViewItemByFlags(context->ListViewHandle, -1, LVNI_SELECTED);
+
+ if (index == -1)
+ break;
+
+ entry = context->LogMessageList->Items[index];
+
+ DialogBoxParam(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_MESSAGE_DIALOG),
+ hwndDlg,
+ DbgPropDlgProc,
+ (LPARAM)entry
+ );
+ }
+ break;
+ case LVN_GETDISPINFO:
+ {
+ NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)hdr;
+ PDEBUG_LOG_ENTRY entry;
+
+ entry = context->LogMessageList->Items[dispInfo->item.iItem];
+
+ if (dispInfo->item.mask & LVIF_IMAGE)
+ {
+ dispInfo->item.iImage = entry->ImageIndex;
+ }
+
+ if (dispInfo->item.iSubItem == 0)
+ {
+ if (dispInfo->item.mask & LVIF_TEXT)
+ {
+ wcsncpy_s(
+ dispInfo->item.pszText,
+ dispInfo->item.cchTextMax,
+ entry->ProcessName->Buffer,
+ _TRUNCATE
+ );
+ }
+ }
+ else if (dispInfo->item.iSubItem == 1)
+ {
+ if (dispInfo->item.mask & LVIF_TEXT)
+ {
+ SYSTEMTIME systemTime;
+ PPH_STRING dateTime;
+ PPH_STRING dateString;
+
+ PhLargeIntegerToLocalSystemTime(&systemTime, &entry->Time);
+
+ dateTime = PhFormatTime(&systemTime, L"hh:mm:ss");
+ dateString = PhFormatString(
+ L"%s.%u",
+ dateTime->Buffer,
+ systemTime.wMilliseconds
+ );
+
+ wcsncpy_s(
+ dispInfo->item.pszText,
+ dispInfo->item.cchTextMax,
+ dateString->Buffer,
+ _TRUNCATE
+ );
+
+ PhDereferenceObject(dateString);
+ PhDereferenceObject(dateTime);
+ }
+ }
+ else if (dispInfo->item.iSubItem == 2)
+ {
+ if (dispInfo->item.mask & LVIF_TEXT)
+ {
+ wcsncpy_s(
+ dispInfo->item.pszText,
+ dispInfo->item.cchTextMax,
+ entry->Message->Buffer,
+ _TRUNCATE
+ );
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case WM_DEBUG_LOG_UPDATED:
+ DbgUpdateLogList(context);
+ break;
+ }
+
+ return FALSE;
+}
+
+NTSTATUS DbgViewDialogThread(
+ _In_ PVOID Parameter
+ )
+{
+ BOOL result;
+ MSG message;
+ PH_AUTO_POOL autoPool;
+
+ PhInitializeAutoPool(&autoPool);
+
+ DbgDialogHandle = CreateDialog(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_DBGVIEW_DIALOG),
+ NULL,
+ DbgViewDlgProc
+ );
+
+ PhSetEvent(&InitializedEvent);
+
+ while (result = GetMessage(&message, NULL, 0, 0))
+ {
+ if (result == -1)
+ break;
+
+ if (!IsDialogMessage(DbgDialogHandle, &message))
+ {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ }
+
+ PhDrainAutoPool(&autoPool);
+ }
+
+ PhDeleteAutoPool(&autoPool);
+ PhResetEvent(&InitializedEvent);
+
+ if (DbgDialogThreadHandle)
+ {
+ NtClose(DbgDialogThreadHandle);
+ DbgDialogThreadHandle = NULL;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID ShowDebugEventsDialog(
+ VOID
+ )
+{
+ if (!DbgDialogThreadHandle)
+ {
+ if (!(DbgDialogThreadHandle = PhCreateThread(0, DbgViewDialogThread, NULL)))
+ {
+ PhShowStatus(PhMainWndHandle, L"Unable to create the window.", 0, GetLastError());
+ return;
+ }
+
+ PhWaitForEvent(&InitializedEvent, NULL);
+ }
+
+ PostMessage(DbgDialogHandle, WM_SHOWDIALOG, 0, 0);
+}
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/filter.c b/plugins-extra/DbgViewPlugin/filter.c
new file mode 100644
index 0000000..c2466c5
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/filter.c
@@ -0,0 +1,81 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+VOID AddFilterType(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ FILTER_BY_TYPE Type,
+ _In_ HANDLE ProcessID,
+ _In_ PPH_STRING ProcessName
+ )
+{
+ PDBG_FILTER_TYPE newFilterEntry;
+
+ newFilterEntry = PhAllocate(sizeof(DBG_FILTER_TYPE));
+ newFilterEntry->Type = Type;
+ newFilterEntry->ProcessId = ProcessID;
+ newFilterEntry->ProcessName = ProcessName;
+
+ PhAddItemList(Context->ExcludeList, newFilterEntry);
+
+ // Remove any existing entries...
+ for (ULONG i = 0; i < Context->LogMessageList->Count; i++)
+ {
+ PDEBUG_LOG_ENTRY listEntry = Context->LogMessageList->Items[i];
+
+ if (Type == FilterByName)
+ {
+ if (PhEqualString(listEntry->ProcessName, newFilterEntry->ProcessName, TRUE))
+ {
+ PhRemoveItemList(Context->LogMessageList, i);
+ i--;
+ }
+ }
+ else if (Type == FilterByPid)
+ {
+ if (listEntry->ProcessId == ProcessID)
+ {
+ PhRemoveItemList(Context->LogMessageList, i);
+ i--;
+ }
+ }
+ }
+}
+
+VOID ResetFilters(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ for (ULONG i = 0; i < Context->ExcludeList->Count; i++)
+ {
+ PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i];
+
+ if (filterEntry->ProcessName)
+ PhDereferenceObject(filterEntry->ProcessName);
+
+ PhFree(filterEntry);
+
+ PhRemoveItemList(Context->ExcludeList, i);
+ i--;
+ }
+}
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/log.c b/plugins-extra/DbgViewPlugin/log.c
new file mode 100644
index 0000000..52034b7
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/log.c
@@ -0,0 +1,495 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+PH_CALLBACK_DECLARE(DbgLoggedCallback);
+
+VOID DbgFreeLogEntry(
+ _Inout_ PDEBUG_LOG_ENTRY Entry
+ )
+{
+ PhClearReference(&Entry->FilePath);
+ PhClearReference(&Entry->ProcessName);
+ PhClearReference(&Entry->Message);
+
+ PhFree(Entry);
+}
+
+VOID DbgAddLogEntry(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ PDEBUG_LOG_ENTRY Entry
+ )
+{
+ if (Context->LogMessageList->Count > PhGetIntegerSetting(SETTING_NAME_MAX_ENTRIES))
+ {
+ DbgFreeLogEntry(Context->LogMessageList->Items[0]);
+ PhRemoveItemList(Context->LogMessageList, 0);
+ }
+
+ PhAddItemList(Context->LogMessageList, Entry);
+ PhInvokeCallback(&DbgLoggedCallback, Entry);
+}
+
+VOID DbgClearLogEntries(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ for (ULONG i = 0; i < Context->LogMessageList->Count; i++)
+ {
+ if (Context->LogMessageList->Items[i])
+ {
+ DbgFreeLogEntry(Context->LogMessageList->Items[i]);
+ }
+ }
+
+ PhClearList(Context->LogMessageList);
+}
+
+VOID DbgShowErrorMessage(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ PWSTR Type
+ )
+{
+ ULONG errorCode = GetLastError();
+ PPH_STRING errorMessage = PhGetWin32Message(errorCode);
+
+ if (errorMessage)
+ {
+ PhShowError(Context->DialogHandle, PhaFormatString(L"%s: [%u] %s", Type, errorCode, errorMessage->Buffer)->Buffer);
+ PhDereferenceObject(errorMessage);
+ }
+}
+
+VOID DbgFormatObjectName(
+ _In_ BOOLEAN LocalName,
+ _In_ PWSTR OriginalName,
+ _Out_ PUNICODE_STRING ObjectName
+ )
+{
+ SIZE_T length;
+ SIZE_T originalNameLength;
+
+ // Sessions other than session 0 require SeCreateGlobalPrivilege.
+ if (LocalName && NtCurrentPeb()->SessionId != 0)
+ {
+ WCHAR buffer[256] = L"";
+
+ memcpy(buffer, L"\\Sessions\\", 10 * sizeof(WCHAR));
+ _ultow(NtCurrentPeb()->SessionId, buffer + 10, 10);
+ length = PhCountStringZ(buffer);
+ originalNameLength = PhCountStringZ(OriginalName);
+ memcpy(buffer + length, OriginalName, (originalNameLength + 1) * sizeof(WCHAR));
+ length += originalNameLength;
+
+ ObjectName->Buffer = buffer;
+ ObjectName->MaximumLength = (ObjectName->Length = (USHORT)(length * sizeof(WCHAR))) + sizeof(WCHAR);
+ }
+ else
+ {
+ RtlInitUnicodeString(ObjectName, OriginalName);
+ }
+}
+
+VOID DbgProcessLogMessageEntry(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN GlobalEvents
+ )
+{
+ NTSTATUS status;
+ PDBWIN_PAGE_BUFFER debugMessageBuffer;
+ PDEBUG_LOG_ENTRY entry = NULL;
+ HANDLE processHandle = NULL;
+ PPH_STRING fileName = NULL;
+ HICON icon = NULL;
+
+ debugMessageBuffer = GlobalEvents ? Context->GlobalDebugBuffer : Context->LocalDebugBuffer;
+
+ entry = PhAllocate(sizeof(DEBUG_LOG_ENTRY));
+ memset(entry, 0, sizeof(DEBUG_LOG_ENTRY));
+
+ PhQuerySystemTime(&entry->Time);
+ entry->ProcessId = UlongToHandle(debugMessageBuffer->ProcessId);
+ entry->Message = PhConvertMultiByteToUtf16(debugMessageBuffer->Buffer);
+
+ if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID)
+ {
+ status = PhGetProcessImageFileNameByProcessId(entry->ProcessId, &fileName);
+ }
+ else
+ {
+ if (NT_SUCCESS(status = PhOpenProcess(&processHandle, ProcessQueryAccess, entry->ProcessId)))
+ {
+ status = PhGetProcessImageFileName(processHandle, &fileName);
+ NtClose(processHandle);
+ }
+ }
+
+ if (!NT_SUCCESS(status))
+ fileName = PhGetKernelFileName();
+
+ PhMoveReference(&fileName, PhGetFileName(fileName));
+
+ icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", TRUE);
+
+ if (icon)
+ {
+ entry->ImageIndex = ImageList_AddIcon(Context->ListViewImageList, icon);
+ DestroyIcon(icon);
+ }
+
+ entry->FilePath = fileName;
+ entry->ProcessName = PhGetBaseName(fileName);
+
+ // Drop event if it matches a filter
+ for (ULONG i = 0; i < Context->ExcludeList->Count; i++)
+ {
+ PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i];
+
+ if (filterEntry->Type == FilterByName)
+ {
+ if (PhEqualString(filterEntry->ProcessName, entry->ProcessName, TRUE))
+ {
+ DbgFreeLogEntry(entry);
+ return;
+ }
+ }
+ else if (filterEntry->Type == FilterByPid)
+ {
+ if (filterEntry->ProcessId == entry->ProcessId)
+ {
+ DbgFreeLogEntry(entry);
+ return;
+ }
+ }
+ }
+
+ DbgAddLogEntry(Context, entry);
+}
+
+NTSTATUS DbgEventsLocalThread(
+ _In_ PVOID Parameter
+ )
+{
+ LARGE_INTEGER timeout;
+ NTSTATUS status;
+ PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Parameter;
+
+ while (TRUE)
+ {
+ NtSetEvent(context->LocalBufferReadyEvent, NULL);
+
+ status = NtWaitForSingleObject(
+ context->LocalDataReadyEvent,
+ FALSE,
+ PhTimeoutFromMilliseconds(&timeout, 100)
+ );
+
+ if (status == STATUS_TIMEOUT)
+ continue;
+ if (status != STATUS_SUCCESS)
+ break;
+
+ // The process calling OutputDebugString is blocked here...
+ // This gives us some time to extract information without the process exiting.
+ DbgProcessLogMessageEntry(context, FALSE);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS DbgEventsGlobalThread(
+ _In_ PVOID Parameter
+ )
+{
+ LARGE_INTEGER timeout;
+ NTSTATUS status;
+ PPH_DBGEVENTS_CONTEXT context = (PPH_DBGEVENTS_CONTEXT)Parameter;
+
+ while (TRUE)
+ {
+ NtSetEvent(context->GlobalBufferReadyEvent, NULL);
+
+ status = NtWaitForSingleObject(
+ context->GlobalDataReadyEvent,
+ FALSE,
+ PhTimeoutFromMilliseconds(&timeout, 100)
+ );
+
+ if (status == STATUS_TIMEOUT)
+ continue;
+ if (status != STATUS_SUCCESS)
+ break;
+
+ // The process calling OutputDebugString is blocked here...
+ // This gives us some time to extract information without the process exiting.
+ DbgProcessLogMessageEntry(context, TRUE);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN DbgCreateSecurityAttributes(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ Context->SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ Context->SecurityAttributes.bInheritHandle = TRUE;
+
+ if (ConvertStringSecurityDescriptorToSecurityDescriptor(
+ L"D:(A;;GRGWGX;;;WD)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGWGX;;;AN)(A;;GRGWGX;;;RC)(A;;GRGWGX;;;S-1-15-2-1)S:(ML;;NW;;;LW)",
+ SDDL_REVISION,
+ &Context->SecurityAttributes.lpSecurityDescriptor,
+ NULL
+ ))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN DbgCleanupSecurityAttributes(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ )
+{
+ if (Context->SecurityAttributes.lpSecurityDescriptor)
+ {
+ LocalFree(Context->SecurityAttributes.lpSecurityDescriptor);
+ Context->SecurityAttributes.lpSecurityDescriptor = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN DbgEventsCreate(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN GlobalEvents
+ )
+{
+ if (GlobalEvents)
+ {
+ SIZE_T viewSize;
+ LARGE_INTEGER maximumSize;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING objectName;
+ HANDLE threadHandle = NULL;
+
+ maximumSize.QuadPart = PAGE_SIZE;
+ viewSize = sizeof(DBWIN_PAGE_BUFFER);
+
+ if (!(Context->GlobalBufferReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Global\\" DBWIN_BUFFER_READY)))
+ {
+ DbgShowErrorMessage(Context, L"DBWIN_BUFFER_READY");
+ return FALSE;
+ }
+
+ if (!(Context->GlobalDataReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Global\\" DBWIN_DATA_READY)))
+ {
+ DbgShowErrorMessage(Context, L"DBWIN_DATA_READY");
+ return FALSE;
+ }
+
+ DbgFormatObjectName(FALSE, DBWIN_BUFFER_SECTION_NAME, &objectName);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &objectName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ Context->SecurityAttributes.lpSecurityDescriptor
+ );
+
+ if (!NT_SUCCESS(NtCreateSection(
+ &Context->GlobalDataBufferHandle,
+ STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
+ &objectAttributes,
+ &maximumSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL
+ )))
+ {
+ DbgShowErrorMessage(Context, L"NtCreateSection");
+ return FALSE;
+ }
+
+ if (!NT_SUCCESS(NtMapViewOfSection(
+ Context->GlobalDataBufferHandle,
+ NtCurrentProcess(),
+ &Context->GlobalDebugBuffer,
+ 0,
+ 0,
+ NULL,
+ &viewSize,
+ ViewShare,
+ 0,
+ PAGE_READONLY
+ )))
+ {
+ DbgShowErrorMessage(Context, L"NtMapViewOfSection");
+ return FALSE;
+ }
+
+ Context->CaptureGlobalEnabled = TRUE;
+
+ if (threadHandle = PhCreateThread(0, DbgEventsGlobalThread, Context))
+ {
+ NtClose(threadHandle);
+ }
+ }
+ else
+ {
+ SIZE_T viewSize;
+ LARGE_INTEGER maximumSize;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING objectName;
+ HANDLE threadHandle = NULL;
+
+ maximumSize.QuadPart = PAGE_SIZE;
+ viewSize = sizeof(DBWIN_PAGE_BUFFER);
+
+ if (!(Context->LocalBufferReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Local\\" DBWIN_BUFFER_READY)))
+ {
+ DbgShowErrorMessage(Context, L"DBWIN_BUFFER_READY");
+ return FALSE;
+ }
+
+ if (!(Context->LocalDataReadyEvent = CreateEvent(&Context->SecurityAttributes, FALSE, FALSE, L"Local\\" DBWIN_DATA_READY)))
+ {
+ DbgShowErrorMessage(Context, L"DBWIN_DATA_READY");
+ return FALSE;
+ }
+
+ DbgFormatObjectName(TRUE, DBWIN_BUFFER_SECTION_NAME, &objectName);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &objectName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ Context->SecurityAttributes.lpSecurityDescriptor
+ );
+
+ if (!NT_SUCCESS(NtCreateSection(
+ &Context->LocalDataBufferHandle,
+ STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
+ &objectAttributes,
+ &maximumSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL
+ )))
+ {
+ DbgShowErrorMessage(Context, L"NtCreateSection");
+ return FALSE;
+ }
+
+ if (!NT_SUCCESS(NtMapViewOfSection(
+ Context->LocalDataBufferHandle,
+ NtCurrentProcess(),
+ &Context->LocalDebugBuffer,
+ 0,
+ 0,
+ NULL,
+ &viewSize,
+ ViewShare,
+ 0,
+ PAGE_READONLY
+ )))
+ {
+ DbgShowErrorMessage(Context, L"NtMapViewOfSection");
+ return FALSE;
+ }
+
+ Context->CaptureLocalEnabled = TRUE;
+
+ if (threadHandle = PhCreateThread(0, DbgEventsLocalThread, Context))
+ {
+ NtClose(threadHandle);
+ }
+ }
+
+ return TRUE;
+}
+
+VOID DbgEventsCleanup(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN CleanupGlobal
+ )
+{
+ if (CleanupGlobal)
+ {
+ Context->CaptureGlobalEnabled = FALSE;
+
+ if (Context->GlobalDebugBuffer)
+ {
+ NtUnmapViewOfSection(NtCurrentProcess(), Context->GlobalDebugBuffer);
+ Context->GlobalDebugBuffer = NULL;
+ }
+
+ if (Context->GlobalDataBufferHandle)
+ {
+ NtClose(Context->GlobalDataBufferHandle);
+ Context->GlobalDataBufferHandle = NULL;
+ }
+
+ if (Context->GlobalBufferReadyEvent)
+ {
+ NtClose(Context->GlobalBufferReadyEvent);
+ Context->GlobalBufferReadyEvent = NULL;
+ }
+
+ if (Context->GlobalDataReadyEvent)
+ {
+ NtClose(Context->GlobalDataReadyEvent);
+ Context->GlobalDataReadyEvent = NULL;
+ }
+ }
+ else
+ {
+ Context->CaptureLocalEnabled = FALSE;
+
+ if (Context->LocalDebugBuffer)
+ {
+ NtUnmapViewOfSection(NtCurrentProcess(), Context->LocalDebugBuffer);
+ Context->LocalDebugBuffer = NULL;
+ }
+
+ if (Context->LocalDataBufferHandle)
+ {
+ NtClose(Context->LocalDataBufferHandle);
+ Context->LocalDataBufferHandle = NULL;
+ }
+
+ if (Context->LocalBufferReadyEvent)
+ {
+ NtClose(Context->LocalBufferReadyEvent);
+ Context->LocalBufferReadyEvent = NULL;
+ }
+
+ if (Context->LocalDataReadyEvent)
+ {
+ NtClose(Context->LocalDataReadyEvent);
+ Context->LocalDataReadyEvent = NULL;
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/main.c b/plugins-extra/DbgViewPlugin/main.c
new file mode 100644
index 0000000..1c79571
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/main.c
@@ -0,0 +1,115 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+PPH_PLUGIN PluginInstance;
+static PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
+static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
+
+VOID NTAPI MainMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM systemMenu;
+ PPH_EMENU_ITEM bootMenuItem;
+
+ if (menuInfo->u.MainMenu.SubMenuIndex != PH_MENU_ITEM_LOCATION_TOOLS)
+ return;
+
+ if (!(systemMenu = PhFindEMenuItem(menuInfo->Menu, 0, L"System", 0)))
+ {
+ PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, PH_EMENU_SEPARATOR, 0, L"", NULL), -1);
+ PhInsertEMenuItem(menuInfo->Menu, systemMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"System", NULL), -1);
+ }
+
+ PhInsertEMenuItem(systemMenu, bootMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, DBGVIEW_MENUITEM, L"Debug View", NULL), -1);
+}
+
+VOID NTAPI MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
+
+ switch (menuItem->Id)
+ {
+ case DBGVIEW_MENUITEM:
+ ShowDebugEventsDialog();
+ break;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"350,350" },
+ { ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|510,380" },
+ { StringSettingType, SETTING_NAME_COLUMNS, L"" },
+ { IntegerSettingType, SETTING_NAME_ALWAYSONTOP, L"0" },
+ { IntegerSettingType, SETTING_NAME_AUTOSCROLL, L"1" },
+ { IntegerSettingType, SETTING_NAME_MAX_ENTRIES, L"2048" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Debug View";
+ info->Author = L"dmex";
+ info->Description = L"Plugin for viewing Win32 debug output via the Tools menu.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
+ MainMenuInitializingCallback,
+ NULL,
+ &MainMenuInitializingCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &PluginMenuItemCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/main.h b/plugins-extra/DbgViewPlugin/main.h
new file mode 100644
index 0000000..56e40a0
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/main.h
@@ -0,0 +1,178 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#ifndef _DBG_H_
+#define _DBG_H_
+
+#define PLUGIN_NAME L"dmex.DbgView"
+#define SETTING_NAME_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
+#define SETTING_NAME_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
+#define SETTING_NAME_COLUMNS (PLUGIN_NAME L".WindowColumns")
+#define SETTING_NAME_ALWAYSONTOP (PLUGIN_NAME L".AlwaysOnTop")
+#define SETTING_NAME_AUTOSCROLL (PLUGIN_NAME L".AutoScroll")
+#define SETTING_NAME_MAX_ENTRIES (PLUGIN_NAME L".MaxEntries")
+
+#define DBGVIEW_MENUITEM 1000
+#define WM_SHOWDIALOG (WM_APP + 100)
+#define WM_DEBUG_LOG_UPDATED (WM_APP + 101)
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+
+#define DBWIN_BUFFER_READY L"DBWIN_BUFFER_READY"
+#define DBWIN_DATA_READY L"DBWIN_DATA_READY"
+#define DBWIN_BUFFER L"DBWIN_BUFFER"
+
+#define DBWIN_BUFFER_READY_OBJECT_NAME L"\\BaseNamedObjects\\DBWIN_BUFFER_READY"
+#define DBWIN_DATA_READY_OBJECT_NAME L"\\BaseNamedObjects\\DBWIN_DATA_READY"
+#define DBWIN_BUFFER_SECTION_NAME L"\\BaseNamedObjects\\DBWIN_BUFFER"
+
+// The Win32 OutputDebugString buffer.
+typedef struct _DBWIN_PAGE_BUFFER
+{
+ ULONG ProcessId; /** The ID of the process. */
+ CHAR Buffer[PAGE_SIZE - sizeof(ULONG)]; /** The buffer containing the debug message. */
+} DBWIN_PAGE_BUFFER, *PDBWIN_PAGE_BUFFER;
+
+extern PPH_PLUGIN PluginInstance;
+extern PH_CALLBACK DbgLoggedCallback;
+
+typedef enum _FILTER_BY_TYPE
+{
+ FilterByUnknown,
+ FilterByPid,
+ FilterByName
+} FILTER_BY_TYPE;
+
+typedef struct _DBG_FILTER_TYPE
+{
+ FILTER_BY_TYPE Type;
+ HANDLE ProcessId;
+ PPH_STRING ProcessName;
+} DBG_FILTER_TYPE, *PDBG_FILTER_TYPE;
+
+typedef enum _COMMAND_ID
+{
+ ID_CAPTURE_WIN32 = 1,
+ ID_CAPTURE_WIN32_GLOBAL,
+ ID_RESET_FILTERS,
+ ID_CLEAR_EVENTS,
+ ID_SAVE_EVENTS,
+} COMMAND_ID;
+
+typedef struct _PH_DBGEVENTS_CONTEXT
+{
+ BOOLEAN AlwaysOnTop;
+ BOOLEAN AutoScroll;
+ BOOLEAN CaptureLocalEnabled;
+ BOOLEAN CaptureGlobalEnabled;
+
+ ULONG ListViewCount;
+
+ HWND DialogHandle;
+ HWND ListViewHandle;
+ HWND AutoScrollHandle;
+ HWND OptionsHandle;
+ HIMAGELIST ListViewImageList;
+
+ PH_LAYOUT_MANAGER LayoutManager;
+ PH_CALLBACK_REGISTRATION DebugLoggedRegistration;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ PPH_LIST ExcludeList;
+ PPH_LIST LogMessageList;
+
+ HANDLE LocalBufferReadyEvent;
+ HANDLE LocalDataReadyEvent;
+ HANDLE LocalDataBufferHandle;
+ PDBWIN_PAGE_BUFFER LocalDebugBuffer;
+ HANDLE GlobalBufferReadyEvent;
+ HANDLE GlobalDataReadyEvent;
+ HANDLE GlobalDataBufferHandle;
+ PDBWIN_PAGE_BUFFER GlobalDebugBuffer;
+} PH_DBGEVENTS_CONTEXT, *PPH_DBGEVENTS_CONTEXT;
+
+typedef struct _DEBUG_LOG_ENTRY
+{
+ INT ImageIndex;
+ LARGE_INTEGER Time;
+ HANDLE ProcessId;
+ PPH_STRING Message;
+ PPH_STRING ProcessName;
+ PPH_STRING FilePath;
+} DEBUG_LOG_ENTRY, *PDEBUG_LOG_ENTRY;
+
+INT_PTR CALLBACK DbgPropDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+VOID ShowDebugEventsDialog(
+ VOID
+ );
+
+// log.c
+
+VOID DbgClearLogEntries(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ );
+
+BOOLEAN DbgCreateSecurityAttributes(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ );
+
+BOOLEAN DbgCleanupSecurityAttributes(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ );
+
+BOOLEAN DbgEventsCreate(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN GlobalEvents
+ );
+
+VOID DbgEventsCleanup(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ BOOLEAN CleanupGlobal
+ );
+
+// Filter.c
+
+VOID AddFilterType(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context,
+ _In_ FILTER_BY_TYPE Type,
+ _In_ HANDLE ProcessID,
+ _In_ PPH_STRING ProcessName
+ );
+
+VOID ResetFilters(
+ _Inout_ PPH_DBGEVENTS_CONTEXT Context
+ );
+
+#endif
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/message.c b/plugins-extra/DbgViewPlugin/message.c
new file mode 100644
index 0000000..47a4349
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/message.c
@@ -0,0 +1,87 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Debug View Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+static PH_LAYOUT_MANAGER LayoutManager;
+
+INT_PTR CALLBACK DbgPropDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ PDEBUG_LOG_ENTRY entry = (PDEBUG_LOG_ENTRY)lParam;
+
+ PhCenterWindow(hwndDlg, GetParent(hwndDlg));
+
+ PhInitializeLayoutManager(&LayoutManager, hwndDlg);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_MESSAGE), NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDCLOSE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+
+ Edit_SetText(GetDlgItem(hwndDlg, IDC_MESSAGE), entry->Message->Buffer);
+ //SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGE), WM_SETFONT, (WPARAM)PhApplicationFont, FALSE);
+ }
+ return TRUE;
+ case WM_DESTROY:
+ PhDeleteLayoutManager(&LayoutManager);
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&LayoutManager);
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ case IDCLOSE:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ }
+ }
+ break;
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORDLG:
+ case WM_CTLCOLORSTATIC:
+ {
+ HDC hDC = (HDC)wParam;
+ HWND hwndChild = (HWND)lParam;
+
+ // Check for our static label and change the color.
+ if (GetDlgCtrlID(hwndChild) == IDC_MESSAGE)
+ {
+ SetBkMode(hDC, TRANSPARENT);
+
+ // set window background color.
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
\ No newline at end of file
diff --git a/plugins-extra/DbgViewPlugin/resource.h b/plugins-extra/DbgViewPlugin/resource.h
new file mode 100644
index 0000000..9f7a807
--- /dev/null
+++ b/plugins-extra/DbgViewPlugin/resource.h
@@ -0,0 +1,22 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by DbgViewPlugin.rc
+//
+#define IDD_DBGVIEW_DIALOG 101
+#define IDD_MESSAGE_DIALOG 103
+#define IDC_DEBUGLISTVIEW 1001
+#define IDC_MESSAGE 1002
+#define IDC_OPTIONS 1003
+#define IDC_AUTOSCROLL 1004
+#define IDC_ALWAYSONTOP 1005
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1006
+#define _APS_NEXT_SYMED_VALUE 105
+#endif
+#endif
diff --git a/plugins-extra/DnsCachePlugin/CHANGELOG.txt b/plugins-extra/DnsCachePlugin/CHANGELOG.txt
new file mode 100644
index 0000000..18d7d78
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/CHANGELOG.txt
@@ -0,0 +1,4 @@
+1.0
+ * Initial release
+
+
diff --git a/plugins-extra/DnsCachePlugin/DnsCachePlugin.rc b/plugins-extra/DnsCachePlugin/DnsCachePlugin.rc
new file mode 100644
index 0000000..a1bc465
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/DnsCachePlugin.rc
@@ -0,0 +1,123 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DNSVIEW DIALOGEX 0, 0, 325, 181
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "DNS Resolver Cache"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,269,160,50,14
+ CONTROL "",IDC_DNSLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,5,312,152
+ PUSHBUTTON "Refresh",IDC_DNS_REFRESH,7,160,50,14
+ PUSHBUTTON "Flush",IDC_DNS_CLEAR,62,160,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DNSVIEW, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 318
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 174
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "DnsCachePlugin plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "dmex.DnsCachePlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "DnsCachePlugin.dll"
+ VALUE "ProductName", "DnsCachePlugin plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj b/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj
new file mode 100644
index 0000000..bb31cc5
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj
@@ -0,0 +1,125 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}
+ DnsCachePlugin
+ Win32Proj
+ DnsCachePlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ dnsapi.lib;%(AdditionalDependencies)
+ dnsapi.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ dnsapi.lib;%(AdditionalDependencies)
+ dnsapi.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ dnsapi.lib;%(AdditionalDependencies)
+ dnsapi.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ dnsapi.lib;%(AdditionalDependencies)
+ dnsapi.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj.filters b/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj.filters
new file mode 100644
index 0000000..472d8e4
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/DnsCachePlugin.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ {f52999d5-d374-492f-b42c-0baf337ae22b}
+
+
+ {b028ae70-b630-49a5-95b3-d9196126eb9a}
+
+
+ {d760553d-e87a-480a-9cbd-4e69599125b8}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/DnsCachePlugin/main.c b/plugins-extra/DnsCachePlugin/main.c
new file mode 100644
index 0000000..ece5d1d
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/main.c
@@ -0,0 +1,434 @@
+/*
+ * Process Hacker Extra Plugins -
+ * DNS Cache Plugin
+ *
+ * Copyright (C) 2014 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 "main.h"
+
+static HINSTANCE DnsApiHandle = NULL;
+static _DnsGetCacheDataTable DnsGetCacheDataTable_I = NULL;
+static _DnsFlushResolverCache DnsFlushResolverCache_I = NULL;
+static _DnsFlushResolverCacheEntry DnsFlushResolverCacheEntry_I = NULL;
+
+static HWND ListViewWndHandle;
+static PH_LAYOUT_MANAGER LayoutManager;
+static PPH_PLUGIN PluginInstance;
+static PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
+static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+
+VOID EnumDnsCacheTable(
+ _In_ HWND hwndDlg
+ )
+{
+ PDNS_CACHE_ENTRY dnsCacheDataTable = NULL;
+
+ __try
+ {
+ if (!DnsGetCacheDataTable_I(&dnsCacheDataTable))
+ __leave;
+
+ while (dnsCacheDataTable)
+ {
+ PDNS_RECORD dnsQueryResultPtr = NULL;
+
+ DNS_STATUS dnsStatus = DnsQuery(
+ dnsCacheDataTable->Name,
+ dnsCacheDataTable->Type,
+ DNS_QUERY_NO_WIRE_QUERY | 32768, // Undocumented flags
+ NULL,
+ &dnsQueryResultPtr,
+ NULL
+ );
+
+ if (dnsStatus == ERROR_SUCCESS)
+ {
+ PDNS_RECORD dnsRecordPtr = dnsQueryResultPtr;
+
+ while (dnsRecordPtr)
+ {
+ INT itemIndex = MAXINT;
+ ULONG ipAddrStringLength = INET6_ADDRSTRLEN;
+ TCHAR ipAddrString[INET6_ADDRSTRLEN] = L"";
+
+ itemIndex = PhAddListViewItem(hwndDlg, MAXINT,
+ PhaFormatString(L"%s", dnsCacheDataTable->Name)->Buffer,
+ NULL
+ );
+
+ if (dnsRecordPtr->wType == DNS_TYPE_A)
+ {
+ IN_ADDR ipv4Address = { 0 };
+
+ ipv4Address.s_addr = dnsRecordPtr->Data.A.IpAddress;
+
+ RtlIpv4AddressToString(&ipv4Address, ipAddrString);
+
+ PhSetListViewSubItem(hwndDlg, itemIndex, 1, PhaFormatString(L"A")->Buffer);
+ PhSetListViewSubItem(hwndDlg, itemIndex, 2, PhaFormatString(L"%s", ipAddrString)->Buffer);
+ }
+ else if (dnsRecordPtr->wType == DNS_TYPE_AAAA)
+ {
+ IN6_ADDR ipv6Address = { 0 };
+
+ memcpy_s(
+ ipv6Address.s6_addr,
+ sizeof(ipv6Address.s6_addr),
+ dnsRecordPtr->Data.AAAA.Ip6Address.IP6Byte,
+ sizeof(dnsRecordPtr->Data.AAAA.Ip6Address.IP6Byte)
+ );
+
+ RtlIpv6AddressToString(&ipv6Address, ipAddrString);
+
+ PhSetListViewSubItem(hwndDlg, itemIndex, 1, PhaFormatString(L"AAAA")->Buffer);
+ PhSetListViewSubItem(hwndDlg, itemIndex, 2, PhaFormatString(L"%s", ipAddrString)->Buffer);
+ }
+ else if (dnsRecordPtr->wType == DNS_TYPE_PTR)
+ {
+ PhSetListViewSubItem(hwndDlg, itemIndex, 1, PhaFormatString(L"PTR")->Buffer);
+ PhSetListViewSubItem(hwndDlg, itemIndex, 2, PhaFormatString(L"%s", dnsRecordPtr->Data.PTR.pNameHost)->Buffer);
+ }
+ else if (dnsRecordPtr->wType == DNS_TYPE_CNAME)
+ {
+ PhSetListViewSubItem(hwndDlg, itemIndex, 1, PhaFormatString(L"CNAME")->Buffer);
+ PhSetListViewSubItem(hwndDlg, itemIndex, 2, PhaFormatString(L"%s", dnsRecordPtr->Data.CNAME.pNameHost)->Buffer);
+ }
+ else
+ {
+ PhSetListViewSubItem(hwndDlg, itemIndex, 1, PhaFormatString(L"UNKNOWN")->Buffer);
+ PhSetListViewSubItem(hwndDlg, itemIndex, 2, PhaFormatString(L"")->Buffer);
+ }
+
+ PhSetListViewSubItem(hwndDlg, itemIndex, 3, PhaFormatString(L"%lu", dnsRecordPtr->dwTtl)->Buffer);
+
+ dnsRecordPtr = dnsRecordPtr->pNext;
+ }
+
+ DnsRecordListFree(dnsQueryResultPtr, DnsFreeRecordList);
+ }
+
+ dnsCacheDataTable = dnsCacheDataTable->Next;
+ }
+ }
+ __finally
+ {
+ if (dnsCacheDataTable)
+ {
+ DnsRecordListFree(dnsCacheDataTable, DnsFreeRecordList);
+ }
+ }
+}
+
+PPH_STRING PhGetSelectedListViewItemText(
+ _In_ HWND hWnd
+ )
+{
+ INT index = PhFindListViewItemByFlags(
+ hWnd,
+ -1,
+ LVNI_SELECTED
+ );
+
+ if (index != -1)
+ {
+ WCHAR textBuffer[MAX_PATH] = L"";
+
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.iSubItem = 0;
+ item.pszText = textBuffer;
+ item.cchTextMax = ARRAYSIZE(textBuffer);
+
+ if (ListView_GetItem(hWnd, &item))
+ return PhCreateString(textBuffer);
+ }
+
+ return NULL;
+}
+
+VOID ShowStatusMenu(
+ _In_ HWND hwndDlg
+ )
+{
+ PPH_STRING cacheEntryName;
+
+ cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle);
+
+ if (cacheEntryName)
+ {
+ POINT cursorPos;
+ PPH_EMENU menu;
+ PPH_EMENU_ITEM selectedItem;
+
+ GetCursorPos(&cursorPos);
+
+ menu = PhCreateEMenu();
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1);
+
+ selectedItem = PhShowEMenu(
+ menu,
+ PhMainWndHandle,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ cursorPos.x,
+ cursorPos.y
+ );
+
+ if (selectedItem && selectedItem->Id != -1)
+ {
+ switch (selectedItem->Id)
+ {
+ case 1:
+ {
+ INT lvItemIndex = PhFindListViewItemByFlags(
+ ListViewWndHandle,
+ -1,
+ LVNI_SELECTED
+ );
+
+ if (lvItemIndex != -1)
+ {
+ if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage(
+ hwndDlg,
+ L"remove",
+ cacheEntryName->Buffer,
+ NULL,
+ FALSE
+ ))
+ {
+ if (DnsFlushResolverCacheEntry_I(cacheEntryName->Buffer))
+ {
+ ListView_DeleteAllItems(ListViewWndHandle);
+ EnumDnsCacheTable(ListViewWndHandle);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ PhDestroyEMenu(menu);
+ PhDereferenceObject(cacheEntryName);
+ }
+}
+
+INT_PTR CALLBACK DnsCacheDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ PhCenterWindow(hwndDlg, PhMainWndHandle);
+ ListViewWndHandle = GetDlgItem(hwndDlg, IDC_DNSLIST);
+
+ PhRegisterDialog(hwndDlg);
+ PhSetListViewStyle(ListViewWndHandle, FALSE, TRUE);
+ PhSetControlTheme(ListViewWndHandle, L"explorer");
+ PhAddListViewColumn(ListViewWndHandle, 0, 0, 0, LVCFMT_LEFT, 280, L"Host Name");
+ PhAddListViewColumn(ListViewWndHandle, 1, 1, 1, LVCFMT_LEFT, 70, L"Type");
+ PhAddListViewColumn(ListViewWndHandle, 2, 2, 2, LVCFMT_LEFT, 100, L"IP Address");
+ PhAddListViewColumn(ListViewWndHandle, 3, 3, 3, LVCFMT_LEFT, 50, L"TTL");
+ PhSetExtendedListView(ListViewWndHandle);
+
+ PhInitializeLayoutManager(&LayoutManager, hwndDlg);
+ PhAddLayoutItem(&LayoutManager, ListViewWndHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_REFRESH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_CLEAR), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+ PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhLoadListViewColumnsFromSetting(SETTING_NAME_COLUMNS, ListViewWndHandle);
+
+ if (DnsApiHandle = LoadLibrary(L"dnsapi.dll"))
+ {
+ DnsGetCacheDataTable_I = PhGetProcedureAddress(DnsApiHandle, "DnsGetCacheDataTable", 0);
+ DnsFlushResolverCache_I = PhGetProcedureAddress(DnsApiHandle, "DnsFlushResolverCache", 0);
+ DnsFlushResolverCacheEntry_I = PhGetProcedureAddress(DnsApiHandle, "DnsFlushResolverCacheEntry_W", 0);
+ }
+
+ EnumDnsCacheTable(ListViewWndHandle);
+ }
+ break;
+ case WM_DESTROY:
+ {
+ if (DnsApiHandle)
+ {
+ FreeLibrary(DnsApiHandle);
+ DnsApiHandle = NULL;
+ }
+
+ PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhSaveListViewColumnsToSetting(SETTING_NAME_COLUMNS, ListViewWndHandle);
+ PhDeleteLayoutManager(&LayoutManager);
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&LayoutManager);
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_DNS_CLEAR:
+ {
+ if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage(
+ hwndDlg,
+ L"Flush",
+ L"the dns cache",
+ NULL,
+ FALSE
+ ))
+ {
+ if (DnsFlushResolverCache_I)
+ DnsFlushResolverCache_I();
+
+ ListView_DeleteAllItems(ListViewWndHandle);
+ EnumDnsCacheTable(ListViewWndHandle);
+ }
+ }
+ break;
+ case IDC_DNS_REFRESH:
+ ListView_DeleteAllItems(ListViewWndHandle);
+ EnumDnsCacheTable(ListViewWndHandle);
+ break;
+ case IDCANCEL:
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR hdr = (LPNMHDR)lParam;
+
+ switch (hdr->code)
+ {
+ case NM_RCLICK:
+ {
+ if (hdr->hwndFrom == ListViewWndHandle)
+ ShowStatusMenu(hwndDlg);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID NTAPI MainMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM systemMenu;
+ PPH_EMENU_ITEM bootMenuItem;
+
+ if (menuInfo->u.MainMenu.SubMenuIndex != PH_MENU_ITEM_LOCATION_TOOLS)
+ return;
+
+ if (!(systemMenu = PhFindEMenuItem(menuInfo->Menu, 0, L"System", 0)))
+ {
+ PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, PH_EMENU_SEPARATOR, 0, L"", NULL), -1);
+ PhInsertEMenuItem(menuInfo->Menu, systemMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"System", NULL), -1);
+ }
+
+ PhInsertEMenuItem(systemMenu, bootMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, DNSCACHE_MENUITEM, L"DNS Cache Table", NULL), -1);
+}
+
+VOID NTAPI MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
+
+ switch (menuItem->Id)
+ {
+ case DNSCACHE_MENUITEM:
+ {
+ DialogBox(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_DNSVIEW),
+ NULL,
+ DnsCacheDlgProc
+ );
+ }
+ break;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"350,350" },
+ { ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|510,380" },
+ { StringSettingType, SETTING_NAME_COLUMNS, L"" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"DNS Cache Viewer";
+ info->Author = L"dmex";
+ info->Description = L"Plugin for viewing the DNS Resolver Cache via the Tools menu.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
+ MainMenuInitializingCallback,
+ NULL,
+ &MainMenuInitializingCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &PluginMenuItemCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/DnsCachePlugin/main.h b/plugins-extra/DnsCachePlugin/main.h
new file mode 100644
index 0000000..32b507f
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/main.h
@@ -0,0 +1,75 @@
+/*
+ * Process Hacker Extra Plugins -
+ * DNS Cache Plugin
+ *
+ * Copyright (C) 2014 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 .
+ */
+
+#ifndef _DNS_H_
+#define _DNS_H_
+
+#define PLUGIN_NAME L"dmex.DnsCachePlugin"
+#define SETTING_NAME_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
+#define SETTING_NAME_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
+#define SETTING_NAME_COLUMNS (PLUGIN_NAME L".WindowColumns")
+
+#define DNSCACHE_MENUITEM 1000
+#define INET_ADDRSTRLEN 22
+#define INET6_ADDRSTRLEN 65
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include "resource.h"
+
+#include
+#include
+#include
+#include
+
+#pragma comment(lib, "Ws2_32.lib")
+
+extern PPH_PLUGIN PluginInstance;
+
+VOID ShowDnsCacheDialog(
+ VOID
+ );
+
+typedef struct _DNS_CACHE_ENTRY
+{
+ struct _DNS_CACHE_ENTRY* Next; // Pointer to next entry
+ PCWSTR Name; // DNS Record Name
+ USHORT Type; // DNS Record Type
+ USHORT DataLength; // Not referenced
+ ULONG Flags; // DNS Record Flags
+} DNS_CACHE_ENTRY, *PDNS_CACHE_ENTRY;
+
+typedef DNS_STATUS (WINAPI* _DnsGetCacheDataTable)(
+ _Inout_ PDNS_CACHE_ENTRY* DnsCacheEntry
+ );
+
+typedef BOOL (WINAPI* _DnsFlushResolverCache)(
+ VOID
+ );
+
+typedef BOOL (WINAPI* _DnsFlushResolverCacheEntry)(
+ _In_ PCWSTR Name
+ );
+
+#endif
\ No newline at end of file
diff --git a/plugins-extra/DnsCachePlugin/resource.h b/plugins-extra/DnsCachePlugin/resource.h
new file mode 100644
index 0000000..49ea6ec
--- /dev/null
+++ b/plugins-extra/DnsCachePlugin/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by DnsCachePlugin.rc
+//
+#define IDD_DNSVIEW 101
+#define IDC_DNSLIST 1021
+#define IDC_DNS_REFRESH 4355
+#define IDC_DNS_CLEAR 4356
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1023
+#define _APS_NEXT_SYMED_VALUE 108
+#endif
+#endif
diff --git a/plugins-extra/ExtraPlugins.props b/plugins-extra/ExtraPlugins.props
new file mode 100644
index 0000000..7965c6f
--- /dev/null
+++ b/plugins-extra/ExtraPlugins.props
@@ -0,0 +1,124 @@
+
+
+
+
+
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\plugins\
+ $(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\
+ NativeRecommendedRules.ruleset
+ true
+ false
+ true
+ false
+ false
+ true
+
+
+
+
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\ProcessHacker.exe
+ $(SolutionDir)..\bin\$(Configuration)$(PlatformArchitecture)\
+ WindowsLocalDebugger
+
+
+
+
+
+ ../../sdk/include;%(AdditionalIncludeDirectories)
+ true
+ Level3
+ true
+ StdCall
+ false
+ true
+ ProgramDatabase
+ true
+
+
+ ProcessHacker.lib;ntdll.lib;%(AdditionalDependencies)
+ true
+ 6.01
+ Windows
+
+
+ $(IntDir)$(MSBuildProjectName).log
+
+
+
+
+
+
+ Disabled
+ MultiThreadedDebug
+ false
+ false
+ EnableFastChecks
+
+
+
+
+
+
+ MaxSpeed
+ MultiThreaded
+ true
+ true
+ AnySuitable
+ true
+
+
+ true
+ true
+ true
+ UseLinkTimeCodeGeneration
+
+
+
+
+
+
+ StreamingSIMDExtensions
+
+
+ ../../sdk/lib/i386;%(AdditionalLibraryDirectories)
+ MachineX86
+
+
+
+
+
+
+ ../../sdk/lib/amd64;%(AdditionalLibraryDirectories)
+ MachineX64
+
+
+
+
+
+
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+
+
+
+
diff --git a/plugins-extra/ExtraPlugins.sln b/plugins-extra/ExtraPlugins.sln
new file mode 100644
index 0000000..624692c
--- /dev/null
+++ b/plugins-extra/ExtraPlugins.sln
@@ -0,0 +1,247 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 14.0.25123.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D7078584-1144-4143-8DE8-D6741F6FD685}"
+ ProjectSection(SolutionItems) = preProject
+ ExtraPlugins.props = ExtraPlugins.props
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HexPidPlugin", "HexPidPlugin\HexPidPlugin.vcxproj", "{50691784-4EB0-4B5E-B428-BD37E52F8D2E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvgCpuPlugin", "AvgCpuPlugin\AvgCpuPlugin.vcxproj", "{A68DC3E8-5E2E-4883-A2A4-81F921458A9C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetCriticalPlugin", "SetCriticalPlugin\SetCriticalPlugin.vcxproj", "{AF008176-46A6-4EFB-8061-D1EF9B9CEC29}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ROTViewerPlugin", "ROTViewerPlugin\ROTViewerPlugin.vcxproj", "{4C581739-03D9-4E73-B453-0536DFB34C91}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DnsCachePlugin", "DnsCachePlugin\DnsCachePlugin.vcxproj", "{34E39D39-7148-45BF-9B36-DEF53E534A11}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AtomTablePlugin", "AtomTablePlugin\AtomTablePlugin.vcxproj", "{12390643-F40D-411F-A2E8-BF85F90223DF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WaitChainPlugin", "WaitChainPlugin\WaitChainPlugin.vcxproj", "{D6EA1C23-4CBC-4CD5-931C-38C984722510}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PerfMonPlugin", "PerfMonPlugin\PerfMonPlugin.vcxproj", "{E373C568-D6C5-4E0E-94ED-A759EDE16A9E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NvGpuPlugin", "NvGpuPlugin\NvGpuPlugin.vcxproj", "{B509BF8F-6007-4173-B05E-5037B958C12F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DbgViewPlugin", "DbgViewPlugin\DbgViewPlugin.vcxproj", "{AAD42A11-92A7-4918-A76A-862528185199}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetExtrasPlugin", "NetExtrasPlugin\NetExtrasPlugin.vcxproj", "{B2F55139-7984-498F-98CB-AC25A3E08CCC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TaskbarExtPlugin", "TaskbarExtPlugin\TaskbarExtPlugin.vcxproj", "{58E266DF-088C-470D-9EC8-403B40042373}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SecurityExplorer", "SecurityExplorerPlugin\SecurityExplorer.vcxproj", "{0DCBC570-B4E3-482A-9872-8BB5678F5E5C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ServiceBackupRestorePlugin", "ServiceBackupRestorePlugin\ServiceBackupRestorePlugin.vcxproj", "{D08A2B6C-822F-46C8-A7AC-A2EE609237D6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FirewallMonitorPlugin", "FirewallMonitorPlugin\FirewallMonitorPlugin.vcxproj", "{44A7C3BA-BAD5-40F3-AB70-442D44539053}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ForceShutdownPlugin", "ForceShutdownPlugin\ForceShutdownPlugin.vcxproj", "{4417E8FC-5FA6-4631-B792-1872561E7DC2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrustedInstallerPlugin", "TrustedInstallerPlugin\TrustedInstallerPlugin.vcxproj", "{652D6556-B8E3-4173-B321-60F623E127E8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminatorPlugin", "TerminatorPlugin\TerminatorPlugin.vcxproj", "{93D93301-3638-4CFA-8F1B-547528023087}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FirmwarePlugin", "FirmwarePlugin\FirmwarePlugin.vcxproj", "{21B34EB4-4C56-4449-A2C0-BC50B4480D7C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PoolMonPlugin", "PoolMonPlugin\PoolMonPlugin.vcxproj", "{34E1194C-61AE-4FAF-A5F9-540DD6DF4872}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ObjectManagerPlugin", "ObjectManagerPlugin\ObjectManagerPlugin.vcxproj", "{DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExtraPlugins", "ExtraPlugins\ExtraPlugins.vcxproj", "{96549A3E-D1BD-470E-A5B3-A64803C4DEF5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Debug|Win32.Build.0 = Debug|Win32
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Debug|x64.ActiveCfg = Debug|x64
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Debug|x64.Build.0 = Debug|x64
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Release|Win32.ActiveCfg = Release|Win32
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Release|Win32.Build.0 = Release|Win32
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Release|x64.ActiveCfg = Release|x64
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}.Release|x64.Build.0 = Release|x64
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Debug|Win32.Build.0 = Debug|Win32
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Debug|x64.ActiveCfg = Debug|x64
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Debug|x64.Build.0 = Debug|x64
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Release|Win32.ActiveCfg = Release|Win32
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Release|Win32.Build.0 = Release|Win32
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Release|x64.ActiveCfg = Release|x64
+ {A68DC3E8-5E2E-4883-A2A4-81F921458A9C}.Release|x64.Build.0 = Release|x64
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Debug|Win32.Build.0 = Debug|Win32
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Debug|x64.ActiveCfg = Debug|x64
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Debug|x64.Build.0 = Debug|x64
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Release|Win32.ActiveCfg = Release|Win32
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Release|Win32.Build.0 = Release|Win32
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Release|x64.ActiveCfg = Release|x64
+ {AF008176-46A6-4EFB-8061-D1EF9B9CEC29}.Release|x64.Build.0 = Release|x64
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Debug|Win32.Build.0 = Debug|Win32
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Debug|x64.ActiveCfg = Debug|x64
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Debug|x64.Build.0 = Debug|x64
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Release|Win32.ActiveCfg = Release|Win32
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Release|Win32.Build.0 = Release|Win32
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Release|x64.ActiveCfg = Release|x64
+ {4C581739-03D9-4E73-B453-0536DFB34C91}.Release|x64.Build.0 = Release|x64
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Debug|Win32.ActiveCfg = Debug|Win32
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Debug|Win32.Build.0 = Debug|Win32
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Debug|x64.ActiveCfg = Debug|x64
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Debug|x64.Build.0 = Debug|x64
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Release|Win32.ActiveCfg = Release|Win32
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Release|Win32.Build.0 = Release|Win32
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Release|x64.ActiveCfg = Release|x64
+ {34E39D39-7148-45BF-9B36-DEF53E534A11}.Release|x64.Build.0 = Release|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|Win32.Build.0 = Debug|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|Win32.Deploy.0 = Debug|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|x64.ActiveCfg = Debug|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|x64.Build.0 = Debug|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Debug|x64.Deploy.0 = Debug|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|Win32.ActiveCfg = Release|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|Win32.Build.0 = Release|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|Win32.Deploy.0 = Release|Win32
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|x64.ActiveCfg = Release|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|x64.Build.0 = Release|x64
+ {12390643-F40D-411F-A2E8-BF85F90223DF}.Release|x64.Deploy.0 = Release|x64
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Debug|Win32.Build.0 = Debug|Win32
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Debug|x64.ActiveCfg = Debug|x64
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Debug|x64.Build.0 = Debug|x64
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Release|Win32.ActiveCfg = Release|Win32
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Release|Win32.Build.0 = Release|Win32
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Release|x64.ActiveCfg = Release|x64
+ {D6EA1C23-4CBC-4CD5-931C-38C984722510}.Release|x64.Build.0 = Release|x64
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Debug|Win32.Build.0 = Debug|Win32
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Debug|x64.ActiveCfg = Debug|x64
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Debug|x64.Build.0 = Debug|x64
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Release|Win32.ActiveCfg = Release|Win32
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Release|Win32.Build.0 = Release|Win32
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Release|x64.ActiveCfg = Release|x64
+ {E373C568-D6C5-4E0E-94ED-A759EDE16A9E}.Release|x64.Build.0 = Release|x64
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Debug|Win32.Build.0 = Debug|Win32
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Debug|x64.ActiveCfg = Debug|x64
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Debug|x64.Build.0 = Debug|x64
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Release|Win32.ActiveCfg = Release|Win32
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Release|Win32.Build.0 = Release|Win32
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Release|x64.ActiveCfg = Release|x64
+ {B509BF8F-6007-4173-B05E-5037B958C12F}.Release|x64.Build.0 = Release|x64
+ {AAD42A11-92A7-4918-A76A-862528185199}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AAD42A11-92A7-4918-A76A-862528185199}.Debug|Win32.Build.0 = Debug|Win32
+ {AAD42A11-92A7-4918-A76A-862528185199}.Debug|x64.ActiveCfg = Debug|x64
+ {AAD42A11-92A7-4918-A76A-862528185199}.Debug|x64.Build.0 = Debug|x64
+ {AAD42A11-92A7-4918-A76A-862528185199}.Release|Win32.ActiveCfg = Release|Win32
+ {AAD42A11-92A7-4918-A76A-862528185199}.Release|Win32.Build.0 = Release|Win32
+ {AAD42A11-92A7-4918-A76A-862528185199}.Release|x64.ActiveCfg = Release|x64
+ {AAD42A11-92A7-4918-A76A-862528185199}.Release|x64.Build.0 = Release|x64
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Debug|Win32.Build.0 = Debug|Win32
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Debug|x64.ActiveCfg = Debug|x64
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Debug|x64.Build.0 = Debug|x64
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Release|Win32.ActiveCfg = Release|Win32
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Release|Win32.Build.0 = Release|Win32
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Release|x64.ActiveCfg = Release|x64
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}.Release|x64.Build.0 = Release|x64
+ {58E266DF-088C-470D-9EC8-403B40042373}.Debug|Win32.ActiveCfg = Debug|Win32
+ {58E266DF-088C-470D-9EC8-403B40042373}.Debug|Win32.Build.0 = Debug|Win32
+ {58E266DF-088C-470D-9EC8-403B40042373}.Debug|x64.ActiveCfg = Debug|x64
+ {58E266DF-088C-470D-9EC8-403B40042373}.Debug|x64.Build.0 = Debug|x64
+ {58E266DF-088C-470D-9EC8-403B40042373}.Release|Win32.ActiveCfg = Release|Win32
+ {58E266DF-088C-470D-9EC8-403B40042373}.Release|Win32.Build.0 = Release|Win32
+ {58E266DF-088C-470D-9EC8-403B40042373}.Release|x64.ActiveCfg = Release|x64
+ {58E266DF-088C-470D-9EC8-403B40042373}.Release|x64.Build.0 = Release|x64
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Debug|Win32.Build.0 = Debug|Win32
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Debug|x64.ActiveCfg = Debug|x64
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Debug|x64.Build.0 = Debug|x64
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Release|Win32.ActiveCfg = Release|Win32
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Release|Win32.Build.0 = Release|Win32
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Release|x64.ActiveCfg = Release|x64
+ {0DCBC570-B4E3-482A-9872-8BB5678F5E5C}.Release|x64.Build.0 = Release|x64
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Debug|Win32.Build.0 = Debug|Win32
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Debug|x64.ActiveCfg = Debug|x64
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Debug|x64.Build.0 = Debug|x64
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Release|Win32.ActiveCfg = Release|Win32
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Release|Win32.Build.0 = Release|Win32
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.Release|x64.ActiveCfg = Release|x64
+ {D08A2B6C-822F-46C8-A7AC-A2EE609237D6}.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
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Debug|Win32.Build.0 = Debug|Win32
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Debug|x64.ActiveCfg = Debug|x64
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Debug|x64.Build.0 = Debug|x64
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|Win32.ActiveCfg = Release|Win32
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|Win32.Build.0 = Release|Win32
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|x64.ActiveCfg = Release|x64
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|x64.Build.0 = Release|x64
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|Win32.Build.0 = Debug|Win32
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|x64.ActiveCfg = Debug|x64
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|x64.Build.0 = Debug|x64
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Release|Win32.ActiveCfg = Release|Win32
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Release|Win32.Build.0 = Release|Win32
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Release|x64.ActiveCfg = Release|x64
+ {652D6556-B8E3-4173-B321-60F623E127E8}.Release|x64.Build.0 = Release|x64
+ {93D93301-3638-4CFA-8F1B-547528023087}.Debug|Win32.ActiveCfg = Debug|Win32
+ {93D93301-3638-4CFA-8F1B-547528023087}.Debug|Win32.Build.0 = Debug|Win32
+ {93D93301-3638-4CFA-8F1B-547528023087}.Debug|x64.ActiveCfg = Debug|x64
+ {93D93301-3638-4CFA-8F1B-547528023087}.Debug|x64.Build.0 = Debug|x64
+ {93D93301-3638-4CFA-8F1B-547528023087}.Release|Win32.ActiveCfg = Release|Win32
+ {93D93301-3638-4CFA-8F1B-547528023087}.Release|Win32.Build.0 = Release|Win32
+ {93D93301-3638-4CFA-8F1B-547528023087}.Release|x64.ActiveCfg = Release|x64
+ {93D93301-3638-4CFA-8F1B-547528023087}.Release|x64.Build.0 = Release|x64
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Debug|Win32.Build.0 = Debug|Win32
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Debug|x64.ActiveCfg = Debug|x64
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Debug|x64.Build.0 = Debug|x64
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Release|Win32.ActiveCfg = Release|Win32
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Release|Win32.Build.0 = Release|Win32
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Release|x64.ActiveCfg = Release|x64
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}.Release|x64.Build.0 = Release|x64
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Debug|Win32.ActiveCfg = Debug|Win32
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Debug|Win32.Build.0 = Debug|Win32
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Debug|x64.ActiveCfg = Debug|x64
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Debug|x64.Build.0 = Debug|x64
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Release|Win32.ActiveCfg = Release|Win32
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Release|Win32.Build.0 = Release|Win32
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Release|x64.ActiveCfg = Release|x64
+ {34E1194C-61AE-4FAF-A5F9-540DD6DF4872}.Release|x64.Build.0 = Release|x64
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Debug|Win32.Build.0 = Debug|Win32
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Debug|x64.ActiveCfg = Debug|x64
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Debug|x64.Build.0 = Debug|x64
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Release|Win32.ActiveCfg = Release|Win32
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Release|Win32.Build.0 = Release|Win32
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Release|x64.ActiveCfg = Release|x64
+ {DADA7017-0A25-4E97-BC21-D7FE3DE2EBF3}.Release|x64.Build.0 = Release|x64
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Debug|Win32.Build.0 = Debug|Win32
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Debug|x64.ActiveCfg = Debug|x64
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Debug|x64.Build.0 = Debug|x64
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Release|Win32.ActiveCfg = Release|Win32
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Release|Win32.Build.0 = Release|Win32
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Release|x64.ActiveCfg = Release|x64
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins-extra/ExtraPlugins/CHANGELOG.txt b/plugins-extra/ExtraPlugins/CHANGELOG.txt
new file mode 100644
index 0000000..18d7d78
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/CHANGELOG.txt
@@ -0,0 +1,4 @@
+1.0
+ * Initial release
+
+
diff --git a/plugins-extra/ExtraPlugins/ExtraPlugins.rc b/plugins-extra/ExtraPlugins/ExtraPlugins.rc
new file mode 100644
index 0000000..ce4808d
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/ExtraPlugins.rc
@@ -0,0 +1,184 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 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 "000904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Extra plugins for Process Hacker"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "InternalName", "dmex.ExtraPlugins"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "ExtraPlugins.dll"
+ VALUE "ProductName", "Extra plugins for Process Hacker"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x9, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_PLUGINS_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 637
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 309
+ END
+
+ IDD_DISABLED_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 307
+ TOPMARGIN, 2
+ BOTTOMMARGIN, 176
+ HORZGUIDE, 2
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_PLUGINS_DIALOG AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+IDD_DISABLED_DIALOG AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_PLUGINS_DIALOG DIALOGEX 0, 0, 639, 313
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Plugin Manager"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "Installed",IDC_INSTALLED,2,2,65,14,NOT WS_TABSTOP
+ PUSHBUTTON "Browse",IDC_BROWSE,73,2,64,14,NOT WS_TABSTOP
+ PUSHBUTTON "Updates (0)",IDC_UPDATES,143,2,65,14,NOT WS_TABSTOP
+ EDITTEXT IDC_SEARCHBOX,483,2,153,14,ES_AUTOHSCROLL,WS_EX_CLIENTEDGE
+ CONTROL "",IDC_PLUGINTREE,"PhTreeNew",WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP | 0xa,2,18,635,275,WS_EX_CLIENTEDGE
+ PUSHBUTTON "Close",IDOK,587,295,50,14
+ PUSHBUTTON "Disabled Plugins (0)",IDC_DISABLED,2,295,75,14,NOT WS_TABSTOP
+ PUSHBUTTON "Clean up",IDC_CLEANUP,81,295,75,14,NOT WS_VISIBLE
+END
+
+IDD_DISABLED_DIALOG DIALOGEX 0, 0, 309, 178
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+CAPTION "Disabled Plugins"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "OK",IDOK,257,162,50,14
+ CONTROL "",IDC_LIST_DISABLED,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,2,15,305,145
+ LTEXT "Changes may require a restart to take effect.",IDC_INSTRUCTION,3,3,154,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_SEARCH_ACTIVE_BMP BITMAP "resources\\active_search.bmp"
+
+IDB_SEARCH_INACTIVE_BMP BITMAP "resources\\inactive_search.bmp"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// PNG
+//
+
+IDB_SEARCH_ACTIVE PNG "resources\\active_search.png"
+
+IDB_SEARCH_INACTIVE PNG "resources\\inactive_search.png"
+
+IDB_SETTINGS_PNG PNG "resources\\cog_edit_modern.png"
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj b/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj
new file mode 100644
index 0000000..034e6b5
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj
@@ -0,0 +1,176 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {96549A3E-D1BD-470E-A5B3-A64803C4DEF5}
+ ExtraPlugins
+ Win32Proj
+ ExtraPlugins
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ windowscodecs.lib;bcrypt.lib;winhttp.lib;uxtheme.lib;%(AdditionalDependencies)
+ windowscodecs.dll;bcrypt.dll;winhttp.dll;uxtheme.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ windowscodecs.lib;bcrypt.lib;winhttp.lib;uxtheme.lib;%(AdditionalDependencies)
+ windowscodecs.dll;bcrypt.dll;winhttp.dll;uxtheme.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ windowscodecs.lib;bcrypt.lib;winhttp.lib;uxtheme.lib;%(AdditionalDependencies)
+ windowscodecs.dll;bcrypt.dll;winhttp.dll;uxtheme.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ windowscodecs.lib;bcrypt.lib;winhttp.lib;uxtheme.lib;%(AdditionalDependencies)
+ windowscodecs.dll;bcrypt.dll;winhttp.dll;uxtheme.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj.filters b/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj.filters
new file mode 100644
index 0000000..483216d
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/ExtraPlugins.vcxproj.filters
@@ -0,0 +1,200 @@
+
+
+
+
+ {802108be-ae96-47c3-8d93-884ed6dd096a}
+
+
+ {3e65ffb8-3f3e-40d7-b3ca-d55cae8edb16}
+
+
+ {b98dd849-bbfe-4b41-8c48-f65680da5c00}
+
+
+ {d13aeaca-3136-44f8-8525-ac088e4170ad}
+
+
+ {297fc08d-cce6-41c6-8e77-63411ddd185b}
+
+
+ {59006979-4faf-455c-b58c-3f81e8ff9272}
+
+
+ {2ff6c860-c958-4bcc-8147-4093cad157e5}
+
+
+ {77191a45-2eba-438a-8ad2-853e25615850}
+
+
+ {50861cd8-df66-4551-a743-f08b54011d1e}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Source Files\zip
+
+
+ Source Files
+
+
+ Source Files\pages
+
+
+ Source Files\pages
+
+
+ Source Files\pages
+
+
+ Source Files\pages
+
+
+ Source Files\pages
+
+
+ Source Files\pages
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files\pages
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Source Files\json-c
+
+
+ Source Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\json-c
+
+
+ Header Files\zip
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/cloud.c b/plugins-extra/ExtraPlugins/cloud.c
new file mode 100644
index 0000000..fce6e36
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/cloud.c
@@ -0,0 +1,594 @@
+/*
+* Process Hacker Extra Plugins -
+* Plugin Manager
+*
+* Copyright (C) 2016 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 "main.h"
+#include "miniz\miniz.h"
+
+ULONGLONG ParseVersionString(
+ _In_ PPH_STRING Version
+ )
+{
+ PH_STRINGREF remainingPart, majorPart, minorPart, revisionPart, reservedPart;
+ ULONG64 majorInteger = 0, minorInteger = 0, revisionInteger = 0, reservedInteger = 0;
+
+ PhInitializeStringRef(&remainingPart, PhGetString(Version));
+ PhSplitStringRefAtChar(&remainingPart, '.', &majorPart, &remainingPart);
+ PhSplitStringRefAtChar(&remainingPart, '.', &minorPart, &remainingPart);
+ PhSplitStringRefAtChar(&remainingPart, '.', &revisionPart, &remainingPart);
+ PhSplitStringRefAtChar(&remainingPart, '.', &reservedPart, &remainingPart);
+
+ PhStringToInteger64(&majorPart, 10, &majorInteger);
+ PhStringToInteger64(&minorPart, 10, &minorInteger);
+ PhStringToInteger64(&revisionPart, 10, &revisionInteger);
+ PhStringToInteger64(&reservedPart, 10, &reservedInteger);
+
+ return MAKE_VERSION_ULONGLONG(majorInteger, minorInteger, reservedInteger, revisionInteger);
+}
+
+json_object_ptr json_get_object(
+ _In_ json_object_ptr Object,
+ _In_ PCSTR Key
+ )
+{
+ json_object_ptr returnObj;
+
+ if (json_object_object_get_ex(Object, Key, &returnObj))
+ {
+ return returnObj;
+ }
+
+ return NULL;
+}
+
+static BOOLEAN ReadRequestString(
+ _In_ HINTERNET Handle,
+ _Out_ _Deref_post_z_cap_(*DataLength) PSTR *Data,
+ _Out_ ULONG *DataLength
+ )
+{
+ BYTE buffer[PAGE_SIZE];
+ PSTR data;
+ ULONG allocatedLength;
+ ULONG dataLength;
+ ULONG returnLength;
+
+ allocatedLength = sizeof(buffer);
+ data = (PSTR)PhAllocate(allocatedLength);
+ dataLength = 0;
+
+ // Zero the buffer
+ memset(buffer, 0, PAGE_SIZE);
+ memset(data, 0, allocatedLength);
+
+ while (WinHttpReadData(Handle, buffer, PAGE_SIZE, &returnLength))
+ {
+ if (returnLength == 0)
+ break;
+
+ if (allocatedLength < dataLength + returnLength)
+ {
+ allocatedLength *= 2;
+ data = (PSTR)PhReAllocate(data, allocatedLength);
+ }
+
+ // Copy the returned buffer into our pointer
+ memcpy(data + dataLength, buffer, returnLength);
+ // Zero the returned buffer for the next loop
+ //memset(buffer, 0, returnLength);
+
+ dataLength += returnLength;
+ }
+
+ if (allocatedLength < dataLength + 1)
+ {
+ allocatedLength++;
+ data = (PSTR)PhReAllocate(data, allocatedLength);
+ }
+
+ // Ensure that the buffer is null-terminated.
+ data[dataLength] = 0;
+
+ *DataLength = dataLength;
+ *Data = data;
+
+ return TRUE;
+}
+
+VOID EnumerateLoadedPlugins(
+ _In_ PWCT_CONTEXT Context
+ )
+{
+ PPH_AVL_LINKS root;
+ PPH_AVL_LINKS links;
+
+ root = PluginInstance->Links.Parent;
+
+ while (root)
+ {
+ if (!root->Parent)
+ break;
+
+ root = root->Parent;
+ }
+
+ for (
+ links = PhMinimumElementAvlTree((PPH_AVL_TREE)root);
+ links;
+ links = PhSuccessorElementAvlTree(links)
+ )
+ {
+ HANDLE handle;
+ IO_STATUS_BLOCK isb;
+ FILE_BASIC_INFORMATION basic;
+ PPHAPP_PLUGIN pluginInstance;
+ PH_STRINGREF pluginBaseName;
+
+ pluginInstance = CONTAINING_RECORD(links, PHAPP_PLUGIN, Links);
+
+ PhInitializeStringRefLongHint(&pluginBaseName, PhGetPluginBaseName(pluginInstance));
+
+ if (PhIsPluginDisabled(&pluginBaseName))
+ {
+ continue;
+ }
+
+ memset(&basic, 0, sizeof(FILE_BASIC_INFORMATION));
+
+ if (NT_SUCCESS(PhCreateFileWin32(
+ &handle,
+ PhGetString(pluginInstance->FileName),
+ FILE_GENERIC_READ,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
+ )))
+ {
+ NtQueryInformationFile(
+ handle,
+ &isb,
+ &basic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation
+ );
+
+ NtClose(handle);
+ }
+
+ ULONG versionSize;
+ PVOID versionInfo;
+ PUSHORT languageInfo;
+ UINT language;
+ UINT bufferSize = 0;
+ PWSTR buffer = NULL;
+ PPH_STRING internalName = NULL;
+ PPH_STRING version = NULL;
+
+ versionSize = GetFileVersionInfoSize(PhGetString(pluginInstance->FileName), NULL);
+ versionInfo = PhAllocate(versionSize);
+ memset(versionInfo, 0, versionSize);
+
+ if (GetFileVersionInfo(PhGetString(pluginInstance->FileName), 0, versionSize, versionInfo))
+ {
+ if (VerQueryValue(versionInfo, L"\\", &buffer, &bufferSize))
+ {
+ VS_FIXEDFILEINFO* info = (VS_FIXEDFILEINFO*)buffer;
+
+ if (info->dwSignature == 0xfeef04bd)
+ {
+ version = PhFormatString(
+ L"%lu.%lu.%lu.%lu",
+ (info->dwFileVersionMS >> 16) & 0xffff,
+ (info->dwFileVersionMS >> 0) & 0xffff,
+ (info->dwFileVersionLS >> 16) & 0xffff,
+ (info->dwFileVersionLS >> 0) & 0xffff
+ );
+ }
+ }
+
+ if (VerQueryValue(versionInfo, L"\\VarFileInfo\\Translation", &languageInfo, &language))
+ {
+ PPH_STRING internalNameString = PhFormatString(
+ L"\\StringFileInfo\\%04x%04x\\InternalName",
+ languageInfo[0],
+ languageInfo[1]
+ );
+
+ if (VerQueryValue(versionInfo, PhGetStringOrEmpty(internalNameString), &buffer, &bufferSize))
+ {
+ internalName = PhCreateStringEx(buffer, bufferSize * sizeof(WCHAR));
+ }
+
+ PhDereferenceObject(internalNameString);
+ }
+ }
+
+ PPLUGIN_NODE entry = PhCreateAlloc(sizeof(PLUGIN_NODE));
+ memset(entry, 0, sizeof(PLUGIN_NODE));
+
+ entry->State = PLUGIN_STATE_LOCAL;
+ entry->PluginInstance = pluginInstance;
+ entry->InternalName = internalName;
+ entry->Version = PhSubstring(version, 0, version->Length / sizeof(WCHAR) - 4);
+ entry->Name = PhCreateString(pluginInstance->Information.DisplayName);
+ entry->Author = PhCreateString(pluginInstance->Information.Author);
+ entry->Description = PhCreateString(pluginInstance->Information.Description);
+ entry->FilePath = PhCreateString2(&pluginInstance->FileName->sr);
+ entry->FileName = PhGetBaseName(entry->FilePath);
+
+ SYSTEMTIME utcTime, localTime;
+ PhLargeIntegerToSystemTime(&utcTime, &basic.LastWriteTime);
+ SystemTimeToTzSpecificLocalTime(NULL, &utcTime, &localTime);
+ entry->UpdatedTime = PhFormatDateTime(&localTime);
+
+ PhLargeIntegerToSystemTime(&utcTime, &basic.CreationTime);
+ SystemTimeToTzSpecificLocalTime(NULL, &utcTime, &localTime);
+ entry->AddedTime = PhFormatDateTime(&localTime);
+
+ entry->PluginOptions = pluginInstance->Information.HasOptions;
+
+ PostMessage(Context->DialogHandle, ID_UPDATE_ADD, 0, (LPARAM)entry);
+ }
+}
+
+NTSTATUS QueryPluginsCallbackThread(
+ _In_ PVOID Parameter
+ )
+{
+ HINTERNET httpSessionHandle = NULL;
+ HINTERNET httpConnectionHandle = NULL;
+ HINTERNET httpRequestHandle = NULL;
+ WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig = { 0 };
+ ULONG xmlStringBufferLength = 0;
+ PSTR xmlStringBuffer = NULL;
+ json_object_ptr rootJsonObject;
+ PWCT_CONTEXT context = Parameter;
+
+ WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
+
+ if (!(httpSessionHandle = WinHttpOpen(
+ L"ExtraPlugins_1.0",
+ proxyConfig.lpszProxy ? WINHTTP_ACCESS_TYPE_NAMED_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ proxyConfig.lpszProxy,
+ proxyConfig.lpszProxyBypass,
+ 0
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (!(httpConnectionHandle = WinHttpConnect(
+ httpSessionHandle,
+ L"wj32.org",
+ INTERNET_DEFAULT_HTTP_PORT,
+ 0
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (!(httpRequestHandle = WinHttpOpenRequest(
+ httpConnectionHandle,
+ NULL,
+ L"/processhacker/plugins/list.php",
+ NULL,
+ WINHTTP_NO_REFERER,
+ WINHTTP_DEFAULT_ACCEPT_TYPES,
+ WINHTTP_FLAG_REFRESH
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (!WinHttpSendRequest(
+ httpRequestHandle,
+ WINHTTP_NO_ADDITIONAL_HEADERS,
+ 0,
+ WINHTTP_NO_REQUEST_DATA,
+ 0,
+ WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
+ 0
+ ))
+ {
+ goto CleanupExit;
+ }
+
+ if (!WinHttpReceiveResponse(httpRequestHandle, NULL))
+ goto CleanupExit;
+
+ if (!ReadRequestString(httpRequestHandle, &xmlStringBuffer, &xmlStringBufferLength))
+ goto CleanupExit;
+
+ if (!(rootJsonObject = json_tokener_parse(xmlStringBuffer)))
+ goto CleanupExit;
+
+ for (INT i = 0; i < json_object_array_length(rootJsonObject); i++)
+ {
+ json_object_ptr jvalue;
+ PPLUGIN_NODE entry;
+ SYSTEMTIME time = { 0 };
+ SYSTEMTIME localTime = { 0 };
+ PH_STRINGREF pluginBaseName;
+ PPH_STRING pluginDllPath;
+
+ entry = PhCreateAlloc(sizeof(PLUGIN_NODE));
+ memset(entry, 0, sizeof(PLUGIN_NODE));
+
+ jvalue = json_object_array_get_idx(rootJsonObject, i);
+ entry->Id = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_id")));
+ entry->Visible = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_visible")));
+ entry->InternalName = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_internal_name")));
+ entry->Name = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_name")));
+ entry->Version = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_version")));
+ entry->Author = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_author")));
+ entry->Description = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_description")));
+ entry->IconUrl = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_icon")));
+ entry->Requirements = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_requirements")));
+ entry->FeedbackUrl = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_feedback")));
+ entry->Screenshots = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_screenshots")));
+ entry->AddedTime = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_datetime_added")));
+ entry->UpdatedTime = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_datetime_updated")));
+ entry->Download_count = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_download_count")));
+ entry->Download_link_32 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_download_link_32")));
+ entry->Download_link_64 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_download_link_64")));
+ entry->SHA2_32 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_hash_32")));
+ entry->SHA2_64 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_hash_64")));
+ entry->HASH_32 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_signed_32")));
+ entry->HASH_64 = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_signed_64")));
+ entry->FileName = PhConvertUtf8ToUtf16(json_object_get_string(json_get_object(jvalue, "plugin_filename")));
+
+ swscanf(
+ PhGetString(entry->UpdatedTime),
+ L"%hu-%hu-%hu %hu:%hu:%hu",
+ &time.wYear,
+ &time.wMonth,
+ &time.wDay,
+ &time.wHour,
+ &time.wMinute,
+ &time.wSecond
+ );
+
+ if (SystemTimeToTzSpecificLocalTime(NULL, &time, &localTime))
+ {
+ entry->UpdatedTime = PhFormatDateTime(&localTime);
+ }
+
+ pluginDllPath = PhConcatStrings(3, PhGetString(PhGetApplicationDirectory()), L"Plugins\\", PhGetString(entry->FileName));
+ PhInitializeStringRefLongHint(&pluginBaseName, PhGetString(entry->FileName));
+
+ if (PhIsPluginDisabled(&pluginBaseName))
+ goto CleanupExit;
+
+ if (RtlDoesFileExists_U(PhGetString(pluginDllPath)))
+ {
+ ULONG versionSize;
+ PVOID versionInfo;
+ PUSHORT languageInfo;
+ UINT language;
+ UINT bufferSize = 0;
+ PWSTR buffer = NULL;
+ PPH_STRING internalName = NULL;
+ PPH_STRING version = NULL;
+
+ entry->FilePath = PhCreateString2(&pluginDllPath->sr);//entry->PluginInstance->FileName->sr);
+
+ versionSize = GetFileVersionInfoSize(PhGetString(entry->FilePath), NULL);
+ versionInfo = PhAllocate(versionSize);
+ memset(versionInfo, 0, versionSize);
+
+ if (GetFileVersionInfo(PhGetString(entry->FilePath), 0, versionSize, versionInfo))
+ {
+ if (VerQueryValue(versionInfo, L"\\", &buffer, &bufferSize))
+ {
+ VS_FIXEDFILEINFO* info = (VS_FIXEDFILEINFO*)buffer;
+
+ if (info->dwSignature == 0xfeef04bd)
+ {
+ version = PhFormatString(
+ L"%lu.%lu.%lu.%lu",
+ (info->dwFileVersionMS >> 16) & 0xffff,
+ (info->dwFileVersionMS >> 0) & 0xffff,
+ (info->dwFileVersionLS >> 16) & 0xffff,
+ (info->dwFileVersionLS >> 0) & 0xffff
+ );
+ }
+ }
+
+ if (VerQueryValue(versionInfo, L"\\VarFileInfo\\Translation", &languageInfo, &language))
+ {
+ PPH_STRING internalNameString = PhFormatString(
+ L"\\StringFileInfo\\%04x%04x\\InternalName",
+ languageInfo[0],
+ languageInfo[1]
+ );
+
+ if (VerQueryValue(versionInfo, PhGetStringOrEmpty(internalNameString), &buffer, &bufferSize))
+ {
+ internalName = PhCreateStringEx(buffer, bufferSize * sizeof(WCHAR));
+ }
+
+ PhDereferenceObject(internalNameString);
+ }
+ }
+
+ PhFree(versionInfo);
+
+ if (entry->PluginInstance = (PPHAPP_PLUGIN)PhFindPlugin(PhGetString(entry->InternalName)))
+ {
+ ULONGLONG currentVersion = ParseVersionString(version);
+ ULONGLONG latestVersion = ParseVersionString(entry->Version);
+
+ entry->PluginOptions = entry->PluginInstance->Information.HasOptions;
+
+ if (currentVersion < latestVersion)
+ {
+ // User is running an older version
+ entry->State = PLUGIN_STATE_UPDATE;
+ PostMessage(context->DialogHandle, ID_UPDATE_ADD, 0, (LPARAM)entry);
+ }
+ }
+ else
+ {
+ // Plugin waiting to load?
+ entry->State = PLUGIN_STATE_RESTART;
+ PostMessage(context->DialogHandle, ID_UPDATE_ADD, 0, (LPARAM)entry);
+ }
+ }
+ else
+ {
+ // New plugin available for download
+ entry->State = PLUGIN_STATE_REMOTE;
+ PostMessage(context->DialogHandle, ID_UPDATE_ADD, 0, (LPARAM)entry);
+ }
+ }
+
+CleanupExit:
+
+ if (httpRequestHandle)
+ WinHttpCloseHandle(httpRequestHandle);
+
+ if (httpConnectionHandle)
+ WinHttpCloseHandle(httpConnectionHandle);
+
+ if (httpSessionHandle)
+ WinHttpCloseHandle(httpSessionHandle);
+
+ if (xmlStringBuffer)
+ PhFree(xmlStringBuffer);
+
+ PostMessage(context->DialogHandle, ID_UPDATE_COUNT, 0, 0);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS SetupExtractBuild(
+ _In_ PVOID Parameter
+ )
+{
+ static PH_STRINGREF pluginsDirectory = PH_STRINGREF_INIT(L"plugins\\");
+
+ mz_uint64 totalLength = 0;
+ mz_uint64 total_size = 0;
+ mz_uint64 downloadedBytes = 0;
+ PPH_STRING totalSizeStr = NULL;
+ mz_bool status = MZ_FALSE;
+ mz_zip_archive zip_archive;
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)Parameter;
+
+ memset(&zip_archive, 0, sizeof(zip_archive));
+
+ // TODO: Move existing folder items.
+
+ if (!(status = mz_zip_reader_init_file(&zip_archive, PhGetStringOrEmpty(context->SetupFilePath), 0)))
+ {
+ goto error;
+ }
+
+ for (mz_uint i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++)
+ {
+ mz_zip_archive_file_stat file_stat;
+
+ if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat))
+ {
+ //mz_zip_reader_end(&zip_archive);
+ break;
+ }
+
+ total_size += file_stat.m_uncomp_size;
+ }
+
+ totalSizeStr = PhFormatSize(total_size, -1);
+
+ for (ULONG i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++)
+ {
+ mz_zip_archive_file_stat stat;
+
+ if (!mz_zip_reader_file_stat(&zip_archive, i, &stat))
+ {
+ continue;
+ }
+
+ if (mz_zip_reader_is_file_a_directory(&zip_archive, i))
+ {
+ PPH_STRING directory;
+ PPH_STRING fileName;
+ PPH_STRING fullSetupPath;
+ PPH_STRING extractPath;
+ ULONG indexOfFileName = -1;
+
+ fileName = PhConvertUtf8ToUtf16(stat.m_filename);
+ directory = PhGetApplicationDirectory();
+ extractPath = PhConcatStringRef3(&directory->sr, &pluginsDirectory, &fileName->sr);
+ fullSetupPath = PhGetFullPath(PhGetStringOrEmpty(extractPath), &indexOfFileName);
+
+ SHCreateDirectoryEx(NULL, PhGetStringOrEmpty(fullSetupPath), NULL);
+ }
+ else
+ {
+ PPH_STRING directory;
+ PPH_STRING fileName;
+ PPH_STRING fullSetupPath;
+ PPH_STRING extractPath;
+ PPH_STRING directoryPath;
+ //PPH_STRING baseNameString;
+ PPH_STRING fileNameString;
+ ULONG indexOfFileName = -1;
+
+ fileName = PhConvertUtf8ToUtf16(stat.m_filename);
+ directory = PhGetApplicationDirectory();
+ extractPath = PhConcatStringRef3(&directory->sr, &pluginsDirectory, &fileName->sr);
+ fullSetupPath = PhGetFullPath(PhGetStringOrEmpty(extractPath), &indexOfFileName);
+ //baseNameString = PhGetBaseName(fullSetupPath);
+ //fullSetupPath = PhGetFullPath(PhGetStringOrEmpty(fileName), &indexOfFileName);
+ fileNameString = PhConcatStrings(2, fullSetupPath->Buffer, L".bak");
+
+ if (indexOfFileName != -1)
+ {
+ if (directoryPath = PhSubstring(fullSetupPath, 0, indexOfFileName))
+ {
+ SHCreateDirectoryEx(NULL, PhGetStringOrEmpty(directoryPath), NULL);
+ PhDereferenceObject(directoryPath);
+ }
+ }
+
+ if (RtlDoesFileExists_U(PhGetStringOrEmpty(fullSetupPath)))
+ {
+ MoveFileEx(PhGetString(fullSetupPath), PhGetString(fileNameString), MOVEFILE_REPLACE_EXISTING);
+ }
+
+ if (!mz_zip_reader_extract_to_file(&zip_archive, i, PhGetString(fullSetupPath), 0))
+ {
+ goto error;
+ }
+
+ PhDereferenceObject(fullSetupPath);
+ PhDereferenceObject(extractPath);
+ }
+ }
+
+ mz_zip_reader_end(&zip_archive);
+ return STATUS_SUCCESS;
+
+error:
+ mz_zip_reader_end(&zip_archive);
+ return STATUS_FAIL_CHECK;
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/dialog.c b/plugins-extra/ExtraPlugins/dialog.c
new file mode 100644
index 0000000..ee4d423
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/dialog.c
@@ -0,0 +1,752 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Plugin Manager
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+BOOLEAN WordMatchStringRef(
+ _In_ PWCT_CONTEXT Context,
+ _In_ PPH_STRINGREF Text
+ )
+{
+ PH_STRINGREF part;
+ PH_STRINGREF remainingPart;
+
+ remainingPart = Context->SearchboxText->sr;
+
+ while (remainingPart.Length)
+ {
+ PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart);
+
+ if (part.Length)
+ {
+ if (PhFindStringInStringRef(Text, &part, TRUE) != -1)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN WordMatchStringZ(
+ _In_ PWCT_CONTEXT Context,
+ _In_ PWSTR Text
+ )
+{
+ PH_STRINGREF text;
+
+ PhInitializeStringRef(&text, Text);
+ return WordMatchStringRef(Context, &text);
+}
+
+VOID UpdateTreeView(
+ _In_ PWCT_CONTEXT Context
+ )
+{
+ //PhSwapReference(&Context->TreeText, PhCreateString(L"Loading Plugins..."));
+ //TreeNew_SetEmptyText(Context->TreeNewHandle, &Context->TreeText->sr, 0);
+
+ PhApplyTreeNewFilters(Context->TreeFilter);
+ TreeNew_AutoSizeColumn(Context->TreeNewHandle, TREE_COLUMN_ITEM_NAME, TN_AUTOSIZE_REMAINING_SPACE);
+}
+
+VOID UpdateMenuView(_In_ PWCT_CONTEXT Context, UINT Id)
+{
+ HWND active = Context->PluginMenuActive;
+ Context->PluginMenuActiveId = Id;
+ Context->PluginMenuActive = GetDlgItem(Context->DialogHandle, Id);
+ RedrawWindow(active, NULL, NULL, RDW_ERASENOW | RDW_INVALIDATE | RDW_FRAME);
+}
+
+LRESULT DrawButton(
+ _In_ PWCT_CONTEXT Context,
+ _In_ LPARAM lParam
+ )
+{
+ LPNMTVCUSTOMDRAW drawInfo = (LPNMTVCUSTOMDRAW)lParam;
+ BOOLEAN isGrayed = (drawInfo->nmcd.uItemState & CDIS_GRAYED) == CDIS_GRAYED;
+ BOOLEAN isChecked = (drawInfo->nmcd.uItemState & CDIS_CHECKED) == CDIS_CHECKED;
+ BOOLEAN isDisabled = (drawInfo->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED;
+ BOOLEAN isSelected = (drawInfo->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED;
+ BOOLEAN isHighlighted = (drawInfo->nmcd.uItemState & CDIS_HOT) == CDIS_HOT;
+ BOOLEAN isFocused = (drawInfo->nmcd.uItemState & CDIS_FOCUS) == CDIS_FOCUS;
+
+ if (drawInfo->nmcd.dwDrawStage == CDDS_PREPAINT)
+ {
+ HPEN PenActive = CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
+ HPEN PenNormal = CreatePen(PS_SOLID, 1, RGB(0, 0xff, 0));
+ HBRUSH BrushNormal = GetSysColorBrush(COLOR_3DFACE);
+ HBRUSH BrushSelected = CreateSolidBrush(RGB(0xff, 0xff, 0xff));
+ HBRUSH BrushPushed = CreateSolidBrush(RGB(153, 209, 255));
+
+ PPH_STRING windowText = PH_AUTO(PhGetWindowText(drawInfo->nmcd.hdr.hwndFrom));
+
+ SetBkMode(drawInfo->nmcd.hdc, TRANSPARENT);
+
+ if (isHighlighted || Context->PluginMenuActiveId == drawInfo->nmcd.hdr.idFrom)
+ {
+ FillRect(drawInfo->nmcd.hdc, &drawInfo->nmcd.rc, BrushNormal);
+
+ SelectObject(drawInfo->nmcd.hdc, PenActive);
+ SelectObject(drawInfo->nmcd.hdc, Context->BoldFontHandle);
+ }
+ else if (isSelected)
+ {
+ FillRect(drawInfo->nmcd.hdc, &drawInfo->nmcd.rc, BrushPushed);
+
+ SelectObject(drawInfo->nmcd.hdc, PenActive);
+ SelectObject(drawInfo->nmcd.hdc, Context->BoldFontHandle);
+ }
+ else
+ {
+ FillRect(drawInfo->nmcd.hdc, &drawInfo->nmcd.rc, BrushNormal);
+ }
+
+ DrawText(
+ drawInfo->nmcd.hdc,
+ windowText->Buffer,
+ (ULONG)windowText->Length / 2,
+ &drawInfo->nmcd.rc,
+ DT_CENTER | DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE
+ );
+
+ MoveToEx(drawInfo->nmcd.hdc, drawInfo->nmcd.rc.left, drawInfo->nmcd.rc.bottom, 0);
+ LineTo(drawInfo->nmcd.hdc, drawInfo->nmcd.rc.right, drawInfo->nmcd.rc.bottom);
+
+ DeletePen(PenNormal);
+ DeletePen(PenActive);
+ DeleteBrush(BrushNormal);
+ DeleteBrush(BrushSelected);
+ DeleteBrush(BrushPushed);
+ return CDRF_SKIPDEFAULT;
+ }
+
+ return CDRF_DODEFAULT;
+}
+
+BOOLEAN ProcessTreeFilterCallback(
+ _In_ PPH_TREENEW_NODE Node,
+ _In_opt_ PVOID Context
+ )
+{
+ PWCT_CONTEXT context = Context;
+ PPLUGIN_NODE node = (PPLUGIN_NODE)Node;
+
+ // Hide plugins from different tabs
+ if (node->State != context->Type)
+ return FALSE;
+
+ // Hide uninstalled plugins from the local tab
+ //if (node->Type == PLUGIN_VIEW_LOCAL && node->State == PLUGIN_STATE_UNINSTALLED)
+ // return FALSE;
+
+ //// Hide installed plugins from the remote tab
+ //if (node->Type == PLUGIN_VIEW_REMOTE && node->State == PLUGIN_STATE_INSTALLED)
+ // return FALSE;
+
+ if (PhIsNullOrEmptyString(context->SearchboxText))
+ return TRUE;
+
+ if (!PhIsNullOrEmptyString(node->InternalName))
+ {
+ if (WordMatchStringRef(context, &node->InternalName->sr))
+ return TRUE;
+ }
+
+ if (!PhIsNullOrEmptyString(node->Id))
+ {
+ if (WordMatchStringRef(context, &node->Id->sr))
+ return TRUE;
+ }
+
+ if (!PhIsNullOrEmptyString(node->Name))
+ {
+ if (WordMatchStringRef(context, &node->Name->sr))
+ return TRUE;
+ }
+
+ if (!PhIsNullOrEmptyString(node->Version))
+ {
+ if (WordMatchStringRef(context, &node->Version->sr))
+ return TRUE;
+ }
+
+ if (!PhIsNullOrEmptyString(node->Author))
+ {
+ if (WordMatchStringRef(context, &node->Author->sr))
+ return TRUE;
+ }
+
+ if (!PhIsNullOrEmptyString(node->Description))
+ {
+ if (WordMatchStringRef(context, &node->Description->sr))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+INT_PTR CALLBACK CloudPluginsDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PWCT_CONTEXT context = NULL;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PWCT_CONTEXT)PhAllocate(sizeof(WCT_CONTEXT));
+ memset(context, 0, sizeof(WCT_CONTEXT));
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PWCT_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_DESTROY)
+ {
+ PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhDeleteLayoutManager(&context->LayoutManager);
+ PhUnregisterDialog(hwndDlg);
+ RemoveProp(hwndDlg, L"Context");
+ PhFree(context);
+
+ PostQuitMessage(0);
+ }
+ }
+
+ if (context == NULL)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ LOGFONT logFont;
+
+ context->DialogHandle = hwndDlg;
+ context->PluginMenuActiveId = IDC_INSTALLED;
+ context->PluginMenuActive = GetDlgItem(hwndDlg, IDC_INSTALLED);
+ context->TreeNewHandle = GetDlgItem(hwndDlg, IDC_PLUGINTREE);
+ context->SearchHandle = GetDlgItem(hwndDlg, IDC_SEARCHBOX);
+ context->SearchboxText = PhReferenceEmptyString();
+
+ CreateSearchControl(hwndDlg, context->SearchHandle, ID_SEARCH_CLEAR);
+
+ if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logFont, 0))
+ {
+ context->NormalFontHandle = CreateFont(
+ -PhMultiplyDivideSigned(-14, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_NORMAL,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+
+ context->BoldFontHandle = CreateFont(
+ -PhMultiplyDivideSigned(-16, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+ }
+
+ PhCenterWindow(hwndDlg, PhMainWndHandle);
+ WtcInitializeWindowTree(hwndDlg, context->TreeNewHandle, &context->TreeContext);
+ PhAddTreeNewFilter(context->TreeFilter = WtcGetTreeListFilterSupport(), (PPH_TN_FILTER_FUNCTION)ProcessTreeFilterCallback, context);
+
+ PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
+ PhAddLayoutItem(&context->LayoutManager, context->TreeNewHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&context->LayoutManager, context->SearchHandle, NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_CLEANUP), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_DISABLED), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+ PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+
+ EnumerateLoadedPlugins(context);
+ SetWindowText(GetDlgItem(hwndDlg, IDC_DISABLED), PhGetString(PhaFormatString(L"Disabled Plugins (%lu)", PhDisabledPluginsCount())));
+ PhQueueItemWorkQueue(PhGetGlobalWorkQueue(), QueryPluginsCallbackThread, context);
+ UpdateTreeView(context);
+
+ SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_INSTALLED), TRUE);
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&context->LayoutManager);
+ TreeNew_AutoSizeColumn(context->TreeNewHandle, TREE_COLUMN_ITEM_NAME, TN_AUTOSIZE_REMAINING_SPACE);
+ break;
+ case WM_COMMAND:
+ {
+ switch (GET_WM_COMMAND_CMD(wParam, lParam))
+ {
+ case EN_CHANGE:
+ {
+ PPH_STRING newSearchboxText;
+
+ newSearchboxText = PH_AUTO(PhGetWindowText(context->SearchHandle));
+
+ if (!PhEqualString(context->SearchboxText, newSearchboxText, FALSE))
+ {
+ // Cache the current search text for our callback.
+ PhSwapReference(&context->SearchboxText, newSearchboxText);
+
+ if (!PhIsNullOrEmptyString(context->SearchboxText))
+ {
+ // Expand the nodes to ensure that they will be visible to the user.
+ }
+
+ PhApplyTreeNewFilters(context->TreeFilter);
+ }
+ }
+ break;
+ }
+
+ switch (GET_WM_COMMAND_ID(wParam, lParam))
+ {
+ case ID_SEARCH_CLEAR:
+ {
+ if (context->SearchHandle)
+ {
+ SetFocus(context->SearchHandle);
+ Static_SetText(context->SearchHandle, L"");
+
+ UpdateTreeView(context);
+ }
+ }
+ break;
+ case IDC_INSTALLED:
+ {
+ context->Type = PLUGIN_STATE_LOCAL;
+
+ UpdateMenuView(context, IDC_INSTALLED);
+ UpdateTreeView(context);
+ }
+ break;
+ case IDC_BROWSE:
+ {
+ context->Type = PLUGIN_STATE_REMOTE;
+
+ UpdateMenuView(context, IDC_BROWSE);
+ UpdateTreeView(context);
+ }
+ break;
+ case IDC_UPDATES:
+ {
+ context->Type = PLUGIN_STATE_UPDATE;
+
+ UpdateMenuView(context, IDC_UPDATES);
+ UpdateTreeView(context);
+ }
+ break;
+ case WM_ACTION:
+ {
+ PPLUGIN_NODE selectedNode;
+
+ if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext))
+ {
+ if (selectedNode->State == PLUGIN_STATE_LOCAL)
+ {
+ if (selectedNode->PluginInstance && selectedNode->PluginInstance->Information.HasOptions)
+ {
+ PhInvokeCallback(PhGetPluginCallback((PPH_PLUGIN)selectedNode->PluginInstance, PluginCallbackShowOptions), hwndDlg);
+ }
+ }
+ else if (selectedNode->State == PLUGIN_STATE_REMOTE)
+ {
+ if (StartInitialCheck(hwndDlg, selectedNode, PLUGIN_ACTION_INSTALL))
+ {
+
+ }
+ }
+ else if (selectedNode->State == PLUGIN_STATE_UPDATE)
+ {
+ if (StartInitialCheck(hwndDlg, selectedNode, PLUGIN_ACTION_INSTALL))
+ {
+
+ }
+ }
+ }
+ }
+ break;
+ case ID_WCTSHOWCONTEXTMENU:
+ {
+ POINT cursorPos;
+ PPH_EMENU menu;
+ PPH_EMENU_ITEM selectedItem;
+ PPLUGIN_NODE selectedNode;
+
+ GetCursorPos(&cursorPos);
+
+ if (!(selectedNode = WeGetSelectedWindowNode(&context->TreeContext)))
+ break;
+
+ menu = PhCreateEMenu();
+
+ if (selectedNode->State == PLUGIN_STATE_LOCAL)
+ {
+ HICON shieldIcon;
+
+ shieldIcon = PhLoadIcon(NULL, IDI_SHIELD, PH_LOAD_ICON_SIZE_SMALL | PH_LOAD_ICON_STRICT, 0, 0);
+ selectedItem = PhCreateEMenuItem(0, ID_MENU_UNINSTALL, L"Uninstall", NULL, NULL);
+
+ if (shieldIcon)
+ {
+ selectedItem->Bitmap = PhIconToBitmap(
+ shieldIcon,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON)
+ );
+ DestroyIcon(shieldIcon);
+ }
+
+ PhInsertEMenuItem(menu, selectedItem, -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_MENU_DISABLE, L"Disable", NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_MENU_PROPERTIES, L"Options", NULL, NULL), -1);
+
+ if (!selectedNode->PluginInstance || !selectedNode->PluginInstance->Information.HasOptions)
+ {
+ PhSetFlagsEMenuItem(menu, ID_MENU_PROPERTIES, PH_EMENU_DISABLED, PH_EMENU_DISABLED);
+ }
+
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ PhSetFlagsEMenuItem(menu, ID_MENU_UNINSTALL, PH_EMENU_DISABLED, PH_EMENU_DISABLED);
+ }
+ }
+ else
+ {
+ HICON shieldIcon;
+
+ shieldIcon = PhLoadIcon(NULL, IDI_SHIELD, PH_LOAD_ICON_SIZE_SMALL | PH_LOAD_ICON_STRICT, 0, 0);
+ selectedItem = PhCreateEMenuItem(0, ID_MENU_INSTALL, PhaFormatString(L"Install %s plugin", PhGetStringOrEmpty(selectedNode->Name))->Buffer, NULL, NULL);
+
+ if (shieldIcon)
+ {
+ selectedItem->Bitmap = PhIconToBitmap(
+ shieldIcon,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON)
+ );
+ DestroyIcon(shieldIcon);
+ }
+
+ PhInsertEMenuItem(menu, selectedItem, -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(0, ID_MENU_DISABLE, L"Disable", NULL, NULL), -1);
+
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ PhSetFlagsEMenuItem(menu, ID_MENU_INSTALL, PH_EMENU_DISABLED, PH_EMENU_DISABLED);
+ }
+ }
+
+ selectedItem = PhShowEMenu(
+ menu,
+ hwndDlg,
+ PH_EMENU_SHOW_LEFTRIGHT,
+ PH_ALIGN_LEFT | PH_ALIGN_TOP,
+ cursorPos.x,
+ cursorPos.y
+ );
+
+ if (selectedItem && selectedItem->Id != -1)
+ {
+ switch (selectedItem->Id)
+ {
+ case ID_MENU_INSTALL:
+ {
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ //SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) };
+ //info.lpFile = L"ProcessHacker.exe";
+ //info.lpParameters = L"-plugin dmex.ExtraPlugins:INSTALL -plugin dmex.ExtraPlugins:hex64value";
+ //info.lpVerb = L"runas";
+ //info.nShow = SW_SHOW;
+ //info.hwnd = hwndDlg;
+
+ //if (!ShellExecuteEx(&info))
+ //{
+
+ //}
+ }
+ else
+ {
+ PPLUGIN_NODE selectedNode;
+ PPLUGIN_NODE existingNode;
+
+ if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext))
+ {
+ if (selectedNode->State == PLUGIN_STATE_LOCAL)
+ {
+ if (existingNode = FindTreeNode(
+ &context->TreeContext,
+ PLUGIN_STATE_REMOTE,
+ selectedNode->InternalName
+ ))
+ {
+ if (StartInitialCheck(hwndDlg, existingNode, PLUGIN_ACTION_INSTALL))
+ {
+
+ }
+ }
+
+ UpdateTreeView(context);
+ }
+ else
+ {
+ if (StartInitialCheck(hwndDlg, selectedNode, PLUGIN_ACTION_INSTALL))
+ {
+
+ }
+
+ if (existingNode = FindTreeNode(
+ &context->TreeContext,
+ PLUGIN_STATE_REMOTE,
+ selectedNode->InternalName
+ ))
+ {
+ selectedNode->State = PLUGIN_STATE_RESTART;
+ }
+
+ UpdateTreeView(context);
+ }
+ }
+ }
+ }
+ break;
+ case ID_MENU_UNINSTALL:
+ {
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ //SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) };
+ //info.lpFile = L"ProcessHacker.exe";
+ //info.lpParameters = L"-plugin dmex.ExtraPlugins:UNINSTALL -plugin dmex.ExtraPlugins:hex64value";
+ //info.lpVerb = L"runas";
+ //info.nShow = SW_SHOW;
+ //info.hwnd = hwndDlg;
+ //
+ //if (!ShellExecuteEx(&info))
+ //{
+ //
+ //}
+ }
+ else
+ {
+ PPLUGIN_NODE selectedNode;
+ PPLUGIN_NODE existingNode;
+
+ if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext))
+ {
+ if (StartInitialCheck(hwndDlg, selectedNode, PLUGIN_ACTION_UNINSTALL))
+ {
+ if (existingNode = FindTreeNode(
+ &context->TreeContext,
+ PLUGIN_STATE_LOCAL,
+ selectedNode->InternalName
+ ))
+ {
+ existingNode->State = PLUGIN_STATE_RESTART;
+ }
+ }
+
+ UpdateTreeView(context);
+ }
+ }
+ }
+ break;
+ case ID_MENU_DISABLE:
+ {
+ PPH_STRING baseName;
+
+ baseName = PhGetBaseName(selectedNode->FileName);
+
+ PhSetPluginDisabled(&baseName->sr, TRUE);
+
+ selectedNode->State = PLUGIN_STATE_RESTART;
+ UpdateTreeView(context);
+
+ SetWindowText(GetDlgItem(hwndDlg, IDC_DISABLED),
+ PhGetString(PhaFormatString(L"Disabled Plugins (%lu)", PhDisabledPluginsCount()))
+ );
+ }
+ break;
+ case ID_MENU_PROPERTIES:
+ {
+ if (selectedNode->PluginInstance)
+ {
+ PhInvokeCallback(PhGetPluginCallback((PPH_PLUGIN)selectedNode->PluginInstance, PluginCallbackShowOptions), hwndDlg);
+ }
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case IDCANCEL:
+ case IDOK:
+ {
+ //ShowUpdateDialog(hwndDlg, PLUGIN_ACTION_RESTART);
+
+ DestroyWindow(hwndDlg);
+ }
+ break;
+ case IDC_DISABLED:
+ {
+ ShowDisabledPluginsDialog(hwndDlg);
+
+ SetWindowText(GetDlgItem(hwndDlg, IDC_DISABLED),
+ PhGetString(PhaFormatString(L"Disabled Plugins (%lu)", PhDisabledPluginsCount()))
+ );
+ }
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR header = (LPNMHDR)lParam;
+
+ switch (header->code)
+ {
+ case NM_CUSTOMDRAW:
+ {
+ if (header->idFrom == IDC_INSTALLED || header->idFrom == IDC_BROWSE || header->idFrom == IDC_UPDATES)
+ {
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, DrawButton(context, lParam));
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case ID_UPDATE_ADD:
+ {
+ PPLUGIN_NODE entry = (PPLUGIN_NODE)lParam;
+
+ CloudAddChildWindowNode(&context->TreeContext, entry);
+
+ UpdateTreeView(context);
+ }
+ break;
+ case ID_UPDATE_COUNT:
+ {
+ ULONG count = 0;
+
+ for (ULONG i = 0; i < context->TreeContext.NodeList->Count; i++)
+ {
+ PPLUGIN_NODE windowNode = context->TreeContext.NodeList->Items[i];
+
+ if (windowNode->State == PLUGIN_STATE_UPDATE)
+ {
+ count++;
+ }
+ }
+
+ SetWindowText(GetDlgItem(hwndDlg, IDC_UPDATES), PhGetString(PhaFormatString(L"Updates (%lu)", count)));
+
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+NTSTATUS CloudDialogThread(
+ _In_ PVOID Parameter
+ )
+{
+ BOOL result;
+ MSG message;
+ HWND cloudDialogHandle;
+ PH_AUTO_POOL autoPool;
+
+ PhInitializeAutoPool(&autoPool);
+
+ cloudDialogHandle = CreateDialog(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_PLUGINS_DIALOG),
+ NULL,
+ CloudPluginsDlgProc
+ );
+
+ if (IsIconic(cloudDialogHandle))
+ ShowWindow(cloudDialogHandle, SW_RESTORE);
+ else
+ ShowWindow(cloudDialogHandle, SW_SHOW);
+
+ SetForegroundWindow(cloudDialogHandle);
+
+ while (result = GetMessage(&message, NULL, 0, 0))
+ {
+ if (result == -1)
+ break;
+
+ if (!IsDialogMessage(cloudDialogHandle, &message))
+ {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ }
+
+ PhDrainAutoPool(&autoPool);
+ }
+
+ PhDeleteAutoPool(&autoPool);
+
+ return STATUS_SUCCESS;
+}
+
+
+VOID ShowPluginManagerDialog(
+ VOID
+ )
+{
+ HANDLE threadHandle;
+
+ if (threadHandle = PhCreateThread(0, CloudDialogThread, NULL))
+ {
+ NtClose(threadHandle);
+ }
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/disabled.c b/plugins-extra/ExtraPlugins/disabled.c
new file mode 100644
index 0000000..79f6caa
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/disabled.c
@@ -0,0 +1,184 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Plugin Manager
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+VOID PhAddDisabledPlugins(
+ _In_ PPLUGIN_DISABLED_CONTEXT Context
+ )
+{
+ PPH_STRING disabled;
+ PH_STRINGREF remainingPart;
+ PH_STRINGREF part;
+ PPH_STRING displayText;
+ INT lvItemIndex;
+
+ disabled = PhGetStringSetting(L"DisabledPlugins");
+ remainingPart = disabled->sr;
+
+ while (remainingPart.Length)
+ {
+ PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart);
+
+ if (part.Length)
+ {
+ displayText = PhCreateString2(&part);
+
+ PhAcquireQueuedLockExclusive(&Context->ListLock);
+ lvItemIndex = PhAddListViewItem(Context->ListViewHandle, MAXINT, PhGetString(displayText), displayText);
+ PhReleaseQueuedLockExclusive(&Context->ListLock);
+
+ ListView_SetItemState(Context->ListViewHandle, lvItemIndex, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
+ }
+ }
+
+ PhDereferenceObject(disabled);
+}
+
+INT_PTR CALLBACK DisabledPluginsDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PPLUGIN_DISABLED_CONTEXT context = NULL;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PPLUGIN_DISABLED_CONTEXT)PhAllocate(sizeof(PLUGIN_DISABLED_CONTEXT));
+ memset(context, 0, sizeof(PLUGIN_DISABLED_CONTEXT));
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PPLUGIN_DISABLED_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_DESTROY)
+ {
+ PhDeleteLayoutManager(&context->LayoutManager);
+ PhUnregisterDialog(hwndDlg);
+ RemoveProp(hwndDlg, L"Context");
+ PhFree(context);
+ }
+ }
+
+ if (context == NULL)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ context->DialogHandle = hwndDlg;
+ context->ListViewHandle = GetDlgItem(hwndDlg, IDC_LIST_DISABLED);
+
+ PhCenterWindow(hwndDlg, GetParent(hwndDlg));
+
+ PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
+ ListView_SetExtendedListViewStyleEx(context->ListViewHandle,
+ LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER,
+ LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
+ PhSetControlTheme(context->ListViewHandle, L"explorer");
+ PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 400, L"Property");
+ PhSetExtendedListView(context->ListViewHandle);
+
+ PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
+ PhAddLayoutItem(&context->LayoutManager, context->ListViewHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+
+ PhAddDisabledPlugins(context);
+
+ SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDOK), TRUE);
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&context->LayoutManager);
+ break;
+ case WM_COMMAND:
+ {
+ switch (GET_WM_COMMAND_ID(wParam, lParam))
+ {
+ case IDCANCEL:
+ case IDOK:
+ {
+ EndDialog(hwndDlg, IDOK);
+ }
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR header = (LPNMHDR)lParam;
+
+ if (header->code == LVN_ITEMCHANGED)
+ {
+ LPNM_LISTVIEW listView = (LPNM_LISTVIEW)lParam;
+
+ if (!PhTryAcquireReleaseQueuedLockExclusive(&context->ListLock))
+ break;
+
+ if (listView->uChanged & LVIF_STATE)
+ {
+ switch (listView->uNewState & LVIS_STATEIMAGEMASK)
+ {
+ case 0x2000: // checked
+ {
+ PPH_STRING param = (PPH_STRING)listView->lParam;
+
+ PhSetPluginDisabled(¶m->sr, TRUE);
+
+ //context->OptionsChanged = TRUE;
+ }
+ break;
+ case 0x1000: // unchecked
+ {
+ PPH_STRING param = (PPH_STRING)listView->lParam;
+
+ PhSetPluginDisabled(¶m->sr, FALSE);
+
+ //context->OptionsChanged = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID ShowDisabledPluginsDialog(
+ _In_ HWND Parent
+ )
+{
+ DialogBox(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_DIALOG1),
+ Parent,
+ DisabledPluginsDlgProc
+ );
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/json-c/AUTHORS b/plugins-extra/ExtraPlugins/json-c/AUTHORS
new file mode 100644
index 0000000..b389989
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/AUTHORS
@@ -0,0 +1,5 @@
+Michael Clark
+Jehiah Czebotar
+Eric Haszlakiewicz
+C. Watford (christopher.watford@gmail.com)
+
diff --git a/plugins-extra/ExtraPlugins/json-c/COPYING b/plugins-extra/ExtraPlugins/json-c/COPYING
new file mode 100644
index 0000000..740d125
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/COPYING
@@ -0,0 +1,42 @@
+
+Copyright (c) 2009-2012 Eric Haszlakiewicz
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+----------------------------------------------------------------
+
+Copyright (c) 2004, 2005 Metaparadigm Pte Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/plugins-extra/ExtraPlugins/json-c/ChangeLog b/plugins-extra/ExtraPlugins/json-c/ChangeLog
new file mode 100644
index 0000000..451b8f6
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/ChangeLog
@@ -0,0 +1,214 @@
+
+0.12
+
+ * Address security issues:
+ * CVE-2013-6371: hash collision denial of service
+ * CVE-2013-6370: buffer overflow if size_t is larger than int
+
+ * Avoid potential overflow in json_object_get_double
+
+ * Eliminate the mc_abort() function and MC_ABORT macro.
+
+ * Make the json_tokener_errors array local. It has been deprecated for
+ a while, and json_tokener_error_desc() should be used instead.
+
+ * change the floating point output format to %.17g so values with
+ more than 6 digits show up in the output.
+
+ * Remove the old libjson.so name compatibility support. The library is
+ only created as libjson-c.so now and headers are only installed
+ into the ${prefix}/json-c directory.
+
+ * When supported by the linker, add the -Bsymbolic-functions flag.
+
+ * Various changes to fix the build on MSVC.
+
+ * Make strict mode more strict:
+ * number must not start with 0
+ * no single-quote strings
+ * no comments
+ * trailing char not allowed
+ * only allow lowercase literals
+
+ * Added a json_object_new_double_s() convenience function to allow
+ an exact string representation of a double to be specified when
+ creating the object and use it in json_tokener_parse_ex() so
+ a re-serialized object more exactly matches the input.
+
+ * Add support NaN and Infinity
+
+
+0.11
+
+ * IMPORTANT: the name of the library has changed to libjson-c.so and
+ the header files are now in include/json-c.
+ The pkgconfig name has also changed from json to json-c.
+ You should change your build to use appropriate -I and -l options.
+ A compatibility shim is in place so builds using the old name will
+ continue to work, but that will be removed in the next release.
+ * Maximum recursion depth is now a runtime option.
+ json_tokener_new() is provided for compatibility.
+ json_tokener_new_ex(depth)
+ * Include json_object_iterator.h in the installed headers.
+ * Add support for building on Android.
+ * Rewrite json_object_object_add to replace just the value if the key already exists so keys remain valid.
+ * Make it safe to delete keys while iterating with the json_object_object_foreach macro.
+ * Add a json_set_serializer() function to allow the string output of a json_object to be customized.
+ * Make float parsing locale independent.
+ * Add a json_tokener_set_flags() function and a JSON_TOKENER_STRICT flag.
+ * Enable -Werror when building.
+ * speed improvements to parsing 64-bit integers on systems with working sscanf
+ * Add a json_object_object_length function.
+ * Fix a bug (buffer overrun) when expanding arrays to more than 64 entries.
+
+0.10
+
+ * Add a json_object_to_json_string_ext() function to allow output to be
+ formatted in a more human readable form.
+ * Add json_object_object_get_ex(), a NULL-safe get object method, to be able
+ to distinguish between a key not present and the value being NULL.
+ * Add an alternative iterator implementation, see json_object_iterator.h
+ * Make json_object_iter public to enable external use of the
+ json_object_object_foreachC macro.
+ * Add a printbuf_memset() function to provide an effecient way to set and
+ append things like whitespace indentation.
+ * Adjust json_object_is_type and json_object_get_type so they return
+ json_type_null for NULL objects and handle NULL passed to
+ json_objct_object_get().
+ * Rename boolean type to json_bool.
+ * Fix various compile issues for Visual Studio and MinGW.
+ * Allow json_tokener_parse_ex() to be re-used to parse multiple object.
+ Also, fix some parsing issues with capitalized hexadecimal numbers and
+ number in E notation.
+ * Add json_tokener_get_error() and json_tokener_error_desc() to better
+ encapsulate the process of retrieving errors while parsing.
+ * Various improvements to the documentation of many functions.
+ * Add new json_object_array_sort() function.
+ * Fix a bug in json_object_get_int(), which would incorrectly return 0
+ when called on a string type object.
+ Eric Haszlakiewicz
+ * Add a json_type_to_name() function.
+ Eric Haszlakiewicz
+ * Add a json_tokener_parse_verbose() function.
+ Jehiah Czebotar
+ * Improve support for null bytes within JSON strings.
+ Jehiah Czebotar
+ * Fix file descriptor leak if memory allocation fails in json_util
+ Zachary Blair, zack_blair at hotmail dot com
+ * Add int64 support. Two new functions json_object_net_int64 and
+ json_object_get_int64. Binary compatibility preserved.
+ Eric Haszlakiewicz, EHASZLA at transunion com
+ Rui Miguel Silva Seabra, rms at 1407 dot org
+ * Fix subtle bug in linkhash where lookup could hang after all slots
+ were filled then successively freed.
+ Spotted by Jean-Marc Naud, j dash m at newtraxtech dot com
+ * Make json_object_from_file take const char *filename
+ Spotted by Vikram Raj V, vsagar at attinteractive dot com
+ * Add handling of surrogate pairs (json_tokener.c, test4.c, Makefile.am)
+ Brent Miller, bdmiller at yahoo dash inc dot com
+ * Correction to comment describing printbuf_memappend in printbuf.h
+ Brent Miller, bdmiller at yahoo dash inc dot com
+
+0.9
+ * Add README.html README-WIN32.html config.h.win32 to Makefile.am
+ Michael Clark,
+ * Add const qualifier to the json_tokener_parse functions
+ Eric Haszlakiewicz, EHASZLA at transunion dot com
+ * Rename min and max so we can never clash with C or C++ std library
+ Ian Atha, thatha at yahoo dash inc dot com
+ * Fix any noticeable spelling or grammar errors.
+ * Make sure every va_start has a va_end.
+ * Check all pointers for validity.
+ Erik Hovland, erik at hovland dot org
+ * Fix json_object_get_boolean to return false for empty string
+ Spotted by Vitaly Kruglikov, Vitaly dot Kruglikov at palm dot com
+ * optimizations to json_tokener_parse_ex(), printbuf_memappend()
+ Brent Miller, bdmiller at yahoo dash inc dot com
+ * Disable REFCOUNT_DEBUG by default in json_object.c
+ * Don't use this as a variable, so we can compile with a C++ compiler
+ * Add casts from void* to type of assignment when using malloc
+ * Add #ifdef __cplusplus guards to all of the headers
+ * Add typedefs for json_object, json_tokener, array_list, printbuf, lh_table
+ Michael Clark,
+ * Null pointer dereference fix. Fix json_object_get_boolean strlen test
+ to not return TRUE for zero length string. Remove redundant includes.
+ Erik Hovland, erik at hovland dot org
+ * Fixed warning reported by adding -Wstrict-prototypes
+ -Wold-style-definition to the compilatin flags.
+ Dotan Barak, dotanba at gmail dot com
+ * Add const correctness to public interfaces
+ Gerard Krol, g dot c dot krol at student dot tudelft dot nl
+
+0.8
+ * Add va_end for every va_start
+ Dotan Barak, dotanba at gmail dot com
+ * Add macros to enable compiling out debug code
+ Geoffrey Young, geoff at modperlcookbook dot org
+ * Fix bug with use of capital E in numbers with exponents
+ Mateusz Loskot, mateusz at loskot dot net
+ * Add stddef.h include
+ * Patch allows for json-c compile with -Werror and not fail due to
+ -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
+ Geoffrey Young, geoff at modperlcookbook dot org
+
+0.7
+ * Add escaping of backslash to json output
+ * Add escaping of foward slash on tokenizing and output
+ * Changes to internal tokenizer from using recursion to
+ using a depth state structure to allow incremental parsing
+
+0.6
+ * Fix bug in escaping of control characters
+ Johan Björklund, johbjo09 at kth dot se
+ * Remove include "config.h" from headers (should only
+ be included from .c files)
+ Michael Clark
+
+0.5
+ * Make headers C++ compatible by change *this to *obj
+ * Add ifdef C++ extern "C" to headers
+ * Use simpler definition of min and max in bits.h
+ Larry Lansing, llansing at fuzzynerd dot com
+
+ * Remove automake 1.6 requirement
+ * Move autogen commands into autogen.sh. Update README
+ * Remove error pointer special case for Windows
+ * Change license from LGPL to MIT
+ Michael Clark
+
+0.4
+ * Fix additional error case in object parsing
+ * Add back sign reversal in nested object parse as error pointer
+ value is negative, while error value is positive.
+ Michael Clark
+
+0.3
+ * fix pointer arithmetic bug for error pointer check in is_error() macro
+ * fix type passed to printbuf_memappend in json_tokener
+ * update autotools bootstrap instructions in README
+ Michael Clark
+
+0.2
+ * printbuf.c - C. Watford (christopher.watford@gmail.com)
+ Added a Win32/Win64 compliant implementation of vasprintf
+ * debug.c - C. Watford (christopher.watford@gmail.com)
+ Removed usage of vsyslog on Win32/Win64 systems, needs to be handled
+ by a configure script
+ * json_object.c - C. Watford (christopher.watford@gmail.com)
+ Added scope operator to wrap usage of json_object_object_foreach, this
+ needs to be rethought to be more ANSI C friendly
+ * json_object.h - C. Watford (christopher.watford@gmail.com)
+ Added Microsoft C friendly version of json_object_object_foreach
+ * json_tokener.c - C. Watford (christopher.watford@gmail.com)
+ Added a Win32/Win64 compliant implementation of strndup
+ * json_util.c - C. Watford (christopher.watford@gmail.com)
+ Added cast and mask to suffice size_t v. unsigned int conversion
+ correctness
+ * json_tokener.c - sign reversal issue on error info for nested object parse
+ spotted by Johan Björklund (johbjo09 at kth.se)
+ * json_object.c - escape " in json_escape_str
+ * Change to automake and libtool to build shared and static library
+ Michael Clark
+
+0.1
+ * initial release
diff --git a/plugins-extra/ExtraPlugins/json-c/arraylist.c b/plugins-extra/ExtraPlugins/json-c/arraylist.c
new file mode 100644
index 0000000..97f2c92
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/arraylist.c
@@ -0,0 +1,101 @@
+/*
+ * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#ifdef STDC_HEADERS
+# include
+# include
+#endif /* STDC_HEADERS */
+
+#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD)
+# include
+#endif /* HAVE_STRINGS_H */
+
+#include "bits.h"
+#include "arraylist.h"
+
+struct array_list*
+array_list_new(array_list_free_fn *free_fn)
+{
+ struct array_list *arr;
+
+ arr = (struct array_list*)calloc(1, sizeof(struct array_list));
+ if(!arr) return NULL;
+ arr->size = ARRAY_LIST_DEFAULT_SIZE;
+ arr->length = 0;
+ arr->free_fn = free_fn;
+ if(!(arr->array = (void**)calloc(sizeof(void*), arr->size))) {
+ free(arr);
+ return NULL;
+ }
+ return arr;
+}
+
+extern void
+array_list_free(struct array_list *arr)
+{
+ int i;
+ for(i = 0; i < arr->length; i++)
+ if(arr->array[i]) arr->free_fn(arr->array[i]);
+ free(arr->array);
+ free(arr);
+}
+
+void*
+array_list_get_idx(struct array_list *arr, int i)
+{
+ if(i >= arr->length) return NULL;
+ return arr->array[i];
+}
+
+static int array_list_expand_internal(struct array_list *arr, int max)
+{
+ void *t;
+ int new_size;
+
+ if(max < arr->size) return 0;
+ new_size = json_max(arr->size << 1, max);
+ if(!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
+ arr->array = (void**)t;
+ (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
+ arr->size = new_size;
+ return 0;
+}
+
+int
+array_list_put_idx(struct array_list *arr, int idx, void *data)
+{
+ if(array_list_expand_internal(arr, idx+1)) return -1;
+ if(arr->array[idx]) arr->free_fn(arr->array[idx]);
+ arr->array[idx] = data;
+ if(arr->length <= idx) arr->length = idx + 1;
+ return 0;
+}
+
+int
+array_list_add(struct array_list *arr, void *data)
+{
+ return array_list_put_idx(arr, arr->length, data);
+}
+
+void
+array_list_sort(struct array_list *arr, int(__cdecl* sort_fn)(const void *, const void *))
+{
+ qsort(arr->array, arr->length, sizeof(arr->array[0]),
+ (int (__cdecl*)(const void *, const void *))sort_fn);
+}
+
+int
+array_list_length(struct array_list *arr)
+{
+ return arr->length;
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/arraylist.h b/plugins-extra/ExtraPlugins/json-c/arraylist.h
new file mode 100644
index 0000000..089be0b
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/arraylist.h
@@ -0,0 +1,56 @@
+/*
+ * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _arraylist_h_
+#define _arraylist_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARRAY_LIST_DEFAULT_SIZE 32
+
+typedef void (array_list_free_fn) (void *data);
+
+struct array_list
+{
+ void **array;
+ int length;
+ int size;
+ array_list_free_fn *free_fn;
+};
+
+extern struct array_list*
+array_list_new(array_list_free_fn *free_fn);
+
+extern void
+array_list_free(struct array_list *al);
+
+extern void*
+array_list_get_idx(struct array_list *al, int i);
+
+extern int
+array_list_put_idx(struct array_list *al, int i, void *data);
+
+extern int
+array_list_add(struct array_list *al, void *data);
+
+extern int
+array_list_length(struct array_list *al);
+
+extern void
+array_list_sort(struct array_list *arr, int(__cdecl* compar)(const void *, const void *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/bits.h b/plugins-extra/ExtraPlugins/json-c/bits.h
new file mode 100644
index 0000000..c8cbbc8
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/bits.h
@@ -0,0 +1,28 @@
+/*
+ * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _bits_h_
+#define _bits_h_
+
+#ifndef json_min
+#define json_min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef json_max
+#define json_max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
+#define error_ptr(error) ((void*)error)
+#define error_description(error) (json_tokener_errors[error])
+#define is_error(ptr) (ptr == NULL)
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/config.h b/plugins-extra/ExtraPlugins/json-c/config.h
new file mode 100644
index 0000000..df46f0a
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/config.h
@@ -0,0 +1,89 @@
+#define PACKAGE_STRING "JSON C Library 0.12-20140410"
+#define PACKAGE_BUGREPORT "json-c@googlegroups.com"
+#define PACKAGE_NAME "JSON C Library"
+#define PACKAGE_TARNAME "json-c"
+#define PACKAGE_VERSION "0.12-20140410"
+
+
+#define HAVE_SETLOCALE 1
+#define HAVE_LOCALE_H 1
+
+#define HAVE_DECL_NAN 1
+#define HAVE_DECL_INFINITY 1
+//#define HAVE_DECL__ISNAN 1
+//#define HAVE_DECL__FINITE 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `open' function. */
+#define HAVE_OPEN 1
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#define HAVE_REALLOC 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the `vsyslog' function. */
+#undef HAVE_VSYSLOG
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
diff --git a/plugins-extra/ExtraPlugins/json-c/config.h.in b/plugins-extra/ExtraPlugins/json-c/config.h.in
new file mode 100644
index 0000000..0dcab1a
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/config.h.in
@@ -0,0 +1,174 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Enable RDRANR Hardware RNG Hash Seed */
+#undef ENABLE_RDRAND
+
+/* Define if .gnu.warning accepts long strings. */
+#undef HAS_GNU_WARNING_LONG
+
+/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
+ don't. */
+#undef HAVE_DECL_INFINITY
+
+/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
+ */
+#undef HAVE_DECL_ISINF
+
+/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
+ */
+#undef HAVE_DECL_ISNAN
+
+/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
+#undef HAVE_DECL_NAN
+
+/* Define to 1 if you have the declaration of `_finite', and to 0 if you
+ don't. */
+#undef HAVE_DECL__FINITE
+
+/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
+ */
+#undef HAVE_DECL__ISNAN
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `open' function. */
+#undef HAVE_OPEN
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#undef HAVE_REALLOC
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_CDEFS_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `vsyslog' function. */
+#undef HAVE_VSYSLOG
+
+/* Public define for json_inttypes.h */
+#undef JSON_C_HAVE_INTTYPES_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to rpl_realloc if the replacement function should be used. */
+#undef realloc
+
+/* Define to `unsigned int' if does not define. */
+#undef size_t
diff --git a/plugins-extra/ExtraPlugins/json-c/debug.c b/plugins-extra/ExtraPlugins/json-c/debug.c
new file mode 100644
index 0000000..9dff781
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/debug.c
@@ -0,0 +1,83 @@
+/*
+ * $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+
+#if HAVE_SYSLOG_H
+# include
+#endif /* HAVE_SYSLOG_H */
+
+#if HAVE_UNISTD_H
+# include
+#endif /* HAVE_UNISTD_H */
+
+#if HAVE_SYS_PARAM_H
+#include
+#endif /* HAVE_SYS_PARAM_H */
+
+#include "debug.h"
+
+static int _syslog = 0;
+static int _debug = 0;
+
+void mc_set_debug(int debug) { _debug = debug; }
+int mc_get_debug(void) { return _debug; }
+
+extern void mc_set_syslog(int syslog)
+{
+ _syslog = syslog;
+}
+
+void mc_debug(const char *msg, ...)
+{
+ va_list ap;
+ if(_debug) {
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_DEBUG, msg, ap);
+ } else
+#endif
+ vprintf(msg, ap);
+ va_end(ap);
+ }
+}
+
+void mc_error(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_ERR, msg, ap);
+ } else
+#endif
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+}
+
+void mc_info(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_INFO, msg, ap);
+ } else
+#endif
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/debug.h b/plugins-extra/ExtraPlugins/json-c/debug.h
new file mode 100644
index 0000000..80ca3e4
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/debug.h
@@ -0,0 +1,71 @@
+/*
+ * $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void mc_set_debug(int debug);
+extern int mc_get_debug(void);
+
+extern void mc_set_syslog(int syslog);
+
+extern void mc_debug(const char *msg, ...);
+extern void mc_error(const char *msg, ...);
+extern void mc_info(const char *msg, ...);
+
+#ifndef __STRING
+#define __STRING(x) #x
+#endif
+
+#ifndef PARSER_BROKEN_FIXED
+
+#define JASSERT(cond) do {} while(0)
+
+#else
+
+#define JASSERT(cond) do { \
+ if (!(cond)) { \
+ mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
+ *(int *)0 = 1;\
+ abort(); \
+ }\
+ } while(0)
+
+#endif
+
+#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__)
+
+#ifdef MC_MAINTAINER_MODE
+#define MC_SET_DEBUG(x) mc_set_debug(x)
+#define MC_GET_DEBUG() mc_get_debug()
+#define MC_SET_SYSLOG(x) mc_set_syslog(x)
+#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
+#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
+#else
+#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
+#define MC_GET_DEBUG() (0)
+#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
+#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
+#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json.h b/plugins-extra/ExtraPlugins/json-c/json.h
new file mode 100644
index 0000000..4339b20
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json.h
@@ -0,0 +1,34 @@
+/*
+ * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_h_
+#define _json_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bits.h"
+#include "debug.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_util.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_object_iterator.h"
+#include "json_c_version.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_c_version.c b/plugins-extra/ExtraPlugins/json-c/json_c_version.c
new file mode 100644
index 0000000..13eb188
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_c_version.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+#include "config.h"
+
+#include "json_c_version.h"
+
+const char *json_c_version(void)
+{
+ return JSON_C_VERSION;
+}
+
+int json_c_version_num(void)
+{
+ return JSON_C_VERSION_NUM;
+}
+
diff --git a/plugins-extra/ExtraPlugins/json-c/json_c_version.h b/plugins-extra/ExtraPlugins/json-c/json_c_version.h
new file mode 100644
index 0000000..eed98a4
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_c_version.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Eric Haszlakiewicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+
+#ifndef _json_c_version_h_
+#define _json_c_version_h_
+
+#define JSON_C_MAJOR_VERSION 0
+#define JSON_C_MINOR_VERSION 12
+#define JSON_C_MICRO_VERSION 0
+#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
+ (JSON_C_MINOR_VERSION << 8) | \
+ JSON_C_MICRO_VERSION)
+#define JSON_C_VERSION "0.12"
+
+const char *json_c_version(void); /* Returns JSON_C_VERSION */
+int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_config.h b/plugins-extra/ExtraPlugins/json-c/json_config.h
new file mode 100644
index 0000000..405fda2
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_config.h
@@ -0,0 +1,3 @@
+
+/* Define to 1 if you have the header file. */
+#define JSON_C_HAVE_INTTYPES_H 1
diff --git a/plugins-extra/ExtraPlugins/json-c/json_inttypes.h b/plugins-extra/ExtraPlugins/json-c/json_inttypes.h
new file mode 100644
index 0000000..9de8d24
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_inttypes.h
@@ -0,0 +1,28 @@
+
+#ifndef _json_inttypes_h_
+#define _json_inttypes_h_
+
+#include "json_config.h"
+
+#if defined(_MSC_VER) && _MSC_VER <= 1700
+
+/* Anything less than Visual Studio C++ 10 is missing stdint.h and inttypes.h */
+typedef __int32 int32_t;
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX ((int32_t)_I32_MAX)
+typedef __int64 int64_t;
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX ((int64_t)_I64_MAX)
+#define PRId64 "I64d"
+#define SCNd64 "I64d"
+
+#else
+
+#ifdef JSON_C_HAVE_INTTYPES_H
+#include
+#endif
+/* inttypes.h includes stdint.h */
+
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_object.c b/plugins-extra/ExtraPlugins/json-c/json_object.c
new file mode 100644
index 0000000..57f3f0d
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_object.c
@@ -0,0 +1,860 @@
+/*
+ * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "debug.h"
+#include "printbuf.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_object_private.h"
+#include "json_util.h"
+#include "math_compat.h"
+
+#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
+ /* MSC has the version as _strdup */
+# define strdup _strdup
+#elif !defined(HAVE_STRDUP)
+# error You do not have strdup on your system.
+#endif /* HAVE_STRDUP */
+
+#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
+ /* MSC has the version as _snprintf */
+# define snprintf _snprintf
+#elif !defined(HAVE_SNPRINTF)
+# error You do not have snprintf on your system.
+#endif /* HAVE_SNPRINTF */
+
+// Don't define this. It's not thread-safe.
+/* #define REFCOUNT_DEBUG 1 */
+
+const char *json_number_chars = "0123456789.+-eE";
+const char *json_hex_chars = "0123456789abcdefABCDEF";
+
+static void json_object_generic_delete(struct json_object* jso);
+static struct json_object* json_object_new(enum json_type o_type);
+
+static json_object_to_json_string_fn json_object_object_to_json_string;
+static json_object_to_json_string_fn json_object_boolean_to_json_string;
+static json_object_to_json_string_fn json_object_int_to_json_string;
+static json_object_to_json_string_fn json_object_double_to_json_string;
+static json_object_to_json_string_fn json_object_string_to_json_string;
+static json_object_to_json_string_fn json_object_array_to_json_string;
+
+
+/* ref count debugging */
+
+#ifdef REFCOUNT_DEBUG
+
+static struct lh_table *json_object_table;
+
+static void json_object_init(void) __attribute__ ((constructor));
+static void json_object_init(void) {
+ MC_DEBUG("json_object_init: creating object table\n");
+ json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
+}
+
+static void json_object_fini(void) __attribute__ ((destructor));
+static void json_object_fini(void) {
+ struct lh_entry *ent;
+ if(MC_GET_DEBUG()) {
+ if (json_object_table->count) {
+ MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
+ json_object_table->count);
+ lh_foreach(json_object_table, ent) {
+ struct json_object* obj = (struct json_object*)ent->v;
+ MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
+ }
+ }
+ }
+ MC_DEBUG("json_object_fini: freeing object table\n");
+ lh_table_free(json_object_table);
+}
+#endif /* REFCOUNT_DEBUG */
+
+
+/* string escaping */
+
+static int json_escape_str(struct printbuf *pb, char *str, size_t len)
+{
+ int pos = 0, start_offset = 0;
+ unsigned char c;
+ while (len--) {
+ c = str[pos];
+ switch(c) {
+ case '\b':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\f':
+ case '"':
+ case '\\':
+ case '/':
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ if(c == '\b') printbuf_memappend(pb, "\\b", 2);
+ else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
+ else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
+ else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
+ else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
+ else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
+ else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
+ else if(c == '/') printbuf_memappend(pb, "\\/", 2);
+ start_offset = ++pos;
+ break;
+ default:
+ if(c < ' ') {
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ sprintbuf(pb, "\\u00%c%c",
+ json_hex_chars[c >> 4],
+ json_hex_chars[c & 0xf]);
+ start_offset = ++pos;
+ } else pos++;
+ }
+ }
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ return 0;
+}
+
+
+/* reference counting */
+
+extern struct json_object* json_object_get(struct json_object *jso)
+{
+ if(jso) {
+ jso->_ref_count++;
+ }
+ return jso;
+}
+
+int json_object_put(struct json_object *jso)
+{
+ if(jso)
+ {
+ jso->_ref_count--;
+ if(!jso->_ref_count)
+ {
+ if (jso->_user_delete)
+ jso->_user_delete(jso, jso->_userdata);
+ jso->_delete(jso);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* generic object construction and destruction parts */
+
+static void json_object_generic_delete(struct json_object* jso)
+{
+#ifdef REFCOUNT_DEBUG
+ MC_DEBUG("json_object_delete_%s: %p\n",
+ json_type_to_name(jso->o_type), jso);
+ lh_table_delete(json_object_table, jso);
+#endif /* REFCOUNT_DEBUG */
+ printbuf_free(jso->_pb);
+ free(jso);
+}
+
+static struct json_object* json_object_new(enum json_type o_type)
+{
+ struct json_object *jso;
+
+ jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
+ if(!jso) return NULL;
+ jso->o_type = o_type;
+ jso->_ref_count = 1;
+ jso->_delete = &json_object_generic_delete;
+#ifdef REFCOUNT_DEBUG
+ lh_table_insert(json_object_table, jso, jso);
+ MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
+#endif /* REFCOUNT_DEBUG */
+ return jso;
+}
+
+
+/* type checking functions */
+
+int json_object_is_type(struct json_object *jso, enum json_type type)
+{
+ if (!jso)
+ return (type == json_type_null);
+ return (jso->o_type == type);
+}
+
+enum json_type json_object_get_type(struct json_object *jso)
+{
+ if (!jso)
+ return json_type_null;
+ return jso->o_type;
+}
+
+/* set a custom conversion to string */
+
+void json_object_set_serializer(json_object *jso,
+ json_object_to_json_string_fn to_string_func,
+ void *userdata,
+ json_object_delete_fn *user_delete)
+{
+ // First, clean up any previously existing user info
+ if (jso->_user_delete)
+ {
+ jso->_user_delete(jso, jso->_userdata);
+ }
+ jso->_userdata = NULL;
+ jso->_user_delete = NULL;
+
+ if (to_string_func == NULL)
+ {
+ // Reset to the standard serialization function
+ switch(jso->o_type)
+ {
+ case json_type_null:
+ jso->_to_json_string = NULL;
+ break;
+ case json_type_boolean:
+ jso->_to_json_string = &json_object_boolean_to_json_string;
+ break;
+ case json_type_double:
+ jso->_to_json_string = &json_object_double_to_json_string;
+ break;
+ case json_type_int:
+ jso->_to_json_string = &json_object_int_to_json_string;
+ break;
+ case json_type_object:
+ jso->_to_json_string = &json_object_object_to_json_string;
+ break;
+ case json_type_array:
+ jso->_to_json_string = &json_object_array_to_json_string;
+ break;
+ case json_type_string:
+ jso->_to_json_string = &json_object_string_to_json_string;
+ break;
+ }
+ return;
+ }
+
+ jso->_to_json_string = to_string_func;
+ jso->_userdata = userdata;
+ jso->_user_delete = user_delete;
+}
+
+
+/* extended conversion to string */
+
+char* json_object_to_json_string_ext(struct json_object *jso, int flags)
+{
+ if (!jso)
+ return "null";
+
+ if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
+ return NULL;
+
+ printbuf_reset(jso->_pb);
+
+ if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
+ return NULL;
+
+ return jso->_pb->buf;
+}
+
+/* backwards-compatible conversion to string */
+
+char* json_object_to_json_string(struct json_object *jso)
+{
+ return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
+}
+
+static void indent(struct printbuf *pb, int level, int flags)
+{
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ {
+ printbuf_memset(pb, -1, ' ', level * 2);
+ }
+}
+
+/* json_object_object */
+
+static int json_object_object_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ int had_children = 0;
+ struct json_object_iter iter;
+
+ sprintbuf(pb, "{" /*}*/);
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ sprintbuf(pb, "\n");
+ json_object_object_foreachC(jso, iter)
+ {
+ if (had_children)
+ {
+ sprintbuf(pb, ",");
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ sprintbuf(pb, "\n");
+ }
+ had_children = 1;
+ if (flags & JSON_C_TO_STRING_SPACED)
+ sprintbuf(pb, " ");
+ indent(pb, level+1, flags);
+ sprintbuf(pb, "\"");
+ json_escape_str(pb, iter.key, strlen(iter.key));
+ if (flags & JSON_C_TO_STRING_SPACED)
+ sprintbuf(pb, "\": ");
+ else
+ sprintbuf(pb, "\":");
+ if(iter.val == NULL)
+ sprintbuf(pb, "null");
+ else
+ iter.val->_to_json_string(iter.val, pb, level+1,flags);
+ }
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ {
+ if (had_children)
+ sprintbuf(pb, "\n");
+ indent(pb,level,flags);
+ }
+ if (flags & JSON_C_TO_STRING_SPACED)
+ return sprintbuf(pb, /*{*/ " }");
+ else
+ return sprintbuf(pb, /*{*/ "}");
+}
+
+
+static void json_object_lh_entry_free(struct lh_entry *ent)
+{
+ free(ent->k);
+ json_object_put((struct json_object*)ent->v);
+}
+
+static void json_object_object_delete(struct json_object* jso)
+{
+ lh_table_free(jso->o.c_object);
+ json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_object(void)
+{
+ struct json_object* jso = json_object_new(json_type_object);
+
+ if (!jso)
+ {
+ return NULL;
+ }
+
+ jso->_delete = &json_object_object_delete;
+ jso->_to_json_string = &json_object_object_to_json_string;
+ jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, NULL, &json_object_lh_entry_free);
+
+ return jso;
+}
+
+struct lh_table* json_object_get_object(struct json_object *jso)
+{
+ if(!jso) return NULL;
+ switch(jso->o_type) {
+ case json_type_object:
+ return jso->o.c_object;
+ default:
+ return NULL;
+ }
+}
+
+void json_object_object_add(struct json_object* jso, const char *key,
+ struct json_object *val)
+{
+ // We lookup the entry and replace the value, rather than just deleting
+ // and re-adding it, so the existing key remains valid.
+ json_object *existing_value = NULL;
+ struct lh_entry *existing_entry;
+ existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
+ if (!existing_entry)
+ {
+ lh_table_insert(jso->o.c_object, strdup(key), val);
+ return;
+ }
+ existing_value = (void *)existing_entry->v;
+ if (existing_value)
+ json_object_put(existing_value);
+ existing_entry->v = val;
+}
+
+int json_object_object_length(struct json_object *jso)
+{
+ return lh_table_length(jso->o.c_object);
+}
+
+struct json_object* json_object_object_get(struct json_object* jso, const char *key)
+{
+ struct json_object *result = NULL;
+ json_object_object_get_ex(jso, key, &result);
+ return result;
+}
+
+json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
+{
+ if (value != NULL)
+ *value = NULL;
+
+ if (NULL == jso)
+ return FALSE;
+
+ switch(jso->o_type)
+ {
+ case json_type_object:
+ return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
+ default:
+ if (value != NULL)
+ *value = NULL;
+ return FALSE;
+ }
+}
+
+void json_object_object_del(struct json_object* jso, const char *key)
+{
+ lh_table_delete(jso->o.c_object, key);
+}
+
+
+/* json_object_boolean */
+
+static int json_object_boolean_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ if(jso->o.c_boolean) return sprintbuf(pb, "true");
+ else return sprintbuf(pb, "false");
+}
+
+struct json_object* json_object_new_boolean(json_bool b)
+{
+ struct json_object *jso = json_object_new(json_type_boolean);
+ if(!jso) return NULL;
+ jso->_to_json_string = &json_object_boolean_to_json_string;
+ jso->o.c_boolean = b;
+ return jso;
+}
+
+json_bool json_object_get_boolean(struct json_object *jso)
+{
+ if(!jso) return FALSE;
+ switch(jso->o_type) {
+ case json_type_boolean:
+ return jso->o.c_boolean;
+ case json_type_int:
+ return (jso->o.c_int64 != 0);
+ case json_type_double:
+ return (jso->o.c_double != 0);
+ case json_type_string:
+ return (jso->o.c_string.len != 0);
+ default:
+ return FALSE;
+ }
+}
+
+
+/* json_object_int */
+
+static int json_object_int_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
+}
+
+struct json_object* json_object_new_int(int32_t i)
+{
+ struct json_object *jso = json_object_new(json_type_int);
+ if(!jso) return NULL;
+ jso->_to_json_string = &json_object_int_to_json_string;
+ jso->o.c_int64 = i;
+ return jso;
+}
+
+int32_t json_object_get_int(struct json_object *jso)
+{
+ int64_t cint64;
+ enum json_type o_type;
+
+ if(!jso) return 0;
+
+ o_type = jso->o_type;
+ cint64 = jso->o.c_int64;
+
+ if (o_type == json_type_string)
+ {
+ /*
+ * Parse strings into 64-bit numbers, then use the
+ * 64-to-32-bit number handling below.
+ */
+ if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
+ return 0; /* whoops, it didn't work. */
+ o_type = json_type_int;
+ }
+
+ switch(o_type) {
+ case json_type_int:
+ /* Make sure we return the correct values for out of range numbers. */
+ if (cint64 <= INT32_MIN)
+ return INT32_MIN;
+ else if (cint64 >= INT32_MAX)
+ return INT32_MAX;
+ else
+ return (int32_t)cint64;
+ case json_type_double:
+ return (int32_t)jso->o.c_double;
+ case json_type_boolean:
+ return jso->o.c_boolean;
+ default:
+ return 0;
+ }
+}
+
+struct json_object* json_object_new_int64(int64_t i)
+{
+ struct json_object *jso = json_object_new(json_type_int);
+ if(!jso) return NULL;
+ jso->_to_json_string = &json_object_int_to_json_string;
+ jso->o.c_int64 = i;
+ return jso;
+}
+
+int64_t json_object_get_int64(struct json_object *jso)
+{
+ int64_t cint;
+
+ if(!jso) return 0;
+ switch(jso->o_type) {
+ case json_type_int:
+ return jso->o.c_int64;
+ case json_type_double:
+ return (int64_t)jso->o.c_double;
+ case json_type_boolean:
+ return jso->o.c_boolean;
+ case json_type_string:
+ if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
+ default:
+ return 0;
+ }
+}
+
+
+/* json_object_double */
+
+static int json_object_double_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ char buf[128], *p, *q;
+ size_t size;
+ /* Although JSON RFC does not support
+ NaN or Infinity as numeric values
+ ECMA 262 section 9.8.1 defines
+ how to handle these cases as strings */
+ if(isnan(jso->o.c_double))
+ size = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "NaN");
+ else if(isinf(jso->o.c_double))
+ if(jso->o.c_double > 0)
+ size = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "Infinity");
+ else
+ size = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "-Infinity");
+ else
+ size = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%.17g", jso->o.c_double);
+
+ p = strchr(buf, ',');
+ if (p) {
+ *p = '.';
+ } else {
+ p = strchr(buf, '.');
+ }
+ if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
+ /* last useful digit, always keep 1 zero */
+ p++;
+ for (q=p ; *q ; q++) {
+ if (*q!='0') p=q;
+ }
+ /* drop trailing zeroes */
+ *(++p) = 0;
+ size = p-buf;
+ }
+ printbuf_memappend(pb, buf, size);
+ return (int)size;
+}
+
+struct json_object* json_object_new_double(double d)
+{
+ struct json_object *jso = json_object_new(json_type_double);
+ if (!jso)
+ return NULL;
+ jso->_to_json_string = &json_object_double_to_json_string;
+ jso->o.c_double = d;
+ return jso;
+}
+
+struct json_object* json_object_new_double_s(double d, const char *ds)
+{
+ struct json_object *jso = json_object_new_double(d);
+ if (!jso)
+ return NULL;
+
+ json_object_set_serializer(jso, json_object_userdata_to_json_string, strdup(ds), json_object_free_userdata);
+ return jso;
+}
+
+int json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb, int level, int flags)
+{
+ size_t userdata_len = strlen(jso->_userdata);
+ printbuf_memappend(pb, jso->_userdata, userdata_len);
+ return (int)userdata_len;
+}
+
+void json_object_free_userdata(struct json_object *jso, void *userdata)
+{
+ free(userdata);
+}
+
+double json_object_get_double(struct json_object *jso)
+{
+ double cdouble;
+ char *errPtr = NULL;
+
+ if(!jso) return 0.0;
+ switch(jso->o_type) {
+ case json_type_double:
+ return jso->o.c_double;
+ case json_type_int:
+ return (double)jso->o.c_int64;
+ case json_type_boolean:
+ return jso->o.c_boolean;
+ case json_type_string:
+ errno = 0;
+ cdouble = strtod(jso->o.c_string.str,&errPtr);
+
+ /* if conversion stopped at the first character, return 0.0 */
+ if (errPtr == jso->o.c_string.str)
+ return 0.0;
+
+ /*
+ * Check that the conversion terminated on something sensible
+ *
+ * For example, { "pay" : 123AB } would parse as 123.
+ */
+ if (*errPtr != '\0')
+ return 0.0;
+
+ /*
+ * If strtod encounters a string which would exceed the
+ * capacity of a double, it returns +/- HUGE_VAL and sets
+ * errno to ERANGE. But +/- HUGE_VAL is also a valid result
+ * from a conversion, so we need to check errno.
+ *
+ * Underflow also sets errno to ERANGE, but it returns 0 in
+ * that case, which is what we will return anyway.
+ *
+ * See CERT guideline ERR30-C
+ */
+ if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
+ (ERANGE == errno))
+ cdouble = 0.0;
+ return cdouble;
+ default:
+ return 0.0;
+ }
+}
+
+
+/* json_object_string */
+
+static int json_object_string_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ sprintbuf(pb, "\"");
+ json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
+ sprintbuf(pb, "\"");
+ return 0;
+}
+
+static void json_object_string_delete(struct json_object* jso)
+{
+ free(jso->o.c_string.str);
+ json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_string(const char *s)
+{
+ struct json_object *jso = json_object_new(json_type_string);
+ if(!jso) return NULL;
+ jso->_delete = &json_object_string_delete;
+ jso->_to_json_string = &json_object_string_to_json_string;
+ jso->o.c_string.str = strdup(s);
+ jso->o.c_string.len = (int)strlen(s);
+ return jso;
+}
+
+struct json_object* json_object_new_string_len(const char *s, size_t len)
+{
+ struct json_object *jso = json_object_new(json_type_string);
+ if(!jso) return NULL;
+ jso->_delete = &json_object_string_delete;
+ jso->_to_json_string = &json_object_string_to_json_string;
+ jso->o.c_string.str = (char*)malloc(len + 1);
+ memcpy(jso->o.c_string.str, (void *)s, len);
+ jso->o.c_string.str[len] = '\0';
+ jso->o.c_string.len = len;
+ return jso;
+}
+
+char* json_object_get_string(struct json_object *jso)
+{
+ if (!jso)
+ return NULL;
+ switch (jso->o_type)
+ {
+ case json_type_string:
+ return jso->o.c_string.str;
+ default:
+ return json_object_to_json_string(jso);
+ }
+}
+
+int json_object_get_string_len(struct json_object *jso) {
+ if(!jso) return 0;
+ switch(jso->o_type) {
+ case json_type_string:
+ return (int)jso->o.c_string.len;
+ default:
+ return 0;
+ }
+}
+
+
+/* json_object_array */
+
+static int json_object_array_to_json_string(struct json_object* jso,
+ struct printbuf *pb,
+ int level,
+ int flags)
+{
+ int had_children = 0;
+ int ii;
+ sprintbuf(pb, "[");
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ sprintbuf(pb, "\n");
+ for(ii=0; ii < json_object_array_length(jso); ii++)
+ {
+ struct json_object *val;
+ if (had_children)
+ {
+ sprintbuf(pb, ",");
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ sprintbuf(pb, "\n");
+ }
+ had_children = 1;
+ if (flags & JSON_C_TO_STRING_SPACED)
+ sprintbuf(pb, " ");
+ indent(pb, level + 1, flags);
+ val = json_object_array_get_idx(jso, ii);
+ if(val == NULL)
+ sprintbuf(pb, "null");
+ else
+ val->_to_json_string(val, pb, level+1, flags);
+ }
+ if (flags & JSON_C_TO_STRING_PRETTY)
+ {
+ if (had_children)
+ sprintbuf(pb, "\n");
+ indent(pb,level,flags);
+ }
+
+ if (flags & JSON_C_TO_STRING_SPACED)
+ return sprintbuf(pb, " ]");
+ else
+ return sprintbuf(pb, "]");
+}
+
+static void json_object_array_entry_free(void *data)
+{
+ json_object_put((struct json_object*)data);
+}
+
+static void json_object_array_delete(struct json_object* jso)
+{
+ array_list_free(jso->o.c_array);
+ json_object_generic_delete(jso);
+}
+
+struct json_object* json_object_new_array(void)
+{
+ struct json_object *jso = json_object_new(json_type_array);
+ if(!jso) return NULL;
+ jso->_delete = &json_object_array_delete;
+ jso->_to_json_string = &json_object_array_to_json_string;
+ jso->o.c_array = array_list_new(&json_object_array_entry_free);
+ return jso;
+}
+
+struct array_list* json_object_get_array(struct json_object *jso)
+{
+ if(!jso) return NULL;
+ switch(jso->o_type) {
+ case json_type_array:
+ return jso->o.c_array;
+ default:
+ return NULL;
+ }
+}
+
+void json_object_array_sort(struct json_object *jso, int(__cdecl* sort_fn)(const void *, const void *))
+{
+ array_list_sort(jso->o.c_array, sort_fn);
+}
+
+int json_object_array_length(struct json_object *jso)
+{
+ return array_list_length(jso->o.c_array);
+}
+
+int json_object_array_add(struct json_object *jso,struct json_object *val)
+{
+ return array_list_add(jso->o.c_array, val);
+}
+
+int json_object_array_put_idx(struct json_object *jso, int idx,
+ struct json_object *val)
+{
+ return array_list_put_idx(jso->o.c_array, idx, val);
+}
+
+struct json_object* json_object_array_get_idx(struct json_object *jso,
+ int idx)
+{
+ return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
+}
+
diff --git a/plugins-extra/ExtraPlugins/json-c/json_object.h b/plugins-extra/ExtraPlugins/json-c/json_object.h
new file mode 100644
index 0000000..c649ab7
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_object.h
@@ -0,0 +1,611 @@
+/*
+ * $Id: json_object.h,v 1.12 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_h_
+#define _json_object_h_
+
+#ifdef __GNUC__
+#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func
+#else
+#define THIS_FUNCTION_IS_DEPRECATED(func) func
+#endif
+
+#include "json_inttypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JSON_OBJECT_DEF_HASH_ENTRIES 16
+
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes the output
+ * to have no extra whitespace or formatting applied.
+ */
+#define JSON_C_TO_STRING_PLAIN 0
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes the output to have
+ * minimal whitespace inserted to make things slightly more readable.
+ */
+#define JSON_C_TO_STRING_SPACED (1<<0)
+/**
+ * A flag for the json_object_to_json_string_ext() and
+ * json_object_to_file_ext() functions which causes
+ * the output to be formatted.
+ *
+ * See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/
+ * for an example of the format.
+ */
+#define JSON_C_TO_STRING_PRETTY (1<<1)
+/**
+ * A flag to drop trailing zero for float values
+ */
+#define JSON_C_TO_STRING_NOZERO (1<<2)
+
+#undef FALSE
+#define FALSE ((json_bool)0)
+
+#undef TRUE
+#define TRUE ((json_bool)1)
+
+extern const char *json_number_chars;
+extern const char *json_hex_chars;
+
+/* CAW: added for ANSI C iteration correctness */
+struct json_object_iter
+{
+ char *key;
+ struct json_object *val;
+ struct lh_entry *entry;
+};
+
+/* forward structure definitions */
+
+typedef int json_bool;
+typedef struct printbuf printbuf;
+typedef struct lh_table lh_table;
+typedef struct array_list array_list;
+typedef struct json_object json_object, *json_object_ptr;
+typedef struct json_object_iter json_object_iter;
+typedef struct json_tokener json_tokener;
+
+/**
+ * Type of custom user delete functions. See json_object_set_serializer.
+ */
+typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata);
+
+/**
+ * Type of a custom serialization function. See json_object_set_serializer.
+ */
+typedef int (json_object_to_json_string_fn)(struct json_object *jso,
+ struct printbuf *pb,
+ int level,
+ int flags);
+
+/* supported object types */
+
+typedef enum json_type {
+ /* If you change this, be sure to update json_type_to_name() too */
+ json_type_null,
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string,
+} json_type;
+
+/* reference counting functions */
+
+/**
+ * Increment the reference count of json_object, thereby grabbing shared
+ * ownership of obj.
+ *
+ * @param obj the json_object instance
+ */
+extern struct json_object* json_object_get(struct json_object *obj);
+
+/**
+ * Decrement the reference count of json_object and free if it reaches zero.
+ * You must have ownership of obj prior to doing this or you will cause an
+ * imbalance in the reference count.
+ *
+ * @param obj the json_object instance
+ * @returns 1 if the object was freed.
+ */
+int json_object_put(struct json_object *obj);
+
+/**
+ * Check if the json_object is of a given type
+ * @param obj the json_object instance
+ * @param type one of:
+ json_type_null (i.e. obj == NULL),
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string,
+ */
+extern int json_object_is_type(struct json_object *obj, enum json_type type);
+
+/**
+ * Get the type of the json_object. See also json_type_to_name() to turn this
+ * into a string suitable, for instance, for logging.
+ *
+ * @param obj the json_object instance
+ * @returns type being one of:
+ json_type_null (i.e. obj == NULL),
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string,
+ */
+extern enum json_type json_object_get_type(struct json_object *obj);
+
+
+/** Stringify object to json format.
+ * Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
+ * @param obj the json_object instance
+ * @returns a string in JSON format
+ */
+extern char* json_object_to_json_string(struct json_object *obj);
+
+/** Stringify object to json format
+ * @param obj the json_object instance
+ * @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
+ * @returns a string in JSON format
+ */
+extern char* json_object_to_json_string_ext(struct json_object *obj, int flags);
+
+/**
+ * Set a custom serialization function to be used when this particular object
+ * is converted to a string by json_object_to_json_string.
+ *
+ * If a custom serializer is already set on this object, any existing
+ * user_delete function is called before the new one is set.
+ *
+ * If to_string_func is NULL, the other parameters are ignored
+ * and the default behaviour is reset.
+ *
+ * The userdata parameter is optional and may be passed as NULL. If provided,
+ * it is passed to to_string_func as-is. This parameter may be NULL even
+ * if user_delete is non-NULL.
+ *
+ * The user_delete parameter is optional and may be passed as NULL, even if
+ * the userdata parameter is non-NULL. It will be called just before the
+ * json_object is deleted, after it's reference count goes to zero
+ * (see json_object_put()).
+ * If this is not provided, it is up to the caller to free the userdata at
+ * an appropriate time. (i.e. after the json_object is deleted)
+ *
+ * @param jso the object to customize
+ * @param to_string_func the custom serialization function
+ * @param userdata an optional opaque cookie
+ * @param user_delete an optional function from freeing userdata
+ */
+extern void json_object_set_serializer(json_object *jso,
+ json_object_to_json_string_fn to_string_func,
+ void *userdata,
+ json_object_delete_fn *user_delete);
+
+/**
+ * Simply call free on the userdata pointer.
+ * Can be used with json_object_set_serializer().
+ *
+ * @param jso unused
+ * @param userdata the pointer that is passed to free().
+ */
+json_object_delete_fn json_object_free_userdata;
+
+/**
+ * Copy the jso->_userdata string over to pb as-is.
+ * Can be used with json_object_set_serializer().
+ *
+ * @param jso The object whose _userdata is used.
+ * @param pb The destination buffer.
+ * @param level Ignored.
+ * @param flags Ignored.
+ */
+json_object_to_json_string_fn json_object_userdata_to_json_string;
+
+
+/* object type methods */
+
+/** Create a new empty object with a reference count of 1. The caller of
+ * this object initially has sole ownership. Remember, when using
+ * json_object_object_add or json_object_array_put_idx, ownership will
+ * transfer to the object/array. Call json_object_get if you want to maintain
+ * shared ownership or also add this object as a child of multiple objects or
+ * arrays. Any ownerships you acquired but did not transfer must be released
+ * through json_object_put.
+ *
+ * @returns a json_object of type json_type_object
+ */
+extern struct json_object* json_object_new_object(void);
+
+/** Get the hashtable of a json_object of type json_type_object
+ * @param obj the json_object instance
+ * @returns a linkhash
+ */
+extern struct lh_table* json_object_get_object(struct json_object *obj);
+
+/** Get the size of an object in terms of the number of fields it has.
+ * @param obj the json_object whose length to return
+ */
+extern int json_object_object_length(struct json_object* obj);
+
+/** Add an object field to a json_object of type json_type_object
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object, independent of the lifetime of obj, you must wrap the
+ * passed object with json_object_get.
+ *
+ * Upon calling this, the ownership of val transfers to obj. Thus you must
+ * make sure that you do in fact have ownership over this object. For instance,
+ * json_object_new_object will give you ownership until you transfer it,
+ * whereas json_object_object_get does not.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name (a private copy will be duplicated)
+ * @param val a json_object or NULL member to associate with the given field
+ */
+extern void json_object_object_add(struct json_object* obj, const char *key,
+ struct json_object *val);
+
+/** Get the json_object associate with a given object field
+ *
+ * *No* reference counts will be changed. There is no need to manually adjust
+ * reference counts through the json_object_put/json_object_get methods unless
+ * you need to have the child (value) reference maintain a different lifetime
+ * than the owning parent (obj). Ownership of the returned value is retained
+ * by obj (do not do json_object_put unless you have done a json_object_get).
+ * If you delete the value from obj (json_object_object_del) and wish to access
+ * the returned reference afterwards, make sure you have first gotten shared
+ * ownership through json_object_get (& don't forget to do a json_object_put
+ * or transfer ownership to prevent a memory leak).
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ * @returns the json_object associated with the given field name
+ * @deprecated Please use json_object_object_get_ex
+ */
+THIS_FUNCTION_IS_DEPRECATED(extern struct json_object* json_object_object_get(struct json_object* obj,
+ const char *key));
+
+/** Get the json_object associated with a given object field.
+ *
+ * This returns true if the key is found, false in all other cases (including
+ * if obj isn't a json_type_object).
+ *
+ * *No* reference counts will be changed. There is no need to manually adjust
+ * reference counts through the json_object_put/json_object_get methods unless
+ * you need to have the child (value) reference maintain a different lifetime
+ * than the owning parent (obj). Ownership of value is retained by obj.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ * @param value a pointer where to store a reference to the json_object
+ * associated with the given field name.
+ *
+ * It is safe to pass a NULL value.
+ * @returns whether or not the key exists
+ */
+extern json_bool json_object_object_get_ex(struct json_object* obj,
+ const char *key,
+ struct json_object **value);
+
+/** Delete the given json_object field
+ *
+ * The reference count will be decremented for the deleted object. If there
+ * are no more owners of the value represented by this key, then the value is
+ * freed. Otherwise, the reference to the value will remain in memory.
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ */
+extern void json_object_object_del(struct json_object* obj, const char *key);
+
+/**
+ * Iterate through all keys and values of an object.
+ *
+ * Adding keys to the object while iterating is NOT allowed.
+ *
+ * Deleting an existing key, or replacing an existing key with a
+ * new value IS allowed.
+ *
+ * @param obj the json_object instance
+ * @param key the local name for the char* key variable defined in the body
+ * @param val the local name for the json_object* object variable defined in
+ * the body
+ */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L
+
+# define json_object_object_foreach(obj,key,val) \
+ char *key; \
+ struct json_object *val __attribute__((__unused__)); \
+ for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
+ ({ if(entry ## key) { \
+ key = (char*)entry ## key->k; \
+ val = (struct json_object*)entry ## key->v; \
+ entry_next ## key = entry ## key->next; \
+ } ; entry ## key; }); \
+ entry ## key = entry_next ## key )
+
+#else /* ANSI C or MSC */
+
+# define json_object_object_foreach(obj,key,val) \
+ char *key;\
+ struct json_object *val; \
+ struct lh_entry *entry ## key; \
+ struct lh_entry *entry_next ## key = NULL; \
+ for(entry ## key = json_object_get_object(obj)->head; \
+ (entry ## key ? ( \
+ key = (char*)entry ## key->k, \
+ val = (struct json_object*)entry ## key->v, \
+ entry_next ## key = entry ## key->next, \
+ entry ## key) : 0); \
+ entry ## key = entry_next ## key)
+
+#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
+
+/** Iterate through all keys and values of an object (ANSI C Safe)
+ * @param obj the json_object instance
+ * @param iter the object iterator
+ */
+#define json_object_object_foreachC(obj,iter) \
+ for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next)
+
+/* Array type methods */
+
+/** Create a new empty json_object of type json_type_array
+ * @returns a json_object of type json_type_array
+ */
+extern struct json_object* json_object_new_array(void);
+
+/** Get the arraylist of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an arraylist
+ */
+extern struct array_list* json_object_get_array(struct json_object *obj);
+
+/** Get the length of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int json_object_array_length(struct json_object *obj);
+
+/** Sorts the elements of jso of type json_type_array
+*
+* Pointers to the json_object pointers will be passed as the two arguments
+* to @sort_fn
+*
+* @param obj the json_object instance
+* @param sort_fn a sorting function
+*/
+extern void json_object_array_sort(struct json_object *jso, int(__cdecl* sort_fn)(const void *, const void *));
+
+/** Add an element to the end of a json_object of type json_type_array
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * @param obj the json_object instance
+ * @param val the json_object to be added
+ */
+extern int json_object_array_add(struct json_object *obj,
+ struct json_object *val);
+
+/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * The reference count of a replaced object will be decremented.
+ *
+ * The array size will be automatically be expanded to the size of the
+ * index if the index is larger than the current size.
+ *
+ * @param obj the json_object instance
+ * @param idx the index to insert the element at
+ * @param val the json_object to be added
+ */
+extern int json_object_array_put_idx(struct json_object *obj, int idx,
+ struct json_object *val);
+
+/** Get the element at specificed index of the array (a json_object of type json_type_array)
+ * @param obj the json_object instance
+ * @param idx the index to get the element at
+ * @returns the json_object at the specified index (or NULL)
+ */
+extern struct json_object* json_object_array_get_idx(struct json_object *obj,
+ int idx);
+
+/* json_bool type methods */
+
+/** Create a new empty json_object of type json_type_boolean
+ * @param b a json_bool TRUE or FALSE (0 or 1)
+ * @returns a json_object of type json_type_boolean
+ */
+extern struct json_object* json_object_new_boolean(json_bool b);
+
+/** Get the json_bool value of a json_object
+ *
+ * The type is coerced to a json_bool if the passed object is not a json_bool.
+ * integer and double objects will return FALSE if there value is zero
+ * or TRUE otherwise. If the passed object is a string it will return
+ * TRUE if it has a non zero length. If any other object type is passed
+ * TRUE will be returned if the object is not NULL.
+ *
+ * @param obj the json_object instance
+ * @returns a json_bool
+ */
+extern json_bool json_object_get_boolean(struct json_object *obj);
+
+
+/* int type methods */
+
+/** Create a new empty json_object of type json_type_int
+ * Note that values are stored as 64-bit values internally.
+ * To ensure the full range is maintained, use json_object_new_int64 instead.
+ * @param i the integer
+ * @returns a json_object of type json_type_int
+ */
+extern struct json_object* json_object_new_int(int32_t i);
+
+
+/** Create a new empty json_object of type json_type_int
+ * @param i the integer
+ * @returns a json_object of type json_type_int
+ */
+extern struct json_object* json_object_new_int64(int64_t i);
+
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int if the passed object is not a int.
+ * double objects will return their integer conversion. Strings will be
+ * parsed as an integer. If no conversion exists then 0 is returned
+ * and errno is set to EINVAL. null is equivalent to 0 (no error values set)
+ *
+ * Note that integers are stored internally as 64-bit values.
+ * If the value of too big or too small to fit into 32-bit, INT32_MAX or
+ * INT32_MIN are returned, respectively.
+ *
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int32_t json_object_get_int(struct json_object *obj);
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int64 if the passed object is not a int64.
+ * double objects will return their int64 conversion. Strings will be
+ * parsed as an int64. If no conversion exists then 0 is returned.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to determine
+ * whether or not conversion was successful (it does not clear the value for
+ * you).
+ *
+ * @param obj the json_object instance
+ * @returns an int64
+ */
+extern int64_t json_object_get_int64(struct json_object *obj);
+
+
+/* double type methods */
+
+/** Create a new empty json_object of type json_type_double
+ * @param d the double
+ * @returns a json_object of type json_type_double
+ */
+extern struct json_object* json_object_new_double(double d);
+
+/**
+ * Create a new json_object of type json_type_double, using
+ * the exact serialized representation of the value.
+ *
+ * This allows for numbers that would otherwise get displayed
+ * inefficiently (e.g. 12.3 => "12.300000000000001") to be
+ * serialized with the more convenient form.
+ *
+ * Note: this is used by json_tokener_parse_ex() to allow for
+ * an exact re-serialization of a parsed object.
+ *
+ * An equivalent sequence of calls is:
+ * @code
+ * jso = json_object_new_double(d);
+ * json_object_set_serializer(d, json_object_userdata_to_json_string,
+ * strdup(ds), json_object_free_userdata)
+ * @endcode
+ *
+ * @param d the numeric value of the double.
+ * @param ds the string representation of the double. This will be copied.
+ */
+extern struct json_object* json_object_new_double_s(double d, const char *ds);
+
+/** Get the double floating point value of a json_object
+ *
+ * The type is coerced to a double if the passed object is not a double.
+ * integer objects will return their double conversion. Strings will be
+ * parsed as a double. If no conversion exists then 0.0 is returned and
+ * errno is set to EINVAL. null is equivalent to 0 (no error values set)
+ *
+ * If the value is too big to fit in a double, then the value is set to
+ * the closest infinity with errno set to ERANGE. If strings cannot be
+ * converted to their double value, then EINVAL is set & NaN is returned.
+ *
+ * Arrays of length 0 are interpreted as 0 (with no error flags set).
+ * Arrays of length 1 are effectively cast to the equivalent object and
+ * converted using the above rules. All other arrays set the error to
+ * EINVAL & return NaN.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to
+ * determine whether or not conversion was successful (it does not clear
+ * the value for you).
+ *
+ * @param obj the json_object instance
+ * @returns a double floating point number
+ */
+extern double json_object_get_double(struct json_object *obj);
+
+
+/* string type methods */
+
+/** Create a new empty json_object of type json_type_string
+ *
+ * A copy of the string is made and the memory is managed by the json_object
+ *
+ * @param s the string
+ * @returns a json_object of type json_type_string
+ */
+extern struct json_object* json_object_new_string(const char *s);
+
+extern struct json_object* json_object_new_string_len(const char *s, size_t len);
+
+/** Get the string value of a json_object
+ *
+ * If the passed object is not of type json_type_string then the JSON
+ * representation of the object is returned.
+ *
+ * The returned string memory is managed by the json_object and will
+ * be freed when the reference count of the json_object drops to zero.
+ *
+ * @param obj the json_object instance
+ * @returns a string
+ */
+extern char* json_object_get_string(struct json_object *obj);
+
+/** Get the string length of a json_object
+ *
+ * If the passed object is not of type json_type_string then zero
+ * will be returned.
+ *
+ * @param obj the json_object instance
+ * @returns int
+ */
+extern int json_object_get_string_len(struct json_object *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_object_iterator.c b/plugins-extra/ExtraPlugins/json-c/json_object_iterator.c
new file mode 100644
index 0000000..7066649
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_object_iterator.c
@@ -0,0 +1,168 @@
+/**
+*******************************************************************************
+* @file json_object_iterator.c
+*
+* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the MIT license. See COPYING for details.
+*
+* @brief json-c forces clients to use its private data
+* structures for JSON Object iteration. This API
+* implementation corrects that by abstracting the
+* private json-c details.
+*
+*******************************************************************************
+*/
+
+#include
+
+#include "json.h"
+#include "json_object_private.h"
+
+#include "json_object_iterator.h"
+
+/**
+ * How It Works
+ *
+ * For each JSON Object, json-c maintains a linked list of zero
+ * or more lh_entry (link-hash entry) structures inside the
+ * Object's link-hash table (lh_table).
+ *
+ * Each lh_entry structure on the JSON Object's linked list
+ * represents a single name/value pair. The "next" field of the
+ * last lh_entry in the list is set to NULL, which terminates
+ * the list.
+ *
+ * We represent a valid iterator that refers to an actual
+ * name/value pair via a pointer to the pair's lh_entry
+ * structure set as the iterator's opaque_ field.
+ *
+ * We follow json-c's current pair list representation by
+ * representing a valid "end" iterator (one that refers past the
+ * last pair) with a NULL value in the iterator's opaque_ field.
+ *
+ * A JSON Object without any pairs in it will have the "head"
+ * field of its lh_table structure set to NULL. For such an
+ * object, json_object_iter_begin will return an iterator with
+ * the opaque_ field set to NULL, which is equivalent to the
+ * "end" iterator.
+ *
+ * When iterating, we simply update the iterator's opaque_ field
+ * to point to the next lh_entry structure in the linked list.
+ * opaque_ will become NULL once we iterate past the last pair
+ * in the list, which makes the iterator equivalent to the "end"
+ * iterator.
+ */
+
+/// Our current representation of the "end" iterator;
+///
+/// @note May not always be NULL
+static const void* kObjectEndIterValue = NULL;
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_begin(struct json_object* obj)
+{
+ struct json_object_iterator iter;
+ struct lh_table* pTable;
+
+ /// @note json_object_get_object will return NULL if passed NULL
+ /// or a non-json_type_object instance
+ pTable = json_object_get_object(obj);
+ JASSERT(NULL != pTable);
+
+ /// @note For a pair-less Object, head is NULL, which matches our
+ /// definition of the "end" iterator
+ iter.opaque_ = pTable->head;
+ return iter;
+}
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_end(const struct json_object* obj)
+{
+ struct json_object_iterator iter;
+
+ JASSERT(NULL != obj);
+ JASSERT(json_object_is_type(obj, json_type_object));
+
+ iter.opaque_ = kObjectEndIterValue;
+
+ return iter;
+}
+
+/**
+ * ****************************************************************************
+ */
+void
+json_object_iter_next(struct json_object_iterator* iter)
+{
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
+
+ iter->opaque_ = ((struct lh_entry *)iter->opaque_)->next;
+}
+
+
+/**
+ * ****************************************************************************
+ */
+const char*
+json_object_iter_peek_name(const struct json_object_iterator* iter)
+{
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
+
+ return (const char*)(((struct lh_entry *)iter->opaque_)->k);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+struct json_object*
+json_object_iter_peek_value(const struct json_object_iterator* iter)
+{
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
+
+ return (struct json_object*)(((struct lh_entry *)iter->opaque_)->v);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+json_bool
+json_object_iter_equal(const struct json_object_iterator* iter1,
+ const struct json_object_iterator* iter2)
+{
+ JASSERT(NULL != iter1);
+ JASSERT(NULL != iter2);
+
+ return (iter1->opaque_ == iter2->opaque_);
+}
+
+
+/**
+ * ****************************************************************************
+ */
+struct json_object_iterator
+json_object_iter_init_default(void)
+{
+ struct json_object_iterator iter;
+
+ /**
+ * @note Make this a negative, invalid value, such that
+ * accidental access to it would likely be trapped by the
+ * hardware as an invalid address.
+ */
+ iter.opaque_ = NULL;
+
+ return iter;
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/json_object_iterator.h b/plugins-extra/ExtraPlugins/json-c/json_object_iterator.h
new file mode 100644
index 0000000..44c9fb2
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_object_iterator.h
@@ -0,0 +1,239 @@
+/**
+*******************************************************************************
+* @file json_object_iterator.h
+*
+* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the MIT license. See COPYING for details.
+*
+* @brief json-c forces clients to use its private data
+* structures for JSON Object iteration. This API
+* corrects that by abstracting the private json-c
+* details.
+*
+* API attributes:
+* * Thread-safe: NO
+* * Reentrant: NO
+*
+*******************************************************************************
+*/
+
+
+#ifndef JSON_OBJECT_ITERATOR_H
+#define JSON_OBJECT_ITERATOR_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Forward declaration for the opaque iterator information.
+ */
+struct json_object_iter_info_;
+
+/**
+ * The opaque iterator that references a name/value pair within
+ * a JSON Object instance or the "end" iterator value.
+ */
+struct json_object_iterator {
+ const void* opaque_;
+};
+
+
+/**
+ * forward declaration of json-c's JSON value instance structure
+ */
+struct json_object;
+
+
+/**
+ * Initializes an iterator structure to a "default" value that
+ * is convenient for initializing an iterator variable to a
+ * default state (e.g., initialization list in a class'
+ * constructor).
+ *
+ * @code
+ * struct json_object_iterator iter = json_object_iter_init_default();
+ * MyClass() : iter_(json_object_iter_init_default())
+ * @endcode
+ *
+ * @note The initialized value doesn't reference any specific
+ * pair, is considered an invalid iterator, and MUST NOT
+ * be passed to any json-c API that expects a valid
+ * iterator.
+ *
+ * @note User and internal code MUST NOT make any assumptions
+ * about and dependencies on the value of the "default"
+ * iterator value.
+ *
+ * @return json_object_iterator
+ */
+struct json_object_iterator
+json_object_iter_init_default(void);
+
+/** Retrieves an iterator to the first pair of the JSON Object.
+ *
+ * @warning Any modification of the underlying pair invalidates all
+ * iterators to that pair.
+ *
+ * @param obj JSON Object instance (MUST be of type json_object)
+ *
+ * @return json_object_iterator If the JSON Object has at
+ * least one pair, on return, the iterator refers
+ * to the first pair. If the JSON Object doesn't
+ * have any pairs, the returned iterator is
+ * equivalent to the "end" iterator for the same
+ * JSON Object instance.
+ *
+ * @code
+ * struct json_object_iterator it;
+ * struct json_object_iterator itEnd;
+ * struct json_object* obj;
+ *
+ * obj = json_tokener_parse("{'first':'george', 'age':100}");
+ * it = json_object_iter_begin(obj);
+ * itEnd = json_object_iter_end(obj);
+ *
+ * while (!json_object_iter_equal(&it, &itEnd)) {
+ * printf("%s\n",
+ * json_object_iter_peek_name(&it));
+ * json_object_iter_next(&it);
+ * }
+ *
+ * @endcode
+ */
+struct json_object_iterator
+json_object_iter_begin(struct json_object* obj);
+
+/** Retrieves the iterator that represents the position beyond the
+ * last pair of the given JSON Object instance.
+ *
+ * @warning Do NOT write code that assumes that the "end"
+ * iterator value is NULL, even if it is so in a
+ * particular instance of the implementation.
+ *
+ * @note The reason we do not (and MUST NOT) provide
+ * "json_object_iter_is_end(json_object_iterator* iter)"
+ * type of API is because it would limit the underlying
+ * representation of name/value containment (or force us
+ * to add additional, otherwise unnecessary, fields to
+ * the iterator structure). The "end" iterator and the
+ * equality test method, on the other hand, permit us to
+ * cleanly abstract pretty much any reasonable underlying
+ * representation without burdening the iterator
+ * structure with unnecessary data.
+ *
+ * @note For performance reasons, memorize the "end" iterator prior
+ * to any loop.
+ *
+ * @param obj JSON Object instance (MUST be of type json_object)
+ *
+ * @return json_object_iterator On return, the iterator refers
+ * to the "end" of the Object instance's pairs
+ * (i.e., NOT the last pair, but "beyond the last
+ * pair" value)
+ */
+struct json_object_iterator
+json_object_iter_end(const struct json_object* obj);
+
+/** Returns an iterator to the next pair, if any
+ *
+ * @warning Any modification of the underlying pair
+ * invalidates all iterators to that pair.
+ *
+ * @param iter [IN/OUT] Pointer to iterator that references a
+ * name/value pair; MUST be a valid, non-end iterator.
+ * WARNING: bad things will happen if invalid or "end"
+ * iterator is passed. Upon return will contain the
+ * reference to the next pair if there is one; if there
+ * are no more pairs, will contain the "end" iterator
+ * value, which may be compared against the return value
+ * of json_object_iter_end() for the same JSON Object
+ * instance.
+ */
+void
+json_object_iter_next(struct json_object_iterator* iter);
+
+
+/** Returns a const pointer to the name of the pair referenced
+ * by the given iterator.
+ *
+ * @param iter pointer to iterator that references a name/value
+ * pair; MUST be a valid, non-end iterator.
+ *
+ * @warning bad things will happen if an invalid or
+ * "end" iterator is passed.
+ *
+ * @return const char* Pointer to the name of the referenced
+ * name/value pair. The name memory belongs to the
+ * name/value pair, will be freed when the pair is
+ * deleted or modified, and MUST NOT be modified or
+ * freed by the user.
+ */
+const char*
+json_object_iter_peek_name(const struct json_object_iterator* iter);
+
+
+/** Returns a pointer to the json-c instance representing the
+ * value of the referenced name/value pair, without altering
+ * the instance's reference count.
+ *
+ * @param iter pointer to iterator that references a name/value
+ * pair; MUST be a valid, non-end iterator.
+ *
+ * @warning bad things will happen if invalid or
+ * "end" iterator is passed.
+ *
+ * @return struct json_object* Pointer to the json-c value
+ * instance of the referenced name/value pair; the
+ * value's reference count is not changed by this
+ * function: if you plan to hold on to this json-c node,
+ * take a look at json_object_get() and
+ * json_object_put(). IMPORTANT: json-c API represents
+ * the JSON Null value as a NULL json_object instance
+ * pointer.
+ */
+struct json_object*
+json_object_iter_peek_value(const struct json_object_iterator* iter);
+
+
+/** Tests two iterators for equality. Typically used to test
+ * for end of iteration by comparing an iterator to the
+ * corresponding "end" iterator (that was derived from the same
+ * JSON Object instance).
+ *
+ * @note The reason we do not (and MUST NOT) provide
+ * "json_object_iter_is_end(json_object_iterator* iter)"
+ * type of API is because it would limit the underlying
+ * representation of name/value containment (or force us
+ * to add additional, otherwise unnecessary, fields to
+ * the iterator structure). The equality test method, on
+ * the other hand, permits us to cleanly abstract pretty
+ * much any reasonable underlying representation.
+ *
+ * @param iter1 Pointer to first valid, non-NULL iterator
+ * @param iter2 POinter to second valid, non-NULL iterator
+ *
+ * @warning if a NULL iterator pointer or an uninitialized
+ * or invalid iterator, or iterators derived from
+ * different JSON Object instances are passed, bad things
+ * will happen!
+ *
+ * @return json_bool non-zero if iterators are equal (i.e., both
+ * reference the same name/value pair or are both at
+ * "end"); zero if they are not equal.
+ */
+json_bool
+json_object_iter_equal(const struct json_object_iterator* iter1,
+ const struct json_object_iterator* iter2);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* JSON_OBJECT_ITERATOR_H */
diff --git a/plugins-extra/ExtraPlugins/json-c/json_object_private.h b/plugins-extra/ExtraPlugins/json-c/json_object_private.h
new file mode 100644
index 0000000..deff7e8
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_object_private.h
@@ -0,0 +1,47 @@
+/*
+ * $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_private_h_
+#define _json_object_private_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (json_object_private_delete_fn)(struct json_object *o);
+
+struct json_object
+{
+ enum json_type o_type;
+ json_object_private_delete_fn *_delete;
+ json_object_to_json_string_fn *_to_json_string;
+ int _ref_count;
+ struct printbuf *_pb;
+ union data {
+ json_bool c_boolean;
+ double c_double;
+ int64_t c_int64;
+ struct lh_table *c_object;
+ struct array_list *c_array;
+ struct {
+ char *str;
+ size_t len;
+ } c_string;
+ } o;
+ json_object_delete_fn *_user_delete;
+ void *_userdata;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_tokener.c b/plugins-extra/ExtraPlugins/json-c/json_tokener.c
new file mode 100644
index 0000000..2959cbd
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_tokener.c
@@ -0,0 +1,888 @@
+/*
+ * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "arraylist.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+#ifdef HAVE_LOCALE_H
+#include
+#endif /* HAVE_LOCALE_H */
+
+#if !HAVE_STRDUP && defined(_MSC_VER)
+ /* MSC has the version as _strdup */
+# define strdup _strdup
+#elif !HAVE_STRDUP
+# error You do not have strdup on your system.
+#endif /* HAVE_STRDUP */
+
+#if !HAVE_STRNCASECMP && defined(_MSC_VER)
+ /* MSC has the version as _strnicmp */
+# define strncasecmp _strnicmp
+#elif !HAVE_STRNCASECMP
+# error You do not have strncasecmp on your system.
+#endif /* HAVE_STRNCASECMP */
+
+/* Use C99 NAN by default; if not available, nan("") should work too. */
+#ifndef NAN
+#define NAN nan("")
+#endif /* !NAN */
+
+static const char json_null_str[] = "null";
+static const int json_null_str_len = sizeof(json_null_str) - 1;
+static const char json_inf_str[] = "Infinity";
+static const int json_inf_str_len = sizeof(json_inf_str) - 1;
+static const char json_nan_str[] = "NaN";
+static const int json_nan_str_len = sizeof(json_nan_str) - 1;
+static const char json_true_str[] = "true";
+static const int json_true_str_len = sizeof(json_true_str) - 1;
+static const char json_false_str[] = "false";
+static const int json_false_str_len = sizeof(json_false_str) - 1;
+
+static const char* json_tokener_errors[] = {
+ "success",
+ "continue",
+ "nesting too deep",
+ "unexpected end of data",
+ "unexpected character",
+ "null expected",
+ "boolean expected",
+ "number expected",
+ "array value separator ',' expected",
+ "quoted object property name expected",
+ "object property name separator ':' expected",
+ "object value separator ',' expected",
+ "invalid string sequence",
+ "expected comment",
+ "buffer size overflow"
+};
+
+const char *json_tokener_error_desc(enum json_tokener_error jerr)
+{
+ int jerr_int = (int)jerr;
+ if (jerr_int < 0 || jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
+ return "Unknown error, invalid json_tokener_error value passed to json_tokener_error_desc()";
+ return json_tokener_errors[jerr];
+}
+
+enum json_tokener_error json_tokener_get_error(json_tokener *tok)
+{
+ return tok->err;
+}
+
+/* Stuff for decoding unicode sequences */
+#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
+#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)
+#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
+static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
+
+struct json_tokener* json_tokener_new_ex(int depth)
+{
+ struct json_tokener *tok;
+
+ tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
+ if (!tok) return NULL;
+ tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
+ if (!tok->stack) {
+ free(tok);
+ return NULL;
+ }
+ tok->pb = printbuf_new();
+ tok->max_depth = depth;
+ json_tokener_reset(tok);
+ return tok;
+}
+
+struct json_tokener* json_tokener_new(void)
+{
+ return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
+}
+
+void json_tokener_free(struct json_tokener *tok)
+{
+ json_tokener_reset(tok);
+ if (tok->pb) printbuf_free(tok->pb);
+ if (tok->stack) free(tok->stack);
+ free(tok);
+}
+
+static void json_tokener_reset_level(struct json_tokener *tok, int depth)
+{
+ tok->stack[depth].state = json_tokener_state_eatws;
+ tok->stack[depth].saved_state = json_tokener_state_start;
+ json_object_put(tok->stack[depth].current);
+ tok->stack[depth].current = NULL;
+ free(tok->stack[depth].obj_field_name);
+ tok->stack[depth].obj_field_name = NULL;
+}
+
+void json_tokener_reset(struct json_tokener *tok)
+{
+ int i;
+ if (!tok)
+ return;
+
+ for(i = tok->depth; i >= 0; i--)
+ json_tokener_reset_level(tok, i);
+ tok->depth = 0;
+ tok->err = json_tokener_success;
+}
+
+struct json_object* json_tokener_parse(const char *str)
+{
+ enum json_tokener_error jerr_ignored;
+ struct json_object* obj;
+ obj = json_tokener_parse_verbose(str, &jerr_ignored);
+ return obj;
+}
+
+struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
+{
+ struct json_tokener* tok;
+ struct json_object* obj;
+
+ tok = json_tokener_new();
+ if (!tok)
+ return NULL;
+ obj = json_tokener_parse_ex(tok, str, -1);
+ *error = tok->err;
+ if(tok->err != json_tokener_success) {
+ if (obj != NULL)
+ json_object_put(obj);
+ obj = NULL;
+ }
+
+ json_tokener_free(tok);
+ return obj;
+}
+
+#define state tok->stack[tok->depth].state
+#define saved_state tok->stack[tok->depth].saved_state
+#define current tok->stack[tok->depth].current
+#define obj_field_name tok->stack[tok->depth].obj_field_name
+
+/* Optimization:
+ * json_tokener_parse_ex() consumed a lot of CPU in its main loop,
+ * iterating character-by character. A large performance boost is
+ * achieved by using tighter loops to locally handle units such as
+ * comments and strings. Loops that handle an entire token within
+ * their scope also gather entire strings and pass them to
+ * printbuf_memappend() in a single call, rather than calling
+ * printbuf_memappend() one char at a time.
+ *
+ * PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
+ * common to both the main loop and the tighter loops.
+ */
+
+/* PEEK_CHAR(dest, tok) macro:
+ * Peeks at the current char and stores it in dest.
+ * Returns 1 on success, sets tok->err and returns 0 if no more chars.
+ * Implicit inputs: str, len vars
+ */
+#define PEEK_CHAR(dest, tok) \
+ (((tok)->char_offset == len) ? \
+ (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \
+ (((tok)->err = json_tokener_success), 0) \
+ : \
+ (((tok)->err = json_tokener_continue), 0) \
+ ) : \
+ (((dest) = *str), 1) \
+ )
+
+/* ADVANCE_CHAR() macro:
+ * Incrementes str & tok->char_offset.
+ * For convenience of existing conditionals, returns the old value of c (0 on eof)
+ * Implicit inputs: c var
+ */
+#define ADVANCE_CHAR(str, tok) \
+ ( ++(str), ((tok)->char_offset)++, c)
+
+
+/* End optimization macro defs */
+
+
+struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+ const char *str, int len)
+{
+ struct json_object *obj = NULL;
+ char c = '\1';
+#ifdef HAVE_SETLOCALE
+ char *oldlocale=NULL, *tmplocale;
+
+ tmplocale = setlocale(LC_NUMERIC, NULL);
+ if (tmplocale) oldlocale = strdup(tmplocale);
+ setlocale(LC_NUMERIC, "C");
+#endif
+
+ tok->char_offset = 0;
+ tok->err = json_tokener_success;
+
+ /* this interface is presently not 64-bit clean due to the int len argument
+ and the internal printbuf interface that takes 32-bit int len arguments
+ so the function limits the maximum string size to INT32_MAX (2GB).
+ If the function is called with len == -1 then strlen is called to check
+ the string length is less than INT32_MAX (2GB) */
+ if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
+ tok->err = json_tokener_error_size;
+ return NULL;
+ }
+
+ while (PEEK_CHAR(c, tok)) {
+
+ redo_char:
+ switch(state) {
+
+ case json_tokener_state_eatws:
+ /* Advance until we change state */
+ while (isspace((int)c)) {
+ if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
+ goto out;
+ }
+ if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
+ printbuf_reset(tok->pb);
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ state = json_tokener_state_comment_start;
+ } else {
+ state = saved_state;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_start:
+ switch(c) {
+ case '{':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_object_field_start;
+ current = json_object_new_object();
+ break;
+ case '[':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_array;
+ current = json_object_new_array();
+ break;
+ case 'I':
+ case 'i':
+ state = json_tokener_state_inf;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case 'N':
+ case 'n':
+ state = json_tokener_state_null; // or NaN
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case '\'':
+ if (tok->flags & JSON_TOKENER_STRICT) {
+ /* in STRICT mode only double-quote are allowed */
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ case '"':
+ state = json_tokener_state_string;
+ printbuf_reset(tok->pb);
+ tok->quote_char = c;
+ break;
+ case 'T':
+ case 't':
+ case 'F':
+ case 'f':
+ state = json_tokener_state_boolean;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+#if defined(__GNUC__)
+ case '0' ... '9':
+#else
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+#endif
+ case '-':
+ state = json_tokener_state_number;
+ printbuf_reset(tok->pb);
+ tok->is_double = 0;
+ goto redo_char;
+ default:
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_finish:
+ if(tok->depth == 0) goto out;
+ obj = json_object_get(current);
+ json_tokener_reset_level(tok, tok->depth);
+ tok->depth--;
+ goto redo_char;
+
+ case json_tokener_state_inf: /* aka starts with 'i' */
+ {
+ int size;
+ int size_inf;
+ int is_negative = 0;
+
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ size = json_min(tok->st_pos+1, json_null_str_len);
+ size_inf = json_min(tok->st_pos+1, json_inf_str_len);
+ char *infbuf = tok->pb->buf;
+ if (*infbuf == '-')
+ {
+ infbuf++;
+ is_negative = 1;
+ }
+ if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_inf_str, infbuf, size_inf) == 0) ||
+ (strncmp(json_inf_str, infbuf, size_inf) == 0)
+ )
+ {
+ if (tok->st_pos == json_inf_str_len)
+ {
+ current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ tok->st_pos++;
+ }
+ break;
+ case json_tokener_state_null: /* aka starts with 'n' */
+ {
+ int size;
+ int size_nan;
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ size = json_min(tok->st_pos+1, json_null_str_len);
+ size_nan = json_min(tok->st_pos+1, json_nan_str_len);
+ if((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_null_str, tok->pb->buf, size) == 0)
+ || (strncmp(json_null_str, tok->pb->buf, size) == 0)
+ ) {
+ if (tok->st_pos == json_null_str_len) {
+ current = NULL;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ }
+ else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
+ (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
+ )
+ {
+ if (tok->st_pos == json_nan_str_len)
+ {
+ current = json_object_new_double(NAN);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_null;
+ goto out;
+ }
+ tok->st_pos++;
+ }
+ break;
+
+ case json_tokener_state_comment_start:
+ if(c == '*') {
+ state = json_tokener_state_comment;
+ } else if(c == '/') {
+ state = json_tokener_state_comment_eol;
+ } else {
+ tok->err = json_tokener_error_parse_comment;
+ goto out;
+ }
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ break;
+
+ case json_tokener_state_comment:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while(c != '*') {
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ goto out;
+ }
+ }
+ printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
+ state = json_tokener_state_comment_end;
+ }
+ break;
+
+ case json_tokener_state_comment_eol:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while(c != '\n') {
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ goto out;
+ }
+ }
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ }
+ break;
+
+ case json_tokener_state_comment_end:
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ if(c == '/') {
+ MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ } else {
+ state = json_tokener_state_comment;
+ }
+ break;
+
+ case json_tokener_state_string:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while(1) {
+ if(c == tok->quote_char) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ break;
+ } else if(c == '\\') {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ saved_state = json_tokener_state_string;
+ state = json_tokener_state_string_escape;
+ break;
+ }
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ goto out;
+ }
+ }
+ }
+ break;
+
+ case json_tokener_state_string_escape:
+ switch(c) {
+ case '"':
+ case '\\':
+ case '/':
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ state = saved_state;
+ break;
+ case 'b':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'f':
+ if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
+ else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
+ else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
+ else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
+ else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
+ state = saved_state;
+ break;
+ case 'u':
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ state = json_tokener_state_escape_unicode;
+ break;
+ default:
+ tok->err = json_tokener_error_parse_string;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_escape_unicode:
+ {
+ unsigned int got_hi_surrogate = 0;
+
+ /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
+ while(1) {
+ if(strchr(json_hex_chars, c)) {
+ tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
+ if(tok->st_pos == 4) {
+ unsigned char unescaped_utf[4];
+
+ if (got_hi_surrogate) {
+ if (IS_LOW_SURROGATE(tok->ucs_char)) {
+ /* Recalculate the ucs_char, then fall thru to process normally */
+ tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
+ } else {
+ /* Hi surrogate was not followed by a low surrogate */
+ /* Replace the hi and process the rest normally */
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ }
+ got_hi_surrogate = 0;
+ }
+
+ if (tok->ucs_char < 0x80) {
+ unescaped_utf[0] = tok->ucs_char;
+ printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
+ } else if (tok->ucs_char < 0x800) {
+ unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
+ unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
+ } else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
+ /* Got a high surrogate. Remember it and look for the
+ * the beginning of another sequence, which should be the
+ * low surrogate.
+ */
+ got_hi_surrogate = tok->ucs_char;
+ /* Not at end, and the next two chars should be "\u" */
+ if ((tok->char_offset+1 != len) &&
+ (tok->char_offset+2 != len) &&
+ (str[1] == '\\') &&
+ (str[2] == 'u'))
+ {
+ /* Advance through the 16 bit surrogate, and move on to the
+ * next sequence. The next step is to process the following
+ * characters.
+ */
+ if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ }
+ /* Advance to the first char of the next sequence and
+ * continue processing with the next sequence.
+ */
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ goto out;
+ }
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ continue; /* other json_tokener_state_escape_unicode */
+ } else {
+ /* Got a high surrogate without another sequence following
+ * it. Put a replacement char in for the hi surrogate
+ * and pretend we finished.
+ */
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ }
+ } else if (IS_LOW_SURROGATE(tok->ucs_char)) {
+ /* Got a low surrogate not preceded by a high */
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ } else if (tok->ucs_char < 0x10000) {
+ unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
+ unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+ unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
+ } else if (tok->ucs_char < 0x110000) {
+ unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
+ unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
+ unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+ unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
+ } else {
+ /* Don't know what we got--insert the replacement char */
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ }
+ state = saved_state;
+ break;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_string;
+ goto out;
+ }
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ if (got_hi_surrogate) /* Clean up any pending chars */
+ printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
+ goto out;
+ }
+ }
+ }
+ break;
+
+ case json_tokener_state_boolean:
+ {
+ int size1, size2;
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ size1 = json_min(tok->st_pos+1, json_true_str_len);
+ size2 = json_min(tok->st_pos+1, json_false_str_len);
+ if((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
+ || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
+ ) {
+ if(tok->st_pos == json_true_str_len) {
+ current = json_object_new_boolean(1);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else if((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
+ || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
+ if(tok->st_pos == json_false_str_len) {
+ current = json_object_new_boolean(0);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_boolean;
+ goto out;
+ }
+ tok->st_pos++;
+ }
+ break;
+
+ case json_tokener_state_number:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ int case_len=0;
+ while(c && strchr(json_number_chars, c)) {
+ ++case_len;
+ if(c == '.' || c == 'e' || c == 'E')
+ tok->is_double = 1;
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, case_start, case_len);
+ goto out;
+ }
+ }
+ if (case_len>0)
+ printbuf_memappend_fast(tok->pb, case_start, case_len);
+
+ // Check for -Infinity
+ if (tok->pb->buf[0] == '-' && case_len == 1 &&
+ (c == 'i' || c == 'I'))
+ {
+ state = json_tokener_state_inf;
+ goto redo_char;
+ }
+ }
+ {
+ int64_t num64;
+ double numd;
+ if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
+ if (num64 && tok->pb->buf[0]=='0' && (tok->flags & JSON_TOKENER_STRICT)) {
+ /* in strict mode, number must not start with 0 */
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ current = json_object_new_int64(num64);
+ }
+ else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
+ {
+ current = json_object_new_double_s(numd, tok->pb->buf);
+ } else {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array_after_sep:
+ case json_tokener_state_array:
+ if(c == ']') {
+ if (state == json_tokener_state_array_after_sep &&
+ (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else {
+ if(tok->depth >= tok->max_depth-1) {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_array_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array_add:
+ json_object_array_add(current, obj);
+ saved_state = json_tokener_state_array_sep;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+
+ case json_tokener_state_array_sep:
+ if(c == ']') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if(c == ',') {
+ saved_state = json_tokener_state_array_after_sep;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_array;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field_start:
+ case json_tokener_state_object_field_start_after_sep:
+ if(c == '}') {
+ if (state == json_tokener_state_object_field_start_after_sep &&
+ (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if (c == '"' || c == '\'') {
+ tok->quote_char = c;
+ printbuf_reset(tok->pb);
+ state = json_tokener_state_object_field;
+ } else {
+ tok->err = json_tokener_error_parse_object_key_name;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while(1) {
+ if(c == tok->quote_char) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ obj_field_name = strdup(tok->pb->buf);
+ saved_state = json_tokener_state_object_field_end;
+ state = json_tokener_state_eatws;
+ break;
+ } else if(c == '\\') {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ saved_state = json_tokener_state_object_field;
+ state = json_tokener_state_string_escape;
+ break;
+ }
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
+ printbuf_memappend_fast(tok->pb, case_start, str-case_start);
+ goto out;
+ }
+ }
+ }
+ break;
+
+ case json_tokener_state_object_field_end:
+ if(c == ':') {
+ saved_state = json_tokener_state_object_value;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_object_key_sep;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_value:
+ if(tok->depth >= tok->max_depth-1) {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_object_value_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+
+ case json_tokener_state_object_value_add:
+ json_object_object_add(current, obj_field_name, obj);
+ free(obj_field_name);
+ obj_field_name = NULL;
+ saved_state = json_tokener_state_object_sep;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+
+ case json_tokener_state_object_sep:
+ if(c == '}') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if(c == ',') {
+ saved_state = json_tokener_state_object_field_start_after_sep;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_object_value_sep;
+ goto out;
+ }
+ break;
+
+ }
+ if (!ADVANCE_CHAR(str, tok))
+ goto out;
+ } /* while(POP_CHAR) */
+
+ out:
+ if (c &&
+ (state == json_tokener_state_finish) &&
+ (tok->depth == 0) &&
+ (tok->flags & JSON_TOKENER_STRICT)) {
+ /* unexpected char after JSON data */
+ tok->err = json_tokener_error_parse_unexpected;
+ }
+ if (!c) { /* We hit an eof char (0) */
+ if(state != json_tokener_state_finish &&
+ saved_state != json_tokener_state_finish)
+ tok->err = json_tokener_error_parse_eof;
+ }
+
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_NUMERIC, oldlocale);
+ if (oldlocale) free(oldlocale);
+#endif
+
+ if (tok->err == json_tokener_success)
+ {
+ json_object *ret = json_object_get(current);
+ int ii;
+
+ /* Partially reset, so we parse additional objects on subsequent calls. */
+ for(ii = tok->depth; ii >= 0; ii--)
+ json_tokener_reset_level(tok, ii);
+ return ret;
+ }
+
+ MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
+ json_tokener_errors[tok->err], tok->char_offset);
+ return NULL;
+}
+
+void json_tokener_set_flags(struct json_tokener *tok, int flags)
+{
+ tok->flags = flags;
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/json_tokener.h b/plugins-extra/ExtraPlugins/json-c/json_tokener.h
new file mode 100644
index 0000000..a72d2bd
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_tokener.h
@@ -0,0 +1,208 @@
+/*
+ * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_tokener_h_
+#define _json_tokener_h_
+
+#include
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum json_tokener_error {
+ json_tokener_success,
+ json_tokener_continue,
+ json_tokener_error_depth,
+ json_tokener_error_parse_eof,
+ json_tokener_error_parse_unexpected,
+ json_tokener_error_parse_null,
+ json_tokener_error_parse_boolean,
+ json_tokener_error_parse_number,
+ json_tokener_error_parse_array,
+ json_tokener_error_parse_object_key_name,
+ json_tokener_error_parse_object_key_sep,
+ json_tokener_error_parse_object_value_sep,
+ json_tokener_error_parse_string,
+ json_tokener_error_parse_comment,
+ json_tokener_error_size
+};
+
+enum json_tokener_state {
+ json_tokener_state_eatws,
+ json_tokener_state_start,
+ json_tokener_state_finish,
+ json_tokener_state_null,
+ json_tokener_state_comment_start,
+ json_tokener_state_comment,
+ json_tokener_state_comment_eol,
+ json_tokener_state_comment_end,
+ json_tokener_state_string,
+ json_tokener_state_string_escape,
+ json_tokener_state_escape_unicode,
+ json_tokener_state_boolean,
+ json_tokener_state_number,
+ json_tokener_state_array,
+ json_tokener_state_array_add,
+ json_tokener_state_array_sep,
+ json_tokener_state_object_field_start,
+ json_tokener_state_object_field,
+ json_tokener_state_object_field_end,
+ json_tokener_state_object_value,
+ json_tokener_state_object_value_add,
+ json_tokener_state_object_sep,
+ json_tokener_state_array_after_sep,
+ json_tokener_state_object_field_start_after_sep,
+ json_tokener_state_inf
+};
+
+struct json_tokener_srec
+{
+ enum json_tokener_state state, saved_state;
+ struct json_object *obj;
+ struct json_object *current;
+ char *obj_field_name;
+};
+
+#define JSON_TOKENER_DEFAULT_DEPTH 32
+
+struct json_tokener
+{
+ char *str;
+ struct printbuf *pb;
+ int max_depth, depth, is_double, st_pos, char_offset;
+ enum json_tokener_error err;
+ unsigned int ucs_char;
+ char quote_char;
+ struct json_tokener_srec *stack;
+ int flags;
+};
+
+/**
+ * Be strict when parsing JSON input. Use caution with
+ * this flag as what is considered valid may become more
+ * restrictive from one release to the next, causing your
+ * code to fail on previously working input.
+ *
+ * This flag is not set by default.
+ *
+ * @see json_tokener_set_flags()
+ */
+#define JSON_TOKENER_STRICT 0x01
+
+/**
+ * Given an error previously returned by json_tokener_get_error(),
+ * return a human readable description of the error.
+ *
+ * @return a generic error message is returned if an invalid error value is provided.
+ */
+const char *json_tokener_error_desc(enum json_tokener_error jerr);
+
+/**
+ * Retrieve the error caused by the last call to json_tokener_parse_ex(),
+ * or json_tokener_success if there is no error.
+ *
+ * When parsing a JSON string in pieces, if the tokener is in the middle
+ * of parsing this will return json_tokener_continue.
+ *
+ * See also json_tokener_error_desc().
+ */
+enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
+
+extern struct json_tokener* json_tokener_new(void);
+extern struct json_tokener* json_tokener_new_ex(int depth);
+extern void json_tokener_free(struct json_tokener *tok);
+extern void json_tokener_reset(struct json_tokener *tok);
+extern struct json_object* json_tokener_parse(const char *str);
+extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
+
+/**
+ * Set flags that control how parsing will be done.
+ */
+extern void json_tokener_set_flags(struct json_tokener *tok, int flags);
+
+/**
+ * Parse a string and return a non-NULL json_object if a valid JSON value
+ * is found. The string does not need to be a JSON object or array;
+ * it can also be a string, number or boolean value.
+ *
+ * A partial JSON string can be parsed. If the parsing is incomplete,
+ * NULL will be returned and json_tokener_get_error() will be return
+ * json_tokener_continue.
+ * json_tokener_parse_ex() can then be called with additional bytes in str
+ * to continue the parsing.
+ *
+ * If json_tokener_parse_ex() returns NULL and the error anything other than
+ * json_tokener_continue, a fatal error has occurred and parsing must be
+ * halted. Then tok object must not be re-used until json_tokener_reset() is
+ * called.
+ *
+ * When a valid JSON value is parsed, a non-NULL json_object will be
+ * returned. Also, json_tokener_get_error() will return json_tokener_success.
+ * Be sure to check the type with json_object_is_type() or
+ * json_object_get_type() before using the object.
+ *
+ * @b XXX this shouldn't use internal fields:
+ * Trailing characters after the parsed value do not automatically cause an
+ * error. It is up to the caller to decide whether to treat this as an
+ * error or to handle the additional characters, perhaps by parsing another
+ * json value starting from that point.
+ *
+ * Extra characters can be detected by comparing the tok->char_offset against
+ * the length of the last len parameter passed in.
+ *
+ * The tokener does \b not maintain an internal buffer so the caller is
+ * responsible for calling json_tokener_parse_ex with an appropriate str
+ * parameter starting with the extra characters.
+ *
+ * This interface is presently not 64-bit clean due to the int len argument
+ * so the function limits the maximum string size to INT32_MAX (2GB).
+ * If the function is called with len == -1 then strlen is called to check
+ * the string length is less than INT32_MAX (2GB)
+ *
+ * Example:
+ * @code
+json_object *jobj = NULL;
+const char *mystring = NULL;
+int stringlen = 0;
+enum json_tokener_error jerr;
+do {
+ mystring = ... // get JSON string, e.g. read from file, etc...
+ stringlen = strlen(mystring);
+ jobj = json_tokener_parse_ex(tok, mystring, stringlen);
+} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+if (jerr != json_tokener_success)
+{
+ fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+ // Handle errors, as appropriate for your application.
+}
+if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
+{
+ // Handle extra characters after parsed object as desired.
+ // e.g. issue an error, parse another object from that point, etc...
+}
+// Success, use jobj here.
+
+@endcode
+ *
+ * @param tok a json_tokener previously allocated with json_tokener_new()
+ * @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
+ * @param len the length of str
+ */
+extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+ const char *str, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/json_util.c b/plugins-extra/ExtraPlugins/json-c/json_util.c
new file mode 100644
index 0000000..fda5d1e
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_util.c
@@ -0,0 +1,301 @@
+/*
+ * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+#undef realloc
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_SYS_TYPES_H
+#include
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+#include
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_FCNTL_H
+#include
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_UNISTD_H
+# include
+#endif /* HAVE_UNISTD_H */
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# include
+# include
+#endif /* defined(_WIN32) */
+
+#if !defined(HAVE_OPEN) && defined(_WIN32)
+# define open _open
+#endif
+
+#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
+ /* MSC has the version as _snprintf */
+# define snprintf _snprintf
+#elif !defined(HAVE_SNPRINTF)
+# error You do not have snprintf on your system.
+#endif /* HAVE_SNPRINTF */
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "json_inttypes.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+static int sscanf_is_broken = 0;
+static int sscanf_is_broken_testdone = 0;
+static void sscanf_is_broken_test(void);
+
+struct json_object* json_object_from_file(const char *filename)
+{
+ //struct printbuf *pb;
+ //struct json_object *obj;
+ //char buf[JSON_FILE_BUF_SIZE];
+ //int fd, ret;
+
+ //if((fd = open(filename, O_RDONLY)) < 0) {
+ // MC_ERROR("json_object_from_file: error opening file %s: %s\n",
+ // filename, strerror(errno));
+ // return NULL;
+ //}
+ //if(!(pb = printbuf_new())) {
+ // close(fd);
+ // MC_ERROR("json_object_from_file: printbuf_new failed\n");
+ // return NULL;
+ //}
+ //while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
+ // printbuf_memappend(pb, buf, ret);
+ //}
+ //close(fd);
+ //if(ret < 0) {
+ // MC_ERROR("json_object_from_file: error reading file %s: %s\n",
+ // filename, strerror(errno));
+ // printbuf_free(pb);
+ // return NULL;
+ //}
+ //obj = json_tokener_parse(pb->buf);
+ //printbuf_free(pb);
+ return NULL;//obj;
+}
+
+/* extended "format and write to file" function */
+
+int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
+{
+ //const char *json_str;
+ //int fd, ret;
+ //unsigned int wpos, wsize;
+
+ //if(!obj) {
+ // MC_ERROR("json_object_to_file: object is null\n");
+ // return -1;
+ //}
+
+ //if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
+ // MC_ERROR("json_object_to_file: error opening file %s: %s\n",
+ // filename, strerror(errno));
+ // return -1;
+ //}
+
+ //if(!(json_str = json_object_to_json_string_ext(obj,flags))) {
+ // close(fd);
+ // return -1;
+ //}
+
+ //wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
+ //wpos = 0;
+ //while(wpos < wsize) {
+ // if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
+ // close(fd);
+ // MC_ERROR("json_object_to_file: error writing file %s: %s\n",
+ // filename, strerror(errno));
+ // return -1;
+ // }
+
+ // /* because of the above check for ret < 0, we can safely cast and add */
+ // wpos += (unsigned int)ret;
+ //}
+
+ //close(fd);
+ return 0;
+}
+
+// backwards compatible "format and write to file" function
+
+int json_object_to_file(const char *filename, struct json_object *obj)
+{
+ return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
+}
+
+int json_parse_double(const char *buf, double *retval)
+{
+ return (sscanf_s(buf, "%lf", retval)==1 ? 0 : 1);
+}
+
+/*
+ * Not all implementations of sscanf actually work properly.
+ * Check whether the one we're currently using does, and if
+ * it's broken, enable the workaround code.
+ */
+static void sscanf_is_broken_test()
+{
+ int64_t num64;
+ int ret_errno, is_int64_min, ret_errno2, is_int64_max;
+
+ sscanf_s(" -01234567890123456789012345", "%" SCNd64, &num64);
+ ret_errno = errno;
+ is_int64_min = (num64 == INT64_MIN);
+
+ sscanf_s(" 01234567890123456789012345", "%" SCNd64, &num64);
+ ret_errno2 = errno;
+ is_int64_max = (num64 == INT64_MAX);
+
+ if (ret_errno != ERANGE || !is_int64_min ||
+ ret_errno2 != ERANGE || !is_int64_max)
+ {
+ MC_DEBUG("sscanf_is_broken_test failed, enabling workaround code\n");
+ sscanf_is_broken = 1;
+ }
+}
+
+int json_parse_int64(const char *buf, int64_t *retval)
+{
+ int64_t num64;
+ const char *buf_sig_digits;
+ int orig_has_neg;
+ int saved_errno;
+
+ if (!sscanf_is_broken_testdone)
+ {
+ sscanf_is_broken_test();
+ sscanf_is_broken_testdone = 1;
+ }
+
+ // Skip leading spaces
+ while (isspace((int)*buf) && *buf)
+ buf++;
+
+ errno = 0; // sscanf won't always set errno, so initialize
+
+ if (sscanf_s(buf, "%" SCNd64, &num64) != 1)
+ {
+ MC_DEBUG("Failed to parse, sscanf != 1\n");
+ return 1;
+ }
+
+ saved_errno = errno;
+ buf_sig_digits = buf;
+ orig_has_neg = 0;
+ if (*buf_sig_digits == '-')
+ {
+ buf_sig_digits++;
+ orig_has_neg = 1;
+ }
+
+ // Not all sscanf implementations actually work
+ if (sscanf_is_broken && saved_errno != ERANGE)
+ {
+ char buf_cmp[100];
+ char *buf_cmp_start = buf_cmp;
+ int recheck_has_neg = 0;
+ int buf_cmp_len;
+
+ // Skip leading zeros, but keep at least one digit
+ while (buf_sig_digits[0] == '0' && buf_sig_digits[1] != '\0')
+ buf_sig_digits++;
+ if (num64 == 0) // assume all sscanf impl's will parse -0 to 0
+ orig_has_neg = 0; // "-0" is the same as just plain "0"
+
+ _snprintf_s(buf_cmp_start, sizeof(buf_cmp), _TRUNCATE, "%" PRId64, num64);
+ if (*buf_cmp_start == '-')
+ {
+ recheck_has_neg = 1;
+ buf_cmp_start++;
+ }
+ // No need to skip leading spaces or zeros here.
+
+ buf_cmp_len = (int)strlen(buf_cmp_start);
+ /**
+ * If the sign is different, or
+ * some of the digits are different, or
+ * there is another digit present in the original string
+ * then we have NOT successfully parsed the value.
+ */
+ if (orig_has_neg != recheck_has_neg ||
+ strncmp(buf_sig_digits, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
+ ((int)strlen(buf_sig_digits) != buf_cmp_len &&
+ isdigit((int)buf_sig_digits[buf_cmp_len])
+ )
+ )
+ {
+ saved_errno = ERANGE;
+ }
+ }
+
+ // Not all sscanf impl's set the value properly when out of range.
+ // Always do this, even for properly functioning implementations,
+ // since it shouldn't slow things down much.
+ if (saved_errno == ERANGE)
+ {
+ if (orig_has_neg)
+ num64 = INT64_MIN;
+ else
+ num64 = INT64_MAX;
+ }
+ *retval = num64;
+ return 0;
+}
+
+#ifndef HAVE_REALLOC
+void* rpl_realloc(void* p, size_t n)
+{
+ if (n == 0)
+ n = 1;
+ if (p == 0)
+ return malloc(n);
+ return realloc(p, n);
+}
+#endif
+
+#define NELEM(a) (sizeof(a) / sizeof(a[0]))
+static const char* json_type_name[] = {
+ /* If you change this, be sure to update the enum json_type definition too */
+ "null",
+ "boolean",
+ "double",
+ "int",
+ "object",
+ "array",
+ "string",
+};
+
+const char *json_type_to_name(enum json_type o_type)
+{
+ int o_type_int = (int)o_type;
+ if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
+ {
+ MC_ERROR("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
+ return NULL;
+ }
+ return json_type_name[o_type];
+}
+
diff --git a/plugins-extra/ExtraPlugins/json-c/json_util.h b/plugins-extra/ExtraPlugins/json-c/json_util.h
new file mode 100644
index 0000000..1005e58
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/json_util.h
@@ -0,0 +1,41 @@
+/*
+ * $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_util_h_
+#define _json_util_h_
+
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define JSON_FILE_BUF_SIZE 4096
+
+/* utility functions */
+extern struct json_object* json_object_from_file(const char *filename);
+extern int json_object_to_file(const char *filename, struct json_object *obj);
+extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
+extern int json_parse_int64(const char *buf, int64_t *retval);
+extern int json_parse_double(const char *buf, double *retval);
+
+
+/**
+ * Return a string describing the type of the object.
+ * e.g. "int", or "object", etc...
+ */
+extern const char *json_type_to_name(enum json_type o_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/libjson.c b/plugins-extra/ExtraPlugins/json-c/libjson.c
new file mode 100644
index 0000000..5284fd0
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/libjson.c
@@ -0,0 +1,26 @@
+
+/* dummy source file for compatibility purposes */
+
+#if defined(HAVE_CDEFS_H)
+#include
+#endif
+
+#ifndef __warn_references
+
+#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG)
+
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text");
+
+#else
+#define __warn_references(sym,msg) /* nothing */
+#endif
+
+#endif
+
+#include "json_object.h"
+
+__warn_references(json_object_get, "Warning: please link against libjson-c instead of libjson");
+
+/* __asm__(".section .gnu.warning." __STRING(sym) \
+ " ; .ascii \"" msg "\" ; .text") */
diff --git a/plugins-extra/ExtraPlugins/json-c/linkhash.c b/plugins-extra/ExtraPlugins/json-c/linkhash.c
new file mode 100644
index 0000000..50de485
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/linkhash.c
@@ -0,0 +1,604 @@
+/*
+ * $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef HAVE_ENDIAN_H
+# include /* attempt to define endianness */
+#endif
+
+#include "random_seed.h"
+#include "linkhash.h"
+
+void lh_abort(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+ vprintf(msg, ap);
+ va_end(ap);
+ exit(1);
+}
+
+unsigned long lh_ptr_hash(const void *k)
+{
+ /* CAW: refactored to be 64bit nice */
+ return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX);
+}
+
+int lh_ptr_equal(const void *k1, const void *k2)
+{
+ return (k1 == k2);
+}
+
+/*
+ * hashlittle from lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ * http://burtleburtle.net/bob/c/lookup3.c
+ * minor modifications to make functions static so no symbols are exported
+ * minor mofifications to compile with -Werror
+ */
+
+/*
+-------------------------------------------------------------------------------
+lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+
+These are functions for producing 32-bit hashes for hash table lookup.
+hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+are externally useful functions. Routines to test the hash are included
+if SELF_TEST is defined. You can use this free for any purpose. It's in
+the public domain. It has no warranty.
+
+You probably want to use hashlittle(). hashlittle() and hashbig()
+hash byte arrays. hashlittle() is is faster than hashbig() on
+little-endian machines. Intel and AMD are little-endian machines.
+On second thought, you probably want hashlittle2(), which is identical to
+hashlittle() except it returns two 32-bit hashes for the price of one.
+You could implement hashbig2() if you wanted but I haven't bothered here.
+
+If you want to find a hash of, say, exactly 7 integers, do
+ a = i1; b = i2; c = i3;
+ mix(a,b,c);
+ a += i4; b += i5; c += i6;
+ mix(a,b,c);
+ a += i7;
+ final(a,b,c);
+then use c as the hash value. If you have a variable length array of
+4-byte integers to hash, use hashword(). If you have a byte array (like
+a character string), use hashlittle(). If you have several byte arrays, or
+a mix of things, see the comments above hashlittle().
+
+Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
+then mix those integers. This is fast (you can do a lot more thorough
+mixing with 12*3 instructions on 3 integers than you can with 3 instructions
+on 1 byte), but shoehorning those bytes into integers efficiently is messy.
+-------------------------------------------------------------------------------
+*/
+
+/*
+ * My best guess at if you are big-endian or little-endian. This may
+ * need adjustment.
+ */
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
+ __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(i386) || defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
+# define HASH_LITTLE_ENDIAN 1
+# define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
+ __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 1
+#else
+# define HASH_LITTLE_ENDIAN 0
+# define HASH_BIG_ENDIAN 0
+#endif
+
+#define hashsize(n) ((uint32_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/*
+-------------------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+
+This is reversible, so any information in (a,b,c) before mix() is
+still in (a,b,c) after mix().
+
+If four pairs of (a,b,c) inputs are run through mix(), or through
+mix() in reverse, there are at least 32 bits of the output that
+are sometimes the same for one pair and different for another pair.
+This was tested for:
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
+satisfy this are
+ 4 6 8 16 19 4
+ 9 15 3 18 27 15
+ 14 9 3 7 17 3
+Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
+for "differ" defined as + with a one-bit base and a two-bit delta. I
+used http://burtleburtle.net/bob/hash/avalanche.html to choose
+the operations, constants, and arrangements of the variables.
+
+This does not achieve avalanche. There are input bits of (a,b,c)
+that fail to affect some output bits of (a,b,c), especially of a. The
+most thoroughly mixed value is c, but it doesn't really even achieve
+avalanche in c.
+
+This allows some parallelism. Read-after-writes are good at doubling
+the number of bits affected, so the goal of mixing pulls in the opposite
+direction as the goal of parallelism. I did what I could. Rotates
+seem to cost as much as shifts on every machine I could lay my hands
+on, and rotates are much kinder to the top and bottom bits, so I used
+rotates.
+-------------------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+
+/*
+-------------------------------------------------------------------------------
+final -- final mixing of 3 32-bit values (a,b,c) into c
+
+Pairs of (a,b,c) values differing in only a few bits will usually
+produce values of c that look totally different. This was tested for
+* pairs that differed by one bit, by two bits, in any combination
+ of top bits of (a,b,c), or in any combination of bottom bits of
+ (a,b,c).
+* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
+ the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
+ is commonly produced by subtraction) look like a single 1-bit
+ difference.
+* the base values were pseudorandom, all zero but one bit set, or
+ all zero plus a counter that starts at zero.
+
+These constants passed:
+ 14 11 25 16 4 14 24
+ 12 14 25 16 4 14 24
+and these came close:
+ 4 8 15 26 3 22 24
+ 10 8 15 26 3 22 24
+ 11 8 15 26 3 22 24
+-------------------------------------------------------------------------------
+*/
+#define final(a,b,c) \
+{ \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c,4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
+}
+
+
+/*
+-------------------------------------------------------------------------------
+hashlittle() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ length : the length of the key, counting by bytes
+ initval : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Two keys differing by one or two bits will have
+totally different hash values.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (uint8_t **)k, do it like this:
+ for (i=0, h=0; i 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 12;
+ k += 3;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
+ * then masks off the part it's not allowed to read. Because the
+ * string is aligned, the masked-off tail is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ */
+#ifndef VALGRIND
+
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+ case 5 : b+=k[1]&0xff; a+=k[0]; break;
+ case 4 : a+=k[0]; break;
+ case 3 : a+=k[0]&0xffffff; break;
+ case 2 : a+=k[0]&0xffff; break;
+ case 1 : a+=k[0]&0xff; break;
+ case 0 : return c; /* zero length strings require no mixing */
+ }
+
+#else /* make valgrind happy */
+
+ const uint8_t *k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]; break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
+ case 1 : a+=k8[0]; break;
+ case 0 : return c;
+ }
+
+#endif /* !valgrind */
+
+ } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12)
+ {
+ a += k[0] + (((uint32_t)k[1])<<16);
+ b += k[2] + (((uint32_t)k[3])<<16);
+ c += k[4] + (((uint32_t)k[5])<<16);
+ mix(a,b,c);
+ length -= 12;
+ k += 6;
+ }
+
+ /*----------------------------- handle the last (probably partial) block */
+ k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=k[4];
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=k[2];
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=k[0];
+ break;
+ case 1 : a+=k8[0];
+ break;
+ case 0 : return c; /* zero length requires no mixing */
+ }
+
+ } else { /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *)key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ a += ((uint32_t)k[1])<<8;
+ a += ((uint32_t)k[2])<<16;
+ a += ((uint32_t)k[3])<<24;
+ b += k[4];
+ b += ((uint32_t)k[5])<<8;
+ b += ((uint32_t)k[6])<<16;
+ b += ((uint32_t)k[7])<<24;
+ c += k[8];
+ c += ((uint32_t)k[9])<<8;
+ c += ((uint32_t)k[10])<<16;
+ c += ((uint32_t)k[11])<<24;
+ mix(a,b,c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32_t)k[11])<<24;
+ case 11: c+=((uint32_t)k[10])<<16;
+ case 10: c+=((uint32_t)k[9])<<8;
+ case 9 : c+=k[8];
+ case 8 : b+=((uint32_t)k[7])<<24;
+ case 7 : b+=((uint32_t)k[6])<<16;
+ case 6 : b+=((uint32_t)k[5])<<8;
+ case 5 : b+=k[4];
+ case 4 : a+=((uint32_t)k[3])<<24;
+ case 3 : a+=((uint32_t)k[2])<<16;
+ case 2 : a+=((uint32_t)k[1])<<8;
+ case 1 : a+=k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ final(a,b,c);
+ return c;
+}
+
+unsigned long lh_char_hash(const void *k)
+{
+ static volatile int random_seed = -1;
+
+ if (random_seed == -1) {
+ int seed;
+ /* we can't use -1 as it is the unitialized sentinel */
+ while ((seed = json_c_get_random_seed()) == -1);
+#if defined __GNUC__
+ __sync_val_compare_and_swap(&random_seed, -1, seed);
+#elif defined _MSC_VER
+ InterlockedCompareExchange(&random_seed, seed, -1);
+#else
+#warning "racy random seed initializtion if used by multiple threads"
+ random_seed = seed; /* potentially racy */
+#endif
+ }
+
+ return hashlittle((const char*)k, strlen((const char*)k), random_seed);
+}
+
+int lh_char_equal(const void *k1, const void *k2)
+{
+ return (strcmp((const char*)k1, (const char*)k2) == 0);
+}
+
+struct lh_table* lh_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn,
+ lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn)
+{
+ int i;
+ struct lh_table *t;
+
+ t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
+ if(!t) lh_abort("lh_table_new: calloc failed\n");
+ t->count = 0;
+ t->size = size;
+ t->name = name;
+ t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry));
+ if(!t->table) lh_abort("lh_table_new: calloc failed\n");
+ t->free_fn = free_fn;
+ t->hash_fn = hash_fn;
+ t->equal_fn = equal_fn;
+ for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
+ return t;
+}
+
+struct lh_table* lh_kchar_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn)
+{
+ return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal);
+}
+
+struct lh_table* lh_kptr_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn)
+{
+ return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal);
+}
+
+void lh_table_resize(struct lh_table *t, int new_size)
+{
+ struct lh_table *new_t;
+ struct lh_entry *ent;
+
+ new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn);
+ ent = t->head;
+ while(ent) {
+ lh_table_insert(new_t, ent->k, ent->v);
+ ent = ent->next;
+ }
+ free(t->table);
+ t->table = new_t->table;
+ t->size = new_size;
+ t->head = new_t->head;
+ t->tail = new_t->tail;
+ t->resizes++;
+ free(new_t);
+}
+
+void lh_table_free(struct lh_table *t)
+{
+ struct lh_entry *c;
+ for(c = t->head; c != NULL; c = c->next) {
+ if(t->free_fn) {
+ t->free_fn(c);
+ }
+ }
+ free(t->table);
+ free(t);
+}
+
+
+int lh_table_insert(struct lh_table *t, void *k, const void *v)
+{
+ unsigned long h, n;
+
+ t->inserts++;
+ if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2);
+
+ h = t->hash_fn(k);
+ n = h % t->size;
+
+ while( 1 ) {
+ if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
+ t->collisions++;
+ if ((int)++n == t->size) n = 0;
+ }
+
+ t->table[n].k = k;
+ t->table[n].v = v;
+ t->count++;
+
+ if(t->head == NULL) {
+ t->head = t->tail = &t->table[n];
+ t->table[n].next = t->table[n].prev = NULL;
+ } else {
+ t->tail->next = &t->table[n];
+ t->table[n].prev = t->tail;
+ t->table[n].next = NULL;
+ t->tail = &t->table[n];
+ }
+
+ return 0;
+}
+
+
+struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
+{
+ unsigned long h = t->hash_fn(k);
+ unsigned long n = h % t->size;
+ int count = 0;
+
+ t->lookups++;
+ while( count < t->size ) {
+ if(t->table[n].k == LH_EMPTY) return NULL;
+ if(t->table[n].k != LH_FREED &&
+ t->equal_fn(t->table[n].k, k)) return &t->table[n];
+ if ((int)++n == t->size) n = 0;
+ count++;
+ }
+ return NULL;
+}
+
+
+const void* lh_table_lookup(struct lh_table *t, const void *k)
+{
+ void *result;
+ lh_table_lookup_ex(t, k, &result);
+ return result;
+}
+
+json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
+{
+ struct lh_entry *e = lh_table_lookup_entry(t, k);
+ if (e != NULL) {
+ if (v != NULL) *v = (void *)e->v;
+ return TRUE; /* key found */
+ }
+ if (v != NULL) *v = NULL;
+ return FALSE; /* key not found */
+}
+
+int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
+{
+ ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
+
+ /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
+ if(n < 0) { return -2; }
+
+ if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
+ t->count--;
+ if(t->free_fn) t->free_fn(e);
+ t->table[n].v = NULL;
+ t->table[n].k = LH_FREED;
+ if(t->tail == &t->table[n] && t->head == &t->table[n]) {
+ t->head = t->tail = NULL;
+ } else if (t->head == &t->table[n]) {
+ t->head->next->prev = NULL;
+ t->head = t->head->next;
+ } else if (t->tail == &t->table[n]) {
+ t->tail->prev->next = NULL;
+ t->tail = t->tail->prev;
+ } else {
+ t->table[n].prev->next = t->table[n].next;
+ t->table[n].next->prev = t->table[n].prev;
+ }
+ t->table[n].next = t->table[n].prev = NULL;
+ return 0;
+}
+
+
+int lh_table_delete(struct lh_table *t, const void *k)
+{
+ struct lh_entry *e = lh_table_lookup_entry(t, k);
+ if(!e) return -1;
+ return lh_table_delete_entry(t, e);
+}
+
+int lh_table_length(struct lh_table *t)
+{
+ return t->count;
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/linkhash.h b/plugins-extra/ExtraPlugins/json-c/linkhash.h
new file mode 100644
index 0000000..950d09f
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/linkhash.h
@@ -0,0 +1,292 @@
+/*
+ * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _linkhash_h_
+#define _linkhash_h_
+
+#include "json_object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * golden prime used in hash functions
+ */
+#define LH_PRIME 0x9e370001UL
+
+/**
+ * The fraction of filled hash buckets until an insert will cause the table
+ * to be resized.
+ * This can range from just above 0 up to 1.0.
+ */
+#define LH_LOAD_FACTOR 0.66
+
+/**
+ * sentinel pointer value for empty slots
+ */
+#define LH_EMPTY (void*)-1
+
+/**
+ * sentinel pointer value for freed slots
+ */
+#define LH_FREED (void*)-2
+
+struct lh_entry;
+
+/**
+ * callback function prototypes
+ */
+typedef void (lh_entry_free_fn) (struct lh_entry *e);
+/**
+ * callback function prototypes
+ */
+typedef unsigned long (lh_hash_fn) (const void *k);
+/**
+ * callback function prototypes
+ */
+typedef int (lh_equal_fn) (const void *k1, const void *k2);
+
+/**
+ * An entry in the hash table
+ */
+struct lh_entry {
+ /**
+ * The key.
+ */
+ void *k;
+ /**
+ * The value.
+ */
+ const void *v;
+ /**
+ * The next entry
+ */
+ struct lh_entry *next;
+ /**
+ * The previous entry.
+ */
+ struct lh_entry *prev;
+};
+
+
+/**
+ * The hash table structure.
+ */
+struct lh_table {
+ /**
+ * Size of our hash.
+ */
+ int size;
+ /**
+ * Numbers of entries.
+ */
+ int count;
+
+ /**
+ * Number of collisions.
+ */
+ int collisions;
+
+ /**
+ * Number of resizes.
+ */
+ int resizes;
+
+ /**
+ * Number of lookups.
+ */
+ int lookups;
+
+ /**
+ * Number of inserts.
+ */
+ int inserts;
+
+ /**
+ * Number of deletes.
+ */
+ int deletes;
+
+ /**
+ * Name of the hash table.
+ */
+ const char *name;
+
+ /**
+ * The first entry.
+ */
+ struct lh_entry *head;
+
+ /**
+ * The last entry.
+ */
+ struct lh_entry *tail;
+
+ struct lh_entry *table;
+
+ /**
+ * A pointer onto the function responsible for freeing an entry.
+ */
+ lh_entry_free_fn *free_fn;
+ lh_hash_fn *hash_fn;
+ lh_equal_fn *equal_fn;
+};
+
+
+/**
+ * Pre-defined hash and equality functions
+ */
+extern unsigned long lh_ptr_hash(const void *k);
+extern int lh_ptr_equal(const void *k1, const void *k2);
+
+extern unsigned long lh_char_hash(const void *k);
+extern int lh_char_equal(const void *k1, const void *k2);
+
+
+/**
+ * Convenience list iterator.
+ */
+#define lh_foreach(table, entry) \
+for(entry = table->head; entry; entry = entry->next)
+
+/**
+ * lh_foreach_safe allows calling of deletion routine while iterating.
+ */
+#define lh_foreach_safe(table, entry, tmp) \
+for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
+
+
+
+/**
+ * Create a new linkhash table.
+ * @param size initial table size. The table is automatically resized
+ * although this incurs a performance penalty.
+ * @param name the table name.
+ * @param free_fn callback function used to free memory for entries
+ * when lh_table_free or lh_table_delete is called.
+ * If NULL is provided, then memory for keys and values
+ * must be freed by the caller.
+ * @param hash_fn function used to hash keys. 2 standard ones are defined:
+ * lh_ptr_hash and lh_char_hash for hashing pointer values
+ * and C strings respectively.
+ * @param equal_fn comparison function to compare keys. 2 standard ones defined:
+ * lh_ptr_hash and lh_char_hash for comparing pointer values
+ * and C strings respectively.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn,
+ lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn);
+
+/**
+ * Convenience function to create a new linkhash
+ * table with char keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kchar_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn);
+
+
+/**
+ * Convenience function to create a new linkhash
+ * table with ptr keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kptr_table_new(int size, const char *name,
+ lh_entry_free_fn *free_fn);
+
+
+/**
+ * Free a linkhash table.
+ * If a callback free function is provided then it is called for all
+ * entries in the table.
+ * @param t table to free.
+ */
+extern void lh_table_free(struct lh_table *t);
+
+
+/**
+ * Insert a record into the table.
+ * @param t the table to insert into.
+ * @param k a pointer to the key to insert.
+ * @param v a pointer to the value to insert.
+ */
+extern int lh_table_insert(struct lh_table *t, void *k, const void *v);
+
+
+/**
+ * Lookup a record into the table.
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the record structure of the value or NULL if it does not exist.
+ */
+extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k);
+
+/**
+ * Lookup a record into the table
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the found value or NULL if it does not exist.
+ * @deprecated Use lh_table_lookup_ex instead.
+ */
+THIS_FUNCTION_IS_DEPRECATED(extern const void* lh_table_lookup(struct lh_table *t, const void *k));
+
+/**
+ * Lookup a record in the table
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
+ * @return whether or not the key was found
+ */
+extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param e a pointer to the entry to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
+
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param k a pointer to the key to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete(struct lh_table *t, const void *k);
+
+extern int lh_table_length(struct lh_table *t);
+
+void lh_abort(const char *msg, ...);
+void lh_table_resize(struct lh_table *t, int new_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/math_compat.h b/plugins-extra/ExtraPlugins/json-c/math_compat.h
new file mode 100644
index 0000000..f40b8fa
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/math_compat.h
@@ -0,0 +1,28 @@
+#ifndef __math_compat_h
+#define __math_compat_h
+
+/* Define isnan and isinf on Windows/MSVC */
+
+#ifndef HAVE_DECL_ISNAN
+# ifdef HAVE_DECL__ISNAN
+#include
+#define isnan(x) _isnan(x)
+# endif
+#endif
+
+#ifndef HAVE_DECL_ISINF
+# ifdef HAVE_DECL__FINITE
+#include
+#define isinf(x) (!_finite(x))
+# endif
+#endif
+
+#ifndef HAVE_DECL_NAN
+#error This platform does not have nan()
+#endif
+
+#ifndef HAVE_DECL_INFINITY
+#error This platform does not have INFINITY
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/printbuf.c b/plugins-extra/ExtraPlugins/json-c/printbuf.c
new file mode 100644
index 0000000..94d41b0
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/printbuf.c
@@ -0,0 +1,194 @@
+/*
+ * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+
+#ifdef HAVE_STDARG_H
+# include
+#else /* !HAVE_STDARG_H */
+# error Not enough var arg support!
+#endif /* HAVE_STDARG_H */
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+
+static int printbuf_extend(struct printbuf *p, size_t min_size);
+
+struct printbuf* printbuf_new(void)
+{
+ struct printbuf *p;
+
+ p = (struct printbuf*)calloc(1, sizeof(struct printbuf));
+ if(!p) return NULL;
+ p->size = 32;
+ p->bpos = 0;
+ if(!(p->buf = (char*)malloc(p->size))) {
+ free(p);
+ return NULL;
+ }
+ return p;
+}
+
+
+/**
+ * Extend the buffer p so it has a size of at least min_size.
+ *
+ * If the current size is large enough, nothing is changed.
+ *
+ * Note: this does not check the available space! The caller
+ * is responsible for performing those calculations.
+ */
+static int printbuf_extend(struct printbuf *p, size_t min_size)
+{
+ char *t;
+ size_t new_size;
+
+ if (p->size >= min_size)
+ return 0;
+
+ new_size = json_max(p->size * 2, min_size + 8);
+#ifdef PRINTBUF_DEBUG
+ MC_DEBUG("printbuf_memappend: realloc "
+ "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+ p->bpos, min_size, p->size, new_size);
+#endif /* PRINTBUF_DEBUG */
+ if(!(t = (char*)realloc(p->buf, new_size)))
+ return -1;
+ p->size = new_size;
+ p->buf = t;
+ return 0;
+}
+
+size_t printbuf_memappend(struct printbuf *p, const char *buf, size_t size)
+{
+ if (p->size <= p->bpos + size + 1) {
+ if (printbuf_extend(p, p->bpos + size + 1) < 0)
+ return -1;
+ }
+ memcpy(p->buf + p->bpos, buf, size);
+ p->bpos += size;
+ p->buf[p->bpos]= '\0';
+ return size;
+}
+
+int printbuf_memset(struct printbuf *pb, size_t offset, int charvalue, size_t len)
+{
+ size_t size_needed;
+
+ if (offset == -1)
+ offset = pb->bpos;
+ size_needed = offset + len;
+ if (pb->size < size_needed)
+ {
+ if (printbuf_extend(pb, size_needed) < 0)
+ return -1;
+ }
+
+ memset(pb->buf + offset, charvalue, len);
+ if (pb->bpos < size_needed)
+ pb->bpos = size_needed;
+
+ return 0;
+}
+
+#if !defined(HAVE_VSNPRINTF) && defined(_MSC_VER)
+# define vsnprintf _vsnprintf
+#elif !defined(HAVE_VSNPRINTF) /* !HAVE_VSNPRINTF */
+# error Need vsnprintf!
+#endif /* !HAVE_VSNPRINTF && defined(_WIN32) */
+
+#if !defined(HAVE_VASPRINTF)
+/* CAW: compliant version of vasprintf */
+static int vasprintf(char **buf, const char *fmt, va_list ap)
+{
+#ifndef _WIN32
+ static char _T_emptybuffer = '\0';
+#endif /* !defined(_WIN32) */
+ int chars;
+ char *b;
+
+ if(!buf) { return -1; }
+
+#ifdef _WIN32
+ chars = _vscprintf(fmt, ap)+1;
+#else /* !defined(_WIN32) */
+ /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
+ our buffer like on some 64bit sun systems.... but hey, its time to move on */
+ chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
+ if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
+#endif /* defined(_WIN32) */
+
+ b = (char*)malloc(sizeof(char) * chars);
+ if(!b) { return -1; }
+
+ if ((chars = vsprintf_s(b, sizeof(char), fmt, ap)) < 0)
+ {
+ free(b);
+ }
+ else
+ {
+ *buf = b;
+ }
+
+ return chars;
+}
+#endif /* !HAVE_VASPRINTF */
+
+int sprintbuf(struct printbuf *p, const char *msg, ...)
+{
+ va_list ap;
+ char *t;
+ int size;
+ char buf[128];
+
+ /* user stack buffer first */
+ va_start(ap, msg);
+ size = _vsnprintf_s(buf, sizeof(buf), _TRUNCATE, msg, ap);
+ va_end(ap);
+ /* if string is greater than stack buffer, then use dynamic string
+ with vasprintf. Note: some implementation of vsnprintf return -1
+ if output is truncated whereas some return the number of bytes that
+ would have been written - this code handles both cases. */
+ if(size == -1 || size > 127) {
+ va_start(ap, msg);
+ if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
+ va_end(ap);
+ printbuf_memappend(p, t, size);
+ free(t);
+ return size;
+ } else {
+ printbuf_memappend(p, buf, size);
+ return size;
+ }
+}
+
+void printbuf_reset(struct printbuf *p)
+{
+ p->buf[0] = '\0';
+ p->bpos = 0;
+}
+
+void printbuf_free(struct printbuf *p)
+{
+ if(p) {
+ free(p->buf);
+ free(p);
+ }
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/printbuf.h b/plugins-extra/ExtraPlugins/json-c/printbuf.h
new file mode 100644
index 0000000..ed003b6
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/printbuf.h
@@ -0,0 +1,81 @@
+/*
+ * $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ *
+ * Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
+ * The copyrights to the contents of this file are licensed under the MIT License
+ * (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+#ifndef _printbuf_h_
+#define _printbuf_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct printbuf {
+ char *buf;
+ size_t bpos;
+ size_t size;
+};
+
+extern struct printbuf*
+printbuf_new(void);
+
+/* As an optimization, printbuf_memappend_fast is defined as a macro
+ * that handles copying data if the buffer is large enough; otherwise
+ * it invokes printbuf_memappend_real() which performs the heavy
+ * lifting of realloc()ing the buffer and copying data.
+ * Your code should not use printbuf_memappend directly--use
+ * printbuf_memappend_fast instead.
+ */
+extern size_t printbuf_memappend(struct printbuf *p, const char *buf, size_t size);
+
+__inline void printbuf_memappend_fast(struct printbuf *p, const char *bufptr, size_t bufsize)
+{
+ if ((p->size - p->bpos) > bufsize)
+ {
+ memcpy(p->buf + p->bpos, (bufptr), bufsize);
+ p->bpos += (int)bufsize;
+ p->buf[p->bpos] = '\0';
+ }
+ else
+ {
+ printbuf_memappend(p, (bufptr), bufsize);
+ }
+}
+
+#define printbuf_length(p) ((p)->bpos)
+
+/**
+ * Set len bytes of the buffer to charvalue, starting at offset offset.
+ * Similar to calling memset(x, charvalue, len);
+ *
+ * The memory allocated for the buffer is extended as necessary.
+ *
+ * If offset is -1, this starts at the end of the current data in the buffer.
+ */
+extern int
+printbuf_memset(struct printbuf *pb, size_t offset, int charvalue, size_t len);
+
+extern int
+sprintbuf(struct printbuf *p, const char *msg, ...);
+
+extern void
+printbuf_reset(struct printbuf *p);
+
+extern void
+printbuf_free(struct printbuf *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/json-c/random_seed.c b/plugins-extra/ExtraPlugins/json-c/random_seed.c
new file mode 100644
index 0000000..ece374e
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/random_seed.c
@@ -0,0 +1,238 @@
+/*
+ * random_seed.c
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include
+#include "config.h"
+
+#define DEBUG_SEED(s)
+
+
+#if defined ENABLE_RDRAND
+
+/* cpuid */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+#define HAS_X86_CPUID 1
+
+static void do_cpuid(int regs[], int h)
+{
+ __asm__ __volatile__(
+#if defined __x86_64__
+ "pushq %%rbx;\n"
+#else
+ "pushl %%ebx;\n"
+#endif
+ "cpuid;\n"
+#if defined __x86_64__
+ "popq %%rbx;\n"
+#else
+ "popl %%ebx;\n"
+#endif
+ : "=a"(regs[0]), [ebx] "=r"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
+ : "a"(h));
+}
+
+#elif defined _MSC_VER
+
+#define HAS_X86_CPUID 1
+#define do_cpuid __cpuid
+
+#endif
+
+/* has_rdrand */
+
+#if HAS_X86_CPUID
+
+static int has_rdrand()
+{
+ // CPUID.01H:ECX.RDRAND[bit 30] == 1
+ int regs[4];
+ do_cpuid(regs, 1);
+ return (regs[2] & (1 << 30)) != 0;
+}
+
+#endif
+
+/* get_rdrand_seed - GCC x86 and X64 */
+
+#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
+
+#define HAVE_RDRAND 1
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int _eax;
+ // rdrand eax
+ __asm__ __volatile__("1: .byte 0x0F\n"
+ " .byte 0xC7\n"
+ " .byte 0xF0\n"
+ " jnc 1b;\n"
+ : "=a" (_eax));
+ return _eax;
+}
+
+#endif
+
+#if defined _MSC_VER
+
+#if _MSC_VER >= 1700
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2012 and above */
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int r;
+ while (_rdrand32_step(&r) == 0);
+ return r;
+}
+
+#elif defined _M_IX86
+#define HAVE_RDRAND 1
+
+/* get_rdrand_seed - Visual Studio 2010 and below - x86 only */
+
+static int get_rdrand_seed()
+{
+ DEBUG_SEED("get_rdrand_seed");
+ int _eax;
+retry:
+ // rdrand eax
+ __asm _emit 0x0F __asm _emit 0xC7 __asm _emit 0xF0
+ __asm jnc retry
+ __asm mov _eax, eax
+ return _eax;
+}
+
+#endif
+#endif
+
+#endif /* defined ENABLE_RDRAND */
+
+
+/* has_dev_urandom */
+
+#if defined (__APPLE__) || defined(__unix__) || defined(__linux__)
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define HAVE_DEV_RANDOM 1
+
+static const char *dev_random_file = "/dev/urandom";
+
+static int has_dev_urandom()
+{
+ struct stat buf;
+ if (stat(dev_random_file, &buf)) {
+ return 0;
+ }
+ return ((buf.st_mode & S_IFCHR) != 0);
+}
+
+
+/* get_dev_random_seed */
+
+static int get_dev_random_seed()
+{
+ DEBUG_SEED("get_dev_random_seed");
+
+ int fd = open(dev_random_file, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
+
+ int r;
+ ssize_t nread = read(fd, &r, sizeof(r));
+ if (nread != sizeof(r)) {
+ fprintf(stderr, "error read %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
+ else if (nread != sizeof(r)) {
+ fprintf(stderr, "error short read %s", dev_random_file);
+ exit(1);
+ }
+ close(fd);
+ return r;
+}
+
+#endif
+
+
+/* get_cryptgenrandom_seed */
+
+#ifdef _WIN32
+
+#define HAVE_CRYPTGENRANDOM 1
+
+#include
+
+static int get_cryptgenrandom_seed()
+{
+ DEBUG_SEED("get_cryptgenrandom_seed");
+
+ HCRYPTPROV hProvider = 0;
+ int r;
+
+ if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ fprintf(stderr, "error CryptAcquireContextW");
+ exit(1);
+ }
+
+ if (!CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r))
+ {
+ fprintf(stderr, "error CryptGenRandom");
+ exit(1);
+ }
+
+ CryptReleaseContext(hProvider, 0);
+
+ return r;
+}
+
+#endif
+
+
+/* get_time_seed */
+
+#include
+
+static int get_time_seed()
+{
+ DEBUG_SEED("get_time_seed");
+
+ return (int)time(NULL) * 433494437;
+}
+
+
+/* json_c_get_random_seed */
+
+int json_c_get_random_seed()
+{
+#if HAVE_RDRAND
+ if (has_rdrand()) return get_rdrand_seed();
+#endif
+#if HAVE_DEV_RANDOM
+ if (has_dev_urandom()) return get_dev_random_seed();
+#endif
+#if HAVE_CRYPTGENRANDOM
+ return get_cryptgenrandom_seed();
+#endif
+ return get_time_seed();
+}
diff --git a/plugins-extra/ExtraPlugins/json-c/random_seed.h b/plugins-extra/ExtraPlugins/json-c/random_seed.h
new file mode 100644
index 0000000..7362d67
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/json-c/random_seed.h
@@ -0,0 +1,25 @@
+/*
+ * random_seed.h
+ *
+ * Copyright (c) 2013 Metaparadigm Pte. Ltd.
+ * Michael Clark
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef seed_h
+#define seed_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int json_c_get_random_seed();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins-extra/ExtraPlugins/main.c b/plugins-extra/ExtraPlugins/main.c
new file mode 100644
index 0000000..3dd841b
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/main.c
@@ -0,0 +1,321 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Plugin Manager
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+PPH_PLUGIN PluginInstance;
+PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
+PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
+
+BOOLEAN LastCleanupExpired(
+ VOID
+ )
+{
+ ULONG64 lastUpdateTimeTicks = 0;
+ LARGE_INTEGER currentUpdateTimeTicks;
+ PPH_STRING lastUpdateTimeString;
+
+ PhQuerySystemTime(¤tUpdateTimeTicks);
+
+ lastUpdateTimeString = PhGetStringSetting(SETTING_NAME_LAST_CLEANUP);
+ PhStringToInteger64(&lastUpdateTimeString->sr, 0, &lastUpdateTimeTicks);
+ PhDereferenceObject(lastUpdateTimeString);
+
+ if (currentUpdateTimeTicks.QuadPart - lastUpdateTimeTicks >= 25 * PH_TICKS_PER_DAY)
+ {
+ PPH_STRING currentUpdateTimeString = PhFormatUInt64(currentUpdateTimeTicks.QuadPart, FALSE);
+
+ PhSetStringSetting2(SETTING_NAME_LAST_CLEANUP, ¤tUpdateTimeString->sr);
+
+ PhDereferenceObject(currentUpdateTimeString);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN PluginsCleanupDirectoryCallback(
+ _In_ PFILE_DIRECTORY_INFORMATION Information,
+ _In_opt_ PVOID Context
+ )
+{
+ PH_STRINGREF baseName;
+ PPH_STRING fileName;
+ PPH_STRING rootDirectoryPath;
+
+ rootDirectoryPath = Context;
+ baseName.Buffer = Information->FileName;
+ baseName.Length = Information->FileNameLength;
+
+ if (PhEqualStringRef2(&baseName, L".", TRUE) || PhEqualStringRef2(&baseName, L"..", TRUE))
+ return TRUE;
+
+ if (Information->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ HANDLE pluginsDirectoryHandle;
+ PPH_STRING directoryPath;
+ PPH_STRING PluginsDirectoryPath;
+
+ directoryPath = PhCreateString2(&baseName);
+ PluginsDirectoryPath = PhConcatStrings(4, rootDirectoryPath->Buffer, L"\\", directoryPath->Buffer, L"\\");
+
+ if (NT_SUCCESS(PhCreateFileWin32(
+ &pluginsDirectoryHandle,
+ PluginsDirectoryPath->Buffer,
+ FILE_GENERIC_READ,
+ 0,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
+ )))
+ {
+ UNICODE_STRING pattern = RTL_CONSTANT_STRING(L"*");
+
+ PhEnumDirectoryFile(pluginsDirectoryHandle, &pattern, PluginsCleanupDirectoryCallback, PluginsDirectoryPath);
+ NtClose(pluginsDirectoryHandle);
+ }
+ }
+ else if (PhEndsWithStringRef2(&baseName, L".bak", TRUE))
+ {
+ NTSTATUS status;
+ HANDLE fileHandle;
+ FILE_DISPOSITION_INFORMATION dispositionInfo;
+ IO_STATUS_BLOCK isb;
+
+ fileName = PhCreateStringEx(NULL, rootDirectoryPath->Length + Information->FileNameLength);
+ memcpy(fileName->Buffer, rootDirectoryPath->Buffer, rootDirectoryPath->Length);
+ memcpy(&fileName->Buffer[rootDirectoryPath->Length / 2], Information->FileName, Information->FileNameLength);
+
+ if (NT_SUCCESS(status = PhCreateFileWin32(
+ &fileHandle,
+ fileName->Buffer,
+ FILE_GENERIC_WRITE | DELETE,
+ 0,
+ 0,
+ FILE_OVERWRITE_IF,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
+ )))
+ {
+ dispositionInfo.DeleteFile = TRUE;
+ NtSetInformationFile(
+ fileHandle,
+ &isb,
+ &dispositionInfo,
+ sizeof(FILE_DISPOSITION_INFORMATION),
+ FileDispositionInformation
+ );
+
+ NtClose(fileHandle);
+ }
+
+ PhDereferenceObject(fileName);
+ }
+
+ return TRUE;
+}
+
+VOID PluginsCleanup(
+ VOID
+ )
+{
+ static UNICODE_STRING pluginsPattern = RTL_CONSTANT_STRING(L"*");
+ HANDLE pluginsDirectoryHandle;
+ PPH_STRING pluginsDirectory;
+ PPH_STRING PluginsDirectoryPath;
+
+ pluginsDirectory = PhGetStringSetting(L"PluginsDirectory");
+
+ if (RtlDetermineDosPathNameType_U(PhGetString(pluginsDirectory)) == RtlPathTypeRelative)
+ {
+ PluginsDirectoryPath = PhConcatStrings(
+ 4,
+ PhGetString(PhGetApplicationDirectory()),
+ L"\\",
+ PhGetStringOrEmpty(pluginsDirectory),
+ L"\\"
+ );
+ PhDereferenceObject(pluginsDirectory);
+ }
+ else
+ {
+ PluginsDirectoryPath = pluginsDirectory;
+ }
+
+ if (NT_SUCCESS(PhCreateFileWin32(
+ &pluginsDirectoryHandle,
+ PhGetStringOrEmpty(PluginsDirectoryPath),
+ FILE_GENERIC_READ,
+ 0,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
+ )))
+ {
+ PhEnumDirectoryFile(
+ pluginsDirectoryHandle,
+ &pluginsPattern,
+ PluginsCleanupDirectoryCallback,
+ PluginsDirectoryPath
+ );
+
+ NtClose(pluginsDirectoryHandle);
+ }
+}
+
+VOID NTAPI LoadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_LIST pluginArgvList = Parameter;
+
+ if (pluginArgvList)
+ {
+ for (ULONG i = 0; i < pluginArgvList->Count; i++)
+ {
+ PPH_STRING pluginCommandParam = pluginArgvList->Items[i];
+
+ if (PhEqualString2(pluginCommandParam, L"INSTALL", TRUE))
+ {
+ //PPH_STRING directory;
+ //PPH_STRING path;
+ //
+ //directory = PH_AUTO(PhGetApplicationDirectory());
+ //path = PhaCreateString(L"\\plugins");
+ //path = PH_AUTO(PhConcatStringRef2(&directory->sr, &path->sr));
+ //
+ //if (MoveFileWithProgress(
+ // L"new.plugin",
+ // path->Buffer,
+ // NULL,
+ // NULL,
+ // MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING
+ // ))
+ //{
+ //
+ //}
+
+ NtTerminateProcess(NtCurrentProcess(), EXIT_SUCCESS);
+ }
+ else if (PhEqualString2(pluginCommandParam, L"UNINSTALL", TRUE))
+ {
+ NtTerminateProcess(NtCurrentProcess(), EXIT_SUCCESS);
+ }
+ }
+ }
+ else
+ {
+ PluginsCleanup();
+ }
+}
+
+VOID NTAPI MainMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM pluginMenu;
+
+ if (menuInfo->u.MainMenu.SubMenuIndex != 0)
+ return;
+
+ if (pluginMenu = PhFindEMenuItem(menuInfo->Menu, PH_EMENU_FIND_DESCEND, NULL, PHAPP_ID_HACKER_PLUGINS))
+ {
+ PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, 0, pluginMenu->Id, L"Plugins... (Beta)", NULL), PhIndexOfEMenuItem(menuInfo->Menu, pluginMenu));
+ PhRemoveEMenuItem(menuInfo->Menu, pluginMenu, 0);
+ }
+}
+
+VOID NTAPI MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = Parameter;
+
+ switch (menuItem->Id)
+ {
+ case PHAPP_ID_HACKER_PLUGINS:
+ ShowPluginManagerDialog();
+ break;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { StringSettingType, SETTING_NAME_TREE_LIST_COLUMNS, L"" },
+ { StringSettingType, SETTING_NAME_LAST_CLEANUP, L"" },
+ { IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"100,100" },
+ { ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|690,540" }
+ };
+
+ PluginInstance = PhRegisterPlugin(SETTING_PREFIX, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Extra Plugins Manager";
+ info->Author = L"dmex";
+ info->Description = L"Process Hacker plugins from the community.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
+ LoadCallback,
+ NULL,
+ &PluginLoadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
+ MainMenuInitializingCallback,
+ NULL,
+ &MainMenuInitializingCallbackRegistration
+ );
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &PluginMenuItemCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/main.h b/plugins-extra/ExtraPlugins/main.h
new file mode 100644
index 0000000..7316f04
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/main.h
@@ -0,0 +1,418 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Plugin Manager
+ *
+ * Copyright (C) 2013 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 .
+ */
+
+#ifndef _WCT_H_
+#define _WCT_H_
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+#include "json-c/json.h"
+
+#define IDD_WCT_MENUITEM 1000
+#define PH_UPDATEISERRORED (WM_APP + 501)
+#define PH_UPDATEAVAILABLE (WM_APP + 502)
+#define PH_UPDATEISCURRENT (WM_APP + 503)
+#define PH_UPDATENEWER (WM_APP + 504)
+#define PH_UPDATESUCCESS (WM_APP + 505)
+#define PH_UPDATEFAILURE (WM_APP + 506)
+#define WM_SHOWDIALOG (WM_APP + 550)
+#define WM_ACTION (WM_APP + 1550)
+#define ID_WCTSHOWCONTEXTMENU 19584
+
+#define SETTING_PREFIX L"dmex.ExtraPlugins"
+#define SETTING_NAME_TREE_LIST_COLUMNS (SETTING_PREFIX L".TreeListColumns")
+#define SETTING_NAME_WINDOW_POSITION (SETTING_PREFIX L".WindowPosition")
+#define SETTING_NAME_WINDOW_SIZE (SETTING_PREFIX L".WindowSize")
+#define SETTING_NAME_LAST_CLEANUP (SETTING_PREFIX L".LastCleanupCheckTime")
+
+#define ID_SEARCH_CLEAR (WM_APP + 8001)
+#define ID_UPDATE_ADD (WM_APP + 8002)
+#define ID_UPDATE_COUNT (WM_APP + 8003)
+
+#define MAKE_VERSION_ULONGLONG(major, minor, build, revision) \
+ (((ULONGLONG)(major) << 48) | \
+ ((ULONGLONG)(minor) << 32) | \
+ ((ULONGLONG)(build) << 16) | \
+ ((ULONGLONG)(revision) << 0))
+
+#define ITEM_CHECKED (INDEXTOSTATEIMAGEMASK(2))
+#define ITEM_UNCHECKED (INDEXTOSTATEIMAGEMASK(1))
+
+extern PPH_PLUGIN PluginInstance;
+
+typedef enum _TREE_PLUGIN_STATE
+{
+ PLUGIN_STATE_LOCAL,
+ PLUGIN_STATE_RESTART,
+ PLUGIN_STATE_REMOTE,
+ PLUGIN_STATE_UPDATE,
+} TREE_PLUGIN_STATE;
+
+typedef enum _WCT_TREE_COLUMN_ITEM_NAME
+{
+ TREE_COLUMN_ITEM_NAME,
+ TREE_COLUMN_ITEM_AUTHOR,
+ TREE_COLUMN_ITEM_VERSION,
+ TREE_COLUMN_ITEM_MAXIMUM
+} WCT_TREE_COLUMN_ITEM_NAME;
+
+typedef struct _PHAPP_PLUGIN
+{
+ // Public
+ PH_AVL_LINKS Links;
+ PVOID Reserved;
+ PVOID DllBase;
+ // end
+
+ // Private
+ PPH_STRING FileName;
+ ULONG Flags;
+ PH_STRINGREF Name;
+ PH_PLUGIN_INFORMATION Information;
+
+ PH_CALLBACK Callbacks[PluginCallbackMaximum];
+} PHAPP_PLUGIN, *PPHAPP_PLUGIN;
+
+
+typedef struct _PLUGIN_NODE
+{
+ PH_TREENEW_NODE Node;
+
+ HICON Icon;
+ TREE_PLUGIN_STATE State;
+
+ BOOLEAN PluginOptions;
+ PPHAPP_PLUGIN PluginInstance;
+
+ // Local
+ PPH_STRING FilePath;
+ PPH_STRING InternalName;
+
+ // Remote
+ PPH_STRING Id;
+ PPH_STRING Visible;
+
+ PPH_STRING Name;
+ PPH_STRING Version;
+ PPH_STRING Author;
+ PPH_STRING Description;
+ PPH_STRING IconUrl;
+ PPH_STRING Requirements;
+ PPH_STRING FeedbackUrl;
+ PPH_STRING Screenshots;
+ PPH_STRING AddedTime;
+ PPH_STRING UpdatedTime;
+ PPH_STRING Download_count;
+ PPH_STRING Download_link_32;
+ PPH_STRING Download_link_64;
+ PPH_STRING SHA2_32;
+ PPH_STRING SHA2_64;
+ PPH_STRING HASH_32;
+ PPH_STRING HASH_64;
+ PPH_STRING FileName;
+
+ PH_STRINGREF TextCache[TREE_COLUMN_ITEM_MAXIMUM];
+} PLUGIN_NODE, *PPLUGIN_NODE;
+
+
+
+typedef struct _WCT_TREE_CONTEXT
+{
+ HWND ParentWindowHandle;
+ HWND TreeNewHandle;
+
+ ULONG TreeNewSortColumn;
+ PH_SORT_ORDER TreeNewSortOrder;
+
+ PPH_HASHTABLE NodeHashtable;
+ PPH_LIST NodeList;
+
+ HFONT TitleFontHandle;
+ HFONT NormalFontHandle;
+ HFONT BoldFontHandle;
+} WCT_TREE_CONTEXT, *PWCT_TREE_CONTEXT;
+
+
+// dialog.c
+VOID ShowPluginManagerDialog(VOID);
+
+// disabled.c
+VOID ShowDisabledPluginsDialog(_In_ HWND Parent);
+
+typedef struct _PLUGIN_DISABLED_CONTEXT
+{
+ PH_QUEUED_LOCK ListLock;
+ HWND DialogHandle;
+ HWND ListViewHandle;
+ PH_LAYOUT_MANAGER LayoutManager;
+} PLUGIN_DISABLED_CONTEXT, *PPLUGIN_DISABLED_CONTEXT;
+
+ULONG PhDisabledPluginsCount(VOID);
+
+// plugin.c
+PWSTR PhGetPluginBaseName(_In_ PPHAPP_PLUGIN Plugin);
+BOOLEAN PhIsPluginLoadedByBaseName(_In_ PPH_STRINGREF BaseName);
+BOOLEAN PhIsPluginDisabled(_In_ PPH_STRINGREF BaseName);
+VOID PhSetPluginDisabled(_In_ PPH_STRINGREF BaseName, _In_ BOOLEAN Disable);
+
+
+VOID WtcInitializeWindowTree(
+ _In_ HWND ParentWindowHandle,
+ _In_ HWND TreeNewHandle,
+ _Out_ PWCT_TREE_CONTEXT Context
+ );
+
+VOID WtcDeleteWindowTree(
+ _In_ PWCT_TREE_CONTEXT Context
+ );
+
+struct _PH_TN_FILTER_SUPPORT* WtcGetTreeListFilterSupport(
+ VOID
+ );
+
+VOID CloudAddChildWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ PPLUGIN_NODE Entry
+ );
+
+PPLUGIN_NODE WeAddWindowNode(
+ _Inout_ PWCT_TREE_CONTEXT Context
+ );
+
+PPLUGIN_NODE FindTreeNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ TREE_PLUGIN_STATE Type,
+ _In_ PPH_STRING InternalName
+ );
+
+VOID WeRemoveWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ PPLUGIN_NODE WindowNode
+ );
+
+VOID WeClearWindowTree(
+ _In_ PWCT_TREE_CONTEXT Context
+ );
+
+PPLUGIN_NODE WeGetSelectedWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context
+ );
+
+VOID WeGetSelectedWindowNodes(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _Out_ PPLUGIN_NODE **Windows,
+ _Out_ PULONG NumberOfWindows
+ );
+
+
+typedef struct _WCT_CONTEXT
+{
+ HWND DialogHandle;
+ HWND SearchHandle;
+ HWND TreeNewHandle;
+
+ PPH_STRING SearchboxText;
+ PPH_STRING TreeText;
+ HFONT NormalFontHandle;
+ HFONT BoldFontHandle;
+
+ TREE_PLUGIN_STATE Type;
+ HWND PluginMenuActive;
+ UINT PluginMenuActiveId;
+
+ WCT_TREE_CONTEXT TreeContext;
+ PPH_TN_FILTER_SUPPORT TreeFilter;
+
+ PH_LAYOUT_MANAGER LayoutManager;
+} WCT_CONTEXT, *PWCT_CONTEXT;
+
+NTSTATUS QueryPluginsCallbackThread(_In_ PVOID Parameter);
+
+VOID EnumerateLoadedPlugins(_In_ PWCT_CONTEXT Context);
+
+typedef enum _PLUGIN_ACTION
+{
+ PLUGIN_ACTION_RESTORE,
+ PLUGIN_ACTION_INSTALL,
+ PLUGIN_ACTION_UNINSTALL,
+ PLUGIN_ACTION_RESTART
+} PLUGIN_ACTION;
+
+typedef struct _PH_UPDATER_CONTEXT
+{
+ BOOLEAN FixedWindowStyles;
+ HWND DialogHandle;
+ HICON IconSmallHandle;
+ HICON IconLargeHandle;
+
+ PLUGIN_ACTION Action;
+ PPLUGIN_NODE Node;
+
+ PPH_STRING FileDownloadUrl;
+ PPH_STRING RevVersion;
+ PPH_STRING Size;
+ PPH_STRING SetupFilePath;
+} PH_UPDATER_CONTEXT, *PPH_UPDATER_CONTEXT;
+
+BOOLEAN ShowUpdateDialog(
+ _In_ HWND Parent,
+ _In_ PLUGIN_ACTION Action
+ );
+
+BOOLEAN StartInitialCheck(
+ _In_ HWND Parent,
+ _In_ PPLUGIN_NODE Node,
+ _In_ PLUGIN_ACTION Action
+ );
+
+VOID ShowAvailableDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID ShowCheckForUpdatesDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID ShowCheckingForUpdatesDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID TaskDialogLinkClicked(_In_ PPH_UPDATER_CONTEXT Context);
+
+NTSTATUS UpdateDownloadThread(_In_ PVOID Parameter);
+
+// page1.c
+VOID ShowCheckForUpdatesDialog(_In_ PPH_UPDATER_CONTEXT Context);
+// page2.c
+VOID ShowCheckingForUpdatesDialog(_In_ PPH_UPDATER_CONTEXT Context);
+// page3.c
+VOID ShowAvailableDialog(_In_ PPH_UPDATER_CONTEXT Context);
+// page4.c
+VOID ShowProgressDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID ShowLatestVersionDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID ShowPluginUninstallDialog(_In_ PPH_UPDATER_CONTEXT Context);
+
+VOID ShowUpdateFailedDialog(
+ _In_ PPH_UPDATER_CONTEXT Context,
+ _In_ BOOLEAN HashFailed,
+ _In_ BOOLEAN SignatureFailed
+ );
+
+// page6.c
+VOID ShowInstallRestartDialog(_In_ PPH_UPDATER_CONTEXT Context);
+VOID ShowUninstallRestartDialog(_In_ PPH_UPDATER_CONTEXT Context);
+NTSTATUS SetupExtractBuild(_In_ PVOID Parameter);
+
+// verify.c
+typedef struct _UPDATER_HASH_CONTEXT
+{
+ BCRYPT_ALG_HANDLE SignAlgHandle;
+ BCRYPT_ALG_HANDLE HashAlgHandle;
+ BCRYPT_KEY_HANDLE KeyHandle;
+ BCRYPT_HASH_HANDLE HashHandle;
+ ULONG HashObjectSize;
+ ULONG HashSize;
+ PVOID HashObject;
+ PVOID Hash;
+} UPDATER_HASH_CONTEXT, *PUPDATER_HASH_CONTEXT;
+
+BOOLEAN UpdaterInitializeHash(
+ _Out_ PUPDATER_HASH_CONTEXT *Context
+ );
+
+BOOLEAN UpdaterUpdateHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_reads_bytes_(Length) PVOID Buffer,
+ _In_ ULONG Length
+ );
+
+BOOLEAN UpdaterVerifyHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_ PPH_STRING Sha2Hash
+ );
+
+BOOLEAN UpdaterVerifySignature(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_ PPH_STRING HexSignature
+ );
+
+VOID UpdaterDestroyHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context
+ );
+
+
+
+VOID CreateSearchControl(
+ _In_ HWND Parent,
+ _In_ HWND WindowHandle,
+ _In_ UINT CommandID
+ );
+
+typedef struct _EDIT_CONTEXT
+{
+ UINT CommandID;
+
+ union
+ {
+ ULONG Flags;
+ struct
+ {
+ ULONG Hot : 1;
+ ULONG Pushed : 1;
+ ULONG Spare : 30;
+ };
+ };
+
+ LONG CXWidth;
+ INT CXBorder;
+ INT ImageWidth;
+ INT ImageHeight;
+ HWND WindowHandle;
+ HFONT WindowFont;
+ HIMAGELIST ImageList;
+ HBITMAP BitmapActive;
+ HBITMAP BitmapInactive;
+ HBRUSH BrushNormal;
+ HBRUSH BrushPushed;
+ HBRUSH BrushHot;
+
+} EDIT_CONTEXT, *PEDIT_CONTEXT;
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PCWSTR Name,
+ _In_ BOOLEAN RGBAImage
+ );
+
+LRESULT SysButtonCustomDraw(
+ _In_ PWCT_CONTEXT Context,
+ _In_ LPARAM lParam
+ );
+
+
+#endif
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/miniz/miniz.c b/plugins-extra/ExtraPlugins/miniz/miniz.c
new file mode 100644
index 0000000..95830af
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/miniz/miniz.c
@@ -0,0 +1,4190 @@
+/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
+ See "unlicense" statement at the end of this file.
+ Rich Geldreich , last updated Oct. 13, 2013
+ Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
+
+ Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
+ MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
+
+ * Change History
+ 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
+ - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
+ would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
+ (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
+ - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
+ - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
+ Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
+ - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
+ - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
+ - Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
+ - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
+ - Merged MZ_FORCEINLINE fix from hdeanclark
+ - Fix include before config #ifdef, thanks emil.brink
+ - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
+ set it to 1 for real-time compression).
+ - Merged in some compiler fixes from paulharris's github repro.
+ - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
+ - Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
+ - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
+ - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
+ - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
+ 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include (thanks fermtect).
+ 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
+ - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
+ - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
+ - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
+ "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
+ - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
+ - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
+ - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
+ - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
+ - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
+ 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
+ level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report.
+ 5/28/11 v1.11 - Added statement from unlicense.org
+ 5/27/11 v1.10 - Substantial compressor optimizations:
+ - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
+ - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
+ - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
+ - Refactored the compression code for better readability and maintainability.
+ - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
+ drop in throughput on some files).
+ 5/15/11 v1.09 - Initial stable release.
+
+ * Low-level Deflate/Inflate implementation notes:
+
+ Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
+ greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
+ approximately as well as zlib.
+
+ Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
+ coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
+ block large enough to hold the entire file.
+
+ The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
+
+ * zlib-style API notes:
+
+ miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
+ zlib replacement in many apps:
+ The z_stream struct, optional memory allocation callbacks
+ deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
+ inflateInit/inflateInit2/inflate/inflateEnd
+ compress, compress2, compressBound, uncompress
+ CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
+ Supports raw deflate streams or standard zlib streams with adler-32 checking.
+
+ Limitations:
+ The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
+ I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
+ there are no guarantees that miniz.c pulls this off perfectly.
+
+ * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
+ Alex Evans. Supports 1-4 bytes/pixel images.
+
+ * ZIP archive API notes:
+
+ The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
+ get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
+ existing archives, create new archives, append new files to existing archives, or clone archive data from
+ one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
+ or you can specify custom file read/write callbacks.
+
+ - Archive reading: Just call this function to read a single file from a disk archive:
+
+ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
+ size_t *pSize, mz_uint zip_flags);
+
+ For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
+ directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
+
+ - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
+
+ int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
+
+ The locate operation can optionally check file comments too, which (as one example) can be used to identify
+ multiple versions of the same file in an archive. This function uses a simple linear search through the central
+ directory, so it's not very fast.
+
+ Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
+ retrieve detailed info on each file by calling mz_zip_reader_file_stat().
+
+ - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
+ to disk and builds an exact image of the central directory in memory. The central directory image is written
+ all at once at the end of the archive file when the archive is finalized.
+
+ The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
+ which can be useful when the archive will be read from optical media. Also, the writer supports placing
+ arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
+ readable by any ZIP tool.
+
+ - Archive appending: The simple way to add a single file to an archive is to call this function:
+
+ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
+ const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+
+ The archive will be created if it doesn't already exist, otherwise it'll be appended to.
+ Note the appending is done in-place and is not an atomic operation, so if something goes wrong
+ during the operation it's possible the archive could be left without a central directory (although the local
+ file headers and file data will be fine, so the archive will be recoverable).
+
+ For more complex archive modification scenarios:
+ 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
+ preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
+ compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
+ you're done. This is safe but requires a bunch of temporary disk space or heap memory.
+
+ 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
+ append new files as needed, then finalize the archive which will write an updated central directory to the
+ original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
+ possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
+
+ - ZIP archive support limitations:
+ No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
+ Requires streams capable of seeking.
+
+ * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
+ below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
+
+ * Important: For best perf. be sure to customize the below macros for your target platform:
+ #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+ #define MINIZ_LITTLE_ENDIAN 1
+ #define MINIZ_HAS_64BIT_REGISTERS 1
+
+ * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
+ uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
+ (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
+*/
+
+#include "miniz.h"
+#include
+#include
+
+typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
+typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
+typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
+
+#define MZ_ASSERT(x) assert(x)
+
+#ifdef MINIZ_NO_MALLOC
+#define MZ_MALLOC(x) NULL
+#define MZ_FREE(x) (void)x, ((void)0)
+#define MZ_REALLOC(p, x) NULL
+#else
+#define MZ_MALLOC(x) malloc(x)
+#define MZ_FREE(x) free(x)
+#define MZ_REALLOC(p, x) realloc(p, x)
+#endif
+
+#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
+#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
+#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
+#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
+#else
+#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
+#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
+#endif
+
+#ifdef _MSC_VER
+#define MZ_FORCEINLINE __forceinline
+#elif defined(__GNUC__)
+#define MZ_FORCEINLINE inline __attribute__((__always_inline__))
+#else
+#define MZ_FORCEINLINE inline
+#endif
+
+
+// ------------------- zlib-style API's
+
+mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
+{
+ mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
+ if (!ptr) return MZ_ADLER32_INIT;
+ while (buf_len) {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
+ s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
+ }
+ return (s2 << 16) + s1;
+}
+
+// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/
+mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len)
+{
+ static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
+ mz_uint32 crcu32 = (mz_uint32)crc;
+ if (!ptr) return MZ_CRC32_INIT;
+ crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
+ return ~crcu32;
+}
+
+void mz_free(void *p)
+{
+ MZ_FREE(p);
+}
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
+static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
+static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); }
+
+const char *mz_version(void)
+{
+ return MZ_VERSION;
+}
+
+int mz_deflateInit(mz_streamp pStream, int level)
+{
+ return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
+}
+
+int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
+{
+ tdefl_compressor *pComp;
+ mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
+
+ if (!pStream) return MZ_STREAM_ERROR;
+ if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = MZ_ADLER32_INIT;
+ pStream->msg = NULL;
+ pStream->reserved = 0;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
+ if (!pStream->zfree) pStream->zfree = def_free_func;
+
+ pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
+ if (!pComp)
+ return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pComp;
+
+ if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
+ {
+ mz_deflateEnd(pStream);
+ return MZ_PARAM_ERROR;
+ }
+
+ return MZ_OK;
+}
+
+int mz_deflateReset(mz_streamp pStream)
+{
+ if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
+ pStream->total_in = pStream->total_out = 0;
+ tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
+ return MZ_OK;
+}
+
+int mz_deflate(mz_streamp pStream, int flush)
+{
+ size_t in_bytes, out_bytes;
+ mz_ulong orig_total_in, orig_total_out;
+ int mz_status = MZ_OK;
+
+ if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
+ if (!pStream->avail_out) return MZ_BUF_ERROR;
+
+ if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
+
+ if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
+ return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
+
+ orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
+ for (; ; )
+ {
+ tdefl_status defl_status;
+ in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
+
+ defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
+ pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
+
+ pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
+ pStream->total_out += (mz_uint)out_bytes;
+
+ if (defl_status < 0)
+ {
+ mz_status = MZ_STREAM_ERROR;
+ break;
+ }
+ else if (defl_status == TDEFL_STATUS_DONE)
+ {
+ mz_status = MZ_STREAM_END;
+ break;
+ }
+ else if (!pStream->avail_out)
+ break;
+ else if ((!pStream->avail_in) && (flush != MZ_FINISH))
+ {
+ if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
+ break;
+ return MZ_BUF_ERROR; // Can't make forward progress without some input.
+ }
+ }
+ return mz_status;
+}
+
+int mz_deflateEnd(mz_streamp pStream)
+{
+ if (!pStream) return MZ_STREAM_ERROR;
+ if (pStream->state)
+ {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
+{
+ (void)pStream;
+ // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.)
+ return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
+}
+
+int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
+{
+ int status;
+ mz_stream stream;
+ memset(&stream, 0, sizeof(stream));
+
+ // In case mz_ulong is 64-bits (argh I hate longs).
+ if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)source_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_deflateInit(&stream, level);
+ if (status != MZ_OK) return status;
+
+ status = mz_deflate(&stream, MZ_FINISH);
+ if (status != MZ_STREAM_END)
+ {
+ mz_deflateEnd(&stream);
+ return (status == MZ_OK) ? MZ_BUF_ERROR : status;
+ }
+
+ *pDest_len = stream.total_out;
+ return mz_deflateEnd(&stream);
+}
+
+int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
+{
+ return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
+}
+
+mz_ulong mz_compressBound(mz_ulong source_len)
+{
+ return mz_deflateBound(NULL, source_len);
+}
+
+typedef struct
+{
+ tinfl_decompressor m_decomp;
+ mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
+ mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
+ tinfl_status m_last_status;
+} inflate_state;
+
+int mz_inflateInit2(mz_streamp pStream, int window_bits)
+{
+ inflate_state *pDecomp;
+ if (!pStream) return MZ_STREAM_ERROR;
+ if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = 0;
+ pStream->msg = NULL;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ pStream->reserved = 0;
+ if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
+ if (!pStream->zfree) pStream->zfree = def_free_func;
+
+ pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
+ if (!pDecomp) return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pDecomp;
+
+ tinfl_init(&pDecomp->m_decomp);
+ pDecomp->m_dict_ofs = 0;
+ pDecomp->m_dict_avail = 0;
+ pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
+ pDecomp->m_first_call = 1;
+ pDecomp->m_has_flushed = 0;
+ pDecomp->m_window_bits = window_bits;
+
+ return MZ_OK;
+}
+
+int mz_inflateInit(mz_streamp pStream)
+{
+ return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
+}
+
+int mz_inflate(mz_streamp pStream, int flush)
+{
+ inflate_state* pState;
+ mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
+ size_t in_bytes, out_bytes, orig_avail_in;
+ tinfl_status status;
+
+ if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
+ if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
+ if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
+
+ pState = (inflate_state*)pStream->state;
+ if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
+ orig_avail_in = pStream->avail_in;
+
+ first_call = pState->m_first_call; pState->m_first_call = 0;
+ if (pState->m_last_status < 0) return MZ_DATA_ERROR;
+
+ if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
+ pState->m_has_flushed |= (flush == MZ_FINISH);
+
+ if ((flush == MZ_FINISH) && (first_call))
+ {
+ // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
+ decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
+ in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+ pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+ pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
+
+ if (status < 0)
+ return MZ_DATA_ERROR;
+ else if (status != TINFL_STATUS_DONE)
+ {
+ pState->m_last_status = TINFL_STATUS_FAILED;
+ return MZ_BUF_ERROR;
+ }
+ return MZ_STREAM_END;
+ }
+ // flush != MZ_FINISH then we must assume there's more input.
+ if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
+
+ if (pState->m_dict_avail)
+ {
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
+ pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+ return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+ }
+
+ for (; ; )
+ {
+ in_bytes = pStream->avail_in;
+ out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
+
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+
+ pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+
+ pState->m_dict_avail = (mz_uint)out_bytes;
+
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
+ pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+
+ if (status < 0)
+ return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
+ else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
+ return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
+ else if (flush == MZ_FINISH)
+ {
+ // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
+ if (status == TINFL_STATUS_DONE)
+ return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
+ // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong.
+ else if (!pStream->avail_out)
+ return MZ_BUF_ERROR;
+ }
+ else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
+ break;
+ }
+
+ return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+}
+
+int mz_inflateEnd(mz_streamp pStream)
+{
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if (pStream->state)
+ {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
+{
+ mz_stream stream;
+ int status;
+ memset(&stream, 0, sizeof(stream));
+
+ // In case mz_ulong is 64-bits (argh I hate longs).
+ if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)source_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_inflateInit(&stream);
+ if (status != MZ_OK)
+ return status;
+
+ status = mz_inflate(&stream, MZ_FINISH);
+ if (status != MZ_STREAM_END)
+ {
+ mz_inflateEnd(&stream);
+ return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
+ }
+ *pDest_len = stream.total_out;
+
+ return mz_inflateEnd(&stream);
+}
+
+const char *mz_error(int err)
+{
+ static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
+ {
+ { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
+ { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
+ };
+ mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc;
+ return NULL;
+}
+
+#endif //MINIZ_NO_ZLIB_APIS
+
+// ------------------- Low-level Decompression (completely independent from all compression API's)
+
+#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
+#define TINFL_MEMSET(p, c, l) memset(p, c, l)
+
+#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
+#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
+#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
+#define TINFL_CR_FINISH }
+
+// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
+// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
+#define TINFL_GET_BYTE(state_index, c) do { \
+ if (pIn_buf_cur >= pIn_buf_end) { \
+ for ( ; ; ) { \
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
+ TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
+ if (pIn_buf_cur < pIn_buf_end) { \
+ c = *pIn_buf_cur++; \
+ break; \
+ } \
+ } else { \
+ c = 0; \
+ break; \
+ } \
+ } \
+ } else c = *pIn_buf_cur++; } MZ_MACRO_END
+
+#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
+#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
+#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
+
+// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
+// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
+// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
+// bit buffer contains >=15 bits (deflate's max. Huffman code size).
+#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
+ do { \
+ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
+ if (temp >= 0) { \
+ code_len = temp >> 9; \
+ if ((code_len) && (num_bits >= code_len)) \
+ break; \
+ } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
+ } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
+ } while (num_bits < 15);
+
+// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
+// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
+// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
+// The slow path is only executed at the very end of the input buffer.
+#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
+ int temp; mz_uint code_len, c; \
+ if (num_bits < 15) { \
+ if ((pIn_buf_end - pIn_buf_cur) < 2) { \
+ TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
+ } else { \
+ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
+ } \
+ } \
+ if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
+ code_len = temp >> 9, temp &= 511; \
+ else { \
+ code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
+ } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
+
+tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
+{
+ static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
+ static const int s_length_extra[31] = { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
+ static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 };
+ static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
+ static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
+ static const int s_min_table_sizes[3] = { 257, 1, 4 };
+
+ tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
+ const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
+ mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
+ size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
+
+ // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
+ if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
+
+ num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
+ TINFL_CR_BEGIN
+
+ bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
+ counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
+ if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
+ if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
+ }
+
+ do
+ {
+ TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
+ if (r->m_type == 0)
+ {
+ TINFL_SKIP_BITS(5, num_bits & 7);
+ for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
+ if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
+ while ((counter) && (num_bits))
+ {
+ TINFL_GET_BITS(51, dist, 8);
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = (mz_uint8)dist;
+ counter--;
+ }
+ while (counter)
+ {
+ size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ while (pIn_buf_cur >= pIn_buf_end)
+ {
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
+ {
+ TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
+ }
+ else
+ {
+ TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
+ }
+ }
+ n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
+ TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
+ }
+ }
+ else if (r->m_type == 3)
+ {
+ TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
+ }
+ else
+ {
+ if (r->m_type == 1)
+ {
+ mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
+ r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
+ for (i = 0; i <= 143; ++i) *p++ = 8; for (; i <= 255; ++i) *p++ = 9; for (; i <= 279; ++i) *p++ = 7; for (; i <= 287; ++i) *p++ = 8;
+ }
+ else
+ {
+ for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
+ MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
+ r->m_table_sizes[2] = 19;
+ }
+ for (; (int)r->m_type >= 0; r->m_type--)
+ {
+ int tree_next, tree_cur; tinfl_huff_table *pTable;
+ mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
+ for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
+ used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
+ for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
+ if ((65536 != total) && (used_syms > 1))
+ {
+ TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
+ }
+ for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
+ {
+ mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
+ cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
+ if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
+ if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
+ rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
+ for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
+ {
+ tree_cur -= ((rev_code >>= 1) & 1);
+ if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
+ else tree_cur = pTable->m_tree[-tree_cur - 1];
+ }
+ tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
+ }
+ if (r->m_type == 2)
+ {
+ for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
+ {
+ mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
+ if ((dist == 16) && (!counter))
+ {
+ TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
+ }
+ num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
+ TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
+ }
+ if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
+ {
+ TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
+ }
+ TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
+ }
+ }
+ for (; ; )
+ {
+ mz_uint8 *pSrc;
+ for (; ; )
+ {
+ if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
+ {
+ TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
+ if (counter >= 256)
+ break;
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = (mz_uint8)counter;
+ }
+ else
+ {
+ int sym2; mz_uint code_len;
+#if TINFL_USE_64BIT_BITBUF
+ if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
+#else
+ if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
+ }
+ counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
+ if (counter & 256)
+ break;
+
+#if !TINFL_USE_64BIT_BITBUF
+ if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
+ }
+ bit_buf >>= code_len; num_bits -= code_len;
+
+ pOut_buf_cur[0] = (mz_uint8)counter;
+ if (sym2 & 256)
+ {
+ pOut_buf_cur++;
+ counter = sym2;
+ break;
+ }
+ pOut_buf_cur[1] = (mz_uint8)sym2;
+ pOut_buf_cur += 2;
+ }
+ }
+ if ((counter &= 511) == 256) break;
+
+ num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
+ if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
+
+ TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
+ num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
+ if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
+
+ dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
+ if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
+ {
+ TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
+ }
+
+ pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
+
+ if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
+ {
+ while (counter--)
+ {
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
+ }
+ continue;
+ }
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+ else if ((counter >= 9) && (counter <= dist))
+ {
+ const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
+ do
+ {
+ ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
+ ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
+ pOut_buf_cur += 8;
+ } while ((pSrc += 8) < pSrc_end);
+ if ((counter &= 7) < 3)
+ {
+ if (counter)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if (counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ continue;
+ }
+ }
+#endif
+ do
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur[2] = pSrc[2];
+ pOut_buf_cur += 3; pSrc += 3;
+ } while ((int)(counter -= 3) > 2);
+ if ((int)counter > 0)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if ((int)counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ }
+ }
+ } while (!(r->m_final & 1));
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
+ }
+ TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
+ TINFL_CR_FINISH
+
+ common_exit :
+ r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
+ *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
+ if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
+ {
+ const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
+ mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
+ while (buf_len)
+ {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
+ {
+ s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
+ }
+ r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
+ }
+ return status;
+}
+
+// Higher level helper functions.
+void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
+{
+ tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
+ *pOut_len = 0;
+ tinfl_init(&decomp);
+ for (; ; )
+ {
+ size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
+ tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size,
+ (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
+ {
+ MZ_FREE(pBuf); *pOut_len = 0; return NULL;
+ }
+ src_buf_ofs += src_buf_size;
+ *pOut_len += dst_buf_size;
+ if (status == TINFL_STATUS_DONE) break;
+ new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
+ pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
+ if (!pNew_buf)
+ {
+ MZ_FREE(pBuf); *pOut_len = 0; return NULL;
+ }
+ pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
+ }
+ return pBuf;
+}
+
+size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
+{
+ tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
+ status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
+}
+
+int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ int result = 0;
+ tinfl_decompressor decomp;
+ mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
+ if (!pDict)
+ return TINFL_STATUS_FAILED;
+ tinfl_init(&decomp);
+ for (; ; )
+ {
+ size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
+ tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
+ (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
+ in_buf_ofs += in_buf_size;
+ if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
+ break;
+ if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
+ {
+ result = (status == TINFL_STATUS_DONE);
+ break;
+ }
+ dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
+ }
+ MZ_FREE(pDict);
+ *pIn_buf_size = in_buf_ofs;
+ return result;
+}
+
+// ------------------- Low-level Compression (independent from all decompression API's)
+
+// Purposely making these tables static for faster init and thread safety.
+static const mz_uint16 s_tdefl_len_sym[256] = {
+ 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272,
+ 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276,
+ 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
+ 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
+ 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
+ 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,
+ 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,
+ 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 };
+
+static const mz_uint8 s_tdefl_len_extra[256] = {
+ 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 };
+
+static const mz_uint8 s_tdefl_small_dist_sym[512] = {
+ 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
+ 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
+ 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
+ 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+ 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+ 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+ 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+ 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 };
+
+static const mz_uint8 s_tdefl_small_dist_extra[512] = {
+ 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7 };
+
+static const mz_uint8 s_tdefl_large_dist_sym[128] = {
+ 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,
+ 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
+ 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 };
+
+static const mz_uint8 s_tdefl_large_dist_extra[128] = {
+ 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+ 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 };
+
+// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
+typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
+static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
+{
+ mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist);
+ for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
+ while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
+ for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
+ {
+ const mz_uint32* pHist = &hist[pass << 8];
+ mz_uint offsets[256], cur_ofs = 0;
+ for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
+ for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
+ { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
+ }
+ return pCur_syms;
+}
+
+// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
+static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
+{
+ int root, leaf, next, avbl, used, dpth;
+ if (n == 0) return; else if (n == 1) { A[0].m_key = 1; return; }
+ A[0].m_key += A[1].m_key; root = 0; leaf = 2;
+ for (next = 1; next < n - 1; next++)
+ {
+ if (leaf >= n || A[root].m_key < A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; }
+ else A[next].m_key = A[leaf++].m_key;
+ if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; }
+ else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
+ }
+ A[n - 2].m_key = 0; for (next = n - 3; next >= 0; next--) A[next].m_key = A[A[next].m_key].m_key + 1;
+ avbl = 1; used = dpth = 0; root = n - 2; next = n - 1;
+ while (avbl > 0)
+ {
+ while (root >= 0 && (int)A[root].m_key == dpth) { used++; root--; }
+ while (avbl > used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
+ avbl = 2 * used; dpth++; used = 0;
+ }
+}
+
+// Limits canonical Huffman code table's max code size.
+enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
+static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
+{
+ int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
+ for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
+ for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
+ while (total != (1UL << max_code_size))
+ {
+ pNum_codes[max_code_size]--;
+ for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
+ total--;
+ }
+}
+
+static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
+{
+ int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes);
+ if (static_table)
+ {
+ for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
+ }
+ else
+ {
+ tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
+ int num_used_syms = 0;
+ const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
+ for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; }
+
+ pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
+
+ for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
+
+ tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
+
+ MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
+ for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
+ for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
+ }
+
+ next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
+
+ for (i = 0; i < table_len; i++)
+ {
+ mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
+ code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
+ d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
+ }
+}
+
+#define TDEFL_PUT_BITS(b, l) do { \
+ mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
+ d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
+ while (d->m_bits_in >= 8) { \
+ if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
+ *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
+ d->m_bit_buffer >>= 8; \
+ d->m_bits_in -= 8; \
+ } \
+} MZ_MACRO_END
+
+#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
+ if (rle_repeat_count < 3) { \
+ d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
+ while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
+ } else { \
+ d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
+} rle_repeat_count = 0; } }
+
+#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
+ if (rle_z_count < 3) { \
+ d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
+ } else if (rle_z_count <= 10) { \
+ d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
+ } else { \
+ d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
+} rle_z_count = 0; } }
+
+static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
+static void tdefl_start_dynamic_block(tdefl_compressor *d)
+{
+ int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
+ mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
+
+ d->m_huff_count[0][256] = 1;
+
+ tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
+ tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
+
+ for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
+ for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
+
+ memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
+ memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
+ total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
+
+ memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
+ for (i = 0; i < total_code_sizes_to_pack; i++)
+ {
+ mz_uint8 code_size = code_sizes_to_pack[i];
+ if (!code_size)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
+ }
+ else
+ {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ if (code_size != prev_code_size)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size;
+ }
+ else if (++rle_repeat_count == 6)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ }
+ }
+ prev_code_size = code_size;
+ }
+ if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); }
+ else { TDEFL_RLE_ZERO_CODE_SIZE(); }
+
+ tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
+
+ TDEFL_PUT_BITS(2, 2);
+
+ TDEFL_PUT_BITS(num_lit_codes - 257, 5);
+ TDEFL_PUT_BITS(num_dist_codes - 1, 5);
+
+ for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break;
+ num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
+ for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
+
+ for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
+ {
+ mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
+ TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
+ if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
+ }
+}
+
+static void tdefl_start_static_block(tdefl_compressor *d)
+{
+ mz_uint i;
+ mz_uint8 *p = &d->m_huff_code_sizes[0][0];
+
+ for (i = 0; i <= 143; ++i) *p++ = 8;
+ for (; i <= 255; ++i) *p++ = 9;
+ for (; i <= 279; ++i) *p++ = 7;
+ for (; i <= 287; ++i) *p++ = 8;
+
+ memset(d->m_huff_code_sizes[1], 5, 32);
+
+ tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
+ tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
+
+ TDEFL_PUT_BITS(1, 2);
+}
+
+static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
+{
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+ mz_uint8 *pOutput_buf = d->m_pOutput_buf;
+ mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
+ mz_uint64 bit_buffer = d->m_bit_buffer;
+ mz_uint bits_in = d->m_bits_in;
+
+#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
+ {
+ if (flags == 1)
+ flags = *pLZ_codes++ | 0x100;
+
+ if (flags & 1)
+ {
+ mz_uint s0, s1, n0, n1, sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
+
+ // This sequence coaxes MSVC into using cmov's vs. jmp's.
+ s0 = s_tdefl_small_dist_sym[match_dist & 511];
+ n0 = s_tdefl_small_dist_extra[match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[match_dist >> 8];
+ n1 = s_tdefl_large_dist_extra[match_dist >> 8];
+ sym = (match_dist < 512) ? s0 : s1;
+ num_extra_bits = (match_dist < 512) ? n0 : n1;
+
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
+ }
+ else
+ {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
+ {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
+ {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+ }
+ }
+ }
+
+ if (pOutput_buf >= d->m_pOutput_buf_end)
+ return MZ_FALSE;
+
+ *(mz_uint64*)pOutput_buf = bit_buffer;
+ pOutput_buf += (bits_in >> 3);
+ bit_buffer >>= (bits_in & ~7);
+ bits_in &= 7;
+ }
+
+#undef TDEFL_PUT_BITS_FAST
+
+ d->m_pOutput_buf = pOutput_buf;
+ d->m_bits_in = 0;
+ d->m_bit_buffer = 0;
+
+ while (bits_in)
+ {
+ mz_uint32 n = MZ_MIN(bits_in, 16);
+ TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
+ bit_buffer >>= n;
+ bits_in -= n;
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#else
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
+{
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
+ {
+ if (flags == 1)
+ flags = *pLZ_codes++ | 0x100;
+ if (flags & 1)
+ {
+ mz_uint sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
+
+ if (match_dist < 512)
+ {
+ sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
+ }
+ else
+ {
+ sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
+ }
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
+ }
+ else
+ {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+ }
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
+
+static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
+{
+ if (static_block)
+ tdefl_start_static_block(d);
+ else
+ tdefl_start_dynamic_block(d);
+ return tdefl_compress_lz_codes(d);
+}
+
+static int tdefl_flush_block(tdefl_compressor *d, int flush)
+{
+ mz_uint saved_bit_buf, saved_bits_in;
+ mz_uint8 *pSaved_output_buf;
+ mz_bool comp_block_succeeded = MZ_FALSE;
+ int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
+ mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
+
+ d->m_pOutput_buf = pOutput_buf_start;
+ d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
+
+ MZ_ASSERT(!d->m_output_flush_remaining);
+ d->m_output_flush_ofs = 0;
+ d->m_output_flush_remaining = 0;
+
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
+ d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
+
+ if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
+ {
+ TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
+ }
+
+ TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
+
+ pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
+
+ if (!use_raw_block)
+ comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
+
+ // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
+ if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
+ ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size))
+ {
+ mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ TDEFL_PUT_BITS(0, 2);
+ if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
+ for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
+ {
+ TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
+ }
+ for (i = 0; i < d->m_total_lz_bytes; ++i)
+ {
+ TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
+ }
+ }
+ // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
+ else if (!comp_block_succeeded)
+ {
+ d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ tdefl_compress_block(d, MZ_TRUE);
+ }
+
+ if (flush)
+ {
+ if (flush == TDEFL_FINISH)
+ {
+ if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
+ if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } }
+ }
+ else
+ {
+ mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); }
+ }
+ }
+
+ MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
+
+ memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++;
+
+ if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
+ {
+ if (d->m_pPut_buf_func)
+ {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
+ return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
+ }
+ else if (pOutput_buf_start == d->m_output_buf)
+ {
+ int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
+ d->m_out_buf_ofs += bytes_to_copy;
+ if ((n -= bytes_to_copy) != 0)
+ {
+ d->m_output_flush_ofs = bytes_to_copy;
+ d->m_output_flush_remaining = n;
+ }
+ }
+ else
+ {
+ d->m_out_buf_ofs += n;
+ }
+ }
+
+ return d->m_output_flush_remaining;
+}
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
+static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
+{
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
+ mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
+ for (; ; )
+ {
+ for (; ; )
+ {
+ if (--num_probes_left == 0) return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
+ TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
+ }
+ if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32;
+ do {} while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
+ if (!probe_len)
+ {
+ *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
+ }
+ else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
+ {
+ *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
+ c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
+ }
+ }
+}
+#else
+static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
+{
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint8 *s = d->m_dict + pos, *p, *q;
+ mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
+ for (; ; )
+ {
+ for (; ; )
+ {
+ if (--num_probes_left == 0) return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
+ TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
+ }
+ if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break;
+ if (probe_len > match_len)
+ {
+ *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
+ c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
+ }
+ }
+}
+#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+static mz_bool tdefl_compress_fast(tdefl_compressor *d)
+{
+ // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
+ mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
+ mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
+ mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+
+ while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
+ {
+ const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
+ mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
+ d->m_src_buf_left -= num_bytes_to_process;
+ lookahead_size += num_bytes_to_process;
+
+ while (num_bytes_to_process)
+ {
+ mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
+ memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
+ d->m_pSrc += n;
+ dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
+ num_bytes_to_process -= n;
+ }
+
+ dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
+ if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
+
+ while (lookahead_size >= 4)
+ {
+ mz_uint cur_match_dist, cur_match_len = 1;
+ mz_uint8 *pCur_dict = d->m_dict + cur_pos;
+ mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
+ mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
+ mz_uint probe_pos = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)lookahead_pos;
+
+ if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
+ {
+ const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
+ const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
+ mz_uint32 probe_len = 32;
+ do {} while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
+ cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
+ if (!probe_len)
+ cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
+
+ if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
+ {
+ cur_match_len = 1;
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ }
+ else
+ {
+ mz_uint32 s0, s1;
+ cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
+
+ MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ cur_match_dist--;
+
+ pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
+ *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
+ pLZ_code_buf += 3;
+ *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
+
+ s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
+ d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
+
+ d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
+ }
+ }
+ else
+ {
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ }
+
+ if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
+
+ total_lz_bytes += cur_match_len;
+ lookahead_pos += cur_match_len;
+ dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
+ MZ_ASSERT(lookahead_size >= cur_match_len);
+ lookahead_size -= cur_match_len;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
+ {
+ int n;
+ d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
+ }
+ }
+
+ while (lookahead_size)
+ {
+ mz_uint8 lit = d->m_dict[cur_pos];
+
+ total_lz_bytes++;
+ *pLZ_code_buf++ = lit;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
+
+ d->m_huff_count[0][lit]++;
+
+ lookahead_pos++;
+ dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
+ lookahead_size--;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
+ {
+ int n;
+ d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
+ }
+ }
+ }
+
+ d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
+ return MZ_TRUE;
+}
+#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+
+static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
+{
+ d->m_total_lz_bytes++;
+ *d->m_pLZ_code_buf++ = lit;
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
+ d->m_huff_count[0][lit]++;
+}
+
+static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
+{
+ mz_uint32 s0, s1;
+
+ MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ d->m_total_lz_bytes += match_len;
+
+ d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
+
+ match_dist -= 1;
+ d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
+ d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3;
+
+ *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
+
+ s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
+ d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
+
+ if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
+}
+
+static mz_bool tdefl_compress_normal(tdefl_compressor *d)
+{
+ const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left;
+ tdefl_flush flush = d->m_flush;
+
+ while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
+ {
+ mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
+ // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
+ if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
+ {
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
+ mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
+ const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
+ src_buf_left -= num_bytes_to_process;
+ d->m_lookahead_size += num_bytes_to_process;
+ while (pSrc != pSrc_end)
+ {
+ mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
+ dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++;
+ }
+ }
+ else
+ {
+ while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
+ {
+ mz_uint8 c = *pSrc++;
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
+ src_buf_left--;
+ d->m_dict[dst_pos] = c;
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
+ {
+ mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
+ mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
+ }
+ }
+ }
+ d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
+ if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
+ break;
+
+ // Simple lazy/greedy parsing state machine.
+ len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+ if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
+ {
+ if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
+ {
+ mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; }
+ if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1;
+ }
+ }
+ else
+ {
+ tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
+ }
+ if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
+ {
+ cur_match_dist = cur_match_len = 0;
+ }
+ if (d->m_saved_match_len)
+ {
+ if (cur_match_len > d->m_saved_match_len)
+ {
+ tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
+ if (cur_match_len >= 128)
+ {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ d->m_saved_match_len = 0; len_to_move = cur_match_len;
+ }
+ else
+ {
+ d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
+ }
+ }
+ else
+ {
+ tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
+ len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0;
+ }
+ }
+ else if (!cur_match_dist)
+ tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
+ else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
+ {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ len_to_move = cur_match_len;
+ }
+ else
+ {
+ d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
+ }
+ // Move the lookahead forward by len_to_move bytes.
+ d->m_lookahead_pos += len_to_move;
+ MZ_ASSERT(d->m_lookahead_size >= len_to_move);
+ d->m_lookahead_size -= len_to_move;
+ d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
+ // Check if it's time to flush the current LZ codes to the internal output buffer.
+ if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
+ ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))))
+ {
+ int n;
+ d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ }
+ }
+
+ d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
+ return MZ_TRUE;
+}
+
+static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
+{
+ if (d->m_pIn_buf_size)
+ {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ }
+
+ if (d->m_pOut_buf_size)
+ {
+ size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
+ d->m_output_flush_ofs += (mz_uint)n;
+ d->m_output_flush_remaining -= (mz_uint)n;
+ d->m_out_buf_ofs += n;
+
+ *d->m_pOut_buf_size = d->m_out_buf_ofs;
+ }
+
+ return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
+{
+ if (!d)
+ {
+ if (pIn_buf_size) *pIn_buf_size = 0;
+ if (pOut_buf_size) *pOut_buf_size = 0;
+ return TDEFL_STATUS_BAD_PARAM;
+ }
+
+ d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size;
+ d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size;
+ d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
+ d->m_out_buf_ofs = 0;
+ d->m_flush = flush;
+
+ if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
+ (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
+ {
+ if (pIn_buf_size) *pIn_buf_size = 0;
+ if (pOut_buf_size) *pOut_buf_size = 0;
+ return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
+ }
+ d->m_wants_to_finish |= (flush == TDEFL_FINISH);
+
+ if ((d->m_output_flush_remaining) || (d->m_finished))
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
+ ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
+ ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
+ {
+ if (!tdefl_compress_fast(d))
+ return d->m_prev_return_status;
+ }
+ else
+#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ {
+ if (!tdefl_compress_normal(d))
+ return d->m_prev_return_status;
+ }
+
+ if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
+ d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
+
+ if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
+ {
+ if (tdefl_flush_block(d, flush) < 0)
+ return d->m_prev_return_status;
+ d->m_finished = (flush == TDEFL_FINISH);
+ if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; }
+ }
+
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+}
+
+tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
+{
+ MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
+}
+
+tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user;
+ d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
+ d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
+ if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash);
+ d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
+ d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8;
+ d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY;
+ d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1;
+ d->m_pIn_buf = NULL; d->m_pOut_buf = NULL;
+ d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL;
+ d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0;
+ memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+ return TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
+{
+ return d->m_prev_return_status;
+}
+
+mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
+{
+ return d->m_adler32;
+}
+
+mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
+ pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE;
+ succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
+ succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
+ MZ_FREE(pComp); return succeeded;
+}
+
+typedef struct
+{
+ size_t m_size, m_capacity;
+ mz_uint8 *m_pBuf;
+ mz_bool m_expandable;
+} tdefl_output_buffer;
+
+static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
+{
+ tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
+ size_t new_size = p->m_size + len;
+ if (new_size > p->m_capacity)
+ {
+ size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE;
+ do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity);
+ pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE;
+ p->m_pBuf = pNew_buf; p->m_capacity = new_capacity;
+ }
+ memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size;
+ return MZ_TRUE;
+}
+
+void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
+{
+ tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_len) return MZ_FALSE; else *pOut_len = 0;
+ out_buf.m_expandable = MZ_TRUE;
+ if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL;
+ *pOut_len = out_buf.m_size; return out_buf.m_pBuf;
+}
+
+size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
+{
+ tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_buf) return 0;
+ out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len;
+ if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0;
+ return out_buf.m_size;
+}
+
+#ifndef MINIZ_NO_ZLIB_APIS
+static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
+
+// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
+mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
+{
+ mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
+ if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
+
+ if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
+ else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES;
+ else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK;
+ else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
+ else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES;
+
+ return comp_flags;
+}
+#endif //MINIZ_NO_ZLIB_APIS
+
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
+#endif
+
+// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
+// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
+// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck.
+void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
+{
+ // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined.
+ static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
+ tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0;
+ if (!pComp) return NULL;
+ MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; }
+ // write dummy header
+ for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
+ // compress image data
+ tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
+ for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); }
+ if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
+ // write real header
+ *pLen_out = out_buf.m_size - 41;
+ {
+ static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
+ mz_uint8 pnghdr[41] = { 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
+ 0,0,(mz_uint8)(w >> 8),(mz_uint8)w,0,0,(mz_uint8)(h >> 8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0,
+ (mz_uint8)(*pLen_out >> 24),(mz_uint8)(*pLen_out >> 16),(mz_uint8)(*pLen_out >> 8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54 };
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17); for (i = 0; i < 4; ++i, c <<= 8) ((mz_uint8*)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
+ memcpy(out_buf.m_pBuf, pnghdr, 41);
+ }
+ // write footer (IDAT CRC-32, followed by IEND chunk)
+ if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4); for (i = 0; i < 4; ++i, c <<= 8) (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
+ // compute final size of file, grab compressed data buffer and return
+ *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
+}
+void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
+{
+ // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
+ return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
+}
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+// ------------------- .ZIP archive reading
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+
+#ifdef MINIZ_NO_STDIO
+#define MZ_FILE void *
+#else
+#include
+#include
+#include
+
+#if defined(_MSC_VER) || defined(__MINGW64__)
+static FILE *mz_fopen(const wchar_t *pFilename, const wchar_t *pMode)
+{
+ FILE* pFile = NULL;
+
+ errno_t err = _wfopen_s(&pFile, pFilename, pMode);
+
+ return pFile;
+}
+static FILE *mz_freopen(const wchar_t *pPath, const wchar_t *pMode, FILE *pStream)
+{
+ FILE* pFile;
+
+ if (_wfreopen_s(&pFile, pPath, pMode, pStream))
+ return NULL;
+
+ return pFile;
+}
+#ifndef MINIZ_NO_TIME
+#include
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN mz_fopen
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 _ftelli64
+#define MZ_FSEEK64 _fseeki64
+#define MZ_FILE_STAT_STRUCT _stat
+#define MZ_FILE_STAT _wstat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN mz_freopen
+#define MZ_DELETE_FILE _wremove
+#elif defined(__MINGW32__)
+#ifndef MINIZ_NO_TIME
+#include
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT _stat
+#define MZ_FILE_STAT _stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__TINYC__)
+#ifndef MINIZ_NO_TIME
+#include
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftell
+#define MZ_FSEEK64 fseek
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__GNUC__) && _LARGEFILE64_SOURCE
+#ifndef MINIZ_NO_TIME
+#include
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen64(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT stat64
+#define MZ_FILE_STAT stat64
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
+#define MZ_DELETE_FILE remove
+#else
+#ifndef MINIZ_NO_TIME
+#include
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello
+#define MZ_FSEEK64 fseeko
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#endif // #ifdef _MSC_VER
+#endif // #ifdef MINIZ_NO_STDIO
+
+#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
+
+// Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff.
+enum
+{
+ // ZIP archive identifiers and record sizes
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
+ // Central directory header record offsets
+ MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
+ MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16,
+ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
+ MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
+ // Local directory header offsets
+ MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10,
+ MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
+ MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
+ // End of central directory offsets
+ MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
+ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
+};
+
+typedef struct _mz_zip_array
+{
+ void *m_p;
+ size_t m_size, m_capacity;
+ mz_uint m_element_size;
+} mz_zip_array;
+
+struct mz_zip_internal_state_tag
+{
+ mz_zip_array m_central_dir;
+ mz_zip_array m_central_dir_offsets;
+ mz_zip_array m_sorted_central_dir_offsets;
+ MZ_FILE *m_pFile;
+ void *m_pMem;
+ size_t m_mem_size;
+ size_t m_mem_capacity;
+};
+
+#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
+#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
+
+static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
+{
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
+ memset(pArray, 0, sizeof(mz_zip_array));
+}
+
+static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
+{
+ void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE;
+ if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; }
+ if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE;
+ pArray->m_p = pNew_p; pArray->m_capacity = new_capacity;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
+{
+ if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; }
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
+{
+ if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; }
+ pArray->m_size = new_size;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
+{
+ return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
+{
+ size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE;
+ memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_TIME
+static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date)
+{
+ struct tm tm;
+ memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1;
+ tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31;
+ tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62;
+ return mktime(&tm);
+}
+
+static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
+{
+#ifdef _MSC_VER
+ struct tm tm_struct;
+ struct tm *tm = &tm_struct;
+ errno_t err = localtime_s(tm, &time);
+ if (err)
+ {
+ *pDOS_date = 0; *pDOS_time = 0;
+ return;
+ }
+#else
+ struct tm *tm = localtime(&time);
+#endif
+ *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
+ *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
+}
+#endif
+
+#ifndef MINIZ_NO_STDIO
+static mz_bool mz_zip_get_file_modified_time(const wchar_t *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
+{
+#ifdef MINIZ_NO_TIME
+ (void)pFilename; *pDOS_date = *pDOS_time = 0;
+#else
+ struct MZ_FILE_STAT_STRUCT file_stat;
+ // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh.
+ if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
+ return MZ_FALSE;
+ mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date);
+#endif // #ifdef MINIZ_NO_TIME
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_TIME
+
+static mz_bool mz_zip_set_file_times(const wchar_t *pFilename, time_t access_time, time_t modified_time)
+{
+ struct _utimbuf t;
+ t.actime = access_time;
+ t.modtime = modified_time;
+
+ return !_wutime(pFilename, &t);
+}
+#endif // #ifndef MINIZ_NO_TIME
+#endif // #ifndef MINIZ_NO_STDIO
+
+static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags)
+{
+ (void)flags;
+ if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return MZ_FALSE;
+
+ if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
+ if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
+ if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_READING;
+ pZip->m_archive_size = 0;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return MZ_FALSE;
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
+{
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
+ const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE)
+ {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
+ break;
+ pL++; pR++;
+ }
+ return (pL == pE) ? (l_len < r_len) : (l < r);
+}
+
+#define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END
+
+// Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.)
+static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+ const int size = pZip->m_total_files;
+ int start = (size - 2) >> 1, end;
+ while (start >= 0)
+ {
+ int child, root = start;
+ for (; ; )
+ {
+ if ((child = (root << 1) + 1) >= size)
+ break;
+ child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
+ }
+ start--;
+ }
+
+ end = size - 1;
+ while (end > 0)
+ {
+ int child, root = 0;
+ MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
+ for (; ; )
+ {
+ if ((child = (root << 1) + 1) >= end)
+ break;
+ child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
+ }
+ end--;
+ }
+}
+
+static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags)
+{
+ mz_uint cdir_size, num_this_disk, cdir_disk_index;
+ mz_uint64 cdir_ofs;
+ mz_int64 cur_file_ofs;
+ const mz_uint8 *p;
+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
+ mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
+ // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there.
+ if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ // Find the end of central directory record by scanning the file from the end towards the beginning.
+ cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
+ for (; ; )
+ {
+ int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
+ return MZ_FALSE;
+ for (i = n - 4; i >= 0; --i)
+ if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
+ break;
+ if (i >= 0)
+ {
+ cur_file_ofs += i;
+ break;
+ }
+ if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
+ return MZ_FALSE;
+ cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
+ }
+ // Read and verify the end of central directory record.
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
+ ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
+ return MZ_FALSE;
+
+ num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
+ cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
+ if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
+ return MZ_FALSE;
+
+ if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+
+ cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
+ if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+
+ pZip->m_central_directory_file_ofs = cdir_ofs;
+
+ if (pZip->m_total_files)
+ {
+ mz_uint i, n;
+
+ // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices.
+ if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
+ (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
+ return MZ_FALSE;
+
+ if (sort_central_dir)
+ {
+ if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
+ return MZ_FALSE;
+ }
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
+ return MZ_FALSE;
+
+ // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported).
+ p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
+ for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
+ {
+ mz_uint total_header_size, comp_size, decomp_size, disk_index;
+ if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
+ return MZ_FALSE;
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
+ if (sort_central_dir)
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF))
+ return MZ_FALSE;
+ disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
+ if ((disk_index != num_this_disk) && (disk_index != 1))
+ return MZ_FALSE;
+ if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+ if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
+ return MZ_FALSE;
+ n -= total_header_size; p += total_header_size;
+ }
+ }
+
+ if (sort_central_dir)
+ mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags)
+{
+ if ((!pZip) || (!pZip->m_pRead))
+ return MZ_FALSE;
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ return MZ_FALSE;
+ pZip->m_archive_size = size;
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
+ memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
+ return s;
+}
+
+mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags)
+{
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ return MZ_FALSE;
+ pZip->m_archive_size = size;
+ pZip->m_pRead = mz_zip_mem_read_func;
+ pZip->m_pIO_opaque = pZip;
+#ifdef __cplusplus
+ pZip->m_pState->m_pMem = const_cast(pMem);
+#else
+ pZip->m_pState->m_pMem = (void *)pMem;
+#endif
+ pZip->m_pState->m_mem_size = size;
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+
+ if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+
+ return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const wchar_t *pFilename, mz_uint32 flags)
+{
+ mz_uint64 file_size;
+ MZ_FILE* pFile = MZ_FOPEN(pFilename, L"rb");
+
+ if (!pFile)
+ return MZ_FALSE;
+
+ if (MZ_FSEEK64(pFile, 0, SEEK_END))
+ {
+ MZ_FCLOSE(pFile);
+ return MZ_FALSE;
+ }
+
+ file_size = MZ_FTELL64(pFile);
+
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ {
+ MZ_FCLOSE(pFile);
+ return MZ_FALSE;
+ }
+
+ pZip->m_pRead = mz_zip_file_read_func;
+ pZip->m_pIO_opaque = pZip;
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_archive_size = file_size;
+
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
+{
+ return pZip ? pZip->m_total_files : 0;
+}
+
+static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
+{
+ if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return NULL;
+ return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
+}
+
+mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
+{
+ mz_uint m_bit_flag;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p)
+ return MZ_FALSE;
+ m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ return (m_bit_flag & 1);
+}
+
+mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
+{
+ mz_uint filename_len, external_attr;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p)
+ return MZ_FALSE;
+
+ // First see if the filename ends with a '/' character.
+ filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_len)
+ {
+ if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
+ return MZ_TRUE;
+ }
+
+ // Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct.
+ // Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field.
+ // FIXME: Remove this check? Is it necessary - we already check the filename.
+ external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ if ((external_attr & 0x10) != 0)
+ return MZ_TRUE;
+
+ return MZ_FALSE;
+}
+
+mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
+{
+ mz_uint n;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if ((!p) || (!pStat))
+ return MZ_FALSE;
+
+ // Unpack the central directory record.
+ pStat->m_file_index = file_index;
+ pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
+ pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
+ pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
+ pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
+#ifndef MINIZ_NO_TIME
+ pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
+#endif
+ pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
+ pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
+ pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+
+ // Copy as much of the filename and comment as possible.
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
+ memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0';
+
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
+ pStat->m_comment_size = n;
+ memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0';
+
+ return MZ_TRUE;
+}
+
+mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
+{
+ mz_uint n;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; }
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_buf_size)
+ {
+ n = MZ_MIN(n, filename_buf_size - 1);
+ memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
+ pFilename[n] = '\0';
+ }
+ return n + 1;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
+{
+ mz_uint i;
+ if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
+ return 0 == memcmp(pA, pB, len);
+ for (i = 0; i < len; ++i)
+ if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
+ return MZ_FALSE;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
+{
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE)
+ {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
+ break;
+ pL++; pR++;
+ }
+ return (pL == pE) ? (int)(l_len - r_len) : (l - r);
+}
+
+static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+ const int size = pZip->m_total_files;
+ const mz_uint filename_len = (mz_uint)strlen(pFilename);
+ int l = 0, h = size - 1;
+ while (l <= h)
+ {
+ int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
+ if (!comp)
+ return file_index;
+ else if (comp < 0)
+ l = m + 1;
+ else
+ h = m - 1;
+ }
+ return -1;
+}
+
+int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
+{
+ mz_uint file_index; size_t name_len, comment_len;
+
+ if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return -1;
+
+ if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
+ return mz_zip_reader_locate_file_binary_search(pZip, pName);
+
+ name_len = strlen(pName);
+
+ if (name_len > 0xFFFF)
+ return -1;
+
+ comment_len = pComment ? strlen(pComment) : 0;
+
+ if (comment_len > 0xFFFF)
+ return -1;
+
+ for (file_index = 0; file_index < pZip->m_total_files; file_index++)
+ {
+ const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
+ mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+
+ if (filename_len < name_len)
+ continue;
+
+ if (comment_len)
+ {
+ mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+
+ const char *pFile_comment = pFilename + filename_len + file_extra_len;
+
+ if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags)))
+ continue;
+ }
+
+ if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
+ {
+ int ofs = filename_len - 1;
+ do
+ {
+ if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
+ break;
+ } while (--ofs >= 0);
+ ofs++;
+ pFilename += ofs; filename_len -= ofs;
+ }
+
+ if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
+ return file_index;
+ }
+
+ return -1;
+}
+
+mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
+{
+ int status = TINFL_STATUS_DONE;
+ mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ tinfl_decompressor inflator;
+
+ if ((buf_size) && (!pBuf))
+ return MZ_FALSE;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
+ if (!file_stat.m_comp_size)
+ return MZ_TRUE;
+
+ // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
+ // I'm torn how to handle this case - should it fail instead?
+ if (mz_zip_reader_is_file_a_directory(pZip, file_index))
+ return MZ_TRUE;
+
+ // Encryption and patch files are not supported.
+ if (file_stat.m_bit_flag & (1 | 32))
+ return MZ_FALSE;
+
+ // This function only supports stored and deflate.
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
+ return MZ_FALSE;
+
+ // Ensure supplied output buffer is large enough.
+ needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
+ if (buf_size < needed_size)
+ return MZ_FALSE;
+
+ // Read and parse the local directory entry.
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
+ {
+ // The file is stored or the caller has requested the compressed data.
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
+ return MZ_FALSE;
+ return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
+ }
+
+ // Decompress the file either directly from memory or from a file input buffer.
+ tinfl_init(&inflator);
+
+ if (pZip->m_pState->m_pMem)
+ {
+ // Read directly from the archive in memory.
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else if (pUser_read_buf)
+ {
+ // Use a user provided read buffer.
+ if (!user_read_buf_size)
+ return MZ_FALSE;
+
+ pRead_buf = (mz_uint8 *)pUser_read_buf;
+ read_buf_size = user_read_buf_size;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+ else
+ {
+ // Temporarily allocate a read buffer.
+ read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
+#endif
+ return MZ_FALSE;
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
+ return MZ_FALSE;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ do
+ {
+ size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+ out_buf_ofs += out_buf_size;
+ } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
+
+ if (status == TINFL_STATUS_DONE)
+ {
+ // Make sure the entire file was decompressed, and check its CRC.
+ if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
+ status = TINFL_STATUS_FAILED;
+ }
+
+ if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
+{
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0)
+ return MZ_FALSE;
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
+}
+
+mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
+{
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
+{
+ return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
+}
+
+void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
+{
+ mz_uint64 comp_size, uncomp_size, alloc_size;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ void *pBuf;
+
+ if (pSize)
+ *pSize = 0;
+ if (!p)
+ return NULL;
+
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+
+ alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
+#endif
+ return NULL;
+
+ if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
+ return NULL;
+
+ if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return NULL;
+ }
+
+ if (pSize)
+ *pSize = (size_t)alloc_size;
+
+ return pBuf;
+}
+
+void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
+{
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0)
+ {
+ if (pSize) *pSize = 0;
+ return MZ_FALSE;
+ }
+ return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
+}
+
+mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
+{
+ int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT;
+ mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf = NULL; void *pWrite_buf = NULL;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
+ if (!file_stat.m_comp_size)
+ return MZ_TRUE;
+
+ // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
+ // I'm torn how to handle this case - should it fail instead?
+ if (mz_zip_reader_is_file_a_directory(pZip, file_index))
+ return MZ_TRUE;
+
+ // Encryption and patch files are not supported.
+ if (file_stat.m_bit_flag & (1 | 32))
+ return MZ_FALSE;
+
+ // This function only supports stored and deflate.
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
+ return MZ_FALSE;
+
+ // Read and parse the local directory entry.
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+
+ // Decompress the file either directly from memory or from a file input buffer.
+ if (pZip->m_pState->m_pMem)
+ {
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else
+ {
+ read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
+ return MZ_FALSE;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
+ {
+ // The file is stored or the caller has requested the compressed data.
+ if (pZip->m_pState->m_pMem)
+ {
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
+#endif
+ return MZ_FALSE;
+
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
+ status = TINFL_STATUS_FAILED;
+ else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
+
+ cur_file_ofs += file_stat.m_comp_size;
+ out_buf_ofs += file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else
+ {
+ while (comp_remaining)
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+ if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
+
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ out_buf_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ }
+ }
+ }
+ else
+ {
+ tinfl_decompressor inflator;
+ tinfl_init(&inflator);
+
+ if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
+ status = TINFL_STATUS_FAILED;
+ else
+ {
+ do
+ {
+ mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+
+ if (out_buf_size)
+ {
+ if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
+ if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
+ {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ }
+ } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
+ }
+ }
+
+ if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
+ {
+ // Make sure the entire file was decompressed, and check its CRC.
+ if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32))
+ status = TINFL_STATUS_FAILED;
+ }
+
+ if (!pZip->m_pState->m_pMem)
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ if (pWrite_buf)
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
+{
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0)
+ return MZ_FALSE;
+ return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
+{
+ (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque);
+}
+
+mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const wchar_t *pDst_filename, mz_uint flags)
+{
+ mz_bool status;
+ mz_zip_archive_file_stat file_stat;
+ MZ_FILE *pFile;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ pFile = MZ_FOPEN(pDst_filename, L"wb");
+
+ if (!pFile)
+ return MZ_FALSE;
+
+ status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
+
+ if (MZ_FCLOSE(pFile) == EOF)
+ return MZ_FALSE;
+
+#ifndef MINIZ_NO_TIME
+ if (status)
+ mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
+#endif
+ return status;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
+{
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return MZ_FALSE;
+
+ if (pZip->m_pState)
+ {
+ mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL;
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile)
+ {
+ MZ_FCLOSE(pState->m_pFile);
+ pState->m_pFile = NULL;
+ }
+#endif // #ifndef MINIZ_NO_STDIO
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ }
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const wchar_t *pDst_filename, mz_uint flags)
+{
+ int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
+ if (file_index < 0)
+ return MZ_FALSE;
+ return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
+}
+#endif
+
+// ------------------- .ZIP archive writing
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); }
+static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); }
+#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
+#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
+
+mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
+{
+ if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return MZ_FALSE;
+
+ if (pZip->m_file_offset_alignment)
+ {
+ // Ensure user specified file offset alignment is a power of 2.
+ if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
+ return MZ_FALSE;
+ }
+
+ if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
+ if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
+ if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+ pZip->m_archive_size = existing_size;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return MZ_FALSE;
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
+ return MZ_TRUE;
+}
+
+static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
+#ifdef _MSC_VER
+ if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
+#else
+ if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
+#endif
+ return 0;
+ if (new_size > pState->m_mem_capacity)
+ {
+ void *pNew_block;
+ size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2;
+ if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
+ return 0;
+ pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity;
+ }
+ memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
+ pState->m_mem_size = (size_t)new_size;
+ return n;
+}
+
+mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
+{
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ pZip->m_pIO_opaque = pZip;
+ if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
+ return MZ_FALSE;
+ if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
+ {
+ if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
+ {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ pZip->m_pState->m_mem_capacity = initial_allocation_size;
+ }
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+ if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+ return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const wchar_t *pFilename, mz_uint64 size_to_reserve_at_beginning)
+{
+ MZ_FILE *pFile;
+ pZip->m_pWrite = mz_zip_file_write_func;
+ pZip->m_pIO_opaque = pZip;
+ if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
+ return MZ_FALSE;
+ if (NULL == (pFile = MZ_FOPEN(pFilename, L"wb")))
+ {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ pZip->m_pState->m_pFile = pFile;
+ if (size_to_reserve_at_beginning)
+ {
+ mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf);
+ do
+ {
+ size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
+ {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ cur_ofs += n; size_to_reserve_at_beginning -= n;
+ } while (size_to_reserve_at_beginning);
+ }
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const wchar_t *pFilename)
+{
+ mz_zip_internal_state *pState;
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return MZ_FALSE;
+ // No sense in trying to write to an archive that's already at the support max size
+ if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ if (pState->m_pFile)
+ {
+#ifdef MINIZ_NO_STDIO
+ pFilename; return MZ_FALSE;
+#else
+ // Archive is being read from stdio - try to reopen as writable.
+ if (pZip->m_pIO_opaque != pZip)
+ return MZ_FALSE;
+ if (!pFilename)
+ return MZ_FALSE;
+ pZip->m_pWrite = mz_zip_file_write_func;
+ if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, L"r+b", pState->m_pFile)))
+ {
+ // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it.
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+#endif // #ifdef MINIZ_NO_STDIO
+ }
+ else if (pState->m_pMem)
+ {
+ // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback.
+ if (pZip->m_pIO_opaque != pZip)
+ return MZ_FALSE;
+ pState->m_mem_capacity = pState->m_mem_size;
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ }
+ // Archive is being read via a user provided read function - make sure the user has specified a write function too.
+ else if (!pZip->m_pWrite)
+ return MZ_FALSE;
+
+ // Start writing new files at the archive's current central directory location.
+ pZip->m_archive_size = pZip->m_central_directory_file_ofs;
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+ pZip->m_central_directory_file_ofs = 0;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
+{
+ return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
+}
+
+typedef struct
+{
+ mz_zip_archive *m_pZip;
+ mz_uint64 m_cur_archive_file_ofs;
+ mz_uint64 m_comp_size;
+} mz_zip_writer_add_state;
+
+static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser)
+{
+ mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
+ if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
+ return MZ_FALSE;
+ pState->m_cur_archive_file_ofs += len;
+ pState->m_comp_size += len;
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
+{
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
+{
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
+ size_t orig_central_dir_size = pState->m_central_dir.m_size;
+ mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+
+ // No zip64 support yet
+ if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1)))
+ {
+ // Try to push the central directory array back into its original state.
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
+{
+ // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes.
+ if (*pArchive_name == '/')
+ return MZ_FALSE;
+ while (*pArchive_name)
+ {
+ if ((*pArchive_name == '\\') || (*pArchive_name == ':'))
+ return MZ_FALSE;
+ pArchive_name++;
+ }
+ return MZ_TRUE;
+}
+
+static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
+{
+ mz_uint32 n;
+ if (!pZip->m_file_offset_alignment)
+ return 0;
+ n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
+ return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1);
+}
+
+static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
+{
+ char buf[4096];
+ memset(buf, 0, MZ_MIN(sizeof(buf), n));
+ while (n)
+ {
+ mz_uint32 s = MZ_MIN(sizeof(buf), n);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
+ return MZ_FALSE;
+ cur_file_ofs += s; n -= s;
+ }
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
+{
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0;
+ mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
+ mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ tdefl_compressor *pComp = NULL;
+ mz_bool store_data_uncompressed;
+ mz_zip_internal_state *pState;
+
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+ level = level_and_flags & 0xF;
+ store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
+ return MZ_FALSE;
+ // No zip64 support yet
+ if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
+ return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ return MZ_FALSE;
+
+#ifndef MINIZ_NO_TIME
+ {
+ time_t cur_time; time(&cur_time);
+ mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date);
+ }
+#endif // #ifndef MINIZ_NO_TIME
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > 0xFFFF)
+ return MZ_FALSE;
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
+ {
+ // Set DOS Subdirectory attribute bit.
+ ext_attributes |= 0x10;
+ // Subdirectories cannot contain data.
+ if ((buf_size) || (uncomp_size))
+ return MZ_FALSE;
+ }
+
+ // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.)
+ if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
+ return MZ_FALSE;
+
+ if ((!store_data_uncompressed) && (buf_size))
+ {
+ if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+ local_dir_header_ofs += num_alignment_padding_bytes;
+ if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
+ cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
+
+ MZ_CLEAR_OBJ(local_dir_header);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+ cur_archive_file_ofs += archive_name_size;
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ {
+ uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size);
+ uncomp_size = buf_size;
+ if (uncomp_size <= 3)
+ {
+ level = 0;
+ store_data_uncompressed = MZ_TRUE;
+ }
+ }
+
+ if (store_data_uncompressed)
+ {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+
+ cur_archive_file_ofs += buf_size;
+ comp_size = buf_size;
+
+ if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
+ method = MZ_DEFLATED;
+ }
+ else if (buf_size)
+ {
+ mz_zip_writer_add_state state;
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
+ (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+
+ method = MZ_DEFLATED;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pComp = NULL;
+
+ // no zip64 support yet
+ if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
+ return MZ_FALSE;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const wchar_t *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
+{
+ mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
+ mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ MZ_FILE *pSrc_file = NULL;
+
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+ level = level_and_flags & 0xF;
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+ if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
+ return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ return MZ_FALSE;
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > 0xFFFF)
+ return MZ_FALSE;
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
+ return MZ_FALSE;
+
+ pSrc_file = MZ_FOPEN(pSrc_filename, L"rb");
+ if (!pSrc_file)
+ return MZ_FALSE;
+ MZ_FSEEK64(pSrc_file, 0, SEEK_END);
+ uncomp_size = MZ_FTELL64(pSrc_file);
+ MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
+
+ if (uncomp_size > 0xFFFFFFFF)
+ {
+ // No zip64 support yet
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ if (uncomp_size <= 3)
+ level = 0;
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
+ {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ local_dir_header_ofs += num_alignment_padding_bytes;
+ if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
+ cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
+
+ MZ_CLEAR_OBJ(local_dir_header);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ cur_archive_file_ofs += archive_name_size;
+
+ if (uncomp_size)
+ {
+ mz_uint64 uncomp_remaining = uncomp_size;
+ void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (!pRead_buf)
+ {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ if (!level)
+ {
+ while (uncomp_remaining)
+ {
+ mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
+ if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
+ uncomp_remaining -= n;
+ cur_archive_file_ofs += n;
+ }
+ comp_size = uncomp_size;
+ }
+ else
+ {
+ mz_bool result = MZ_FALSE;
+ mz_zip_writer_add_state state;
+ tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
+ if (!pComp)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ for (; ; )
+ {
+ size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE);
+ tdefl_status status;
+
+ if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
+ break;
+
+ uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
+ uncomp_remaining -= in_buf_size;
+
+ status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
+ if (status == TDEFL_STATUS_DONE)
+ {
+ result = MZ_TRUE;
+ break;
+ }
+ else if (status != TDEFL_STATUS_OKAY)
+ break;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+
+ if (!result)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+
+ method = MZ_DEFLATED;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ }
+
+ MZ_FCLOSE(pSrc_file); pSrc_file = NULL;
+
+ // no zip64 support yet
+ if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
+ return MZ_FALSE;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index)
+{
+ mz_uint n, bit_flags, num_alignment_padding_bytes;
+ mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
+ mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+ size_t orig_central_dir_size;
+ mz_zip_internal_state *pState;
+ void *pBuf; const mz_uint8 *pSrc_central_header;
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
+ return MZ_FALSE;
+ if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
+ return MZ_FALSE;
+ pState = pZip->m_pState;
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+ cur_dst_file_ofs = pZip->m_archive_size;
+
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+ cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
+ return MZ_FALSE;
+ cur_dst_file_ofs += num_alignment_padding_bytes;
+ local_dir_header_ofs = cur_dst_file_ofs;
+ if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+
+ if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining)))))
+ return MZ_FALSE;
+
+ while (comp_bytes_remaining)
+ {
+ n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+ cur_src_file_ofs += n;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+ cur_dst_file_ofs += n;
+
+ comp_bytes_remaining -= n;
+ }
+
+ bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
+ if (bit_flags & 8)
+ {
+ // Copy data descriptor
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+
+ n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+
+ cur_src_file_ofs += n;
+ cur_dst_file_ofs += n;
+ }
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+
+ // no zip64 support yet
+ if (cur_dst_file_ofs > 0xFFFFFFFF)
+ return MZ_FALSE;
+
+ orig_central_dir_size = pState->m_central_dir.m_size;
+
+ memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
+ return MZ_FALSE;
+
+ n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n))
+ {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ if (pState->m_central_dir.m_size > 0xFFFFFFFF)
+ return MZ_FALSE;
+ n = (mz_uint32)orig_central_dir_size;
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
+ {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_dst_file_ofs;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
+{
+ mz_zip_internal_state *pState;
+ mz_uint64 central_dir_ofs, central_dir_size;
+ mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE];
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ // no zip64 support yet
+ if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ central_dir_ofs = 0;
+ central_dir_size = 0;
+ if (pZip->m_total_files)
+ {
+ // Write central directory
+ central_dir_ofs = pZip->m_archive_size;
+ central_dir_size = pState->m_central_dir.m_size;
+ pZip->m_central_directory_file_ofs = central_dir_ofs;
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
+ return MZ_FALSE;
+ pZip->m_archive_size += central_dir_size;
+ }
+
+ // Write end of central directory record
+ MZ_CLEAR_OBJ(hdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr))
+ return MZ_FALSE;
+#ifndef MINIZ_NO_STDIO
+ if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
+ return MZ_FALSE;
+#endif // #ifndef MINIZ_NO_STDIO
+
+ pZip->m_archive_size += sizeof(hdr);
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize)
+{
+ if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize))
+ return MZ_FALSE;
+ if (pZip->m_pWrite != mz_zip_heap_write_func)
+ return MZ_FALSE;
+ if (!mz_zip_writer_finalize_archive(pZip))
+ return MZ_FALSE;
+
+ *pBuf = pZip->m_pState->m_pMem;
+ *pSize = pZip->m_pState->m_mem_size;
+ pZip->m_pState->m_pMem = NULL;
+ pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
+{
+ mz_zip_internal_state *pState;
+ mz_bool status = MZ_TRUE;
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+ pZip->m_pState = NULL;
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile)
+ {
+ MZ_FCLOSE(pState->m_pFile);
+ pState->m_pFile = NULL;
+ }
+#endif // #ifndef MINIZ_NO_STDIO
+
+ if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
+ pState->m_pMem = NULL;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+ return status;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_add_mem_to_archive_file_in_place(const wchar_t *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
+{
+ mz_bool status, created_new_archive = MZ_FALSE;
+ mz_zip_archive zip_archive;
+ struct MZ_FILE_STAT_STRUCT file_stat;
+ MZ_CLEAR_OBJ(zip_archive);
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+ if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ return MZ_FALSE;
+ if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
+ {
+ // Create a new archive.
+ if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
+ return MZ_FALSE;
+ created_new_archive = MZ_TRUE;
+ }
+ else
+ {
+ // Append to an existing archive.
+ if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
+ return MZ_FALSE;
+ if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename))
+ {
+ mz_zip_reader_end(&zip_archive);
+ return MZ_FALSE;
+ }
+ }
+ status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
+ // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.)
+ if (!mz_zip_writer_finalize_archive(&zip_archive))
+ status = MZ_FALSE;
+ if (!mz_zip_writer_end(&zip_archive))
+ status = MZ_FALSE;
+ if ((!status) && (created_new_archive))
+ {
+ // It's a new archive and something went wrong, so just delete it.
+ int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
+ (void)ignoredStatus;
+ }
+ return status;
+}
+
+void *mz_zip_extract_archive_file_to_heap(const wchar_t *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
+{
+ int file_index;
+ mz_zip_archive zip_archive;
+ void *p = NULL;
+
+ if (pSize)
+ *pSize = 0;
+
+ if ((!pZip_filename) || (!pArchive_name))
+ return NULL;
+
+ MZ_CLEAR_OBJ(zip_archive);
+ if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
+ return NULL;
+
+ if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0)
+ p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
+
+ mz_zip_reader_end(&zip_archive);
+ return p;
+}
+
+#endif // #ifndef MINIZ_NO_STDIO
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
+
+
+/*
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to
+*/
diff --git a/plugins-extra/ExtraPlugins/miniz/miniz.h b/plugins-extra/ExtraPlugins/miniz/miniz.h
new file mode 100644
index 0000000..261ac5a
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/miniz/miniz.h
@@ -0,0 +1,785 @@
+#ifndef MINIZ_HEADER_INCLUDED
+#define MINIZ_HEADER_INCLUDED
+
+#include
+
+// Defines to completely disable specific portions of miniz.c:
+// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
+
+// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
+//#define MINIZ_NO_STDIO
+
+// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
+// get/set file times, and the C run-time funcs that get/set times won't be called.
+// The current downside is the times written to your archives will be from 1979.
+//#define MINIZ_NO_TIME
+
+// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
+//#define MINIZ_NO_ARCHIVE_APIS
+
+// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
+//#define MINIZ_NO_ARCHIVE_WRITING_APIS
+
+// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
+//#define MINIZ_NO_ZLIB_APIS
+
+// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
+#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+
+// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
+// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
+// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
+// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
+//#define MINIZ_NO_MALLOC
+
+#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
+#include
+#endif
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
+// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
+#define MINIZ_X86_OR_X64_CPU 1
+#endif
+
+#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
+// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
+#define MINIZ_LITTLE_ENDIAN 1
+#endif
+
+#if MINIZ_X86_OR_X64_CPU
+// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+#endif
+
+#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
+// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).
+#define MINIZ_HAS_64BIT_REGISTERS 1
+#endif
+
+// ------------------- Types and macros
+
+typedef unsigned char mz_uint8;
+typedef signed short mz_int16;
+typedef unsigned short mz_uint16;
+typedef unsigned int mz_uint32;
+typedef unsigned int mz_uint;
+typedef long long mz_int64;
+typedef unsigned long long mz_uint64;
+typedef int mz_bool;
+
+#define MZ_FALSE (0)
+#define MZ_TRUE (1)
+
+// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
+#ifdef _MSC_VER
+#define MZ_MACRO_END while (0, 0)
+#else
+#define MZ_MACRO_END while (0)
+#endif
+
+// ------------------- zlib-style API Definitions.
+
+// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
+typedef unsigned long mz_ulong;
+
+// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap.
+void mz_free(void *p);
+
+#define MZ_ADLER32_INIT (1)
+// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
+mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
+
+#define MZ_CRC32_INIT (0)
+// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
+mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
+
+// Compression strategies.
+enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
+
+// Method
+#define MZ_DEFLATED 8
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+// Heap allocation callbacks.
+// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
+typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
+typedef void(*mz_free_func)(void *opaque, void *address);
+typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
+
+#define MZ_VERSION "9.1.15"
+#define MZ_VERNUM 0x91F0
+#define MZ_VER_MAJOR 9
+#define MZ_VER_MINOR 1
+#define MZ_VER_REVISION 15
+#define MZ_VER_SUBREVISION 0
+
+// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
+enum
+{
+ MZ_NO_FLUSH = 0,
+ MZ_PARTIAL_FLUSH = 1,
+ MZ_SYNC_FLUSH = 2,
+ MZ_FULL_FLUSH = 3,
+ MZ_FINISH = 4,
+ MZ_BLOCK = 5
+};
+
+// Return status codes. MZ_PARAM_ERROR is non-standard.
+enum
+{
+ MZ_OK = 0,
+ MZ_STREAM_END = 1,
+ MZ_NEED_DICT = 2,
+ MZ_ERRNO = -1,
+ MZ_STREAM_ERROR = -2,
+ MZ_DATA_ERROR = -3,
+ MZ_MEM_ERROR = -4,
+ MZ_BUF_ERROR = -5,
+ MZ_VERSION_ERROR = -6,
+ MZ_PARAM_ERROR = -10000
+};
+
+// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
+enum
+{
+ MZ_NO_COMPRESSION = 0,
+ MZ_BEST_SPEED = 1,
+ MZ_BEST_COMPRESSION = 9,
+ MZ_UBER_COMPRESSION = 10,
+ MZ_DEFAULT_LEVEL = 6,
+ MZ_DEFAULT_COMPRESSION = -1
+};
+
+// Window bits
+#define MZ_DEFAULT_WINDOW_BITS 15
+
+struct mz_internal_state;
+
+// Compression/decompression stream struct.
+typedef struct mz_stream_s
+{
+ const unsigned char *next_in; // pointer to next byte to read
+ unsigned int avail_in; // number of bytes available at next_in
+ mz_ulong total_in; // total number of bytes consumed so far
+
+ unsigned char *next_out; // pointer to next byte to write
+ unsigned int avail_out; // number of bytes that can be written to next_out
+ mz_ulong total_out; // total number of bytes produced so far
+
+ char *msg; // error msg (unused)
+ struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
+
+ mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
+ mz_free_func zfree; // optional heap free function (defaults to free)
+ void *opaque; // heap alloc function user pointer
+
+ int data_type; // data_type (unused)
+ mz_ulong adler; // adler32 of the source or uncompressed data
+ mz_ulong reserved; // not used
+} mz_stream;
+
+typedef mz_stream *mz_streamp;
+
+// Returns the version string of miniz.c.
+const char *mz_version(void);
+
+// mz_deflateInit() initializes a compressor with default options:
+// Parameters:
+// pStream must point to an initialized mz_stream struct.
+// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
+// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
+// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
+// Return values:
+// MZ_OK on success.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_PARAM_ERROR if the input parameters are bogus.
+// MZ_MEM_ERROR on out of memory.
+int mz_deflateInit(mz_streamp pStream, int level);
+
+// mz_deflateInit2() is like mz_deflate(), except with more control:
+// Additional parameters:
+// method must be MZ_DEFLATED
+// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
+// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
+int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
+
+// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
+int mz_deflateReset(mz_streamp pStream);
+
+// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
+// Parameters:
+// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
+// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
+// Return values:
+// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
+// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_PARAM_ERROR if one of the parameters is invalid.
+// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
+int mz_deflate(mz_streamp pStream, int flush);
+
+// mz_deflateEnd() deinitializes a compressor:
+// Return values:
+// MZ_OK on success.
+// MZ_STREAM_ERROR if the stream is bogus.
+int mz_deflateEnd(mz_streamp pStream);
+
+// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH.
+mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
+
+// Single-call compression functions mz_compress() and mz_compress2():
+// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
+int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
+int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
+
+// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
+mz_ulong mz_compressBound(mz_ulong source_len);
+
+// Initializes a decompressor.
+int mz_inflateInit(mz_streamp pStream);
+
+// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
+// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
+int mz_inflateInit2(mz_streamp pStream, int window_bits);
+
+// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
+// Parameters:
+// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
+// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
+// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
+// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
+// Return values:
+// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
+// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_DATA_ERROR if the deflate stream is invalid.
+// MZ_PARAM_ERROR if one of the parameters is invalid.
+// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again
+// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
+int mz_inflate(mz_streamp pStream, int flush);
+
+// Deinitializes a decompressor.
+int mz_inflateEnd(mz_streamp pStream);
+
+// Single-call decompression.
+// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
+int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
+
+// Returns a string description of the specified error code, or NULL if the error code is invalid.
+const char *mz_error(int err);
+
+// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports.
+// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
+#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+typedef unsigned char Byte;
+typedef unsigned int uInt;
+typedef mz_ulong uLong;
+typedef Byte Bytef;
+typedef uInt uIntf;
+typedef char charf;
+typedef int intf;
+typedef void *voidpf;
+typedef uLong uLongf;
+typedef void *voidp;
+typedef void *const voidpc;
+#define Z_NULL 0
+#define Z_NO_FLUSH MZ_NO_FLUSH
+#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
+#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
+#define Z_FULL_FLUSH MZ_FULL_FLUSH
+#define Z_FINISH MZ_FINISH
+#define Z_BLOCK MZ_BLOCK
+#define Z_OK MZ_OK
+#define Z_STREAM_END MZ_STREAM_END
+#define Z_NEED_DICT MZ_NEED_DICT
+#define Z_ERRNO MZ_ERRNO
+#define Z_STREAM_ERROR MZ_STREAM_ERROR
+#define Z_DATA_ERROR MZ_DATA_ERROR
+#define Z_MEM_ERROR MZ_MEM_ERROR
+#define Z_BUF_ERROR MZ_BUF_ERROR
+#define Z_VERSION_ERROR MZ_VERSION_ERROR
+#define Z_PARAM_ERROR MZ_PARAM_ERROR
+#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
+#define Z_BEST_SPEED MZ_BEST_SPEED
+#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
+#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
+#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
+#define Z_FILTERED MZ_FILTERED
+#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
+#define Z_RLE MZ_RLE
+#define Z_FIXED MZ_FIXED
+#define Z_DEFLATED MZ_DEFLATED
+#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
+#define alloc_func mz_alloc_func
+#define free_func mz_free_func
+#define internal_state mz_internal_state
+#define z_stream mz_stream
+#define deflateInit mz_deflateInit
+#define deflateInit2 mz_deflateInit2
+#define deflateReset mz_deflateReset
+#define deflate mz_deflate
+#define deflateEnd mz_deflateEnd
+#define deflateBound mz_deflateBound
+#define compress mz_compress
+#define compress2 mz_compress2
+#define compressBound mz_compressBound
+#define inflateInit mz_inflateInit
+#define inflateInit2 mz_inflateInit2
+#define inflate mz_inflate
+#define inflateEnd mz_inflateEnd
+#define uncompress mz_uncompress
+#define crc32 mz_crc32
+#define adler32 mz_adler32
+#define MAX_WBITS 15
+#define MAX_MEM_LEVEL 9
+#define zError mz_error
+#define ZLIB_VERSION MZ_VERSION
+#define ZLIB_VERNUM MZ_VERNUM
+#define ZLIB_VER_MAJOR MZ_VER_MAJOR
+#define ZLIB_VER_MINOR MZ_VER_MINOR
+#define ZLIB_VER_REVISION MZ_VER_REVISION
+#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
+#define zlibVersion mz_version
+#define zlib_version mz_version()
+#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+
+#endif // MINIZ_NO_ZLIB_APIS
+
+
+
+ // ------------------- ZIP archive reading/writing
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+
+enum
+{
+ MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
+ MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
+ MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
+};
+
+typedef struct _mz_zip_archive_file_stat
+{
+ mz_uint32 m_file_index;
+ mz_uint32 m_central_dir_ofs;
+ mz_uint16 m_version_made_by;
+ mz_uint16 m_version_needed;
+ mz_uint16 m_bit_flag;
+ mz_uint16 m_method;
+#ifndef MINIZ_NO_TIME
+ time_t m_time;
+#endif
+ mz_uint32 m_crc32;
+ mz_uint64 m_comp_size;
+ mz_uint64 m_uncomp_size;
+ mz_uint16 m_internal_attr;
+ mz_uint32 m_external_attr;
+ mz_uint64 m_local_header_ofs;
+ mz_uint32 m_comment_size;
+ char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
+ char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
+} mz_zip_archive_file_stat;
+
+typedef size_t(*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
+typedef size_t(*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
+
+struct mz_zip_internal_state_tag;
+typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
+
+typedef enum _mz_zip_mode
+{
+ MZ_ZIP_MODE_INVALID = 0,
+ MZ_ZIP_MODE_READING = 1,
+ MZ_ZIP_MODE_WRITING = 2,
+ MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
+} mz_zip_mode;
+
+typedef struct _mz_zip_archive
+{
+ mz_uint64 m_archive_size;
+ mz_uint64 m_central_directory_file_ofs;
+ mz_uint m_total_files;
+ mz_zip_mode m_zip_mode;
+
+ mz_uint m_file_offset_alignment;
+
+ mz_alloc_func m_pAlloc;
+ mz_free_func m_pFree;
+ mz_realloc_func m_pRealloc;
+ void *m_pAlloc_opaque;
+
+ mz_file_read_func m_pRead;
+ mz_file_write_func m_pWrite;
+ void *m_pIO_opaque;
+
+ mz_zip_internal_state *m_pState;
+
+} mz_zip_archive;
+
+typedef enum _mz_zip_flags
+{
+ MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
+ MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
+ MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
+ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
+} mz_zip_flags;
+
+// ZIP archive reading
+
+// Inits a ZIP archive reader.
+// These functions read and validate the archive's central directory.
+mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
+mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const wchar_t *pFilename, mz_uint32 flags);
+#endif
+
+// Returns the total number of files in the archive.
+mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
+
+// Returns detailed information about an archive file entry.
+mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
+
+// Determines if an archive file entry is a directory entry.
+mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
+mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
+
+// Retrieves the filename of an archive file entry.
+// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
+mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
+
+// Attempts to locates a file in the archive's central directory.
+// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
+// Returns -1 if the file cannot be found.
+int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
+
+// Extracts a archive file to a memory buffer using no memory allocation.
+mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
+mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
+
+// Extracts a archive file to a memory buffer.
+mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
+
+// Extracts a archive file to a dynamically allocated heap buffer.
+void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
+void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
+
+// Extracts a archive file using a callback function to output the file's data.
+mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
+
+#ifndef MINIZ_NO_STDIO
+// Extracts a archive file to a disk file and sets its last accessed and modified times.
+// This function only extracts files, not archive directory records.
+mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const wchar_t *pDst_filename, mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const wchar_t *pDst_filename, mz_uint flags);
+#endif
+
+// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
+mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
+
+// ZIP archive writing
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+ // Inits a ZIP archive writer.
+mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
+mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const wchar_t *pFilename, mz_uint64 size_to_reserve_at_beginning);
+#endif
+
+// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
+// For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called.
+// For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it).
+// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
+// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
+// the archive is finalized the file's central directory will be hosed.
+mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const wchar_t *pFilename);
+
+// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
+// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
+mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
+
+#ifndef MINIZ_NO_STDIO
+// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const wchar_t *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+#endif
+
+// Adds a file to an archive by fully cloning the data from another archive.
+// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
+mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
+
+// Finalizes the archive by writing the central directory records followed by the end of central directory record.
+// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
+// An archive must be manually finalized by calling this function for it to be valid.
+mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
+mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
+
+// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
+// Note for the archive to be valid, it must have been finalized before ending.
+mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
+
+// Misc. high-level helper functions:
+
+// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_add_mem_to_archive_file_in_place(const wchar_t *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+
+// Reads a single file from an archive into a heap block.
+// Returns NULL on failure.
+void *mz_zip_extract_archive_file_to_heap(const wchar_t *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
+
+// ------------------- Low-level Decompression API Definitions
+
+// Decompression flags used by tinfl_decompress().
+// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
+// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
+// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
+// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
+enum
+{
+ TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
+ TINFL_FLAG_HAS_MORE_INPUT = 2,
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
+ TINFL_FLAG_COMPUTE_ADLER32 = 8
+};
+
+// High level decompression functions:
+// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
+// On entry:
+// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
+// On return:
+// Function returns a pointer to the decompressed data, or NULL on failure.
+// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
+// The caller must call mz_free() on the returned block when it's no longer needed.
+void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
+
+// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
+// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
+#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
+size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
+
+// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
+// Returns 1 on success or 0 on failure.
+typedef int(*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
+int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
+
+// Max size of LZ dictionary.
+#define TINFL_LZ_DICT_SIZE 32768
+
+ // Return status.
+typedef enum
+{
+ TINFL_STATUS_BAD_PARAM = -3,
+ TINFL_STATUS_ADLER32_MISMATCH = -2,
+ TINFL_STATUS_FAILED = -1,
+ TINFL_STATUS_DONE = 0,
+ TINFL_STATUS_NEEDS_MORE_INPUT = 1,
+ TINFL_STATUS_HAS_MORE_OUTPUT = 2
+} tinfl_status;
+
+// Initializes the decompressor to its initial state.
+#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
+#define tinfl_get_adler32(r) (r)->m_check_adler32
+
+ // Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
+ // This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
+tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
+
+// Internal/private bits follow.
+enum
+{
+ TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
+};
+
+typedef struct
+{
+ mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
+ mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
+} tinfl_huff_table;
+
+#if MINIZ_HAS_64BIT_REGISTERS
+#define TINFL_USE_64BIT_BITBUF 1
+#endif
+
+#if TINFL_USE_64BIT_BITBUF
+typedef mz_uint64 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (64)
+#else
+typedef mz_uint32 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (32)
+#endif
+
+struct tinfl_decompressor_tag
+{
+ mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
+ tinfl_bit_buf_t m_bit_buf;
+ size_t m_dist_from_out_buf_start;
+ tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
+ mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
+};
+
+// ------------------- Low-level Compression API Definitions
+
+// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
+#define TDEFL_LESS_MEMORY 0
+
+ // tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
+ // TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
+enum
+{
+ TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
+};
+
+// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
+// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
+// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
+// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
+// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
+// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
+// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
+// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
+// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
+enum
+{
+ TDEFL_WRITE_ZLIB_HEADER = 0x01000,
+ TDEFL_COMPUTE_ADLER32 = 0x02000,
+ TDEFL_GREEDY_PARSING_FLAG = 0x04000,
+ TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
+ TDEFL_RLE_MATCHES = 0x10000,
+ TDEFL_FILTER_MATCHES = 0x20000,
+ TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
+ TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
+};
+
+// High level compression functions:
+// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
+// On entry:
+// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
+// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
+// On return:
+// Function returns a pointer to the compressed data, or NULL on failure.
+// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
+// The caller must free() the returned block when it's no longer needed.
+void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
+
+// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
+// Returns 0 on failure.
+size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
+
+// Compresses an image to a compressed PNG file in memory.
+// On entry:
+// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
+// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
+// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
+// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
+// On return:
+// Function returns a pointer to the compressed data, or NULL on failure.
+// *pLen_out will be set to the size of the PNG image file.
+// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
+void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
+void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
+
+// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
+typedef mz_bool(*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
+
+// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
+mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 };
+
+// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
+#if TDEFL_LESS_MEMORY
+enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
+#else
+enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
+#endif
+
+// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
+typedef enum
+{
+ TDEFL_STATUS_BAD_PARAM = -2,
+ TDEFL_STATUS_PUT_BUF_FAILED = -1,
+ TDEFL_STATUS_OKAY = 0,
+ TDEFL_STATUS_DONE = 1,
+} tdefl_status;
+
+// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
+typedef enum
+{
+ TDEFL_NO_FLUSH = 0,
+ TDEFL_SYNC_FLUSH = 2,
+ TDEFL_FULL_FLUSH = 3,
+ TDEFL_FINISH = 4
+} tdefl_flush;
+
+// tdefl's compression state structure.
+typedef struct
+{
+ tdefl_put_buf_func_ptr m_pPut_buf_func;
+ void *m_pPut_buf_user;
+ mz_uint m_flags, m_max_probes[2];
+ int m_greedy_parsing;
+ mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
+ mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
+ mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
+ mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
+ tdefl_status m_prev_return_status;
+ const void *m_pIn_buf;
+ void *m_pOut_buf;
+ size_t *m_pIn_buf_size, *m_pOut_buf_size;
+ tdefl_flush m_flush;
+ const mz_uint8 *m_pSrc;
+ size_t m_src_buf_left, m_out_buf_ofs;
+ mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
+ mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
+ mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
+ mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
+ mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
+} tdefl_compressor;
+
+// Initializes the compressor.
+// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
+// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
+// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
+// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
+tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
+tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
+
+// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
+// tdefl_compress_buffer() always consumes the entire input buffer.
+tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
+
+tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
+mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
+
+// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
+#ifndef MINIZ_NO_ZLIB_APIS
+ // Create tdefl_compress() flags given zlib-style compression parameters.
+ // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
+ // window_bits may be -15 (raw deflate) or 15 (zlib)
+ // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
+mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
+#endif // #ifndef MINIZ_NO_ZLIB_APIS
+
+#endif // MINIZ_HEADER_INCLUDED
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/plugin.c b/plugins-extra/ExtraPlugins/plugin.c
new file mode 100644
index 0000000..25a45c3
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/plugin.c
@@ -0,0 +1,211 @@
+#include "main.h"
+
+ULONG PhDisabledPluginsCount(
+ VOID
+ )
+{
+ PPH_STRING disabled;
+ PH_STRINGREF remainingPart;
+ PH_STRINGREF part;
+ ULONG count = 0;
+
+ disabled = PhGetStringSetting(L"DisabledPlugins");
+ remainingPart = disabled->sr;
+
+ while (remainingPart.Length)
+ {
+ PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart);
+
+ if (part.Length)
+ {
+ count++;
+ }
+ }
+
+ PhDereferenceObject(disabled);
+
+ return count;
+}
+
+// Copied from Process Hacker, plugin.c
+
+PWSTR PhGetPluginBaseName(
+ _In_ PPHAPP_PLUGIN Plugin
+ )
+{
+ if (Plugin->FileName)
+ {
+ PH_STRINGREF pathNamePart;
+ PH_STRINGREF baseNamePart;
+
+ if (PhSplitStringRefAtLastChar(&Plugin->FileName->sr, '\\', &pathNamePart, &baseNamePart))
+ return baseNamePart.Buffer;
+ else
+ return Plugin->FileName->Buffer;
+ }
+ else
+ {
+ // Fake disabled plugin.
+ return Plugin->Name.Buffer;
+ }
+}
+
+BOOLEAN PhIsPluginLoadedByBaseName(
+ _In_ PPH_STRINGREF BaseName
+ )
+{
+ PPH_AVL_LINKS root;
+ PPH_AVL_LINKS links;
+
+ root = PluginInstance->Links.Parent;
+
+ while (root)
+ {
+ if (!root->Parent)
+ break;
+
+ root = root->Parent;
+ }
+
+ for (
+ links = PhMinimumElementAvlTree((PPH_AVL_TREE)root);
+ links;
+ links = PhSuccessorElementAvlTree(links)
+ )
+ {
+ PPHAPP_PLUGIN plugin = CONTAINING_RECORD(links, PHAPP_PLUGIN, Links);
+ PH_STRINGREF pluginBaseName;
+
+ PhInitializeStringRefLongHint(&pluginBaseName, PhGetPluginBaseName(plugin));
+
+ if (PhEqualStringRef(&pluginBaseName, BaseName, TRUE))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN PhpLocateDisabledPlugin(
+ _In_ PPH_STRING List,
+ _In_ PPH_STRINGREF BaseName,
+ _Out_opt_ PULONG FoundIndex
+ )
+{
+ PH_STRINGREF namePart;
+ PH_STRINGREF remainingPart;
+
+ remainingPart = List->sr;
+
+ while (remainingPart.Length != 0)
+ {
+ PhSplitStringRefAtChar(&remainingPart, '|', &namePart, &remainingPart);
+
+ if (PhEqualStringRef(&namePart, BaseName, TRUE))
+ {
+ if (FoundIndex)
+ *FoundIndex = (ULONG)(namePart.Buffer - List->Buffer);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOLEAN PhIsPluginDisabled(
+ _In_ PPH_STRINGREF BaseName
+ )
+{
+ BOOLEAN found;
+ PPH_STRING disabled;
+
+ disabled = PhGetStringSetting(L"DisabledPlugins");
+ found = PhpLocateDisabledPlugin(disabled, BaseName, NULL);
+ PhDereferenceObject(disabled);
+
+ return found;
+}
+
+VOID PhSetPluginDisabled(
+ _In_ PPH_STRINGREF BaseName,
+ _In_ BOOLEAN Disable
+ )
+{
+ BOOLEAN found;
+ PPH_STRING disabled;
+ ULONG foundIndex;
+ PPH_STRING newDisabled;
+
+ disabled = PhGetStringSetting(L"DisabledPlugins");
+
+ found = PhpLocateDisabledPlugin(disabled, BaseName, &foundIndex);
+
+ if (Disable && !found)
+ {
+ // We need to add the plugin to the disabled list.
+
+ if (disabled->Length != 0)
+ {
+ // We have other disabled plugins. Append a pipe character followed by the plugin name.
+ newDisabled = PhCreateStringEx(NULL, disabled->Length + sizeof(WCHAR) + BaseName->Length);
+ memcpy(newDisabled->Buffer, disabled->Buffer, disabled->Length);
+ newDisabled->Buffer[disabled->Length / 2] = '|';
+ memcpy(&newDisabled->Buffer[disabled->Length / 2 + 1], BaseName->Buffer, BaseName->Length);
+ PhSetStringSetting2(L"DisabledPlugins", &newDisabled->sr);
+ PhDereferenceObject(newDisabled);
+ }
+ else
+ {
+ // This is the first disabled plugin.
+ PhSetStringSetting2(L"DisabledPlugins", BaseName);
+ }
+ }
+ else if (!Disable && found)
+ {
+ ULONG removeCount;
+
+ // We need to remove the plugin from the disabled list.
+
+ removeCount = (ULONG)BaseName->Length / 2;
+
+ if (foundIndex + (ULONG)BaseName->Length / 2 < (ULONG)disabled->Length / 2)
+ {
+ // Remove the following pipe character as well.
+ removeCount++;
+ }
+ else if (foundIndex != 0)
+ {
+ // Remove the preceding pipe character as well.
+ foundIndex--;
+ removeCount++;
+ }
+
+ newDisabled = PhCreateStringEx(NULL, disabled->Length - removeCount * sizeof(WCHAR));
+ memcpy(newDisabled->Buffer, disabled->Buffer, foundIndex * sizeof(WCHAR));
+ memcpy(&newDisabled->Buffer[foundIndex], &disabled->Buffer[foundIndex + removeCount],
+ disabled->Length - removeCount * sizeof(WCHAR) - foundIndex * sizeof(WCHAR));
+ PhSetStringSetting2(L"DisabledPlugins", &newDisabled->sr);
+ PhDereferenceObject(newDisabled);
+ }
+
+ PhDereferenceObject(disabled);
+}
+
+
+PPHAPP_PLUGIN PhCreateDisabledPlugin(
+ _In_ PPH_STRINGREF BaseName
+ )
+{
+ PPHAPP_PLUGIN plugin;
+
+ plugin = PhAllocate(sizeof(PHAPP_PLUGIN));
+ memset(plugin, 0, sizeof(PHAPP_PLUGIN));
+
+ plugin->Name.Length = BaseName->Length;
+ plugin->Name.Buffer = PhAllocate(BaseName->Length + sizeof(WCHAR));
+ memcpy(plugin->Name.Buffer, BaseName->Buffer, BaseName->Length);
+ plugin->Name.Buffer[BaseName->Length / 2] = 0;
+
+ return plugin;
+}
+
diff --git a/plugins-extra/ExtraPlugins/resource.h b/plugins-extra/ExtraPlugins/resource.h
new file mode 100644
index 0000000..301cf1e
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/resource.h
@@ -0,0 +1,38 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ExtraPlugins.rc
+//
+#define IDD_PLUGINS_DIALOG 102
+#define IDB_SEARCH_ACTIVE_BMP 105
+#define IDB_SEARCH_ACTIVE 106
+#define IDB_SEARCH_INACTIVE_BMP 107
+#define IDB_SEARCH_INACTIVE 108
+#define IDD_DIALOG1 111
+#define IDD_DISABLED_DIALOG 111
+#define IDB_SETTINGS 113
+#define IDB_SETTINGS_PNG 113
+#define IDC_PLUGINTREE 1001
+#define IDC_INSTALLED 1036
+#define IDC_BROWSE 1037
+#define IDC_UPDATES 1038
+#define IDC_DISABLED 1039
+#define IDC_LIST_DISABLED 1046
+#define IDC_CLEANUP 1057
+#define ID_MENU_INSTALL 4059
+#define ID_MENU_UNINSTALL 40011
+#define ID_MENU_DISABLE 40012
+#define ID_MENU_PROPERTIES 40013
+#define ID_MENU_UNLOAD 40014
+#define IDC_INSTRUCTION 40025
+#define IDC_SEARCHBOX 40026
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40028
+#define _APS_NEXT_CONTROL_VALUE 1047
+#define _APS_NEXT_SYMED_VALUE 104
+#endif
+#endif
diff --git a/plugins-extra/ExtraPlugins/resources/active_search.bmp b/plugins-extra/ExtraPlugins/resources/active_search.bmp
new file mode 100644
index 0000000..61b13de
Binary files /dev/null and b/plugins-extra/ExtraPlugins/resources/active_search.bmp differ
diff --git a/plugins-extra/ExtraPlugins/resources/active_search.png b/plugins-extra/ExtraPlugins/resources/active_search.png
new file mode 100644
index 0000000..1cf2957
Binary files /dev/null and b/plugins-extra/ExtraPlugins/resources/active_search.png differ
diff --git a/plugins-extra/ExtraPlugins/resources/cog_edit_modern.png b/plugins-extra/ExtraPlugins/resources/cog_edit_modern.png
new file mode 100644
index 0000000..8cf8e4d
Binary files /dev/null and b/plugins-extra/ExtraPlugins/resources/cog_edit_modern.png differ
diff --git a/plugins-extra/ExtraPlugins/resources/inactive_search.bmp b/plugins-extra/ExtraPlugins/resources/inactive_search.bmp
new file mode 100644
index 0000000..cf19cb8
Binary files /dev/null and b/plugins-extra/ExtraPlugins/resources/inactive_search.bmp differ
diff --git a/plugins-extra/ExtraPlugins/resources/inactive_search.png b/plugins-extra/ExtraPlugins/resources/inactive_search.png
new file mode 100644
index 0000000..29eaa91
Binary files /dev/null and b/plugins-extra/ExtraPlugins/resources/inactive_search.png differ
diff --git a/plugins-extra/ExtraPlugins/searchbox.c b/plugins-extra/ExtraPlugins/searchbox.c
new file mode 100644
index 0000000..0f39237
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/searchbox.c
@@ -0,0 +1,666 @@
+/*/*
+ * Process Hacker -
+ * Subclassed Edit control
+ *
+ * Copyright (C) 2012-2016 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 "main.h"
+#include
+#include
+#include
+
+VOID NcAreaFreeTheme(
+ _Inout_ PEDIT_CONTEXT Context
+ )
+{
+ if (Context->BrushNormal)
+ DeleteObject(Context->BrushNormal);
+
+ if (Context->BrushHot)
+ DeleteObject(Context->BrushHot);
+
+ if (Context->BrushPushed)
+ DeleteObject(Context->BrushPushed);
+}
+
+VOID NcAreaInitializeFont(
+ _Inout_ PEDIT_CONTEXT Context
+ )
+{
+ LOGFONT logFont;
+
+ if (Context->WindowFont)
+ DeleteObject(Context->WindowFont);
+
+ if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logFont, 0))
+ {
+ Context->WindowFont = CreateFont(
+ -PhMultiplyDivideSigned(-14, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_MEDIUM,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+
+ SendMessage(Context->WindowHandle, WM_SETFONT, (WPARAM)Context->WindowFont, TRUE);
+ }
+}
+
+VOID NcAreaInitializeTheme(
+ _Inout_ PEDIT_CONTEXT Context
+)
+{
+ Context->CXWidth = PhMultiplyDivide(20, PhGlobalDpi, 96);
+ Context->BrushNormal = GetSysColorBrush(COLOR_WINDOW);
+ Context->BrushHot = CreateSolidBrush(RGB(205, 232, 255));
+ Context->BrushPushed = CreateSolidBrush(RGB(153, 209, 255));
+
+ if (IsThemeActive())
+ {
+ HTHEME themeDataHandle;
+
+ if (themeDataHandle = OpenThemeData(Context->WindowHandle, VSCLASS_EDIT))
+ {
+ //IsThemePartDefined_I(themeDataHandle, EP_EDITBORDER_NOSCROLL, EPSHV_NORMAL);
+
+ if (!SUCCEEDED(GetThemeInt(
+ themeDataHandle,
+ EP_EDITBORDER_NOSCROLL,
+ EPSHV_NORMAL,
+ TMT_BORDERSIZE,
+ &Context->CXBorder
+ )))
+ {
+ Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
+ }
+
+ CloseThemeData(themeDataHandle);
+ }
+ else
+ {
+ Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
+ }
+ }
+ else
+ {
+ Context->CXBorder = GetSystemMetrics(SM_CXBORDER) * 2;
+ }
+}
+
+VOID NcAreaInitializeImageList(
+ _Inout_ PEDIT_CONTEXT Context
+)
+{
+ HBITMAP bitmapActive;
+ HBITMAP bitmapInactive;
+
+ Context->ImageWidth = GetSystemMetrics(SM_CXSMICON) + 4;
+ Context->ImageHeight = GetSystemMetrics(SM_CYSMICON) + 4;
+ Context->ImageList = ImageList_Create(16, 16, ILC_COLOR32, 2, 2);
+ ImageList_SetImageCount(Context->ImageList, 2);
+
+ if (bitmapActive = LoadImageFromResources(Context->ImageWidth, Context->ImageHeight, MAKEINTRESOURCE(IDB_SEARCH_ACTIVE), TRUE))
+ {
+ ImageList_Replace(Context->ImageList, 0, bitmapActive, NULL);
+ DeleteObject(bitmapActive);
+ }
+ else
+ {
+ PhSetImageListBitmap(Context->ImageList, 0, PluginInstance->DllBase, MAKEINTRESOURCE(IDB_SEARCH_ACTIVE_BMP));
+ }
+
+ if (bitmapInactive = LoadImageFromResources(Context->ImageWidth, Context->ImageHeight, MAKEINTRESOURCE(IDB_SEARCH_INACTIVE), TRUE))
+ {
+ ImageList_Replace(Context->ImageList, 1, bitmapInactive, NULL);
+ DeleteObject(bitmapInactive);
+ }
+ else
+ {
+ PhSetImageListBitmap(Context->ImageList, 1, PluginInstance->DllBase, MAKEINTRESOURCE(IDB_SEARCH_INACTIVE_BMP));
+ }
+}
+
+VOID NcAreaGetButtonRect(
+ _Inout_ PEDIT_CONTEXT Context,
+ _Inout_ PRECT ButtonRect
+)
+{
+ ButtonRect->left = (ButtonRect->right - Context->CXWidth) - Context->CXBorder - 1; // offset left border by 1
+ ButtonRect->bottom -= Context->CXBorder;
+ ButtonRect->right -= Context->CXBorder;
+ ButtonRect->top += Context->CXBorder;
+}
+
+VOID NcAreaDrawButton(
+ _Inout_ PEDIT_CONTEXT Context,
+ _In_ RECT ButtonRect
+ )
+{
+ HDC hdc;
+ HDC bufferDc;
+ HBITMAP bufferBitmap;
+ HBITMAP oldBufferBitmap;
+ RECT bufferRect =
+ {
+ 0, 0,
+ ButtonRect.right - ButtonRect.left,
+ ButtonRect.bottom - ButtonRect.top
+ };
+
+ if (!(hdc = GetWindowDC(Context->WindowHandle)))
+ return;
+
+ bufferDc = CreateCompatibleDC(hdc);
+ bufferBitmap = CreateCompatibleBitmap(hdc, bufferRect.right, bufferRect.bottom);
+ oldBufferBitmap = SelectObject(bufferDc, bufferBitmap);
+
+ if (Context->Pushed)
+ {
+ FillRect(bufferDc, &bufferRect, Context->BrushPushed);
+ //FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(0xff, 0, 0)));
+ }
+ else if (Context->Hot)
+ {
+ FillRect(bufferDc, &bufferRect, Context->BrushHot);
+ //FrameRect(bufferDc, &bufferRect, CreateSolidBrush(RGB(38, 160, 218)));
+ }
+ else
+ {
+ FillRect(bufferDc, &bufferRect, Context->BrushNormal);
+ }
+
+ if (Edit_GetTextLength(Context->WindowHandle) > 0)
+ {
+ ImageList_Draw(
+ Context->ImageList,
+ 0,
+ bufferDc,
+ bufferRect.left + ((bufferRect.right - bufferRect.left) - Context->ImageWidth) / 2 + 1, // offset by one
+ bufferRect.top + ((bufferRect.bottom - bufferRect.top) - Context->ImageHeight) / 2 + 1, // offset by one
+ ILD_NORMAL | ILD_TRANSPARENT
+ );
+ }
+ else
+ {
+ ImageList_Draw(
+ Context->ImageList,
+ 1,
+ bufferDc,
+ bufferRect.left + ((bufferRect.right - bufferRect.left) - (Context->ImageWidth - 2)) / 2, // offset by one
+ bufferRect.top + ((bufferRect.bottom - bufferRect.top) - (Context->ImageHeight - 2)) / 2 + 1, // offset by one
+ ILD_NORMAL | ILD_TRANSPARENT
+ );
+ }
+
+ BitBlt(hdc, ButtonRect.left, ButtonRect.top, ButtonRect.right, ButtonRect.bottom, bufferDc, 0, 0, SRCCOPY);
+ SelectObject(bufferDc, oldBufferBitmap);
+ DeleteObject(bufferBitmap);
+ DeleteDC(bufferDc);
+
+ ReleaseDC(Context->WindowHandle, hdc);
+}
+
+LRESULT CALLBACK NcAreaWndSubclassProc(
+ _In_ HWND hWnd,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ UINT_PTR uIdSubclass,
+ _In_ ULONG_PTR dwRefData
+)
+{
+ PEDIT_CONTEXT context;
+
+ context = (PEDIT_CONTEXT)GetProp(hWnd, L"SearchBoxContext");
+
+ switch (uMsg)
+ {
+ case WM_NCDESTROY:
+ {
+ NcAreaFreeTheme(context);
+
+ if (context->ImageList)
+ ImageList_Destroy(context->ImageList);
+
+ if (context->WindowFont)
+ DeleteObject(context->WindowFont);
+
+ RemoveWindowSubclass(hWnd, NcAreaWndSubclassProc, uIdSubclass);
+ RemoveProp(hWnd, L"SearchBoxContext");
+ PhFree(context);
+ }
+ break;
+ case WM_ERASEBKGND:
+ return 1;
+ case WM_NCCALCSIZE:
+ {
+ LPNCCALCSIZE_PARAMS ncCalcSize = (NCCALCSIZE_PARAMS*)lParam;
+
+ // Let Windows handle the non-client defaults.
+ DefSubclassProc(hWnd, uMsg, wParam, lParam);
+
+ // Deflate the client area to accommodate the custom button.
+ ncCalcSize->rgrc[0].right -= context->CXWidth;
+ }
+ return 0;
+ case WM_NCPAINT:
+ {
+ RECT windowRect;
+
+ // Let Windows handle the non-client defaults.
+ DefSubclassProc(hWnd, uMsg, wParam, lParam);
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Adjust the coordinates (start from 0,0).
+ OffsetRect(&windowRect, -windowRect.left, -windowRect.top);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Draw the button.
+ NcAreaDrawButton(context, windowRect);
+ }
+ return 0;
+ case WM_NCHITTEST:
+ {
+ POINT windowPoint;
+ RECT windowRect;
+
+ // Get the screen coordinates of the mouse.
+ if (!GetCursorPos(&windowPoint))
+ break;
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Check that the mouse is within the inserted button.
+ if (PtInRect(&windowRect, windowPoint))
+ {
+ return HTBORDER;
+ }
+ }
+ break;
+ case WM_NCLBUTTONDOWN:
+ {
+ POINT windowPoint;
+ RECT windowRect;
+
+ // Get the screen coordinates of the mouse.
+ if (!GetCursorPos(&windowPoint))
+ break;
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Check that the mouse is within the inserted button.
+ if (PtInRect(&windowRect, windowPoint))
+ {
+ context->Pushed = TRUE;
+
+ SetCapture(hWnd);
+
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ }
+ }
+ break;
+ case WM_LBUTTONUP:
+ {
+ POINT windowPoint;
+ RECT windowRect;
+
+ // Get the screen coordinates of the mouse.
+ if (!GetCursorPos(&windowPoint))
+ break;
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Check that the mouse is within the inserted button.
+ if (PtInRect(&windowRect, windowPoint))
+ {
+ // Forward click notification.
+ SendMessage(GetParent(context->WindowHandle), WM_COMMAND, MAKEWPARAM(context->CommandID, BN_CLICKED), 0);
+ }
+
+ if (GetCapture() == hWnd)
+ {
+ context->Pushed = FALSE;
+ ReleaseCapture();
+ }
+
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ }
+ break;
+ case WM_CUT:
+ case WM_CLEAR:
+ case WM_PASTE:
+ case WM_UNDO:
+ case WM_KEYUP:
+ case WM_SETTEXT:
+ case WM_KILLFOCUS:
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ break;
+ case WM_SETTINGCHANGE:
+ case WM_SYSCOLORCHANGE:
+ case WM_THEMECHANGED:
+ {
+ NcAreaFreeTheme(context);
+ NcAreaInitializeTheme(context);
+ NcAreaInitializeFont(context);
+
+ // Reset the client area margins.
+ SendMessage(hWnd, EM_SETMARGINS, EC_LEFTMARGIN, MAKELPARAM(0, 0));
+
+ // Refresh the non-client area.
+ SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
+
+ // Force the edit control to update its non-client area.
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ }
+ break;
+ case WM_NCMOUSEMOVE:
+ {
+ POINT windowPoint;
+ RECT windowRect;
+
+ // Get the screen coordinates of the mouse.
+ if (!GetCursorPos(&windowPoint))
+ break;
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Check that the mouse is within the inserted button.
+ if (PtInRect(&windowRect, windowPoint) && !context->Hot)
+ {
+ TRACKMOUSEEVENT trackMouseEvent;
+
+ trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
+ trackMouseEvent.dwFlags = TME_LEAVE | TME_NONCLIENT;
+ trackMouseEvent.hwndTrack = hWnd;
+ trackMouseEvent.dwHoverTime = 0;
+
+ context->Hot = TRUE;
+
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+
+ TrackMouseEvent(&trackMouseEvent);
+ }
+ }
+ break;
+ case WM_NCMOUSELEAVE:
+ {
+ if (context->Hot)
+ {
+ context->Hot = FALSE;
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ }
+ }
+ break;
+ case WM_MOUSEMOVE:
+ {
+ if ((wParam & MK_LBUTTON) && GetCapture() == hWnd)
+ {
+ POINT windowPoint;
+ RECT windowRect;
+
+ // Get the screen coordinates of the mouse.
+ if (!GetCursorPos(&windowPoint))
+ break;
+
+ // Get the screen coordinates of the window.
+ GetWindowRect(hWnd, &windowRect);
+
+ // Get the position of the inserted button.
+ NcAreaGetButtonRect(context, &windowRect);
+
+ // Check that the mouse is within the inserted button.
+ context->Pushed = PtInRect(&windowRect, windowPoint);
+
+ RedrawWindow(hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+ }
+ }
+ break;
+ }
+
+ return DefSubclassProc(hWnd, uMsg, wParam, lParam);
+}
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PCWSTR Name,
+ _In_ BOOLEAN RGBAImage
+)
+{
+ UINT frameCount = 0;
+ BOOLEAN success = FALSE;
+ ULONG resourceLength = 0;
+ HGLOBAL resourceHandle = NULL;
+ HRSRC resourceHandleSource = NULL;
+ WICInProcPointer resourceBuffer = NULL;
+ HDC screenHdc = NULL;
+ HDC bufferDc = NULL;
+ BITMAPINFO bitmapInfo = { 0 };
+ HBITMAP bitmapHandle = NULL;
+ PBYTE bitmapBuffer = NULL;
+ IWICStream* wicStream = NULL;
+ IWICBitmapSource* wicBitmapSource = NULL;
+ IWICBitmapDecoder* wicDecoder = NULL;
+ IWICBitmapFrameDecode* wicFrame = NULL;
+ IWICImagingFactory* wicFactory = NULL;
+ IWICBitmapScaler* wicScaler = NULL;
+ WICPixelFormatGUID pixelFormat;
+ WICRect rect = { 0, 0, Width, Height };
+
+ // Create the ImagingFactory
+ if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory)))
+ goto CleanupExit;
+
+ if ((resourceHandleSource = FindResource(PluginInstance->DllBase, Name, L"PNG")) == NULL)
+ goto CleanupExit;
+
+ resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource);
+
+ if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL)
+ goto CleanupExit;
+
+ if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL)
+ goto CleanupExit;
+
+ if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream)))
+ goto CleanupExit;
+
+ if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength)))
+ goto CleanupExit;
+
+ if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder)))
+ goto CleanupExit;
+
+ if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad)))
+ goto CleanupExit;
+
+ if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1)
+ goto CleanupExit;
+
+ if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame)))
+ goto CleanupExit;
+
+ if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat)))
+ goto CleanupExit;
+
+ // Check if the image format is supported
+ if (IsEqualGUID(&pixelFormat, RGBAImage ? &GUID_WICPixelFormat32bppPRGBA : &GUID_WICPixelFormat32bppPBGRA))
+ {
+ wicBitmapSource = (IWICBitmapSource*)wicFrame;
+ }
+ else
+ {
+ IWICFormatConverter* wicFormatConverter = NULL;
+
+ if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter)))
+ goto CleanupExit;
+
+ if (FAILED(IWICFormatConverter_Initialize(
+ wicFormatConverter,
+ (IWICBitmapSource*)wicFrame,
+ RGBAImage ? &GUID_WICPixelFormat32bppPRGBA : &GUID_WICPixelFormat32bppPBGRA,
+ WICBitmapDitherTypeNone,
+ NULL,
+ 0.0,
+ WICBitmapPaletteTypeCustom
+ )))
+ {
+ IWICFormatConverter_Release(wicFormatConverter);
+ goto CleanupExit;
+ }
+
+ // Convert the image to the correct format
+ IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource);
+ IWICFormatConverter_Release(wicFormatConverter);
+
+ // Dispose the old frame now that the converted frame is in wicBitmapSource
+ IWICBitmapFrameDecode_Release(wicFrame);
+ }
+
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = rect.Width;
+ bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height);
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ screenHdc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
+ bufferDc = CreateCompatibleDC(screenHdc);
+ bitmapHandle = CreateDIBSection(screenHdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
+
+ // Check if it's the same rect as the requested size.
+ //if (width != rect.Width || height != rect.Height)
+ if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler)))
+ goto CleanupExit;
+ if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant)))
+ goto CleanupExit;
+ if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer)))
+ goto CleanupExit;
+
+ success = TRUE;
+
+CleanupExit:
+
+ // Cleanup resources in the same order they were created.
+ if (wicScaler)
+ {
+ IWICBitmapScaler_Release(wicScaler);
+ }
+
+ if (bufferDc)
+ {
+ DeleteDC(bufferDc);
+ }
+
+ if (screenHdc)
+ {
+ DeleteDC(screenHdc);
+ }
+
+ if (wicBitmapSource)
+ {
+ IWICBitmapSource_Release(wicBitmapSource);
+ }
+
+ if (wicStream)
+ {
+ IWICStream_Release(wicStream);
+ }
+
+ if (wicDecoder)
+ {
+ IWICBitmapDecoder_Release(wicDecoder);
+ }
+
+ if (wicFactory)
+ {
+ IWICImagingFactory_Release(wicFactory);
+ }
+
+ if (resourceHandle)
+ {
+ FreeResource(resourceHandle);
+ }
+
+ if (success)
+ return bitmapHandle;
+
+ DeleteObject(bitmapHandle);
+ return NULL;
+}
+
+VOID CreateSearchControl(
+ _In_ HWND Parent,
+ _In_ HWND WindowHandle,
+ _In_ UINT CommandID
+ )
+{
+ PEDIT_CONTEXT context;
+
+ context = (PEDIT_CONTEXT)PhAllocate(sizeof(EDIT_CONTEXT));
+ memset(context, 0, sizeof(EDIT_CONTEXT));
+
+ context->CommandID = CommandID;
+ context->WindowHandle = WindowHandle;
+
+ //NcAreaInitializeTheme(context);
+ NcAreaInitializeImageList(context);
+
+ // Set initial text
+ Edit_SetCueBannerText(context->WindowHandle, L"Search Plugins (Ctrl+K)");
+
+ // Set our window context data.
+ SetProp(context->WindowHandle, L"SearchBoxContext", (HANDLE)context);
+
+ // Subclass the Edit control window procedure.
+ SetWindowSubclass(context->WindowHandle, NcAreaWndSubclassProc, 0, (ULONG_PTR)context);
+
+ // Initialize the theme parameters.
+ SendMessage(context->WindowHandle, WM_THEMECHANGED, 0, 0);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/page1.c b/plugins-extra/ExtraPlugins/setup/page1.c
new file mode 100644
index 0000000..e84f162
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/page1.c
@@ -0,0 +1,82 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2016 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 "..\main.h"
+
+static TASKDIALOG_BUTTON TaskDialogButtonArray[] =
+{
+ { IDOK, L"Install" }
+};
+
+HRESULT CALLBACK CheckForUpdatesCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ break;
+ case TDN_BUTTON_CLICKED:
+ {
+ if ((INT)wParam == IDOK)
+ {
+ ShowCheckingForUpdatesDialog(context);
+ return S_FALSE;
+ }
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowCheckForUpdatesDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_ENABLE_HYPERLINKS;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker";
+ config.pszMainInstruction = L"Install ABC??";
+ //config.pszContent = L"The updater will check for new Process Hacker releases and optionally download and install the update.\r\n\r\nClick the check for updates button to continue.";
+ config.pszContent = L"Name: ToolStatus.dll\r\nName: ToolStatus.dll\r\nName: ToolStatus.dll\r\nName: ToolStatus.dll\r\n\r\nClick the check for updates button to continue.";
+
+ config.cxWidth = 200;
+ config.pButtons = TaskDialogButtonArray;
+ config.cButtons = ARRAYSIZE(TaskDialogButtonArray);
+ config.pfCallback = CheckForUpdatesCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/page2.c b/plugins-extra/ExtraPlugins/setup/page2.c
new file mode 100644
index 0000000..69a1293
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/page2.c
@@ -0,0 +1,71 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2016 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 "..\main.h"
+
+HRESULT CALLBACK CheckingForUpdatesCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ {
+ SendMessage(hwndDlg, TDM_SET_MARQUEE_PROGRESS_BAR, TRUE, 0);
+ SendMessage(hwndDlg, TDM_SET_PROGRESS_BAR_MARQUEE, TRUE, 1);
+
+ //PhQueueItemWorkQueue(PhGetGlobalWorkQueue(), UpdateCheckThread, context);
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowCheckingForUpdatesDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_MARQUEE_PROGRESS_BAR;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker";
+ //config.pszMainInstruction = L"Installing ToolStatus plugin";
+ config.pszContent = L"Checking plugin signature...";
+
+ config.cxWidth = 200;
+ config.pfCallback = CheckingForUpdatesCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/page3.c b/plugins-extra/ExtraPlugins/setup/page3.c
new file mode 100644
index 0000000..f50b7a1
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/page3.c
@@ -0,0 +1,100 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2016 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 "..\main.h"
+
+static TASKDIALOG_BUTTON TaskDialogButtonArray[] =
+{
+ { IDOK, L"Download" }
+};
+
+HRESULT CALLBACK ShowAvailableCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ break;
+ case TDN_BUTTON_CLICKED:
+ {
+ if ((INT)wParam == IDOK)
+ {
+ //if (UpdaterInstalledUsingSetup())
+ {
+ ShowProgressDialog(context);
+ return S_FALSE;
+ }
+ //else
+ {
+ //PhShellExecute(hwndDlg, L"https://wj32.org/processhacker/downloads.php", NULL);
+ }
+ }
+ }
+ break;
+ case TDN_HYPERLINK_CLICKED:
+ {
+ //TaskDialogLinkClicked(context);
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowAvailableDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED | TDF_ENABLE_HYPERLINKS | TDF_SHOW_PROGRESS_BAR;
+ config.dwCommonButtons = TDCBF_CANCEL_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = PhIsNullOrEmptyString(Context->Node->Name) ? PhGetStringOrEmpty(Context->Node->InternalName) : PhGetStringOrEmpty(Context->Node->Name);
+ config.pszContent = PhaFormatString(L"%s\r\n\r\nAuthor: %s\r\nVersion: %s\r\nUpdated: %s",
+ PhGetStringOrEmpty(Context->Node->Description),
+ PhGetStringOrEmpty(Context->Node->Author),
+ PhGetStringOrEmpty(Context->Node->Version),
+ PhGetStringOrEmpty(Context->Node->UpdatedTime)
+ )->Buffer;
+ //config.pszExpandedInformation = L"View Changelog";
+
+ config.cxWidth = 200;
+ config.pButtons = TaskDialogButtonArray;
+ config.cButtons = ARRAYSIZE(TaskDialogButtonArray);
+
+ config.lpCallbackData = (LONG_PTR)Context;
+ config.pfCallback = ShowAvailableCallbackProc;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/page4.c b/plugins-extra/ExtraPlugins/setup/page4.c
new file mode 100644
index 0000000..566019d
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/page4.c
@@ -0,0 +1,77 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2016 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 "..\main.h"
+
+HRESULT CALLBACK ShowProgressCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ {
+ SendMessage(hwndDlg, TDM_SET_MARQUEE_PROGRESS_BAR, TRUE, 0);
+ SendMessage(hwndDlg, TDM_SET_PROGRESS_BAR_MARQUEE, TRUE, 1);
+
+ PhQueueItemWorkQueue(PhGetGlobalWorkQueue(), UpdateDownloadThread, context);
+ }
+ break;
+ case TDN_HYPERLINK_CLICKED:
+ {
+ TaskDialogLinkClicked(context);
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowProgressDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED | TDF_ENABLE_HYPERLINKS | TDF_SHOW_PROGRESS_BAR;
+ config.dwCommonButtons = TDCBF_CANCEL_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = L"Downloading 0.0.0.0...";
+ config.pszContent = L"Downloaded: ~ of ~ (0%)\r\nSpeed: ~ KB/s";
+ //config.pszExpandedInformation = L"View Changelog";
+
+ config.cxWidth = 200;
+ config.lpCallbackData = (LONG_PTR)Context;
+ config.pfCallback = ShowProgressCallbackProc;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/page5.c b/plugins-extra/ExtraPlugins/setup/page5.c
new file mode 100644
index 0000000..ab36e49
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/page5.c
@@ -0,0 +1,227 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2016 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 "..\main.h"
+#include
+#include
+
+static TASKDIALOG_BUTTON TaskDialogButtonArray[] =
+{
+ { IDYES, L"Restart" }
+};
+
+HRESULT CALLBACK RestartTaskDialogCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_BUTTON_CLICKED:
+ {
+ if ((INT)wParam == IDYES)
+ {
+ SHELLEXECUTEINFO info = { sizeof(SHELLEXECUTEINFO) };
+
+ /* if (PhIsNullOrEmptyString(context->SetupFilePath))
+ break;*/
+
+ info.lpFile = L"ProcessHacker.exe";
+ info.nShow = SW_SHOW;
+ info.hwnd = hwndDlg;
+ //info.lpParameters = L"-plugin dmex.ExtraPlugins:INSTALL -plugin dmex.ExtraPlugins:hex64value";
+
+ ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle);
+
+ if (ShellExecuteEx(&info))
+ {
+ NtTerminateProcess(NtCurrentProcess(), STATUS_SUCCESS);
+ }
+ else
+ {
+ // Install failed, cancel the shutdown
+ ProcessHacker_CancelEarlyShutdown(PhMainWndHandle);
+ // Set button text for next action
+ //Button_SetText(GetDlgItem(hwndDlg, IDOK), L"Retry");
+ return S_FALSE;
+ }
+ }
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+HRESULT CALLBACK FinalTaskDialogCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ {
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ SendMessage(hwndDlg, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, IDYES, TRUE);
+ }
+ }
+ break;
+ case TDN_BUTTON_CLICKED:
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowInstallRestartDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = L"Process Hacker needs to restart";
+ config.pszContent = L"Changes may require a restart to take effect...";
+
+ config.pButtons = TaskDialogButtonArray;
+ config.cButtons = ARRAYSIZE(TaskDialogButtonArray);
+
+ config.cxWidth = 200;
+ config.pfCallback = RestartTaskDialogCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
+
+VOID ShowUninstallRestartDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = L"Process Hacker needs to restart";
+ config.pszContent = L"Changes may require a restart to take effect...";
+
+ config.pButtons = TaskDialogButtonArray;
+ config.cButtons = ARRAYSIZE(TaskDialogButtonArray);
+
+ config.cxWidth = 200;
+ config.pfCallback = RestartTaskDialogCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
+
+VOID ShowLatestVersionDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ PPH_UPDATER_CONTEXT context;
+ TASKDIALOGCONFIG config;
+
+ context = (PPH_UPDATER_CONTEXT)Context;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED | TDF_ENABLE_HYPERLINKS;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = L"You're running the latest version.";
+ //config.pszContent = PhaFormatString(
+ // L"Stable release build: v%lu.%lu.%lu\r\n\r\nView Changelog",
+ // context->CurrentMajorVersion,
+ // context->CurrentMinorVersion,
+ // context->CurrentRevisionVersion
+ // )->Buffer;
+
+ config.cxWidth = 200;
+ config.pfCallback = FinalTaskDialogCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
+
+
+VOID ShowUpdateFailedDialog(
+ _In_ PPH_UPDATER_CONTEXT Context,
+ _In_ BOOLEAN HashFailed,
+ _In_ BOOLEAN SignatureFailed
+ )
+{
+ TASKDIALOGCONFIG config;
+
+ memset(&config, 0, sizeof(TASKDIALOGCONFIG));
+ config.cbSize = sizeof(TASKDIALOGCONFIG);
+ //config.pszMainIcon = MAKEINTRESOURCE(65529);
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON | TDCBF_RETRY_BUTTON;
+ config.hMainIcon = Context->IconLargeHandle;
+
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = L"Error downloading plugin files.";
+
+ if (SignatureFailed)
+ {
+ config.pszContent = L"Signature check failed. Click Retry to download the plugin again.";
+ }
+ else if (HashFailed)
+ {
+ config.pszContent = L"Hash check failed. Click Retry to download the plugin again.";
+ }
+ else
+ {
+ config.pszContent = L"Click Retry to download the plugin again.";
+ }
+
+ config.cxWidth = 200;
+ config.pfCallback = FinalTaskDialogCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/uninstall.c b/plugins-extra/ExtraPlugins/setup/uninstall.c
new file mode 100644
index 0000000..e7f9231
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/uninstall.c
@@ -0,0 +1,81 @@
+#include "..\main.h"
+#include
+#include
+
+static TASKDIALOG_BUTTON TaskDialogButtonArray[] =
+{
+ { IDYES, L"Uninstall" }
+};
+
+HRESULT CALLBACK TaskDialogUninstallCallbackProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_NAVIGATED:
+ {
+ //PhQueueItemWorkQueue(PhGetGlobalWorkQueue(), SetupExtractBuild, context);
+ }
+ break;
+ case TDN_BUTTON_CLICKED:
+ {
+ if ((INT)wParam == IDYES)
+ {
+ PPH_STRING baseNameString;
+ PPH_STRING fileNameString;
+ PPH_STRING bakNameString;
+
+ context->Node->State = PLUGIN_STATE_RESTART;
+
+ fileNameString = PhGetFileName(context->Node->FilePath);
+ baseNameString = PhGetBaseName(context->Node->FilePath);
+ bakNameString = PhConcatStrings(2, PhGetString(fileNameString), L".bak");
+
+ if (RtlDoesFileExists_U(PhGetString(fileNameString)))
+ {
+ MoveFileEx(PhGetString(fileNameString), PhGetString(bakNameString), MOVEFILE_REPLACE_EXISTING);
+ }
+
+ PhDereferenceObject(bakNameString);
+ PhDereferenceObject(baseNameString);
+ PhDereferenceObject(fileNameString);
+
+ PostMessage(context->DialogHandle, PH_UPDATENEWER, 0, 0);
+ return S_FALSE;
+ }
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+VOID ShowPluginUninstallDialog(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ PPH_UPDATER_CONTEXT context;
+ TASKDIALOGCONFIG config = { sizeof(TASKDIALOGCONFIG) };
+
+ context = (PPH_UPDATER_CONTEXT)Context;
+
+ config.cxWidth = 200;
+ config.pszWindowTitle = L"Process Hacker - Plugin Manager";
+ config.pszMainInstruction = PhaFormatString(L"Uninstall %s?", PhIsNullOrEmptyString(Context->Node->Name) ? PhGetStringOrEmpty(Context->Node->InternalName) : PhGetStringOrEmpty(Context->Node->Name))->Buffer;
+ config.dwFlags = TDF_USE_HICON_MAIN | TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED;
+ config.dwCommonButtons = TDCBF_CLOSE_BUTTON;
+ config.hMainIcon = context->IconLargeHandle;
+ config.pfCallback = TaskDialogUninstallCallbackProc;
+ config.lpCallbackData = (LONG_PTR)Context;
+ config.pButtons = TaskDialogButtonArray;
+ config.cButtons = ARRAYSIZE(TaskDialogButtonArray);
+
+ SendMessage(Context->DialogHandle, TDM_NAVIGATE_PAGE, 0, (LPARAM)&config);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/updater.c b/plugins-extra/ExtraPlugins/setup/updater.c
new file mode 100644
index 0000000..27befa8
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/updater.c
@@ -0,0 +1,1090 @@
+/*
+ * Process Hacker Plugins -
+ * Update Checker Plugin
+ *
+ * Copyright (C) 2011-2016 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 "..\main.h"
+#include
+
+PPH_UPDATER_CONTEXT CreateUpdateContext(
+ _In_ PPLUGIN_NODE Node,
+ _In_ PLUGIN_ACTION Action
+ )
+{
+ PPH_UPDATER_CONTEXT context;
+
+ context = (PPH_UPDATER_CONTEXT)PhCreateAlloc(sizeof(PH_UPDATER_CONTEXT));
+ memset(context, 0, sizeof(PH_UPDATER_CONTEXT));
+
+ context->Action = Action;
+ context->Node = Node;
+
+ return context;
+}
+
+VOID FreeUpdateContext(
+ _In_ _Post_invalid_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ //PhClearReference(&Context->Version);
+ PhClearReference(&Context->RevVersion);
+ //PhClearReference(&Context->RelDate);
+ PhClearReference(&Context->Size);
+ //PhClearReference(&Context->Signature);
+ //PhClearReference(&Context->ReleaseNotesUrl);
+ PhClearReference(&Context->SetupFilePath);
+ PhClearReference(&Context->FileDownloadUrl);
+
+ PhDereferenceObject(Context);
+}
+
+VOID TaskDialogCreateIcons(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ // Load the Process Hacker window icon
+ Context->IconLargeHandle = (HICON)LoadImage(
+ NtCurrentPeb()->ImageBaseAddress,
+ MAKEINTRESOURCE(PHAPP_IDI_PROCESSHACKER),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON),
+ LR_SHARED
+ );
+ Context->IconSmallHandle = (HICON)LoadImage(
+ NtCurrentPeb()->ImageBaseAddress,
+ MAKEINTRESOURCE(PHAPP_IDI_PROCESSHACKER),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ LR_SHARED
+ );
+
+ // Set the TaskDialog window icons
+ SendMessage(Context->DialogHandle, WM_SETICON, ICON_SMALL, (LPARAM)Context->IconSmallHandle);
+ SendMessage(Context->DialogHandle, WM_SETICON, ICON_BIG, (LPARAM)Context->IconLargeHandle);
+}
+
+VOID TaskDialogLinkClicked(
+ _In_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ //if (!PhIsNullOrEmptyString(Context->ReleaseNotesUrl))
+ {
+ // Launch the ReleaseNotes URL (if it exists) with the default browser
+ //PhShellExecute(Context->DialogHandle, Context->ReleaseNotesUrl->Buffer, NULL);
+ }
+}
+
+PPH_STRING UpdaterGetOpaqueXmlNodeText(
+ _In_ mxml_node_t *xmlNode
+ )
+{
+ if (xmlNode && xmlNode->child && xmlNode->child->type == MXML_OPAQUE && xmlNode->child->value.opaque)
+ {
+ return PhConvertUtf8ToUtf16(xmlNode->child->value.opaque);
+ }
+
+ return PhReferenceEmptyString();
+}
+
+BOOLEAN LastUpdateCheckExpired(
+ VOID
+ )
+{
+#ifdef FORCE_UPDATE_CHECK
+ return TRUE;
+#else
+ ULONG64 lastUpdateTimeTicks = 0;
+ LARGE_INTEGER currentUpdateTimeTicks;
+ //PPH_STRING lastUpdateTimeString;
+
+ // Get the last update check time
+ //lastUpdateTimeString = PhGetStringSetting(SETTING_NAME_LAST_CHECK);
+ //PhStringToInteger64(&lastUpdateTimeString->sr, 0, &lastUpdateTimeTicks);
+
+ // Query the current time
+ PhQuerySystemTime(¤tUpdateTimeTicks);
+
+ // Check if the last update check was more than 7 days ago
+ if (currentUpdateTimeTicks.QuadPart - lastUpdateTimeTicks >= 7 * PH_TICKS_PER_DAY)
+ {
+ PPH_STRING currentUpdateTimeString = PhFormatUInt64(currentUpdateTimeTicks.QuadPart, FALSE);
+
+ // Save the current time
+ // PhSetStringSetting2(SETTING_NAME_LAST_CHECK, ¤tUpdateTimeString->sr);
+
+ // Cleanup
+ PhDereferenceObject(currentUpdateTimeString);
+ // P//hDereferenceObject(lastUpdateTimeString);
+ return TRUE;
+ }
+
+ // Cleanup
+ //PhDereferenceObject(lastUpdateTimeString);
+ return FALSE;
+#endif
+}
+
+PPH_STRING UpdateVersionString(
+ VOID
+ )
+{
+ ULONG majorVersion;
+ ULONG minorVersion;
+ ULONG revisionVersion;
+ PPH_STRING currentVersion = NULL;
+ PPH_STRING versionHeader = NULL;
+
+ PhGetPhVersionNumbers(
+ &majorVersion,
+ &minorVersion,
+ NULL,
+ &revisionVersion
+ );
+
+ currentVersion = PhFormatString(
+ L"%lu.%lu.%lu",
+ majorVersion,
+ minorVersion,
+ revisionVersion
+ );
+
+ if (currentVersion)
+ {
+ versionHeader = PhConcatStrings2(L"ProcessHacker-Build: ", currentVersion->Buffer);
+ PhDereferenceObject(currentVersion);
+ }
+
+ return versionHeader;
+}
+
+PPH_STRING UpdateWindowsString(
+ VOID
+ )
+{
+ static PH_STRINGREF keyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows NT\\CurrentVersion");
+
+ HANDLE keyHandle = NULL;
+ PPH_STRING buildLabHeader = NULL;
+
+ if (NT_SUCCESS(PhOpenKey(
+ &keyHandle,
+ KEY_READ,
+ PH_KEY_LOCAL_MACHINE,
+ &keyName,
+ 0
+ )))
+ {
+ PPH_STRING buildLabString;
+
+ if (buildLabString = PhQueryRegistryString(keyHandle, L"BuildLabEx"))
+ {
+ buildLabHeader = PhConcatStrings2(L"ProcessHacker-OsBuild: ", buildLabString->Buffer);
+ PhDereferenceObject(buildLabString);
+ }
+ else if (buildLabString = PhQueryRegistryString(keyHandle, L"BuildLab"))
+ {
+ buildLabHeader = PhConcatStrings2(L"ProcessHacker-OsBuild: ", buildLabString->Buffer);
+ PhDereferenceObject(buildLabString);
+ }
+
+ NtClose(keyHandle);
+ }
+
+ return buildLabHeader;
+}
+
+//BOOLEAN ParseVersionString(
+// _Inout_ PPH_UPDATER_CONTEXT Context
+// )
+//{
+// PH_STRINGREF sr, majorPart, minorPart, revisionPart;
+// ULONG64 majorInteger = 0, minorInteger = 0, revisionInteger = 0;
+//
+// //PhInitializeStringRef(&sr, Context->VersionString->Buffer);
+// PhInitializeStringRef(&revisionPart, Context->RevVersion->Buffer);
+//
+// if (PhSplitStringRefAtChar(&sr, '.', &majorPart, &minorPart))
+// {
+// PhStringToInteger64(&majorPart, 10, &majorInteger);
+// PhStringToInteger64(&minorPart, 10, &minorInteger);
+// PhStringToInteger64(&revisionPart, 10, &revisionInteger);
+//
+// //Context->MajorVersion = (ULONG)majorInteger;
+// //Context->MinorVersion = (ULONG)minorInteger;
+// //Context->RevisionVersion = (ULONG)revisionInteger;
+//
+// return TRUE;
+// }
+//
+// return FALSE;
+//}
+
+BOOLEAN ReadRequestString(
+ _In_ HINTERNET Handle,
+ _Out_ _Deref_post_z_cap_(*DataLength) PSTR *Data,
+ _Out_ ULONG *DataLength
+ )
+{
+ PSTR data;
+ ULONG allocatedLength;
+ ULONG dataLength;
+ ULONG returnLength;
+ BYTE buffer[PAGE_SIZE];
+
+ allocatedLength = sizeof(buffer);
+ data = (PSTR)PhAllocate(allocatedLength);
+ dataLength = 0;
+
+ // Zero the buffer
+ memset(buffer, 0, PAGE_SIZE);
+
+ while (WinHttpReadData(Handle, buffer, PAGE_SIZE, &returnLength))
+ {
+ if (returnLength == 0)
+ break;
+
+ if (allocatedLength < dataLength + returnLength)
+ {
+ allocatedLength *= 2;
+ data = (PSTR)PhReAllocate(data, allocatedLength);
+ }
+
+ // Copy the returned buffer into our pointer
+ memcpy(data + dataLength, buffer, returnLength);
+ // Zero the returned buffer for the next loop
+ //memset(buffer, 0, returnLength);
+
+ dataLength += returnLength;
+ }
+
+ if (allocatedLength < dataLength + 1)
+ {
+ allocatedLength++;
+ data = (PSTR)PhReAllocate(data, allocatedLength);
+ }
+
+ // Ensure that the buffer is null-terminated.
+ data[dataLength] = 0;
+
+ *DataLength = dataLength;
+ *Data = data;
+
+ return TRUE;
+}
+
+BOOLEAN QueryUpdateData(
+ _Inout_ PPH_UPDATER_CONTEXT Context
+ )
+{
+ BOOLEAN isSuccess = FALSE;
+ HINTERNET httpSessionHandle = NULL;
+ HINTERNET httpConnectionHandle = NULL;
+ HINTERNET httpRequestHandle = NULL;
+ WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig = { 0 };
+ mxml_node_t* xmlNode = NULL;
+ ULONG xmlStringBufferLength = 0;
+ PSTR xmlStringBuffer = NULL;
+ PPH_STRING versionHeader = UpdateVersionString();
+ PPH_STRING windowsHeader = UpdateWindowsString();
+
+ // Get the current Process Hacker version
+ //PhGetPhVersionNumbers(
+ // &Context->CurrentMajorVersion,
+ // &Context->CurrentMinorVersion,
+ // NULL,
+ // &Context->CurrentRevisionVersion
+ // );
+
+ __try
+ {
+ // Query the current system proxy
+ WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
+
+ // Open the HTTP session with the system proxy configuration if available
+ if (!(httpSessionHandle = WinHttpOpen(
+ NULL,
+ proxyConfig.lpszProxy != NULL ? WINHTTP_ACCESS_TYPE_NAMED_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ proxyConfig.lpszProxy,
+ proxyConfig.lpszProxyBypass,
+ 0
+ )))
+ {
+ __leave;
+ }
+
+ if (WindowsVersion >= WINDOWS_8_1)
+ {
+ // Enable GZIP and DEFLATE support on Windows 8.1 and above using undocumented flags.
+ ULONG httpFlags = WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE;
+
+ WinHttpSetOption(
+ httpSessionHandle,
+ WINHTTP_OPTION_DECOMPRESSION,
+ &httpFlags,
+ sizeof(ULONG)
+ );
+ }
+
+ if (!(httpConnectionHandle = WinHttpConnect(
+ httpSessionHandle,
+ L"wj32.org",
+ INTERNET_DEFAULT_HTTPS_PORT,
+ 0
+ )))
+ {
+ __leave;
+ }
+
+ if (!(httpRequestHandle = WinHttpOpenRequest(
+ httpConnectionHandle,
+ NULL,
+ L"/processhacker/update.php",
+ NULL,
+ WINHTTP_NO_REFERER,
+ WINHTTP_DEFAULT_ACCEPT_TYPES,
+ WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE
+ )))
+ {
+ __leave;
+ }
+
+ if (WindowsVersion >= WINDOWS_7)
+ {
+ ULONG keepAlive = WINHTTP_DISABLE_KEEP_ALIVE;
+ WinHttpSetOption(httpRequestHandle, WINHTTP_OPTION_DISABLE_FEATURE, &keepAlive, sizeof(ULONG));
+ }
+
+ if (versionHeader)
+ {
+ WinHttpAddRequestHeaders(
+ httpRequestHandle,
+ versionHeader->Buffer,
+ (ULONG)versionHeader->Length / sizeof(WCHAR),
+ WINHTTP_ADDREQ_FLAG_ADD
+ );
+ }
+
+ if (windowsHeader)
+ {
+ WinHttpAddRequestHeaders(
+ httpRequestHandle,
+ windowsHeader->Buffer,
+ (ULONG)windowsHeader->Length / sizeof(WCHAR),
+ WINHTTP_ADDREQ_FLAG_ADD
+ );
+ }
+
+ if (!WinHttpSendRequest(
+ httpRequestHandle,
+ WINHTTP_NO_ADDITIONAL_HEADERS,
+ 0,
+ WINHTTP_NO_REQUEST_DATA,
+ 0,
+ WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
+ 0
+ ))
+ {
+ __leave;
+ }
+
+ if (!WinHttpReceiveResponse(httpRequestHandle, NULL))
+ __leave;
+
+ // Read the resulting xml into our buffer.
+ if (!ReadRequestString(httpRequestHandle, &xmlStringBuffer, &xmlStringBufferLength))
+ __leave;
+
+ // Check the buffer for valid data.
+ if (xmlStringBuffer == NULL || xmlStringBuffer[0] == '\0')
+ __leave;
+
+ // Load our XML
+ xmlNode = mxmlLoadString(NULL, xmlStringBuffer, MXML_OPAQUE_CALLBACK);
+ if (xmlNode == NULL || xmlNode->type != MXML_ELEMENT)
+ __leave;
+
+ // Find the version node
+ /* Context->Version = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "ver", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->Version)*/
+ __leave;
+
+ // Find the revision node
+ Context->RevVersion = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "rev", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->RevVersion))
+ __leave;
+
+ // Find the release date node
+ /* Context->RelDate = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "reldate", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->RelDate))
+ __leave;*/
+
+ // Find the size node
+ Context->Size = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "size", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->Size))
+ __leave;
+
+ // Find the Hash node
+ //Context->Hash = UpdaterGetOpaqueXmlNodeText(
+ // mxmlFindElement(xmlNode->child, xmlNode, "sha2", NULL, NULL, MXML_DESCEND)
+ // );
+ //if (PhIsNullOrEmptyString(Context->Hash))
+ // __leave;
+
+ // Find the signature node
+ /*Context->Signature = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "sig", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->Signature))
+ __leave;*/
+
+ // Find the release notes URL
+ /*Context->ReleaseNotesUrl = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "relnotes", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->ReleaseNotesUrl))
+ __leave;*/
+
+ // Find the installer download URL
+ /*Context->SetupFileDownloadUrl = UpdaterGetOpaqueXmlNodeText(
+ mxmlFindElement(xmlNode->child, xmlNode, "setupurl", NULL, NULL, MXML_DESCEND)
+ );
+ if (PhIsNullOrEmptyString(Context->SetupFileDownloadUrl))
+ __leave;*/
+
+ // if (!ParseVersionString(Context))
+ // __leave;
+
+ isSuccess = TRUE;
+ }
+ __finally
+ {
+ if (httpRequestHandle)
+ WinHttpCloseHandle(httpRequestHandle);
+
+ if (httpConnectionHandle)
+ WinHttpCloseHandle(httpConnectionHandle);
+
+ if (httpSessionHandle)
+ WinHttpCloseHandle(httpSessionHandle);
+
+ if (xmlNode)
+ mxmlDelete(xmlNode);
+
+ if (xmlStringBuffer)
+ PhFree(xmlStringBuffer);
+
+ PhClearReference(&versionHeader);
+ PhClearReference(&windowsHeader);
+ }
+
+ return isSuccess;
+}
+
+NTSTATUS UpdateDownloadThread(
+ _In_ PVOID Parameter
+ )
+{
+ BOOLEAN downloadSuccess = FALSE;
+ BOOLEAN hashSuccess = FALSE;
+ BOOLEAN signatureSuccess = FALSE;
+ HANDLE tempFileHandle = NULL;
+ HINTERNET httpSessionHandle = NULL;
+ HINTERNET httpConnectionHandle = NULL;
+ HINTERNET httpRequestHandle = NULL;
+ PPH_STRING setupTempPath = NULL;
+ PPH_STRING downloadHostPath = NULL;
+ PPH_STRING downloadUrlPath = NULL;
+ PPH_STRING userAgentString = NULL;
+ PPH_STRING fullSetupPath = NULL;
+ PPH_STRING randomGuidString = NULL;
+ PUPDATER_HASH_CONTEXT hashContext = NULL;
+ ULONG indexOfFileName = -1;
+ GUID randomGuid;
+ URL_COMPONENTS httpUrlComponents = { sizeof(URL_COMPONENTS) };
+ WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig = { 0 };
+ LARGE_INTEGER timeNow;
+ LARGE_INTEGER timeStart;
+ ULONG64 timeTicks = 0;
+ ULONG64 timeBitsPerSecond = 0;
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)Parameter;
+
+ context->FileDownloadUrl = PhFormatString(
+ L"https://wj32.org/processhacker/plugins/download.php?id=%s&type=64",
+ PhGetStringOrEmpty(context->Node->Id)
+ );
+
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Initializing download request...");
+
+ // Create a user agent string.
+ //userAgentString = PhFormatString(
+ // L"PH_%lu.%lu_%lu",
+ // context->CurrentMajorVersion,
+ // context->CurrentMinorVersion,
+ // context->CurrentRevisionVersion
+ // );
+ //if (PhIsNullOrEmptyString(userAgentString))
+ // goto CleanupExit;
+
+ setupTempPath = PhCreateStringEx(NULL, GetTempPath(0, NULL) * sizeof(WCHAR));
+ if (PhIsNullOrEmptyString(setupTempPath))
+ goto CleanupExit;
+ if (GetTempPath((ULONG)setupTempPath->Length / sizeof(WCHAR), setupTempPath->Buffer) == 0)
+ goto CleanupExit;
+ if (PhIsNullOrEmptyString(setupTempPath))
+ goto CleanupExit;
+
+ // Generate random guid for our directory path.
+ PhGenerateGuid(&randomGuid);
+
+ if (randomGuidString = PhFormatGuid(&randomGuid))
+ {
+ PPH_STRING guidSubString;
+
+ // Strip the left and right curly brackets.
+ guidSubString = PhSubstring(randomGuidString, 1, randomGuidString->Length / sizeof(WCHAR) - 2);
+
+ PhSwapReference(&randomGuidString, guidSubString);
+ }
+
+ // Append the tempath to our string: %TEMP%RandomString\\processhacker-%lu.%lu-setup.exe
+ // Example: C:\\Users\\dmex\\AppData\\Temp\\ABCD\\processhacker-2.90-setup.exe
+ context->SetupFilePath = PhFormatString(
+ L"%s%s\\%s.zip",
+ PhGetStringOrEmpty(setupTempPath),
+ PhGetStringOrEmpty(randomGuidString),
+ PhGetStringOrEmpty(context->Node->InternalName)
+ );
+ if (PhIsNullOrEmptyString(context->SetupFilePath))
+ goto CleanupExit;
+
+ // Create the directory if it does not exist.
+ if (fullSetupPath = PhGetFullPath(PhGetString(context->SetupFilePath), &indexOfFileName))
+ {
+ PPH_STRING directoryPath;
+
+ if (indexOfFileName == -1)
+ goto CleanupExit;
+
+ if (directoryPath = PhSubstring(fullSetupPath, 0, indexOfFileName))
+ {
+ SHCreateDirectoryEx(NULL, PhGetString(directoryPath), NULL);
+ PhDereferenceObject(directoryPath);
+ }
+ }
+
+ // Create output file
+ if (!NT_SUCCESS(PhCreateFileWin32(
+ &tempFileHandle,
+ PhGetStringOrEmpty(context->SetupFilePath),
+ FILE_GENERIC_READ | FILE_GENERIC_WRITE,
+ FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_TEMPORARY,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_OVERWRITE_IF,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ // Set lengths to non-zero enabling these params to be cracked.
+ httpUrlComponents.dwSchemeLength = (ULONG)-1;
+ httpUrlComponents.dwHostNameLength = (ULONG)-1;
+ httpUrlComponents.dwUrlPathLength = (ULONG)-1;
+
+ if (!WinHttpCrackUrl(
+ PhGetStringOrEmpty(context->FileDownloadUrl),
+ 0,
+ 0,
+ &httpUrlComponents
+ ))
+ {
+ goto CleanupExit;
+ }
+
+ // Create the Host string.
+ downloadHostPath = PhCreateStringEx(httpUrlComponents.lpszHostName, httpUrlComponents.dwHostNameLength * sizeof(WCHAR));
+ // Create the Path string.
+ downloadUrlPath = PhCreateStringEx(httpUrlComponents.lpszUrlPath, httpUrlComponents.dwUrlPathLength * sizeof(WCHAR));
+
+
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Connecting...");
+
+
+ // Query the current system proxy
+ WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
+
+ // Open the HTTP session with the system proxy configuration if available
+ if (!(httpSessionHandle = WinHttpOpen(
+ PhGetStringOrEmpty(userAgentString),
+ proxyConfig.lpszProxy != NULL ? WINHTTP_ACCESS_TYPE_NAMED_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ proxyConfig.lpszProxy,
+ proxyConfig.lpszProxyBypass,
+ 0
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (WindowsVersion >= WINDOWS_8_1)
+ {
+ // Enable GZIP and DEFLATE support on Windows 8.1 and above using undocumented flags.
+ ULONG httpFlags = WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE;
+
+ WinHttpSetOption(
+ httpSessionHandle,
+ WINHTTP_OPTION_DECOMPRESSION,
+ &httpFlags,
+ sizeof(ULONG)
+ );
+ }
+
+ if (!(httpConnectionHandle = WinHttpConnect(
+ httpSessionHandle,
+ PhGetStringOrEmpty(downloadHostPath),
+ httpUrlComponents.nScheme == INTERNET_SCHEME_HTTP ? INTERNET_DEFAULT_HTTP_PORT : INTERNET_DEFAULT_HTTPS_PORT,
+ 0
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (!(httpRequestHandle = WinHttpOpenRequest(
+ httpConnectionHandle,
+ NULL,
+ PhGetStringOrEmpty(downloadUrlPath),
+ NULL,
+ WINHTTP_NO_REFERER,
+ WINHTTP_DEFAULT_ACCEPT_TYPES,
+ WINHTTP_FLAG_REFRESH | (httpUrlComponents.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0)
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ if (WindowsVersion >= WINDOWS_7)
+ {
+ ULONG keepAlive = WINHTTP_DISABLE_KEEP_ALIVE;
+ WinHttpSetOption(httpRequestHandle, WINHTTP_OPTION_DISABLE_FEATURE, &keepAlive, sizeof(ULONG));
+ }
+
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Sending download request...");
+
+ if (!WinHttpSendRequest(
+ httpRequestHandle,
+ WINHTTP_NO_ADDITIONAL_HEADERS,
+ 0,
+ WINHTTP_NO_REQUEST_DATA,
+ 0,
+ WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
+ 0
+ ))
+ {
+ goto CleanupExit;
+ }
+
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)L"Waiting for response...");
+
+ if (WinHttpReceiveResponse(httpRequestHandle, NULL))
+ {
+ ULONG bytesDownloaded = 0;
+ ULONG downloadedBytes = 0;
+ ULONG contentLengthSize = sizeof(ULONG);
+ ULONG contentLength = 0;
+ PPH_STRING status;
+ IO_STATUS_BLOCK isb;
+ BYTE buffer[PAGE_SIZE];
+
+ status = PhFormatString(L"Downloading %s...", PhGetString(context->Node->Name));
+
+ SendMessage(context->DialogHandle, TDM_SET_MARQUEE_PROGRESS_BAR, FALSE, 0);
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_MAIN_INSTRUCTION, (LPARAM)PhGetString(status));
+
+ PhDereferenceObject(status);
+
+ // Start the clock.
+ PhQuerySystemTime(&timeStart);
+
+ if (!WinHttpQueryHeaders(
+ httpRequestHandle,
+ WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER,
+ WINHTTP_HEADER_NAME_BY_INDEX,
+ &contentLength,
+ &contentLengthSize,
+ 0
+ ))
+ {
+ goto CleanupExit;
+ }
+
+ // Initialize hash algorithm.
+ if (!UpdaterInitializeHash(&hashContext))
+ goto CleanupExit;
+
+ // Zero the buffer.
+ memset(buffer, 0, PAGE_SIZE);
+
+ // Download the data.
+ while (WinHttpReadData(httpRequestHandle, buffer, PAGE_SIZE, &bytesDownloaded))
+ {
+ // If we get zero bytes, the file was uploaded or there was an error
+ if (bytesDownloaded == 0)
+ break;
+
+ // If the dialog was closed, just cleanup and exit
+ //if (!UpdateDialogThreadHandle)
+ // __leave;
+
+ // Update the hash of bytes we downloaded.
+ UpdaterUpdateHash(hashContext, buffer, bytesDownloaded);
+
+ // Write the downloaded bytes to disk.
+ if (!NT_SUCCESS(NtWriteFile(
+ tempFileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &isb,
+ buffer,
+ bytesDownloaded,
+ NULL,
+ NULL
+ )))
+ {
+ goto CleanupExit;
+ }
+
+ downloadedBytes += (DWORD)isb.Information;
+
+ // Check the number of bytes written are the same we downloaded.
+ if (bytesDownloaded != isb.Information)
+ goto CleanupExit;
+
+ // Query the current time
+ PhQuerySystemTime(&timeNow);
+
+ // Calculate the number of ticks
+ timeTicks = (timeNow.QuadPart - timeStart.QuadPart) / PH_TICKS_PER_SEC;
+ timeBitsPerSecond = downloadedBytes / __max(timeTicks, 1);
+
+ // TODO: Update on timer callback.
+ {
+ FLOAT percent = ((FLOAT)downloadedBytes / contentLength * 100);
+ PPH_STRING totalLength = PhFormatSize(contentLength, -1);
+ PPH_STRING totalDownloaded = PhFormatSize(downloadedBytes, -1);
+ PPH_STRING totalSpeed = PhFormatSize(timeBitsPerSecond, -1);
+
+ PPH_STRING statusMessage = PhFormatString(
+ L"Downloaded: %s of %s (%.0f%%)\r\nSpeed: %s/s",
+ totalDownloaded->Buffer,
+ totalLength->Buffer,
+ percent,
+ totalSpeed->Buffer
+ );
+
+ SendMessage(context->DialogHandle, TDM_SET_PROGRESS_BAR_POS, (WPARAM)percent, 0);
+ SendMessage(context->DialogHandle, TDM_UPDATE_ELEMENT_TEXT, TDE_CONTENT, (LPARAM)statusMessage->Buffer);
+
+ PhDereferenceObject(statusMessage);
+ PhDereferenceObject(totalSpeed);
+ PhDereferenceObject(totalLength);
+ PhDereferenceObject(totalDownloaded);
+ }
+ }
+
+ downloadSuccess = TRUE;
+
+ if (UpdaterVerifyHash(hashContext, context->Node->SHA2_64))
+ {
+ hashSuccess = TRUE;
+ }
+
+ if (UpdaterVerifySignature(hashContext, context->Node->HASH_64))
+ {
+ signatureSuccess = TRUE;
+ }
+ }
+
+CleanupExit:
+
+ if (hashContext)
+ UpdaterDestroyHash(hashContext);
+
+ if (tempFileHandle)
+ NtClose(tempFileHandle);
+
+ if (httpRequestHandle)
+ WinHttpCloseHandle(httpRequestHandle);
+
+ if (httpConnectionHandle)
+ WinHttpCloseHandle(httpConnectionHandle);
+
+ if (httpSessionHandle)
+ WinHttpCloseHandle(httpSessionHandle);
+
+ PhClearReference(&randomGuidString);
+ PhClearReference(&fullSetupPath);
+ PhClearReference(&setupTempPath);
+ PhClearReference(&downloadHostPath);
+ PhClearReference(&downloadUrlPath);
+ PhClearReference(&userAgentString);
+
+ if (downloadSuccess && hashSuccess && signatureSuccess)
+ {
+ if (NT_SUCCESS(SetupExtractBuild(context)))
+ {
+ PostMessage(context->DialogHandle, PH_UPDATESUCCESS, 0, 0);
+ }
+ else
+ {
+ PostMessage(context->DialogHandle, PH_UPDATEISERRORED, 0, 0);
+ }
+ }
+ else
+ {
+ PostMessage(context->DialogHandle, PH_UPDATEISERRORED, 0, 0);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+LRESULT CALLBACK TaskDialogSubclassProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ UINT_PTR uIdSubclass,
+ _In_ ULONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case WM_NCDESTROY:
+ {
+ RemoveWindowSubclass(hwndDlg, TaskDialogSubclassProc, uIdSubclass);
+ }
+ break;
+ case WM_APP + 1:
+ {
+ if (IsIconic(hwndDlg))
+ ShowWindow(hwndDlg, SW_RESTORE);
+ else
+ ShowWindow(hwndDlg, SW_SHOW);
+
+ SetForegroundWindow(hwndDlg);
+ }
+ break;
+ case PH_UPDATEAVAILABLE:
+ {
+ ShowAvailableDialog(context);
+ }
+ break;
+ case PH_UPDATEISCURRENT:
+ {
+ ShowLatestVersionDialog(context);
+ }
+ break;
+ case PH_UPDATENEWER:
+ {
+ ShowUninstallRestartDialog(context);
+ }
+ break;
+ case PH_UPDATESUCCESS:
+ {
+ ShowInstallRestartDialog(context);
+ }
+ break;
+ case PH_UPDATEFAILURE:
+ {
+ if ((BOOLEAN)wParam)
+ ShowUpdateFailedDialog(context, TRUE, FALSE);
+ else if ((BOOLEAN)lParam)
+ ShowUpdateFailedDialog(context, FALSE, TRUE);
+ else
+ ShowUpdateFailedDialog(context, FALSE, FALSE);
+ }
+ break;
+ case PH_UPDATEISERRORED:
+ {
+ ShowUpdateFailedDialog(context, FALSE, FALSE);
+ }
+ break;
+ //case WM_PARENTNOTIFY:
+ // {
+ // if (wParam == WM_CREATE)
+ // {
+ // // uMsg == 49251 for expand/collapse button click
+ // HWND hwndEdit = CreateWindowEx(
+ // WS_EX_CLIENTEDGE,
+ // L"EDIT",
+ // NULL,
+ // WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
+ // 5,
+ // 5,
+ // 390,
+ // 85,
+ // (HWND)lParam, // parent window
+ // 0,
+ // NULL,
+ // NULL
+ // );
+ //
+ // CommonCreateFont(-11, hwndEdit);
+ //
+ // // Add text to the window.
+ // SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)L"TEST");
+ // }
+ // }
+ // break;
+ //case WM_NCACTIVATE:
+ // {
+ // if (IsWindowVisible(PhMainWndHandle) && !IsMinimized(PhMainWndHandle))
+ // {
+ // if (!context->FixedWindowStyles)
+ // {
+ // SetWindowLongPtr(hwndDlg, GWLP_HWNDPARENT, (LONG_PTR)PhMainWndHandle);
+ // PhSetWindowExStyle(hwndDlg, WS_EX_APPWINDOW, WS_EX_APPWINDOW);
+ // context->FixedWindowStyles = TRUE;
+ // }
+ // }
+ // }
+ // break;
+ }
+
+ return DefSubclassProc(hwndDlg, uMsg, wParam, lParam);
+}
+
+HRESULT CALLBACK TaskDialogBootstrapCallback(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam,
+ _In_ LONG_PTR dwRefData
+ )
+{
+ PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData;
+
+ switch (uMsg)
+ {
+ case TDN_CREATED:
+ {
+ context->DialogHandle = hwndDlg;
+
+ TaskDialogCreateIcons(context);
+
+ SetWindowSubclass(hwndDlg, TaskDialogSubclassProc, 0, (ULONG_PTR)context);
+
+ switch (context->Action)
+ {
+ case PLUGIN_ACTION_INSTALL:
+ {
+ ShowAvailableDialog(context);
+ }
+ break;
+ case PLUGIN_ACTION_UNINSTALL:
+ {
+ ShowPluginUninstallDialog(context);
+ }
+ break;
+ case PLUGIN_ACTION_RESTART:
+ {
+ ShowUninstallRestartDialog(context);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return S_OK;
+}
+
+BOOLEAN ShowInitialDialog(
+ _In_ HWND Parent,
+ _In_ PVOID Context
+ )
+{
+ INT result = 0;
+ TASKDIALOGCONFIG config = { sizeof(TASKDIALOGCONFIG) };
+ config.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_CAN_BE_MINIMIZED | TDF_POSITION_RELATIVE_TO_WINDOW;
+ config.pszContent = L"Initializing...";
+ config.lpCallbackData = (LONG_PTR)Context;
+ config.pfCallback = TaskDialogBootstrapCallback;
+ config.hwndParent = Parent;
+
+ // Start the TaskDialog bootstrap
+ TaskDialogIndirect(&config, &result, NULL, NULL);
+
+ return result == IDOK;
+}
+
+BOOLEAN ShowUpdateDialog(
+ _In_ HWND Parent,
+ _In_ PLUGIN_ACTION Action
+ )
+{
+ BOOLEAN result;
+ PH_AUTO_POOL autoPool;
+ PPH_UPDATER_CONTEXT context;
+
+ context = CreateUpdateContext(NULL, Action);
+
+ PhInitializeAutoPool(&autoPool);
+
+ result = ShowInitialDialog(Parent, context);
+
+ FreeUpdateContext(context);
+ PhDeleteAutoPool(&autoPool);
+
+ return result;
+}
+
+BOOLEAN StartInitialCheck(
+ _In_ HWND Parent,
+ _In_ PPLUGIN_NODE Node,
+ _In_ PLUGIN_ACTION Action
+ )
+{
+ BOOLEAN result;
+ PH_AUTO_POOL autoPool;
+ PPH_UPDATER_CONTEXT context;
+
+ context = CreateUpdateContext(Node, Action);
+
+ PhInitializeAutoPool(&autoPool);
+
+ result = ShowInitialDialog(Parent, context);
+
+ FreeUpdateContext(context);
+ PhDeleteAutoPool(&autoPool);
+
+ return result;
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/setup/verify.c b/plugins-extra/ExtraPlugins/setup/verify.c
new file mode 100644
index 0000000..a3f52bf
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/setup/verify.c
@@ -0,0 +1,206 @@
+#include "..\main.h"
+
+static UCHAR ExtraPluginsPublicKey[] =
+{
+ 0x45, 0x43, 0x53, 0x31, 0x20, 0x00, 0x00, 0x00, 0x24, 0x33, 0x0F, 0x97,
+ 0x6B, 0xBA, 0x8B, 0xDD, 0x18, 0x2F, 0x7A, 0xAC, 0x53, 0x8F, 0xE3, 0x2A,
+ 0x30, 0xA8, 0x8A, 0x47, 0x12, 0x3A, 0x4D, 0xCB, 0x11, 0x6A, 0x7E, 0x61,
+ 0x32, 0xEE, 0xF8, 0xE9, 0x6A, 0x9B, 0x85, 0x23, 0x9F, 0x08, 0xEB, 0xC3,
+ 0x8C, 0x60, 0xFD, 0xDE, 0xD3, 0x73, 0xCB, 0xFE, 0x53, 0xF6, 0x08, 0xCB,
+ 0xE6, 0xF9, 0x34, 0x4B, 0x14, 0x37, 0x17, 0x74, 0xAF, 0xFF, 0xCC, 0xAB
+};
+
+BOOLEAN UpdaterInitializeHash(
+ _Out_ PUPDATER_HASH_CONTEXT *Context
+ )
+{
+ ULONG querySize;
+ PUPDATER_HASH_CONTEXT hashContext;
+
+ hashContext = PhAllocate(sizeof(UPDATER_HASH_CONTEXT));
+ memset(hashContext, 0, sizeof(UPDATER_HASH_CONTEXT));
+
+ if (!NT_SUCCESS(BCryptOpenAlgorithmProvider(
+ &hashContext->SignAlgHandle,
+ BCRYPT_ECDSA_P256_ALGORITHM,
+ NULL,
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ if (!NT_SUCCESS(BCryptImportKeyPair(
+ hashContext->SignAlgHandle,
+ NULL,
+ BCRYPT_ECCPUBLIC_BLOB,
+ &hashContext->KeyHandle,
+ ExtraPluginsPublicKey,
+ sizeof(ExtraPluginsPublicKey),
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ if (!NT_SUCCESS(BCryptOpenAlgorithmProvider(
+ &hashContext->HashAlgHandle,
+ BCRYPT_SHA256_ALGORITHM,
+ NULL,
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ if (!NT_SUCCESS(BCryptGetProperty(
+ hashContext->HashAlgHandle,
+ BCRYPT_OBJECT_LENGTH,
+ (PUCHAR)&hashContext->HashObjectSize,
+ sizeof(ULONG),
+ &querySize,
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ if (!NT_SUCCESS(BCryptGetProperty(
+ hashContext->HashAlgHandle,
+ BCRYPT_HASH_LENGTH,
+ (PUCHAR)&hashContext->HashSize,
+ sizeof(ULONG),
+ &querySize,
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ if (!(hashContext->HashObject = PhAllocate(hashContext->HashObjectSize)))
+ goto error;
+ if (!(hashContext->Hash = PhAllocate(hashContext->HashSize)))
+ goto error;
+
+ if (!NT_SUCCESS(BCryptCreateHash(
+ hashContext->HashAlgHandle,
+ &hashContext->HashHandle,
+ hashContext->HashObject,
+ hashContext->HashObjectSize,
+ NULL,
+ 0,
+ 0
+ )))
+ {
+ goto error;
+ }
+
+ *Context = hashContext;
+ return TRUE;
+
+error:
+ UpdaterDestroyHash(hashContext);
+ return FALSE;
+}
+
+BOOLEAN UpdaterUpdateHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_reads_bytes_(Length) PVOID Buffer,
+ _In_ ULONG Length
+ )
+{
+ return NT_SUCCESS(BCryptHashData(Context->HashHandle, Buffer, Length, 0));
+}
+
+BOOLEAN UpdaterVerifyHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_ PPH_STRING Sha2Hash
+ )
+{
+ PPH_STRING sha2HexString;
+
+ // Compute the final hash.
+
+ if (!NT_SUCCESS(BCryptFinishHash(
+ Context->HashHandle,
+ Context->Hash,
+ Context->HashSize,
+ 0
+ )))
+ {
+ return FALSE;
+ }
+
+ if (!(sha2HexString = PhBufferToHexString(Context->Hash, Context->HashSize)))
+ return FALSE;
+
+ if (!PhEqualString2(sha2HexString, PhGetStringOrEmpty(Sha2Hash), TRUE))
+ {
+ PhDereferenceObject(sha2HexString);
+ return FALSE;
+ }
+
+ PhDereferenceObject(sha2HexString);
+ return TRUE;
+}
+
+BOOLEAN UpdaterVerifySignature(
+ _Inout_ PUPDATER_HASH_CONTEXT Context,
+ _In_ PPH_STRING HexSignature
+ )
+{
+ ULONG signatureLength;
+ PUCHAR signatureBuffer;
+
+ signatureLength = (ULONG)HexSignature->Length / sizeof(WCHAR) / 2;
+ signatureBuffer = PhAllocate(signatureLength);
+
+ if (!PhHexStringToBuffer(&HexSignature->sr, signatureBuffer))
+ {
+ PhFree(signatureBuffer);
+ return FALSE;
+ }
+
+ // Verify the signature.
+ if (!NT_SUCCESS(BCryptVerifySignature(
+ Context->KeyHandle,
+ NULL,
+ Context->Hash,
+ Context->HashSize,
+ signatureBuffer,
+ signatureLength,
+ 0
+ )))
+ {
+ PhFree(signatureBuffer);
+ return FALSE;
+ }
+
+ PhFree(signatureBuffer);
+ return TRUE;
+}
+
+VOID UpdaterDestroyHash(
+ _Inout_ PUPDATER_HASH_CONTEXT Context
+ )
+{
+ if (Context->HashAlgHandle)
+ BCryptCloseAlgorithmProvider(Context->HashAlgHandle, 0);
+
+ if (Context->SignAlgHandle)
+ BCryptCloseAlgorithmProvider(Context->SignAlgHandle, 0);
+
+ if (Context->HashHandle)
+ BCryptDestroyHash(Context->HashHandle);
+
+ if (Context->KeyHandle)
+ BCryptDestroyKey(Context->KeyHandle);
+
+ if (Context->HashObject)
+ PhFree(Context->HashObject);
+
+ if (Context->Hash)
+ PhFree(Context->Hash);
+
+ PhFree(Context);
+}
\ No newline at end of file
diff --git a/plugins-extra/ExtraPlugins/wndtree.c b/plugins-extra/ExtraPlugins/wndtree.c
new file mode 100644
index 0000000..56585be
--- /dev/null
+++ b/plugins-extra/ExtraPlugins/wndtree.c
@@ -0,0 +1,574 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Plugin Manager
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+static PH_TN_FILTER_SUPPORT FilterSupport;
+
+BOOLEAN WepWindowNodeHashtableCompareFunction(
+ _In_ PVOID Entry1,
+ _In_ PVOID Entry2
+ );
+ULONG WepWindowNodeHashtableHashFunction(
+ _In_ PVOID Entry
+ );
+VOID WepDestroyWindowNode(
+ _In_ PPLUGIN_NODE WindowNode
+ );
+BOOLEAN NTAPI WepWindowTreeNewCallback(
+ _In_ HWND hwnd,
+ _In_ PH_TREENEW_MESSAGE Message,
+ __in_opt PVOID Parameter1,
+ __in_opt PVOID Parameter2,
+ __in_opt PVOID Context
+ );
+
+VOID WtcInitializeWindowTree(
+ _In_ HWND ParentWindowHandle,
+ _In_ HWND TreeNewHandle,
+ __out PWCT_TREE_CONTEXT Context
+ )
+{
+ memset(Context, 0, sizeof(WCT_TREE_CONTEXT));
+
+ Context->NodeHashtable = PhCreateHashtable(
+ sizeof(PPLUGIN_NODE),
+ WepWindowNodeHashtableCompareFunction,
+ WepWindowNodeHashtableHashFunction,
+ 100
+ );
+ Context->NodeList = PhCreateList(100);
+
+ Context->ParentWindowHandle = ParentWindowHandle;
+ Context->TreeNewHandle = TreeNewHandle;
+ PhSetControlTheme(TreeNewHandle, L"explorer");
+
+ LOGFONT logFont;
+
+ if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logFont, 0))
+ {
+ Context->TitleFontHandle = CreateFont(
+ -PhMultiplyDivideSigned(-14, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_BOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+
+ Context->NormalFontHandle = CreateFont(
+ -PhMultiplyDivideSigned(-10, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_NORMAL,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+
+ Context->BoldFontHandle = CreateFont(
+ -PhMultiplyDivideSigned(-12, PhGlobalDpi, 72),
+ 0,
+ 0,
+ 0,
+ FW_SEMIBOLD,
+ FALSE,
+ FALSE,
+ FALSE,
+ ANSI_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ CLEARTYPE_QUALITY | ANTIALIASED_QUALITY,
+ DEFAULT_PITCH,
+ logFont.lfFaceName
+ );
+ }
+
+ TreeNew_SetCallback(TreeNewHandle, WepWindowTreeNewCallback, Context);
+ TreeNew_SetRowHeight(TreeNewHandle, 48);
+
+ PhAddTreeNewColumnEx2(TreeNewHandle, TREE_COLUMN_ITEM_NAME, TRUE, L"Plugin", 80, PH_ALIGN_LEFT, TREE_COLUMN_ITEM_NAME, 0, TN_COLUMN_FLAG_CUSTOMDRAW);
+ PhAddTreeNewColumnEx2(TreeNewHandle, TREE_COLUMN_ITEM_AUTHOR, TRUE, L"Author", 80, PH_ALIGN_LEFT, TREE_COLUMN_ITEM_AUTHOR, 0, 0);
+ PhAddTreeNewColumnEx2(TreeNewHandle, TREE_COLUMN_ITEM_VERSION, TRUE, L"Version", 80, PH_ALIGN_CENTER, TREE_COLUMN_ITEM_VERSION, DT_CENTER, 0);
+
+ TreeNew_SetSort(TreeNewHandle, 0, NoSortOrder);
+
+ PPH_STRING settings = PhGetStringSetting(SETTING_NAME_TREE_LIST_COLUMNS);
+ PhCmLoadSettings(TreeNewHandle, &settings->sr);
+ PhDereferenceObject(settings);
+
+ PhInitializeTreeNewFilterSupport(&FilterSupport, TreeNewHandle, Context->NodeList);
+}
+
+VOID WtcDeleteWindowTree(
+ _In_ PWCT_TREE_CONTEXT Context
+ )
+{
+ PPH_STRING settings = PhCmSaveSettings(Context->TreeNewHandle);
+ PhSetStringSetting2(SETTING_NAME_TREE_LIST_COLUMNS, &settings->sr);
+ PhDereferenceObject(settings);
+
+ for (ULONG i = 0; i < Context->NodeList->Count; i++)
+ {
+ WepDestroyWindowNode(Context->NodeList->Items[i]);
+ }
+
+ PhDereferenceObject(Context->NodeHashtable);
+ PhDereferenceObject(Context->NodeList);
+}
+
+struct _PH_TN_FILTER_SUPPORT* WtcGetTreeListFilterSupport(
+ VOID
+ )
+{
+ return &FilterSupport;
+}
+
+BOOLEAN WepWindowNodeHashtableCompareFunction(
+ _In_ PVOID Entry1,
+ _In_ PVOID Entry2
+ )
+{
+ PPLUGIN_NODE windowNode1 = *(PPLUGIN_NODE *)Entry1;
+ PPLUGIN_NODE windowNode2 = *(PPLUGIN_NODE *)Entry2;
+
+ return PhEqualString(windowNode1->InternalName, windowNode2->InternalName, TRUE);
+}
+
+ULONG WepWindowNodeHashtableHashFunction(
+ _In_ PVOID Entry
+ )
+{
+ return PhHashStringRef(&(*(PPLUGIN_NODE*)Entry)->InternalName->sr, TRUE);
+}
+
+VOID CloudAddChildWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ PPLUGIN_NODE Entry
+ )
+{
+ PhInitializeTreeNewNode(&Entry->Node);
+
+ memset(Entry->TextCache, 0, sizeof(PH_STRINGREF) * TREE_COLUMN_ITEM_MAXIMUM);
+ Entry->Node.TextCache = Entry->TextCache;
+ Entry->Node.TextCacheSize = TREE_COLUMN_ITEM_MAXIMUM;
+
+ PhAddEntryHashtable(Context->NodeHashtable, &Entry);
+ PhAddItemList(Context->NodeList, Entry);
+
+ if (FilterSupport.NodeList)
+ {
+ Entry->Node.Visible = PhApplyTreeNewFiltersToNode(&FilterSupport, &Entry->Node);
+ }
+}
+
+PPLUGIN_NODE FindTreeNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ TREE_PLUGIN_STATE State,
+ _In_ PPH_STRING InternalName
+ )
+{
+ for (ULONG i = 0; i < Context->NodeList->Count; i++)
+ {
+ PPLUGIN_NODE entry = Context->NodeList->Items[i];
+
+ if (entry->State == State && PhEqualString(entry->InternalName, InternalName, TRUE))
+ return entry;
+ }
+
+ /*PLUGIN_NODE lookupWindowNode;
+ PPLUGIN_NODE lookupWindowNodePtr = &lookupWindowNode;
+ PPLUGIN_NODE *windowNode;
+
+ lookupWindowNode.Type = Type;
+ lookupWindowNode.InternalName = InternalName;
+
+ windowNode = (PPLUGIN_NODE*)PhFindEntryHashtable(
+ Context->NodeHashtable,
+ &lookupWindowNodePtr
+ );
+
+ if (windowNode)
+ return *windowNode;
+ else*/
+ return NULL;
+}
+
+VOID WeRemoveWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context,
+ _In_ PPLUGIN_NODE WindowNode
+ )
+{
+ ULONG index = 0;
+
+ // Remove from hashtable/list and cleanup.
+ PhRemoveEntryHashtable(Context->NodeHashtable, &WindowNode);
+
+ if ((index = PhFindItemList(Context->NodeList, WindowNode)) != -1)
+ {
+ PhRemoveItemList(Context->NodeList, index);
+ }
+
+ WepDestroyWindowNode(WindowNode);
+
+ TreeNew_NodesStructured(Context->TreeNewHandle);
+}
+
+VOID WepDestroyWindowNode(
+ _In_ PPLUGIN_NODE WindowNode
+ )
+{
+ //if (WindowNode->NameString)
+ // PhDereferenceObject(WindowNode->NameString);
+ //if (WindowNode->VersionString)
+ // PhDereferenceObject(WindowNode->VersionString);
+ //if (WindowNode->DescriptionString)
+ // PhDereferenceObject(WindowNode->DescriptionString);
+ //if (WindowNode->AuthorString)
+ // PhDereferenceObject(WindowNode->AuthorString);
+
+ PhDereferenceObject(WindowNode);
+}
+
+
+#define SORT_FUNCTION(Column) PmPoolTreeNewCompare##Column
+#define BEGIN_SORT_FUNCTION(Column) static int __cdecl PmPoolTreeNewCompare##Column( \
+ _In_ void *_context, \
+ _In_ const void *_elem1, \
+ _In_ const void *_elem2 \
+ ) \
+{ \
+ PPLUGIN_NODE node1 = *(PPLUGIN_NODE *)_elem1; \
+ PPLUGIN_NODE node2 = *(PPLUGIN_NODE *)_elem2; \
+ int sortResult = 0;
+
+#define END_SORT_FUNCTION \
+ if (sortResult == 0) \
+ sortResult = uintptrcmp((ULONG_PTR)node1->Node.Index, (ULONG_PTR)node2->Node.Index); \
+ \
+ return PhModifySort(sortResult, ((PWCT_TREE_CONTEXT)_context)->TreeNewSortOrder); \
+}
+
+BEGIN_SORT_FUNCTION(Name)
+{
+ sortResult = PhCompareString(node1->Name, node2->Name, FALSE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Author)
+{
+ sortResult = PhCompareString(node1->Author, node2->Author, FALSE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Version)
+{
+ sortResult = PhCompareString(node1->Version, node2->Version, FALSE);
+}
+END_SORT_FUNCTION
+
+BOOLEAN NTAPI WepWindowTreeNewCallback(
+ _In_ HWND hwnd,
+ _In_ PH_TREENEW_MESSAGE Message,
+ __in_opt PVOID Parameter1,
+ __in_opt PVOID Parameter2,
+ __in_opt PVOID Context
+ )
+{
+ PWCT_TREE_CONTEXT context;
+ PPLUGIN_NODE node;
+
+ context = Context;
+
+ switch (Message)
+ {
+ case TreeNewGetChildren:
+ {
+ PPH_TREENEW_GET_CHILDREN getChildren = Parameter1;
+ node = (PPLUGIN_NODE)getChildren->Node;
+
+ if (!getChildren->Node)
+ {
+ static PVOID sortFunctions[] =
+ {
+ SORT_FUNCTION(Name),
+ SORT_FUNCTION(Author),
+ SORT_FUNCTION(Version),
+ //SORT_FUNCTION(PagedAlloc),
+ //SORT_FUNCTION(PagedFree),
+ //SORT_FUNCTION(PagedCurrent),
+ //SORT_FUNCTION(PagedTotal),
+ //SORT_FUNCTION(NonPagedAlloc),
+ //SORT_FUNCTION(NonPagedFree),
+ //SORT_FUNCTION(NonPagedCurrent),
+ //SORT_FUNCTION(NonPagedTotal),
+ };
+ int (__cdecl *sortFunction)(void *, const void *, const void *);
+
+ if (context->TreeNewSortColumn < TREE_COLUMN_ITEM_MAXIMUM)
+ sortFunction = sortFunctions[context->TreeNewSortColumn];
+ else
+ sortFunction = NULL;
+
+ if (sortFunction)
+ {
+ qsort_s(context->NodeList->Items, context->NodeList->Count, sizeof(PVOID), sortFunction, context);
+ }
+
+ getChildren->Children = (PPH_TREENEW_NODE *)context->NodeList->Items;
+ getChildren->NumberOfChildren = context->NodeList->Count;
+ }
+ }
+ return TRUE;
+ case TreeNewIsLeaf:
+ {
+ PPH_TREENEW_IS_LEAF isLeaf = (PPH_TREENEW_IS_LEAF)Parameter1;
+ node = (PPLUGIN_NODE)isLeaf->Node;
+
+ isLeaf->IsLeaf = TRUE;
+ }
+ return TRUE;
+ case TreeNewGetCellText:
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = (PPH_TREENEW_GET_CELL_TEXT)Parameter1;
+ node = (PPLUGIN_NODE)getCellText->Node;
+
+ switch (getCellText->Id)
+ {
+ case TREE_COLUMN_ITEM_NAME:
+ getCellText->Text = PhGetStringRef(node->Name);
+ break;
+ case TREE_COLUMN_ITEM_AUTHOR:
+ getCellText->Text = PhGetStringRef(node->Author);
+ break;
+ case TREE_COLUMN_ITEM_VERSION:
+ getCellText->Text = PhGetStringRef(node->Version);
+ break;
+ default:
+ return FALSE;
+ }
+
+ getCellText->Flags = TN_CACHE;
+ }
+ return TRUE;
+ case TreeNewGetNodeColor:
+ {
+ PPH_TREENEW_GET_NODE_COLOR getNodeColor = (PPH_TREENEW_GET_NODE_COLOR)Parameter1;
+ node = (PPLUGIN_NODE)getNodeColor->Node;
+
+ getNodeColor->Flags = TN_CACHE;
+ }
+ return TRUE;
+ case TreeNewSortChanged:
+ {
+ TreeNew_GetSort(hwnd, &context->TreeNewSortColumn, &context->TreeNewSortOrder);
+ TreeNew_NodesStructured(hwnd);
+ }
+ return TRUE;
+ case TreeNewKeyDown:
+ case TreeNewNodeExpanding:
+ return TRUE;
+ case TreeNewLeftDoubleClick:
+ {
+ SendMessage(context->ParentWindowHandle, WM_COMMAND, WM_ACTION, (LPARAM)context);
+ }
+ return TRUE;
+ case TreeNewContextMenu:
+ {
+ PPH_TREENEW_MOUSE_EVENT mouseEvent = (PPH_TREENEW_MOUSE_EVENT)Parameter1;
+
+ SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_WCTSHOWCONTEXTMENU, MAKELONG(mouseEvent->Location.x, mouseEvent->Location.y));
+ }
+ 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_ALIGN_LEFT | PH_ALIGN_TOP, data.MouseEvent->ScreenLocation.x, data.MouseEvent->ScreenLocation.y);
+ PhHandleTreeNewColumnMenu(&data);
+ PhDeleteTreeNewColumnMenu(&data);
+ }
+ return TRUE;
+ case TreeNewCustomDraw:
+ {
+ PPH_TREENEW_CUSTOM_DRAW customDraw = Parameter1;
+ RECT rect = customDraw->CellRect;
+ node = (PPLUGIN_NODE)customDraw->Node;
+
+ switch (customDraw->Column->Id)
+ {
+ case TREE_COLUMN_ITEM_NAME:
+ {
+ PH_STRINGREF text;
+ SIZE nameSize;
+ SIZE textSize;
+
+ if (node->PluginOptions)
+ {
+ if (!node->Icon)
+ {
+ HBITMAP bitmapActive;
+
+ bitmapActive = LoadImageFromResources(17, 17, MAKEINTRESOURCE(IDB_SETTINGS_PNG), TRUE);
+
+ if (bitmapActive)
+ {
+ HDC screenDc;
+ HBITMAP screenBitmap;
+ ICONINFO iconInfo = { TRUE };
+
+ screenDc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
+ screenBitmap = CreateCompatibleBitmap(screenDc, 17, 17);
+
+ iconInfo.hbmColor = bitmapActive;
+ iconInfo.hbmMask = screenBitmap;
+ node->Icon = CreateIconIndirect(&iconInfo);
+
+ DeleteObject(screenBitmap);
+ DeleteObject(bitmapActive);
+ DeleteDC(screenDc);
+ }
+ }
+
+ if (node->Icon)
+ {
+ DrawIconEx(
+ customDraw->Dc,
+ rect.left + 5,
+ rect.top + ((rect.bottom - rect.top) - 17) / 2,
+ node->Icon,
+ 17,
+ 17,
+ 0,
+ NULL,
+ DI_NORMAL
+ );
+ }
+ }
+
+ rect.left += 19;
+ rect.left += 8;
+
+ rect.top += 5;
+ rect.right -= 5;
+ rect.bottom -= 8;
+
+ // top
+ SetTextColor(customDraw->Dc, RGB(0x0, 0x0, 0x0));
+ SelectObject(customDraw->Dc, context->TitleFontHandle);
+ text = PhIsNullOrEmptyString(node->Name) ? PhGetStringRef(node->InternalName) : PhGetStringRef(node->Name);
+ GetTextExtentPoint32(customDraw->Dc, text.Buffer, (ULONG)text.Length / 2, &nameSize);
+ DrawText(customDraw->Dc, text.Buffer, (ULONG)text.Length / 2, &rect, DT_TOP | DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE);
+
+ // bottom
+ SetTextColor(customDraw->Dc, RGB(0x64, 0x64, 0x64));
+ SelectObject(customDraw->Dc, context->NormalFontHandle);
+ text = PhGetStringRef(node->Description);
+ GetTextExtentPoint32(customDraw->Dc, text.Buffer, (ULONG)text.Length / 2, &textSize);
+ DrawText(
+ customDraw->Dc,
+ text.Buffer,
+ (ULONG)text.Length / 2,
+ &rect,
+ DT_BOTTOM | DT_LEFT | DT_END_ELLIPSIS | DT_SINGLELINE
+ );
+ }
+ break;
+ }
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+VOID WeClearWindowTree(
+ _In_ PWCT_TREE_CONTEXT Context
+ )
+{
+ for (ULONG i = 0; i < Context->NodeList->Count; i++)
+ WepDestroyWindowNode(Context->NodeList->Items[i]);
+
+ PhClearHashtable(Context->NodeHashtable);
+ PhClearList(Context->NodeList);
+
+ TreeNew_NodesStructured(Context->TreeNewHandle);
+}
+
+PPLUGIN_NODE WeGetSelectedWindowNode(
+ _In_ PWCT_TREE_CONTEXT Context
+ )
+{
+ for (ULONG i = 0; i < Context->NodeList->Count; i++)
+ {
+ PPLUGIN_NODE windowNode = Context->NodeList->Items[i];
+
+ if (windowNode->Node.Selected)
+ return windowNode;
+ }
+
+ return NULL;
+}
+
+VOID WeGetSelectedWindowNodes(
+ _In_ PWCT_TREE_CONTEXT Context,
+ __out PPLUGIN_NODE **Windows,
+ __out PULONG NumberOfWindows
+ )
+{
+ PPH_LIST list = PhCreateList(2);
+
+ for (ULONG i = 0; i < Context->NodeList->Count; i++)
+ {
+ PPLUGIN_NODE node = (PPLUGIN_NODE)Context->NodeList->Items[i];
+
+ if (node->Node.Selected)
+ PhAddItemList(list, node);
+ }
+
+ *Windows = PhAllocateCopy(list->Items, sizeof(PVOID) * list->Count);
+ *NumberOfWindows = list->Count;
+
+ PhDereferenceObject(list);
+}
\ No newline at end of file
diff --git a/plugins-extra/FirewallMonitorPlugin/CHANGELOG.txt b/plugins-extra/FirewallMonitorPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.rc b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.rc
new file mode 100644
index 0000000..3d0f21b
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.rc
@@ -0,0 +1,150 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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 ""winres.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", "FirewallMonitorPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "FirewallMonitorPlugin.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 MENU
+BEGIN
+ POPUP "Event"
+ BEGIN
+ MENUITEM "&Copy\aCtrl+C", ID_EVENT_COPY
+ MENUITEM SEPARATOR
+ MENUITEM "Properties", ID_FW_PROPERTIES
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_FWTABERROR DIALOGEX 0, 0, 309, 176
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+EXSTYLE WS_EX_TRANSPARENT
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "Restart",IDC_RESTART,20,28,50,14
+ LTEXT "Firewall monitoring requires Process Hacker to be restarted with administrative privileges.",IDC_STATIC,16,14,286,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_FWTABERROR, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 302
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 169
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj
new file mode 100644
index 0000000..dee17b8
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj
@@ -0,0 +1,96 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {44A7C3BA-BAD5-40F3-AB70-442D44539053}
+ FirewallMonitorPlugin
+ Win32Proj
+ FirewallMonitorPlugin
+ 10.0.10586.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ true
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj.filters b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj.filters
new file mode 100644
index 0000000..40c98d0
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/FirewallMonitorPlugin.vcxproj.filters
@@ -0,0 +1,50 @@
+
+
+
+
+ {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
+
+
+ Source Files
+
+
+
+
+
+
+
+ Resource Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/FirewallMonitorPlugin/fwdialog.c b/plugins-extra/FirewallMonitorPlugin/fwdialog.c
new file mode 100644
index 0000000..3a7ba30
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/fwdialog.c
@@ -0,0 +1,84 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firewall Monitor
+ *
+ * Copyright (C) 2015 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"
+
+static INT_PTR CALLBACK OptionsDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PFW_EVENT_NODE context;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ SetProp(hwndDlg, L"Context", (HANDLE)lParam);
+ context = (PFW_EVENT_NODE)GetProp(hwndDlg, L"Context");
+ }
+ else
+ {
+ context = (PFW_EVENT_NODE)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_DESTROY)
+ RemoveProp(hwndDlg, L"Context");
+ }
+
+ if (!context)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ PhCenterWindow(hwndDlg, PhMainWndHandle);
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+NTSTATUS NTAPI ShowFwRuleProperties(
+ _In_ PVOID ThreadParameter
+ )
+{
+ //DialogBoxParam(
+ // PluginInstance->DllBase,
+ // MAKEINTRESOURCE(IDD_PROPDIALOG),
+ // PhMainWndHandle,
+ // OptionsDlgProc,
+ // (LPARAM)ThreadParameter
+ // );
+
+ return STATUS_SUCCESS;
+}
\ No newline at end of file
diff --git a/plugins-extra/FirewallMonitorPlugin/fwmon.h b/plugins-extra/FirewallMonitorPlugin/fwmon.h
new file mode 100644
index 0000000..f8e3f5f
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/fwmon.h
@@ -0,0 +1,105 @@
+#ifndef FWMON_H
+#define FWMON_H
+
+#include
+
+#include "resource.h"
+
+#include
+#include
+#include
+#include
+
+#pragma comment(lib, "fwpuclnt.lib")
+#pragma comment(lib, "iphlpapi.lib")
+#pragma comment(lib, "Ws2_32.lib")
+
+#define PLUGIN_NAME L"dmex.FirewallMonitor"
+#define SETTING_NAME_FW_TREE_LIST_COLUMNS (PLUGIN_NAME L".TreeListColumns")
+#define SETTING_NAME_FW_TREE_LIST_SORT (PLUGIN_NAME L".TreeListSort")
+
+extern PPH_PLUGIN PluginInstance;
+extern BOOLEAN FwEnabled;
+extern PPH_LIST FwNodeList;
+
+typedef struct _FW_EVENT_ITEM
+{
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ ULONG Index;
+ PPH_STRING IndexString;
+
+ LARGE_INTEGER AddedTime;
+
+ PPH_STRING TimeString;
+ PPH_STRING UserNameString;
+ PH_STRINGREF ProtocalString;
+ PPH_STRING ProcessNameString;
+ PPH_STRING ProcessBaseString;
+ PH_STRINGREF DirectionString;
+
+ PPH_STRING LocalPortString;
+ PPH_STRING LocalAddressString;
+ PPH_STRING RemotePortString;
+ PPH_STRING RemoteAddressString;
+
+ //HICON Icon;
+ PH_STRINGREF FwRuleActionString;
+ PPH_STRING FwRuleNameString;
+ PPH_STRING FwRuleDescriptionString;
+ PPH_STRING FwRuleLayerNameString;
+ PPH_STRING FwRuleLayerDescriptionString;
+} FW_EVENT_ITEM, *PFW_EVENT_ITEM;
+
+#define FWTNC_TIME 0
+#define FWTNC_ACTION 1
+#define FWTNC_RULENAME 2
+#define FWTNC_RULEDESCRIPTION 3
+#define FWTNC_PROCESSBASENAME 4
+#define FWTNC_PROCESSFILENAME 5
+#define FWTNC_USER 6
+#define FWTNC_LOCALADDRESS 7
+#define FWTNC_LOCALPORT 8
+#define FWTNC_REMOTEADDRESS 9
+#define FWTNC_REMOTEPORT 10
+#define FWTNC_PROTOCOL 11
+#define FWTNC_DIRECTION 12
+#define FWTNC_INDEX 13
+#define FWTNC_MAXIMUM 14
+
+typedef struct _FW_EVENT_NODE
+{
+ PH_TREENEW_NODE Node;
+ PH_STRINGREF TextCache[FWTNC_MAXIMUM];
+ PPH_STRING TooltipText;
+
+ PFW_EVENT_ITEM EventItem;
+} FW_EVENT_NODE, *PFW_EVENT_NODE;
+
+
+// monitor
+extern PH_CALLBACK FwItemAddedEvent;
+extern PH_CALLBACK FwItemModifiedEvent;
+extern PH_CALLBACK FwItemRemovedEvent;
+extern PH_CALLBACK FwItemsUpdatedEvent;
+
+BOOLEAN StartFwMonitor(VOID);
+VOID StopFwMonitor(VOID);
+VOID InitializeFwTab(VOID);
+VOID LoadSettingsFwTreeList(VOID);
+VOID SaveSettingsFwTreeList(VOID);
+
+NTSTATUS NTAPI ShowFwRuleProperties(
+ _In_ PVOID ThreadParameter
+ );
+
+
+typedef ULONG (WINAPI* _FwpmNetEventSubscribe1)(
+ _In_ HANDLE engineHandle,
+ _In_ const FWPM_NET_EVENT_SUBSCRIPTION0* subscription,
+ _In_ FWPM_NET_EVENT_CALLBACK1 callback,
+ _In_opt_ void* context,
+ _Out_ HANDLE* eventsHandle
+ );
+
+#endif
diff --git a/plugins-extra/FirewallMonitorPlugin/fwtab.c b/plugins-extra/FirewallMonitorPlugin/fwtab.c
new file mode 100644
index 0000000..f44ca5e
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/fwtab.c
@@ -0,0 +1,1083 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firewall Monitor
+ *
+ * Copyright (C) 2015 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 "fwtabp.h"
+#include "..\..\plugins\include\toolstatusintf.h"
+
+static BOOLEAN FwTreeNewCreated = FALSE;
+static HWND FwTreeNewHandle = NULL;
+static ULONG FwTreeNewSortColumn = 0;
+static PH_SORT_ORDER FwTreeNewSortOrder;
+
+BOOLEAN FwEnabled;
+PPH_LIST FwNodeList;
+static PH_QUEUED_LOCK FwLock = PH_QUEUED_LOCK_INIT;
+
+static PH_CALLBACK_REGISTRATION FwItemAddedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemModifiedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemRemovedRegistration;
+static PH_CALLBACK_REGISTRATION FwItemsUpdatedRegistration;
+static BOOLEAN FwNeedsRedraw = FALSE;
+
+static PH_TN_FILTER_SUPPORT FilterSupport;
+static PTOOLSTATUS_INTERFACE ToolStatusInterface;
+static PH_CALLBACK_REGISTRATION SearchChangedRegistration;
+
+HWND NTAPI EtpToolStatusGetTreeNewHandle(
+ VOID
+ );
+INT_PTR CALLBACK FwTabErrorDialogProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+VOID InitializeFwTab(
+ VOID
+ )
+{
+ PH_ADDITIONAL_TAB_PAGE tabPage;
+ PPH_ADDITIONAL_TAB_PAGE addedTabPage;
+ PPH_PLUGIN toolStatusPlugin;
+
+ if (toolStatusPlugin = PhFindPlugin(TOOLSTATUS_PLUGIN_NAME))
+ {
+ ToolStatusInterface = PhGetPluginInformation(toolStatusPlugin)->Interface;
+
+ if (ToolStatusInterface->Version < TOOLSTATUS_INTERFACE_VERSION)
+ ToolStatusInterface = NULL;
+ }
+
+ 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;
+ addedTabPage = ProcessHacker_AddTabPage(PhMainWndHandle, &tabPage);
+
+ if (ToolStatusInterface)
+ {
+ PTOOLSTATUS_TAB_INFO tabInfo;
+
+ tabInfo = ToolStatusInterface->RegisterTabInfo(addedTabPage->Index);
+ tabInfo->BannerText = L"Search Firewall";
+ tabInfo->ActivateContent = FwToolStatusActivateContent;
+ tabInfo->GetTreeNewHandle = FwToolStatusGetTreeNewHandle;
+ }
+}
+
+HWND NTAPI FwTabCreateFunction(
+ _In_ PVOID Context
+ )
+{
+ HWND hwnd;
+
+ if (FwEnabled)
+ {
+ ULONG thinRows;
+
+ thinRows = PhGetIntegerSetting(L"ThinRows") ? TN_STYLE_THIN_ROWS : 0;
+ hwnd = CreateWindow(
+ PH_TREENEW_CLASSNAME,
+ NULL,
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_BORDER | TN_STYLE_ICONS | TN_STYLE_DOUBLE_BUFFERED | thinRows,
+ 0,
+ 0,
+ 3,
+ 3,
+ PhMainWndHandle,
+ NULL,
+ NULL,
+ NULL
+ );
+ }
+ else
+ {
+ return CreateDialog(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_FWTABERROR),
+ PhMainWndHandle,
+ FwTabErrorDialogProc
+ );
+ }
+
+ FwTreeNewCreated = TRUE;
+
+ 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 = (PPH_FILE_STREAM)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);
+}
+
+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);
+
+ PhAddTreeNewColumn(hwnd, FWTNC_PROCESSBASENAME, TRUE, L"Name", 100, PH_ALIGN_LEFT, MAXINT, DT_PATH_ELLIPSIS);
+ PhAddTreeNewColumn(hwnd, FWTNC_PROCESSFILENAME, FALSE, L"File Path", 80, PH_ALIGN_LEFT, MAXINT, DT_PATH_ELLIPSIS);
+ PhAddTreeNewColumn(hwnd, FWTNC_DIRECTION, TRUE, L"Direction", 40, PH_ALIGN_LEFT, MAXINT, 0);
+ PhAddTreeNewColumn(hwnd, FWTNC_ACTION, TRUE, L"Action", 70, PH_ALIGN_LEFT, MAXINT, 0);
+ PhAddTreeNewColumn(hwnd, FWTNC_PROTOCOL, TRUE, L"Protocol", 60, PH_ALIGN_LEFT, MAXINT, 0);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_LOCALADDRESS, TRUE, L"Local Address", 220, PH_ALIGN_RIGHT, MAXINT, DT_RIGHT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_LOCALPORT, TRUE, L"Local Port", 50, PH_ALIGN_LEFT, MAXINT, DT_LEFT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_REMOTEADDRESS, TRUE, L"Remote Address", 220, PH_ALIGN_RIGHT, MAXINT, DT_RIGHT, TRUE);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_REMOTEPORT, TRUE, L"Remote Port", 50, PH_ALIGN_LEFT, MAXINT, DT_LEFT, TRUE);
+ PhAddTreeNewColumn(hwnd, FWTNC_USER, FALSE, L"User", 120, PH_ALIGN_LEFT, MAXINT, DT_PATH_ELLIPSIS);
+ PhAddTreeNewColumnEx(hwnd, FWTNC_TIME, TRUE, L"Time", 30, PH_ALIGN_LEFT, MAXINT, 0, TRUE);
+ PhAddTreeNewColumn(hwnd, FWTNC_RULENAME, TRUE, L"Rule", 200, PH_ALIGN_LEFT, MAXINT, 0);
+ PhAddTreeNewColumn(hwnd, FWTNC_RULEDESCRIPTION, TRUE, L"Description", 180, PH_ALIGN_LEFT, 12, 0);
+ PhAddTreeNewColumn(hwnd, FWTNC_INDEX, TRUE, L"Index", 180, PH_ALIGN_LEFT, 12, 0);
+
+ TreeNew_SetRedraw(hwnd, TRUE);
+ TreeNew_SetSort(hwnd, FWTNC_INDEX, DescendingSortOrder);
+
+ LoadSettingsFwTreeList();
+
+ PhInitializeTreeNewFilterSupport(&FilterSupport, hwnd, FwNodeList);
+
+ if (ToolStatusInterface)
+ {
+ PhRegisterCallback(ToolStatusInterface->SearchChangedEvent, FwSearchChangedHandler, NULL, &SearchChangedRegistration);
+ PhAddTreeNewFilter(&FilterSupport, FwSearchFilterCallback, NULL);
+ }
+}
+
+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;
+
+ PhAcquireQueuedLockExclusive(&FwLock);
+ PhAddItemList(FwNodeList, FwNode);
+ PhReleaseQueuedLockExclusive(&FwLock);
+
+ if (FilterSupport.NodeList)
+ FwNode->Node.Visible = PhApplyTreeNewFiltersToNode(&FilterSupport, &FwNode->Node);
+
+ TreeNew_NodesStructured(FwTreeNewHandle);
+
+ return FwNode;
+}
+
+VOID RemoveFwNode(
+ _In_ PFW_EVENT_NODE FwNode
+ )
+{
+ ULONG index;
+
+ PhAcquireQueuedLockExclusive(&FwLock);
+
+ // Remove from the hashtable/list and cleanup.
+ if ((index = PhFindItemList(FwNodeList, FwNode)) != -1)
+ PhRemoveItemList(FwNodeList, index);
+
+ PhReleaseQueuedLockExclusive(&FwLock);
+
+ if (FwNode->TooltipText)
+ PhDereferenceObject(FwNode->TooltipText);
+
+ if (FwNode->EventItem->TimeString)
+ PhDereferenceObject(FwNode->EventItem->TimeString);
+ if (FwNode->EventItem->UserNameString)
+ PhDereferenceObject(FwNode->EventItem->UserNameString);
+ if (FwNode->EventItem->ProcessNameString)
+ PhDereferenceObject(FwNode->EventItem->ProcessNameString);
+ if (FwNode->EventItem->ProcessBaseString)
+ PhDereferenceObject(FwNode->EventItem->ProcessBaseString);
+ if (FwNode->EventItem->LocalPortString)
+ PhDereferenceObject(FwNode->EventItem->LocalPortString);
+ if (FwNode->EventItem->LocalAddressString)
+ PhDereferenceObject(FwNode->EventItem->LocalAddressString);
+ if (FwNode->EventItem->RemotePortString)
+ PhDereferenceObject(FwNode->EventItem->RemotePortString);
+ if (FwNode->EventItem->RemoteAddressString)
+ PhDereferenceObject(FwNode->EventItem->RemoteAddressString);
+ if (FwNode->EventItem->FwRuleNameString)
+ PhDereferenceObject(FwNode->EventItem->FwRuleNameString);
+ if (FwNode->EventItem->FwRuleDescriptionString)
+ PhDereferenceObject(FwNode->EventItem->FwRuleDescriptionString);
+ if (FwNode->EventItem->FwRuleLayerNameString)
+ PhDereferenceObject(FwNode->EventItem->FwRuleLayerNameString);
+ if (FwNode->EventItem->FwRuleLayerDescriptionString)
+ PhDereferenceObject(FwNode->EventItem->FwRuleLayerDescriptionString);
+
+ if (FwNode->EventItem->IndexString)
+ PhDereferenceObject(FwNode->EventItem->IndexString);
+
+ //if (FwNode->EventItem->Icon)
+ // DestroyIcon(FwNode->EventItem->Icon);
+
+ 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 = uintcmp(fwItem1->Index, fwItem2->Index); \
+ \
+ return PhModifySort(sortResult, FwTreeNewSortOrder); \
+}
+
+BEGIN_SORT_FUNCTION(Name)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->ProcessBaseString, fwItem2->ProcessBaseString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(FilePath)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->ProcessNameString, fwItem2->ProcessNameString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Direction)
+{
+ sortResult = PhCompareStringRef(&fwItem1->DirectionString, &fwItem2->DirectionString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Action)
+{
+ sortResult = PhCompareStringRef(&fwItem1->FwRuleActionString, &fwItem2->FwRuleActionString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Protocol)
+{
+ sortResult = PhCompareStringRef(&fwItem1->ProtocalString, &fwItem2->ProtocalString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(LocalAddress)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->LocalAddressString, fwItem2->LocalAddressString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(LocalPort)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->LocalPortString, fwItem2->LocalPortString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(RemoteAddress)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->RemoteAddressString, fwItem2->RemoteAddressString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(RemotePort)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->RemotePortString, fwItem2->RemotePortString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(User)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->UserNameString, fwItem2->UserNameString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Time)
+{
+ sortResult = uint64cmp(fwItem1->AddedTime.QuadPart, fwItem2->AddedTime.QuadPart);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Rule)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->FwRuleNameString, fwItem2->FwRuleNameString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Description)
+{
+ sortResult = PhCompareStringWithNull(fwItem1->FwRuleDescriptionString, fwItem2->FwRuleDescriptionString, TRUE);
+}
+END_SORT_FUNCTION
+
+BEGIN_SORT_FUNCTION(Index)
+{
+ sortResult = uintcmp(fwItem1->Index, fwItem2->Index);
+}
+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(Name),
+ SORT_FUNCTION(FilePath),
+ SORT_FUNCTION(Direction),
+ SORT_FUNCTION(Action),
+ SORT_FUNCTION(Protocol),
+ SORT_FUNCTION(LocalAddress),
+ SORT_FUNCTION(LocalPort),
+ SORT_FUNCTION(RemoteAddress),
+ SORT_FUNCTION(RemotePort),
+ SORT_FUNCTION(User),
+ SORT_FUNCTION(Time),
+ SORT_FUNCTION(Rule),
+ SORT_FUNCTION(Description),
+ SORT_FUNCTION(Index)
+ };
+ 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 = (PPH_TREENEW_IS_LEAF)Parameter1;
+
+ isLeaf->IsLeaf = TRUE;
+ }
+ return TRUE;
+ case TreeNewGetCellText:
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = (PPH_TREENEW_GET_CELL_TEXT)Parameter1;
+ PFW_EVENT_ITEM fwItem;
+
+ node = (PFW_EVENT_NODE)getCellText->Node;
+ fwItem = node->EventItem;
+
+ switch (getCellText->Id)
+ {
+ case FWTNC_TIME:
+ getCellText->Text = PhGetStringRef(node->EventItem->TimeString);
+ break;
+ case FWTNC_ACTION:
+ getCellText->Text = node->EventItem->FwRuleActionString;
+ break;
+ case FWTNC_RULENAME:
+ getCellText->Text = PhGetStringRef(node->EventItem->FwRuleNameString);
+ break;
+ case FWTNC_RULEDESCRIPTION:
+ getCellText->Text = PhGetStringRef(node->EventItem->FwRuleDescriptionString);
+ break;
+ case FWTNC_PROCESSBASENAME:
+ getCellText->Text = PhGetStringRef(node->EventItem->ProcessBaseString);
+ break;
+ case FWTNC_PROCESSFILENAME:
+ getCellText->Text = PhGetStringRef(node->EventItem->ProcessNameString);
+ break;
+ case FWTNC_USER:
+ getCellText->Text = PhGetStringRef(node->EventItem->UserNameString);
+ break;
+ case FWTNC_LOCALADDRESS:
+ getCellText->Text = PhGetStringRef(node->EventItem->LocalAddressString);
+ break;
+ case FWTNC_LOCALPORT:
+ getCellText->Text = PhGetStringRef(node->EventItem->LocalPortString);
+ break;
+ case FWTNC_REMOTEADDRESS:
+ getCellText->Text = PhGetStringRef(node->EventItem->RemoteAddressString);
+ break;
+ case FWTNC_REMOTEPORT:
+ getCellText->Text = PhGetStringRef(node->EventItem->RemotePortString);
+ break;
+ case FWTNC_PROTOCOL:
+ getCellText->Text = node->EventItem->ProtocalString;
+ break;
+ case FWTNC_DIRECTION:
+ getCellText->Text = node->EventItem->DirectionString;
+ break;
+ case FWTNC_INDEX:
+ getCellText->Text = PhGetStringRef(node->EventItem->IndexString);
+ break;
+ default:
+ return FALSE;
+ }
+
+ getCellText->Flags = TN_CACHE;
+ }
+ return TRUE;
+ //case TreeNewGetNodeIcon:
+ // {
+ // PPH_TREENEW_GET_NODE_ICON getNodeIcon = (PPH_TREENEW_GET_NODE_ICON)Parameter1;
+ // node = (PFW_EVENT_NODE)getNodeIcon->Node;
+ //
+ // if (node->EventItem->Icon)
+ // {
+ // getNodeIcon->Icon = node->EventItem->Icon;
+ // }
+ // else
+ // {
+ // PhGetStockApplicationIcon(&getNodeIcon->Icon, NULL);
+ // }
+ //
+ // getNodeIcon->Flags = TN_CACHE;
+ // }
+ // return TRUE;
+ case TreeNewGetCellTooltip:
+ {
+ PPH_TREENEW_GET_CELL_TOOLTIP getCellTooltip = (PPH_TREENEW_GET_CELL_TOOLTIP)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_ALIGN_LEFT | PH_ALIGN_TOP, data.MouseEvent->ScreenLocation.x, data.MouseEvent->ScreenLocation.y);
+ PhHandleTreeNewColumnMenu(&data);
+ PhDeleteTreeNewColumnMenu(&data);
+ }
+ return TRUE;
+ case TreeNewLeftDoubleClick:
+ {
+ PPH_TREENEW_MOUSE_EVENT mouseEvent = (PPH_TREENEW_MOUSE_EVENT)Parameter1;
+ node = (PFW_EVENT_NODE)mouseEvent->Node;
+
+ //PhCreateThread(0, ShowFwRuleProperties, node);
+ }
+ return TRUE;
+ case TreeNewContextMenu:
+ {
+ PPH_TREENEW_MOUSE_EVENT mouseEvent = (PPH_TREENEW_MOUSE_EVENT)Parameter1;
+
+ ShowFwContextMenu(mouseEvent->Location);
+ }
+ return TRUE;
+ case TreeNewDestroying:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+PFW_EVENT_NODE GetSelectedFwItem(
+ VOID
+ )
+{
+ PFW_EVENT_NODE FwItem = NULL;
+
+ for (ULONG i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = (PFW_EVENT_NODE)FwNodeList->Items[i];
+
+ if (node->Node.Selected)
+ {
+ FwItem = node;
+ break;
+ }
+ }
+
+ return FwItem;
+}
+
+VOID GetSelectedFwItems(
+ _Out_ PFW_EVENT_NODE **FwItems,
+ _Out_ PULONG NumberOfFwItems
+ )
+{
+ PPH_LIST list = PhCreateList(2);
+
+ for (ULONG i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = (PFW_EVENT_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);
+ PhSetClipboardString(FwTreeNewHandle, &text->sr);
+ PhDereferenceObject(text);
+}
+
+VOID WriteFwList(
+ __inout PPH_FILE_STREAM FileStream,
+ _In_ ULONG Mode
+ )
+{
+ PPH_LIST lines = PhGetGenericTreeNewLines(FwTreeNewHandle, Mode);
+
+ for (ULONG i = 0; i < lines->Count; i++)
+ {
+ PPH_STRING line;
+
+ line = lines->Items[i];
+
+ PhWriteStringAsUtf8FileStream(FileStream, &line->sr);
+ PhDereferenceObject(line);
+ PhWriteStringAsUtf8FileStream2(FileStream, L"\r\n");
+ }
+
+ PhDereferenceObject(lines);
+}
+
+VOID HandleFwCommand(
+ _In_ ULONG Id
+ )
+{
+ switch (Id)
+ {
+ case ID_FW_PROPERTIES:
+ {
+ PFW_EVENT_NODE fwItem = GetSelectedFwItem();
+ //PhCreateThread(0, ShowFwRuleProperties, fwItem);
+ }
+ break;
+ }
+}
+
+VOID InitializeFwMenu(
+ _In_ PPH_EMENU Menu,
+ _In_ PFW_EVENT_NODE* 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_NODE* 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 = (PFW_EVENT_ITEM)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_NODE fwNode = (PFW_EVENT_NODE)Parameter;
+
+ UpdateFwNode(fwNode);
+}
+
+static VOID NTAPI OnFwItemRemoved(
+ _In_ PVOID Parameter
+ )
+{
+ PFW_EVENT_NODE fwNode = (PFW_EVENT_NODE)Parameter;
+
+ if (!FwNeedsRedraw)
+ {
+ TreeNew_SetRedraw(FwTreeNewHandle, FALSE);
+ FwNeedsRedraw = TRUE;
+ }
+
+ RemoveFwNode(fwNode);
+}
+
+static VOID NTAPI OnFwItemsUpdated(
+ _In_ PVOID Parameter
+ )
+{
+ if (FwNeedsRedraw)
+ {
+ TreeNew_SetRedraw(FwTreeNewHandle, TRUE);
+ FwNeedsRedraw = FALSE;
+ }
+
+ // Text invalidation
+ for (ULONG i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = (PFW_EVENT_NODE)FwNodeList->Items[i];
+
+ // The name and file name never change, so we don't invalidate that.
+ memset(&node->TextCache[1], 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);
+}
+
+VOID NTAPI FwSearchChangedHandler(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ if (!FwEnabled)
+ return;
+
+ PhApplyTreeNewFilters(&FilterSupport);
+}
+
+BOOLEAN NTAPI FwSearchFilterCallback(
+ _In_ PPH_TREENEW_NODE Node,
+ _In_opt_ PVOID Context
+ )
+{
+ PFW_EVENT_NODE fwNode = (PFW_EVENT_NODE)Node;
+ PTOOLSTATUS_WORD_MATCH wordMatch = ToolStatusInterface->WordMatch;
+
+ if (PhIsNullOrEmptyString(ToolStatusInterface->GetSearchboxText()))
+ return TRUE;
+
+ if (wordMatch(&fwNode->EventItem->ProcessNameString->sr))
+ return TRUE;
+
+ if (wordMatch(&fwNode->EventItem->LocalAddressString->sr))
+ return TRUE;
+
+ if (wordMatch(&fwNode->EventItem->RemoteAddressString->sr))
+ return TRUE;
+
+ return FALSE;
+}
+
+VOID NTAPI FwToolStatusActivateContent(
+ _In_ BOOLEAN Select
+ )
+{
+ SetFocus(FwTreeNewHandle);
+
+ if (Select)
+ {
+ if (TreeNew_GetFlatNodeCount(FwTreeNewHandle) > 0)
+ SelectAndEnsureVisibleFwNode((PFW_EVENT_NODE)TreeNew_GetFlatNode(FwTreeNewHandle, 0));
+ }
+}
+
+HWND NTAPI FwToolStatusGetTreeNewHandle(
+ VOID
+ )
+{
+ return FwTreeNewHandle;
+}
+
+INT_PTR CALLBACK FwTabErrorDialogProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ SendMessage(GetDlgItem(hwndDlg, IDC_RESTART), BCM_SETSHIELD, 0, TRUE);
+ }
+ else
+ {
+ //SetDlgItemText(hwndDlg, IDC_ERROR, L"Unable to start the kernel event tracing session.");
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), SW_HIDE);
+ }
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_RESTART:
+ ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle);
+
+ if (PhShellProcessHacker(
+ PhMainWndHandle,
+ L"-v -selecttab Firewall",
+ SW_SHOW,
+ PH_SHELL_EXECUTE_ADMIN,
+ PH_SHELL_APP_PROPAGATE_PARAMETERS | PH_SHELL_APP_PROPAGATE_PARAMETERS_IGNORE_VISIBILITY,
+ 0,
+ NULL
+ ))
+ {
+ ProcessHacker_Destroy(PhMainWndHandle);
+ }
+ else
+ {
+ ProcessHacker_CancelEarlyShutdown(PhMainWndHandle);
+ }
+
+ break;
+ }
+ }
+ break;
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORSTATIC:
+ {
+ SetBkMode((HDC)wParam, TRANSPARENT);
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
+ }
+ break;
+ }
+
+ return FALSE;
+}
diff --git a/plugins-extra/FirewallMonitorPlugin/fwtabp.h b/plugins-extra/FirewallMonitorPlugin/fwtabp.h
new file mode 100644
index 0000000..ea71e4c
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/fwtabp.h
@@ -0,0 +1,156 @@
+#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
+ );
+
+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_NODE GetSelectedFwItem(
+ VOID
+ );
+
+VOID GetSelectedFwItems(
+ _Out_ PFW_EVENT_NODE **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_NODE *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
+ );
+
+BOOLEAN NTAPI FwSearchFilterCallback(
+ _In_ PPH_TREENEW_NODE Node,
+ _In_opt_ PVOID Context
+ );
+
+VOID NTAPI FwSearchChangedHandler(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ );
+
+VOID NTAPI FwToolStatusActivateContent(
+ _In_ BOOLEAN Select
+ );
+
+HWND NTAPI FwToolStatusGetTreeNewHandle(
+ VOID
+ );
+
+#endif
diff --git a/plugins-extra/FirewallMonitorPlugin/main.c b/plugins-extra/FirewallMonitorPlugin/main.c
new file mode 100644
index 0000000..27d072f
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/main.c
@@ -0,0 +1,122 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firewall Monitor
+ *
+ * Copyright (C) 2015 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"
+
+PPH_PLUGIN PluginInstance;
+static PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+static PH_CALLBACK_REGISTRATION MainWindowShowingCallbackRegistration;
+
+static VOID NTAPI LoadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ FwEnabled = StartFwMonitor();
+}
+
+static VOID NTAPI UnloadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ StopFwMonitor();
+ SaveSettingsFwTreeList();
+}
+
+static VOID NTAPI ShowOptionsCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ NOTHING;
+}
+
+static VOID NTAPI MainWindowShowingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ InitializeFwTab();
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { StringSettingType, SETTING_NAME_FW_TREE_LIST_COLUMNS, L"" },
+ { IntegerPairSettingType, SETTING_NAME_FW_TREE_LIST_SORT, L"0,2" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Firewall Monitor";
+ info->Author = L"dmex";
+ info->Description = L"Adds a new tab for monitoring kernel/process 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
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/plugins-extra/FirewallMonitorPlugin/monitor.c b/plugins-extra/FirewallMonitorPlugin/monitor.c
new file mode 100644
index 0000000..8878c74
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/monitor.c
@@ -0,0 +1,788 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firewall Monitor
+ *
+ * Copyright (C) 2015 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"
+
+#define FWP_DIRECTION_IN 0x00003900L
+#define FWP_DIRECTION_OUT 0x00003901L
+#define FWP_DIRECTION_FORWARD 0x00003902L
+
+PH_CALLBACK_DECLARE(FwItemAddedEvent);
+PH_CALLBACK_DECLARE(FwItemModifiedEvent);
+PH_CALLBACK_DECLARE(FwItemRemovedEvent);
+PH_CALLBACK_DECLARE(FwItemsUpdatedEvent);
+
+static PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
+static PPH_OBJECT_TYPE FwObjectType = NULL;
+static HANDLE FwEngineHandle = NULL;
+static HANDLE FwEventHandle = NULL;
+static HANDLE FwEnumHandle = NULL;
+static _FwpmNetEventSubscribe1 FwpmNetEventSubscribe1_I = NULL;
+
+static VOID NTAPI FwObjectTypeDeleteProcedure(
+ _In_ PVOID Object,
+ _In_ ULONG Flags
+ )
+{
+ PhClearReference(&Object);
+}
+
+PFW_EVENT_ITEM EtCreateFirewallEntryItem(
+ VOID
+ )
+{
+ static ULONG itemCount = 0;
+ PFW_EVENT_ITEM diskItem;
+
+ diskItem = PhCreateObject(sizeof(FW_EVENT_ITEM), FwObjectType);
+ memset(diskItem, 0, sizeof(FW_EVENT_ITEM));
+
+ diskItem->Index = itemCount;
+ diskItem->IndexString = PhFormatString(L"%lu", itemCount);
+ itemCount++;
+
+ return diskItem;
+}
+
+static VOID CALLBACK DropEventCallback(
+ _Inout_ PVOID FwContext,
+ _In_ const FWPM_NET_EVENT* FwEvent
+ )
+{
+ PFW_EVENT_ITEM fwEventItem = EtCreateFirewallEntryItem();
+ SYSTEMTIME systemTime;
+
+ PhQuerySystemTime(&fwEventItem->AddedTime);
+ PhLargeIntegerToLocalSystemTime(&systemTime, &fwEventItem->AddedTime);
+ fwEventItem->TimeString = PhFormatDateTime(&systemTime);
+
+ switch (FwEvent->type)
+ {
+ case FWPM_NET_EVENT_TYPE_CLASSIFY_DROP:
+ {
+ FWPM_FILTER* fwFilterItem = NULL;
+ FWPM_LAYER* fwLayerItem = NULL;
+ FWPM_NET_EVENT_CLASSIFY_DROP* fwDropEvent = FwEvent->classifyDrop;
+
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"DROP");
+
+ if (FwpmFilterGetById(FwEngineHandle, fwDropEvent->filterId, &fwFilterItem) == ERROR_SUCCESS)
+ {
+ if (fwFilterItem->displayData.name)
+ {
+ fwEventItem->FwRuleNameString = PhCreateString(fwFilterItem->displayData.name);
+ }
+
+ if (fwFilterItem->displayData.description)
+ {
+ fwEventItem->FwRuleDescriptionString = PhCreateString(fwFilterItem->displayData.description);
+ }
+
+ if ((fwFilterItem->action.type & FWP_ACTION_BLOCK) != 0)
+ {
+
+ }
+
+ FwpmFreeMemory(&fwFilterItem);
+ }
+
+ if (FwpmLayerGetById(FwEngineHandle, fwDropEvent->layerId, &fwLayerItem) == ERROR_SUCCESS)
+ {
+ if (fwLayerItem->displayData.name)
+ {
+ fwEventItem->FwRuleLayerNameString = PhCreateString(fwLayerItem->displayData.name);
+ }
+
+ //fwEventItem->FwRuleLayerDescriptionString = PhCreateString(fwLayerRuleItem->displayData.description);
+
+ for (UINT32 i = 0; i < fwLayerItem->numFields; i++)
+ {
+ FWPM_FIELD fwRuleField = fwLayerItem->field[i];
+
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa363996.aspx
+
+ if (memcmp(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_APP_ID, sizeof(GUID)) == 0)
+ {
+ //The fully qualified device path of the application, as returned by the FwpmGetAppIdFromFileName0 function.
+ // (For example, "\device0\hardiskvolume1\Program Files\Application.exe".)
+ // Data type : FWP_BYTE_BLOB_TYPE
+
+ //fwDropEvent->
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_ORIGINAL_APP_ID))
+ {
+ // The fully qualified device path of the application, such as "\device0\hardiskvolume1\Program Files\Application.exe".
+ // When a connection has been redirected, this will be the identifier of the originating app,
+ // otherwise this will be the same as FWPM_CONDITION_ALE_APP_ID.
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_USER_ID))
+ {
+ //The identification of the local user.
+ //Data type : FWP_SECURITY_DESCRIPTOR_TYPE
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS))
+ {
+
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS_TYPE))
+ {
+ //The local IP address type.
+ //Possible values : Any of the following NL_ADDRESS_TYPE enumeration values.
+ //NlatUnspecified
+ //NlatUnicast
+ //NlatAnycast
+ //NlatMulticast
+ //NlatBroadcast
+ //Data type : FWP_UINT8
+
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_PORT))
+ {
+ //The local transport protocol port number.
+ //Data type : FWP_UINT16
+
+ }
+ //else
+ //{
+ // PhInitializeStringRef(&fwEventItem->FwRuleModeString, L"UNKNOWN");
+ //}
+ }
+
+ FwpmFreeMemory(&fwLayerItem);
+ }
+
+ if (fwDropEvent->isLoopback)
+ {
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Loopback");
+ }
+ else
+ {
+ switch (fwDropEvent->msFwpDirection)
+ {
+ case FWP_DIRECTION_IN:
+ case FWP_DIRECTION_INBOUND:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"In");
+ break;
+ case FWP_DIRECTION_OUT:
+ case FWP_DIRECTION_OUTBOUND:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Out");
+ break;
+ case FWP_DIRECTION_FORWARD:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Forward");
+ break;
+ default:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"");
+ break;
+ }
+ }
+ }
+ break;
+ case FWPM_NET_EVENT_TYPE_CLASSIFY_ALLOW:
+ {
+ FWPM_FILTER* fwFilterItem = NULL;
+ FWPM_LAYER* fwLayerItem = NULL;
+ FWPM_NET_EVENT_CLASSIFY_ALLOW* fwAllowEvent = FwEvent->classifyAllow;
+
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"ALLOW");
+
+ if (FwpmFilterGetById(FwEngineHandle, fwAllowEvent->filterId, &fwFilterItem) == ERROR_SUCCESS)
+ {
+ if (fwFilterItem->displayData.name)
+ {
+ fwEventItem->FwRuleNameString = PhCreateString(fwFilterItem->displayData.name);
+ }
+
+ if (fwFilterItem->displayData.description)
+ {
+ fwEventItem->FwRuleDescriptionString = PhCreateString(fwFilterItem->displayData.description);
+ }
+
+ if ((fwFilterItem->action.type & FWP_ACTION_BLOCK) != 0)
+ {
+
+ }
+
+ FwpmFreeMemory(&fwFilterItem);
+ }
+
+ if (FwpmLayerGetById(FwEngineHandle, fwAllowEvent->layerId, &fwLayerItem) == ERROR_SUCCESS)
+ {
+ for (UINT32 i = 0; i < fwLayerItem->numFields; i++)
+ {
+ FWPM_FIELD fwRuleField = fwLayerItem->field[i];
+
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa363996.aspx
+
+ if (memcmp(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_APP_ID, sizeof(GUID)) == 0)
+ {
+ //The fully qualified device path of the application, as returned by the FwpmGetAppIdFromFileName0 function.
+ // (For example, "\device0\hardiskvolume1\Program Files\Application.exe".)
+ // Data type : FWP_BYTE_BLOB_TYPE
+
+ //fwAllowEvent->
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_ORIGINAL_APP_ID))
+ {
+ // The fully qualified device path of the application, such as "\device0\hardiskvolume1\Program Files\Application.exe".
+ // When a connection has been redirected, this will be the identifier of the originating app,
+ // otherwise this will be the same as FWPM_CONDITION_ALE_APP_ID.
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_ALE_USER_ID))
+ {
+ //The identification of the local user.
+ //Data type : FWP_SECURITY_DESCRIPTOR_TYPE
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS))
+ {
+
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_ADDRESS_TYPE))
+ {
+ //The local IP address type.
+ //Possible values : Any of the following NL_ADDRESS_TYPE enumeration values.
+ //NlatUnspecified
+ //NlatUnicast
+ //NlatAnycast
+ //NlatMulticast
+ //NlatBroadcast
+ //Data type : FWP_UINT8
+
+ }
+ else if (IsEqualGUID(fwRuleField.fieldKey, &FWPM_CONDITION_IP_LOCAL_PORT))
+ {
+ //The local transport protocol port number.
+ //Data type : FWP_UINT16
+
+ }
+ //else
+ //{
+ // PhInitializeStringRef(&fwEventItem->FwRuleModeString, L"UNKNOWN");
+ //}
+ }
+
+ fwEventItem->FwRuleLayerNameString = PhCreateString(fwLayerItem->displayData.name);
+ //fwEventItem->FwRuleLayerDescriptionString = PhCreateString(fwLayerRuleItem->displayData.description);
+
+ FwpmFreeMemory(&fwLayerItem);
+ }
+
+ if (fwAllowEvent->isLoopback)
+ {
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Loopback");
+ }
+ else
+ {
+ switch (fwAllowEvent->msFwpDirection)
+ {
+ case FWP_DIRECTION_IN:
+ case FWP_DIRECTION_INBOUND:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"In");
+ break;
+ case FWP_DIRECTION_OUT:
+ case FWP_DIRECTION_OUTBOUND:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Out");
+ break;
+ case FWP_DIRECTION_FORWARD:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"Forward");
+ break;
+ default:
+ PhInitializeStringRef(&fwEventItem->DirectionString, L"");
+ break;
+ }
+ }
+ }
+ break;
+ case FWPM_NET_EVENT_TYPE_CAPABILITY_DROP:
+ //FWPM_NET_EVENT_CAPABILITY_DROP* fwCapDropEvent = FwEvent->capabilityDrop;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CAPABILITY_DROP");
+ return;
+ case FWPM_NET_EVENT_TYPE_CAPABILITY_ALLOW:
+ //FWPM_NET_EVENT_CAPABILITY_ALLOW* fwCapAllowEvent = FwEvent->capabilityAllow;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CAPABILITY_ALLOW");
+ return;
+ case FWPM_NET_EVENT_TYPE_CLASSIFY_DROP_MAC:
+ //FWPM_NET_EVENT_CLASSIFY_DROP_MAC* fwMacDropEvent = FwEvent->classifyDropMac;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"CLASSIFY_DROP_MAC");
+ break;
+ case FWPM_NET_EVENT_TYPE_IPSEC_KERNEL_DROP:
+ //FWPM_NET_EVENT_IPSEC_KERNEL_DROP* fwIpSecDropEvent = FwEvent->ipsecDrop;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IPSEC_KERNEL_DROP");
+ break;
+ case FWPM_NET_EVENT_TYPE_IPSEC_DOSP_DROP:
+ //FWPM_NET_EVENT_IPSEC_DOSP_DROP* fwIpSecDoSDropEvent = FwEvent->idpDrop;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IPSEC_DOSP_DROP");
+ break;
+ case FWPM_NET_EVENT_TYPE_IKEEXT_MM_FAILURE:
+ //FWPM_NET_EVENT_IKEEXT_MM_FAILURE* fwIkeextMMFailureEvent = FwEvent->ikeMmFailure;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"IKEEXT_MM_FAILURE");
+ break;
+ case FWPM_NET_EVENT_TYPE_IKEEXT_QM_FAILURE:
+ //FWPM_NET_EVENT_IKEEXT_QM_FAILURE* fwIkeextQMFailureEvent = FwEvent->ikeQmFailure;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"QM_FAILURE");
+ break;
+ case FWPM_NET_EVENT_TYPE_IKEEXT_EM_FAILURE:
+ //FWPM_NET_EVENT_IKEEXT_EM_FAILURE* fwIkeextEMFailureEvent = FwEvent->ikeEmFailure;
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"EM_FAILURE");
+ break;
+ default:
+ PhInitializeStringRef(&fwEventItem->FwRuleActionString, L"unknown");
+ break;
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_PORT_SET) != 0)
+ {
+ fwEventItem->LocalPort = FwEvent->header.localPort;
+ fwEventItem->LocalPortString = PhFormatString(L"%u", FwEvent->header.localPort);
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_PORT_SET) != 0)
+ {
+ fwEventItem->RemotePort = FwEvent->header.remotePort;
+ fwEventItem->RemotePortString = PhFormatString(L"%u", FwEvent->header.remotePort);
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_IP_VERSION_SET) != 0)
+ {
+ if (FwEvent->header.ipVersion == FWP_IP_VERSION_V4)
+ {
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET) != 0)
+ {
+ //IN_ADDR ipv4Address = { 0 };
+ //PWSTR ipv4StringTerminator = 0;
+ //WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
+ //
+ //ULONG localAddrV4 = _byteswap_ulong(FwEvent->header.localAddrV4);
+ //
+ //RtlIpv4AddressToString((PIN_ADDR)&localAddrV4, ipv4AddressString);
+ //RtlIpv4StringToAddress(ipv4AddressString, TRUE, &ipv4StringTerminator, &ipv4Address);
+ //
+ //fwEventItem->LocalAddressString = PhFormatString(L"%s", ipv4AddressString);
+
+ fwEventItem->LocalAddressString = PhFormatString(
+ L"%lu.%lu.%lu.%lu",
+ ((PBYTE)&FwEvent->header.localAddrV4)[3],
+ ((PBYTE)&FwEvent->header.localAddrV4)[2],
+ ((PBYTE)&FwEvent->header.localAddrV4)[1],
+ ((PBYTE)&FwEvent->header.localAddrV4)[0]
+ );
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET) != 0)
+ {
+ //IN_ADDR ipv4Address = { 0 };
+ //PWSTR ipv4StringTerminator = 0;
+ //WCHAR ipv4AddressString[INET_ADDRSTRLEN] = L"";
+ //
+ //ULONG remoteAddrV4 = _byteswap_ulong(FwEvent->header.remoteAddrV4);
+ //
+ //RtlIpv4AddressToString((PIN_ADDR)&remoteAddrV4, ipv4AddressString);
+ //RtlIpv4StringToAddress(ipv4AddressString, TRUE, &ipv4StringTerminator, &ipv4Address);
+ //
+ //fwEventItem->RemoteAddressString = PhFormatString(L"%s", ipv4AddressString);
+
+ fwEventItem->RemoteAddressString = PhFormatString(
+ L"%lu.%lu.%lu.%lu",
+ ((PBYTE)&FwEvent->header.remoteAddrV4)[3],
+ ((PBYTE)&FwEvent->header.remoteAddrV4)[2],
+ ((PBYTE)&FwEvent->header.remoteAddrV4)[1],
+ ((PBYTE)&FwEvent->header.remoteAddrV4)[0]
+ );
+ }
+ }
+ else if (FwEvent->header.ipVersion == FWP_IP_VERSION_V6)
+ {
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET) != 0)
+ {
+ IN6_ADDR ipv6Address = { 0 };
+ PWSTR ipv6StringTerminator = 0;
+ WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
+
+ RtlIpv6AddressToString((struct in6_addr*)&FwEvent->header.localAddrV6, ipv6AddressString);
+ RtlIpv6StringToAddress(ipv6AddressString, &ipv6StringTerminator, &ipv6Address);
+
+ fwEventItem->LocalAddressString = PhFormatString(L"%s", ipv6AddressString);
+
+ //fwEventItem->LocalAddressString = PhFormatString(
+ // L"%x:%x:%x:%x%x:%x:%x:%x",
+ // ((WORD*)&FwEvent->header.localAddrV6)[7],
+ // ((WORD*)&FwEvent->header.localAddrV6)[6],
+ // ((WORD*)&FwEvent->header.localAddrV6)[5],
+ // ((WORD*)&FwEvent->header.localAddrV6)[4],
+ // ((WORD*)&FwEvent->header.localAddrV6)[3],
+ // ((WORD*)&FwEvent->header.localAddrV6)[2],
+ // ((WORD*)&FwEvent->header.localAddrV6)[1],
+ // ((WORD*)&FwEvent->header.localAddrV6)[0]
+ // );
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET) != 0)
+ {
+ WCHAR ipv6AddressString[INET6_ADDRSTRLEN] = L"";
+ PWSTR ipv6StringTerminator = 0;
+ IN6_ADDR ipv6Address = { 0 };
+
+ RtlIpv6AddressToString((struct in6_addr*)&FwEvent->header.remoteAddrV6, ipv6AddressString);
+ RtlIpv6StringToAddress(ipv6AddressString, &ipv6StringTerminator, &ipv6Address);
+
+ fwEventItem->RemoteAddressString = PhFormatString(L"%s", ipv6AddressString);
+
+ //fwEventItem->RemoteAddressString = PhFormatString(
+ // L"%x:%x:%x:%x%x:%x:%x:%x",
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[7],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[6],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[5],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[4],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[3],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[2],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[1],
+ // ((WORD*)&FwEvent->header.remoteAddrV6)[0]
+ // );
+ }
+ }
+ else
+ {
+ //FwEvent->header.addressFamily Available when ipVersion is FWP_IP_VERSION_NONE.
+ }
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_APP_ID_SET) != 0)
+ {
+ PPH_STRING fileName = NULL;
+ PPH_STRING resolvedName = NULL;
+
+ if (FwEvent->header.appId.data && FwEvent->header.appId.size > 0)
+ {
+ fileName = PhCreateStringEx((PWSTR)FwEvent->header.appId.data, (SIZE_T)FwEvent->header.appId.size);
+ resolvedName = PhResolveDevicePrefix(fileName);
+ PhDereferenceObject(fileName);
+ }
+
+ if (resolvedName)
+ {
+ fwEventItem->ProcessNameString = PhGetFileName(resolvedName);
+ fwEventItem->ProcessBaseString = PhGetBaseName(resolvedName);
+
+ //FWP_BYTE_BLOB* fwpApplicationByteBlob = NULL;
+ //if (FwpmGetAppIdFromFileName(fileNameString->Buffer, &fwpApplicationByteBlob) == ERROR_SUCCESS)
+ //fwEventItem->ProcessBaseString = PhCreateStringEx(fwpApplicationByteBlob->data, fwpApplicationByteBlob->size);
+
+ //fwEventItem->Icon = PhGetFileShellIcon(PhGetString(resolvedName), L".exe", FALSE);
+
+ PhDereferenceObject(resolvedName);
+ }
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_USER_ID_SET) != 0)
+ {
+ if (RtlValidSid(FwEvent->header.userId))
+ {
+ fwEventItem->UserNameString = PhGetSidFullName(FwEvent->header.userId, TRUE, NULL);
+ }
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_IP_PROTOCOL_SET))
+ {
+ // The ipProtocol member is set.
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_SCOPE_ID_SET))
+ {
+ // The scopeId member is set.
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_REAUTH_REASON_SET) != 0)
+ {
+ // Indicates an existing connection was reauthorized.
+ }
+
+ if ((FwEvent->header.flags & FWPM_NET_EVENT_FLAG_PACKAGE_ID_SET) != 0)
+ {
+ // The packageSid member is set.
+ }
+
+ switch (FwEvent->header.ipProtocol)
+ {
+ case IPPROTO_HOPOPTS:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"HOPOPTS");
+ break;
+ case IPPROTO_ICMP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICMP");
+ break;
+ case IPPROTO_IGMP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IGMP");
+ break;
+ case IPPROTO_GGP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"GGP");
+ break;
+ case IPPROTO_IPV4:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPv4");
+ break;
+ case IPPROTO_ST:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ST");
+ break;
+ case IPPROTO_TCP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"TCP");
+ break;
+ case IPPROTO_CBT:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"CBT");
+ break;
+ case IPPROTO_EGP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"EGP");
+ break;
+ case IPPROTO_IGP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IGP");
+ break;
+ case IPPROTO_PUP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"PUP");
+ break;
+ case IPPROTO_UDP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"UDP");
+ break;
+ case IPPROTO_IDP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IDP");
+ break;
+ case IPPROTO_RDP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"RDP");
+ break;
+ case IPPROTO_IPV6:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPv6");
+ break;
+ case IPPROTO_ROUTING:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ROUTING");
+ break;
+ case IPPROTO_FRAGMENT:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"FRAGMENT");
+ break;
+ case IPPROTO_ESP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ESP");
+ break;
+ case IPPROTO_AH:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"AH");
+ break;
+ case IPPROTO_ICMPV6:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICMPv6");
+ break;
+ case IPPROTO_DSTOPTS:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"DSTOPTS");
+ break;
+ case IPPROTO_ND:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ND");
+ break;
+ case IPPROTO_ICLFXBM:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"ICLFXBM");
+ break;
+ case IPPROTO_PIM:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"PIM");
+ break;
+ case IPPROTO_PGM:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"PGM");
+ break;
+ case IPPROTO_L2TP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"L2TP");
+ break;
+ case IPPROTO_SCTP:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"SCTP");
+ break;
+ case IPPROTO_RESERVED_IPSEC:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPSEC");
+ break;
+ case IPPROTO_RESERVED_IPSECOFFLOAD:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"IPSECOFFLOAD");
+ break;
+ case IPPROTO_RESERVED_WNV:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"WNV");
+ break;
+ case IPPROTO_RAW:
+ case IPPROTO_RESERVED_RAW:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"RAW");
+ break;
+ case IPPROTO_NONE:
+ default:
+ PhInitializeStringRef(&fwEventItem->ProtocalString, L"Unknown");
+ break;
+ }
+
+ PhInvokeCallback(&FwItemAddedEvent, fwEventItem);
+}
+
+static VOID NTAPI ProcessesUpdatedCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ static LARGE_INTEGER systemTime;
+
+ PhQuerySystemTime(&systemTime);
+
+ for (ULONG i = 0; i < FwNodeList->Count; i++)
+ {
+ PFW_EVENT_NODE node = (PFW_EVENT_NODE)FwNodeList->Items[i];
+
+ if (systemTime.QuadPart > (node->EventItem->AddedTime.QuadPart + (60 * PH_TIMEOUT_SEC)))
+ {
+ PhInvokeCallback(&FwItemRemovedEvent, node);
+ }
+ }
+
+ PhInvokeCallback(&FwItemsUpdatedEvent, NULL);
+}
+
+
+BOOLEAN StartFwMonitor(
+ VOID
+ )
+{
+ FWP_VALUE value = { FWP_EMPTY };
+ FWPM_SESSION session = { 0 };
+ FWPM_NET_EVENT_SUBSCRIPTION subscription = { 0 };
+ FWPM_NET_EVENT_ENUM_TEMPLATE eventTemplate = { 0 };
+
+
+ FwpmNetEventSubscribe1_I = PhGetModuleProcAddress(L"fwpuclnt.dll", "FwpmNetEventSubscribe1");
+
+ FwNodeList = PhCreateList(100);
+ FwObjectType = PhCreateObjectType(L"FwObject", 0, FwObjectTypeDeleteProcedure);
+
+
+ session.flags = 0;
+ session.displayData.name = L"PhFirewallMonitoringSession";
+ session.displayData.description = L"Non-Dynamic session for Process Hacker";
+
+ // Create a non-dynamic BFE session
+ if (FwpmEngineOpen(
+ NULL,
+ RPC_C_AUTHN_WINNT,
+ NULL,
+ &session,
+ &FwEngineHandle
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ value.type = FWP_UINT32;
+ value.uint32 = 1;
+
+ // Enable collection of NetEvents
+ if (FwpmEngineSetOption(
+ FwEngineHandle,
+ FWPM_ENGINE_COLLECT_NET_EVENTS,
+ &value
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ if (WindowsVersion > WINDOWS_7)
+ {
+ value.type = FWP_UINT32;
+ value.uint32 = FWPM_NET_EVENT_KEYWORD_CAPABILITY_DROP | FWPM_NET_EVENT_KEYWORD_CAPABILITY_ALLOW | FWPM_NET_EVENT_KEYWORD_CLASSIFY_ALLOW; // FWPM_NET_EVENT_KEYWORD_INBOUND_MCAST | FWPM_NET_EVENT_KEYWORD_INBOUND_BCAST
+
+ if (FwpmEngineSetOption(
+ FwEngineHandle,
+ FWPM_ENGINE_NET_EVENT_MATCH_ANY_KEYWORDS,
+ &value
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ value.type = FWP_UINT32;
+ value.uint32 = 1;
+
+ if (FwpmEngineSetOption(
+ FwEngineHandle,
+ FWPM_ENGINE_MONITOR_IPSEC_CONNECTIONS,
+ &value
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+ }
+
+ eventTemplate.numFilterConditions = 0; // get events for all conditions
+
+ subscription.sessionKey = session.sessionKey;
+ subscription.enumTemplate = &eventTemplate;
+
+ // Subscribe to the events
+ if (FwpmNetEventSubscribe1_I)
+ {
+ if (FwpmNetEventSubscribe1_I(
+ FwEngineHandle,
+ &subscription,
+ DropEventCallback,
+ NULL,
+ &FwEventHandle
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (FwpmNetEventSubscribe0(
+ FwEngineHandle,
+ &subscription,
+ (FWPM_NET_EVENT_CALLBACK0)DropEventCallback, // TODO: Use correct function.
+ NULL,
+ &FwEventHandle
+ ) != ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+ }
+
+ PhRegisterCallback(
+ &PhProcessesUpdatedEvent,
+ ProcessesUpdatedCallback,
+ NULL,
+ &ProcessesUpdatedCallbackRegistration
+ );
+
+ return TRUE;
+}
+
+VOID StopFwMonitor(
+ VOID
+ )
+{
+ if (FwEventHandle)
+ {
+ FwpmNetEventUnsubscribe(FwEngineHandle, FwEventHandle);
+ FwEventHandle = NULL;
+ }
+
+ if (FwEngineHandle)
+ {
+ //FWP_VALUE value = { FWP_EMPTY };
+ //value.type = FWP_UINT32;
+ //value.uint32 = 0;
+
+ // TODO: return to previous state if other applications require event collection enabled??
+ // Disable collection of NetEvents
+ //FwpmEngineSetOption(FwEngineHandle, FWPM_ENGINE_COLLECT_NET_EVENTS, &value);
+
+ FwpmEngineClose(FwEngineHandle);
+ FwEngineHandle = NULL;
+ }
+}
diff --git a/plugins-extra/FirewallMonitorPlugin/resource.h b/plugins-extra/FirewallMonitorPlugin/resource.h
new file mode 100644
index 0000000..d2091c2
--- /dev/null
+++ b/plugins-extra/FirewallMonitorPlugin/resource.h
@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by FirewallMonitorPlugin.rc
+//
+#define IDR_FW 101
+#define IDR_FW_MENU 101
+#define IDD_PROPDIALOG 102
+#define IDD_FWTABERROR 102
+#define IDC_RESTART 1001
+#define ID_EVENT_COPY 40001
+#define ID_EVENT_PROPERTIES 40002
+#define ID_FW_PROPERTIES 40003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40004
+#define _APS_NEXT_CONTROL_VALUE 1002
+#define _APS_NEXT_SYMED_VALUE 103
+#endif
+#endif
diff --git a/plugins-extra/FirmwarePlugin/CHANGELOG.txt b/plugins-extra/FirmwarePlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/Efi/EfiDevicePath.h b/plugins-extra/FirmwarePlugin/Efi/EfiDevicePath.h
new file mode 100644
index 0000000..137da8d
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/Efi/EfiDevicePath.h
@@ -0,0 +1,651 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+EfiDevicePath.h
+
+Abstract:
+
+EFI Device Path definitions
+
+--*/
+
+#ifndef _EFI_DEVICE_PATH_H
+#define _EFI_DEVICE_PATH_H
+
+#pragma pack(1)
+
+
+//
+// Device Path defines and macros
+//
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH_PROTOCOL))
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK )
+#define DevicePathSubType(a) ( (a)->SubType )
+#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
+#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED )
+
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+
+
+//
+// Device Path protocol
+//
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0x9576e91, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ }
+
+#pragma pack(push, 1)
+
+typedef struct _EFI_DEVICE_PATH_PROTOCOL
+{
+ UINT8 Type;
+ UINT8 SubType;
+ UINT8 Length[2];
+} EFI_DEVICE_PATH_PROTOCOL;
+
+#pragma pack(pop)
+
+#define EFI_END_ENTIRE_DEVICE_PATH 0xff
+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define EFI_END_INSTANCE_DEVICE_PATH 0x01
+#define EFI_END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+
+#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8))
+#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a)))
+
+#define EfiDevicePathType(a) (((a)->Type) & 0x7f)
+#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == 0x7f)
+
+#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
+#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH)
+
+#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
+#define EfiIsDevicePathEndInstance(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a))
+
+
+
+
+
+
+
+
+
+
+//
+// Hardware Device Paths
+//
+#define HARDWARE_DEVICE_PATH 0x01
+
+#define HW_PCI_DP 0x01
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 Function;
+ UINT8 Device;
+} PCI_DEVICE_PATH;
+
+#define HW_PCCARD_DP 0x02
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+#define HW_MEMMAP_DP 0x03
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 MemoryType;
+ EFI_PHYSICAL_ADDRESS StartingAddress;
+ EFI_PHYSICAL_ADDRESS EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+#define HW_VENDOR_DP 0x04
+
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+} VENDOR_DEVICE_PATH;
+
+#define HW_CONTROLLER_DP 0x05
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Controller;
+} CONTROLLER_DEVICE_PATH;
+
+//
+// ACPI Device Paths
+//
+#define ACPI_DEVICE_PATH 0x02
+
+#define ACPI_DP 0x01
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 HID;
+ UINT32 UID;
+} ACPI_HID_DEVICE_PATH;
+
+#define ACPI_EXTENDED_DP 0x02
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 HID;
+ UINT32 UID;
+ UINT32 CID;
+ //
+ // Optional variable length _HIDSTR
+ // Optional variable length _UIDSTR
+ //
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+#define ACPI_ADR_DP 0x03
+
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 ADR;
+} ACPI_ADR_DEVICE_PATH;
+
+#define ACPI_ADR_DISPLAY_TYPE_OTHER 0
+#define ACPI_ADR_DISPLAY_TYPE_VGA 1
+#define ACPI_ADR_DISPLAY_TYPE_TV 2
+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3
+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4
+
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+ ((UINT32) ( (((_DeviceIdScheme) & 0x1) << 31) | \
+ (((_HeadId) & 0x7) << 18) | \
+ (((_NonVgaOutput) & 0x1) << 17) | \
+ (((_BiosCanDetect) & 0x1) << 16) | \
+ (((_VendorInfo) & 0xf) << 12) | \
+ (((_Type) & 0xf) << 8) | \
+ (((_Port) & 0xf) << 4) | \
+ ((_Index) & 0xf) ))
+
+//
+// EISA ID Macro
+// EISA ID Definition 32-bits
+// bits[15:0] - three character compressed ASCII EISA ID.
+// bits[31:16] - binary number
+// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST 0x41d0
+#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK 0xffff
+#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
+
+//
+// Messaging Device Paths
+//
+#define MESSAGING_DEVICE_PATH 0x03
+
+#define MSG_ATAPI_DP 0x01
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 PrimarySecondary;
+ UINT8 SlaveMaster;
+ UINT16 Lun;
+} ATAPI_DEVICE_PATH;
+
+#define MSG_SCSI_DP 0x02
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 Pun;
+ UINT16 Lun;
+} SCSI_DEVICE_PATH;
+
+#define MSG_FIBRECHANNEL_DP 0x03
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Reserved;
+ UINT64 WWN;
+ UINT64 Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+#define MSG_1394_DP 0x04
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Reserved;
+ UINT64 Guid;
+} F1394_DEVICE_PATH;
+
+#define MSG_USB_DP 0x05
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 ParentPortNumber;
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+
+#define MSG_USB_CLASS_DP 0x0f
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 VendorId;
+ UINT16 ProductId;
+ UINT8 DeviceClass;
+ UINT8 DeviceSubClass;
+ UINT8 DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+#define MSG_USB_WWID_DP 0x10
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 InterfaceNumber;
+ UINT16 VendorId;
+ UINT16 ProductId;
+ //
+ // CHAR16 SerialNumber[];
+ //
+} USB_WWID_DEVICE_PATH;
+
+#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+#define MSG_SATA_DP 0x12
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 HBAPortNumber;
+ UINT16 PortMultiplierPortNumber;
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
+
+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000
+
+#define MSG_I2O_DP 0x06
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Tid;
+} I2O_DEVICE_PATH;
+
+#define MSG_MAC_ADDR_DP 0x0b
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_MAC_ADDRESS MacAddress;
+ UINT8 IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+#define MSG_IPv4_DP 0x0c
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_IPv4_ADDRESS LocalIpAddress;
+ EFI_IPv4_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+} IPv4_DEVICE_PATH;
+
+#define MSG_IPv6_DP 0x0d
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_IPv6_ADDRESS LocalIpAddress;
+ EFI_IPv6_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+} IPv6_DEVICE_PATH;
+
+#define MSG_INFINIBAND_DP 0x09
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 ResourceFlags;
+ UINT8 PortGid[16];
+ UINT64 ServiceId;
+ UINT64 TargetPortId;
+ UINT64 DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
+
+#define MSG_UART_DP 0x0e
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Reserved;
+ UINT64 BaudRate;
+ UINT8 DataBits;
+ UINT8 Parity;
+ UINT8 StopBits;
+} UART_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MSG_VENDOR_DP 0x0a
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI \
+ { 0xe0c14753, 0xf9be, 0x11d2, 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+
+#define DEVICE_PATH_MESSAGING_VT_100 \
+ { 0xdfa66065, 0xb419, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS \
+ { 0x7baec70b, 0x57e0, 0x4c76, 0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 }
+
+#define DEVICE_PATH_MESSAGING_VT_UTF8 \
+ { 0xad15a0d6, 0x8bec, 0x4acf, 0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 }
+
+#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL \
+ { 0x37499a9d, 0x542f, 0x4c89, 0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 }
+
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT32 FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+#define DEVICE_PATH_MESSAGING_SAS \
+ { 0xd487ddb4, 0x008b, 0x11d9, 0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d }
+
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT32 Reserved;
+ UINT64 SasAddress;
+ UINT64 Lun;
+ UINT16 DeviceTopology;
+ UINT16 RelativeTargetPort;
+} SAS_DEVICE_PATH;
+
+#define MSG_ISCSI_DP 0x13
+typedef struct
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ // CHAR8 iSCSI Target Name
+} ISCSI_DEVICE_PATH;
+
+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002
+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000
+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000
+#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000
+#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000
+
+//
+// Media Device Path
+//
+#define MEDIA_DEVICE_PATH 0x04
+
+#define MEDIA_HARDDRIVE_DP 0x01
+typedef struct _HARDDRIVE_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 PartitionNumber;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+ UINT8 Signature[16];
+ UINT8 MBRType;
+ UINT8 SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define SIGNATURE_TYPE_MBR 0x01
+#define SIGNATURE_TYPE_GUID 0x02
+
+#define MEDIA_CDROM_DP 0x02
+typedef struct _CDROM_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 BootEntry;
+ UINT64 PartitionStart;
+ UINT64 PartitionSize;
+} CDROM_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MEDIA_VENDOR_DP 0x03
+
+#define MEDIA_FILEPATH_DP 0x04
+typedef struct _FILEPATH_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ CHAR16 PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName)
+
+#define MEDIA_PROTOCOL_DP 0x05
+typedef struct _MEDIA_PROTOCOL_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+#define MEDIA_FV_DP 0x07
+typedef struct _MEDIA_FW_VOL_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID NameGuid;
+} MEDIA_FW_VOL_DEVICE_PATH;
+
+#define MEDIA_FV_FILEPATH_DP 0x06
+typedef struct _MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID NameGuid;
+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
+
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+typedef struct _MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT64 StartingOffset;
+ UINT64 EndingOffset;
+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
+
+//
+// BBS Device Path
+//
+#define BBS_DEVICE_PATH 0x05
+#define BBS_BBS_DP 0x01
+typedef struct _BBS_BBS_DEVICE_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 DeviceType;
+ UINT16 StatusFlag;
+ CHAR8 String[ANYSIZE_ARRAY];
+} BBS_BBS_DEVICE_PATH;
+
+//
+// DeviceType definitions - from BBS specification
+//
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+#define UNKNOWN_DEVICE_GUID \
+ { 0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b }
+
+typedef struct _UNKNOWN_DEVICE_VENDOR_DEVICE_PATH
+{
+ VENDOR_DEVICE_PATH DevicePath;
+ UINT8 LegacyDriveLetter;
+} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;
+
+
+//
+// Union of all possible Device Paths and pointers to Device Paths
+//
+
+typedef union _EFI_DEV_PATH
+{
+ EFI_DEVICE_PATH_PROTOCOL DevPath;
+ PCI_DEVICE_PATH Pci;
+ PCCARD_DEVICE_PATH PcCard;
+ MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;
+
+ CONTROLLER_DEVICE_PATH Controller;
+ ACPI_HID_DEVICE_PATH Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH AdrAcpi;
+
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+ SATA_DEVICE_PATH Sata;
+
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ USB_WWID_DEVICE_PATH UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit;
+ I2O_DEVICE_PATH I2O;
+ MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl;
+ SAS_DEVICE_PATH Sas;
+ ISCSI_DEVICE_PATH Iscsi;
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+
+ FILEPATH_DEVICE_PATH FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH PiwgFirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH PiwgFirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset;
+
+ BBS_BBS_DEVICE_PATH Bbs;
+} EFI_DEV_PATH;
+
+
+
+typedef union _EFI_DEV_PATH_PTR
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ PCI_DEVICE_PATH *Pci;
+ PCCARD_DEVICE_PATH *PcCard;
+ MEMMAP_DEVICE_PATH *MemMap;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor;
+
+ CONTROLLER_DEVICE_PATH *Controller;
+ ACPI_HID_DEVICE_PATH *Acpi;
+ ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
+ ACPI_ADR_DEVICE_PATH *AdrAcpi;
+
+ ATAPI_DEVICE_PATH *Atapi;
+ SCSI_DEVICE_PATH *Scsi;
+ FIBRECHANNEL_DEVICE_PATH *FibreChannel;
+ SATA_DEVICE_PATH *Sata;
+
+ F1394_DEVICE_PATH *F1394;
+ USB_DEVICE_PATH *Usb;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit;
+ I2O_DEVICE_PATH *I2O;
+ MAC_ADDR_DEVICE_PATH *MacAddr;
+ IPv4_DEVICE_PATH *Ipv4;
+ IPv6_DEVICE_PATH *Ipv6;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+ UART_DEVICE_PATH *Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ SAS_DEVICE_PATH *Sas;
+ ISCSI_DEVICE_PATH *Iscsi;
+
+ HARDDRIVE_DEVICE_PATH *HardDrive;
+ CDROM_DEVICE_PATH *CD;
+
+ FILEPATH_DEVICE_PATH *FilePath;
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
+
+ MEDIA_FW_VOL_DEVICE_PATH *PiwgFirmwareVolume;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *PiwgFirmwareFile;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ BBS_BBS_DEVICE_PATH *Bbs;
+ UINT8 *Raw;
+} EFI_DEV_PATH_PTR;
+
+#pragma pack()
+
+
+#endif
diff --git a/plugins-extra/FirmwarePlugin/Efi/EfiTypes.h b/plugins-extra/FirmwarePlugin/Efi/EfiTypes.h
new file mode 100644
index 0000000..4a27f19
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/Efi/EfiTypes.h
@@ -0,0 +1,293 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiTypes.h
+
+Abstract:
+
+ EFI defined types. Use these types when ever possible!
+
+--*/
+
+#ifndef _EFI_TYPES_H_
+#define _EFI_TYPES_H_
+
+//
+// EFI Data Types based on ANSI C integer types in EfiBind.h
+//
+typedef uint8_t BOOLEAN;
+//typedef intn_t INTN;
+//typedef uintn_t UINTN;
+typedef int8_t INT8;
+typedef uint8_t UINT8;
+typedef int16_t INT16;
+typedef uint16_t UINT16;
+typedef int32_t INT32;
+typedef uint32_t UINT32;
+typedef int64_t INT64;
+typedef uint64_t UINT64;
+typedef uint8_t CHAR8;
+typedef uint16_t CHAR16;
+typedef UINT64 EFI_LBA;
+
+//
+// Modifiers for EFI Data Types used to self document code.
+// Please see EFI coding convention for proper usage.
+//
+#ifndef IN
+//
+// Some other envirnments use this construct, so #ifndef to prevent
+// mulitple definition.
+//
+#define IN
+#define OUT
+#define OPTIONAL
+#endif
+
+//#define UNALIGNED
+
+//
+// Modifiers for EFI Runtime and Boot Services
+//
+#define EFI_RUNTIMESERVICE
+#define EFI_BOOTSERVICE
+
+//
+// Boot Service add in EFI 1.1
+//
+#define EFI_BOOTSERVICE11
+
+//
+// Modifiers to absract standard types to aid in debug of problems
+//
+#define CONST const
+#define STATIC static
+#define VOID void
+#define VOLATILE volatile
+
+//
+// Modifier to ensure that all protocol member functions and EFI intrinsics
+// use the correct C calling convention. All protocol member functions and
+// EFI intrinsics are required to modify thier member functions with EFIAPI.
+//
+#define EFIAPI _EFIAPI
+
+//
+// EFI Constants. They may exist in other build structures, so #ifndef them.
+//
+#ifndef TRUE
+#define TRUE ((BOOLEAN) (1 == 1))
+#endif
+
+#ifndef FALSE
+#define FALSE ((BOOLEAN) (0 == 1))
+#endif
+
+#ifndef NULL
+#define NULL ((VOID *) 0)
+#endif
+//
+// EFI Data Types derived from other EFI data types.
+//
+typedef UINT32 EFI_STATUS; // UINTN
+
+typedef VOID *EFI_HANDLE;
+#define NULL_HANDLE ((VOID *) 0)
+
+typedef VOID *EFI_EVENT;
+typedef UINT32 EFI_TPL; // UINTN
+
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+
+typedef union {
+ EFI_GUID Guid;
+ UINT8 Raw[16];
+} EFI_GUID_UNION;
+
+//
+// EFI Time Abstraction:
+// Year: 2000 - 20XX
+// Month: 1 - 12
+// Day: 1 - 31
+// Hour: 0 - 23
+// Minute: 0 - 59
+// Second: 0 - 59
+// Nanosecond: 0 - 999,999,999
+// TimeZone: -1440 to 1440 or 2047
+//
+typedef struct {
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+ UINT8 Pad1;
+ UINT32 Nanosecond;
+ INT16 TimeZone;
+ UINT8 Daylight;
+ UINT8 Pad2;
+} EFI_TIME;
+
+//
+// Bit definitions for EFI_TIME.Daylight
+//
+#define EFI_TIME_ADJUST_DAYLIGHT 0x01
+#define EFI_TIME_IN_DAYLIGHT 0x02
+
+//
+// Value definition for EFI_TIME.TimeZone
+//
+#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
+
+//
+// Networking
+//
+typedef struct {
+ UINT8 Addr[4];
+} EFI_IPv4_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[16];
+} EFI_IPv6_ADDRESS;
+
+typedef struct {
+ UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+typedef union {
+ UINT32 Addr[4];
+ EFI_IPv4_ADDRESS v4;
+ EFI_IPv6_ADDRESS v6;
+} EFI_IP_ADDRESS;
+
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+typedef enum {
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ AllocateAddress,
+ MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+typedef struct {
+ UINT64 Signature;
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 CRC32;
+ UINT32 Reserved;
+} EFI_TABLE_HEADER;
+
+//
+// possible caching types for the memory range
+//
+#define EFI_MEMORY_UC 0x0000000000000001
+#define EFI_MEMORY_WC 0x0000000000000002
+#define EFI_MEMORY_WT 0x0000000000000004
+#define EFI_MEMORY_WB 0x0000000000000008
+#define EFI_MEMORY_UCE 0x0000000000000010
+
+//
+// physical memory protection on range
+//
+#define EFI_MEMORY_WP 0x0000000000001000
+#define EFI_MEMORY_RP 0x0000000000002000
+#define EFI_MEMORY_XP 0x0000000000004000
+
+//
+// range requires a runtime mapping
+//
+#define EFI_MEMORY_RUNTIME 0x8000000000000000
+
+typedef UINT64 EFI_PHYSICAL_ADDRESS;
+typedef UINT64 EFI_VIRTUAL_ADDRESS;
+
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+typedef struct {
+ UINT32 Type;
+ UINT32 Pad;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ EFI_VIRTUAL_ADDRESS VirtualStart;
+ UINT64 NumberOfPages;
+ UINT64 Attribute;
+} EFI_MEMORY_DESCRIPTOR;
+
+//
+// The EFI memory allocation functions work in units of EFI_PAGEs that are
+// 4K. This should in no way be confused with the page size of the processor.
+// An EFI_PAGE is just the quanta of memory in EFI.
+//
+#define EFI_PAGE_SIZE 4096
+#define EFI_PAGE_MASK 0xFFF
+#define EFI_PAGE_SHIFT 12
+
+#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0))
+
+#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT)
+
+//
+// ALIGN_POINTER - aligns a pointer to the lowest boundry
+//
+#define ALIGN_POINTER(p, s) ((VOID *) (p + ((s - ((UINTN) p)) & (s - 1))))
+
+//
+// ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor
+//
+#define ALIGN_VARIABLE(Value, Adjustment) \
+ (UINTN) Adjustment = 0; \
+ if ((UINTN) Value % sizeof (UINTN)) { \
+ (UINTN) Adjustment = sizeof (UINTN) - ((UINTN) Value % sizeof (UINTN)); \
+ } \
+ Value = (UINTN) Value + (UINTN) Adjustment
+
+//
+// EFI_FIELD_OFFSET - returns the byte offset to a field within a structure
+//
+#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8))
+#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32))
+
+#endif
diff --git a/plugins-extra/FirmwarePlugin/FirmwarePlugin.rc b/plugins-extra/FirmwarePlugin/FirmwarePlugin.rc
new file mode 100644
index 0000000..c62f019
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/FirmwarePlugin.rc
@@ -0,0 +1,133 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "UEFI firmware plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "dmex.UefiFirmwareEntriesPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "UEFIFirmwarePlugin.dll"
+ VALUE "ProductName", "UEFI firmware plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_BOOT DIALOGEX 0, 0, 325, 181
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Firmware Table"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,269,160,50,14
+ CONTROL "",IDC_BOOT_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,5,312,152
+ PUSHBUTTON "Refresh",IDC_BOOT_REFRESH,7,160,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_BOOT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 318
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 174
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_BOOT AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj b/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj
new file mode 100644
index 0000000..2b919f9
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj
@@ -0,0 +1,114 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {21B34EB4-4C56-4449-A2C0-BC50B4480D7C}
+ FirmwarePlugin
+ Win32Proj
+ FirmwarePlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj.filters b/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj.filters
new file mode 100644
index 0000000..d4a658e
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/FirmwarePlugin.vcxproj.filters
@@ -0,0 +1,52 @@
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ {72b9a8a4-fadc-4ee4-a1fa-3ff4282321f7}
+
+
+ {e81548ad-7412-443d-b106-d783ab419943}
+
+
+ {e9c87a83-df4f-47d8-9595-60b3bd34eb2d}
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/dialog.c b/plugins-extra/FirmwarePlugin/dialog.c
new file mode 100644
index 0000000..2b40cb1
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/dialog.c
@@ -0,0 +1,292 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firmware Plugin
+ *
+ * Copyright (C) 2016 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 "main.h"
+#include "efi_guid_list.h"
+
+PPH_STRING FirmwareAttributeToString(
+ _In_ ULONG Attribute
+ )
+{
+ PH_STRING_BUILDER sb;
+
+ PhInitializeStringBuilder(&sb, 0x100);
+
+ if (Attribute & EFI_VARIABLE_NON_VOLATILE)
+ PhAppendStringBuilder2(&sb, L"Non Volatile, ");
+
+ if (Attribute & EFI_VARIABLE_BOOTSERVICE_ACCESS)
+ PhAppendStringBuilder2(&sb, L"Boot Service, ");
+
+ if (Attribute & EFI_VARIABLE_RUNTIME_ACCESS)
+ PhAppendStringBuilder2(&sb, L"Runtime Access, ");
+
+ if (Attribute & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
+ PhAppendStringBuilder2(&sb, L"Hardware Error Record, ");
+
+ if (Attribute & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+ PhAppendStringBuilder2(&sb, L"Authenticated Write Access, ");
+
+ if (Attribute & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
+ PhAppendStringBuilder2(&sb, L"Authenticated Write Access (Time Based), ");
+
+ if (Attribute & EFI_VARIABLE_APPEND_WRITE)
+ PhAppendStringBuilder2(&sb, L"Append Write, ");
+
+ if (PhEndsWithStringRef2(&sb.String->sr, L", ", FALSE))
+ PhRemoveEndStringBuilder(&sb, 2);
+
+ return PhFinalStringBuilderString(&sb);
+}
+
+PWSTR FirmwareGuidToNameString(
+ _In_ PGUID VendorGuid
+ )
+{
+ for (ULONG i = 0; i < ARRAYSIZE(table); i++)
+ {
+ if (IsEqualGUID(VendorGuid, &table[i].Guid))
+ return table[i].Name;
+ }
+
+ return L"";
+}
+
+NTSTATUS EnumerateEnvironmentValues(
+ _In_ HWND ListViewHandle
+ )
+{
+ NTSTATUS status;
+ PVOID variables;
+
+ ExtendedListView_SetRedraw(ListViewHandle, FALSE);
+ ListView_DeleteAllItems(ListViewHandle);
+
+ if (NT_SUCCESS(status = EnumerateFirmwareValues(&variables)))
+ {
+ PVARIABLE_NAME_AND_VALUE i;
+
+ for (i = PH_FIRST_EFI_VARIABLE(variables); i; i = PH_NEXT_EFI_VARIABLE(i))
+ {
+ INT index;
+ GUID vendorGuid;
+ PPH_STRING guidString;
+
+ vendorGuid = i->VendorGuid;
+ guidString = PhFormatGuid(&vendorGuid);
+
+ index = PhAddListViewItem(
+ ListViewHandle,
+ MAXINT,
+ i->Name,
+ NULL
+ );
+ PhSetListViewSubItem(
+ ListViewHandle,
+ index,
+ 1,
+ FirmwareAttributeToString(i->Attributes)->Buffer
+ );
+
+ PhSetListViewSubItem(
+ ListViewHandle,
+ index,
+ 2,
+ FirmwareGuidToNameString(&vendorGuid)
+ );
+
+ PhSetListViewSubItem(
+ ListViewHandle,
+ index,
+ 3,
+ guidString->Buffer
+ );
+
+ PhSetListViewSubItem(ListViewHandle, index, 4, PhaFormatSize(i->ValueLength, -1)->Buffer);
+
+ PhDereferenceObject(guidString);
+ }
+
+ PhFree(variables);
+ }
+
+ ExtendedListView_SortItems(ListViewHandle);
+ ExtendedListView_SetRedraw(ListViewHandle, TRUE);
+
+ return status;
+}
+
+PPH_STRING PhGetSelectedListViewItemText(
+ _In_ HWND hWnd
+ )
+{
+ INT index = PhFindListViewItemByFlags(
+ hWnd,
+ -1,
+ LVNI_SELECTED
+ );
+
+ if (index != -1)
+ {
+ WCHAR textBuffer[MAX_PATH] = L"";
+
+ LVITEM item;
+ item.mask = LVIF_TEXT;
+ item.iItem = index;
+ item.iSubItem = 0;
+ item.pszText = textBuffer;
+ item.cchTextMax = ARRAYSIZE(textBuffer);
+
+ if (ListView_GetItem(hWnd, &item))
+ return PhCreateString(textBuffer);
+ }
+
+ return NULL;
+}
+
+VOID ShowBootEntryMenu(
+ _In_ PBOOT_WINDOW_CONTEXT Context,
+ _In_ HWND hwndDlg
+ )
+{
+ PPH_STRING bootEntryName;
+
+ if (bootEntryName = PhGetSelectedListViewItemText(Context->ListViewHandle))
+ {
+ PhDereferenceObject(bootEntryName);
+ }
+}
+
+INT NTAPI FirmwareNameCompareFunction(
+ _In_ PVOID Item1,
+ _In_ PVOID Item2,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_STRING item1 = Item1;
+ PPH_STRING item2 = Item2;
+
+ return PhCompareStringZ(PhGetStringOrEmpty(item1), PhGetStringOrEmpty(item2), TRUE);
+}
+
+INT_PTR CALLBACK BootEntriesDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PBOOT_WINDOW_CONTEXT context;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PBOOT_WINDOW_CONTEXT)PhAllocate(sizeof(BOOT_WINDOW_CONTEXT));
+ memset(context, 0, sizeof(BOOT_WINDOW_CONTEXT));
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PBOOT_WINDOW_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_DESTROY)
+ {
+ PhSaveListViewColumnsToSetting(SETTING_NAME_LISTVIEW_COLUMNS, context->ListViewHandle);
+ PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+ PhDeleteLayoutManager(&context->LayoutManager);
+ PhUnregisterDialog(hwndDlg);
+ RemoveProp(hwndDlg, L"Context");
+ PhFree(context);
+ }
+ }
+
+ if (!context)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ context->ListViewHandle = GetDlgItem(hwndDlg, IDC_BOOT_LIST);
+
+ PhRegisterDialog(hwndDlg);
+ PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE);
+ PhSetControlTheme(context->ListViewHandle, L"explorer");
+ PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Name");
+ PhAddListViewColumn(context->ListViewHandle, 1, 1, 1, LVCFMT_LEFT, 140, L"Attributes");
+ PhAddListViewColumn(context->ListViewHandle, 2, 2, 2, LVCFMT_LEFT, 140, L"Guid Name");
+ PhAddListViewColumn(context->ListViewHandle, 3, 3, 3, LVCFMT_LEFT, 140, L"Guid");
+ PhAddListViewColumn(context->ListViewHandle, 4, 4, 4, LVCFMT_LEFT, 50, L"Data Length");
+ PhSetExtendedListView(context->ListViewHandle);
+
+ //ExtendedListView_SetSortFast(context->ListViewHandle, TRUE);
+ ExtendedListView_SetCompareFunction(context->ListViewHandle, 0, FirmwareNameCompareFunction);
+ ExtendedListView_SetCompareFunction(context->ListViewHandle, 1, FirmwareNameCompareFunction);
+ PhLoadListViewColumnsFromSetting(SETTING_NAME_LISTVIEW_COLUMNS, context->ListViewHandle);
+
+ PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
+ PhAddLayoutItem(&context->LayoutManager, context->ListViewHandle, NULL, PH_ANCHOR_ALL);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BOOT_REFRESH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT);
+ PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg);
+
+ EnumerateEnvironmentValues(context->ListViewHandle);
+ }
+ break;
+ case WM_SIZE:
+ PhLayoutManagerLayout(&context->LayoutManager);
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_BOOT_REFRESH:
+ {
+ EnumerateEnvironmentValues(context->ListViewHandle);
+ }
+ break;
+ case IDCANCEL:
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ LPNMHDR hdr = (LPNMHDR)lParam;
+
+ switch (hdr->code)
+ {
+ case NM_RCLICK:
+ {
+ if (hdr->hwndFrom == context->ListViewHandle)
+ ShowBootEntryMenu(context, hwndDlg);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/efi.c b/plugins-extra/FirmwarePlugin/efi.c
new file mode 100644
index 0000000..5b4b351
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/efi.c
@@ -0,0 +1,200 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firmware Plugin
+ *
+ * Copyright (C) 2016 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 "main.h"
+#include "Efi\EfiTypes.h"
+#include "Efi\EfiDevicePath.h"
+
+NTSTATUS EnumerateFirmwareValues(
+ _Out_ PVOID *Values
+ )
+{
+ NTSTATUS status;
+ PVOID buffer;
+ ULONG bufferLength;
+
+ bufferLength = PAGE_SIZE;
+ buffer = PhAllocate(bufferLength);
+
+ while (TRUE)
+ {
+ status = NtEnumerateSystemEnvironmentValuesEx(
+ SystemEnvironmentValueInformation,
+ buffer,
+ &bufferLength
+ );
+
+ if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ PhFree(buffer);
+ buffer = PhAllocate(bufferLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (!NT_SUCCESS(status))
+ {
+ PhFree(buffer);
+ return status;
+ }
+
+ *Values = buffer;
+
+ return status;
+}
+
+NTSTATUS EfiEnumerateBootEntries(
+ _Out_ PVOID *Entries
+ )
+{
+ NTSTATUS status;
+ PVOID buffer;
+ ULONG bufferLength;
+
+ bufferLength = PAGE_SIZE;
+ buffer = PhAllocate(bufferLength);
+
+ while (TRUE)
+ {
+ status = NtEnumerateBootEntries(
+ buffer,
+ &bufferLength
+ );
+
+ if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ PhFree(buffer);
+ buffer = PhAllocate(bufferLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (!NT_SUCCESS(status))
+ {
+ PhFree(buffer);
+ return status;
+ }
+
+ *Entries = buffer;
+
+ return status;
+}
+
+
+//VOID EfiQueryBootOptions(
+// VOID
+// )
+//{
+// NTSTATUS status;
+// PVOID buffer = NULL;
+// ULONG bufferLength = 0;
+//
+// __try
+// {
+// if (status = NtQueryBootOptions(NULL, &bufferLength) != STATUS_BUFFER_TOO_SMALL)
+// __leave;
+//
+// buffer = PhAllocate(bufferLength);
+// memset(buffer, 0, bufferLength);
+//
+// if (NT_SUCCESS(NtQueryBootOptions(buffer, &bufferLength)))
+// {
+// //PBOOT_OPTIONS bootOptions = buffer;
+// }
+// }
+// __finally
+// {
+// if (buffer)
+// {
+// PhFree(buffer);
+// }
+// }
+//}
+
+
+
+NTSTATUS EnumerateBootEntriesThread(
+ _In_ PVOID Context
+ )
+{
+ NTSTATUS status;
+ PVOID entries;
+
+ if (NT_SUCCESS(status = EfiEnumerateBootEntries(&entries)))
+ {
+ PBOOT_ENTRY_LIST i;
+
+ for (i = PH_FIRST_BOOT_ENTRY(entries); i; i = PH_NEXT_BOOT_ENTRY(i))
+ {
+
+ }
+
+ PhFree(entries);
+ }
+
+ return status;
+}
+
+BOOLEAN EfiSupported(
+ VOID
+ )
+{
+ // The GetFirmwareEnvironmentVariable function will always fail on a legacy BIOS-based system,
+ // or if Windows was installed using legacy BIOS on a system that supports both legacy BIOS and UEFI.
+ // To identify these conditions, call the function with a dummy firmware environment name such as an empty string ("")
+ // for the lpName parameter and a dummy GUID such as "{00000000-0000-0000-0000-000000000000}" for the lpGuid parameter.
+ // On a legacy BIOS-based system, or on a system that supports both legacy BIOS and UEFI where Windows was installed using legacy BIOS,
+ // the function will fail with ERROR_INVALID_FUNCTION.
+ // On a UEFI-based system, the function will fail with an error specific to the firmware, such as ERROR_NOACCESS,
+ // to indicate that the dummy GUID namespace does not exist.
+
+ UNICODE_STRING variableName = RTL_CONSTANT_STRING(L" ");
+ PVOID variableValue = NULL;
+ ULONG variableValueLength = 0;
+
+ //GetFirmwareEnvironmentVariable(
+ // L"",
+ // L"{00000000-0000-0000-0000-000000000000}",
+ // NULL,
+ // 0
+ // );
+ //if (GetLastError() == ERROR_INVALID_FUNCTION)
+
+ if (NtQuerySystemEnvironmentValueEx(
+ &variableName,
+ (PGUID)&GUID_NULL,
+ variableValue,
+ &variableValueLength,
+ NULL
+ ) == STATUS_VARIABLE_NOT_FOUND)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/efi_guid_list.h b/plugins-extra/FirmwarePlugin/efi_guid_list.h
new file mode 100644
index 0000000..9862724
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/efi_guid_list.h
@@ -0,0 +1,1520 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firmware Plugin
+ *
+ * Copyright (C) 2016 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 .
+ */
+
+#pragma once
+
+struct _EFI_GUID_TABLE
+{
+ PWSTR Name;
+ GUID Guid;
+} table[] =
+{
+ // dmex: 77fa9abd-0359-4d32-bd60-28f4e78f784b
+ { L"EFI_WINNT_OS", { 0x77fa9abd, 0x0359, 0x4d32,{ 0xbd, 0x60, 0x28, 0xf4, 0xe7, 0x8f, 0x78, 0x4b } } },
+
+ // dmex: ba57e015-65b3-4c3c-b274-659192f699e3
+ { L"EFI_WINNT_WHEA", { 0xba57e015, 0x65b3, 0x4c3c,{ 0xb2, 0x74, 0x65, 0x91, 0x92, 0xf6, 0x99, 0xe3 } } },
+
+ // https://raw.githubusercontent.com/mazzoo/efiguid/master/efi_guid_list.h
+ { L"ACOUSTIC_SETUP_PROTOCOL_GUID", { 0xc1d7859d, 0x5719, 0x46c3, { 0xa2, 0x98, 0xd0, 0x71, 0xe3, 0x02, 0x64, 0xd1 } } },
+ { L"ADD_BOOT_OPTION_GUID", { 0x19d96d3f, 0x6a6a, 0x47d2, { 0xb1, 0x95, 0x7b, 0x24, 0x32, 0xda, 0x3b, 0xe2 } } },
+ { L"ADVANCED_FORM_SET_GUID", { 0xe14f04fa, 0x8706, 0x4353, { 0x92, 0xf2, 0x9c, 0x24, 0x24, 0x74, 0x6f, 0x9f } } },
+ { L"AHCI_BUS_INIT_PROTOCOL_GUID", { 0xb2fa4764, 0x3b6e, 0x43d3, { 0x91, 0xdf, 0x87, 0xd1, 0x5a, 0x3e, 0x56, 0x68 } } },
+ { L"AHCI_SMM_PROTOCOL_GUID", { 0xb2fa5764, 0x3b6e, 0x43d3, { 0x91, 0xdf, 0x87, 0xd1, 0x5a, 0x3e, 0x56, 0x68 } } },
+ { L"AMI_APTIO_SIG_OWNER_GUID", { 0x26dc4851, 0x195f, 0x4ae1, { 0x9a, 0x19, 0xfb, 0xf8, 0x83, 0xbb, 0xb3, 0x5e } } },
+ { L"AMI_BBS_DEVICE_PATH_GUID", { 0x1db184ae, 0x81f5, 0x4e72, { 0x85, 0x44, 0x2b, 0xab, 0x0c, 0x2c, 0xac, 0x5c } } },
+ { L"AMI_BEFORE_CPU_RC_PROTOCOL_GUID", { 0x1d26adc3, 0xb011, 0xee2c, { 0x21, 0x77, 0x89, 0xbb, 0xaa, 0xcc, 0x33, 0x92 } } },
+ { L"AMI_BIOSPPI_FLAGS_MANAGEMENT_GUID", { 0xe9008d70, 0x2a4e, 0x47ea, { 0x8e, 0xc4, 0x72, 0xe2, 0x57, 0x67, 0xe5, 0xef } } },
+ { L"AMI_BOARD_INFO_PROTOCOL_GUID", { 0x0273146c, 0x96c4, 0x45a1, { 0xa7, 0xaf, 0x78, 0xe0, 0x52, 0x4a, 0x0a, 0xe2 } } },
+ { L"AMI_BOARD_INFO_SECTION_GUID", { 0xe6f4f8f7, 0x4992, 0x47b2, { 0x83, 0x02, 0x85, 0x08, 0x74, 0x5e, 0x4a, 0x23 } } },
+ { L"AMI_CALLBACK_GUID", { 0x9cf0f18e, 0x7c7d, 0x49de, { 0xb5, 0xaa, 0xbb, 0xba, 0xd6, 0xb2, 0x10, 0x07 } } },
+ { L"AMI_CAPSULE_HOB_GUID", { 0xbf66fdf7, 0xf64c, 0x4b11, { 0x8a, 0xb7, 0xf8, 0x43, 0xaa, 0x2a, 0x8b, 0xea } } },
+ { L"AMI_CCID_IO_PROTOCOL_GUID", { 0xb167c2f5, 0xe26a, 0x4dff, { 0x8e, 0x1c, 0x08, 0x07, 0xc7, 0xf0, 0x2a, 0x88 } } },
+ { L"AMI_CCID_PRESENCE_GUID", { 0x5fdee00d, 0xda40, 0x405a, { 0xb9, 0x2e, 0xcf, 0x4a, 0x80, 0xea, 0x8f, 0x76 } } },
+ { L"AMI_CMOS_BAD_FLAG_HOB_GUID", { 0xb098f766, 0xb17a, 0x4005, { 0x83, 0x09, 0xeb, 0x23, 0xf1, 0x44, 0x8c, 0x15 } } },
+ { L"AMI_CPUID_CKSUM_HOB_GUID", { 0xd4ca32b1, 0xb1f2, 0x4ff3, { 0xb4, 0x75, 0x66, 0xe7, 0xb8, 0x19, 0x2a, 0x3b } } },
+ { L"AMI_CPU_INFO_2_PROTOCOL_GUID", { 0xac9cf0a8, 0xe551, 0x4be2, { 0xad, 0x0a, 0xe1, 0xb5, 0x64, 0xee, 0xa2, 0x73 } } },
+ { L"AMI_CSM_DRIVER_STARTED_GUID", { 0x3ea824d1, 0x81e3, 0x4ff5, { 0xbd, 0x43, 0xbb, 0x9c, 0x65, 0xdf, 0x7c, 0x46 } } },
+ { L"AMICSM_PCIBUSNUM_XLAT_PROTOCOL_GUID", { 0xcb5c54c0, 0x230d, 0x43db, { 0x92, 0x2c, 0x24, 0xd3, 0x4f, 0x8c, 0x91, 0x5c } } },
+ { L"AMI_CSM_THUNK_PROTOCOL_GUID", { 0x2362ea9c, 0x84e5, 0x4dff, { 0x83, 0xbc, 0xb5, 0xac, 0xec, 0xb5, 0x7c, 0xbb } } },
+ { L"AMI_DDDT_PRESENT_FLAG_HOB_GUID", { 0x4e7af417, 0xc200, 0x400a, { 0x9d, 0x18, 0x86, 0x5a, 0xda, 0xd3, 0x08, 0x96 } } },
+ { L"AMI_DEBUGGER_CPU_PROTOCOL_GUID", { 0xab21acc3, 0xba33, 0xee2c, { 0x66, 0xbc, 0x12, 0x56, 0x77, 0x11, 0x1a, 0xb2 } } },
+ { L"AMI_DEBUGPORT_HOB_GUID", { 0xe894b313, 0x54ca, 0x4bb2, { 0x8c, 0xdd, 0x85, 0x1e, 0x8a, 0xc9, 0x02, 0x7c } } },
+ { L"AMI_DEVICE_NAME_DEVICE_PATH_GUID", { 0x2d6447ef, 0x3bc9, 0x41a0, { 0xac, 0x19, 0x4d, 0x51, 0xd0, 0x1b, 0x4c, 0xe6 } } },
+ { L"AMI_DIGITAL_SIGNATURE_PROTOCOL_GUID", { 0x5f87ba17, 0x957d, 0x433d, { 0x9e, 0x15, 0xc0, 0xe7, 0xc8, 0x79, 0x88, 0x99 } } },
+ { L"AMI_DIMM_SPD_DATA_HOB_GUID", { 0xd4ca32b3, 0xb1fe, 0x4ff7, { 0xb0, 0x73, 0x60, 0xed, 0xbb, 0x16, 0x22, 0x33 } } },
+ { L"AMI_EARLY_BIST_PPI_GUID", { 0xa7e2ce72, 0xdc32, 0x4bc0, { 0x9e, 0x35, 0xfe, 0xb3, 0x0a, 0xe5, 0xcc, 0x47 } } },
+ { L"AMI_EFIKEYCODE_PROTOCOL_GUID", { 0x0adfb62d, 0xff74, 0x484c, { 0x89, 0x44, 0xf8, 0x5c, 0x4b, 0xea, 0x87, 0xa8 } } },
+ { L"AMI_FAST_BOOT_PROTOCOL_GUID", { 0x3496a19a, 0x2e99, 0x41ba, { 0x83, 0x3e, 0x0f, 0xde, 0x2e, 0xbf, 0x2a, 0x55 } } },
+ { L"AMI_FW_RECOVERY_CAPSULE_GUID", { 0x5e794317, 0xa07e, 0x45df, { 0x94, 0xbb, 0x1c, 0x99, 0x7d, 0x62, 0x32, 0xca } } },
+ { L"AMI_HECI_SMM_GUID", { 0xfc9a50c1, 0x8b3d, 0x40d0, { 0x99, 0x12, 0x6e, 0x26, 0xd7, 0x89, 0x6c, 0xba } } },
+ { L"AMI_INTERNAL_FACTORY_TDC_TDP_HOB_GUID", { 0x982d8c6f, 0xf6f6, 0x4135, { 0xa3, 0x09, 0xa4, 0x59, 0x3e, 0xa5, 0x64, 0x17 } } },
+ { L"AMI_INTERNAL_UCODE_HOB_GUID", { 0x94567c6f, 0xf7a9, 0x4229, { 0x13, 0x30, 0xfe, 0x11, 0xcc, 0xab, 0x3a, 0x11 } } },
+ { L"AMI_INT_SMM_COMM_PROTOCOL_GUID", { 0xb27dab38, 0x9814, 0x4e06, { 0xa5, 0xa2, 0x65, 0xae, 0x9a, 0x14, 0x25, 0x8f } } },
+ { L"AMI_IRQ_DMA_MASK_VARIABLE_GUID", { 0xfc8be767, 0x89f1, 0x4d6e, { 0x80, 0x99, 0x6f, 0x02, 0x1e, 0xbc, 0x87, 0xcc } } },
+ { L"AMI_ISO9660_MEDIA_GUID", { 0xba7c46d1, 0x9c5e, 0x4fc8, { 0x94, 0x3d, 0x1a, 0x49, 0x1f, 0x23, 0xfe, 0x01 } } },
+ { L"AMI_LOAD_CSM_GUID", { 0x16287ba4, 0x5b9d, 0x4d98, { 0x91, 0x9f, 0x7b, 0x7b, 0x78, 0xcb, 0x2b, 0xe0 } } },
+ { L"AMI_MASKED_DEVICE_PATH_GUID", { 0x99e275e7, 0x75a0, 0x4b37, { 0xa2, 0xe6, 0xc5, 0x38, 0x5e, 0x6c, 0x00, 0xcb } } },
+ { L"AMI_MEASURE_PCIOPROM_GUID", { 0xb3dae700, 0x2a77, 0x4ea4, { 0xaf, 0x79, 0x32, 0x97, 0xb4, 0x84, 0xbe, 0x61 } } },
+ { L"AMI_MEDIA_DEVICE_PATH_GUID", { 0x5023b95c, 0xdb26, 0x429b, { 0xa6, 0x48, 0xbd, 0x47, 0x66, 0x4c, 0x80, 0x12 } } },
+ { L"AMI_MEMORY_ERROR_REPORT_PPI_GUID", { 0x85226559, 0x0def, 0x48d8, { 0xa8, 0xc9, 0xb7, 0x46, 0xd6, 0xa4, 0xdf, 0x01 } } },
+ { L"AMI_MRC_INFO_HOB_GUID", { 0xa6351a87, 0x2965, 0x4718, { 0x88, 0xc7, 0x0b, 0x5b, 0x5a, 0xc0, 0xb5, 0xe4 } } },
+ { L"AMI_NB_MRC_INFO_GUID", { 0x6737934b, 0xa27e, 0x4c05, { 0xad, 0x5b, 0x6a, 0xb8, 0x62, 0x73, 0x68, 0x0b } } },
+ { L"AMI_NVRAM_SPD_MAP_GUID", { 0x717fc150, 0xabd9, 0x4614, { 0x80, 0x15, 0x0b, 0x33, 0x23, 0xea, 0xb9, 0x5c } } },
+ { L"AMI_OPROM_POLICY_PROTOCOL_GUID", { 0x542d6248, 0x4198, 0x4960, { 0x9f, 0x59, 0x23, 0x84, 0x64, 0x6d, 0x63, 0xb4 } } },
+ { L"AMI_OS_PPI_CONFIRMATION_OVERRIDE_GUID", { 0x5f171f5f, 0x8385, 0x4086, { 0xa6, 0x9b, 0x1f, 0xcf, 0x06, 0xae, 0x4a, 0x3d } } },
+ { L"AMI_PB_KEY_RSA2048_GUID", { 0x04627b9b, 0x385e, 0x4744, { 0x90, 0x21, 0xe6, 0x63, 0x19, 0xf2, 0x03, 0x94 } } },
+ { L"AMI_PCI_BUS_EXT_PROTOCOL_GUID", { 0xf42a009d, 0x977f, 0x4f08, { 0x94, 0x40, 0xbc, 0xa5, 0xa3, 0xbe, 0xd9, 0xaf } } },
+ { L"AMI_PEI_AFTER_MRC_GUID", { 0x64c96700, 0x6b4c, 0x480c, { 0xa3, 0xe1, 0xb8, 0xbd, 0xe8, 0xf6, 0x02, 0xb2 } } },
+ { L"AMI_PEI_CPUINIT_POLICY_PPI_GUID", { 0xf824ccbb, 0xd8e0, 0x4522, { 0x8a, 0xa8, 0x65, 0xf0, 0x4b, 0x46, 0x3d, 0xb5 } } },
+ { L"AMI_PEI_END_MEMORY_DETECT_GUID", { 0x9f58e424, 0xb96b, 0x45a5, { 0xad, 0xdc, 0xd2, 0xfe, 0x39, 0x4a, 0x99, 0xd9 } } },
+ { L"AMI_PEI_END_OF_MRC_GUID", { 0x633194be, 0x1697, 0x11e1, { 0xb5, 0xf0, 0x2c, 0xb2, 0x48, 0x24, 0x01, 0x9b } } },
+ { L"AMI_PEIM_HOB_GUID", { 0xf4491ba4, 0x7672, 0x486f, { 0xb4, 0xd7, 0x99, 0x89, 0x9d, 0x22, 0xda, 0x57 } } },
+ { L"AMI_PEIM_LOAD_HOB_GUID", { 0xec9c36fd, 0x1642, 0x4b84, { 0x91, 0xfa, 0x91, 0x9c, 0x2d, 0x06, 0x6f, 0xb4 } } },
+ { L"AMI_PEI_MRC_DEFAULT_GUID", { 0xe813e116, 0xc099, 0x4d21, { 0x9c, 0x34, 0xa5, 0x52, 0xd5, 0xe9, 0xa5, 0xd0 } } },
+ { L"AMI_PEI_NB_CPU_ONLY_RESET_PPI_GUID", { 0x1f0f049e, 0x3a68, 0x4c97, { 0x86, 0x5a, 0xbc, 0x5e, 0xed, 0x79, 0x20, 0xe7 } } },
+ { L"AMI_PEI_NB_CUSTOM_PPI_GUID", { 0x584cc99f, 0x4be8, 0x43d1, { 0xa4, 0x5a, 0x93, 0x3d, 0xc3, 0x94, 0x79, 0xfc } } },
+ { L"AMI_PEI_NBINIT_POLICY_PPI_GUID", { 0x9ce4d938, 0x9c87, 0x41d0, { 0x9e, 0x55, 0x34, 0x92, 0x3f, 0xaf, 0x8b, 0x4f } } },
+ { L"AMI_PEI_PCI_TABLE_INIT_PPI_GUID", { 0x97f91e78, 0xea12, 0x4ea6, { 0xb7, 0xb3, 0x7b, 0x06, 0x78, 0xc2, 0x86, 0x73 } } },
+ { L"AMI_PEI_SB_CUSTOM_PPI_GUID", { 0x38965bb5, 0x8097, 0x40f5, { 0xb7, 0x42, 0x8c, 0xc1, 0x4a, 0x64, 0x9b, 0x64 } } },
+ { L"AMI_PEI_SBINIT_POLICY_PPI_GUID", { 0x95e8152b, 0x1b98, 0x4f11, { 0x8a, 0x77, 0xdb, 0x26, 0x58, 0x3e, 0xbc, 0x42 } } },
+ { L"AMI_PEI_SB_OEM_PLATFORM_POLICY_OVERRIDE_PPI_GUID", { 0x61187967, 0x9a77, 0x419d, { 0xaa, 0xea, 0x64, 0xdd, 0x56, 0x19, 0x08, 0x15 } } },
+ { L"AMI_PEI_SET_NB_SUBID_PPI_GUID", { 0x584cc99f, 0x4be8, 0x43d1, { 0xa4, 0x5a, 0x93, 0x3d, 0xc3, 0x94, 0x79, 0xfc } } },
+ { L"AMI_PERF_TUNE_DATA_HOB_GUID", { 0x4d6c0496, 0x8de4, 0x4af2, { 0x9a, 0x2e, 0x9b, 0xe5, 0xb9, 0x15, 0x6a, 0xc5 } } },
+ { L"AMI_PLL_OVER_VOTAGE_FLAG_HOB_GUID", { 0x181e874d, 0xc089, 0x4c99, { 0x8e, 0xc2, 0x6d, 0x67, 0x61, 0x34, 0x82, 0x20 } } },
+ { L"AMI_POST_MANAGER_PROTOCOL_GUID", { 0x8a91b1e1, 0x56c7, 0x4adc, { 0xab, 0xeb, 0x1c, 0x2c, 0xa1, 0x72, 0x9e, 0xff } } },
+ { L"AMI_RECOVERY_IMAGE_HOB_GUID", { 0xdac3cb98, 0x2295, 0x412e, { 0x82, 0x6d, 0xfd, 0xee, 0xa3, 0x20, 0xcf, 0x31 } } },
+ { L"AMI_RESET_TYPE_HOB_GUID", { 0x39e8cda1, 0x6a35, 0x4cdd, { 0xa9, 0x02, 0xd1, 0xa7, 0x95, 0xf7, 0x03, 0x80 } } },
+ { L"AMI_RESET_TYPE_VARIABLE_GUID", { 0x308dd02c, 0x092b, 0x4123, { 0xa2, 0xaf, 0x3e, 0xf4, 0x44, 0x0a, 0x6b, 0x4a } } },
+ { L"AMI_ROM_LAYOUT_HOB_GUID", { 0xd7642443, 0x87b7, 0x4832, { 0x96, 0x07, 0x0e, 0x1e, 0xa8, 0x1c, 0x1d, 0x86 } } },
+ { L"AMI_SB_SMI_PROTOCOL_GUID", { 0x589bc616, 0xbb4f, 0x47ed, { 0x92, 0xf7, 0x93, 0x39, 0x3c, 0x69, 0x7e, 0x25 } } },
+ { L"AMI_SETUP_NVRAM_UPDATE_GUID", { 0xd84beff0, 0x159a, 0x4b60, { 0x9a, 0xb9, 0xac, 0x5c, 0x47, 0x4b, 0xd3, 0xb1 } } },
+ { L"AMI_SMBIOS_CPU_INFO_PROTOCOL_GUID", { 0x3d6cdb0a, 0x5b1f, 0x43a3, { 0xa4, 0x3b, 0x44, 0x12, 0x67, 0xf9, 0xda, 0xb5 } } },
+ { L"AMI_SMBIOS_MEMORY_INFO_HOB_GUID", { 0x7d6b8734, 0xb754, 0x443f, { 0xb5, 0x88, 0x77, 0x43, 0x84, 0x3a, 0xd3, 0xf1 } } },
+ { L"AMI_SMBUS_HOB_GUID", { 0x017cb4b7, 0xb80c, 0x4040, { 0xb6, 0xc8, 0xea, 0x98, 0x2b, 0xbb, 0x25, 0xb7 } } },
+ { L"AMI_SMBUS_SMM_PROTOCOL_GUID", { 0x72e40094, 0x2ee1, 0x497a, { 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0x0c } } },
+ { L"AMI_SMM_DIGITAL_SIGNATURE_PROTOCOL_GUID", { 0x91abc830, 0x16fc, 0x4d9e, { 0xa1, 0x89, 0x5f, 0xc8, 0xbb, 0x41, 0x14, 0x02 } } },
+ { L"AMI_SMM_INFO_PROTOCOL_GUID", { 0xeb5198eb, 0xe7f5, 0x45a1, { 0x9c, 0xcb, 0xe5, 0x33, 0x64, 0xbb, 0x49, 0x92 } } },
+ { L"AMI_STANDARD_DEFAULTS_VARIABLE_GUID", { 0x4599d26f, 0x1a11, 0x49b8, { 0xb9, 0x1f, 0x85, 0x87, 0x45, 0xcf, 0xf8, 0x24 } } },
+ { L"AMI_STATUS_CODE_CPU_BIST_DATA_GUID", { 0xcd541d77, 0x6699, 0x4b36, { 0xa3, 0x1e, 0x1a, 0xa4, 0xc5, 0xd5, 0xb9, 0x46 } } },
+ { L"AMI_TCG_CONFIRMATION_FLAGS_GUID", { 0x7d3dceee, 0xcbce, 0x4ea7, { 0x87, 0x09, 0x6e, 0x55, 0x2f, 0x1e, 0xdb, 0xde } } },
+ { L"AMI_TCG_EFI_OS_VARIABLE_GUID", { 0xa8a2093b, 0xfefa, 0x43c1, { 0x8e, 0x62, 0xce, 0x52, 0x68, 0x47, 0x26, 0x5e } } },
+ { L"AMI_TCG_PERM_FLAGS_GUID", { 0x2325f2fc, 0x5683, 0x4648, { 0x97, 0xc4, 0x9a, 0x52, 0x0d, 0xfb, 0xe3, 0x25 } } },
+ { L"AMI_TCG_PLATFORM_PPI_AFTER_MEM_GUID", { 0x890c2cef, 0x43c8, 0x4209, { 0xa7, 0x8d, 0xae, 0x14, 0xaa, 0x17, 0x98, 0xb4 } } },
+ { L"AMI_TCG_PLATFORM_PPI_BEFORE_MEM_GUID", { 0xc1e6791d, 0xf35b, 0x43ef, { 0x92, 0x0a, 0xbe, 0x06, 0xba, 0x7f, 0x86, 0xa1 } } },
+ { L"AMI_TCG_PLATFORM_PPI_GUID", { 0x05687f4a, 0x3ca7, 0x4d19, { 0x9b, 0xc5, 0xe1, 0x80, 0xce, 0xa3, 0x56, 0x9f } } },
+ { L"AMI_TCG_PLATFORM_PROTOCOL_GUID", { 0x320bdc39, 0x3fa0, 0x4ba9, { 0xbf, 0x2d, 0xb3, 0x3f, 0x72, 0xba, 0x9c, 0xa1 } } },
+ { L"AMI_TCG_RESETVAR_HOB_GUID", { 0xa8a2093b, 0xfefa, 0x43c1, { 0x8e, 0x62, 0xce, 0x52, 0x68, 0x47, 0x26, 0x5e } } },
+ { L"AMITSE_ADMIN_PASSWORD_VALID_GUID", { 0x541d5a75, 0x95ee, 0x43c7, { 0x9e, 0x5d, 0x23, 0x94, 0xdc, 0x48, 0x62, 0x49 } } },
+ { L"AMITSE_AFTER_FIRST_BOOT_OPTION_GUID", { 0xc48d651c, 0x9d0e, 0x4ce7, { 0xad, 0x39, 0xed, 0xd1, 0xab, 0x83, 0x6b, 0x30 } } },
+ { L"AMITSE_BOOT_ORDER_CHANGE_GUID", { 0x1b6bc809, 0xc986, 0x4937, { 0x93, 0x4f, 0x1e, 0xa5, 0x86, 0x22, 0xfe, 0x50 } } },
+ { L"AMITSE_DRIVER_HEALTH_CTRL_GUID", { 0x58279c2d, 0xfb19, 0x466e, { 0xb4, 0x2e, 0xcd, 0x43, 0x70, 0x16, 0xdc, 0x25 } } },
+ { L"AMITSE_DRIVER_HEALTH_ENB_GUID", { 0x0885f288, 0x418c, 0x4be1, { 0xa6, 0xaf, 0x8b, 0xad, 0x61, 0xda, 0x08, 0xfe } } },
+ { L"AMITSE_DRIVER_HEALTH_GUID", { 0x7459a7d4, 0x6533, 0x4480, { 0xbb, 0xa7, 0x79, 0xe2, 0x5a, 0x44, 0x43, 0xc9 } } },
+ { L"AMITSE_EVENT_BEFORE_BOOT_GUID", { 0x3677770f, 0xefb2, 0x43b2, { 0xb8, 0xae, 0xb3, 0x02, 0xe9, 0x60, 0x48, 0x82 } } },
+ { L"AMITSE_INVALID_PASSWORD_GUID", { 0xd69240c0, 0xdd40, 0x4f2d, { 0x98, 0x63, 0x48, 0x48, 0xda, 0x6e, 0x61, 0x5f } } },
+ { L"AMITSE_NVRAM_UPDATE_GUID", { 0xd84beff0, 0x159a, 0x4b60, { 0x9a, 0xb9, 0xac, 0x5c, 0x47, 0x4b, 0xd3, 0xb1 } } },
+ { L"AMITSE_PASSWORD_PROMPT_ENTER_GUID", { 0x073e7e01, 0x2611, 0x4e85, { 0xb8, 0x96, 0xa3, 0xb6, 0x76, 0x7c, 0xba, 0x00 } } },
+ { L"AMITSE_PASSWORD_PROMPT_EXIT_GUID", { 0xb9b038b0, 0xe2b6, 0x4aab, { 0x94, 0x35, 0x41, 0x65, 0xec, 0xfe, 0xd0, 0x32 } } },
+ { L"AMITSE_SETUP_ENTER_GUID", { 0x71202eee, 0x5f53, 0x40d9, { 0xab, 0x3d, 0x9e, 0x0c, 0x26, 0xd9, 0x66, 0x57 } } },
+ { L"AMITSESETUP_GUID", { 0xc811fa38, 0x42c8, 0x4579, { 0xa9, 0xbb, 0x60, 0xe9, 0x4e, 0xdd, 0xfb, 0x34 } } },
+ { L"AMITSE_USER_PASSWORD_VALID_GUID", { 0xab1404ca, 0x4801, 0x4208, { 0x98, 0xbf, 0x30, 0xd5, 0x21, 0xda, 0xd4, 0xd3 } } },
+ { L"AMI_USB_SMM_PROTOCOL_GUID", { 0x3ef7500e, 0xcf55, 0x474f, { 0x8e, 0x7e, 0x00, 0x9e, 0x0e, 0xac, 0xec, 0xd2 } } },
+ { L"AMT_FORCE_PUSH_PET_HOB_GUID", { 0x4efa0db6, 0x26dc, 0x4bb1, { 0xa7, 0x6f, 0x14, 0xbc, 0x63, 0x0c, 0x7b, 0x3c } } },
+ { L"AMT_FORCE_PUSH_PET_POLICY_GUID", { 0xacc8e1e4, 0x9f9f, 0x4e40, { 0xa5, 0x7e, 0xf9, 0x9e, 0x52, 0xf3, 0x4c, 0xa5 } } },
+ { L"AMT_FORCE_PUSH_PET_VARIABLE_GUID", { 0xd7ac94af, 0xa498, 0x45ec, { 0xbf, 0xa2, 0xa5, 0x6e, 0x95, 0x34, 0x61, 0x8b } } },
+ { L"AMT_INT16_CSM_GUID", { 0x6046e678, 0x24ef, 0x4005, { 0xba, 0x39, 0xbd, 0xa1, 0x1f, 0x6d, 0x55, 0x5d } } },
+ { L"AMT_READY_TO_BOOT_PROTOCOL_GUID", { 0x40b09b5a, 0xf0ef, 0x4627, { 0x93, 0xd5, 0x27, 0xf0, 0x4b, 0x75, 0x4d, 0x05 } } },
+ { L"AOAC_EC_WAKEUP_CUSTOM_PPI_GUID", { 0x82627acf, 0xd92d, 0x416d, { 0x8a, 0x6f, 0x78, 0x3c, 0xac, 0xd9, 0x12, 0x23 } } },
+ { L"AOAC_FFS_TABLE_STORAGE_GUID", { 0xfb045db2, 0x598e, 0x485a, { 0xba, 0x30, 0x5d, 0x7b, 0x1b, 0x1b, 0xd5, 0x4d } } },
+ { L"APTIO_FW_CAPSULE_GUID", { 0x4a3ca68b, 0x7723, 0x48fb, { 0x80, 0x3d, 0x57, 0x8c, 0xc1, 0xfe, 0xc4, 0x4d } } },
+ { L"APTIO_HII_PROTOCOL_GUID", { 0xea816d2c, 0xcee5, 0x4f02, { 0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77 } } },
+ { L"ARM_GLOBAL_VARIABLE_PPI_GUID", { 0xab1c1816, 0xd542, 0x4e6f, { 0x9b, 0x1e, 0x8e, 0xcd, 0x92, 0x53, 0xe2, 0xe7 } } },
+ { L"ARM_HOB_GLOBAL_VARIABLE_GUID", { 0xc3253c90, 0xa24f, 0x4599, { 0xa6, 0x64, 0x1f, 0x88, 0x13, 0x77, 0x8f, 0xc9 } } },
+ { L"ARM_MP_CORE_INFO_GUID", { 0xa4ee0728, 0xe5d7, 0x4ac5, { 0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34 } } },
+ { L"ARM_MP_CORE_INFO_PPI_GUID", { 0x6847cc74, 0xe9ec, 0x4f8f, { 0xa2, 0x9d, 0xab, 0x44, 0xe7, 0x54, 0xa8, 0xfc } } },
+ { L"AUTHVAR_MAILBOX_VARIABLE_GUID", { 0x532b6532, 0x6499, 0x428d, { 0xac, 0xb1, 0xf6, 0xf7, 0x79, 0xc9, 0x4d, 0xf9 } } },
+ { L"BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID", { 0xdbc9fd21, 0xfad8, 0x45b0, { 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93 } } },
+ { L"BDS_CONNECT_DRIVERS_PROTOCOL_GUID", { 0x3aa83745, 0x9454, 0x4f7a, { 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e } } },
+ { L"BDS_LIB_STRING_PACKAGE_GUID", { 0x3b4d9b23, 0x95ac, 0x44f6, { 0x9f, 0xcd, 0x0e, 0x95, 0x94, 0x58, 0x6c, 0x72 } } },
+ { L"BLOCK_DEVICE_RECOVERY_CAPSULE_GUID", { 0x0ba8263c, 0xa8bd, 0x4aad, { 0xb4, 0x02, 0x6a, 0x6a, 0xf2, 0xf7, 0xe7, 0x7d } } },
+ { L"BLOCKIO_VENDOR_GUID", { 0xcf31fac5, 0xc24e, 0x11d2, { 0x85, 0xf3, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } } },
+ { L"BLOCK_MMIO_PROTOCOL_GUID", { 0x6b558ce3, 0x69e5, 0x4c67, { 0xa6, 0x34, 0xf7, 0xfe, 0x72, 0xad, 0xbe, 0x84 } } },
+ { L"BOOT_FLOW_VARIABLE_GUID", { 0xef152fb4, 0x7b2f, 0x427d, { 0xbd, 0xb4, 0x7e, 0x0a, 0x05, 0x82, 0x6e, 0x64 } } },
+ { L"BOOT_FORM_SET_GUID", { 0x8b33ffe0, 0xd71c, 0x4f82, { 0x9c, 0xeb, 0xc9, 0x70, 0x58, 0xc1, 0x3f, 0x8e } } },
+ { L"BOOT_MAINT_FORMSET_GUID", { 0x642237c7, 0x35d4, 0x472d, { 0x83, 0x65, 0x12, 0xe0, 0xcc, 0xf2, 0x7a, 0x22 } } },
+ { L"BOOT_MANAGER_FORMSET_GUID", { 0x847bc3fe, 0xb974, 0x446d, { 0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b } } },
+ { L"BOOT_MANAGER_GUID", { 0xb4909cf3, 0x7b93, 0x4751, { 0x9b, 0xd8, 0x5b, 0xa8, 0x22, 0x0b, 0x9b, 0xb2 } } },
+ { L"BOOT_NOW_COUNT_GUID", { 0x052e6eb0, 0xf240, 0x42c5, { 0x83, 0x09, 0x45, 0x87, 0x45, 0x45, 0xc6, 0xb4 } } },
+ { L"BOOT_OBJECT_AUTHORIZATION_PARMSET_GUID", { 0xedd35e31, 0x07b9, 0x11d2, { 0x83, 0xa3, 0x00, 0xa0, 0xc9, 0x1f, 0xad, 0xcf } } },
+ { L"CHIPSET_FORM_SET_GUID", { 0xadfe34c8, 0x9ae1, 0x4f8f, { 0xbe, 0x13, 0xcf, 0x96, 0xa2, 0xcb, 0x2c, 0x5b } } },
+ { L"CMOS_MANAGER_HOB_GUID", { 0xd5367802, 0xb873, 0x4c0f, { 0xb5, 0x44, 0x31, 0xb7, 0xcc, 0xf5, 0xc5, 0x55 } } },
+ { L"CONNECT_CONIN_EVENT_GUID", { 0xdb4e8151, 0x57ed, 0x4bed, { 0x88, 0x33, 0x67, 0x51, 0xb5, 0xd1, 0xa8, 0xd7 } } },
+ { L"CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID", { 0x2df1e051, 0x906d, 0x4eff, { 0x86, 0x9d, 0x24, 0xe6, 0x53, 0x78, 0xfb, 0x9e } } },
+ { L"CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID", { 0xef9a3971, 0xc1a0, 0x4a93, { 0xbd, 0x40, 0x5a, 0xa1, 0x65, 0xf2, 0xdc, 0x3a } } },
+ { L"CPU_MICROCODE_FILE_GUID", { 0x17088572, 0x377f, 0x44ef, { 0x8f, 0x4e, 0xb0, 0x9f, 0xff, 0x46, 0xa0, 0x70 } } },
+ { L"CPU_WAKE_UP_BUFFER_VARIABLE_GUID", { 0xdf665292, 0x79d7, 0x40e2, { 0xba, 0x51, 0xf7, 0xd4, 0x94, 0x62, 0x81, 0x85 } } },
+ { L"CSM_VIDEO_POLICY_PROTOCOL_GUID", { 0x3a4e4376, 0x4871, 0x4b0e, { 0xa0, 0x2f, 0xed, 0x36, 0xf2, 0xae, 0xcd, 0x00 } } },
+ { L"DCA_HOB_GUID", { 0x6865c455, 0x8626, 0x40d8, { 0x90, 0xf4, 0xa6, 0x94, 0x60, 0xa4, 0xab, 0x5a } } },
+ { L"DEBUGGER_TERMINAL_VAR_GUID", { 0x97ca1a5b, 0xb760, 0x4d1f, { 0xa5, 0x4b, 0xd1, 0x90, 0x92, 0x03, 0x2c, 0x90 } } },
+ { L"DEFINE_GUID_AcpiPlatformPeiBin_GUID", { 0x333bb2a3, 0x4f20, 0x4c8b, { 0xac, 0x38, 0x06, 0x72, 0xd7, 0x43, 0x15, 0xf8 } } },
+ { L"DEFINE_GUID_AcpiPlatformSmiBin_GUID", { 0xdfd8d5cc, 0x5aed, 0x4820, { 0xa2, 0xb6, 0x5c, 0x55, 0xe4, 0xe6, 0x40, 0xef } } },
+ { L"DEFINE_GUID_CRBDXEBin_GUID", { 0x16271fca, 0x55d9, 0x4a33, { 0x93, 0xfc, 0x5a, 0x3e, 0xb1, 0x28, 0xde, 0xb6 } } },
+ { L"DEFINE_GUID_CRBPEIBin_GUID", { 0x0d1ed2f7, 0xe92b, 0x4562, { 0x92, 0xdd, 0x5c, 0x82, 0xec, 0x91, 0x7e, 0xae } } },
+ { L"DEFINE_GUID_CRBSMIBin_GUID", { 0x221f1d4f, 0x034c, 0x4bea, { 0xb2, 0xbb, 0xb7, 0xa9, 0x67, 0x2b, 0x06, 0xd7 } } },
+ { L"DEFINE_GUID_NBDXEBin_GUID", { 0xe4ecd0b2, 0xe277, 0x4f2b, { 0xbe, 0xcb, 0xe4, 0xd7, 0x5c, 0x9a, 0x81, 0x2e } } },
+ { L"DEFINE_GUID_NBPEIBin_GUID", { 0x79aa6086, 0x035a, 0x4ad9, { 0xa8, 0x9a, 0xa6, 0xd5, 0xaa, 0x27, 0xf0, 0xe2 } } },
+ { L"DEFINE_GUID_OEMDXEBin_GUID", { 0xbfe205c9, 0x5b17, 0x4f8f, { 0x93, 0x75, 0x89, 0x61, 0x4a, 0xf8, 0xe1, 0x99 } } },
+ { L"DEFINE_GUID_OEMPEIBin_GUID", { 0x6e59df06, 0x62d3, 0x40b0, { 0x82, 0xb5, 0x17, 0x5c, 0xf8, 0x4a, 0x94, 0xe4 } } },
+ { L"DEFINE_GUID_SBDXEBin_GUID", { 0xb7d19491, 0xe55a, 0x470d, { 0x85, 0x08, 0x85, 0xa5, 0xdf, 0xa4, 0x19, 0x74 } } },
+ { L"DEFINE_GUID_SBPEIBin_GUID", { 0xc1fbd624, 0x27ea, 0x40d1, { 0xaa, 0x48, 0x94, 0xc3, 0xdc, 0x5c, 0x7e, 0x0d } } },
+ { L"DEFINE_GUID_SBRunBin_GUID", { 0xe23f86e1, 0x056e, 0x4888, { 0xb6, 0x85, 0xcf, 0xcd, 0x67, 0xc1, 0x79, 0xd4 } } },
+ { L"DEL_BOOT_OPTION_GUID", { 0xf6c73719, 0xf34c, 0x479c, { 0xb3, 0x2f, 0x27, 0x7f, 0xcb, 0xbc, 0xfe, 0x4f } } },
+ { L"DEVICE_MANAGER_FORMSET_GUID", { 0x3ebfa8e6, 0x511d, 0x4b5b, { 0xa9, 0x5f, 0xfb, 0x38, 0x26, 0x0f, 0x1c, 0x27 } } },
+ { L"DIMM_TS_INFO_GUID", { 0xce673a28, 0x800d, 0x4b4a, { 0x83, 0x16, 0x26, 0x61, 0xf9, 0xb3, 0xd9, 0xc6 } } },
+ { L"DRIVER_HEALTH_FORMSET_GUID", { 0xf76e0a70, 0xb5ed, 0x4c38, { 0xac, 0x9a, 0xe5, 0xf5, 0x4b, 0xf1, 0x6e, 0x34 } } },
+ { L"DRIVER_SAMPLE_FORMSET_GUID", { 0xa04a27f4, 0xdf00, 0x4d42, { 0xb5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3d } } },
+ { L"DRIVER_SAMPLE_INVENTORY_GUID", { 0xb3f56470, 0x6141, 0x4621, { 0x8f, 0x19, 0x70, 0x4e, 0x57, 0x7a, 0xa9, 0xe8 } } },
+ { L"DUET_CONSOLEOUT_CONFIG_GUID", { 0xed150714, 0xdf30, 0x407d, { 0xb2, 0x4a, 0x4b, 0x74, 0x2f, 0xd5, 0xce, 0xa2 } } },
+ { L"DXE_CORE_FILE_NAME_GUID", { 0xd6a2cb7f, 0x6a18, 0x4e2f, { 0xb4, 0x3b, 0x99, 0x20, 0xa7, 0x33, 0x70, 0x0a } } },
+ { L"DXE_CPU_CACHE_PROTOCOL_GUID", { 0x5c6fa2c9, 0x9768, 0x45f6, { 0x8e, 0x64, 0x5a, 0xec, 0xca, 0xda, 0xb4, 0x81 } } },
+ { L"DXE_CPU_INFO_PROTOCOL_GUID", { 0xe223cf65, 0xf6ce, 0x4122, { 0xb3, 0xaf, 0x4b, 0xd1, 0x8a, 0xff, 0x40, 0xa1 } } },
+ { L"DXE_CPU_PLATFORM_POLICY_PROTOCOL_GUID", { 0xbd26cdc9, 0xa092, 0x462a, { 0x87, 0x7a, 0x5a, 0xb6, 0xad, 0xce, 0x48, 0x12 } } },
+ { L"DXE_ENHANCED_SPEEDSTEP_PROTOCOL_GUID", { 0x00e98021, 0xf4fe, 0x46cc, { 0xab, 0x2d, 0x89, 0x4c, 0x37, 0x3a, 0xfa, 0x01 } } },
+ { L"DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID", { 0xe0a31dbe, 0xf20e, 0x4e2a, { 0x9f, 0x2b, 0x9f, 0x02, 0xa2, 0x7d, 0x3d, 0x69 } } },
+ { L"DXE_PLATFORM_AMT_POLICY_GUID", { 0xb2ab115e, 0xc8b6, 0x4036, { 0xbf, 0x31, 0xe7, 0x4b, 0xd8, 0x92, 0x6c, 0xce } } },
+ { L"DXE_PLATFORM_ME_POLICY_GUID", { 0xf8bff014, 0x18fb, 0x4ef9, { 0xb1, 0x0c, 0xae, 0x22, 0x73, 0x8d, 0xbe, 0xed } } },
+ { L"DXE_PLATFORM_SA_POLICY_GUID", { 0xcd2333d7, 0x6a0a, 0x4c76, { 0x83, 0x50, 0x24, 0x0a, 0xda, 0x36, 0xa2, 0xc7 } } },
+ { L"DXE_PLATFORM_SG_POLICY_GUID", { 0x6199dc36, 0xe114, 0x4e0d, { 0x80, 0x99, 0x99, 0xa0, 0xbd, 0x80, 0xa9, 0x71 } } },
+ { L"DXE_PLATFORM_TDT_POLICY_GUID", { 0x20daf0fc, 0x5548, 0x44dc, { 0xa4, 0x2a, 0x60, 0xea, 0xf0, 0xa2, 0x2e, 0x47 } } },
+ { L"DXE_SERVICES_TABLE_GUID", { 0x05ad34ba, 0x6f02, 0x4214, { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } } },
+ { L"DXE_TXT_POLICY_PROTOCOL_GUID", { 0x43f66ffd, 0xb288, 0x4139, { 0xba, 0xd5, 0xb8, 0x98, 0x03, 0xe7, 0x30, 0xa2 } } },
+ { L"DYNAMIC_PAGE_COUNT_GUID", { 0xb63bf800, 0xf267, 0x4f55, { 0x92, 0x17, 0xe9, 0x7f, 0xb3, 0xb6, 0x98, 0x46 } } },
+ { L"EBL_ADD_COMMAND_PROTOCOL_GUID", { 0xaeda2428, 0x9a22, 0x4637, { 0x9b, 0x21, 0x54, 0x5e, 0x28, 0xfb, 0xb8, 0x29 } } },
+ { L"ECP_PEI_PCI_CFG_PPI_GUID", { 0xb0ee53d4, 0xa049, 0x4a79, { 0xb2, 0xff, 0x19, 0xd9, 0xfa, 0xef, 0xaa, 0x94 } } },
+ { L"EDKII_FAULT_TOLERANT_WRITE_GUID", { 0x1d3e9cb8, 0x43af, 0x490b, { 0x83, 0x0a, 0x35, 0x16, 0xaa, 0x53, 0x20, 0x47 } } },
+ { L"EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL_GUID", { 0xa770c357, 0xb693, 0x4e6d, { 0xa6, 0xcf, 0xd2, 0x1c, 0x72, 0x8e, 0x55, 0x0b } } },
+ { L"EDKII_FORM_DISPLAY_ENGINE_PROTOCOL_GUID", { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } } },
+ { L"EDKII_VARIABLE_LOCK_PROTOCOL_GUID", { 0xcd3d0a05, 0x9e24, 0x437c, { 0xa8, 0x91, 0x1e, 0xe0, 0x53, 0xdb, 0x76, 0x38 } } },
+ { L"EDKII_WORKING_BLOCK_SIGNATURE_GUID", { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x00, 0xfd, 0x9f, 0x1b, 0x95 } } },
+ { L"EFI_ABSOLUTE_POINTER_PROTOCOL_GUID", { 0x8d59d32b, 0xc655, 0x4ae9, { 0x9b, 0x15, 0xf2, 0x59, 0x04, 0x99, 0x2a, 0x43 } } },
+ { L"EFI_ACPI_20_TABLE_GUID", { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_ACPI_DESCRIPTION_GUID", { 0x3c699197, 0x093c, 0x4c69, { 0xb0, 0x6b, 0x12, 0x8a, 0xe3, 0x48, 0x1d, 0xc9 } } },
+ { L"EFI_ACPI_S3_CONTEXT_GUID", { 0x0ef98d3a, 0x3e33, 0x497a, { 0xa4, 0x01, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38 } } },
+ { L"EFI_ACPI_S3_SAVE_GUID", { 0x125f2de1, 0xfb85, 0x440c, { 0xa5, 0x4c, 0x4d, 0x99, 0x35, 0x8a, 0x8d, 0x38 } } },
+ { L"EFI_ACPI_SDT_PROTOCOL_GUID", { 0xeb97088e, 0xcfdf, 0x49c6, { 0xbe, 0x4b, 0xd9, 0x06, 0xa5, 0xb2, 0x0e, 0x86 } } },
+ { L"EFI_ACPI_SUPPORT_GUID", { 0xdbff9d55, 0x89b7, 0x46da, { 0xbd, 0xdf, 0x67, 0x7d, 0x3d, 0xc0, 0x24, 0x1d } } },
+ { L"EFI_ACPI_TABLE_GUID", { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_ACPI_TABLE_GUID", { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_ACPI_TABLE_PROTOCOL_GUID", { 0xffe06bdd, 0x6107, 0x46a6, { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c } } },
+ { L"EFI_ACPI_TABLE_STORAGE_GUID", { 0x7e374e25, 0x8e01, 0x4fee, { 0x87, 0xf2, 0x39, 0x0c, 0x23, 0xc6, 0x06, 0xcd } } },
+ { L"EFI_ACPI_VARIABLE_COMPATIBILITY_GUID", { 0xc020489e, 0x6db2, 0x4ef2, { 0x9a, 0xa5, 0xca, 0x06, 0xfc, 0x11, 0xd3, 0x6a } } },
+ { L"EFI_ACPI_VARIABLE_GUID", { 0xaf9ffd67, 0xec10, 0x488a, { 0x9d, 0xfc, 0x6c, 0xbf, 0x5e, 0xe2, 0x2c, 0x2e } } },
+ { L"EFI_ACTIVE_BIOS_PROTOCOL_GUID", { 0xebbe2d1b, 0x1647, 0x4bda, { 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a } } },
+ { L"EFI_ACTIVE_MANAGEMENT_PROTOCOL_GUID", { 0x8555fd40, 0x140b, 0x4f3c, { 0x90, 0x5e, 0x3b, 0xf3, 0x78, 0xa0, 0x99, 0xfa } } },
+ { L"EFI_AHCI_INT13_INIT_PROTOCOL_GUID", { 0x67820532, 0x7613, 0x4dd3, { 0x9e, 0xd7, 0x3d, 0x9b, 0xe3, 0xa7, 0xda, 0x63 } } },
+ { L"EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GUID", { 0xcc93a70b, 0xec27, 0x49c5, { 0x8b, 0x34, 0x13, 0x93, 0x1e, 0xfe, 0xd6, 0xe2 } } },
+ { L"EFI_ALTERNATE_FV_BLOCK_GUID", { 0xf496922d, 0x172f, 0x4bbc, { 0xa1, 0xeb, 0x0e, 0xeb, 0x94, 0x9c, 0x34, 0x86 } } },
+ { L"EFI_AMI_LEGACYBOOT_PROTOCOL_GUID", { 0x120d28aa, 0x6630, 0x46f0, { 0x81, 0x57, 0xc0, 0xad, 0xc2, 0x38, 0x3b, 0xf5 } } },
+ { L"EFI_APRIORI_GUID", { 0xfc510ee7, 0xffdc, 0x11d4, { 0xbd, 0x41, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_ARP_PROTOCOL_GUID", { 0xf4b427bb, 0xba21, 0x4f16, { 0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c } } },
+ { L"EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID", { 0xf44c00ee, 0x1f2c, 0x4a00, { 0xaa, 0x09, 0x1c, 0x9f, 0x3e, 0x08, 0x00, 0xa3 } } },
+ { L"EFI_ATA_PASS_THRU_PROTOCOL_GUID", { 0x1d3de7f0, 0x0807, 0x424f, { 0xaa, 0x69, 0x11, 0xa5, 0x4e, 0x19, 0xa4, 0x6f } } },
+ { L"EFI_AUTHENTICATED_VARIABLE_GUID", { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } } },
+ { L"EFI_AUTHENTICATION_CHAP_LOCAL_GUID", { 0xc280c73e, 0x15ca, 0x11da, { 0xb0, 0xca, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } } },
+ { L"EFI_AUTHENTICATION_CHAP_RADIUS_GUID", { 0xd6062b50, 0x15ca, 0x11da, { 0x92, 0x19, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } } },
+ { L"EFI_AUTHENTICATION_INFO_PROTOCOL_GUID", { 0x7671d9d0, 0x53db, 0x4173, { 0xaa, 0x69, 0x23, 0x27, 0xf2, 0x1f, 0x0b, 0xc7 } } },
+ { L"EFI_AUTHORIZATION_PROTOCOL_GUID", { 0x995188b1, 0x9f96, 0x11d4, { 0x87, 0xae, 0x00, 0x06, 0x29, 0x2e, 0x8a, 0x3b } } },
+ { L"EFI_BDAT_ACCESS_GUID", { 0xb979746a, 0x8c1f, 0x4a2b, { 0x97, 0xe4, 0x78, 0xe9, 0x3a, 0x71, 0xa7, 0x0a } } },
+ { L"EFI_BDS_ARCH_PROTOCOL_GUID", { 0x665e3ff6, 0x46cc, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_BIS_PROTOCOL_GUID", { 0x0b64aab0, 0x5429, 0x11d4, { 0x98, 0x16, 0x00, 0xa0, 0xc9, 0x1f, 0xad, 0xcf } } },
+ { L"EFI_BLOCK_IO2_PROTOCOL_GUID", { 0xa77b2472, 0xe282, 0x4e9f, { 0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1 } } },
+ { L"EFI_BLOCK_IO_PROTOCOL_GUID", { 0x964e5b21, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_BOOT_LOGO_PROTOCOL_GUID", { 0xcdea2bd3, 0xfc25, 0x4c1c, { 0xb9, 0x7c, 0xb3, 0x11, 0x86, 0x06, 0x49, 0x90 } } },
+ { L"EFI_BOOT_SCRIPT_EXECUTOR_CONTEXT_GUID", { 0x79cb58c4, 0xac51, 0x442f, { 0xaf, 0xd7, 0x98, 0xe4, 0x7d, 0x2e, 0x99, 0x08 } } },
+ { L"EFI_BOOT_SCRIPT_EXECUTOR_VARIABLE_GUID", { 0x3079818c, 0x46d4, 0x4a73, { 0xae, 0xf3, 0xe3, 0xe4, 0x6c, 0xf1, 0xee, 0xdb } } },
+ { L"EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID", { 0x470e1529, 0xb79e, 0x4e32, { 0xa0, 0xfe, 0x6a, 0x15, 0x6d, 0x29, 0xf9, 0xb2 } } },
+ { L"EFI_BOOT_STATE_VARIABLE_GUID", { 0x60b5e939, 0x0fcf, 0x4227, { 0xba, 0x83, 0x6b, 0xbe, 0xd4, 0x5b, 0xc0, 0xe3 } } },
+ { L"EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID", { 0x3bc1b285, 0x8a15, 0x4a82, { 0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65 } } },
+ { L"EFI_CACHE_INSTALL_PPI_GUID", { 0xbb628ae0, 0xcd4f, 0x49fe, { 0x8d, 0x60, 0x63, 0x18, 0x6f, 0xd1, 0xe0, 0x5b } } },
+ { L"EFI_CACHE_SUBCLASS_GUID", { 0x7f0013a7, 0xdc79, 0x4b22, { 0x80, 0x99, 0x11, 0xf7, 0x5f, 0xdc, 0x82, 0x9d } } },
+ { L"EFI_CAPSULE_AMI_GUID", { 0xfac2efad, 0x8511, 0x4e34, { 0x9c, 0xae, 0x16, 0xa2, 0x57, 0xba, 0x94, 0x88 } } },
+ { L"EFI_CAPSULE_ARCH_PROTOCOL_GUID", { 0x5053697e, 0x2cbc, 0x4819, { 0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54 } } },
+ { L"EFI_CAPSULE_GUID", { 0x3b6686bd, 0x0d76, 0x4030, { 0xb7, 0x0e, 0xb5, 0x51, 0x9e, 0x2f, 0xc5, 0xa0 } } },
+ { L"EFI_CAPSULE_INFO_GUID", { 0x8b34eac7, 0x2690, 0x460b, { 0x8b, 0xa5, 0xd5, 0xcf, 0x32, 0x83, 0x17, 0x35 } } },
+ { L"EFI_CAPSULE_VENDOR_GUID", { 0x711c703f, 0xc285, 0x4b10, { 0xa3, 0xb0, 0x36, 0xec, 0xbd, 0x3c, 0x8b, 0xe2 } } },
+ { L"EFI_CERT_RSA2048_GUID", { 0x3c5766e8, 0x269c, 0x4e34, { 0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6 } } },
+ { L"EFI_CERT_RSA2048_SHA1_GUID", { 0x67f8444f, 0x8743, 0x48f1, { 0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80 } } },
+ { L"EFI_CERT_RSA2048_SHA256_GUID", { 0xe2b36190, 0x879b, 0x4a3d, { 0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84 } } },
+ { L"EFI_CERT_SHA1_GUID", { 0x826ca512, 0xcf10, 0x4ac9, { 0xb1, 0x87, 0xbe, 0x01, 0x49, 0x66, 0x31, 0xbd } } },
+ { L"EFI_CERT_SHA224_GUID", { 0x0b6e5233, 0xa65c, 0x44c9, { 0x94, 0x07, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd } } },
+ { L"EFI_CERT_SHA256_GUID", { 0xc1c41626, 0x504c, 0x4092, { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 } } },
+ { L"EFI_CERT_SHA384_GUID", { 0xff3e5307, 0x9fd0, 0x48c9, { 0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x01 } } },
+ { L"EFI_CERT_SHA512_GUID", { 0x093e0fae, 0xa6c4, 0x4f50, { 0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a } } },
+ { L"EFI_CERT_TYPE_PKCS7_GUID", { 0x4aafd29d, 0x68df, 0x49ee, { 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7 } } },
+ { L"EFI_CERT_TYPE_RSA2048_SHA256_GUID", { 0xa7717414, 0xc616, 0x4977, { 0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } } },
+ { L"EFI_CERT_X509_GUID", { 0xa5c059a1, 0x94e4, 0x4aa7, { 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 } } },
+ { L"EFI_CLP_PROTOCOL_GUID", { 0xcbbee336, 0x2682, 0x4cd6, { 0x81, 0x8b, 0x0a, 0x0d, 0x96, 0x7e, 0x5a, 0x67 } } },
+ { L"EFI_CMOS_DATA_HOB_INSTALLED_GUID", { 0x5a6a93f4, 0x2907, 0x4a34, { 0xbd, 0x11, 0x6c, 0xa8, 0xa0, 0x95, 0x9e, 0x09 } } },
+ { L"EFI_COMPATIBLE_MEMORY_TESTED_PROTOCOL_GUID", { 0x64c475ef, 0x344b, 0x492c, { 0x93, 0xad, 0xab, 0x9e, 0xb4, 0x39, 0x50, 0x04 } } },
+ { L"EFI_COMPONENT_NAME2_PROTOCOL_GUID", { 0x6a7a5cff, 0xe8d9, 0x4f70, { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14 } } },
+ { L"EFI_COMPONENT_NAME_PROTOCOL_GUID", { 0x107a772c, 0xd5e1, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_CONFIG_FILE_NAME_GUID", { 0x98b8d59b, 0xe8ba, 0x48ee, { 0x98, 0xdd, 0xc2, 0x95, 0x39, 0x2f, 0x1e, 0xdb } } },
+ { L"EFI_CONSOLE_CONTROL_PROTOCOL_GUID", { 0xf42f7782, 0x012e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x04, 0xf7, 0x21 } } },
+ { L"EFI_CONSOLE_IN_DEVICE_GUID", { 0xd3b36f2b, 0xd551, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_CONSOLE_LOCK_GUID", { 0x368cda0d, 0xcf31, 0x4b9b, { 0x8c, 0xf6, 0xe7, 0xd1, 0xbf, 0xff, 0x15, 0x7e } } },
+ { L"EFI_CONSOLE_OUT_DEVICE_GUID", { 0xd3b36f2c, 0xd551, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_CPU_ARCH_PROTOCOL_GUID", { 0x26baccb1, 0x6f42, 0x11d4, { 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_CPU_IO2_PROTOCOL_GUID", { 0xad61f191, 0xae5f, 0x4c0e, { 0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f } } },
+ { L"EFI_CPU_IO2_PROTOCOL_GUID", { 0xb0732526, 0x38c8, 0x4b40, { 0x88, 0x77, 0x61, 0xc7, 0xb0, 0x6a, 0xac, 0x45 } } },
+ { L"EFI_CPU_IO_PROTOCOL_GUID", { 0xb0732526, 0x38c8, 0x4b40, { 0x88, 0x77, 0x61, 0xc7, 0xb0, 0x6a, 0xac, 0x45 } } },
+ { L"EFI_CPU_TYPE_FRU_GUID", { 0xf064c91f, 0x188c, 0x4f56, { 0xb7, 0xfd, 0x30, 0xa9, 0xb8, 0x6a, 0x29, 0xf3 } } },
+ { L"EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID", { 0xfc1bcdb0, 0x7d31, 0x49aa, { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } } },
+ { L"EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID", { 0xfc1bcdb0, 0x7d31, 0x49aa, { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } } },
+ { L"EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID", { 0x9a44198e, 0xa4a2, 0x44e6, { 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f } } },
+ { L"EFI_DATA_HUB_PROTOCOL_GUID", { 0xae80d021, 0x618e, 0x11d4, { 0xbc, 0xd7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_DATA_HUB_STATUS_CODE_RECORD_GUID", { 0xd083e94c, 0x6560, 0x42e4, { 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a } } },
+ { L"EFI_DEBUG_AGENT_GUID", { 0x865a5a9b, 0xb85d, 0x474c, { 0x84, 0x55, 0x65, 0xd1, 0xbe, 0x84, 0x4b, 0xe2 } } },
+ { L"EFI_DEBUG_ASSERT_PROTOCOL_GUID", { 0xbe499c92, 0x7d4b, 0x11d4, { 0xbc, 0xee, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_DEBUG_IMAGE_INFO_TABLE_GUID", { 0x49152e77, 0x1ada, 0x4764, { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } } },
+ { L"EFI_DEBUG_MASK_PPI_GUID", { 0x3bd930fd, 0xf823, 0x4948, { 0x86, 0x91, 0x98, 0xe6, 0xfe, 0x36, 0xac, 0xe2 } } },
+ { L"EFI_DEBUG_MASK_PROTOCOL_GUID", { 0x4c8a2451, 0xc207, 0x405b, { 0x96, 0x94, 0x99, 0xea, 0x13, 0x25, 0x13, 0x41 } } },
+ { L"EFI_DEBUGPORT_PROTOCOL_GUID", { 0xeba4e8d2, 0x3858, 0x41ec, { 0xa2, 0x81, 0x26, 0x47, 0xba, 0x96, 0x60, 0xd0 } } },
+ { L"EFI_DEBUG_SERIAL_IO_PROTOCOL_GUID", { 0xe683dc4f, 0x09ed, 0x4f22, { 0x86, 0x6b, 0x8e, 0x40, 0x46, 0x94, 0x7c, 0x6c } } },
+ { L"EFI_DEBUG_SUPPORT_PERIODIC_CALLBACK_PROTOCOL_GUID", { 0x9546e07c, 0x2cbb, 0x4c88, { 0x98, 0x6c, 0xcd, 0x34, 0x10, 0x86, 0xf0, 0x44 } } },
+ { L"EFI_DEBUG_SUPPORT_PROTOCOL_GUID", { 0x2755590c, 0x6f3c, 0x42fa, { 0x9e, 0xa4, 0xa3, 0xba, 0x54, 0x3c, 0xda, 0x25 } } },
+ { L"EFI_DECOMPRESS_PROTOCOL_GUID", { 0xd8117cfe, 0x94a6, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_DEFAULT_BMP_LOGO_GUID", { 0x7bb28b99, 0x61bb, 0x11d5, { 0x9a, 0x5d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_DEFERRED_IMAGE_LOAD_PROTOCOL_GUID", { 0x15853d7c, 0x3ddf, 0x43e0, { 0xa1, 0xcb, 0xeb, 0xf8, 0x5b, 0x8f, 0x87, 0x2c } } },
+ { L"EFI_DEVICE_IO_PROTOCOL_GUID", { 0xaf6ac311, 0x84c3, 0x11d2, { 0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID", { 0x05c99a21, 0xc70f, 0x4ad2, { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } } },
+ { L"EFI_DEVICE_PATH_PROTOCOL_GUID", { 0x09576e91, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID", { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } } },
+ { L"EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID", { 0x0379be4e, 0xd706, 0x437d, { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } } },
+ { L"EFI_DHCP4_PROTOCOL_GUID", { 0x8a219718, 0x4ef5, 0x4761, { 0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56 } } },
+ { L"EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID", { 0x9d9a39d8, 0xbd42, 0x4a73, { 0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80 } } },
+ { L"EFI_DHCP6_PROTOCOL_GUID", { 0x87c8bad7, 0x0595, 0x4053, { 0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b } } },
+ { L"EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID", { 0x9fb9a8a1, 0x2f4a, 0x43a6, { 0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5 } } },
+ { L"EFI_DISK_INFO_AHCI_INTERFACE_GUID", { 0x9e498932, 0x4abc, 0x45af, { 0xa3, 0x4d, 0x02, 0x47, 0x78, 0x7b, 0xe7, 0xc6 } } },
+ { L"EFI_DISK_INFO_IDE_INTERFACE_GUID", { 0x5e948fe3, 0x26d3, 0x42b5, { 0xaf, 0x17, 0x61, 0x02, 0x87, 0x18, 0x8d, 0xec } } },
+ { L"EFI_DISK_INFO_NVME_INTERFACE_GUID", { 0x3ab14680, 0x5d3f, 0x4a4d, { 0xbc, 0xdc, 0xcc, 0x38, 0x00, 0x18, 0xc7, 0xf7 } } },
+ { L"EFI_DISK_INFO_PROTOCOL_GUID", { 0xd432a67f, 0x14dc, 0x484b, { 0xb3, 0xbb, 0x3f, 0x02, 0x91, 0x84, 0x93, 0x27 } } },
+ { L"EFI_DISK_INFO_SCSI_INTERFACE_GUID", { 0x08f74baa, 0xea36, 0x41d9, { 0x95, 0x21, 0x21, 0xa7, 0x0f, 0x87, 0x80, 0xbc } } },
+ { L"EFI_DISK_INFO_USB_INTERFACE_GUID", { 0xcb871572, 0xc11a, 0x47b5, { 0xb4, 0x92, 0x67, 0x5e, 0xaf, 0xa7, 0x77, 0x27 } } },
+ { L"EFI_DISK_IO2_PROTOCOL_GUID", { 0x151c8eae, 0x7f2c, 0x472c, { 0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88 } } },
+ { L"EFI_DISK_IO_PROTOCOL_GUID", { 0xce345171, 0xba0b, 0x11d2, { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_DMI_FORMAT_FRU_GUID", { 0x67ef7a73, 0x2594, 0x4a5e, { 0x93, 0x0a, 0xe1, 0x66, 0xfa, 0xbc, 0xd2, 0xc8 } } },
+ { L"EFI_DPC_PROTOCOL_GUID", { 0x480f8ae9, 0x0c46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x06 } } },
+ { L"EFI_DRIVER_BINDING_PROTOCOL_GUID", { 0x18a031ab, 0xb443, 0x4d1a, { 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71 } } },
+ { L"EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID", { 0xbfd7dc1d, 0x24f1, 0x40d9, { 0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe } } },
+ { L"EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID", { 0x107a772b, 0xd5e1, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID", { 0x4d330321, 0x025f, 0x4aac, { 0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63 } } },
+ { L"EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID", { 0x0784924f, 0xe296, 0x11d4, { 0x9a, 0x49, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID", { 0x4d330321, 0x025f, 0x4aac, { 0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63 } } },
+ { L"EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID", { 0xb1ee129e, 0xda36, 0x4181, { 0x91, 0xf8, 0x04, 0xa4, 0x92, 0x37, 0x66, 0xa7 } } },
+ { L"EFI_DRIVER_HEALTH_PROTOCOL_GUID", { 0x2a534210, 0x9280, 0x41d8, { 0xae, 0x79, 0xca, 0xda, 0x01, 0xa2, 0xb1, 0x27 } } },
+ { L"EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL_GUID", { 0x5c198761, 0x16a8, 0x4e69, { 0x97, 0x2c, 0x89, 0xd6, 0x79, 0x54, 0xf8, 0x1d } } },
+ { L"EFI_DXE_CMOS_ACCESS_GUID", { 0x9851740c, 0x22e0, 0x440d, { 0x90, 0x90, 0xef, 0x2d, 0x71, 0xc2, 0x51, 0xc9 } } },
+ { L"EFI_DXE_IPL_PPI_GUID", { 0x0ae8ce5d, 0xe448, 0x4437, { 0xa8, 0xd7, 0xeb, 0xf5, 0xf1, 0x94, 0xf7, 0x31 } } },
+ { L"EFI_DXE_SERVICES_TABLE_GUID", { 0x05ad34ba, 0x6f02, 0x4214, { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } } },
+ { L"EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID", { 0x60ff8964, 0xe906, 0x41d0, { 0xaf, 0xed, 0xf2, 0x41, 0xe9, 0x74, 0xe0, 0x8e } } },
+ { L"EFI_EAP_MANAGEMENT_PROTOCOL_GUID", { 0xbb62e663, 0x625d, 0x40b2, { 0xa0, 0x88, 0xbb, 0xe8, 0x36, 0x23, 0xa2, 0x45 } } },
+ { L"EFI_EAP_PROTOCOL_GUID", { 0x5d9f96db, 0xe731, 0x4caa, { 0xa0, 0x0d, 0x72, 0xe1, 0x87, 0xcd, 0x77, 0x62 } } },
+ { L"EFI_EBC_INTERPRETER_PROTOCOL_GUID", { 0x13ac6dd1, 0x73d0, 0x11d4, { 0xb0, 0x6b, 0x00, 0xaa, 0x00, 0xbd, 0x6d, 0xe7 } } },
+ { L"EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL_GUID", { 0x2a72d11e, 0x7376, 0x40f6, { 0x9c, 0x68, 0x23, 0xfa, 0x2f, 0xe3, 0x63, 0xf1 } } },
+ { L"EFI_EBC_VM_TEST_PROTOCOL_GUID", { 0xaaeaccfd, 0xf27b, 0x4c17, { 0xb6, 0x10, 0x75, 0xca, 0x1f, 0x2d, 0xfb, 0x52 } } },
+ { L"EFI_EDID_ACTIVE_PROTOCOL_GUID", { 0xbd8c1056, 0x9f36, 0x44ec, { 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 } } },
+ { L"EFI_EDID_DISCOVERED_PROTOCOL_GUID", { 0x1c0c34f6, 0xd380, 0x41fa, { 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa } } },
+ { L"EFI_EDID_OVERRIDE_PROTOCOL_GUID", { 0x48ecb431, 0xfb72, 0x45c0, { 0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5 } } },
+ { L"EFI_EMUL6064KBDINPUT_PROTOCOL_GUID", { 0x62ceef5a, 0x1d7c, 0x4943, { 0x9b, 0x3a, 0x95, 0xe2, 0x49, 0x4c, 0x89, 0x90 } } },
+ { L"EFI_EMUL6064MSINPUT_PROTOCOL_GUID", { 0x7578b307, 0xb25b, 0x44f9, { 0x89, 0x2e, 0x20, 0x9b, 0x0e, 0x39, 0x93, 0xc6 } } },
+ { L"EFI_EMUL6064TRAP_PROTOCOL_GUID", { 0x6ea0f71c, 0x614a, 0x437e, { 0x8f, 0x49, 0x24, 0x3a, 0xd4, 0xe8, 0x32, 0x68 } } },
+ { L"EFI_EMU_PHYSICAL_DISK_GUID", { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } } },
+ { L"EFI_EMU_SYSTEM_CONFIG_GUID", { 0x9c4fb516, 0x3a1e, 0xd847, { 0xa1, 0xa1, 0x70, 0x58, 0xb6, 0x98, 0x67, 0x32 } } },
+ { L"EFI_EMU_VIRTUAL_DISK_GUID", { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } } },
+ { L"EFI_END_OF_DXE_EVENT_GROUP_GUID", { 0x02ce967a, 0xdd7e, 0x4ffc, { 0x9e, 0xe7, 0x81, 0x0c, 0xf0, 0x47, 0x08, 0x80 } } },
+ { L"EFI_ERROR_SECTION_DIRECTED_IO_DMAR_GUID", { 0x71761d37, 0x32b2, 0x45cd, { 0xa7, 0xd0, 0xb0, 0xfe, 0xdd, 0x93, 0xe8, 0xcf } } },
+ { L"EFI_ERROR_SECTION_DMAR_GENERIC_GUID", { 0x5b51fef7, 0xc79d, 0x4434, { 0x8f, 0x1b, 0xaa, 0x62, 0xde, 0x3e, 0x2c, 0x64 } } },
+ { L"EFI_ERROR_SECTION_FW_ERROR_RECORD_GUID", { 0x81212a96, 0x09ed, 0x4996, { 0x94, 0x71, 0x8d, 0x72, 0x9c, 0x8e, 0x69, 0xed } } },
+ { L"EFI_ERROR_SECTION_IOMMU_DMAR_GUID", { 0x036f84e1, 0x7f37, 0x428c, { 0xa7, 0x9e, 0x57, 0x5f, 0xdf, 0xaa, 0x84, 0xec } } },
+ { L"EFI_ERROR_SECTION_PCI_DEVICE_GUID", { 0xeb5e4685, 0xca66, 0x4769, { 0xb6, 0xa2, 0x26, 0x06, 0x8b, 0x00, 0x13, 0x26 } } },
+ { L"EFI_ERROR_SECTION_PCIE_GUID", { 0xd995e954, 0xbbc1, 0x430f, { 0xad, 0x91, 0xb4, 0x4d, 0xcb, 0x3c, 0x6f, 0x35 } } },
+ { L"EFI_ERROR_SECTION_PCI_PCIX_BUS_GUID", { 0xc5753963, 0x3b84, 0x4095, { 0xbf, 0x78, 0xed, 0xda, 0xd3, 0xf9, 0xc9, 0xdd } } },
+ { L"EFI_ERROR_SECTION_PLATFORM_MEMORY_GUID", { 0xa5bc1114, 0x6f64, 0x4ede, { 0xb8, 0x63, 0x3e, 0x83, 0xed, 0x7c, 0x83, 0xb1 } } },
+ { L"EFI_ERROR_SECTION_PROCESSOR_GENERIC_GUID", { 0x9876ccad, 0x47b4, 0x4bdb, { 0xb6, 0x5e, 0x16, 0xf1, 0x93, 0xc4, 0xf3, 0xdb } } },
+ { L"EFI_ERROR_SECTION_PROCESSOR_SPECIFIC_GUID", { 0xdc3ea0b0, 0xa144, 0x4797, { 0xb9, 0x5b, 0x53, 0xfa, 0x24, 0x2b, 0x6e, 0x1d } } },
+ { L"EFI_EVENT_GROUP_DXE_DISPATCH_GUID", { 0x7081e22f, 0xcac6, 0x4053, { 0x94, 0x68, 0x67, 0x57, 0x82, 0xcf, 0x88, 0xe5 } } },
+ { L"EFI_EVENT_LEGACY_BOOT_GUID", { 0x2a571201, 0x4966, 0x47f6, { 0x8b, 0x86, 0xf3, 0x1e, 0x41, 0xf3, 0x2f, 0x10 } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_BOOT_GUID", { 0x3d61a466, 0xab40, 0x409a, { 0xa6, 0x98, 0xf3, 0x62, 0xd4, 0x64, 0xb3, 0x8f } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_CMC_GUID", { 0x2dce8bb1, 0xbdd7, 0x450e, { 0xb9, 0xad, 0x9c, 0xf4, 0xeb, 0xd4, 0xf8, 0x90 } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_CPE_GUID", { 0x4e292f96, 0xd843, 0x4a55, { 0xa8, 0xc2, 0xd4, 0x81, 0xf2, 0x7e, 0xbe, 0xee } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_DMAR_GUID", { 0x667dd791, 0xc6b3, 0x4c27, { 0x8a, 0x6b, 0x0f, 0x8e, 0x72, 0x2d, 0xeb, 0x41 } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_INIT_GUID", { 0xcc5263e8, 0x9308, 0x454a, { 0x89, 0xd0, 0x34, 0x0b, 0xd3, 0x9b, 0xc9, 0x8e } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_MCE_GUID", { 0xe8f56ffe, 0x919c, 0x4cc5, { 0xba, 0x88, 0x65, 0xab, 0xe1, 0x49, 0x13, 0xbb } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_NMI_GUID", { 0x5bad89ff, 0xb7e6, 0x42c9, { 0x81, 0x4a, 0xcf, 0x24, 0x85, 0xd6, 0xe9, 0x8a } } },
+ { L"EFI_EVENT_NOTIFICATION_TYEP_PCIE_GUID", { 0xcf93c01f, 0x1a16, 0x4dfc, { 0xb8, 0xbc, 0x9c, 0x4d, 0xaf, 0x67, 0xc1, 0x04 } } },
+ { L"EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID", { 0x5aea42b5, 0x31e1, 0x4515, { 0xbc, 0x31, 0xb8, 0xd5, 0x25, 0x75, 0x65, 0xa6 } } },
+ { L"EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID", { 0xd9e9fa06, 0x0fe0, 0x41c3, { 0x96, 0xfb, 0x83, 0x42, 0x5a, 0x33, 0x94, 0xf8 } } },
+ { L"EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID", { 0x0edc9494, 0x2743, 0x4ba5, { 0x88, 0x18, 0x0a, 0xef, 0x52, 0x13, 0xf1, 0x88 } } },
+ { L"EFI_EXTENDED_SAL_ELOG_SERVICES_PROTOCOL_GUID", { 0xd5e4ee5f, 0x3e0a, 0x453c, { 0xa7, 0x25, 0xb6, 0x92, 0xbb, 0x06, 0x36, 0x5a } } },
+ { L"EFI_EXTENDED_SAL_FV_BLOCK_SERVICES_PROTOCOL_GUID", { 0xa2271df1, 0xbcbb, 0x4f1d, { 0x98, 0xa9, 0x06, 0xbc, 0x17, 0x2f, 0x07, 0x1a } } },
+ { L"EFI_EXTENDED_SAL_LOCK_SERVICES_PROTOCOL_GUID", { 0x76b75c23, 0xfe4f, 0x4e17, { 0xa2, 0xad, 0x1a, 0x65, 0x3d, 0xbb, 0x49, 0x4a } } },
+ { L"EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID", { 0xcb3fd86e, 0x38a3, 0x4c03, { 0x9a, 0x5c, 0x90, 0xcf, 0xa3, 0xa2, 0xab, 0x7a } } },
+ { L"EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID", { 0x2a591128, 0x6cc7, 0x42b1, { 0x8a, 0xf0, 0x58, 0x93, 0x3b, 0x68, 0x2d, 0xbb } } },
+ { L"EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID", { 0x697d81a2, 0xcf18, 0x4dc0, { 0x9e, 0x0d, 0x06, 0x11, 0x3b, 0x61, 0x8a, 0x3f } } },
+ { L"EFI_EXTENDED_SAL_MTC_SERVICES_PROTOCOL_GUID", { 0x899afd18, 0x75e8, 0x408b, { 0xa4, 0x1a, 0x6e, 0x2e, 0x7e, 0xcd, 0xf4, 0x54 } } },
+ { L"EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID", { 0xe1cd9d21, 0x0fc2, 0x438d, { 0x97, 0x03, 0x04, 0xe6, 0x6d, 0x96, 0x1e, 0x57 } } },
+ { L"EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID", { 0xa46b1a31, 0xad66, 0x4905, { 0x92, 0xf6, 0x2b, 0x46, 0x59, 0xdc, 0x30, 0x63 } } },
+ { L"EFI_EXTENDED_SAL_RESET_SERVICES_PROTOCOL_GUID", { 0x7d019990, 0x8ce1, 0x46f5, { 0xa7, 0x76, 0x3c, 0x51, 0x98, 0x67, 0x6a, 0xa0 } } },
+ { L"EFI_EXTENDED_SAL_RTC_SERVICES_PROTOCOL_GUID", { 0x7e97a470, 0xefdb, 0x4d02, { 0x8f, 0xce, 0x61, 0x90, 0xd2, 0x7b, 0xa2, 0x96 } } },
+ { L"EFI_EXTENDED_SAL_SENSOR_SERVICES_PROTOCOL_GUID", { 0x4a153b6e, 0x85a1, 0x4982, { 0x98, 0xf4, 0x6a, 0x8c, 0xfc, 0xa4, 0xab, 0xa1 } } },
+ { L"EFI_EXTENDED_SAL_SM_COM_LAYER_SERVICES_PROTOCOL_GUID", { 0x04356799, 0x81b7, 0x4e08, { 0xa3, 0x8d, 0xd9, 0x78, 0xfa, 0x47, 0xba, 0x42 } } },
+ { L"EFI_EXTENDED_SAL_SST_GUID", { 0x38802700, 0x868a, 0x4b4e, { 0x81, 0xd4, 0x4f, 0x1b, 0xdc, 0xcf, 0xb4, 0x6f } } },
+ { L"EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID", { 0x53a58d06, 0xac27, 0x4d8c, { 0xb5, 0xe9, 0xf0, 0x8a, 0x80, 0x65, 0x41, 0x70 } } },
+ { L"EFI_EXTENDED_SAL_STATUS_CODE_SERVICES_PROTOCOL_GUID", { 0x00dbd91d, 0x55e9, 0x420f, { 0x96, 0x39, 0x5e, 0x9f, 0x84, 0x37, 0xb4, 0x4f } } },
+ { L"EFI_EXTENDED_SAL_VARIABLE_SERVICES_PROTOCOL_GUID", { 0x4ecb6c53, 0xc641, 0x4370, { 0x8c, 0xb2, 0x3b, 0x0e, 0x49, 0x6e, 0x83, 0x78 } } },
+ { L"EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID", { 0xc1a74056, 0x260e, 0x4871, { 0xa0, 0x31, 0xe6, 0x45, 0xa6, 0x5b, 0x6e, 0x11 } } },
+ { L"EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID", { 0x143b7632, 0xb81b, 0x4cb7, { 0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe } } },
+ { L"EFI_FAULT_TOLERANT_WRITE_PROTOCOL_GUID", { 0x3ebd9e82, 0x2c78, 0x4de6, { 0x97, 0x86, 0x8d, 0x4b, 0xfc, 0xb7, 0xc8, 0x81 } } },
+ { L"EFI_FFS_VOLUME_TOP_FILE_GUID", { 0x1ba0062e, 0xc779, 0x4582, { 0x85, 0x66, 0x33, 0x6a, 0xe8, 0xf7, 0x8f, 0x09 } } },
+ { L"EFI_FILE_SYSTEM_INFO_ID_GUID", { 0x09576e93, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID_GUID", { 0xdb47d7d3, 0xfe81, 0x11d3, { 0x9a, 0x35, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_FIND_FV_PPI_GUID", { 0x36164812, 0xa023, 0x44e5, { 0xbd, 0x85, 0x05, 0xbf, 0x3c, 0x77, 0x00, 0xaa } } },
+ { L"EFI_FIRMWARE_CONTENTS_SIGNED_GUID", { 0x0f9d89e8, 0x9259, 0x4f76, { 0xa5, 0xaf, 0x0c, 0x89, 0xe3, 0x40, 0x23, 0xdf } } },
+ { L"EFI_FIRMWARE_FILE_SYSTEM2_GUID", { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } } },
+ { L"EFI_FIRMWARE_FILE_SYSTEM3_GUID", { 0x5473c07a, 0x3dcb, 0x4dca, { 0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a } } },
+ { L"EFI_FIRMWARE_FILE_SYSTEM_GUID", { 0x7a9354d9, 0x0468, 0x444a, { 0x81, 0xce, 0x0b, 0xf6, 0x17, 0xd8, 0x90, 0xdf } } },
+ { L"EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID", { 0x6dcbd5ed, 0xe82d, 0x4c44, { 0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a } } },
+ { L"EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID", { 0x86c77a67, 0x0b97, 0x4633, { 0xa1, 0x87, 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7 } } },
+ { L"EFI_FIRMWARE_PERFORMANCE_GUID", { 0xc095791a, 0x3001, 0x47b2, { 0x80, 0xc9, 0xea, 0xc7, 0x31, 0x9f, 0x2f, 0xa4 } } },
+ { L"EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID", { 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x05, 0xb9, 0x74, 0xb1, 0x08, 0x61, 0x9a } } },
+ { L"EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL_GUID", { 0x8f644fa9, 0xe850, 0x4db1, { 0x9c, 0xe2, 0x0b, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } },
+ { L"EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID", { 0x8f644fa9, 0xe850, 0x4db1, { 0x9c, 0xe2, 0x0b, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } },
+ { L"EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID", { 0x7aa35a69, 0x506c, 0x444f, { 0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8 } } },
+ { L"EFI_FIRMWARE_VOLUME_PROTOCOL_GUID", { 0x389f751f, 0x1838, 0x4388, { 0x83, 0x90, 0xcd, 0x81, 0x54, 0xbd, 0x27, 0xf8 } } },
+ { L"EFI_FLASH_MAP_HOB_GUID", { 0xb091e7d2, 0x05a0, 0x4198, { 0x94, 0xf0, 0x74, 0xb7, 0xb8, 0xc5, 0x54, 0x59 } } },
+ { L"EFI_FORM_BROWSER2_PROTOCOL_GUID", { 0xb9d4c360, 0xbcfb, 0x4f9b, { 0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58 } } },
+ { L"EFI_FORM_BROWSER_COMPATIBILITY_PROTOCOL_GUID", { 0x0fb7c852, 0xadca, 0x4853, { 0x8d, 0x0f, 0xfb, 0xa7, 0x1b, 0x1c, 0xe1, 0x1a } } },
+ { L"EFI_FORM_BROWSER_PROTOCOL_GUID", { 0x0fb7c852, 0xadca, 0x4853, { 0x8d, 0x0f, 0xfb, 0xa7, 0x1b, 0x1c, 0xe1, 0x1a } } },
+ { L"EFI_FORM_BROWSER_PROTOCOL_GUID", { 0xe5a1333e, 0xe1b4, 0x4d55, { 0xce, 0xeb, 0x35, 0xc3, 0xef, 0x13, 0x34, 0x43 } } },
+ { L"EFI_FORM_CALLBACK_PROTOCOL_GUID", { 0xf3e4543d, 0xcf35, 0x6cef, { 0x35, 0xc4, 0x4f, 0xe6, 0x34, 0x4d, 0xfc, 0x54 } } },
+ { L"EFI_FRAMEWORK_DEVICE_PATH_GUID", { 0xb7084e63, 0x46b7, 0x4d1a, { 0x86, 0x77, 0xe3, 0x0b, 0x53, 0xdb, 0xf0, 0x50 } } },
+ { L"EFI_FTP4_PROTOCOL_GUID", { 0xeb338826, 0x681b, 0x4295, { 0xb3, 0x56, 0x2b, 0x36, 0x4c, 0x75, 0x7b, 0x09 } } },
+ { L"EFI_FTP4_SERVICE_BINDING_PROTOCOL_GUID", { 0x0faaecb1, 0x226e, 0x4782, { 0xaa, 0xce, 0x7d, 0xb9, 0xbc, 0xbf, 0x4d, 0xaf } } },
+ { L"EFI_FTW_LITE_PROTOCOL_GUID", { 0x3f557189, 0x8dae, 0x45ae, { 0xa0, 0xb3, 0x2b, 0x99, 0xca, 0x7a, 0xa7, 0xa0 } } },
+ { L"EFI_FVB_EXTENSION_PROTOCOL_GUID", { 0x53a4c71b, 0xb581, 0x4170, { 0x91, 0xb3, 0x8d, 0xb8, 0x7a, 0x4b, 0x5c, 0x46 } } },
+ { L"EFI_GENERIC_MEMORY_TEST_PROTOCOL_GUID", { 0x309de7f1, 0x7f5e, 0x4ace, { 0xb4, 0x9c, 0x53, 0x1b, 0xe5, 0xaa, 0x95, 0xef } } },
+ { L"EFI_GENERIC_VARIABLE_GUID", { 0x59d1c24f, 0x50f1, 0x401a, { 0xb1, 0x01, 0xf3, 0x3e, 0x0d, 0xae, 0xd4, 0x43 } } },
+ { L"EFI_GLOBAL_NVS_AREA_PROTOCOL_GUID", { 0x074e1e48, 0x8132, 0x47a1, { 0x8c, 0x2c, 0x3f, 0x14, 0xad, 0x9a, 0x66, 0xdc } } },
+ { L"EFI_GLOBAL_VARIABLE_GUID", { 0x8be4df61, 0x93ca, 0x11d2, { 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } } },
+ { L"EFI_GPIO_PROTOCOL_GUID", { 0xb5d09084, 0x80ad, 0x4759, { 0xb5, 0x1c, 0x27, 0x54, 0x8a, 0xfb, 0x8b, 0x8d } } },
+ { L"EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID", { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } } },
+ { L"EFI_GUID", { 0x1e753e16, 0xdcef, 0x47d0, { 0x9a, 0x38, 0x7a, 0xde, 0xcd, 0xb9, 0x83, 0xed } } },
+ { L"EFI_GUID", { 0x8983fd2d, 0x113c, 0x4e2b, { 0x8f, 0x47, 0x0a, 0xbf, 0xeb, 0x20, 0xa4, 0x1a } } },
+ { L"EFI_GUID", { 0x8ff925f1, 0x8624, 0x4d38, { 0x9e, 0xd2, 0xf8, 0xf5, 0xaa, 0x94, 0xf8, 0x4a } } },
+ { L"EFI_GUID", { 0xa6a72875, 0x2962, 0x4c18, { 0x9f, 0x46, 0x8d, 0xa6, 0x44, 0xcc, 0xfe, 0x00 } } },
+ { L"EFI_GUID", { 0xbb2f3c9d, 0xc7a1, 0x4283, { 0x8a, 0xe2, 0x4f, 0x43, 0x62, 0x99, 0x0e, 0x2e } } },
+ { L"EFI_GUID", { 0xc1bdd34e, 0x9ec0, 0x48aa, { 0x80, 0x6a, 0x6c, 0x2e, 0xba, 0x0d, 0xc4, 0x45 } } },
+ { L"EFI_HARDWARE_ERROR_VARIABLE_GUID", { 0x414e6bdd, 0xe47b, 0x47cc, { 0xb2, 0x44, 0xbb, 0x61, 0x02, 0x0c, 0xf5, 0x16 } } },
+ { L"EFI_HASH_ALGORITHM_SHA1_GUID", { 0x2ae9d80f, 0x3fb2, 0x4095, { 0xb7, 0xb1, 0xe9, 0x31, 0x57, 0xb9, 0x46, 0xb6 } } },
+ { L"EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID", { 0x24c5dc2f, 0x53e2, 0x40ca, { 0x9e, 0xd6, 0xa5, 0xd9, 0xa4, 0x9f, 0x46, 0x3b } } },
+ { L"EFI_HASH_ALGORITHM_SHA224_GUID", { 0x8df01a06, 0x9bd5, 0x4bf7, { 0xb0, 0x21, 0xdb, 0x4f, 0xd9, 0xcc, 0xf4, 0x5b } } },
+ { L"EFI_HASH_ALGORITHM_SHA256_GUID", { 0x51aa59de, 0xfdf2, 0x4ea3, { 0xbc, 0x63, 0x87, 0x5f, 0xb7, 0x84, 0x2e, 0xe9 } } },
+ { L"EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID", { 0x8628752a, 0x6cb7, 0x4814, { 0x96, 0xfc, 0x24, 0xa8, 0x15, 0xac, 0x22, 0x26 } } },
+ { L"EFI_HASH_ALGORITHM_SHA384_GUID", { 0xefa96432, 0xde33, 0x4dd2, { 0xae, 0xe6, 0x32, 0x8c, 0x33, 0xdf, 0x77, 0x7a } } },
+ { L"EFI_HASH_ALGORITHM_SHA512_GUID", { 0xcaa4381e, 0x750c, 0x4770, { 0xb8, 0x70, 0x7a, 0x23, 0xb4, 0xe4, 0x21, 0x30 } } },
+ { L"EFI_HASH_ALGORTIHM_MD5_GUID", { 0x0af7c79c, 0x65b5, 0x4319, { 0xb0, 0xae, 0x44, 0xec, 0x48, 0x4e, 0x4a, 0xd7 } } },
+ { L"EFI_HASH_PROTOCOL_GUID", { 0xc5184932, 0xdba5, 0x46db, { 0xa5, 0xba, 0xcc, 0x0b, 0xda, 0x9c, 0x14, 0x35 } } },
+ { L"EFI_HASH_SERVICE_BINDING_PROTOCOL_GUID", { 0x42881c98, 0xa4f3, 0x44b0, { 0xa3, 0x9d, 0xdf, 0xa1, 0x86, 0x67, 0xd8, 0xcd } } },
+ { L"EFI_HII_COMPATIBILITY_PROTOCOL_GUID", { 0x5542cce1, 0xdf5c, 0x4d1b, { 0xab, 0xca, 0x36, 0x4f, 0x77, 0xd3, 0x99, 0xfb } } },
+ { L"EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID", { 0x330d4706, 0xf2a0, 0x4e4f, { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } } },
+ { L"EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID", { 0x587e72d7, 0xcc50, 0x4f79, { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } } },
+ { L"EFI_HII_DATABASE_PROTOCOL_GUID", { 0xef9fc172, 0xa1b2, 0x4693, { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } } },
+ { L"EFI_HII_DRIVER_HEALTH_FORMSET_GUID", { 0xf22fc20c, 0x8cf4, 0x45eb, { 0x8e, 0x06, 0xad, 0x4e, 0x50, 0xb9, 0x5d, 0xd3 } } },
+ { L"EFI_HII_EXT_PROTOCOL_GUID", { 0x2a57ae75, 0x8b7a, 0x4c64, { 0x86, 0x56, 0xdb, 0x51, 0xdd, 0xc3, 0x6f, 0x7b } } },
+ { L"EFI_HII_FONT_PROTOCOL_GUID", { 0xe9ca4775, 0x8657, 0x47fc, { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x08, 0x43, 0x24 } } },
+ { L"EFI_HII_FRONT_PAGE_CLASS_GUID", { 0x94d411b7, 0x7669, 0x45c3, { 0xba, 0x3b, 0xf3, 0xa5, 0x8a, 0x71, 0x56, 0x81 } } },
+ { L"EFI_HII_IMAGE_PROTOCOL_GUID", { 0x31a6406a, 0x6bdf, 0x4e46, { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x09, 0x20 } } },
+ { L"EFI_HII_NEW_PROTOCOL_GUID", { 0xea816d2c, 0xcee5, 0x4f02, { 0x99, 0xb5, 0xd3, 0x90, 0x5c, 0xbb, 0xd0, 0x77 } } },
+ { L"EFI_HII_OLD_PROTOCOL_GUID", { 0xcd361957, 0xafbe, 0x425e, { 0xa3, 0x58, 0x5f, 0x58, 0x89, 0xcf, 0xfe, 0x7b } } },
+ { L"EFI_HII_PACKAGE_LIST_PROTOCOL_GUID", { 0x6a1ee763, 0xd47a, 0x43b4, { 0xaa, 0xbe, 0xef, 0x1d, 0xe2, 0xab, 0x56, 0xfc } } },
+ { L"EFI_HII_PLATFORM_SETUP_FORMSET_GUID", { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x04, 0x0e } } },
+ { L"EFI_HII_PROTOCOL_GUID", { 0x5542cce1, 0xdf5c, 0x4d1b, { 0xab, 0xca, 0x36, 0x4f, 0x77, 0xd3, 0x99, 0xfb } } },
+ { L"EFI_HII_PROTOCOL_GUID", { 0xd7ad636e, 0xb997, 0x459b, { 0xbf, 0x3f, 0x88, 0x46, 0x89, 0x79, 0x80, 0xe1 } } },
+ { L"EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID", { 0x14982a4f, 0xb0ed, 0x45b8, { 0xa8, 0x11, 0x5a, 0x7a, 0x9b, 0xc2, 0x32, 0xdf } } },
+ { L"EFI_HII_STANDARD_FORM_GUID", { 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x01, 0x17, 0x42, 0x55, 0x62 } } },
+ { L"EFI_HII_STRING_PROTOCOL_GUID", { 0x0fd96974, 0x23aa, 0x4cdc, { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } } },
+ { L"EFI_HII_USER_CREDENTIAL_FORMSET_GUID", { 0x337f4407, 0x5aee, 0x4b83, { 0xb2, 0xa7, 0x4e, 0xad, 0xca, 0x30, 0x88, 0xcd } } },
+ { L"EFI_HOB_LIST_GUID", { 0x7739f24c, 0x93d7, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_HOB_MEMORY_ALLOC_BSP_STORE_GUID", { 0x564b33cd, 0xc92a, 0x4593, { 0x90, 0xbf, 0x24, 0x73, 0xe4, 0x3c, 0x63, 0x22 } } },
+ { L"EFI_HOB_MEMORY_ALLOC_MODULE_GUID", { 0xf8e21975, 0x0899, 0x4f58, { 0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a } } },
+ { L"EFI_HOB_MEMORY_ALLOC_STACK_GUID", { 0x4ed4bf27, 0x4092, 0x42e9, { 0x80, 0x7d, 0x52, 0x7b, 0x1d, 0x00, 0xc9, 0xbd } } },
+ { L"EFI_HOT_KEYS_PROTOCOL_GUID", { 0xf1e48287, 0x3fe1, 0x4535, { 0x89, 0xab, 0x48, 0xd6, 0xc3, 0xda, 0x27, 0x59 } } },
+ { L"EFI_HT_BIST_HOB_GUID", { 0xbe644001, 0xe7d4, 0x48b1, { 0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7 } } },
+ { L"EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL_GUID", { 0x55b71fb5, 0x17c6, 0x410e, { 0xb5, 0xbd, 0x5f, 0xa2, 0xe3, 0xd4, 0x46, 0x6b } } },
+ { L"EFI_I2C_ENUMERATE_PROTOCOL_GUID", { 0xda8cd7c4, 0x1c00, 0x49e2, { 0x80, 0x3e, 0x52, 0x14, 0xe7, 0x01, 0x89, 0x4c } } },
+ { L"EFI_I2C_HOST_PROTOCOL_GUID", { 0xa5aab9e3, 0xc727, 0x48cd, { 0x8b, 0xbf, 0x42, 0x72, 0x33, 0x85, 0x49, 0x48 } } },
+ { L"EFI_I2C_IO_PROTOCOL_GUID", { 0xb60a3e6b, 0x18c4, 0x46e5, { 0xa2, 0x9a, 0xc9, 0xa1, 0x06, 0x65, 0xa2, 0x8e } } },
+ { L"EFI_I2C_MASTER_PROTOCOL_GUID", { 0xcd72881f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 } } },
+ { L"EFI_IA32_X64_ERROR_TYPE_BUS_CHECK_GUID", { 0x1cf3f8b3, 0xc5b1, 0x49a2, { 0xaa, 0x59, 0x5e, 0xef, 0x92, 0xff, 0xa6, 0x3c } } },
+ { L"EFI_IA32_X64_ERROR_TYPE_CACHE_CHECK_GUID", { 0xa55701f5, 0xe3ef, 0x43de, { 0xac, 0x72, 0x24, 0x9b, 0x57, 0x3f, 0xad, 0x2c } } },
+ { L"EFI_IA32_X64_ERROR_TYPE_MS_CHECK_GUID", { 0x48ab7f57, 0xdc34, 0x4f6c, { 0xa7, 0xd3, 0xb0, 0xb5, 0xb0, 0xa7, 0x43, 0x14 } } },
+ { L"EFI_IA32_X64_ERROR_TYPE_TLB_CHECK_GUID", { 0xfc06b535, 0x5e1f, 0x4562, { 0x9f, 0x25, 0x0a, 0x3b, 0x9a, 0xdb, 0x63, 0xc3 } } },
+ { L"EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID", { 0xa1e37052, 0x80d9, 0x4e65, { 0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9 } } },
+ { L"EFI_IDER_CONTROLLER_DRIVER_PROTOCOL_GUID", { 0x956a2ed0, 0xa6cf, 0x409a, { 0xb8, 0xf5, 0x35, 0xf1, 0x4c, 0x3e, 0x3c, 0x02 } } },
+ { L"EFI_IFR_FRAMEWORK_GUID", { 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 } } },
+ { L"EFI_IFR_REFRESH_ID_OP_GUID", { 0xf5e655d9, 0x02a6, 0x46f2, { 0x9e, 0x76, 0xb8, 0xbe, 0x8e, 0x60, 0xab, 0x22 } } },
+ { L"EFI_IFR_TIANO_GUID", { 0x0f0b1735, 0x87a0, 0x4193, { 0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce } } },
+ { L"EFI_IMAGE_SECURITY_DATABASE_GUID", { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f } } },
+ { L"EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL_GUID", { 0xeb23f55a, 0x7863, 0x4ac2, { 0x8d, 0x3d, 0x95, 0x65, 0x35, 0xde, 0x03, 0x75 } } },
+ { L"EFI_INTEL_MFG_FORMAT_FRU_GUID", { 0x79e8c9c7, 0x1152, 0x4f00, { 0xb8, 0x31, 0x14, 0xf1, 0xc4, 0x04, 0x1a, 0xe0 } } },
+ { L"EFI_IOBASE_HOB_GUID", { 0xd4a28a3e, 0xdcf2, 0x43cf, { 0xa2, 0xb7, 0xf3, 0x57, 0x2a, 0x7c, 0xab, 0x09 } } },
+ { L"EFI_IP4_CONFIG_PROTOCOL_GUID", { 0x3b95aa31, 0x3793, 0x434b, { 0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e } } },
+ { L"EFI_IP4_PROTOCOL_GUID", { 0x41d94cd2, 0x35b6, 0x455a, { 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } } },
+ { L"EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID", { 0xc51711e7, 0xb4bf, 0x404a, { 0xbf, 0xb8, 0x0a, 0x04, 0x8e, 0xf1, 0xff, 0xe4 } } },
+ { L"EFI_IP6_CONFIG_PROTOCOL_GUID", { 0x937fe521, 0x95ae, 0x4d1a, { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } } },
+ { L"EFI_IP6_PROTOCOL_GUID", { 0x2c8759d5, 0x5c2d, 0x66ef, { 0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 } } },
+ { L"EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID", { 0xec835dd3, 0xfe0f, 0x617b, { 0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 } } },
+ { L"EFI_IP_PROTOCOL_GUID", { 0x89deef37, 0x31d8, 0x469c, { 0x95, 0xb6, 0x01, 0x69, 0xbc, 0x86, 0x6c, 0xfb } } },
+ { L"EFI_IPSEC2_PROTOCOL_GUID", { 0xa3979e64, 0xace8, 0x4ddc, { 0xbc, 0x07, 0x4d, 0x66, 0xb8, 0xfd, 0x09, 0x77 } } },
+ { L"EFI_IPSEC_CONFIG_PROTOCOL_GUID", { 0xce5e5929, 0xc7a3, 0x4602, { 0xad, 0x9e, 0xc9, 0xda, 0xf9, 0x4e, 0xbf, 0xcf } } },
+ { L"EFI_IPSEC_PROTOCOL_GUID", { 0xdfb386f7, 0xe100, 0x43ad, { 0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 } } },
+ { L"EFI_ISA_ACPI_PROTOCOL_GUID", { 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } } },
+ { L"EFI_ISA_IO_PROTOCOL_GUID", { 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_ISCSI_INITIATOR_NAME_PROTOCOL_GUID", { 0x59324945, 0xec44, 0x4c0d, { 0xb1, 0xcd, 0x9d, 0xb1, 0x39, 0xdf, 0x07, 0x0c } } },
+ { L"EFI_KMS_FORMAT_AESCBC_128_GUID", { 0xa0e8ee6a, 0x0e92, 0x44d4, { 0x86, 0x1b, 0x0e, 0xaa, 0x4a, 0xca, 0x44, 0xa2 } } },
+ { L"EFI_KMS_FORMAT_AESCBC_256_GUID", { 0xd7e69789, 0x1f68, 0x45e8, { 0x96, 0xef, 0x3b, 0x64, 0x07, 0xa5, 0xb2, 0xdc } } },
+ { L"EFI_KMS_FORMAT_AESXTS_128_GUID", { 0x4776e33f, 0xdb47, 0x479a, { 0xa2, 0x5f, 0xa1, 0xcd, 0x0a, 0xfa, 0xb3, 0x8b } } },
+ { L"EFI_KMS_FORMAT_AESXTS_256_GUID", { 0xdc7e8613, 0xc4bb, 0x4db0, { 0x84, 0x62, 0x13, 0x51, 0x13, 0x57, 0xab, 0xe2 } } },
+ { L"EFI_KMS_FORMAT_GENERIC_1024_GUID", { 0x43be0b44, 0x874b, 0x4ead, { 0xb0, 0x9c, 0x24, 0x1a, 0x4f, 0xbd, 0x7e, 0xb3 } } },
+ { L"EFI_KMS_FORMAT_GENERIC_128_GUID", { 0xec8a3d69, 0x6ddf, 0x4108, { 0x94, 0x76, 0x73, 0x37, 0xfc, 0x52, 0x21, 0x36 } } },
+ { L"EFI_KMS_FORMAT_GENERIC_160_GUID", { 0xa3b3e6f8, 0xefca, 0x4bc1, { 0x88, 0xfb, 0xcb, 0x87, 0x33, 0x9b, 0x25, 0x79 } } },
+ { L"EFI_KMS_FORMAT_GENERIC_2048_GUID", { 0x40093f23, 0x630c, 0x4626, { 0x9c, 0x48, 0x40, 0x37, 0x3b, 0x19, 0xcb, 0xbe } } },
+ { L"EFI_KMS_FORMAT_GENERIC_256_GUID", { 0x70f64793, 0xc323, 0x4261, { 0xac, 0x2c, 0xd8, 0x76, 0xf2, 0x7c, 0x53, 0x45 } } },
+ { L"EFI_KMS_FORMAT_GENERIC_3072_GUID", { 0xb9237513, 0x6c44, 0x4411, { 0xa9, 0x90, 0x21, 0xe5, 0x56, 0xe0, 0x5a, 0xde } } },
+ { L"EFI_KMS_FORMAT_GENERIC_512_GUID", { 0x978fe043, 0xd7af, 0x422e, { 0x8a, 0x92, 0x2b, 0x48, 0xe4, 0x63, 0xbd, 0xe6 } } },
+ { L"EFI_KMS_FORMAT_MD2_128_GUID", { 0x78be11c4, 0xee44, 0x4a22, { 0x9f, 0x05, 0x03, 0x85, 0x2e, 0xc5, 0xc9, 0x78 } } },
+ { L"EFI_KMS_FORMAT_MD4_128_GUID", { 0xd1c17aa1, 0xcac5, 0x400f, { 0xbe, 0x17, 0xe2, 0xa2, 0xae, 0x06, 0x67, 0x7c } } },
+ { L"EFI_KMS_FORMAT_MD5_128_GUID", { 0xdcbc3662, 0x9cda, 0x4b52, { 0xa0, 0x4c, 0x82, 0xeb, 0x1d, 0x23, 0x48, 0xc7 } } },
+ { L"EFI_KMS_FORMAT_MD5SHA_128_GUID", { 0x1c178237, 0x6897, 0x459e, { 0x9d, 0x36, 0x67, 0xce, 0x8e, 0xf9, 0x4f, 0x76 } } },
+ { L"EFI_KMS_FORMAT_MDC2_128_GUID", { 0xf7ad60f8, 0xefa8, 0x44a3, { 0x91, 0x13, 0x23, 0x1f, 0x39, 0x9e, 0xb4, 0xc7 } } },
+ { L"EFI_KMS_FORMAT_MDC4_128_GUID", { 0x3fa4f847, 0xd8eb, 0x4df4, { 0xbd, 0x49, 0x10, 0x3a, 0x0a, 0x84, 0x7b, 0xbc } } },
+ { L"EFI_KMS_FORMAT_RSASHA1_1024_GUID", { 0x56417bed, 0x6bbe, 0x4882, { 0x86, 0xa0, 0x3a, 0xe8, 0xbb, 0x17, 0xf8, 0xf9 } } },
+ { L"EFI_KMS_FORMAT_RSASHA1_2048_GUID", { 0xf66447d4, 0x75a6, 0x463e, { 0xa8, 0x19, 0x07, 0x7f, 0x2d, 0xda, 0x05, 0xe9 } } },
+ { L"EFI_KMS_FORMAT_RSASHA256_2048_GUID", { 0xa477af13, 0x877d, 0x4060, { 0xba, 0xa1, 0x25, 0xd1, 0xbe, 0xa0, 0x8a, 0xd3 } } },
+ { L"EFI_KMS_FORMAT_RSASHA256_3072_GUID", { 0x4e1356c2, 0x0eed, 0x463f, { 0x81, 0x47, 0x99, 0x33, 0xab, 0xdb, 0xc7, 0xd5 } } },
+ { L"EFI_KMS_FORMAT_SHA1_160_GUID", { 0x453c5e5a, 0x482d, 0x43f0, { 0x87, 0xc9, 0x59, 0x41, 0xf3, 0xa3, 0x8a, 0xc2 } } },
+ { L"EFI_KMS_FORMAT_SHA256_256_GUID", { 0x6bb4f5cd, 0x8022, 0x448d, { 0xbc, 0x6d, 0x77, 0x1b, 0xae, 0x93, 0x5f, 0xc6 } } },
+ { L"EFI_KMS_FORMAT_SHA512_512_GUID", { 0x2f240e12, 0xe14d, 0x475c, { 0x83, 0xb0, 0xef, 0xff, 0x22, 0xd7, 0x7b, 0xe7 } } },
+ { L"EFI_KMS_PROTOCOL_GUID", { 0xec3a978d, 0x7c4e, 0x48fa, { 0x9a, 0xbe, 0x6a, 0xd9, 0x1c, 0xc8, 0xf8, 0x11 } } },
+ { L"EFI_LEGACY_8259_PROTOCOL_GUID", { 0x38321dba, 0x4fe0, 0x4e17, { 0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } } },
+ { L"EFI_LEGACY_BIOS_EXT_PROTOCOL_GUID", { 0x8e008510, 0x9bb1, 0x457d, { 0x9f, 0x70, 0x89, 0x7a, 0xba, 0x86, 0x5d, 0xb9 } } },
+ { L"EFI_LEGACY_BIOS_GUID", { 0x2e3044ac, 0x879f, 0x490f, { 0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 } } },
+ { L"EFI_LEGACY_BIOS_PLATFORM_PROTOCOL_GUID", { 0x783658a3, 0x4172, 0x4421, { 0xa2, 0x99, 0xe0, 0x09, 0x07, 0x9c, 0x0c, 0xb4 } } },
+ { L"EFI_LEGACY_BIOS_PROTOCOL_GUID", { 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } } },
+ { L"EFI_LEGACY_BIOS_THUNK_PROTOCOL_GUID", { 0x4c51a7ba, 0x7195, 0x442d, { 0x87, 0x92, 0xbe, 0xea, 0x6e, 0x2f, 0xf6, 0xec } } },
+ { L"EFI_LEGACY_DEV_ORDER_VARIABLE_GUID", { 0xa56074db, 0x65fe, 0x45f7, { 0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 } } },
+ { L"EFI_LEGACY_INTERRUPT_PROTOCOL_GUID", { 0x31ce593d, 0x108a, 0x485d, { 0xad, 0xb2, 0x78, 0xf2, 0x1f, 0x29, 0x66, 0xbe } } },
+ { L"EFI_LEGACY_REGION2_PROTOCOL_GUID", { 0x70101eaf, 0x0085, 0x440c, { 0xb3, 0x56, 0x8e, 0xe3, 0x6f, 0xef, 0x24, 0xf0 } } },
+ { L"EFI_LEGACY_REGION_PROTOCOL_GUID", { 0x0fc9013a, 0x0568, 0x4ba9, { 0x9b, 0x7e, 0xc9, 0xc3, 0x90, 0xa6, 0x60, 0x9b } } },
+ { L"EFI_LEGACY_SREDIR_PROTOCOL_GUID", { 0xa062cf1f, 0x8473, 0x4aa3, { 0x87, 0x93, 0x60, 0x0b, 0xc4, 0xff, 0xa9, 0xa9 } } },
+ { L"EFI_LIGHT_ISA_IO_PROTOCOL_GUID", { 0x7cc7ed80, 0x9a68, 0x4781, { 0x80, 0xe4, 0xda, 0x16, 0x99, 0x10, 0x5a, 0xfe } } },
+ { L"EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID", { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } } },
+ { L"EFI_LOADED_IMAGE_PROTOCOL_GUID", { 0x5b1b31a1, 0x9562, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_LOAD_FILE2_PROTOCOL_GUID", { 0x4006c0c1, 0xfcb3, 0x403e, { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } } },
+ { L"EFI_LOAD_FILE_PROTOCOL_GUID", { 0x56ec3091, 0x954c, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE_GUID", { 0x2ca88b53, 0xd296, 0x4080, { 0xa4, 0xa5, 0xca, 0xd9, 0xba, 0xe2, 0x4b, 0x09 } } },
+ { L"EFI_LOCK_BOX_PROTOCOL_GUID", { 0xbd445d79, 0xb7ad, 0x4f04, { 0x9a, 0xd8, 0x29, 0xbd, 0x20, 0x40, 0xeb, 0x3c } } },
+ { L"EFI_MANAGED_NETWORK_PROTOCOL_GUID", { 0x7ab33a91, 0xace5, 0x4326, { 0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16 } } },
+ { L"EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID", { 0xf36ff770, 0xa7e1, 0x42cf, { 0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c } } },
+ { L"EFI_MEASURED_FV_HOB_GUID", { 0xb2360b42, 0x7173, 0x420a, { 0x86, 0x96, 0x46, 0xca, 0x6b, 0xab, 0x10, 0x60 } } },
+ { L"EFI_ME_BIOS_EXTENSION_SETUP_GUID", { 0x1bad711c, 0xd451, 0x4241, { 0xb1, 0xf3, 0x85, 0x37, 0x81, 0x2e, 0x0c, 0x70 } } },
+ { L"EFI_ME_FW_SKU_VARIABLE_GUID", { 0xe1a21d94, 0x4a20, 0x4e0e, { 0xae, 0x09, 0xa9, 0xa2, 0x1f, 0x24, 0xbb, 0x9e } } },
+ { L"EFI_MEMORY_CONFIG_DATA_GUID", { 0x80dbd530, 0xb74c, 0x4f11, { 0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31 } } },
+ { L"EFI_MEMORY_PRODUCER_GUID", { 0x1d7add6e, 0xb2da, 0x4b0b, { 0xb2, 0x9f, 0x49, 0xcb, 0x42, 0xf4, 0x63, 0x56 } } },
+ { L"EFI_MEMORY_SUBCLASS_DRIVER_GUID", { 0x1767ceed, 0xdb82, 0x47cd, { 0xbf, 0x2b, 0x68, 0x45, 0x8a, 0x8c, 0xcf, 0xff } } },
+ { L"EFI_MEMORY_SUBCLASS_GUID", { 0x4e8f4ebb, 0x64b9, 0x4e05, { 0x9b, 0x18, 0x4c, 0xfe, 0x49, 0x23, 0x50, 0x97 } } },
+ { L"EFI_MEMORY_TYPE_FRU_GUID", { 0xd50234f4, 0x6f4b, 0x43e8, { 0xa0, 0x13, 0x3c, 0x1e, 0x33, 0xd9, 0xb9, 0xb1 } } },
+ { L"EFI_MEMORY_TYPE_INFORMATION_GUID", { 0x4c19049f, 0x4137, 0x4dd3, { 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } } },
+ { L"EFI_ME_RC_INFO_PROTOCOL_GUID", { 0x11fbfdfb, 0x10d2, 0x43e6, { 0xb5, 0xb1, 0xb4, 0x38, 0x6e, 0xdc, 0xcb, 0x9a } } },
+ { L"EFI_METRONOME_ARCH_PROTOCOL_GUID", { 0x26baccb2, 0x6f42, 0x11d4, { 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_MINI_SHELL_FILE_GUID", { 0x86ad232b, 0xd33a, 0x465c, { 0xbf, 0x5f, 0x41, 0x37, 0x0b, 0xa9, 0x2f, 0xe2 } } },
+ { L"EFI_MISC_PRODUCER_GUID", { 0x62512c92, 0x63c4, 0x4d80, { 0x82, 0xb1, 0xc1, 0xa4, 0xdc, 0x44, 0x80, 0xe5 } } },
+ { L"EFI_MISC_SUBCLASS_DRIVER_GUID", { 0xf50e702c, 0x8653, 0x4cde, { 0xbb, 0xce, 0x43, 0xb4, 0xd5, 0x5b, 0x34, 0xb8 } } },
+ { L"EFI_MISC_SUBCLASS_GUID", { 0x772484b2, 0x7482, 0x4b91, { 0x9f, 0x9a, 0xad, 0x43, 0xf8, 0x1c, 0x58, 0x81 } } },
+ { L"EFI_MMC_HOST_PROTOCOL_GUID", { 0x3e591c00, 0x9e4a, 0x11df, { 0x92, 0x44, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } } },
+ { L"EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID", { 0x1da97072, 0xbddc, 0x4b30, { 0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a } } },
+ { L"EFI_MONTONIC_COUNTER_ARCH_PROTOCOL_GUID", { 0x1da97072, 0xbddc, 0x4b30, { 0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a } } },
+ { L"EFI_MP_SERVICES_PROTOCOL_GUID", { 0x3fdda605, 0xa76e, 0x4f46, { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } } },
+ { L"EFI_MP_SERVICES_PROTOCOL_GUID", { 0xf33261e7, 0x23cb, 0x11d5, { 0xbd, 0x5c, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_MPS_TABLE_GUID", { 0xeb9d2d2f, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_MTFTP4_PROTOCOL_GUID", { 0x78247c57, 0x63db, 0x4708, { 0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b } } },
+ { L"EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID", { 0x2fe800be, 0x8f01, 0x4aa6, { 0x94, 0x6b, 0xd7, 0x13, 0x88, 0xe1, 0x83, 0x3f } } },
+ { L"EFI_MTFTP6_PROTOCOL_GUID", { 0xbf0a78ba, 0xec29, 0x49cf, { 0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51 } } },
+ { L"EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID", { 0xd9760ff3, 0x3cca, 0x4267, { 0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23 } } },
+ { L"EFI_NB_ERROR_LOG_DISPATCH_PROTOCOL_GUID", { 0xff2d54d4, 0x5c55, 0x4c06, { 0x85, 0x49, 0xc3, 0x62, 0x7c, 0xb8, 0xb9, 0x95 } } },
+ { L"EFI_NB_MRC_INFO_GUID", { 0xd7bd52b0, 0xb2dc, 0x4f08, { 0xb4, 0x67, 0xde, 0x50, 0xd7, 0x28, 0xf6, 0xbd } } },
+ { L"EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID", { 0x1aced566, 0x76ed, 0x4218, { 0xbc, 0x81, 0x76, 0x7f, 0x1f, 0x97, 0x7a, 0x89 } } },
+ { L"EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID", { 0xe18541cd, 0xf755, 0x4f73, { 0x92, 0x8d, 0x64, 0x3c, 0x8a, 0x79, 0xb2, 0x29 } } },
+ { L"EFI_NIC_IP4_CONFIG_NVDATA_GUID", { 0x09d5b53f, 0xf4b0, 0x4f59, { 0xa0, 0xb1, 0x7b, 0x57, 0xd3, 0x5c, 0x0e, 0x05 } } },
+ { L"EFI_NIC_IP4_CONFIG_PROTOCOL_GUID", { 0x0dca3d4d, 0x12da, 0x4728, { 0xbf, 0x7e, 0x86, 0xce, 0xb9, 0x28, 0xd0, 0x67 } } },
+ { L"EFI_NIC_IP4_CONFIG_VARIABLE_GUID", { 0xd8944553, 0xc4dd, 0x41f4, { 0x9b, 0x30, 0xe1, 0x39, 0x7c, 0xfb, 0x26, 0x7b } } },
+ { L"EFI_NONSMMEMUL6064TRAP_PROTOCOL_GUID", { 0x68b81e51, 0x2583, 0x4582, { 0x95, 0xdb, 0xc5, 0x72, 0x32, 0x36, 0xc4, 0xf1 } } },
+ { L"EFI_NT_LOAD_AS_DLL_PPI_GUID", { 0xccc53f6b, 0xa03a, 0x4ed8, { 0x83, 0x9a, 0x03, 0xd9, 0x9c, 0x02, 0xb4, 0xe3 } } },
+ { L"EFI_NULL_GUID", { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { L"EFI_OEM_BADGING_PROTOCOL_GUID", { 0x170e13c0, 0xbf1b, 0x4218, { 0x87, 0x1d, 0x2a, 0xbd, 0xc6, 0xf8, 0x87, 0xbc } } },
+ { L"EFI_PART_TYPE_EFI_SYSTEM_PART_GUID", { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } } },
+ { L"EFI_PART_TYPE_LEGACY_MBR_GUID", { 0x024dee41, 0x33e7, 0x11d3, { 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f } } },
+ { L"EFI_PART_TYPE_UNUSED_GUID", { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { L"EFI_PATH_FILE_NAME_GUID", { 0x7644c181, 0xfa6e, 0x46da, { 0x80, 0xcb, 0x04, 0xb9, 0x90, 0x40, 0x62, 0xe8 } } },
+ { L"EFI_PC_ANSI_GUID", { 0xe0c14753, 0xf9be, 0x11d2, { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PCCARD_CS_PROTOCOL_GUID", { 0xca54f443, 0x1ef2, 0x4dab, { 0x9e, 0x7e, 0x6d, 0xb7, 0xb7, 0x20, 0xb5, 0x87 } } },
+ { L"EFI_PCCARD_SS_PROTOCOL_GUID", { 0xc38e6d34, 0x5a7f, 0x4bf9, { 0xbe, 0x57, 0x94, 0xdd, 0x30, 0x38, 0x02, 0x76 } } },
+ { L"EFI_PCD_PROTOCOL_GUID", { 0x13a3f0f6, 0x264a, 0x3ef0, { 0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34 } } },
+ { L"EFI_PCH_INFO_PROTOCOL_GUID", { 0x984eb4e9, 0x5a95, 0x41de, { 0xaa, 0xd0, 0x53, 0x66, 0x8c, 0xa5, 0x13, 0xc0 } } },
+ { L"EFI_PCH_S3_IMAGE_GUID", { 0x271dd6f2, 0x54cb, 0x45e6, { 0x85, 0x85, 0x8c, 0x92, 0x3c, 0x1a, 0xc7, 0x06 } } },
+ { L"EFI_PCH_S3_SUPPORT_PROTOCOL_GUID", { 0xe287d20b, 0xd897, 0x4e1e, { 0xa5, 0xd9, 0x97, 0x77, 0x63, 0x93, 0x6a, 0x04 } } },
+ { L"EFI_PCI_ENUMERATION_COMPLETE_GUID", { 0x30cfe3e7, 0x3de1, 0x4586, { 0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93 } } },
+ { L"EFI_PCI_EXPRESS_BASE_ADDRESS_GUID", { 0x3677d529, 0x326f, 0x4603, { 0xa9, 0x26, 0xea, 0xac, 0xe0, 0x1d, 0xcb, 0xb0 } } },
+ { L"EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GUID", { 0xcf8034be, 0x6768, 0x4d8b, { 0xb7, 0x39, 0x7c, 0xce, 0x68, 0x3a, 0x9f, 0xbe } } },
+ { L"EFI_PCI_HOTPLUG_DEVICE_GUID", { 0x0b280816, 0x52e7, 0x4e51, { 0xaa, 0x57, 0x11, 0xbd, 0x41, 0xcb, 0xef, 0xc3 } } },
+ { L"EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID", { 0xaa0e8bc1, 0xdabc, 0x46b0, { 0xa8, 0x44, 0x37, 0xb8, 0x16, 0x9b, 0x2b, 0xea } } },
+ { L"EFI_PCI_HOTPLUG_REQUEST_PROTOCOL_GUID", { 0x19cb87ab, 0x2cb9, 0x4665, { 0x83, 0x60, 0xdd, 0xcf, 0x60, 0x54, 0xf7, 0x9d } } },
+ { L"EFI_PCI_IO_PROTOCOL_GUID", { 0x4cf5b200, 0x68b8, 0x4ca5, { 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a } } },
+ { L"EFI_PCI_OPTION_ROM_TABLE_GUID", { 0x7462660f, 0x1cbd, 0x48da, { 0xad, 0x11, 0x91, 0x71, 0x79, 0x13, 0x83, 0x1c } } },
+ { L"EFI_PCI_OVERRIDE_GUID", { 0xb5b35764, 0x460c, 0x4a06, { 0x99, 0xfc, 0x77, 0xa1, 0x7c, 0x1b, 0x5c, 0xeb } } },
+ { L"EFI_PCI_PLATFORM_PROTOCOL_GUID", { 0x07d75280, 0x27d4, 0x4d69, { 0x90, 0xd0, 0x56, 0x43, 0xe2, 0x38, 0xb3, 0x41 } } },
+ { L"EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID", { 0x2f707ebb, 0x4a1a, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PCMCIA_REQUEST_PROTOCOL_GUID", { 0xf238f47c, 0x1de9, 0x4e8b, { 0x81, 0xb9, 0xcc, 0x92, 0x4e, 0x6b, 0x5b, 0xe5 } } },
+ { L"EFI_PEI_AMI_KEYCODE_PPI_GUID", { 0x20b0f1c2, 0xb0d8, 0x4c5d, { 0xaa, 0xd9, 0xf4, 0x45, 0x80, 0xdf, 0xdf, 0x8b } } },
+ { L"EFI_PEI_APRIORI_FILE_NAME_GUID", { 0x1b45cc0a, 0x156a, 0x428a, { 0xaf, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6 } } },
+ { L"EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID", { 0xabd42895, 0x78cf, 0x4872, { 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xff } } },
+ { L"EFI_PEI_CAPSULE_PPI_GUID", { 0x066785b1, 0xedb8, 0x46dc, { 0x84, 0x2f, 0x57, 0x44, 0x04, 0xb8, 0x69, 0x2f } } },
+ { L"EFI_PEI_CMOS_ACCESS_GUID", { 0xccbf2786, 0xcd6c, 0x4308, { 0xbd, 0xfa, 0x62, 0x58, 0x70, 0xce, 0xbf, 0x81 } } },
+ { L"EFI_PEI_CONSPLIT_AMI_KEYCODE_PPI_GUID", { 0x73ddb5e1, 0x5fb4, 0x4751, { 0xaf, 0x1e, 0x83, 0xcf, 0x75, 0xbe, 0xcb, 0xb6 } } },
+ { L"EFI_PEI_CORE_PRIVATE_GUID", { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 } } },
+ { L"EFI_PEI_CPU_IO_PPI_INSTALLED_GUID", { 0xe6af1f7b, 0xfc3f, 0x46da, { 0xa8, 0x28, 0xa3, 0xb4, 0x57, 0xa4, 0x42, 0x82 } } },
+ { L"EFI_PEI_DECOMPRESS_PPI_GUID", { 0x1a36e4e7, 0xfab6, 0x476a, { 0x8e, 0x75, 0x69, 0x5a, 0x05, 0x76, 0xfd, 0xd7 } } },
+ { L"EFI_PEI_DEVICE_RECOVERY_MODULE_PPI_GUID", { 0x0de2ce25, 0x446a, 0x45a7, { 0xbf, 0xc9, 0x37, 0xda, 0x26, 0x34, 0x4b, 0x37 } } },
+ { L"EFI_PEI_END_OF_PEI_PHASE_PPI_GUID", { 0x605ea650, 0xc65c, 0x42e1, { 0xba, 0x80, 0x91, 0xa5, 0x2a, 0xb6, 0x18, 0xc6 } } },
+ { L"EFI_PEI_FIND_FV_PPI_GUID", { 0x36164812, 0xa023, 0x44e5, { 0xbd, 0x85, 0x05, 0xbf, 0x3c, 0x77, 0x00, 0xaa } } },
+ { L"EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI_GUID", { 0xea7ca24b, 0xded5, 0x4dad, { 0xa3, 0x89, 0xbf, 0x82, 0x7e, 0x8f, 0x9b, 0x38 } } },
+ { L"EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI_GUID", { 0x6e056ff9, 0xc695, 0x4364, { 0x9e, 0x2c, 0x61, 0x26, 0xf5, 0xce, 0xea, 0xae } } },
+ { L"EFI_PEI_FIRMWARE_VOLUME_INFO_PPI_GUID", { 0x49edb1c1, 0xbf21, 0x4761, { 0xbb, 0x12, 0xeb, 0x00, 0x31, 0xaa, 0xbb, 0x39 } } },
+ { L"EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID", { 0xd8117cfc, 0x94a6, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PEI_FV_FILE_LOADER_GUID", { 0x7e1f0d85, 0x04ff, 0x4bb2, { 0x86, 0x6a, 0x31, 0xa2, 0x99, 0x6a, 0x48, 0xa8 } } },
+ { L"EFI_PEI_I2C_MASTER_PPI_GUID", { 0xb3bfab9b, 0x9f9c, 0x4e8b, { 0xad, 0x37, 0x7f, 0x8c, 0x51, 0xfc, 0x62, 0x80 } } },
+ { L"EFI_PEI_LOADED_IMAGE_PPI_GUID", { 0xa62a3fff, 0x97f0, 0x4332, { 0x8c, 0xfd, 0x1e, 0x34, 0x3d, 0x36, 0x31, 0xf2 } } },
+ { L"EFI_PEI_LOADED_IMAGE_PPI_GUID", { 0xc1fcd448, 0x6300, 0x4458, { 0xb8, 0x64, 0x28, 0xdf, 0x01, 0x53, 0x64, 0xbc } } },
+ { L"EFI_PEI_LOAD_FILE_GUID", { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } },
+ { L"EFI_PEI_LOAD_FILE_PPI_GUID", { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } },
+ { L"EFI_PEI_PCD_PPI_GUID", { 0x01f34d25, 0x4de2, 0x23ad, { 0x3f, 0xf3, 0x36, 0x35, 0x3f, 0xf3, 0x23, 0xf1 } } },
+ { L"EFI_PEI_PCI_CFG2_PPI_GUID", { 0x057a449a, 0x1fdc, 0x4c06, { 0xbf, 0xc9, 0xf5, 0x3f, 0x6a, 0x99, 0xbb, 0x92 } } },
+ { L"EFI_PEI_PCI_CFG2_PPI_GUID", { 0xe1f2eba0, 0xf7b9, 0x4a26, { 0x86, 0x20, 0x13, 0x12, 0x21, 0x64, 0x2a, 0x90 } } },
+ { L"EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID", { 0xe1f2eba0, 0xf7b9, 0x4a26, { 0x86, 0x20, 0x13, 0x12, 0x21, 0x64, 0x2a, 0x90 } } },
+ { L"EFI_PEI_PE_COFF_LOADER_GUID", { 0xd8117cff, 0x94a6, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PEI_PERFORMANCE_HOB_GUID", { 0x10f432de, 0xdeec, 0x4631, { 0x80, 0xcd, 0x47, 0xf6, 0x5d, 0x8f, 0x80, 0xbb } } },
+ { L"EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID", { 0xf894643d, 0xc449, 0x42d1, { 0x8e, 0xa8, 0x85, 0xbd, 0xd8, 0xc6, 0x5b, 0xde } } },
+ { L"EFI_PEI_PLATFORMPEI_EXECUTED_PPI_GUID", { 0x8c72c36e, 0xdacc, 0x4e81, { 0x8d, 0x60, 0xff, 0xa6, 0x1d, 0x88, 0xff, 0x54 } } },
+ { L"EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID", { 0x2ab86ef5, 0xecb5, 0x4134, { 0xb5, 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4 } } },
+ { L"EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID", { 0x3cdc90c6, 0x13fb, 0x4a75, { 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa } } },
+ { L"EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID", { 0x3cdc90c6, 0x13fb, 0x4a75, { 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa } } },
+ { L"EFI_PEI_RECOVERY_BLOCK_IO_PPI_GUID", { 0x695d8aa1, 0x42ee, 0x4c46, { 0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3 } } },
+ { L"EFI_PEI_RECOVERY_MODULE_PPI_GUID", { 0xfb6d9542, 0x612d, 0x4f45, { 0x87, 0x2f, 0x5c, 0xff, 0x52, 0xe9, 0x3d, 0xcf } } },
+ { L"EFI_PEI_REPORT_PROGRESS_CODE_PPI_GUID", { 0x229832d3, 0x7a30, 0x4b36, { 0xb8, 0x27, 0xf4, 0x0c, 0xb7, 0xd4, 0x54, 0x36 } } },
+ { L"EFI_PEI_RESET_PPI_GUID", { 0xef398d58, 0x9dfd, 0x4103, { 0xbf, 0x94, 0x78, 0xc6, 0xf4, 0xfe, 0x71, 0x2f } } },
+ { L"EFI_PEI_RSC_HANDLER_PPI_GUID", { 0x0065d394, 0x9951, 0x4144, { 0x82, 0xa3, 0x0a, 0xfc, 0x85, 0x79, 0xc2, 0x51 } } },
+ { L"EFI_PEI_S3_RESUME2_PPI_GUID", { 0x6d582dbc, 0xdb85, 0x4514, { 0x8f, 0xcc, 0x5a, 0xdf, 0x62, 0x27, 0xb1, 0x47 } } },
+ { L"EFI_PEI_S3_RESUME_PPI_GUID", { 0x4426ccb2, 0xe684, 0x4a8a, { 0xae, 0x40, 0x20, 0xd4, 0xb0, 0x25, 0xb7, 0x10 } } },
+ { L"EFI_PEI_SECTION_EXTRACTION_PPI_GUID", { 0x4f89e208, 0xe144, 0x4804, { 0x9e, 0xc8, 0x0f, 0x89, 0x4f, 0x7e, 0x36, 0xd7 } } },
+ { L"EFI_PEI_SECURITY2_PPI_GUID", { 0xdcd0be23, 0x9586, 0x40f4, { 0xb6, 0x43, 0x06, 0x52, 0x2c, 0xed, 0x4e, 0xde } } },
+ { L"EFI_PEI_SECURITY_PPI_GUID", { 0x1388066e, 0x3a57, 0x4efa, { 0x98, 0xf3, 0xc1, 0x2f, 0x3a, 0x95, 0x8a, 0x29 } } },
+ { L"EFI_PEI_SMBUS2_PPI_GUID", { 0x9ca93627, 0xb65b, 0x4324, { 0xa2, 0x02, 0xc0, 0xb4, 0x61, 0x76, 0x45, 0x43 } } },
+ { L"EFI_PEI_SMBUS_PPI_GUID", { 0xabd42895, 0x78cf, 0x4872, { 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xda } } },
+ { L"EFI_PEI_SMM_COMMUNICATION_PPI_GUID", { 0xae933e1c, 0xcc47, 0x4e38, { 0x8f, 0x0e, 0xe2, 0xf6, 0x1d, 0x26, 0x05, 0xdf } } },
+ { L"EFI_PEI_STALL_PPI_GUID", { 0x1f4c6f90, 0xb06b, 0x48d8, { 0xa2, 0x01, 0xba, 0xe5, 0xf1, 0xcd, 0x7d, 0x56 } } },
+ { L"EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI_GUID", { 0xdbe23aa9, 0xa345, 0x4b97, { 0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89 } } },
+ { L"EFI_PEI_TRANSFER_CONTROL_GUID", { 0xd8117d02, 0x94a6, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PERFORMANCE_PROTOCOL_GUID", { 0xffecffff, 0x923c, 0x14d2, { 0x9e, 0x3f, 0x22, 0xa0, 0xc9, 0x69, 0x56, 0x3b } } },
+ { L"EFI_PHYSICAL_PRESENCE_DATA_GUID", { 0x0f6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc } } },
+ { L"EFI_PI_MP_SERVICES_PROTOCOL_GUID", { 0x3fdda605, 0xa76e, 0x4f46, { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } } },
+ { L"EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID", { 0x6b30c738, 0xa391, 0x11d4, { 0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PLATFORM_GOP_POLICY_PROTOCOL_GUID", { 0xec2e931b, 0x3281, 0x48a5, { 0x81, 0x07, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d } } },
+ { L"EFI_PLATFORM_INFO_PROTOCOL_GUID", { 0xd9035175, 0x8ce2, 0x47de, { 0xa8, 0xb8, 0xcc, 0x98, 0xe5, 0xe2, 0xa8, 0x85 } } },
+ { L"EFI_PLATFORM_MEMTEST_PROTOCOL_GUID", { 0x0859ba18, 0x7dd7, 0x4ed7, { 0xa8, 0x8e, 0x10, 0x9c, 0x63, 0x91, 0x7b, 0xdd } } },
+ { L"EFI_PLATFORM_TO_DRIVER_CONFIGURATION_CLP_GUID", { 0x345ecc0e, 0x0cb6, 0x4b75, { 0xbb, 0x57, 0x1b, 0x12, 0x9c, 0x47, 0x33, 0x3e } } },
+ { L"EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL_GUID", { 0x642cd590, 0x8059, 0x4c0a, { 0xa9, 0x58, 0xc5, 0xec, 0x07, 0xd2, 0x3c, 0x4b } } },
+ { L"EFI_POWER_ON_HOB_GUID", { 0x0468a601, 0xc535, 0x46fd, { 0xa9, 0x5d, 0xbb, 0xab, 0x99, 0x1b, 0x17, 0x8c } } },
+ { L"EFI_PPM_GLOBAL_NVS_AREA_PROTOCOL_GUID", { 0x6c50cdcb, 0x7f46, 0x4dcc, { 0x8d, 0xdd, 0xd9, 0xf0, 0xa3, 0xc6, 0x11, 0x28 } } },
+ { L"EFI_PPM_INFO_PROTOCOL_GUID", { 0xd71db106, 0xe32d, 0x4225, { 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 } } },
+ { L"EFI_PRIMARY_CONSOLE_IN_DEVICE_GUID", { 0xe451dcbe, 0x96a1, 0x4729, { 0xa5, 0xcf, 0x6b, 0x9c, 0x2c, 0xff, 0x47, 0xfd } } },
+ { L"EFI_PRIMARY_CONSOLE_OUT_DEVICE_GUID", { 0x62bdf38a, 0xe3d5, 0x492c, { 0x95, 0x0c, 0x23, 0xa7, 0xf6, 0x6e, 0x67, 0x2e } } },
+ { L"EFI_PRIMARY_STANDARD_ERROR_DEVICE_GUID", { 0x5a68191b, 0x9b97, 0x4752, { 0x99, 0x46, 0xe3, 0x6a, 0x5d, 0xa9, 0x42, 0xb1 } } },
+ { L"EFI_PRINT2_PROTOCOL_GUID", { 0xf05976ef, 0x83f1, 0x4f3d, { 0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38 } } },
+ { L"EFI_PRINT_PROTOCOL_GUID", { 0xdf2d868e, 0x32fc, 0x4cf0, { 0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0 } } },
+ { L"EFI_PROCESSOR_PRODUCER_GUID", { 0x1bf06aea, 0x5bec, 0x4a8d, { 0x95, 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30 } } },
+ { L"EFI_PROCESSOR_SUBCLASS_GUID", { 0x26fdeb7e, 0xb8af, 0x4ccf, { 0xaa, 0x97, 0x02, 0x63, 0x3c, 0xe4, 0x8c, 0xa7 } } },
+ { L"EFI_PS2_POLICY_PROTOCOL_GUID", { 0x4df19259, 0xdc71, 0x4d46, { 0xbe, 0xf1, 0x35, 0x7b, 0xb5, 0x78, 0xc4, 0x18 } } },
+ { L"EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID", { 0x245dca21, 0xfb7b, 0x11d3, { 0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_PXE_BASE_CODE_PROTOCOL_GUID", { 0x03c4e603, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_PXE_DHCP4_CALLBACK_PROTOCOL_GUID", { 0xc1544c01, 0x92a4, 0x4198, { 0x8a, 0x84, 0x77, 0x85, 0x83, 0xc2, 0x36, 0x21 } } },
+ { L"EFI_PXE_DHCP4_PROTOCOL_GUID", { 0x03c4e624, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x29, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL_GUID", { 0x27cfac87, 0x46cc, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_RESET_ARCH_PROTOCOL_GUID", { 0x27cfac88, 0x46cc, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_RSC_HANDLER_PROTOCOL_GUID", { 0x86212936, 0x0e76, 0x41c8, { 0xa0, 0x3a, 0x2a, 0xf2, 0xfc, 0x1c, 0x39, 0xe2 } } },
+ { L"EFI_RUNTIME_ARCH_PROTOCOL_GUID", { 0xb7dfb4e1, 0x052f, 0x449f, { 0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33 } } },
+ { L"EFI_RUNTIME_CRYPT_PROTOCOL_GUID", { 0xe1475e0c, 0x1746, 0x4802, { 0x86, 0x2e, 0x01, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } } },
+ { L"EFI_S3_SAVE_STATE_PROTOCOL_GUID", { 0xe857caf6, 0xc046, 0x45dc, { 0xbe, 0x3f, 0xee, 0x07, 0x65, 0xfb, 0xa8, 0x87 } } },
+ { L"EFI_S3_SMM_SAVE_STATE_PROTOCOL_GUID", { 0x320afe62, 0xe593, 0x49cb, { 0xa9, 0xf1, 0xd4, 0xc2, 0xf4, 0xaf, 0x01, 0x4c } } },
+ { L"EFI_SA_INFO_PROTOCOL_GUID", { 0x493b5bac, 0xbb9e, 0x4bf5, { 0x83, 0x79, 0x20, 0xe2, 0xac, 0xa9, 0x85, 0x41 } } },
+ { L"EFI_SAL_MCA_INIT_PMI_PROTOCOL_GUID", { 0xb60dc6e8, 0x3b6f, 0x11d5, { 0xaf, 0x09, 0x00, 0xa0, 0xc9, 0x44, 0xa0, 0x5b } } },
+ { L"EFI_SAL_SYSTEM_TABLE_GUID", { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_SAS_DEVICE_PATH_GUID", { 0xd487ddb4, 0x008b, 0x11d9, { 0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } } },
+ { L"EFI_SB_PCIE_ERROR_LOG_DISPATCH_PROTOCOL_GUID", { 0xf281fc6e, 0xf4c4, 0x431c, { 0x96, 0x2b, 0x2f, 0x13, 0xae, 0x79, 0x84, 0xec } } },
+ { L"EFI_SCSI_IO_PROTOCOL_GUID", { 0x932f47e6, 0x2362, 0x4002, { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } } },
+ { L"EFI_SCSI_PASS_THRU_PROTOCOL_GUID", { 0xa59e8fcf, 0xbda0, 0x43bb, { 0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77 } } },
+ { L"EFI_SEC_PLATFORM_INFORMATION_GUID", { 0x6f8c2b35, 0xfef4, 0x448d, { 0x82, 0x56, 0xe1, 0x1b, 0x19, 0xd6, 0x10, 0x77 } } },
+ { L"EFI_SEC_SMI_FLASH_GUID", { 0x3bf4af16, 0xab7c, 0x4b43, { 0x89, 0x8d, 0xab, 0x26, 0xac, 0x5d, 0xdc, 0x6c } } },
+ { L"EFI_SECTION_EXTRACTION_PROTOCOL_GUID", { 0x448f5da4, 0x6dd7, 0x4fe1, { 0x93, 0x07, 0x69, 0x22, 0x41, 0x92, 0x21, 0x5d } } },
+ { L"EFI_SECURITY2_ARCH_PROTOCOL_GUID", { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } } },
+ { L"EFI_SECURITY_ARCH_PROTOCOL_GUID", { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } } },
+ { L"EFI_SECURITY_POLICY_PROTOCOL_GUID", { 0x78e4d245, 0xcd4d, 0x4a05, { 0xa2, 0xba, 0x47, 0x43, 0xe8, 0x6c, 0xfc, 0xab } } },
+ { L"EFI_SE_EXT_SIGNATURE_GUID", { 0xd2c18636, 0x40e5, 0x4eb5, { 0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87 } } },
+ { L"EFI_SERIAL_GPIO_PROTOCOL_GUID", { 0xf52c3858, 0x5ef8, 0x4d41, { 0x83, 0x4e, 0xc3, 0x9e, 0xef, 0x8a, 0x45, 0xa3 } } },
+ { L"EFI_SERIAL_IO_PROTOCOL_GUID", { 0xbb25cf6f, 0xf1d4, 0x11d2, { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } } },
+ { L"EFI_SHELL_FILE_GUID", { 0xc57ad6b7, 0x0515, 0x40a8, { 0x9d, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4e, 0x37 } } },
+ { L"EFI_SHELL_PARAMETERS_PROTOCOL_GUID", { 0x752f3136, 0x4e16, 0x4fdc, { 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca } } },
+ { L"EFI_SHELLPKG_TOKEN_SPACE_GUID", { 0x171e9188, 0x31d3, 0x40f5, { 0xb1, 0x0c, 0x53, 0x9b, 0x2d, 0xb9, 0x40, 0xcd } } },
+ { L"EFI_SHELL_PROTOCOL_GUID", { 0x6302d008, 0x7f9b, 0x4f30, { 0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e } } },
+ { L"EFI_SIMPLE_AUDIO_OUT_PROTOCOL_GUID", { 0xc723f288, 0x52f9, 0x4d80, { 0xb6, 0x33, 0xe1, 0x52, 0xf9, 0x30, 0xa0, 0xdc } } },
+ { L"EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID", { 0x964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_SIMPLE_NETWORK_PROTOCOL_GUID", { 0xa19832b9, 0xac25, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_SIMPLE_POINTER_PROTOCOL_GUID", { 0x31878c87, 0x0b75, 0x11d5, { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID", { 0x387477c1, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID", { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } },
+ { L"EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID", { 0x387477c1, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID", { 0x387477c2, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID", { 0x387477c2, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_SIO_PROTOCOL_GUID", { 0x215fdd18, 0xbd50, 0x4feb, { 0x89, 0x0b, 0x58, 0xca, 0x0b, 0x47, 0x39, 0xe9 } } },
+ { L"EFI_SMBIOS_BOARD_PROTOCOL_GUID", { 0x0903dd14, 0x2ca0, 0x458a, { 0xb5, 0xeb, 0x0c, 0x0c, 0xa3, 0x0d, 0x78, 0x5c } } },
+ { L"EFI_SMBIOS_DYNAMIC_DATA_GUID", { 0xe380280c, 0x4c35, 0x4aa3, { 0xb9, 0x61, 0x7a, 0xe4, 0x89, 0xa2, 0xb9, 0x26 } } },
+ { L"EFI_SMBIOS_NVRAM_DATA_GUID", { 0x4b3082a3, 0x80c6, 0x4d7e, { 0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1 } } },
+ { L"EFI_SMBIOS_PROTOCOL_GUID", { 0x03583ff6, 0xcb36, 0x4940, { 0x94, 0x7e, 0xb9, 0xb3, 0x9f, 0x4a, 0xfa, 0xf7 } } },
+ { L"EFI_SMBIOS_PROTOCOL_GUID", { 0x5e90a50d, 0x6955, 0x4a49, { 0x90, 0x32, 0xda, 0x38, 0x12, 0xf8, 0xe8, 0xe5 } } },
+ { L"EFI_SMBIOS_STATIC_DATA_GUID", { 0xdaf4bf89, 0xce71, 0x4917, { 0xb5, 0x22, 0xc8, 0x9d, 0x32, 0xfb, 0xc5, 0x9f } } },
+ { L"EFI_SMBIOS_TABLE_GUID", { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_SMBUS_ARP_MAP_GUID", { 0x707be83e, 0x0bf6, 0x40a5, { 0xbe, 0x64, 0x34, 0xc0, 0x3a, 0xa0, 0xb8, 0xe2 } } },
+ { L"EFI_SMBUS_HC_PROTOCOL_GUID", { 0xe49d33ed, 0x513d, 0x4634, { 0xb6, 0x98, 0x6f, 0x55, 0xaa, 0x75, 0x1c, 0x1b } } },
+ { L"EFI_SMM_ACCESS2_PROTOCOL_GUID", { 0xc2702b74, 0x800c, 0x4131, { 0x87, 0x46, 0x8f, 0xb5, 0xb8, 0x9c, 0xe4, 0xac } } },
+ { L"EFI_SMM_ACCESS_PROTOCOL_GUID", { 0x3792095a, 0xe309, 0x4c1e, { 0xaa, 0x01, 0x85, 0xf5, 0x65, 0x5a, 0x17, 0xf1 } } },
+ { L"EFI_SMM_BASE2_PROTOCOL_GUID", { 0xf4ccbfb7, 0xf6e0, 0x47fd, { 0x9d, 0xd4, 0x10, 0xa8, 0xf1, 0x50, 0xc1, 0x91 } } },
+ { L"EFI_SMM_BASE_HELPER_READY_PROTOCOL_GUID", { 0x910dca07, 0x1f94, 0x4ee7, { 0xaf, 0x2f, 0xff, 0x72, 0xf3, 0x15, 0x43, 0x53 } } },
+ { L"EFI_SMM_BASE_PROTOCOL_GUID", { 0x1390954d, 0xda95, 0x4227, { 0x93, 0x28, 0x72, 0x82, 0xc2, 0x17, 0xda, 0xa8 } } },
+ { L"EFI_SMM_BASE_THUNK_COMMUNICATION_GUID", { 0x6568a3d6, 0x015f, 0x4b4a, { 0x9c, 0x89, 0x1d, 0x14, 0x63, 0x14, 0x13, 0x0a } } },
+ { L"EFI_SMM_BIOS_WRITE_DISPATCH_PROTOCOL_GUID", { 0xe512dfe4, 0xbf44, 0x480d, { 0x9b, 0x7a, 0x77, 0x7b, 0x0b, 0xe3, 0x27, 0x75 } } },
+ { L"EFI_SMM_CMOS_ACCESS_GUID", { 0xe5d3026a, 0x1ca5, 0x40f0, { 0x8f, 0xb6, 0x4b, 0x1a, 0xfa, 0x3c, 0x6e, 0xaa } } },
+ { L"EFI_SMM_COMMUNICATION_PROTOCOL_GUID", { 0xc68ed8e2, 0x9dc6, 0x4cbd, { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 } } },
+ { L"EFI_SMM_CONFIGURATION_PROTOCOL_GUID", { 0x26eeb3de, 0xb689, 0x492e, { 0x80, 0xf0, 0xbe, 0x8b, 0xd7, 0xda, 0x4b, 0xa7 } } },
+ { L"EFI_SMM_CONTROL2_PROTOCOL_GUID", { 0x843dc720, 0xab1e, 0x42cb, { 0x93, 0x57, 0x8a, 0x00, 0x78, 0xf3, 0x56, 0x1b } } },
+ { L"EFI_SMM_CONTROL_PROTOCOL_GUID", { 0x8d12e231, 0xc667, 0x4fd1, { 0x98, 0xf2, 0x24, 0x49, 0xa7, 0xe7, 0xb2, 0xe5 } } },
+ { L"EFI_SMM_CPU_IO2_PROTOCOL_GUID", { 0x3242a9d8, 0xce70, 0x4aa0, { 0x95, 0x5d, 0x5e, 0x7b, 0x14, 0x0d, 0xe4, 0xd2 } } },
+ { L"EFI_SMM_CPU_IO_GUID", { 0x5f439a0b, 0x45d8, 0x4682, { 0xa4, 0xf4, 0xf0, 0x57, 0x6b, 0x51, 0x34, 0x41 } } },
+ { L"EFI_SMM_CPU_PROTOCOL_GUID", { 0xeb346b97, 0x975f, 0x4a9f, { 0x8b, 0x22, 0xf8, 0xe9, 0x2b, 0xb3, 0xd5, 0x69 } } },
+ { L"EFI_SMM_CPU_SAVE_STATE_PROTOCOL_GUID", { 0x21f302ad, 0x6e94, 0x471b, { 0x84, 0xbc, 0xb1, 0x48, 0x00, 0x40, 0x3a, 0x1d } } },
+ { L"EFI_SMM_END_OF_DXE_PROTOCOL_GUID", { 0x24e70042, 0xd5c5, 0x4260, { 0x8c, 0x39, 0x0a, 0xd3, 0xaa, 0x32, 0xe9, 0x3d } } },
+ { L"EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL_GUID", { 0x3868fc3b, 0x7e45, 0x43a7, { 0x90, 0x6c, 0x4b, 0xa4, 0x7d, 0xe1, 0x75, 0x4d } } },
+ { L"EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID", { 0xd326d041, 0xbd31, 0x4c01, { 0xb5, 0xa8, 0x62, 0x8b, 0xe8, 0x7f, 0x06, 0x53 } } },
+ { L"EFI_SMM_GPI_DISPATCH2_PROTOCOL_GUID", { 0x25566b03, 0xb577, 0x4cbf, { 0x95, 0x8c, 0xed, 0x66, 0x3e, 0xa2, 0x43, 0x80 } } },
+ { L"EFI_SMM_GPI_DISPATCH_PROTOCOL_GUID", { 0xe0744b81, 0x9513, 0x49cd, { 0x8c, 0xea, 0xe9, 0x24, 0x5e, 0x70, 0x39, 0xda } } },
+ { L"EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID", { 0x3920405b, 0xc897, 0x44da, { 0x88, 0xf3, 0x4c, 0x49, 0x8a, 0x6f, 0xf7, 0x36 } } },
+ { L"EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID", { 0xc50b323e, 0x9075, 0x4f2a, { 0xac, 0x8e, 0xd2, 0x59, 0x6a, 0x10, 0x85, 0xcc } } },
+ { L"EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL_GUID", { 0x58dc368d, 0x7bfa, 0x4e77, { 0xab, 0xbc, 0x0e, 0x29, 0x41, 0x8d, 0xf9, 0x30 } } },
+ { L"EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL_GUID", { 0xf1507845, 0x6494, 0x4377, { 0xa1, 0x15, 0x45, 0xdf, 0xe6, 0x5f, 0x5d, 0x71 } } },
+ { L"EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID", { 0x58dc368d, 0x7bfa, 0x4e77, { 0xab, 0xbc, 0x0e, 0x29, 0x41, 0x8d, 0xf9, 0x30 } } },
+ { L"EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID", { 0xbd18369d, 0xc242, 0x45ca, { 0x82, 0xad, 0x13, 0x8a, 0xc2, 0xe2, 0x9b, 0xab } } },
+ { L"EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID", { 0xdb7f536b, 0xede4, 0x4714, { 0xa5, 0xc8, 0xe3, 0x46, 0xeb, 0xaa, 0x20, 0x1d } } },
+ { L"EFI_SMM_LOCK_BOX_COMMUNICATION_GUID", { 0x2a3cfebd, 0x27e8, 0x4d0a, { 0x8b, 0x79, 0xd6, 0x88, 0xc2, 0xa3, 0xe1, 0xc0 } } },
+ { L"EFI_SMM_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID", { 0x8bc1714d, 0xffcb, 0x41c3, { 0x89, 0xdc, 0x6c, 0x74, 0xd0, 0x6d, 0x98, 0xea } } },
+ { L"EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL_GUID", { 0x4cec368e, 0x8e8e, 0x4d71, { 0x8b, 0xe1, 0x95, 0x8c, 0x45, 0xfc, 0x8a, 0x53 } } },
+ { L"EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL_GUID", { 0x9cca03fc, 0x4c9e, 0x4a19, { 0x9b, 0x06, 0xed, 0x7b, 0x47, 0x9b, 0xde, 0x55 } } },
+ { L"EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL_GUID", { 0x1b1183fa, 0x1823, 0x46a7, { 0x88, 0x72, 0x9c, 0x57, 0x87, 0x55, 0x40, 0x9d } } },
+ { L"EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL_GUID", { 0xb709efa0, 0x47a6, 0x4b41, { 0xb9, 0x31, 0x12, 0xec, 0xe7, 0xa8, 0xee, 0x56 } } },
+ { L"EFI_SMM_RC_TO_APTIO_BRIDGE_GUID", { 0xfcdf7788, 0x7878, 0x11ff, { 0xcc, 0x77, 0x88, 0xcc, 0xcc, 0x77, 0x88, 0xcc } } },
+ { L"EFI_SMM_READY_TO_LOCK_PROTOCOL_GUID", { 0x47b7fa8c, 0xf4bd, 0x4af6, { 0x82, 0x00, 0x33, 0x30, 0x86, 0xf0, 0xd2, 0xc8 } } },
+ { L"EFI_SMM_RSC_HANDLER_PROTOCOL_GUID", { 0x2ff29fa7, 0x5e80, 0x4ed9, { 0xb3, 0x80, 0x01, 0x7d, 0x3c, 0x55, 0x4f, 0xf4 } } },
+ { L"EFI_SMM_RUNTIME_PROTOCOL_GUID", { 0xa56897a1, 0xa77f, 0x4600, { 0x84, 0xdb, 0x22, 0xb0, 0xa8, 0x01, 0xfa, 0x9a } } },
+ { L"EFI_SMM_RUNTIME_SERVICES_TABLE_GUID", { 0x395c33fe, 0x287f, 0x413e, { 0xa0, 0x55, 0x80, 0x88, 0xc0, 0xe1, 0xd4, 0x3e } } },
+ { L"EFI_SMM_SMBUS_PROTOCOL_GUID", { 0x72e40094, 0x2ee1, 0x497a, { 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0x0c } } },
+ { L"EFI_SMM_SPI_PROTOCOL_GUID", { 0xaff3be49, 0x6d71, 0x421c, { 0x92, 0x77, 0xa0, 0xb1, 0x50, 0x8e, 0x84, 0x7d } } },
+ { L"EFI_SMM_SPI_PROTOCOL_GUID", { 0xd9072c35, 0xeb8f, 0x43ad, { 0xa2, 0x20, 0x34, 0xd4, 0x0e, 0x2a, 0x82, 0x85 } } },
+ { L"EFI_SMM_STANDBY_BUTTON_DISPATCH2_PROTOCOL_GUID", { 0x7300c4a1, 0x43f2, 0x4017, { 0xa5, 0x1b, 0xc8, 0x1a, 0x7f, 0x40, 0x58, 0x5b } } },
+ { L"EFI_SMM_STANDBY_BUTTON_DISPATCH_PROTOCOL_GUID", { 0x78965b98, 0xb0bf, 0x449e, { 0x8b, 0x22, 0xd2, 0x91, 0x4e, 0x49, 0x8a, 0x98 } } },
+ { L"EFI_SMM_STATUS_CODE_PROTOCOL_GUID", { 0x6afd2b77, 0x98c1, 0x4acd, { 0xa6, 0xf9, 0x8a, 0x94, 0x39, 0xde, 0x0f, 0xb1 } } },
+ { L"EFI_SMM_SWAP_ADDRESS_RANGE_PROTOCOL_GUID", { 0x67c4f112, 0x3385, 0x4e55, { 0x9c, 0x5b, 0xc0, 0x5b, 0x71, 0x7c, 0x42, 0x28 } } },
+ { L"EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID", { 0x18a3c6dc, 0x5eea, 0x48c8, { 0xa1, 0xc1, 0xb5, 0x33, 0x89, 0xf9, 0x89, 0x99 } } },
+ { L"EFI_SMM_SW_DISPATCH_PROTOCOL_GUID", { 0xe541b773, 0xdd11, 0x420c, { 0xb0, 0x26, 0xdf, 0x99, 0x36, 0x53, 0xf8, 0xbf } } },
+ { L"EFI_SMM_SX_DISPATCH2_PROTOCOL_GUID", { 0x456d2859, 0xa84b, 0x4e47, { 0xa2, 0xee, 0x32, 0x76, 0xd8, 0x86, 0x99, 0x7d } } },
+ { L"EFI_SMM_SX_DISPATCH_PROTOCOL_GUID", { 0x14fc52be, 0x01dc, 0x426c, { 0x91, 0xae, 0xa2, 0x3c, 0x3e, 0x22, 0x0a, 0xe8 } } },
+ { L"EFI_SMM_TCO_DISPATCH_PROTOCOL_GUID", { 0x0e2d6bb1, 0xc624, 0x446d, { 0x99, 0x82, 0x69, 0x3c, 0xd1, 0x81, 0xa6, 0x07 } } },
+ { L"EFI_SMM_THUNK_PROTOCOL_GUID", { 0x2a82fce6, 0x8bb6, 0x413e, { 0xb9, 0xeb, 0x45, 0xdf, 0xc0, 0x52, 0x2d, 0xf3 } } },
+ { L"EFI_SMM_USB_DISPATCH2_PROTOCOL_GUID", { 0xee9b8d90, 0xc5a6, 0x40a2, { 0xbd, 0xe2, 0x52, 0x55, 0x8d, 0x33, 0xcc, 0xa1 } } },
+ { L"EFI_SMM_USB_DISPATCH_PROTOCOL_GUID", { 0xa05b6ffd, 0x87af, 0x4e42, { 0x95, 0xc9, 0x62, 0x28, 0xb6, 0x3c, 0xf3, 0xf3 } } },
+ { L"EFI_SMM_VARIABLE_PROTOCOL_GUID", { 0x3025da01, 0xdc5f, 0x4f59, { 0xbc, 0xc3, 0xb3, 0x77, 0xc8, 0x32, 0x5a, 0x4a } } },
+ { L"EFI_SMM_VARIABLE_PROTOCOL_GUID", { 0xed32d533, 0x99e6, 0x4209, { 0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7 } } },
+ { L"EFI_SMM_VARIABLE_WRITE_GUID", { 0x93ba1826, 0xdffb, 0x45dd, { 0x82, 0xa7, 0xe7, 0xdc, 0xaa, 0x3b, 0xbd, 0xf3 } } },
+ { L"EFI_SMRAM_NVS_HEADER_GUID", { 0xec7f4fa1, 0xb217, 0x42fc, { 0xa7, 0xf7, 0x02, 0x0c, 0x43, 0x05, 0xd5, 0xba } } },
+ { L"EFI_SMTP_PROTOCOL_GUID", { 0x5f67d40c, 0x1d06, 0x4e3e, { 0x8b, 0x4a, 0xd2, 0x71, 0x3f, 0x46, 0xe1, 0xdc } } },
+ { L"EFI_SPEAKER_INTERFACE_PROTOCOL_GUID", { 0x400b4476, 0x3081, 0x11d6, { 0x87, 0xed, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } } },
+ { L"EFI_SPI_PROTOCOL_GUID", { 0x01a660d9, 0x8009, 0x4330, { 0xba, 0x89, 0x71, 0xb0, 0x76, 0xcd, 0x5d, 0x0a } } },
+ { L"EFI_SPI_PROTOCOL_GUID", { 0x1156efc6, 0xea32, 0x4396, { 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 } } },
+ { L"EFI_STANDARD_CALLER_ID_GUID", { 0xc9dcf469, 0xa7c4, 0x11d5, { 0x87, 0xda, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } } },
+ { L"EFI_STANDARD_ERROR_DEVICE_GUID", { 0xd3b36f2d, 0xd551, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_STATUS_CODE_ARCH_PROTOCOL_GUID", { 0xd98e3ea3, 0x6f39, 0x4be4, { 0x82, 0xce, 0x5a, 0x89, 0x0c, 0xcb, 0x2c, 0x95 } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID", { 0xda571595, 0x4d99, 0x487c, { 0x82, 0x7c, 0x26, 0x22, 0x67, 0x7d, 0x33, 0x07 } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID", { 0x9a4e9246, 0xd553, 0x11d5, { 0x87, 0xe2, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_ERROR_GUID", { 0xab359ce3, 0x99b3, 0xae18, { 0xc8, 0x9d, 0x95, 0xd3, 0xb0, 0x72, 0xe1, 0x9b } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_EXCEPTION_HANDLER_GUID", { 0x3bc2bd12, 0xad2e, 0x11d5, { 0x87, 0xdd, 0x00, 0x06, 0x29, 0x45, 0xc3, 0xb9 } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_PROGRESS_CODE_GUID", { 0xa356ab39, 0x35c4, 0x35da, { 0xb3, 0x7a, 0xf8, 0xea, 0x9e, 0x8b, 0x36, 0xa3 } } },
+ { L"EFI_STATUS_CODE_DATA_TYPE_STRING_GUID", { 0x92d11080, 0x496f, 0x4d95, { 0xbe, 0x7e, 0x03, 0x74, 0x88, 0x38, 0x2b, 0x0a } } },
+ { L"EFI_STATUS_CODE_GUID", { 0xd083e94c, 0x6560, 0x42e4, { 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a } } },
+ { L"EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID", { 0xd2b2b828, 0x0826, 0x48a7, { 0xb3, 0xdf, 0x98, 0x3c, 0x00, 0x60, 0x24, 0xf0 } } },
+ { L"EFI_STATUS_CODE_SPECIFIC_DATA_GUID", { 0x335984bd, 0xe805, 0x409a, { 0xb8, 0xf8, 0xd2, 0x7e, 0xce, 0x5f, 0xf7, 0xa6 } } },
+ { L"EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID", { 0xc88b0b6d, 0x0dfc, 0x49a7, { 0x9c, 0xb4, 0x49, 0x07, 0x4b, 0x4c, 0x3a, 0x78 } } },
+ { L"EFI_SWAP_ADDRESS_RANGE_PROTOCOL_GUID", { 0x1259f60d, 0xb754, 0x468e, { 0xa7, 0x89, 0x4d, 0xb8, 0x5d, 0x55, 0xe8, 0x7e } } },
+ { L"EFI_SYSTEM_NV_DATA_FV_GUID", { 0xfff12b8d, 0x7696, 0x4c8b, { 0xa9, 0x85, 0x27, 0x47, 0x07, 0x5b, 0x4f, 0x50 } } },
+ { L"EFI_SYSTEM_NV_DATA_HOB_GUID", { 0xd6e5092d, 0xc7b2, 0x4872, { 0xaf, 0x66, 0xfd, 0xc0, 0xe6, 0xf9, 0x5e, 0x78 } } },
+ { L"EFI_SYSTEM_TYPE_FRU_GUID", { 0xaab16018, 0x679d, 0x4461, { 0xba, 0x20, 0xe7, 0x0c, 0xf7, 0x86, 0x6a, 0x9b } } },
+ { L"EFI_TAPE_IO_PROTOCOL_GUID", { 0x1e93e633, 0xd65a, 0x459e, { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } } },
+ { L"EFI_TCG_EVENT_HOB_GUID", { 0x2b9ffb52, 0x1b13, 0x416f, { 0xa8, 0x7b, 0xbc, 0x93, 0x0d, 0xef, 0x92, 0xa8 } } },
+ { L"EFI_TCG_LOG_HOB_GUID", { 0x5f7d4e0e, 0x3d6d, 0x42bc, { 0xa9, 0x42, 0x0e, 0x91, 0xe8, 0x3e, 0x3c, 0x31 } } },
+ { L"EFI_TCG_PEI_READ_ONLY_VARIABLE_PPI_GUID", { 0x3cdc90c6, 0x13fb, 0x4a75, { 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa } } },
+ { L"EFI_TCG_PLATFORM_PROTOCOL_GUID", { 0x8c4c9a41, 0xbf56, 0x4627, { 0x9e, 0x0a, 0xc8, 0x38, 0x6d, 0x66, 0x11, 0x5c } } },
+ { L"EFI_TCG_PRIVATE_INTERFACE_GUID", { 0x8c4c9a41, 0xbf56, 0x4627, { 0x9e, 0x0a, 0xc8, 0x38, 0x6d, 0x66, 0x11, 0x5c } } },
+ { L"EFI_TCG_PROTOCOL_GUID", { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } } },
+ { L"EFI_TCG_WAKE_EVENT_DATA_HOB_GUID", { 0xbbb810bb, 0x5ef0, 0x4e8f, { 0xb2, 0x98, 0xad, 0x74, 0xaa, 0x50, 0xef, 0x0a } } },
+ { L"EFI_TCP4_PROTOCOL_GUID", { 0x65530bc7, 0xa359, 0x410f, { 0xb0, 0x10, 0x5a, 0xad, 0xc7, 0xec, 0x2b, 0x62 } } },
+ { L"EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID", { 0x00720665, 0x67eb, 0x4a99, { 0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c, 0x7c, 0xc9 } } },
+ { L"EFI_TCP6_PROTOCOL_GUID", { 0x46e44855, 0xbd60, 0x4ab7, { 0xab, 0x0d, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77 } } },
+ { L"EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID", { 0xec20eb79, 0x6c1a, 0x4664, { 0x9a, 0x0d, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64 } } },
+ { L"EFI_TCP_PROTOCOL_GUID", { 0x02b3d5f2, 0xac28, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_TCP_SOCK_PROTOCOL_GUID", { 0x5187359b, 0x790d, 0x425b, { 0xa5, 0x93, 0xca, 0x1c, 0xdb, 0x3c, 0xeb, 0xad } } },
+ { L"EFI_TDT_PROTOCOL_GUID", { 0x0bf70067, 0xd53b, 0x42df, { 0xb7, 0x70, 0xe9, 0x2c, 0x91, 0xc6, 0x14, 0x11 } } },
+ { L"EFI_TELNET_SERVER_PROTOCOL_GUID", { 0x6d3569d4, 0x85e5, 0x4943, { 0xae, 0x46, 0xee, 0x67, 0xa6, 0xe1, 0xab, 0x5a } } },
+ { L"EFI_TIANO_DECOMPRESS_PROTOCOL_GUID", { 0xe84cf29c, 0x191f, 0x4eae, { 0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b } } },
+ { L"EFI_TIMER_ARCH_PROTOCOL_GUID", { 0x26baccb3, 0x6f42, 0x11d4, { 0xbc, 0xe7, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_TIMESTAMP_PROTOCOL_GUID", { 0xafbfde41, 0x2e6e, 0x4262, { 0xba, 0x65, 0x62, 0xb9, 0x23, 0x6e, 0x54, 0x95 } } },
+ { L"EFI_TIME_VARIABLE_GUID", { 0x9d0da369, 0x540b, 0x46f8, { 0x85, 0xa0, 0x2b, 0x5f, 0x2c, 0x30, 0x1e, 0x15 } } },
+ { L"EFI_TPM_DEVICE_PROTOCOL_GUID", { 0xde161cfe, 0x1e60, 0x42a1, { 0x8c, 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52, 0x12 } } },
+ { L"EFI_TPM_STATE_INIT_HUB_GUID", { 0xa0c6d918, 0x8dee, 0x41bb, { 0x9d, 0x92, 0x67, 0x53, 0xa5, 0x72, 0xb6, 0x52 } } },
+ { L"EFI_TREE_PHYSICAL_PRESENCE_DATA_GUID", { 0xf24643c2, 0xc622, 0x494e, { 0x8a, 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b } } },
+ { L"EFI_TREE_PROTOCOL_GUID", { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } } },
+ { L"EFI_TSC_FREQUENCY_GUID", { 0xdba6a7e3, 0xbb57, 0x4be7, { 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } } },
+ { L"EFI_TXT_INFO_PROTOCOL_GUID", { 0x601211dc, 0x0b12, 0x4c09, { 0xae, 0x27, 0xab, 0x0e, 0xc9, 0x69, 0x24, 0x68 } } },
+ { L"EFI_UART_DEVICE_PATH_GUID", { 0x37499a9d, 0x542f, 0x4c89, { 0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } } },
+ { L"EFI_UDP4_PROTOCOL_GUID", { 0x3ad9df29, 0x4501, 0x478d, { 0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3 } } },
+ { L"EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID", { 0x83f01464, 0x99bd, 0x45e5, { 0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6 } } },
+ { L"EFI_UDP6_PROTOCOL_GUID", { 0x4f948815, 0xb4b9, 0x43cb, { 0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 } } },
+ { L"EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID", { 0x66ed4721, 0x3c98, 0x4d3e, { 0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 } } },
+ { L"EFI_UDP_PROTOCOL_GUID", { 0xc56fb1b2, 0x017b, 0x4984, { 0xa3, 0xf6, 0x3f, 0x73, 0x4f, 0xfa, 0x9e, 0x33 } } },
+ { L"EFI_UGA_DRAW_PROTOCOL_GUID", { 0x982c298b, 0xf4fa, 0x41cb, { 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } } },
+ { L"EFI_UGA_IO_PROTOCOL_GUID", { 0x61a4d49e, 0x6f68, 0x4f1b, { 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2 } } },
+ { L"EFI_UGA_SPLASH_PROTOCOL_GUID", { 0xa45b3a0d, 0x2e55, 0x4c03, { 0xad, 0x9c, 0x27, 0xd4, 0x82, 0x0b, 0x50, 0x7e } } },
+ { L"EFI_UNICODE_COLLATION2_PROTOCOL_GUID", { 0xa4c751fc, 0x23ae, 0x4c3e, { 0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49 } } },
+ { L"EFI_UNICODE_COLLATION_PROTOCOL2_GUID", { 0xa4c751fc, 0x23ae, 0x4c3e, { 0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49 } } },
+ { L"EFI_UNICODE_COLLATION_PROTOCOL_GUID", { 0x1d85cd7f, 0xf43d, 0x11d2, { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_UPDATE_DATA_FILE_GUID", { 0x283fa2ee, 0x532c, 0x484d, { 0x93, 0x83, 0x9f, 0x93, 0xb3, 0x6f, 0x0b, 0x7e } } },
+ { L"EFI_USB2_HC_PROTOCOL_GUID", { 0x3e745226, 0x9818, 0x45b6, { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } } },
+ { L"EFI_USB_ATAPI_PROTOCOL_GUID", { 0x2b2f68da, 0x0cd2, 0x44cf, { 0x8e, 0x8b, 0xbb, 0xa2, 0x0b, 0x1b, 0x5b, 0x75 } } },
+ { L"EFI_USB_HC_PROTOCOL_GUID", { 0xf5089266, 0x1aa0, 0x4953, { 0x97, 0xd8, 0x56, 0x2f, 0x8a, 0x73, 0xb5, 0x19 } } },
+ { L"EFI_USB_IO_PROTOCOL_GUID", { 0x2b2f68d6, 0x0cd2, 0x44cf, { 0x8e, 0x8b, 0xbb, 0xa2, 0x0b, 0x1b, 0x5b, 0x75 } } },
+ { L"EFI_USB_POLICY_PROTOCOL_GUID", { 0x5859cb76, 0x6bef, 0x468a, { 0xbe, 0x2d, 0xb3, 0xdd, 0x1a, 0x27, 0xf0, 0x12 } } },
+ { L"EFI_USB_PROTOCOL_GUID", { 0x2ad8e2d2, 0x2e91, 0x4cd1, { 0x95, 0xf5, 0xe7, 0x8f, 0xe5, 0xeb, 0xe3, 0x16 } } },
+ { L"EFI_USER_CREDENTIAL2_PROTOCOL_GUID", { 0xe98adb03, 0xb8b9, 0x4af8, { 0xba, 0x20, 0x26, 0xe9, 0x11, 0x4c, 0xbc, 0xe5 } } },
+ { L"EFI_USER_CREDENTIAL_PROTOCOL_GUID", { 0x71ee5e94, 0x65b9, 0x45d5, { 0x82, 0x1a, 0x3a, 0x4d, 0x86, 0xcf, 0xe6, 0xbe } } },
+ { L"EFI_USER_INFO_ACCESS_SETUP_ADMIN_GUID", { 0x85b75607, 0xf7ce, 0x471e, { 0xb7, 0xe4, 0x2a, 0xea, 0x5f, 0x72, 0x32, 0xee } } },
+ { L"EFI_USER_INFO_ACCESS_SETUP_NORMAL_GUID", { 0x1db29ae0, 0x9dcb, 0x43bc, { 0x8d, 0x87, 0x5d, 0xa1, 0x49, 0x64, 0xdd, 0xe2 } } },
+ { L"EFI_USER_INFO_ACCESS_SETUP_RESTRICTED_GUID", { 0xbdb38125, 0x4d63, 0x49f4, { 0x82, 0x12, 0x61, 0xcf, 0x5a, 0x19, 0x0a, 0xf8 } } },
+ { L"EFI_USER_MANAGER_PROTOCOL_GUID", { 0x6fd5b00c, 0xd426, 0x4283, { 0x98, 0x87, 0x6c, 0xf5, 0xcf, 0x1c, 0xb1, 0xfe } } },
+ { L"EFI_VARIABLE_ARCH_PROTOCOL_GUID", { 0x1e5668e2, 0x8481, 0x11d4, { 0xbc, 0xf1, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_VARIABLE_GUID", { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d } } },
+ { L"EFI_VARIABLE_INDEX_TABLE_GUID", { 0x8cfdb8c8, 0xd6b2, 0x40f3, { 0x8e, 0x97, 0x02, 0x30, 0x7c, 0xc9, 0x8b, 0x7c } } },
+ { L"EFI_VARIABLE_STORE_PROTOCOL_GUID", { 0xf088cd91, 0xa046, 0x11d2, { 0x8e, 0x42, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID", { 0x6441f818, 0x6362, 0x4e44, { 0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53 } } },
+ { L"EFI_VGA_MINI_PORT_PROTOCOL_GUID", { 0xc7735a2f, 0x88f5, 0x4882, { 0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3 } } },
+ { L"EFI_VIRTUAL_MEMORY_ACCESS_PROTOCOL_GUID", { 0x745d377a, 0xb988, 0x47b2, { 0xb1, 0x8f, 0xbb, 0xc8, 0x0d, 0xc5, 0x66, 0x98 } } },
+ { L"EFI_VLAN_CONFIG_PROTOCOL_GUID", { 0x9e23d768, 0xd2f3, 0x4366, { 0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74 } } },
+ { L"EFI_VT_100_GUID", { 0xdfa66065, 0xb419, 0x11d3, { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_VT_100_PLUS_GUID", { 0x7baec70b, 0x57e0, 0x4c76, { 0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } } },
+ { L"EFI_VT_UTF8_GUID", { 0xad15a0d6, 0x8bec, 0x4acf, { 0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } } },
+ { L"EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID", { 0x665e3ff5, 0x46cc, 0x11d4, { 0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID", { 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_CONSOLE_GUID", { 0xba73672c, 0xa5d3, 0x11d4, { 0xbd, 0x00, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_CPU_MODEL_GUID", { 0xbee9b6ce, 0x2f8a, 0x11d4, { 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_CPU_SPEED_GUID", { 0xd4f29055, 0xe1fb, 0x11d4, { 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_FILE_SYSTEM_GUID", { 0x0c95a935, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_GOP_GUID", { 0x4e11e955, 0xccca, 0x11d4, { 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_IO_PROTOCOL_GUID", { 0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_MEMORY_GUID", { 0x99042912, 0x122a, 0x11d4, { 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_PASS_THROUGH_GUID", { 0xcc664eb8, 0x3c24, 0x4086, { 0xb6, 0xf6, 0x34, 0xe8, 0x56, 0xbc, 0xe3, 0x6e } } },
+ { L"EFI_WIN_NT_PHYSICAL_DISKS_GUID", { 0x0c95a92f, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_SERIAL_PORT_GUID", { 0x0c95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_SYSTEM_CONFIG_GUID", { 0xb347f047, 0xaf8c, 0x490e, { 0xac, 0x07, 0x0a, 0xa9, 0xb7, 0xe5, 0x38, 0x58 } } },
+ { L"EFI_WIN_NT_THUNK_PROTOCOL_GUID", { 0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_UGA_GUID", { 0xab248e99, 0xabe1, 0x11d4, { 0xbd, 0x0d, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_WIN_NT_VIRTUAL_DISKS_GUID", { 0x0c95a928, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"EFI_XEN_INFO_GUID", { 0xd3b46f3b, 0xd441, 0x1244, { 0x9a, 0x12, 0x00, 0x12, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"EMBEDDED_DEVICE_PROTOCOL_GUID", { 0xbf4b9d10, 0x13ec, 0x43dd, { 0x88, 0x80, 0xe9, 0x0b, 0x71, 0x8f, 0x27, 0xde } } },
+ { L"EMBEDDED_EXTERNAL_DEVICE_PROTOCOL_GUID", { 0x735f8c64, 0xd696, 0x44d0, { 0xbd, 0xf2, 0x44, 0x7f, 0xd0, 0x5a, 0x54, 0x06 } } },
+ { L"EMU_BLOCK_IO_PROTOCOL_GUID", { 0x6888a4ae, 0xafce, 0xe84b, { 0x91, 0x02, 0xf7, 0xb9, 0xda, 0xe6, 0xa0, 0x30 } } },
+ { L"EMU_GRAPHICS_WINDOW_PROTOCOL_GUID", { 0x30fd316a, 0x6728, 0x2e41, { 0xa6, 0x90, 0x0d, 0x13, 0x33, 0xd8, 0xca, 0xc1 } } },
+ { L"EMU_IO_THUNK_PROTOCO_GUID", { 0x453368f6, 0x7c85, 0x434a, { 0xa9, 0x8a, 0x72, 0xd1, 0xb7, 0xff, 0xa9, 0x26 } } },
+ { L"EMU_SNP_PROTOCOL_GUID", { 0xfd5fbe54, 0x8c35, 0xb345, { 0x8a, 0x0f, 0x7a, 0xc8, 0xa5, 0xfd, 0x05, 0x21 } } },
+ { L"EMU_THUNK_PPI_GUID", { 0xb958b78c, 0x1d3e, 0xee40, { 0x8b, 0xf4, 0xf0, 0x63, 0x2d, 0x06, 0x39, 0x16 } } },
+ { L"EMU_THUNK_PROTOCOL_GUID", { 0x5cf32e0b, 0x8edf, 0x2e44, { 0x9c, 0xda, 0x93, 0x20, 0x5e, 0x99, 0xec, 0x1c } } },
+ { L"ERROR_MANAGER_GUID", { 0xaddebf82, 0xa560, 0x46b9, { 0xa2, 0x80, 0x78, 0xc6, 0xab, 0x61, 0xae, 0xda } } },
+ { L"EXIT_FORM_SET_GUID", { 0xa43b03dc, 0xc18a, 0x41b1, { 0x91, 0xc8, 0x3f, 0xf9, 0xaa, 0xa2, 0x57, 0x13 } } },
+ { L"EXIT_PAGE_GUID", { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } } },
+ { L"EXIT_PM_AUTH_PROTOCOL_GUID", { 0xd088a413, 0x0a70, 0x4217, { 0xba, 0x55, 0x9a, 0x3c, 0xb6, 0x5c, 0x41, 0xb3 } } },
+ { L"EXTENDED_SAL_BOOT_SERVICE_PROTOCOL_GUID", { 0xde0ee9a4, 0x3c7a, 0x44f2, { 0xb7, 0x8b, 0xe3, 0xcc, 0xd6, 0x9c, 0x3a, 0xf7 } } },
+ { L"FAST_BOOT_TSE_PROTOCOL_GUID", { 0x0fba43b8, 0xacdb, 0x4ee2, { 0xab, 0x31, 0x0f, 0xa4, 0xd5, 0xb6, 0xc3, 0xc5 } } },
+ { L"FAST_BOOT_VARIABLE_GUID", { 0xb540a530, 0x6978, 0x4da7, { 0x91, 0xcb, 0x72, 0x07, 0xd7, 0x64, 0xd2, 0x62 } } },
+ { L"FID_TABLE_GUID", { 0x3fd1d3a2, 0x99f7, 0x420b, { 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 } } },
+ { L"FID_TABLE_SECTION_GUID", { 0x2ebe0275, 0x6458, 0x4af9, { 0x91, 0xed, 0xd3, 0xf4, 0xed, 0xb1, 0x00, 0xaa } } },
+ { L"FILE_EXPLORE_FORMSET_GUID", { 0x1f2d63e1, 0xfebd, 0x4dc7, { 0x9c, 0xc5, 0xba, 0x2b, 0x1c, 0xef, 0x9c, 0x5b } } },
+ { L"FIRMWARE_PERFORMANCE_PROTOCOL_GUID", { 0xbc412d75, 0x2729, 0x4c3a, { 0xb1, 0x93, 0x5b, 0x9a, 0x58, 0x8f, 0xf6, 0x6f } } },
+ { L"FIRMWARE_PERFORMANCE_S3_POINTER_GUID", { 0x0dc65adc, 0xa973, 0x4130, { 0x8d, 0xf0, 0x2a, 0xdb, 0xeb, 0x9e, 0x4a, 0x31 } } },
+ { L"FLASH_PROTOCOL_GUID", { 0x755b6596, 0x6896, 0x4ba3, { 0xb3, 0xdd, 0x1c, 0x62, 0x9f, 0xd1, 0xea, 0x88 } } },
+ { L"FLASH_SMM_PROTOCOL_GUID", { 0xecb867ab, 0x8df4, 0x492d, { 0x81, 0x50, 0xa7, 0xfd, 0x1b, 0x9b, 0x5a, 0x75 } } },
+ { L"FLASH_UPDATE_GUID", { 0x974231d5, 0xed4b, 0x44d1, { 0x88, 0x70, 0xce, 0x51, 0x5c, 0xc1, 0x4d, 0x68 } } },
+ { L"FONT_FFS_FILE_GUID", { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0x0d, 0xcc, 0x77, 0x06, 0x1b, 0x9b } } },
+ { L"FORM_BROWSER_EXTENSION_PROTOCOL_GUID", { 0x1f73b18d, 0x4630, 0x43c1, { 0xa1, 0xde, 0x6f, 0x80, 0x85, 0x5d, 0x7d, 0xa4 } } },
+ { L"FPDT_PERFORMANCE_PROTOCOL_GUID", { 0x444c3203, 0xf8b1, 0x42a7, { 0xab, 0xe9, 0x2e, 0x58, 0x02, 0x5b, 0xe1, 0x2a } } },
+ { L"FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID", { 0x9e0c30bc, 0x3f06, 0x4ba6, { 0x82, 0x88, 0x09, 0x17, 0x9b, 0x85, 0x5d, 0xbe } } },
+ { L"FRAMEWORK_EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID", { 0xde28bc59, 0x6228, 0x41bd, { 0xbd, 0xf6, 0xa3, 0xb9, 0xad, 0xb5, 0x8d, 0xa1 } } },
+ { L"FRAMEWORK_EFI_MP_SERVICES_PROTOCOL_GUID", { 0xf33261e7, 0x23cb, 0x11d5, { 0xbd, 0x5c, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } },
+ { L"FRONT_PAGE_FORMSET_GUID", { 0x9e0c30bc, 0x3f06, 0x4ba6, { 0x82, 0x88, 0x09, 0x17, 0x9b, 0x85, 0x5d, 0xbe } } },
+ { L"FW_VERSION_GUID", { 0xb5c59087, 0xfeac, 0x4b41, { 0x9d, 0x80, 0x79, 0x0b, 0xa5, 0xaa, 0x07, 0x0f } } },
+ { L"FW_VOLUME_BLOCK_PROTOCOL_GUID", { 0xde28bc59, 0x6228, 0x41bd, { 0xbd, 0xf6, 0xa3, 0xb9, 0xad, 0xb5, 0x8d, 0xa1 } } },
+ { L"HANDLE_PARSING_HII_GUID", { 0xb8969637, 0x81de, 0x43af, { 0xbc, 0x9a, 0x24, 0xd9, 0x89, 0x13, 0xf2, 0xf6 } } },
+ { L"HD_BOOT_DEVICE_PATH_VARIABLE_GUID", { 0xfab7e9e1, 0x39dd, 0x4f2b, { 0x84, 0x08, 0xe2, 0x0e, 0x90, 0x6c, 0xb6, 0xde } } },
+ { L"HDD_SECURITY_END_PROTOCOL_GUID", { 0xad77ae29, 0x4c20, 0x4fdd, { 0x85, 0x04, 0x81, 0x76, 0x61, 0x9b, 0x67, 0x6a } } },
+ { L"HDD_SECURITY_INIT_PROTOCOL_GUID", { 0xce6f86bb, 0xb800, 0x4c71, { 0xb2, 0xd1, 0x38, 0x97, 0xa3, 0xbc, 0x1d, 0xae } } },
+ { L"HDD_SMART_INIT_PROTOCOL_GUID", { 0x9401bd4f, 0x1a00, 0x4990, { 0xab, 0x56, 0xda, 0xf0, 0xe4, 0xe3, 0x48, 0xde } } },
+ { L"HDD_UNLOCKED_GUID", { 0x1fd29be6, 0x70d0, 0x42a4, { 0xa6, 0xe7, 0xe5, 0xd1, 0x0e, 0x6a, 0xc3, 0x76 } } },
+ { L"HECI_PROTOCOL_GUID", { 0xcfb33810, 0x6e87, 0x4284, { 0xb2, 0x03, 0xa6, 0x6a, 0xbe, 0x07, 0xf6, 0xe8 } } },
+ { L"HII_RESOURCE_SAMPLE_FORM_SET_GUID", { 0x4f4ef7f0, 0xaa29, 0x4ce9, { 0xba, 0x41, 0x64, 0x3e, 0x01, 0x23, 0xa9, 0x9f } } },
+ { L"HII_RESOURCES_FFS_SECTION_GUID", { 0x97e409e6, 0x4cc1, 0x11d9, { 0x81, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { L"HOB_LIST_GUID", { 0x7739f24c, 0x93d7, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"HOT_PLUG_DEVICE_GUID", { 0x220ac432, 0x1d43, 0x49e5, { 0xa7, 0x4f, 0x4c, 0x9d, 0xa6, 0x7a, 0xd2, 0x3b } } },
+ { L"ICC_OVERCLOCKING_PROTOCOL_GUID", { 0x8e8cbc58, 0x834c, 0x41e3, { 0xb8, 0xca, 0xf0, 0x0c, 0xcf, 0x5a, 0x71, 0x7c } } },
+ { L"ICC_PERSISTENT_DATA_GUID", { 0x64192dca, 0xd034, 0x49d2, { 0xa6, 0xde, 0x65, 0xa8, 0x29, 0xeb, 0x4c, 0x74 } } },
+ { L"ICC_VOLATILE_SETUP_DATA_GUID", { 0x7b77fb8b, 0x1e0d, 0x4d7e, { 0x95, 0x3f, 0x39, 0x80, 0xa2, 0x61, 0xe0, 0x77 } } },
+ { L"IDE_BUS_DRIVER_BINDING_PROTOCOL_GUID", { 0x8aa67071, 0x8bec, 0x47ab, { 0x83, 0xc8, 0xcd, 0x0e, 0xb7, 0x23, 0xd0, 0x72 } } },
+ { L"IDE_BUS_INIT_PROTOCOL_GUID", { 0xe159a956, 0x3299, 0x4ee9, { 0x91, 0x76, 0x65, 0x18, 0x1a, 0x4e, 0x5e, 0x9f } } },
+ { L"IDE_CONTROLLER_PROTOCOL_GUID", { 0x20e28787, 0xdf32, 0x4bda, { 0xb7, 0xe7, 0xcb, 0xbd, 0xa3, 0x37, 0x1e, 0xf8 } } },
+ { L"IDE_HPA_INTERFACE_GUID", { 0x51aa65fc, 0x82b6, 0x49e6, { 0x95, 0xe2, 0xe6, 0x82, 0x7a, 0x8d, 0x7d, 0xb4 } } },
+ { L"IDE_POWER_MGMT_INTERFACE_GUID", { 0x67bc3883, 0x7e79, 0x4bc1, { 0xa3, 0x3e, 0x3a, 0xf7, 0xd1, 0x75, 0x89, 0xba } } },
+ { L"IDE_SECURITY_INTERFACE_GUID", { 0xf4f63529, 0x281e, 0x4040, { 0xa3, 0x13, 0xc1, 0xd6, 0x76, 0x63, 0x84, 0xbe } } },
+ { L"IDE_SECURITY_PWNV_GUID", { 0x69967a8c, 0x1159, 0x4522, { 0xaa, 0x89, 0x74, 0xcd, 0xc6, 0xe5, 0x99, 0xa0 } } },
+ { L"IDE_SETUP_PROTOCOL_GUID", { 0x5578ae16, 0xf1c9, 0x4e8f, { 0xb1, 0x29, 0xba, 0x07, 0xf8, 0xfc, 0xf8, 0x4a } } },
+ { L"IDE_SMART_INTERFACE_GUID", { 0xffbd9ad2, 0xf1db, 0x4f92, { 0xa6, 0x49, 0xeb, 0x9e, 0xed, 0xea, 0x86, 0xb5 } } },
+ { L"IDLE_LOOP_EVENT_GUID", { 0x3c8d294c, 0x5fc3, 0x4451, { 0xbb, 0x31, 0xc4, 0xc0, 0x32, 0x29, 0x5e, 0x6c } } },
+ { L"IFFS_ACPI_TABLE_STORAGE_GUID", { 0x60ac3a8f, 0x4d66, 0x4cd4, { 0x89, 0x5a, 0xc3, 0xf0, 0x6e, 0x66, 0x65, 0xee } } },
+ { L"IFFS_GLOBAL_NVS_AREA_PROTOCOL_GUID", { 0xa5559f06, 0x6415, 0x4759, { 0x88, 0x69, 0xde, 0x15, 0xf9, 0xcd, 0x9c, 0x9b } } },
+ { L"IFFS_GPT_GUID", { 0xd3bfe2de, 0x3daf, 0x11df, { 0xba, 0x40, 0xe3, 0xa5, 0x56, 0xd8, 0x95, 0x93 } } },
+ { L"IFFS_INFO_PROTOCOL_GUID", { 0xd231db5b, 0x4a9c, 0x4092, { 0xa8, 0xc5, 0x9c, 0xa0, 0xbc, 0x7d, 0x6a, 0xa6 } } },
+ { L"IFFS_PARTITION_STATUS_PROTOCOL_GUID", { 0x65639144, 0xd492, 0x4328, { 0xa4, 0x98, 0xf4, 0xb5, 0x54, 0x5e, 0x4a, 0x30 } } },
+ { L"IFFS_PERSISTENT_DATA_GUID", { 0xf9f0b131, 0xf346, 0x4f16, { 0x80, 0xdd, 0xf9, 0x41, 0x07, 0x2b, 0x3a, 0x7d } } },
+ { L"IFFS_PLATFORM_POLICY_PROTOCOL_GUID", { 0x42bbaca3, 0x7161, 0x4891, { 0xac, 0x10, 0xc7, 0x5e, 0x2e, 0x4d, 0xf6, 0x14 } } },
+ { L"IFFS_PPI_GUID", { 0x3d0e663a, 0xdc72, 0x4489, { 0x87, 0xc5, 0xe4, 0x9e, 0xe7, 0x73, 0xa4, 0x52 } } },
+ { L"IGD_OPREGION_PROTOCOL_GUID", { 0xcdc5dddf, 0xe79d, 0x41ec, { 0xa9, 0xb0, 0x65, 0x65, 0x49, 0x0d, 0xb9, 0xd3 } } },
+ { L"INTEL_FRAMEWORK_MODULEPKG_TOKEN_SPACE_GUID", { 0xd3705011, 0xbc19, 0x4af7, { 0xbe, 0x16, 0xf6, 0x80, 0x30, 0x37, 0x8c, 0x15 } } },
+ { L"INTEL_MEBX_PROTOCOL_GUID", { 0x01ab1829, 0xcecd, 0x4cfa, { 0xa1, 0x8c, 0xea, 0x75, 0xd6, 0x6f, 0x3e, 0x74 } } },
+ { L"IP4_ISCSI_CONFIG_GUID", { 0x6456ed61, 0x3579, 0x41c9, { 0x8a, 0x26, 0x0a, 0x0b, 0xd6, 0x2b, 0x78, 0xfc } } },
+ { L"IP6_CONFIG_NVDATA_GUID", { 0x02eea107, 0x98db, 0x400e, { 0x98, 0x30, 0x46, 0x0a, 0x15, 0x42, 0xd7, 0x99 } } },
+ { L"ISCSI_CHAP_AUTH_INFO_GUID", { 0x786ec0ac, 0x65ae, 0x4d1b, { 0xb1, 0x37, 0x0d, 0x11, 0x0a, 0x48, 0x37, 0x97 } } },
+ { L"ISCSI_CONFIG_GUID", { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0x0f, 0x4c, 0xf9 } } },
+ { L"ISCSI_V4_PRIVATE_GUID", { 0xfa3cde4c, 0x87c2, 0x427d, { 0xae, 0xde, 0x7d, 0xd0, 0x96, 0xc8, 0x8c, 0x58 } } },
+ { L"ISCSI_V6_PRIVATE_GUID", { 0x28be27e5, 0x66cc, 0x4a31, { 0xa3, 0x15, 0xdb, 0x14, 0xc3, 0x74, 0x4d, 0x85 } } },
+ { L"LAST_ENUM_LANGUAGE_GUID", { 0x0e8c545b, 0xa2ee, 0x470d, { 0x8e, 0x26, 0xbd, 0xa1, 0xa1, 0x3c, 0x0a, 0xa3 } } },
+ { L"LDR_MEMORY_DESCRIPTOR_GUID", { 0x7701d7e5, 0x7d1d, 0x4432, { 0xa4, 0x68, 0x67, 0x3d, 0xab, 0x8a, 0xde, 0x60 } } },
+ { L"LEGACY_DEV_ORDER_GUID", { 0xa56074db, 0x65fe, 0x45f7, { 0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 } } },
+ { L"LOAD_FILE_PROTOCOL_GUID", { 0x56ec3091, 0x954c, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"LZMA_CUSTOM_DECOMPRESS_GUID", { 0xee4e5898, 0x3914, 0x4259, { 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } } },
+ { L"LZMAF86_CUSTOM_DECOMPRESS_GUID", { 0xd42ae6bd, 0x1352, 0x4bfb, { 0x90, 0x9a, 0xca, 0x72, 0xa6, 0xea, 0xe8, 0x89 } } },
+ { L"MAIN_FORM_SET_GUID", { 0x985eee91, 0xbcac, 0x4238, { 0x87, 0x78, 0x57, 0xef, 0xdc, 0x93, 0xf2, 0x4e } } },
+ { L"MDEMODULEPKG_TOKEN_SPACE_GUID", { 0xa1aff049, 0xfdeb, 0x442a, { 0xb3, 0x20, 0x13, 0xab, 0x4c, 0xb7, 0x2b, 0xbc } } },
+ { L"MDEPKG_TOKEN_SPACE_GUID", { 0x914aebe7, 0x4635, 0x459b, { 0xaa, 0x1c, 0x11, 0xe2, 0x19, 0xb0, 0x3a, 0x10 } } },
+ { L"MDES_STATUS_CODE_PROTOCOL_GUID", { 0xe5d0875a, 0xf647, 0x4e16, { 0xbe, 0x4d, 0x95, 0x02, 0x40, 0x29, 0xcc, 0x44 } } },
+ { L"ME_ALERT_AT_HANDLER_GUID", { 0xb441df87, 0x8d94, 0x4811, { 0x85, 0xf7, 0x0f, 0x9a, 0x7b, 0xf8, 0x9d, 0x2a } } },
+ { L"ME_BIOS_PAYLOAD_DATA_PROTOCOL_GUID", { 0x71a19494, 0x2ab6, 0x4e96, { 0x85, 0x81, 0xcf, 0x34, 0x25, 0x42, 0x73, 0xfe } } },
+ { L"MEBX_FILE_GUID", { 0x7c81c66a, 0x4f11, 0x47ab, { 0x82, 0xd3, 0x67, 0xc4, 0xd6, 0x35, 0xae, 0xd1 } } },
+ { L"ME_INFO_SETUP_GUID", { 0x78259433, 0x7b6d, 0x4db3, { 0x9a, 0xe8, 0x36, 0xc4, 0xc2, 0xc3, 0xa1, 0x7d } } },
+ { L"MEM_INFO_PROTOCOL_GUID", { 0x6f20f7c8, 0xe5ef, 0x4f21, { 0x8d, 0x19, 0xed, 0xc5, 0xf0, 0xc4, 0x96, 0xae } } },
+ { L"MEMORY_ONLY_RESET_CONTROL_GUID", { 0xe20939be, 0x32d4, 0x41be, { 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29 } } },
+ { L"MEMORY_STATUS_CODE_RECORD_GUID", { 0x060cc026, 0x4c0d, 0x4dda, { 0x8f, 0x41, 0x59, 0x5f, 0xef, 0x00, 0xa5, 0x02 } } },
+ { L"ME_PLATFORM_GET_RESET_TYPE_GUID", { 0xb8cdced7, 0xbdc4, 0x4464, { 0x9a, 0x1a, 0xff, 0x3f, 0xbd, 0xf7, 0x48, 0x69 } } },
+ { L"MEUD_ERROR_GUID", { 0x0732bd39, 0xd6b0, 0x4039, { 0xb6, 0xc2, 0x96, 0x54, 0x46, 0x6d, 0xe5, 0x25 } } },
+ { L"MEUD_FILE_GUID", { 0xfeaaa7a6, 0xcb95, 0x4670, { 0xb4, 0x99, 0x87, 0x7f, 0xa6, 0xca, 0x6b, 0xae } } },
+ { L"MICROCODE_LOADER_PPI_GUID", { 0x9b6eecf6, 0xfbdc, 0x4db6, { 0x95, 0x62, 0xd2, 0x5f, 0x40, 0xd5, 0x76, 0x61 } } },
+ { L"MINI_SETUP_RESOURCE_SECTION_GUID", { 0x97e409e6, 0x4cc1, 0x11d9, { 0x81, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { L"MTC_VENDOR_GUID", { 0xeb704011, 0x1402, 0x11d3, { 0x8e, 0x77, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"MXM30_PEI_GUID", { 0x2ef1ba1a, 0xc836, 0x4a50, { 0xbf, 0x89, 0x52, 0x5f, 0xf2, 0x9f, 0xf7, 0x87 } } },
+ { L"MXM3_EFI_GUID", { 0x4ea9d4fe, 0xe6f6, 0x410b, { 0x90, 0x37, 0x0f, 0x98, 0xb5, 0x96, 0x8b, 0x65 } } },
+ { L"NBCI_EFI_GUID", { 0x4ea9d4fe, 0xe6f6, 0x410b, { 0x80, 0x37, 0x0f, 0x98, 0xb5, 0x96, 0x8b, 0x65 } } },
+ { L"NETWORK_STACK_GUID", { 0xd1405d16, 0x7afc, 0x4695, { 0xbb, 0x12, 0x41, 0x45, 0x9d, 0x36, 0x95, 0xa2 } } },
+ { L"NT_FWH_PPI_GUID", { 0x4e76928f, 0x50ad, 0x4334, { 0xb0, 0x6b, 0xa8, 0x42, 0x13, 0x10, 0x8a, 0x57 } } },
+ { L"NT_PEI_LOAD_FILE_GUID", { 0xfd0c65eb, 0x0405, 0x4cd2, { 0x8a, 0xee, 0xf4, 0x00, 0xef, 0x13, 0xba, 0xc2 } } },
+ { L"NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID", { 0xec51ef5c, 0x2cf3, 0x4a55, { 0xbf, 0x85, 0xb6, 0x3c, 0xa3, 0xb1, 0x3f, 0x44 } } },
+ { L"NVRAM_HOB_GUID", { 0xc0ec00fd, 0xc2f8, 0x4e47, { 0x90, 0xef, 0x9c, 0x81, 0x55, 0x28, 0x5b, 0xec } } },
+ { L"NVRAM_MAILBOX_ADDRESS_VARIABLE_GUID", { 0x54913a6d, 0xf4ee, 0x4cdb, { 0x84, 0x75, 0x74, 0x06, 0x2b, 0xfc, 0xec, 0xf5 } } },
+ { L"OEM_RECOVERY_CAPSULE_GUID", { 0x595a6edc, 0x6d2c, 0x474a, { 0x90, 0x82, 0x3b, 0x99, 0x28, 0x51, 0xdf, 0xfe } } },
+ { L"OEM_ROM_HOLE_0_GUID", { 0x05ca01fc, 0x0fc1, 0x11dc, { 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 } } },
+ { L"OEM_ROM_HOLE_1_GUID", { 0x05ca01fd, 0x0fc1, 0x11dc, { 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 } } },
+ { L"OEM_TSE_VAR_GUID", { 0xf4b2c007, 0x94a1, 0x4cd5, { 0xa7, 0x10, 0xf4, 0x14, 0x1f, 0xce, 0xbc, 0xa0 } } },
+ { L"ONBOARD_RAID_GUID", { 0x5d206dd3, 0x516a, 0x47dc, { 0xa1, 0xbc, 0x6d, 0xa2, 0x04, 0xaa, 0xbe, 0x08 } } },
+ { L"OPAL_SEC_INIT_PROTOCOL_GUID", { 0x59af16b0, 0x661d, 0x4865, { 0xa3, 0x81, 0x38, 0xde, 0x68, 0x38, 0x5d, 0x8d } } },
+ { L"OPROM_START_END_PROTOCOL_GUID", { 0xf2a128ff, 0x257b, 0x456e, { 0x9d, 0xe8, 0x63, 0xe7, 0xc7, 0xdc, 0xdf, 0xac } } },
+ { L"PARTITION_VARIABLE_GUID", { 0x8db699cc, 0xbc81, 0x41e2, { 0xaa, 0xc6, 0xd8, 0x1d, 0x53, 0x00, 0xd7, 0x59 } } },
+ { L"PASSWORD_HOB_GUID", { 0x79ce097a, 0x91aa, 0x41ff, { 0xb3, 0xa8, 0x53, 0x45, 0x59, 0xb3, 0x0d, 0xb1 } } },
+ { L"PCATCHIPSET_TOKEN_SPACE_GUID", { 0x326ae723, 0xae32, 0x4589, { 0x98, 0xb8, 0xca, 0xc2, 0x3c, 0xdc, 0xc1, 0xb1 } } },
+ { L"PCD_DATABASE_HOB_GUID", { 0xea296d92, 0x0b69, 0x423c, { 0x8c, 0x28, 0x33, 0xb4, 0xe0, 0xa9, 0x12, 0x68 } } },
+ { L"PCD_PPI_GUID", { 0x06e81c58, 0x4ad7, 0x44bc, { 0x83, 0x90, 0xf1, 0x02, 0x65, 0xf7, 0x24, 0x80 } } },
+ { L"PCD_PROTOCOL_GUID", { 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0x0e, 0xf7 } } },
+ { L"PCH_DMI_TC_VC_PPI_GUID", { 0xed097352, 0x9041, 0x445a, { 0x80, 0xb6, 0xb2, 0x9d, 0x50, 0x9e, 0x88, 0x45 } } },
+ { L"PCH_EFI_RAID_DRIVER_EXECUTION_GUID", { 0x99d5757c, 0xd906, 0x11e0, { 0x8d, 0x78, 0x8d, 0xe4, 0x48, 0x24, 0x01, 0x9b } } },
+ { L"PCH_INIT_PPI_GUID", { 0xe8c7ce14, 0x1eed, 0x48fd, { 0x83, 0x47, 0x8e, 0x55, 0x41, 0x10, 0xc0, 0xd9 } } },
+ { L"PCH_INIT_VARIABLE_GUID", { 0xe6c2f70a, 0xb604, 0x4877, { 0x85, 0xba, 0xde, 0xec, 0x89, 0xe1, 0x17, 0xeb } } },
+ { L"PCH_ME_UMA_PPI_GUID", { 0x8c376010, 0x2400, 0x4d7d, { 0xb4, 0x7b, 0x9d, 0x85, 0x1d, 0xf3, 0xc9, 0xd1 } } },
+ { L"PCH_PLATFORM_POLICY_PPI_GUID", { 0x22074e71, 0xbccc, 0x4517, { 0x87, 0x57, 0x79, 0x95, 0xed, 0xfd, 0x80, 0x32 } } },
+ { L"PCH_RESET_CALLBACK_PROTOCOL_GUID", { 0x3a3300ab, 0xc929, 0x487d, { 0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0 } } },
+ { L"PCH_RESET_PROTOCOL_GUID", { 0xdb63592c, 0xb8cc, 0x44c8, { 0x91, 0x8c, 0x51, 0xf5, 0x34, 0x59, 0x8a, 0x5a } } },
+ { L"PCH_SATA_CONTROLLER_DRIVER_GUID", { 0xbb929da9, 0x68f7, 0x4035, { 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55 } } },
+ { L"PCH_USB_POLICY_PPI_GUID", { 0xc02b0573, 0x2b4e, 0x4a31, { 0xa3, 0x1a, 0x94, 0x56, 0x7b, 0x50, 0x44, 0x2c } } },
+ { L"PE32_IMAGE_PROTOCOL_GUID", { 0x5cb5c776, 0x60d5, 0x45ee, { 0x88, 0x3c, 0x45, 0x27, 0x08, 0xcd, 0x74, 0x3f } } },
+ { L"PE_COFF_LOADER_PROTOCOL_GUID", { 0xb323179b, 0x97fb, 0x477e, { 0xb0, 0xfe, 0xd8, 0x85, 0x91, 0xfa, 0x11, 0xab } } },
+ { L"PEI_AMT_PLATFORM_POLICY_PPI_GUID", { 0xb4a1208e, 0x4d9a, 0x4ea2, { 0x9d, 0x6b, 0xe4, 0x1a, 0x61, 0xe6, 0xc5, 0xac } } },
+ { L"PEI_AMT_STATUS_CODE_PPI_GUID", { 0x881807d2, 0x98d1, 0x4ec9, { 0xaf, 0xa0, 0x77, 0x46, 0xc4, 0x2f, 0x24, 0x49 } } },
+ { L"PEI_APRIORI_FILE_NAME_GUID", { 0x1b45cc0a, 0x156a, 0x428a, { 0x62, 0xaf, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6 } } },
+ { L"PEI_AP_STARTUP_FILE_GUID", { 0xd1e59f50, 0xe8c3, 0x4545, { 0xbf, 0x61, 0x11, 0xf0, 0x02, 0x23, 0x3c, 0x97 } } },
+ { L"PEI_ATA_CONTROLLER_PPI_GUID", { 0xa1e2176f, 0xcbda, 0x4f32, { 0x87, 0x56, 0x7d, 0x7a, 0xe5, 0x22, 0xd6, 0x93 } } },
+ { L"PEI_ATA_CONTROLLER_PPI_GUID", { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d } } },
+ { L"PEI_ATA_POLICY_PPI_GUID", { 0x1b8ddea4, 0xdeb2, 0x4152, { 0x91, 0xc2, 0xb7, 0x3c, 0xb1, 0x6c, 0xe4, 0x64 } } },
+ { L"PEI_BASE_MEMORY_TEST_GUID", { 0xb6ec423c, 0x21d2, 0x490d, { 0x85, 0xc6, 0xdd, 0x58, 0x64, 0xea, 0xa6, 0x74 } } },
+ { L"PEI_BIOS_ACM_FILE_GUID", { 0x2d27c618, 0x7dcd, 0x41f5, { 0xbb, 0x10, 0x21, 0x16, 0x6b, 0xe7, 0xe1, 0x43 } } },
+ { L"PEI_BLOCK_IO_PPI_GUID", { 0x695d8aa1, 0x42ee, 0x4c46, { 0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3 } } },
+ { L"PEI_BOOT_SCRIPT_DONE_PPI_GUID", { 0xfd7c4665, 0x34be, 0x426b, { 0xb1, 0xf8, 0x3a, 0xb7, 0x53, 0xce, 0x44, 0xb0 } } },
+ { L"PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID", { 0xabd42895, 0x78cf, 0x4872, { 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xff } } },
+ { L"PEI_CACHE_PPI_GUID", { 0x09be4bc2, 0x790e, 0x4dea, { 0x8b, 0xdc, 0x38, 0x05, 0x16, 0x98, 0x39, 0x44 } } },
+ { L"PEI_CACHE_PPI_GUID", { 0xc153205a, 0xe898, 0x4c24, { 0x86, 0x89, 0xa4, 0xb4, 0xbc, 0xc5, 0xc8, 0xa2 } } },
+ { L"PEI_CAPSULE_PPI_GUID", { 0x3acf33ee, 0xd892, 0x40f4, { 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d } } },
+ { L"PEI_CPU_IO_PPI_GUID", { 0xe6af1f7b, 0xfc3f, 0x46da, { 0xa8, 0x28, 0xa3, 0xb4, 0x57, 0xa4, 0x42, 0x82 } } },
+ { L"PEI_CPU_PLATFORM_POLICY_PPI_GUID", { 0x7b8ee7a1, 0x4e35, 0x4556, { 0xbb, 0x56, 0x67, 0x97, 0xe2, 0x44, 0x45, 0xc2 } } },
+ { L"PEI_END_OF_PEI_PHASE_PPI_GUID", { 0x605ea650, 0xc65c, 0x42e1, { 0xba, 0x80, 0x91, 0xa5, 0x2a, 0xb6, 0x18, 0xc6 } } },
+ { L"PEI_FLASH_MAP_PPI_GUID", { 0xf34c2fa0, 0xde88, 0x4270, { 0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } } },
+ { L"PEI_HECI_PPI_GUID", { 0xee0ea811, 0xfbd9, 0x4777, { 0xb9, 0x5a, 0xba, 0x4f, 0x71, 0x10, 0x1f, 0x74 } } },
+ { L"PEI_IDE_RECOVERY_NATIVE_MODE_PPI_GUID", { 0x7e13637a, 0xc3f8, 0x43d1, { 0xb0, 0x51, 0xed, 0x19, 0xd7, 0x08, 0xec, 0x7a } } },
+ { L"PEI_IFFS_TRANSITION_START_PPI_GUID", { 0xde8f2878, 0x36d5, 0x498e, { 0xba, 0x59, 0x16, 0x8c, 0x26, 0x47, 0xb3, 0x35 } } },
+ { L"PEI_IN_MEMORY_GUID", { 0x643b8786, 0xb417, 0x48d2, { 0x8f, 0x5e, 0x78, 0x19, 0x93, 0x1c, 0xae, 0xd8 } } },
+ { L"PEI_LOCK_PHYSICAL_PRESENCE_PPI_GUID", { 0xef9aefe5, 0x2bd3, 0x4031, { 0xaf, 0x7d, 0x5e, 0xfe, 0x5a, 0xbb, 0x9a, 0x0d } } },
+ { L"PEI_ME_PLATFORM_POLICY_PPI_GUID", { 0x7ae3ceb7, 0x2ee2, 0x48fa, { 0xaa, 0x49, 0x35, 0x10, 0xbc, 0x83, 0xca, 0xbf } } },
+ { L"PEI_NT_AUTOSCAN_PPI_GUID", { 0x0dce384d, 0x007c, 0x4ba5, { 0x94, 0xbd, 0x0f, 0x6e, 0xb6, 0x4d, 0x2a, 0xa9 } } },
+ { L"PEI_NT_THUNK_GUID", { 0x98c281e5, 0xf906, 0x43dd, { 0xa9, 0x2b, 0xb0, 0x03, 0xbf, 0x27, 0x65, 0xda } } },
+ { L"PEI_NT_THUNK_PPI_GUID", { 0x98c281e5, 0xf906, 0x43dd, { 0xa9, 0x2b, 0xb0, 0x03, 0xbf, 0x27, 0x65, 0xda } } },
+ { L"PEI_OPERATOR_PRESENCE_PPI_GUID", { 0x20a7378c, 0xaa83, 0x4ce1, { 0x82, 0x1f, 0x47, 0x40, 0xee, 0x1b, 0x3f, 0x9f } } },
+ { L"PEI_PCI_CFG_PPI_GUID", { 0xe1f2eba0, 0xf7b9, 0x4a26, { 0x86, 0x20, 0x13, 0x12, 0x21, 0x64, 0x2a, 0x90 } } },
+ { L"PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID", { 0xf894643d, 0xc449, 0x42d1, { 0x8e, 0xa8, 0x85, 0xbd, 0xd8, 0xc6, 0x5b, 0xde } } },
+ { L"PEI_PLATFORM_MEMORY_RANGE_PPI_GUID", { 0x30eb2979, 0xb0f7, 0x4d60, { 0xb2, 0xdc, 0x1a, 0x2c, 0x96, 0xce, 0xb1, 0xf4 } } },
+ { L"PEI_PLATFORM_MEMORY_SIZE_PPI_GUID", { 0x9a7ef41e, 0xc140, 0x4bd1, { 0xb8, 0x84, 0x1e, 0x11, 0x24, 0x0b, 0x4c, 0xe6 } } },
+ { L"PEI_POST_BOOT_SCRIPT_TABLE_PPI_GUID", { 0x88c9d306, 0x0900, 0x4eb5, { 0x82, 0x60, 0x3e, 0x2d, 0xbe, 0xda, 0x1f, 0x89 } } },
+ { L"PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID", { 0x3cdc90c6, 0x13fb, 0x4a75, { 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa } } },
+ { L"PEI_RESET_PPI_GUID", { 0xef398d58, 0x9dfd, 0x4103, { 0xbf, 0x94, 0x78, 0xc6, 0xf4, 0xfe, 0x71, 0x2f } } },
+ { L"PEI_S3_RESUME_PPI_GUID", { 0x4426ccb2, 0xe684, 0x4a8a, { 0xae, 0x40, 0x20, 0xd4, 0xb0, 0x25, 0xb7, 0x10 } } },
+ { L"PEI_SEC_PERFORMANCE_PPI_GUID", { 0x0ecc666b, 0x4662, 0x47f9, { 0x9d, 0xd5, 0xd0, 0x96, 0xff, 0x7d, 0xa4, 0x9e } } },
+ { L"PEI_SECURITY_PPI_GUID", { 0x1388066e, 0x3a57, 0x4efa, { 0x98, 0xf3, 0xc1, 0x2f, 0x3a, 0x95, 0x8a, 0x29 } } },
+ { L"PEI_SMBUS2_PPI_GUID", { 0x9ca93627, 0xb65b, 0x4324, { 0xa2, 0x02, 0xc0, 0xb4, 0x61, 0x76, 0x45, 0x43 } } },
+ { L"PEI_SMBUS_POLICY_PPI_GUID", { 0x63b6e435, 0x32bc, 0x49c6, { 0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c } } },
+ { L"PEI_SMBUS_PPI_GUID", { 0xabd42895, 0x78cf, 0x4872, { 0x84, 0x44, 0x1b, 0x5c, 0x18, 0x0b, 0xfb, 0xda } } },
+ { L"PEI_SMM_ACCESS_PPI_GUID", { 0x268f33a9, 0xcccd, 0x48be, { 0x88, 0x17, 0x86, 0x05, 0x3a, 0xc3, 0x2e, 0xd6 } } },
+ { L"PEI_SMM_CONTROL_PPI_GUID", { 0x61c68702, 0x4d7e, 0x4f43, { 0x8d, 0xef, 0xa7, 0x43, 0x05, 0xce, 0x74, 0xc5 } } },
+ { L"PEI_SPI_PPI_GUID", { 0x64e42e92, 0xe958, 0x4e99, { 0x90, 0xe2, 0xf7, 0xfd, 0x90, 0xa7, 0x6c, 0x59 } } },
+ { L"PEI_STALL_PPI_GUID", { 0x1f4c6f90, 0xb06b, 0x48d8, { 0xa2, 0x01, 0xba, 0xe5, 0xf1, 0xcd, 0x7d, 0x56 } } },
+ { L"PEI_STATUS_CODE_MEMORY_PPI_GUID", { 0x26f8ab01, 0xd3cd, 0x489c, { 0x98, 0x4f, 0xdf, 0xde, 0xf7, 0x68, 0x39, 0x5b } } },
+ { L"PEI_STATUS_CODE_PPI_GUID", { 0x229832d3, 0x7a30, 0x4b36, { 0xb8, 0x27, 0xf4, 0x0c, 0xb7, 0xd4, 0x54, 0x36 } } },
+ { L"PEI_TCG_INTERNAL_FLAGS_GUID", { 0x70fff0ff, 0xa543, 0x45b9, { 0x8b, 0xe3, 0x1b, 0xdb, 0x90, 0x41, 0x20, 0x80 } } },
+ { L"PEI_TCG_PPI_GUID", { 0x177d39d2, 0x43b8, 0x40c8, { 0x9a, 0xe1, 0x3c, 0x51, 0x98, 0xd6, 0x94, 0x1e } } },
+ { L"PEI_TPM_INITIALIZED_PPI_GUID", { 0xe9db0d58, 0xd48d, 0x47f6, { 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 } } },
+ { L"PEI_TPM_PPI_2_GUID", { 0xca4853f4, 0xe94b, 0x42b4, { 0x86, 0x42, 0xcd, 0xe2, 0x8a, 0x7f, 0xac, 0x2d } } },
+ { L"PEI_TPM_PPI_GUID", { 0xca4853f4, 0xe94b, 0x42b4, { 0x86, 0x42, 0xcd, 0xe2, 0x8a, 0x7f, 0xac, 0x2d } } },
+ { L"PEI_TPM_PPI_GUID", { 0xe9db0d58, 0xd48d, 0x47f6, { 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 } } },
+ { L"PEI_TXT_MEMORY_UNLOCKED_PPI_GUID", { 0x38cdd10b, 0x767d, 0x4f6e, { 0xa7, 0x44, 0x67, 0xee, 0x1d, 0xfe, 0x2f, 0xa5 } } },
+ { L"PEI_USB2_HOST_CONTROLLER_PPI_GUID", { 0xa7d09fe1, 0x74d4, 0x4ba5, { 0x84, 0x7c, 0x12, 0xed, 0x5b, 0x19, 0xad, 0xe4 } } },
+ { L"PEI_USB_CONTROLLER_PPI_GUID", { 0x3bc1f6de, 0x693e, 0x4547, { 0xa3, 0x00, 0x21, 0x82, 0x3c, 0xa4, 0x20, 0xb2 } } },
+ { L"PEI_USB_HOST_CONTROLLER_PPI_GUID", { 0x652b38a9, 0x77f4, 0x453f, { 0x89, 0xd5, 0xe7, 0xbd, 0xc3, 0x52, 0xfc, 0x53 } } },
+ { L"PEI_USB_IO_PPI_GUID", { 0x7c29785c, 0x66b9, 0x49fc, { 0xb7, 0x97, 0x1c, 0xa5, 0x55, 0x0e, 0xf2, 0x83 } } },
+ { L"PERFORMANCE_EX_PROTOCOL_GUID", { 0x1ea81bec, 0xf01a, 0x4d98, { 0xa2, 0x01, 0x4a, 0x61, 0xce, 0x2f, 0xc0, 0x22 } } },
+ { L"PERFORMANCEPKG_TOKEN_SPACE_GUID", { 0x669346ef, 0xfdad, 0x4aeb, { 0x08, 0xa6, 0x21, 0x46, 0x2d, 0x3f, 0xef, 0x7d } } },
+ { L"PERFORMANCE_PROTOCOL_GUID", { 0x76b6bdfa, 0x2acd, 0x4462, { 0x9e, 0x3f, 0xcb, 0x58, 0xc9, 0x69, 0xd9, 0x37 } } },
+ { L"PERF_TUNE_PPI_GUID", { 0xc49189f3, 0x1d4c, 0x4ad7, { 0xa4, 0x39, 0xd0, 0x13, 0xab, 0x72, 0x09, 0x31 } } },
+ { L"PERF_TUNE_PROTOCOL_GUID", { 0xdd6c613a, 0x5a77, 0x4b4f, { 0xa6, 0x1e, 0x3b, 0xdd, 0x2a, 0xe2, 0x1d, 0x81 } } },
+ { L"PERF_TUNE_WDT_PPI_GUID", { 0xa7c88fae, 0xebec, 0x45ed, { 0xa7, 0xc5, 0x5f, 0xa7, 0x55, 0x17, 0x73, 0x06 } } },
+ { L"PERF_TUNE_WDT_PROTOCOL_GUID", { 0xc0557eed, 0x9a89, 0x4770, { 0x96, 0x26, 0xfc, 0xa0, 0x51, 0xf2, 0xba, 0x09 } } },
+ { L"PK_PUB_FFS_FILE_EFI_AUTH_VAR_GUID", { 0x9e625a27, 0x4840, 0x47cc, { 0xa6, 0xb5, 0x1e, 0x93, 0x11, 0xcf, 0xc6, 0x0e } } },
+ { L"PKPUB_KEY_GUID", { 0xa6c0e11e, 0x929e, 0x42b3, { 0x90, 0xcc, 0x4f, 0x77, 0x8e, 0x03, 0xff, 0x57 } } },
+ { L"PLATFORM_IDE_PROTOCOL_GUID", { 0x6737f69b, 0xb8cc, 0x45bc, { 0x93, 0x27, 0xcc, 0xf5, 0xee, 0xf7, 0x0c, 0xde } } },
+ { L"PLATFORM_ME_HOOK_PPI_GUID", { 0xe806424f, 0xd425, 0x4b1a, { 0xbc, 0x26, 0x5f, 0x69, 0x03, 0x89, 0xa1, 0x5a } } },
+ { L"PLATFORM_ME_HOOK_PROTOCOL_GUID", { 0xbc52476e, 0xf67e, 0x4301, { 0xb2, 0x62, 0x36, 0x9c, 0x48, 0x78, 0xaa, 0xc2 } } },
+ { L"PLAT_OVER_MNGR_GUID", { 0x8614567d, 0x35be, 0x4415, { 0x8d, 0x88, 0xbd, 0x7d, 0x0c, 0x9c, 0x70, 0xc0 } } },
+ { L"POWER_MANAGEMENT_ACPI_TABLE_STORAGE_GUID", { 0x299141bb, 0x211a, 0x48a5, { 0x92, 0xc0, 0x6f, 0x9a, 0x0a, 0x3a, 0x00, 0x6e } } },
+ { L"PPM_PLATFORM_POLICY_PROTOCOL_GUID", { 0x6f27e990, 0x7bc8, 0x42c9, { 0x8f, 0x71, 0x99, 0x80, 0x06, 0x36, 0x93, 0xe9 } } },
+ { L"PPM_PROCESSOR_SUPPORT_PROTOCOL_3_GUID", { 0xa60c7dcd, 0x512f, 0x4f02, { 0xb1, 0x80, 0x52, 0x2e, 0x01, 0x5e, 0x06, 0xb7 } } },
+ { L"PR_KEY_FFS_FILE_RAW_GUID", { 0x3feec852, 0xf14c, 0x4e7f, { 0x97, 0xfd, 0x4c, 0x3a, 0x8c, 0x5b, 0xbe, 0xcc } } },
+ { L"PR_KEY_GUID", { 0x4e0f9bd4, 0xe338, 0x4b26, { 0x84, 0x3e, 0xbd, 0x3a, 0xd9, 0xb2, 0x83, 0x7b } } },
+ { L"PTID_FFS_TABLE_STORAGE_GUID", { 0x95dfcae5, 0xbb28, 0x4d6b, { 0xb1, 0xe2, 0x3a, 0xf3, 0xa6, 0xbf, 0x43, 0x4f } } },
+ { L"PWD_CREDENTIAL_PROVIDER_GUID", { 0x78b9ec8b, 0xc000, 0x46c5, { 0xac, 0x93, 0x24, 0xa0, 0xc1, 0xbb, 0x00, 0xce } } },
+ { L"RECOVERY_FORM_SET_GUID", { 0x80e1202e, 0x2697, 0x4264, { 0x9c, 0xc9, 0x80, 0x76, 0x2c, 0x3e, 0x58, 0x63 } } },
+ { L"RECOVERY_ON_DATA_CD_GUID", { 0x5cac0099, 0x0dc9, 0x48e5, { 0x80, 0x68, 0xbb, 0x95, 0xf5, 0x40, 0x0a, 0x9f } } },
+ { L"RECOVERY_ON_FAT_FLOPPY_DISK_GUID", { 0x2e3d2e75, 0x9b2e, 0x412d, { 0xb4, 0xb1, 0x70, 0x41, 0x6b, 0x87, 0x00, 0xff } } },
+ { L"RECOVERY_ON_FAT_IDE_DISK_GUID", { 0xb38573b6, 0x6200, 0x4ac5, { 0xb5, 0x1d, 0x82, 0xe6, 0x59, 0x38, 0xd7, 0x83 } } },
+ { L"RECOVERY_ON_FAT_USB_DISK_GUID", { 0x0ffbce19, 0x324c, 0x4690, { 0xa0, 0x09, 0x98, 0xc6, 0xae, 0x2e, 0xb1, 0x86 } } },
+ { L"ROM_CACHE_ENABLE_PPI_GUID", { 0x36e835bb, 0x661d, 0x4d37, { 0x8d, 0xe5, 0x88, 0x53, 0x25, 0xda, 0xe9, 0x10 } } },
+ { L"ROM_IMAGE_ADDRESS_GUID", { 0xdde1bc72, 0xd45e, 0x4209, { 0xab, 0x85, 0x14, 0x46, 0x2d, 0x2f, 0x50, 0x74 } } },
+ { L"ROM_IMAGE_MEMORY_HOB_GUID", { 0xee2f45d2, 0x5ba4, 0x441e, { 0x8a, 0x1d, 0xaa, 0x22, 0xdf, 0xa3, 0xb6, 0xc5 } } },
+ { L"ROM_LAYOUT_FFS_GUID", { 0x0dca793a, 0xea96, 0x42d8, { 0xbd, 0x7b, 0xdc, 0x7f, 0x68, 0x4e, 0x38, 0xc1 } } },
+ { L"ROM_LAYOUT_SECTION_GUID", { 0x88a15a4f, 0x977d, 0x4682, { 0xb1, 0x7c, 0xda, 0x1f, 0x31, 0x6c, 0x1f, 0x32 } } },
+ { L"RSDP_PLUS_PROTOCOL_GUID", { 0xa33319b5, 0x8ee1, 0x45e0, { 0x8c, 0x9f, 0x80, 0x9f, 0x5b, 0x09, 0x02, 0xcc } } },
+ { L"SAL_SYSTEM_TABLE_GUID", { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"SA_PEG_DATA_HOB_GUID", { 0x5f5d3502, 0x8a4b, 0x40ca, { 0x88, 0xa2, 0x23, 0x05, 0x42, 0x7a, 0x13, 0x1a } } },
+ { L"SA_PEG_DATA_VARIABLE_GUID", { 0xc4975200, 0x64f1, 0x4fb6, { 0x97, 0x73, 0xf6, 0xa9, 0xf8, 0x9d, 0x98, 0x5e } } },
+ { L"SA_PEI_INIT_PPI_GUID", { 0x09ea8911, 0xbe0d, 0x4230, { 0xa0, 0x03, 0xed, 0xc6, 0x93, 0xb4, 0x8e, 0x11 } } },
+ { L"SA_PLATFORM_POLICY_PPI_GUID", { 0x150ce416, 0xee63, 0x46b6, { 0x8b, 0xa3, 0x73, 0x22, 0xbb, 0xe0, 0x46, 0x37 } } },
+ { L"SATA_CONTROLLER_PROTOCOL_GUID", { 0x2acb6627, 0xdf02, 0x4e23, { 0xb4, 0xf9, 0x6a, 0x93, 0xfa, 0x6e, 0x9d, 0xa6 } } },
+ { L"SECUREBOOT_CONFIG_FORM_SET_GUID", { 0x5daf50a5, 0xea81, 0x4de2, { 0x8f, 0x9b, 0xca, 0xbd, 0xa9, 0xcf, 0x5c, 0x14 } } },
+ { L"SECURITY_FORM_SET_GUID", { 0x981ceaee, 0x931c, 0x4a17, { 0xb9, 0xc8, 0x66, 0xc7, 0xbc, 0xfd, 0x77, 0xe1 } } },
+ { L"SECURITYPKG_TOKEN_SPACE_GUID", { 0x0d3fb176, 0x9569, 0x4d51, { 0xa3, 0xef, 0x7d, 0x61, 0xc6, 0x4f, 0xea, 0xba } } },
+ { L"SERIAL_RECOVERY_CAPSULE_GUID", { 0x699add70, 0x8554, 0x4993, { 0x83, 0xf6, 0xd2, 0xcd, 0xc0, 0x81, 0xdd, 0x85 } } },
+ { L"SETUP_DEFAULTS_FFS_GUID", { 0x9221315b, 0x30bb, 0x46b5, { 0x81, 0x3e, 0x1b, 0x1b, 0xf4, 0x71, 0x2b, 0xd3 } } },
+ { L"SETUP_GUID", { 0xec87d643, 0xeba4, 0x4bb5, { 0xa1, 0xe5, 0x3f, 0x3e, 0x36, 0xb2, 0x0d, 0xa9 } } },
+ { L"SG_ACPI_TABLE_STORAGE_GUID", { 0xcacb3817, 0x81e6, 0x497e, { 0x87, 0xff, 0xc8, 0xfa, 0x8f, 0x24, 0xec, 0x28 } } },
+ { L"SG_INFO_HOB_GUID", { 0x648ce07b, 0xae5d, 0x4973, { 0xbd, 0x3c, 0x8c, 0x91, 0x53, 0xc0, 0x5d, 0xc5 } } },
+ { L"SGOEM_ACPI_SSDT_GUID", { 0x5b232086, 0x350a, 0x42c7, { 0xa7, 0x0e, 0x34, 0x97, 0xb5, 0x76, 0x5d, 0x85 } } },
+ { L"SG_PEI_INIT_PPI_GUID", { 0xaa40d00e, 0x5b9b, 0x4dad, { 0xa4, 0x87, 0xfc, 0x1b, 0xcb, 0xef, 0x81, 0x70 } } },
+ { L"SG_PLATFORM_POLICY_PPI_GUID", { 0xa391e822, 0x7044, 0x4cf4, { 0xbe, 0x5b, 0x34, 0x5e, 0x44, 0xb8, 0x62, 0x7c } } },
+ { L"SGTPV_ACPI_SSDT_GUID", { 0x6a061113, 0xfe54, 0x4a07, { 0xa2, 0x8e, 0x0a, 0x69, 0x35, 0x9e, 0xb0, 0x69 } } },
+ { L"SHELL_ALIAS_VARIABLE_GUID", { 0x0053d9d6, 0x2659, 0x4599, { 0xa2, 0x6b, 0xef, 0x45, 0x36, 0xe6, 0x31, 0xa9 } } },
+ { L"SHELL_DEBUG1_HII_GUID", { 0x25f200aa, 0xd3cb, 0x470a, { 0xbf, 0x51, 0xe7, 0xd1, 0x62, 0xd2, 0x2e, 0x6f } } },
+ { L"SHELL_DRIVER1_HII_GUID", { 0x0af0b742, 0x63ec, 0x45bd, { 0x8d, 0xb6, 0x71, 0xad, 0x7f, 0x2f, 0xe8, 0xe8 } } },
+ { L"SHELL_ENVIRONMENT_PROTOCOL_GUID", { 0x47c7b221, 0xc42a, 0x11d2, { 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"SHELL_INSTALL1_HII_GUID", { 0x7d574d54, 0xd364, 0x4d4a, { 0x95, 0xe3, 0x49, 0x45, 0xdb, 0x7a, 0xd3, 0xee } } },
+ { L"SHELL_INTERFACE_PROTOCOL_GUID", { 0x47c7b223, 0xc42a, 0x11d2, { 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"SHELL_LEVEL1_HII_GUID", { 0xdec5daa4, 0x6781, 0x4820, { 0x9c, 0x63, 0xa7, 0xb0, 0xe4, 0xf1, 0xdb, 0x31 } } },
+ { L"SHELL_LEVEL2_HII_GUID", { 0xf95a7ccc, 0x4c55, 0x4426, { 0xa7, 0xb4, 0xdc, 0x89, 0x61, 0x95, 0x0b, 0xae } } },
+ { L"SHELL_LEVEL3_HII_GUID", { 0x4344558d, 0x4ef9, 0x4725, { 0xb1, 0xe4, 0x33, 0x76, 0xe8, 0xd6, 0x97, 0x4f } } },
+ { L"SHELL_MAP_GUID", { 0x51271e13, 0x7de3, 0x43af, { 0x8b, 0xc2, 0x71, 0xad, 0x3b, 0x82, 0x43, 0x25 } } },
+ { L"SHELL_NETWORK1_HII_GUID", { 0xf3d301bb, 0xf4a5, 0x45a8, { 0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae } } },
+ { L"SHELLPKG_SHELL_ENV2_EXT_GUID", { 0xd2c18636, 0x40e5, 0x4eb5, { 0xa3, 0x1b, 0x36, 0x69, 0x5f, 0xd4, 0x2c, 0x87 } } },
+ { L"SHELL_VARIABLE_GUID", { 0x158def5a, 0xf656, 0x419c, { 0xb0, 0x27, 0x7a, 0x31, 0x92, 0xc0, 0x79, 0xd2 } } },
+ { L"SIO_DEV_STATUS_VAR_GUID", { 0x5820de98, 0xfc8e, 0x4b0b, { 0xa4, 0xb9, 0x0a, 0x94, 0x0d, 0x16, 0x2a, 0x7e } } },
+ { L"SIO_IO_PROTOCOL_GUID", { 0x964e5b21, 0x6000, 0x23d2, { 0x9e, 0x39, 0x01, 0xa0, 0xc9, 0x69, 0x72, 0x3b } } },
+ { L"SMBIOS_FLASH_DATA_FFS_GUID", { 0xfd44820b, 0xf1ab, 0x41c0, { 0xae, 0x4e, 0x0c, 0x55, 0x55, 0x6e, 0xb9, 0xbd } } },
+ { L"SMBIOS_TABLE_GUID", { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"SM_BUS_CONTROLLER_IDENTIFIER_GUID", { 0x882f2546, 0xef1f, 0x4090, { 0x9f, 0x9c, 0x93, 0x84, 0x5a, 0xd7, 0x84, 0x1c } } },
+ { L"SMM_CHILD_DISPATCHER2_GUID", { 0x950c3a26, 0xe0c2, 0x491c, { 0xb6, 0xb2, 0x03, 0x74, 0xf5, 0xc7, 0x3b, 0x96 } } },
+ { L"SMM_COMMUNICATE_HEADER_GUID", { 0xf328e36c, 0x23b6, 0x4a95, { 0x85, 0x4b, 0x32, 0xe1, 0x95, 0x34, 0xcd, 0x75 } } },
+ { L"SMM_HECI_PROTOCOL_GUID", { 0xfc9a50c1, 0x8b3d, 0x40d0, { 0x99, 0x12, 0x6e, 0x26, 0xd7, 0x89, 0x6c, 0xba } } },
+ { L"SMM_PERFORMANCE_EX_PROTOCOL_GUID", { 0x931fc048, 0xc71d, 0x4455, { 0x89, 0x30, 0x47, 0x06, 0x30, 0xe3, 0x0e, 0xe5 } } },
+ { L"SMM_PERFORMANCE_PROTOCOL_GUID", { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0x0a, 0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } } },
+ { L"SMRAM_CPU_DATA_HEADER_GUID", { 0x5848fd2d, 0xd6af, 0x474b, { 0x82, 0x75, 0x95, 0xdd, 0xe7, 0x0a, 0xe8, 0x23 } } },
+ { L"SMRAM_CPU_DATA_VARIABLE_GUID", { 0x429501d9, 0xe447, 0x40f4, { 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e } } },
+ { L"STATUS_CODE_CALLBACK_GUID", { 0xe701458c, 0x4900, 0x4ca5, { 0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27 } } },
+ { L"SYSTEM_ACCESS_GUID", { 0xe770bb69, 0xbcb4, 0x4d04, { 0x9e, 0x97, 0x23, 0xff, 0x94, 0x56, 0xfe, 0xac } } },
+ { L"TCG_CONFIG_FORM_SET_GUID", { 0xb0f901e4, 0xc424, 0x45de, { 0x90, 0x81, 0x95, 0xe2, 0x0b, 0xde, 0x6f, 0xb5 } } },
+ { L"TCG_EFI_ACPI_TABLE_GUID", { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"TCG_EFI_HOB_LIST_GUID", { 0x7739f24c, 0x93d7, 0x11d4, { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } },
+ { L"TCG_INTERNAL_FLAGS_GUID", { 0x70fff0ff, 0xa543, 0x45b9, { 0x8b, 0xe3, 0x1b, 0xdb, 0x90, 0x41, 0x20, 0x80 } } },
+ { L"TCG_LOCK_DOWN_VAR_GUID", { 0x6e605536, 0xa30a, 0x4d56, { 0x93, 0x9e, 0x1c, 0x37, 0x3f, 0x79, 0x8d, 0x7b } } },
+ { L"TCG_PLATFORM_SETUP_PEI_POLICY_GUID", { 0xa76b4e22, 0xb50a, 0x401d, { 0x8b, 0x35, 0x51, 0x24, 0xb0, 0xba, 0x41, 0x04 } } },
+ { L"TCG_PLATFORM_SETUP_POLICY_GUID", { 0xbb6cbeff, 0xe072, 0x40d2, { 0xa6, 0xeb, 0xba, 0xb7, 0x5b, 0xde, 0x87, 0xe7 } } },
+ { L"TCG_PPI_SYNC_FLAG_GUID", { 0xf3ed95df, 0x828e, 0x41c7, { 0xbc, 0xa0, 0x16, 0xc4, 0x19, 0x65, 0xa6, 0x34 } } },
+ { L"TDTHI_PROTOCOL_FIXED_GUID", { 0xfa8f55e8, 0xab22, 0x42dd, { 0xb9, 0x16, 0x7d, 0xce, 0x39, 0x00, 0x25, 0x74 } } },
+ { L"TDTHI_PROTOCOL_GUID", { 0x3c4852d6, 0xd47b, 0x4f46, { 0xb0, 0x5e, 0xb5, 0xed, 0xc1, 0xaa, 0x43, 0x0a } } },
+ { L"TDT_VOLATILE_SETUP_DATA_GUID", { 0x7b77fb8b, 0x1e0d, 0x4d7e, { 0x95, 0x3f, 0x39, 0x80, 0xa2, 0x61, 0xe0, 0x76 } } },
+ { L"TEMPORARY_RAM_SUPPORT_PPI_GUID", { 0xdbe23aa9, 0xa345, 0x4b97, { 0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89 } } },
+ { L"TERMINAL_VAR_GUID", { 0x560bf58a, 0x1e0d, 0x4d7e, { 0x95, 0x3f, 0x29, 0x80, 0xa2, 0x61, 0xe0, 0x31 } } },
+ { L"TIANO_CUSTOM_DECOMPRESS_GUID", { 0xa31280ad, 0x481e, 0x41b6, { 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } } },
+ { L"TPM_BOOT_FLOW_VARIABLE_GUID", { 0xb6460a49, 0x0ac1, 0x484f, { 0xae, 0x58, 0xf1, 0x6e, 0xb2, 0x39, 0xdb, 0x3d } } },
+ { L"TPM_DEVICE_SELECTED_GUID", { 0x7f4158d3, 0x074d, 0x456d, { 0x8c, 0xb2, 0x01, 0xf9, 0xc8, 0xf7, 0x9d, 0xaa } } },
+ { L"TREE_CONFIG_FORM_SET_GUID", { 0xc54b425f, 0xaa79, 0x48b4, { 0x98, 0x1f, 0x99, 0x8b, 0x3c, 0x4b, 0x64, 0x1c } } },
+ { L"TXT_INFO_HOB_GUID", { 0x2986883f, 0x88e0, 0x48d0, { 0x4b, 0x82, 0x20, 0xc2, 0x69, 0x48, 0xdd, 0xac } } },
+ { L"TXT_ONE_TOUCH_GUID", { 0x3d989471, 0xcfac, 0x46b7, { 0x9b, 0x1c, 0x08, 0x43, 0x01, 0x09, 0x40, 0x2d } } },
+ { L"TXT_ONE_TOUCH_OP_PROTOCOL_GUID", { 0xfa2338ad, 0x80df, 0x49d0, { 0x93, 0x96, 0xcf, 0x71, 0x45, 0xd0, 0x3a, 0x76 } } },
+ { L"UNKNOWN_DEVICE_GUID", { 0xcf31fac5, 0xc24e, 0x11d2, { 0x85, 0xf3, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } } },
+ { L"USB_CREDENTIAL_PROVIDER_GUID", { 0xd0849ed1, 0xa88c, 0x4ba6, { 0xb1, 0xd6, 0xab, 0x50, 0xe2, 0x80, 0xb7, 0xa9 } } },
+ { L"USB_KEYBOARD_LAYOUT_KEY_GUID", { 0x3a4d7a7c, 0x018a, 0x4b42, { 0x81, 0xb3, 0xdc, 0x10, 0xe3, 0xb5, 0x91, 0xbd } } },
+ { L"USB_KEYBOARD_LAYOUT_PACKAGE_GUID", { 0x0c0f3b43, 0x44de, 0x4907, { 0xb4, 0x78, 0x22, 0x5f, 0x6f, 0x62, 0x89, 0xdc } } },
+ { L"USB_TIMING_POLICY_PROTOCOL_GUID", { 0x89e3c1dc, 0xb5e3, 0x4d34, { 0xae, 0xad, 0xdd, 0x7e, 0xb2, 0x82, 0x8c, 0x18 } } },
+ { L"USER_DEFAULTS_GUID", { 0xc4cc0de8, 0x0687, 0x4422, { 0x99, 0xc1, 0x65, 0x35, 0x1a, 0x5d, 0x5f, 0x95 } } },
+ { L"USER_IDENTIFY_MANAGER_GUID", { 0x3ccd3dd8, 0x8d45, 0x4fed, { 0x96, 0x2d, 0x2b, 0x38, 0xcd, 0x82, 0xb3, 0xc4 } } },
+ { L"USER_PROFILE_MANAGER_GUID", { 0xc35f272c, 0x97c2, 0x465a, { 0xa2, 0x16, 0x69, 0x6b, 0x66, 0x8a, 0x8c, 0xfe } } },
+ { L"VIRTUAL_UNCACHED_PAGES_PROTOCOL_GUID", { 0xad651c7d, 0x3c22, 0x4dbf, { 0x92, 0xe8, 0x38, 0xa7, 0xcd, 0xae, 0x87, 0xb2 } } },
+ { L"VLAN_CONFIG_FORM_SET_GUID", { 0xd79df6b0, 0xef44, 0x43bd, { 0x97, 0x97, 0x43, 0xe9, 0x3b, 0xcf, 0x5f, 0xa8 } } },
+ { L"WDT_APP_PROTOCOL_GUID", { 0x92c7d0bb, 0x679e, 0x479d, { 0x87, 0x8d, 0xd4, 0xb8, 0x29, 0x68, 0x57, 0x8b } } },
+ { L"WDT_HOB_GUID", { 0x65675786, 0xacca, 0x4b11, { 0x8a, 0xb7, 0xf8, 0x43, 0xaa, 0x2a, 0x8b, 0xea } } },
+ { L"WDT_PERSISTENT_DATA_GUID", { 0x78ce2354, 0xcfbc, 0x4643, { 0xae, 0xba, 0x07, 0xa2, 0x7f, 0xa8, 0x92, 0xbf } } },
+ { L"WDT_PPI_GUID", { 0xf38d1338, 0xaf7a, 0x4fb6, { 0x91, 0xdb, 0x1a, 0x9c, 0x21, 0x83, 0x57, 0x0d } } },
+ { L"WDT_PROTOCOL_GUID", { 0xb42b8d12, 0x2acb, 0x499a, { 0xa9, 0x20, 0xdd, 0x5b, 0xe6, 0xcf, 0x09, 0xb1 } } },
+ { L"CPU_PEI_BEFORE_MEM_GUID", { 0x1555acf3, 0xbd07, 0x4e88, { 0xb3, 0xa0, 0xb7, 0x7f, 0x78, 0xeb, 0x34, 0xfe } } },
+ { L"CPU_PEI_GUID", { 0x2bb5afa9, 0xff33, 0x417b, { 0x84, 0x97, 0xcb, 0x77, 0x3c, 0x2b, 0x93, 0xbf } } },
+ { L"CPU_DXE_GUID", { 0xe03abadf, 0xe536, 0x4e88, { 0xb3, 0xa0, 0xb7, 0x7f, 0x78, 0xeb, 0x34, 0xfe } } },
+ { L"PCI_OSC_HOST_BUS_GUID", { 0x33db4d5b, 0x1ff7, 0x401c, { 0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66 } } },
+ { L"DEFINE_CpuSsdtTemplate_GUID", { 0x8337f5ab, 0x1ec0, 0x4e64, { 0x97, 0x4a, 0x86, 0xf1, 0xe1, 0x72, 0x42, 0xe1 } } },
+ { L"EistSsdtTemplate_GUID", { 0xafae7706, 0x55b4, 0x4325, { 0xa8, 0x9a, 0x7d, 0x7c, 0x6f, 0x2e, 0x5b, 0x27 } } },
+ { L"CstSsdtTemplate_GUID", { 0xafaebc06, 0x64b4, 0x4123, { 0x55, 0x73, 0x2c, 0x1f, 0x35, 0x89, 0x94, 0x1b } } },
+ { L"EcPs2KbdBin_GUID", { 0x2f72309e, 0xd5b0, 0x4a9d, { 0x84, 0xa9, 0x1a, 0xb3, 0x8c, 0x69, 0x8f, 0x78 } } },
+ { L"SgTpvAcpiS3SaveBin_GUID", { 0xc18b8105, 0xab89, 0x44de, { 0x8d, 0x37, 0x50, 0xb3, 0x1f, 0xae, 0x5d, 0x1e } } },
+ { L"SgTpvPeiBin_GUID", { 0x0e2daf63, 0x8a4f, 0x4026, { 0xa8, 0x99, 0xde, 0x2d, 0x7f, 0x46, 0xe5, 0xec } } },
+ { L"SgTpvDxeBin_GUID", { 0x3fe57ac2, 0xc675, 0x46b1, { 0x84, 0x58, 0xac, 0x62, 0x06, 0x58, 0x84, 0x24 } } },
+ { L"Mxm30DxeBin_GUID", { 0x31a0b6ef, 0xa400, 0x4419, { 0x83, 0x27, 0x0f, 0xb1, 0x34, 0xaa, 0x59, 0xe7 } } },
+ { L"MXMdat_GUID", { 0x6707536e, 0x46af, 0x42d3, { 0x8f, 0x6c, 0x15, 0xf2, 0xf2, 0x02, 0xc2, 0x34 } } },
+ { L"NvOptimusSMMBin_GUID", { 0x8a4e8240, 0x74f8, 0x4024, { 0xae, 0x2b, 0xb3, 0x92, 0x21, 0xc9, 0xfa, 0x59 } } },
+ { L"NVHG_NOTIFY_POLICYCHANGE_GUID", { 0x921a2f40, 0x0dc4, 0x402d, { 0xac, 0x18, 0xb4, 0x84, 0x44, 0xef, 0x9e, 0xd2 } } },
+ { L"NVHG_NOTIFY_POLICYSET_GUID", { 0xc12ad361, 0x9fa9, 0x4c74, { 0x90, 0x1f, 0x95, 0xcb, 0x09, 0x45, 0xcf, 0x3e } } },
+ { L"NVHG_DISPLAY_SCALING_GUID", { 0x42848006, 0x8886, 0x490e, { 0x8c, 0x72, 0x2b, 0xdc, 0xa9, 0x3a, 0x8a, 0x09 } } },
+ { L"ACPI_NOTIFY_PANEL_SWITCH_GUID", { 0xe06bde62, 0xee75, 0x48f4, { 0xa5, 0x83, 0xb2, 0x3e, 0x69, 0xab, 0xf8, 0x91 } } },
+ { L"ACPI_NOTIFY_DEVICE_HOTPLUG_GUID", { 0x3adebd0f, 0x0c5f, 0x46ed, { 0xab, 0x2e, 0x04, 0x96, 0x2b, 0x4f, 0xdc, 0xbc } } },
+ { L"ACPI_NOTIFY_INC_BRIGHTNESS_HOTKEY_GUID", { 0x1e519311, 0x3e75, 0x4208, { 0xb0, 0x5e, 0xeb, 0xe1, 0x7e, 0x3f, 0xf4, 0x1f } } },
+ { L"ACPI_NOTIFY_DEC_BRIGHTNESS_HOTKEY_GUID", { 0x37f85341, 0x4418, 0x4f24, { 0x85, 0x33, 0x38, 0xff, 0xc7, 0x29, 0x55, 0x42 } } },
+ { L"Ventura_DSM_GUID", { 0x95db88fd, 0x940a, 0x4253, { 0xa4, 0x46, 0x70, 0xce, 0x05, 0x04, 0xae, 0xdf } } },
+ { L"SG_dGPU_GUID", { 0x9d95a0a0, 0x0060, 0x4d48, { 0xb3, 0x4d, 0x7e, 0x5f, 0xea, 0x12, 0x9f, 0xd4 } } },
+ { L"NBCI_GUID", { 0xd4a50b75, 0x65c7, 0x46f7, { 0xbf, 0xb7, 0x41, 0x51, 0x4c, 0xea, 0x02, 0x44 } } },
+ { L"Ventura_GUID", { 0x95db88fd, 0x940a, 0x4253, { 0xa4, 0x46, 0x70, 0xce, 0x05, 0x04, 0xae, 0xdf } } },
+ { L"Optimus_DSM_GUID", { 0xa486d8f8, 0x0bda, 0x471b, { 0xa7, 0x2b, 0x60, 0x42, 0xa6, 0xb5, 0xbe, 0xe0 } } },
+ { L"ECBin_GUID", { 0x41015350, 0xba3b, 0x4916, { 0xb0, 0x43, 0x46, 0x15, 0x40, 0x8a, 0x87, 0xb3 } } },
+ { L"ECSMIBin_GUID", { 0xe7e63dd1, 0xe89f, 0x4845, { 0x9e, 0x4a, 0xb6, 0x09, 0x52, 0xb3, 0x58, 0x9c } } },
+ { L"TXTWrapperPeiBin_GUID", { 0x6b789215, 0xb063, 0x45fd, { 0x86, 0x8a, 0x66, 0x8a, 0x49, 0xf0, 0x0e, 0xc6 } } },
+ { L"TXTWrapperDxeBin_GUID", { 0x87d402cd, 0x8b07, 0x4b93, { 0xb3, 0x8b, 0xf8, 0x79, 0x9f, 0x28, 0xb0, 0x33 } } },
+ { L"MePciPlatformBin_GUID", { 0x459c70c3, 0x9344, 0x4484, { 0x9f, 0x93, 0x78, 0x22, 0x53, 0x0d, 0x0d, 0x11 } } },
+ { L"IccOverClocking_GUID", { 0x5bba83e5, 0xf027, 0x4ca7, { 0xbf, 0xd0, 0x16, 0x35, 0x8c, 0xc9, 0xe1, 0x23 } } },
+ { L"IccPlatform_Bin_GUID", { 0x14257b56, 0xbda2, 0x4faf, { 0x8e, 0x4f, 0xc8, 0x85, 0xdf, 0x75, 0x58, 0x3c } } },
+ { L"MePlatformPolicyBin_GUID", { 0xba67550c, 0x3628, 0x4137, { 0xa5, 0x3e, 0x42, 0x66, 0x0e, 0x08, 0x16, 0x04 } } },
+ { L"AmtSmbiosBin_GUID", { 0xa8c67255, 0xe029, 0x4b1a, { 0x96, 0x8e, 0xec, 0xa6, 0xe9, 0xc1, 0x1c, 0x73 } } },
+ { L"AmtPlatformPolicyBin_GUID", { 0x1be65202, 0x9318, 0x492d, { 0xa5, 0x51, 0x08, 0xdf, 0x2b, 0xd6, 0x0a, 0xee } } },
+ { L"AMTLOCKKBDBin_GUID", { 0x5507247a, 0x846b, 0x4f22, { 0xb5, 0x5f, 0x72, 0xb4, 0x04, 0x94, 0x35, 0xef } } },
+ { L"AmtWrapperDxeBin_GUID", { 0xd77c900d, 0xa1c7, 0x41c5, { 0xb9, 0x89, 0x0c, 0x3d, 0x37, 0xfc, 0xa4, 0x32 } } },
+ { L"AmtPetAlertBin_GUID", { 0x290ea249, 0x6e88, 0x423c, { 0xb0, 0xda, 0x75, 0xcd, 0xde, 0x79, 0x20, 0xcc } } },
+ { L"AsfTableBin_GUID", { 0xe72527cf, 0x505b, 0x4b50, { 0x99, 0xcd, 0xa3, 0x24, 0x67, 0xfa, 0x4a, 0xa4 } } },
+ { L"AmtSetupBin_GUID", { 0x773cb08b, 0x511a, 0x4bd5, { 0x85, 0xad, 0x41, 0xd4, 0xf4, 0xb6, 0x4a, 0x52 } } },
+ { L"ASFVERBBin_GUID", { 0x4f4ff580, 0xb8a0, 0x4332, { 0xa6, 0xb0, 0xe2, 0xe5, 0x68, 0xe3, 0x6c, 0x9c } } },
+ { L"TdtWrapperBin_GUID", { 0xca5e3df0, 0x940a, 0x48f1, { 0x8c, 0x14, 0xdb, 0x2f, 0xb5, 0x99, 0x8b, 0x36 } } },
+ { L"MeSpiRegionBin_GUID", { 0x10654683, 0xe6cb, 0x49f6, { 0x99, 0xed, 0x1b, 0x23, 0xa2, 0xce, 0xfc, 0x09 } } },
+ { L"SmmMeSpiRegionBin_GUID", { 0x0eb9d3ed, 0xc4d3, 0x4d9a, { 0xb2, 0x91, 0xac, 0x3b, 0xc9, 0xc3, 0xc8, 0xfb } } },
+ { L"AmtSmbios131Bin_GUID", { 0x2b341c7b, 0x0b32, 0x4a65, { 0x9d, 0x46, 0xe1, 0xb3, 0xab, 0xd4, 0xc2, 0x5c } } },
+ { L"ACPI20_DSDT_GUID", { 0x11d8ac35, 0xfb8a, 0x44d1, { 0x8d, 0x09, 0x0b, 0x56, 0x06, 0xd3, 0x21, 0xb9 } } },
+ { L"ACPIBin_GUID", { 0x16d0a23e, 0xc09c, 0x407d, { 0xa1, 0x4a, 0xad, 0x05, 0x8f, 0xdd, 0x0c, 0xa1 } } },
+ { L"SmbiosDMIEditBoardBin_GUID", { 0xaf382531, 0x52e6, 0x4cc4, { 0xb2, 0x47, 0xdb, 0x8e, 0x32, 0x0c, 0xbb, 0xa3 } } },
+ { L"SMBiosStaticData_SECTION_GUID", { 0xab56dc60, 0x0057, 0x11da, { 0xa8, 0xdb, 0x00, 0x01, 0x02, 0xee, 0xe6, 0x26 } } },
+ { L"SMBiosBoardBin_GUID", { 0xcef68c66, 0x06ab, 0x4fb3, { 0xa3, 0xed, 0x5f, 0xfa, 0x88, 0x5b, 0x57, 0x25 } } },
+ { L"DtsDxePolicyInit_FILE_GUID", { 0x09767db6, 0x412a, 0x45ba, { 0x80, 0x26, 0xf0, 0x87, 0xca, 0xe2, 0x10, 0xe3 } } },
+ { L"AmiDtsPolicyBin_GUID", { 0x1ab12a1b, 0xeebd, 0x33f0, { 0x8b, 0x3c, 0xa1, 0x45, 0xb8, 0xbe, 0x3f, 0xf0 } } },
+ { L"SetupBin_GUID", { 0x899407d7, 0x99fe, 0x43d8, { 0x9a, 0x21, 0x79, 0xec, 0x32, 0x8c, 0xac, 0x21 } } },
+ { L"AmiPpmPolicyBin_GUID", { 0x1ce12314, 0xafbc, 0x11f0, { 0x8a, 0x3e, 0xab, 0x44, 0xb8, 0xee, 0x31, 0x20 } } },
+ { L"PpmPolicyInitDxe_FILE_GUID", { 0x2df10014, 0xcf21, 0x4280, { 0x8c, 0x3f, 0xe5, 0x39, 0xb8, 0xee, 0x51, 0x50 } } },
+ { L"DPPM_ACPI_TABLE_STORAGE_GUID", { 0xd8de84b4, 0x223e, 0x4aa9, { 0xa7, 0xb3, 0x7f, 0x17, 0x13, 0x76, 0x8d, 0xb2 } } },
+ { L"Dppm_FILE_GUID", { 0x42a78463, 0x8175, 0x406a, { 0xb5, 0x63, 0x75, 0x8a, 0xda, 0x64, 0x5e, 0xbc } } },
+ { L"AcpiPlatformBin_GUID", { 0x8b5fbabd, 0xf51f, 0x4942, { 0xbf, 0x16, 0x16, 0xaa, 0xa3, 0x8a, 0xe5, 0x2b } } },
+ { L"SMBIOSUpdateDataBin_GUID", { 0xb98999a4, 0xe96f, 0x475a, { 0x99, 0xfc, 0x76, 0x21, 0x26, 0xf5, 0x0f, 0x5a } } },
+ { L"PlatformInfoBin_GUID", { 0x1314216c, 0xcb8d, 0x421c, { 0xb8, 0x54, 0x06, 0x23, 0x13, 0x86, 0xe6, 0x42 } } },
+ { L"AMI_EFI_SOL_POST_MESSAGE_GUID", { 0xf42f3752, 0x012e, 0x4812, { 0x99, 0xe6, 0x49, 0xf9, 0x43, 0x04, 0x84, 0x54 } } },
+ { L"DXE_CPU_INT_LIB_GUID", { 0x1ba0062e, 0xc779, 0x4582, { 0x85, 0x66, 0x33, 0x6a, 0xe8, 0xf7, 0x8f, 0x09 } } },
+ { L"FastBootPeiBin_GUID", { 0x333bb2a3, 0x4f20, 0x4ccc, { 0xac, 0x38, 0x06, 0x72, 0xd7, 0x41, 0x23, 0x45 } } },
+ { L"LegacyRegionBin_GUID", { 0x59242dd8, 0xe7cf, 0x4979, { 0xb6, 0x0e, 0xa6, 0x06, 0x7e, 0x2a, 0x18, 0x5f } } },
+ { L"UpdateMemoryRecordBin_GUID", { 0x24ccd374, 0x3df6, 0x4181, { 0x86, 0xf6, 0xe3, 0xc6, 0x69, 0x20, 0xa1, 0x45 } } },
+ { L"SmBiosMemoryBin_GUID", { 0xeda39402, 0xf375, 0x4496, { 0x92, 0xd3, 0x83, 0xb4, 0x3c, 0xb8, 0xa7, 0x6a } } },
+ { L"SmmChildDispatcherBin_GUID", { 0x753630c9, 0xfae5, 0x47a9, { 0xbb, 0xbf, 0x88, 0xd6, 0x21, 0xcd, 0x72, 0x82 } } },
+ { L"LegacyInterruptBin_GUID", { 0x71ed12d1, 0x250b, 0x42fb, { 0x8c, 0x17, 0x10, 0xdc, 0xfa, 0x77, 0x17, 0x01 } } },
+ { L"SBSMIBin_GUID", { 0x7b8db049, 0xc7c7, 0x4d3b, { 0x80, 0x9f, 0x92, 0x6d, 0xee, 0x47, 0xcc, 0xa2 } } },
+ { L"AcpiModeEnableBin_GUID", { 0x750890a6, 0x7acf, 0x4f4f, { 0x81, 0xbd, 0xb4, 0x00, 0xc2, 0xbe, 0xa9, 0x5a } } },
+ { L"PowerButtonBin_GUID", { 0xe566b097, 0x4378, 0x485f, { 0x91, 0xd0, 0x1c, 0x09, 0x7c, 0x19, 0x0c, 0xe2 } } },
+ { L"SleepSmiBin_GUID", { 0x6298fe18, 0xd5ef, 0x42b7, { 0xbb, 0x0c, 0x29, 0x53, 0x28, 0x3f, 0x57, 0x04 } } },
+ { L"WdtAppDxe_Bin_GUID", { 0xce366d33, 0xb057, 0x4c03, { 0x85, 0x61, 0xca, 0xf1, 0x77, 0x38, 0xb6, 0x6f } } },
+ { L"WdtAppPeiBin_GUID", { 0x0f69f6d7, 0x0e4b, 0x43a6, { 0xbf, 0xc2, 0x68, 0x71, 0x69, 0x43, 0x69, 0xb0 } } },
+ { L"PciHotPlugBin_GUID", { 0x3022e512, 0xb94a, 0x4f12, { 0x80, 0x6d, 0x7e, 0xf1, 0x17, 0x78, 0x99, 0xd8 } } },
+ { L"PchSpiWrapBin_GUID", { 0xb716a6f8, 0xf3a1, 0x4b8e, { 0x85, 0x82, 0x5a, 0x30, 0x3f, 0x1c, 0xdd, 0x64 } } },
+ { L"SignONPack_GUID", { 0x2ebe0275, 0x6458, 0x4af9, { 0x91, 0xed, 0xd3, 0xf4, 0xed, 0xb1, 0x00, 0xaa } } },
+ { L"AMICspLibDxe_GUID", { 0xcd84562c, 0x6864, 0x40a3, { 0xa0, 0x81, 0xc8, 0xd3, 0x5e, 0x82, 0xb9, 0x20 } } },
+ { L"MicrocodeUpdateBin_GUID", { 0xf3331de6, 0x4a55, 0x44e4, { 0xb7, 0x67, 0x74, 0x53, 0xf7, 0xa1, 0xa0, 0x21 } } },
+ { L"CORE_DXEBin_GUID", { 0x5ae3f37e, 0x4eae, 0x41ae, { 0x82, 0x40, 0x35, 0x46, 0x5b, 0x5e, 0x81, 0xeb } } },
+ { L"NVRAM_FFS_GUID", { 0xcef5b9a3, 0x476d, 0x497f, { 0x9f, 0xdc, 0xe9, 0x81, 0x43, 0xe0, 0x42, 0x2c } } },
+ { L"IdeSMARTBin_GUID", { 0xd57c852e, 0x809f, 0x45cf, { 0xa3, 0x77, 0xd7, 0x7b, 0xc0, 0xcb, 0x78, 0xee } } },
+ { L"AhciSmmBin_GUID", { 0xbc3245bd, 0xb982, 0x4f55, { 0x9f, 0x79, 0x05, 0x6a, 0xd7, 0xe9, 0x87, 0xc5 } } },
+ { L"AhciBin_GUID", { 0x8f5a2e02, 0x538c, 0x4d59, { 0xb9, 0x20, 0xc4, 0x78, 0x6a, 0xcb, 0xc5, 0x52 } } },
+ { L"CSMCOREBin_GUID", { 0xa062cf1f, 0x8473, 0x4aa3, { 0x87, 0x93, 0x60, 0x0b, 0xc4, 0xff, 0xe9, 0xa8 } } },
+ { L"CSMCOREBin_GUID", { 0xe6f4f8f7, 0x4992, 0x47b2, { 0x83, 0x02, 0x85, 0x08, 0x74, 0x5e, 0x4a, 0x23 } } },
+ { L"x86Thunk_ffs_GUID", { 0xa08276ec, 0xa0fe, 0x4e06, { 0x86, 0x70, 0x38, 0x53, 0x36, 0xc7, 0xd0, 0x93 } } },
+ { L"CsmVideoBin_GUID", { 0x29cf55f8, 0xb675, 0x4f5d, { 0x8f, 0x2f, 0xb8, 0x7a, 0x3e, 0xcf, 0xd0, 0x63 } } },
+ { L"CsmBlockIoBin_GUID", { 0x25acf158, 0xdd61, 0x4e64, { 0x9a, 0x49, 0x55, 0x85, 0x1e, 0x9a, 0x26, 0xc7 } } },
+ { L"PeiRamBootBin_GUID", { 0x08efd15d, 0xec55, 0x4023, { 0xb6, 0x48, 0x7b, 0xa4, 0x0d, 0xf7, 0xd0, 0x5d } } },
+ { L"PeiRamBootCacheRdyBin_GUID", { 0xa6a3a962, 0xc591, 0x4701, { 0x9d, 0x25, 0x73, 0xd0, 0x22, 0x6d, 0x89, 0xdc } } },
+ { L"SmmDispatcherBin_GUID", { 0x4a37320b, 0x3fb3, 0x4365, { 0x97, 0x30, 0x9e, 0x89, 0xc6, 0x00, 0x39, 0x5d } } },
+ { L"SmmEntryBin_GUID", { 0xd2596f82, 0xf0e1, 0x49fa, { 0x95, 0xbc, 0x62, 0x01, 0x2c, 0x79, 0x57, 0x28 } } },
+ { L"SmmBaseBin_GUID", { 0xd0632c90, 0xafd7, 0x4492, { 0xb1, 0x86, 0x25, 0x7c, 0x63, 0x14, 0x3c, 0x61 } } },
+ { L"TERMINALBIN_GUID", { 0x7a08cb98, 0xe9bc, 0x41c3, { 0xbe, 0x19, 0xb3, 0x02, 0xf3, 0xf1, 0xf5, 0x95 } } },
+ { L"tcgdxeBin_GUID", { 0x5e9caba3, 0xf2b1, 0x497a, { 0xad, 0xac, 0x24, 0xf5, 0x75, 0xe9, 0xcd, 0xe9 } } },
+ { L"MPTPM_ffs_GUID", { 0x7d113aa9, 0x6280, 0x48c6, { 0xba, 0xce, 0xdf, 0xe7, 0x66, 0x8e, 0x83, 0x07 } } },
+ { L"TPM32BIN_ffs_GUID", { 0x0aa31bc6, 0x3379, 0x41e8, { 0x82, 0x5a, 0x53, 0xf8, 0x2c, 0xc0, 0xf2, 0x54 } } },
+ { L"LEGX16_ffs_GUID", { 0x142204e2, 0xc7b1, 0x4af9, { 0xa7, 0x29, 0x92, 0x37, 0x58, 0xd9, 0x6d, 0x03 } } },
+ { L"TcgLegacyBIN_GUID", { 0x858ebe6f, 0x360f, 0x415b, { 0xb7, 0xdc, 0x46, 0x3a, 0xae, 0xb0, 0x34, 0x12 } } },
+ { L"TCGSmmBin_GUID", { 0xfd93f9e1, 0x3c73, 0x46e0, { 0xb7, 0xb8, 0x2b, 0xba, 0x3f, 0x71, 0x8f, 0x6c } } },
+ { L"TcgPeiBin_GUID", { 0x34989d8e, 0x930a, 0x4a95, { 0xab, 0x04, 0x2e, 0x6c, 0xfd, 0xff, 0x66, 0x31 } } },
+ { L"OFBDBin_GUID", { 0x57e56594, 0xce95, 0x46ad, { 0x95, 0x31, 0x3c, 0x49, 0x31, 0x0c, 0xa7, 0xce } } },
+ { L"AMITSEBin_GUID", { 0xb1da0adf, 0x4f77, 0x4070, { 0xa8, 0x8e, 0xbf, 0xfe, 0x1c, 0x60, 0x52, 0x9a } } },
+ { L"AMITSEBin_GUID", { 0xfe612b72, 0x203c, 0x47b1, { 0x85, 0x60, 0xa6, 0x6d, 0x94, 0x6e, 0xb3, 0x71 } } },
+ { L"SmLogo_ffs_GUID", { 0x294b1cef, 0x9beb, 0x42d5, { 0x99, 0x71, 0x0c, 0x89, 0x63, 0xcd, 0xaf, 0x02 } } },
+ { L"SignONPack_GUID", { 0xa59a0056, 0x3341, 0x44b5, { 0x9c, 0x9c, 0x6d, 0x76, 0xf7, 0x67, 0x38, 0x17 } } },
+ { L"UhcipeiUsbBin_GUID", { 0x6895f6f0, 0x8879, 0x45b8, { 0xa9, 0xd9, 0x96, 0x39, 0xe5, 0x32, 0x31, 0x9e } } },
+ { L"UhcPeimBin_GUID", { 0xc463ceac, 0xfc57, 0x4f36, { 0x88, 0xb7, 0x35, 0x6c, 0x75, 0x0c, 0x3b, 0xca } } },
+ { L"OhciPeiBin_GUID", { 0x52daa304, 0xdeb3, 0x449b, { 0xaf, 0xb8, 0xa8, 0x8a, 0x54, 0xf2, 0x8f, 0x95 } } },
+ { L"XhciPeiBin_GUID", { 0x45d68db9, 0x8b4e, 0x48c0, { 0x99, 0xe9, 0xf2, 0x1f, 0x26, 0x2d, 0xb6, 0x53 } } },
+ { L"EhciPeiBin_GUID", { 0xd56a4094, 0x570f, 0x4d3d, { 0x8f, 0x5f, 0x8d, 0x8a, 0xa0, 0xb3, 0x96, 0xcb } } },
+ { L"UsbBotPeimSrcBin_GUID", { 0x8401a046, 0x6f70, 0x4505, { 0x84, 0x71, 0x70, 0x15, 0xb4, 0x03, 0x55, 0xe3 } } },
+ { L"FloppyCtrlBin_GUID", { 0x8b9d3ee0, 0x4ba4, 0x433b, { 0x9c, 0x48, 0x4e, 0x83, 0x0b, 0x3b, 0x40, 0xfd } } },
+ { L"FileSystemBin_GUID", { 0x93022f8c, 0x1f09, 0x47ef, { 0xbb, 0xb2, 0x58, 0x14, 0xff, 0x60, 0x9d, 0xf5 } } },
+ { L"LEGACYSREDIRBin_GUID", { 0x4a3602bc, 0x1a05, 0x4c82, { 0x99, 0xb4, 0x58, 0x8c, 0xd2, 0xa3, 0x2c, 0xd5 } } },
+ { L"LEGACYSREDIRBin_GUID", { 0x9ba21891, 0x7e7d, 0x4e94, { 0xb8, 0xdf, 0xf4, 0xd2, 0xd3, 0x20, 0x80, 0x1c } } },
+ { L"ReFlashBin_GUID", { 0x70e1a818, 0x0be1, 0x4449, { 0xbf, 0xd4, 0x9e, 0xf6, 0x8c, 0x7f, 0x02, 0xa8 } } },
+ { L"RecoveryBin_GUID", { 0xe008b434, 0x0e73, 0x440c, { 0x86, 0x12, 0xa1, 0x43, 0xf6, 0xa0, 0x7b, 0xcb } } },
+ { L"PciBusBin_GUID", { 0x3c1de39f, 0xd207, 0x408a, { 0xaa, 0xcc, 0x73, 0x1c, 0xfb, 0x7f, 0x1d, 0xd7 } } },
+ { L"PciRootBridgeBin_GUID", { 0x80e66e0a, 0xccd1, 0x43fa, { 0xa7, 0xb1, 0x2d, 0x5e, 0xe0, 0xf1, 0x39, 0x10 } } },
+ { L"SmbiosDMIEditBin_GUID", { 0xe2a74738, 0x8934, 0x48f5, { 0x84, 0x12, 0x99, 0xe9, 0x48, 0xc8, 0xdc, 0x1b } } },
+ { L"SmbiosGetFlashDataBin_GUID", { 0xded7956d, 0x7e20, 0x4f20, { 0x91, 0xa1, 0x19, 0x04, 0x39, 0xb0, 0x4d, 0x5b } } },
+ { L"SMBiosBin_GUID", { 0xb13edd38, 0x684c, 0x41ed, { 0xa3, 0x05, 0xd7, 0xb7, 0xe3, 0x24, 0x97, 0xdf } } },
+ { L"AmiBoardInfoBin_GUID", { 0x9f3a0016, 0xae55, 0x4288, { 0x82, 0x9d, 0xd2, 0x2f, 0xd3, 0x44, 0xc3, 0x47 } } },
+ { L"RUNTIMEBin_GUID", { 0xcbc59c4a, 0x383a, 0x41eb, { 0xa8, 0xee, 0x44, 0x98, 0xae, 0xa5, 0x67, 0xe4 } } },
+ { L"IDEBusBin_GUID", { 0x59b90a53, 0x461b, 0x4c50, { 0xa7, 0x9f, 0xa3, 0x27, 0x73, 0xc3, 0x19, 0xae } } },
+ { L"CmosManagerSmmBin_GUID", { 0x6869c5b3, 0xac8d, 0x4973, { 0x8b, 0x37, 0xe3, 0x54, 0xdb, 0xf3, 0x4a, 0xdd } } },
+ { L"PeiDbgIDTBin_GUID", { 0x811b4f4d, 0xfb0b, 0x4008, { 0xa4, 0x2b, 0xe5, 0x51, 0xfd, 0x4a, 0x0f, 0x28 } } },
+ { L"PeiDbgXportBin_GUID", { 0xc7e8bb67, 0x1c3f, 0x41ba, { 0x82, 0x0f, 0x3d, 0x0e, 0x9c, 0x36, 0x50, 0x42 } } },
+ { L"PeiDbgDbgrBin_GUID", { 0x4aaaae15, 0x5aeb, 0x4c11, { 0xb9, 0x1d, 0xa3, 0x96, 0x6a, 0xc0, 0x48, 0x47 } } },
+ { L"PeiDebugSupportBin_GUID", { 0xa47438d5, 0x94e9, 0x49b3, { 0xbc, 0x31, 0x7e, 0x6b, 0xc9, 0x36, 0x38, 0x14 } } },
+ { L"PeiDbgPortBin_GUID", { 0xeb7d9740, 0xdb60, 0x45c2, { 0xa7, 0xa0, 0xc2, 0x71, 0x4e, 0xf4, 0xeb, 0x56 } } },
+ { L"PeiDbgXportx64Bin_GUID", { 0x511d0266, 0xf2e0, 0x4df8, { 0xae, 0x3a, 0xfd, 0xb9, 0x85, 0x23, 0xbf, 0xb9 } } },
+ { L"PeiDbgDbgrx64Bin_GUID", { 0xc253ed0a, 0xc48b, 0x4ee3, { 0xa6, 0x5e, 0x75, 0xf6, 0x1f, 0x3a, 0xd2, 0x51 } } },
+ { L"IdeSMMBin_GUID", { 0x316b1230, 0x0500, 0x4592, { 0x8c, 0x09, 0xea, 0xba, 0x0f, 0xb6, 0xb0, 0x7f } } },
+ { L"IdeSecurityBin_GUID", { 0xa9b700cf, 0x019e, 0x4d8b, { 0xa3, 0xa7, 0x88, 0xe1, 0xea, 0x01, 0x69, 0x9e } } },
+ { L"SMIFlashBin_GUID", { 0xbc327dbd, 0xb982, 0x4f55, { 0x9f, 0x79, 0x05, 0x6a, 0xd7, 0xe9, 0x87, 0xc5 } } },
+ { L"S3SaveBin_GUID", { 0x26a2481e, 0x4424, 0x46a2, { 0x99, 0x43, 0xcc, 0x40, 0x39, 0xea, 0xd8, 0xf8 } } },
+ { L"S3RestoreBin_GUID", { 0xefd652cc, 0x0e99, 0x40f0, { 0x96, 0xc0, 0xe0, 0x8c, 0x08, 0x90, 0x70, 0xfc } } },
+ { L"USBRTBin_GUID", { 0x04eaaaa1, 0x29a1, 0x11d7, { 0x88, 0x38, 0x00, 0x50, 0x04, 0x73, 0xd4, 0xeb } } },
+ { L"USBI13_GUID", { 0x4c006cd9, 0x19ba, 0x4617, { 0x84, 0x83, 0x60, 0x91, 0x94, 0xa1, 0xac, 0xfc } } },
+ { L"UHCDBin_GUID", { 0x580dd900, 0x385d, 0x11d7, { 0x88, 0x3a, 0x00, 0x50, 0x04, 0x73, 0xd4, 0xeb } } },
+ { L"CORE_PEIBin_GUID", { 0x92685943, 0xd810, 0x47ff, { 0xa1, 0x12, 0xcc, 0x84, 0x90, 0x77, 0x6a, 0x1f } } },
+ { L"DigitalThermalSensorSmmBin_GUID", { 0x77a6009e, 0x116e, 0x464d, { 0x8e, 0xf8, 0xb3, 0x52, 0x01, 0xa0, 0x22, 0xdd } } },
+ { L"SwitchableGraphicsDxeBin_GUID", { 0x0d82a9ec, 0x1289, 0x4fd4, { 0xac, 0x0b, 0x4c, 0x6b, 0x1a, 0x25, 0xab, 0xc6 } } },
+ { L"SgDxePolicyInitBin_GUID", { 0x63b2bc2d, 0xdf5d, 0x419b, { 0x87, 0x3c, 0x2c, 0x78, 0xa6, 0x60, 0x4a, 0x7a } } },
+ { L"SgPeiPolicyInitBin_GUID", { 0x1e75e77f, 0x8a15, 0x4653, { 0x96, 0x4d, 0x54, 0x2c, 0x15, 0x7e, 0xf4, 0x0a } } },
+ { L"SwitchableGraphicsPeiBin_GUID", { 0x7ede6a1f, 0x548e, 0x453e, { 0xa9, 0x5c, 0x66, 0x93, 0x9f, 0xe0, 0x29, 0x5c } } },
+ { L"TxtDxeBin_GUID", { 0xff917e22, 0xa228, 0x448d, { 0xbd, 0xaa, 0x68, 0xef, 0xcc, 0xdd, 0xa5, 0xd3 } } },
+ { L"TxtPeiBin_GUID", { 0xca9d8617, 0xd652, 0x403b, { 0xb6, 0xc5, 0xba, 0x47, 0x57, 0x01, 0x16, 0xad } } },
+ { L"PciExpressDxeBin_GUID", { 0xa89ec8e0, 0x0ba1, 0x40aa, { 0xa0, 0x3e, 0xab, 0xdd, 0xa5, 0x29, 0x5c, 0xde } } },
+ { L"SmmAccessBin_GUID", { 0x1323c7f8, 0xdad5, 0x4126, { 0xa5, 0x4b, 0x7a, 0x05, 0xfb, 0xf4, 0x15, 0x15 } } },
+ { L"MemoryInitBin_GUID", { 0x3b42ef57, 0x16d3, 0x44cb, { 0x86, 0x32, 0x9f, 0xdb, 0x06, 0xb4, 0x14, 0x51 } } },
+ { L"SaInitDxeBin_GUID", { 0xde23acee, 0xcf55, 0x4fb6, { 0xaa, 0x77, 0x98, 0x4a, 0xb5, 0x3d, 0xe8, 0x11 } } },
+ { L"PchInitDxeBin_GUID", { 0xde23acee, 0xcf55, 0x4fb6, { 0xaa, 0x77, 0x98, 0x4a, 0xb5, 0x3d, 0xe8, 0x23 } } },
+ { L"CvInitDxeBin_GUID", { 0xde23acee, 0xcf55, 0x4fb6, { 0xaa, 0x77, 0x98, 0x4a, 0xb5, 0x3d, 0xe8, 0x11 } } },
+ { L"SaInitPeimBin_GUID", { 0xfd236ae7, 0x0791, 0x48c4, { 0xb2, 0x9e, 0x29, 0xbd, 0xee, 0xe1, 0xa8, 0x11 } } },
+ { L"PchInitPeimBin_GUID", { 0xfd236ae7, 0x0791, 0x48c4, { 0xb2, 0x9e, 0x29, 0xbd, 0xee, 0xe1, 0xa8, 0x38 } } },
+ { L"CvInitPeimBin_GUID", { 0xfd236ae7, 0x0791, 0x48c4, { 0xb2, 0x9e, 0x29, 0xbd, 0xee, 0xe1, 0xa8, 0x11 } } },
+ { L"IchInitPeimBin_GUID", { 0xfd236ae7, 0x0791, 0x48c4, { 0xb2, 0x9e, 0x29, 0xbd, 0xee, 0xe1, 0xa8, 0x38 } } },
+ { L"SaAcpiTables_ffs_GUID", { 0x27e569d5, 0x0afc, 0x4d8f, { 0x8c, 0x90, 0x78, 0x3a, 0xc4, 0xa3, 0x18, 0xab } } },
+ { L"PciHostBridgeBin_GUID", { 0x8d6756b9, 0xe55e, 0x4d6a, { 0xa3, 0xa5, 0x5e, 0x4d, 0x72, 0xdd, 0xf7, 0x72 } } },
+ { L"SataControllerBin_GUID", { 0xbb65942b, 0x521f, 0x4ec3, { 0xba, 0xf9, 0xa9, 0x25, 0x40, 0xcf, 0x60, 0xd2 } } },
+ { L"SmmControlBin_GUID", { 0xa0bad9f7, 0xab78, 0x491b, { 0xb5, 0x83, 0xc5, 0x2b, 0x7f, 0x84, 0xb9, 0xe0 } } },
+ { L"PchResetBin_GUID", { 0xbb1fbd4f, 0x2e30, 0x4793, { 0x9b, 0xed, 0x74, 0xf6, 0x72, 0xbc, 0x8f, 0xfe } } },
+ { L"PchSmbusDxeBin_GUID", { 0xe052d8a6, 0x224a, 0x4c32, { 0x8d, 0x37, 0x2e, 0x0a, 0xe1, 0x62, 0x36, 0x4d } } },
+ { L"DxeIchSmbusBin_GUID", { 0xe052d8a6, 0x224a, 0x4c32, { 0x8d, 0x37, 0x2e, 0x0a, 0xe1, 0x62, 0x36, 0x4d } } },
+ { L"PchSmbusSmmBin_GUID", { 0x59287178, 0x59b2, 0x49ca, { 0xbc, 0x63, 0x53, 0x2b, 0x12, 0xea, 0x2c, 0x53 } } },
+ { L"PchSmbusArpDisabledBin_GUID", { 0x643df777, 0xf312, 0x42ed, { 0x81, 0xcc, 0x1b, 0x1f, 0x57, 0xe1, 0x8a, 0xd6 } } },
+ { L"IchSmbusArpDisabledBin_GUID", { 0x643df777, 0xf312, 0x42ed, { 0x81, 0xcc, 0x1b, 0x1f, 0x57, 0xe1, 0x8a, 0xd6 } } },
+ { L"PchSmbusArpEnabledBin_GUID", { 0x22b194b4, 0xcc0e, 0x46c7, { 0x9f, 0xce, 0xda, 0x10, 0xd6, 0xed, 0x17, 0x31 } } },
+ { L"WdtDxeBin_GUID", { 0x5aab83e5, 0xf027, 0x4ca7, { 0xbf, 0xd0, 0x16, 0x35, 0x8c, 0xc9, 0xe4, 0x53 } } },
+ { L"WdtPeiBin_GUID", { 0x1d88c542, 0x9df7, 0x424a, { 0xaa, 0x90, 0x02, 0xb6, 0x1f, 0x28, 0x69, 0x38 } } },
+ { L"PchPcieSmmBin_GUID", { 0xacaeaa7a, 0xc039, 0x4424, { 0x88, 0xda, 0xf4, 0x22, 0x12, 0xea, 0x0e, 0x55 } } },
+ { L"SmartTimerBin_GUID", { 0x90cb75db, 0x71fc, 0x489d, { 0xaa, 0xcf, 0x94, 0x34, 0x77, 0xec, 0x72, 0x12 } } },
+ { L"PchSpiSmmBin_GUID", { 0x27f4917b, 0xa707, 0x4aad, { 0x96, 0x76, 0x26, 0xdf, 0x16, 0x8c, 0xbf, 0x0d } } },
+ { L"IchSpiSmmBin_GUID", { 0x27f4917b, 0xa707, 0x4aad, { 0x96, 0x76, 0x26, 0xdf, 0x16, 0x8c, 0xbf, 0x0d } } },
+ { L"PchSpiPeimBin_GUID", { 0xaa652cb9, 0x2d52, 0x4624, { 0x9f, 0xae, 0xd4, 0xe5, 0x8b, 0x67, 0xca, 0x46 } } },
+ { L"IchSpiPeimBin_GUID", { 0xaa652cb9, 0x2d52, 0x4624, { 0x9f, 0xae, 0xd4, 0xe5, 0x8b, 0x67, 0xca, 0x46 } } },
+ { L"PchSpiRuntimeBin_GUID", { 0xc194c6ea, 0xb68c, 0x4981, { 0xb6, 0x4b, 0x9b, 0xd2, 0x71, 0x47, 0x4b, 0x20 } } },
+ { L"IchSpiRuntimeBin_GUID", { 0xc194c6ea, 0xb68c, 0x4981, { 0xb6, 0x4b, 0x9b, 0xd2, 0x71, 0x47, 0x4b, 0x20 } } },
+ { L"PchSerialGpioBin_GUID", { 0xfc1b7640, 0x3466, 0x4c06, { 0xb1, 0xcc, 0x1c, 0x93, 0x53, 0x94, 0xb5, 0xc2 } } },
+ { L"IoTrapBin_GUID", { 0x2374eddf, 0xf203, 0x4fc0, { 0xa2, 0x0e, 0x61, 0xba, 0xd7, 0x30, 0x89, 0xd6 } } },
+ { L"PchS3SupportBin_GUID", { 0x08f2c63b, 0x08de, 0x4ccd, { 0x86, 0x70, 0xac, 0xfe, 0x64, 0x4a, 0x1c, 0x48 } } },
+ { L"PchS3PeimBin_GUID", { 0x271dd6f2, 0x54cb, 0x45e6, { 0x85, 0x85, 0x8c, 0x92, 0x3c, 0x1a, 0xc7, 0x06 } } },
+ { L"PchSmiDispatcherBin_GUID", { 0xb0d6ed53, 0xb844, 0x43f5, { 0xbd, 0x2f, 0x61, 0x09, 0x52, 0x64, 0xe7, 0x7e } } },
+ { L"PchUsbBin_GUID", { 0x6b4fdbd2, 0x47e1, 0x4a09, { 0xba, 0x8e, 0x8e, 0x04, 0x1f, 0x20, 0x8b, 0x95 } } },
+ { L"IntelLegacyInterruptBin_GUID", { 0xc1c418f9, 0x591d, 0x461c, { 0x82, 0xa2, 0xb9, 0xcd, 0x96, 0xdf, 0xea, 0x86 } } },
+ { L"ActiveBiosBin_GUID", { 0xbfd59d42, 0xfe0f, 0x4251, { 0xb7, 0x72, 0x4b, 0x09, 0x8a, 0x1a, 0xec, 0x85 } } },
+ { L"LegacyMebxMain_ffs_GUID", { 0x17772369, 0xd262, 0x4b90, { 0x9f, 0x31, 0xbd, 0xc4, 0x1f, 0x26, 0x63, 0xa5 } } },
+ { L"LegacyMebxLaunch_ffs_GUID", { 0x7c81c66a, 0x4f11, 0x47ab, { 0x82, 0xd3, 0x67, 0xc4, 0xd6, 0x35, 0xae, 0xd1 } } },
+ { L"BiosExtensionLoaderBin_GUID", { 0x97cc7188, 0x79c9, 0x449f, { 0xb9, 0x69, 0x06, 0x5b, 0x64, 0xbf, 0x9c, 0x69 } } },
+ { L"HeciDxeBin_GUID", { 0x55e76644, 0x78a5, 0x4a82, { 0xa9, 0x00, 0x71, 0x26, 0xa5, 0x79, 0x88, 0x92 } } },
+ { L"HeciSmmBin_GUID", { 0x921cd783, 0x3e22, 0x4579, { 0xa7, 0x1f, 0x00, 0xd7, 0x41, 0x97, 0xfc, 0xc8 } } },
+ { L"TdtDxeBin_GUID", { 0xdcaa4b60, 0x408f, 0x4bad, { 0x99, 0xb9, 0xb8, 0x80, 0xd4, 0xef, 0x09, 0x50 } } },
+ { L"TdtAmBin_GUID", { 0xc810485e, 0xd0ec, 0x4e98, { 0xaa, 0xb5, 0x12, 0x0c, 0x7e, 0x55, 0x44, 0x28 } } },
+ { L"Tdt3gBin_GUID", { 0x24be45e6, 0x2b61, 0x440d, { 0x8a, 0x75, 0xe7, 0x1f, 0xb6, 0xeb, 0x5b, 0x10 } } },
+ { L"TdtUsbWdmBin_GUID", { 0xe9490ad8, 0x348c, 0x4e65, { 0xba, 0xba, 0xed, 0x14, 0xc6, 0x16, 0xc4, 0x14 } } },
+ { L"AMTDxeBin_GUID", { 0xd739f969, 0xfb2d, 0x4bc2, { 0xaf, 0xe7, 0x08, 0x13, 0x27, 0xd3, 0xfe, 0xde } } },
+ { L"AsfInitSmmBin_GUID", { 0xeb78ce7e, 0x4107, 0x4ef5, { 0x86, 0xcb, 0x22, 0xe8, 0xd8, 0xac, 0x49, 0x50 } } },
+ { L"StartWatchDogBin_GUID", { 0x5479e09c, 0x2e74, 0x481b, { 0x89, 0xf8, 0xb0, 0x17, 0x2e, 0x38, 0x8d, 0x1f } } },
+ { L"IdeRControllerBin_GUID", { 0xc4f2d007, 0x37fd, 0x422d, { 0xb6, 0x3d, 0x7e, 0xd7, 0x38, 0x86, 0xe6, 0xca } } },
+ { L"PciSerialBin_GUID", { 0xfb142b99, 0xdf57, 0x46cb, { 0xbc, 0x69, 0x0b, 0xf8, 0x58, 0xa7, 0x34, 0xf9 } } },
+ { L"FlashWriteProtectBin_GUID", { 0xc1443436, 0xb954, 0x43ba, { 0x82, 0x78, 0xc1, 0xe4, 0x42, 0xc2, 0x15, 0x39 } } },
+ { L"FlashWriteProtectSmmBin_GUID", { 0x69ef78bc, 0x3b71, 0x4ecc, { 0x83, 0x4f, 0x3b, 0x74, 0xf9, 0x14, 0x84, 0x30 } } },
+ { L"AlertStandardFormatDxeBin_GUID", { 0x33c6406d, 0x2f6b, 0x41b5, { 0x87, 0x05, 0x52, 0xba, 0xfb, 0x63, 0x3c, 0x09 } } },
+ { L"AlertStandardFormatSmmBin_GUID", { 0xbb87b31d, 0xf366, 0x47e9, { 0x88, 0x5e, 0xe8, 0x16, 0xb0, 0x9b, 0x97, 0xb6 } } },
+ { L"AlertStandardFormatPeiBin_GUID", { 0x3e4817fd, 0x2742, 0x4351, { 0xb5, 0x9f, 0x91, 0x49, 0x32, 0x80, 0x32, 0x9c } } },
+ { L"MeFwDowngradeBin_GUID", { 0x5820eeb4, 0xc135, 0x4854, { 0x9d, 0x2a, 0xaa, 0x9e, 0xfc, 0x44, 0x75, 0xe9 } } },
+ { L"PowerManagementDxeBin_GUID", { 0x84991287, 0x3ff0, 0x4fcc, { 0x9c, 0x11, 0xc7, 0xe0, 0x41, 0x86, 0x2c, 0x76 } } },
+ { L"PowerManagementBin_GUID", { 0x8c783970, 0xf02a, 0x4a4d, { 0xaf, 0x09, 0x87, 0x97, 0xa5, 0x1e, 0xec, 0x8d } } },
+ { L"CpuCspLibAsm_obj_GUID", { 0x1ba0062e, 0xc779, 0x4582, { 0x85, 0x66, 0x33, 0x6a, 0xe8, 0xf7, 0x8f, 0x09 } } },
+ { L"STARTUP_GUID", { 0x1ba0062e, 0xc779, 0x4582, { 0x85, 0x66, 0x33, 0x6a, 0xe8, 0xf7, 0x8f, 0x09 } } },
+ { L"IntelGigabitLan_ffs_GUID", { 0x4953f720, 0x006d, 0x41f5, { 0x99, 0x0d, 0x0a, 0xc7, 0x74, 0x2a, 0xbb, 0x60 } } },
+ { L"RsdpPlusBin_GUID", { 0x67c53648, 0xda56, 0x4726, { 0xae, 0x21, 0xfb, 0xa4, 0xd0, 0x46, 0x86, 0xb3 } } },
+ { L"AmiTcgPlatformPeiBeforeMembin_GUID", { 0xe9312938, 0xe56b, 0x4614, { 0xa2, 0x52, 0xcf, 0x7d, 0x2f, 0x37, 0x7e, 0x26 } } },
+ { L"TcgPeiplatformBin_GUID", { 0x6b844c5b, 0x6b75, 0x42ca, { 0x8e, 0x8e, 0x1c, 0xb9, 0x44, 0x12, 0xb5, 0x9b } } },
+ { L"AmiTcgPlatformPeiAfterMembin_GUID", { 0x9b3f28d5, 0x10a6, 0x46c8, { 0xba, 0x72, 0xbd, 0x40, 0xb8, 0x47, 0xa7, 0x1a } } },
+ { L"TcgPlatformSetupPolicyBin_GUID", { 0x196ca3d8, 0x9a5a, 0x4735, { 0xb3, 0x28, 0x8f, 0xfc, 0x1d, 0x93, 0xd1, 0x88 } } },
+ { L"TcgDxeplatformBin_GUID", { 0x2688b232, 0x9c02, 0x4c12, { 0xbe, 0x1f, 0x85, 0x7c, 0x0f, 0xf2, 0xaa, 0xe3 } } },
+ { L"AmiTcgPlatformDxebin_GUID", { 0xa29a63e3, 0xe4e7, 0x495f, { 0x8a, 0x6a, 0x07, 0x73, 0x83, 0x00, 0xcb, 0xb3 } } },
+ { L"AmiTcgNvflagSamplebin_GUID", { 0x50f6096d, 0x7c98, 0x4c78, { 0x9a, 0x1d, 0xc5, 0xa1, 0x83, 0x3b, 0x6a, 0x88 } } },
+ { L"TcgPlatformSetupPeiPolicyBin_GUID", { 0x0fe9da53, 0x043d, 0x4265, { 0xa9, 0x4d, 0xfd, 0x77, 0xfe, 0xde, 0x2e, 0xb4 } } },
+ { L"MEPeiPolicyInitBin_GUID", { 0x12c67be1, 0xad2e, 0x4f13, { 0xa9, 0x5f, 0x6e, 0xdc, 0x2c, 0x43, 0x92, 0xde } } },
+ { L"AmtPeiPolicyInitBin_GUID", { 0xa05ece52, 0x15a8, 0x424e, { 0xbf, 0xd3, 0xfc, 0xf3, 0xd5, 0x66, 0xa0, 0x9c } } },
+ { L"iFfsDxePolicyInitBin_GUID", { 0xddb412a6, 0xe3f3, 0x4e9e, { 0x90, 0xa3, 0x2a, 0x99, 0x12, 0x70, 0x21, 0x9c } } },
+ { L"AcousticBin_GUID", { 0x0639408b, 0x19a6, 0x4b5d, { 0xba, 0xfb, 0x12, 0xa2, 0xf5, 0x11, 0x40, 0x32 } } },
+ { L"PerfTunePeiBin_GUID", { 0xdf8556f0, 0x3a61, 0x11de, { 0x8a, 0x39, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } } },
+ { L"PerfTuneDxeBin_GUID", { 0xf16bdbf0, 0x3a61, 0x11de, { 0x8a, 0x39, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } } },
+ { L"PerfTuneSmmBin_GUID", { 0xcb49ce50, 0x3a75, 0x11de, { 0x8a, 0x39, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } } },
+ { L"SBSATAIDE_ffs_GUID", { 0x22046d50, 0xf390, 0x498c, { 0x92, 0xe5, 0x5b, 0xa4, 0xf8, 0xe7, 0xf8, 0xb6 } } },
+ { L"LegacyRegion2Bin_GUID", { 0xfe6f8acd, 0x55a6, 0x4c6b, { 0xb4, 0x48, 0x64, 0xe6, 0x59, 0xde, 0x94, 0xb3 } } },
+ { L"IntelSaGopDriverBin_GUID", { 0x5c266089, 0xe103, 0x4d43, { 0x9a, 0xb5, 0x12, 0xd7, 0x09, 0x5b, 0xe2, 0xaf } } },
+ { L"IvbDummyName_ffs_GUID", { 0x878ac2cc, 0x5343, 0x46f2, { 0xb5, 0x63, 0x51, 0xf8, 0x9d, 0xaf, 0x56, 0xba } } },
+ { L"IntelIvbGopDriver_ffs_GUID", { 0x5bba83e6, 0xf027, 0x4ca7, { 0xbf, 0xd0, 0x16, 0x35, 0x8c, 0xc9, 0xe1, 0x23 } } },
+ { L"SnbDummyName_ffs_GUID", { 0x0f729f33, 0x25c1, 0x41a7, { 0x86, 0xb2, 0x23, 0xa7, 0x37, 0xa9, 0x18, 0x23 } } },
+ { L"IntelSnbGopDriver_ffs_GUID", { 0x8d59ebc8, 0xb85e, 0x400e, { 0x97, 0x0a, 0x1f, 0x99, 0x5d, 0x1d, 0xb9, 0x1e } } },
+ { L"SmmChildDispatcher2Bin_GUID", { 0xe53734a3, 0xe594, 0x4c25, { 0xb1, 0xa2, 0x08, 0x14, 0x45, 0x65, 0x0f, 0x7f } } },
+ { L"AMISmBusLib_lib_GUID", { 0x4b680e2d, 0x0d63, 0x4f62, { 0xb9, 0x30, 0x7a, 0xe9, 0x95, 0xb9, 0xb3, 0xa3 } } },
+ { L"SmBusPeiBin_GUID", { 0x9ea28d33, 0x0175, 0x4788, { 0xbe, 0xa8, 0x69, 0x50, 0x51, 0x60, 0x30, 0xa5 } } },
+ { L"SataDriver_ffs_GUID", { 0x91b4d9c1, 0x141c, 0x4824, { 0x8d, 0x02, 0x3c, 0x29, 0x8e, 0x36, 0xeb, 0x3f } } },
+ { L"CpuSpSmiBin_GUID", { 0x116e1acf, 0x2533, 0x4cc2, { 0x82, 0x0a, 0xbb, 0xc1, 0x0a, 0x2a, 0xb0, 0x7c } } },
+ { L"CpuSmmSaveResBin_GUID", { 0x326e7ace, 0x2133, 0x1ba2, { 0x80, 0x0a, 0xb9, 0xc0, 0x0a, 0xcc, 0xb1, 0x7d } } },
+ { L"NVRAM_FFS_GUID", { 0x9221315b, 0x30bb, 0x46b5, { 0x81, 0x3e, 0x1b, 0x1b, 0xf4, 0x71, 0x2b, 0xd3 } } },
+ { L"RomLayout_ini_GUID", { 0xae717c2f, 0x1a42, 0x4f2b, { 0x88, 0x61, 0x78, 0xb7, 0x9c, 0xa0, 0x7e, 0x07 } } },
+ { L"AhciMmioSmmBin_GUID", { 0x96f1ac24, 0x2b21, 0x45fa, { 0xa0, 0xb5, 0x67, 0x01, 0x0c, 0x95, 0xe9, 0xd8 } } },
+ { L"CryptoAPIPeiBin_GUID", { 0xd6d2fba6, 0xef60, 0x4c38, { 0xa8, 0x3e, 0x67, 0x69, 0x81, 0x4d, 0x23, 0xb0 } } },
+ { L"CryptoAPIDxeBin_GUID", { 0x20d8fffe, 0x15c3, 0x4ea9, { 0x9d, 0x28, 0xcf, 0xe2, 0x74, 0x5d, 0x78, 0xf3 } } },
+ { L"TcgPeiBinMem_GUID", { 0x12345678, 0x930a, 0x4a95, { 0xab, 0x04, 0x2e, 0x6c, 0xfd, 0xff, 0x66, 0x31 } } },
+ { L"FastBootSMIBin_GUID", { 0xd122882c, 0xda73, 0x438b, { 0xa6, 0xb3, 0xe0, 0x7b, 0x7d, 0x18, 0xdb, 0x6f } } },
+ { L"EBCBin_GUID", { 0x13ac6dd0, 0x73d0, 0x11d4, { 0xb0, 0x6b, 0x00, 0xaa, 0x00, 0xbd, 0x6d, 0xe7 } } },
+ { L"KbcEmulBin_GUID", { 0x3b24f79d, 0x91a0, 0x46ff, { 0xbe, 0x29, 0x45, 0x8a, 0xe2, 0x11, 0xfa, 0xc5 } } },
+ { L"OemActivationBin_GUID", { 0xc8ca0bb8, 0x67da, 0x4883, { 0x8c, 0xfc, 0x91, 0x80, 0xcb, 0x9e, 0xec, 0x68 } } },
+ { L"SecFlashUpdDxeBin_GUID", { 0xa0ef80e3, 0xf9ab, 0x4cba, { 0x98, 0xfd, 0x70, 0x46, 0x20, 0xf4, 0x04, 0x8d } } },
+ { L"FwCapsuleRecoveryPPIBin_GUID", { 0x83fa5aed, 0x5171, 0x4949, { 0xbd, 0xc9, 0x0c, 0xbc, 0x9e, 0x12, 0x36, 0x63 } } },
+ { L"FWpriv_GUID", { 0x3feec852, 0xf14c, 0x4e7f, { 0x97, 0xfd, 0x4c, 0x3a, 0x8c, 0x5b, 0xbe, 0xcc } } },
+ { L"FWpriv_GUID", { 0x9e625a27, 0x4840, 0x47cc, { 0xa6, 0xb5, 0x1e, 0x93, 0x11, 0xcf, 0xc6, 0x0e } } },
+ { L"SecureBootModDxe_GUID", { 0xa95c1d60, 0xcb9f, 0x4bd8, { 0xa0, 0x30, 0x3f, 0x1c, 0x4a, 0x18, 0x51, 0x56 } } },
+ { L"SETPLATFORMKEYS_GUID", { 0xcc0f8a3f, 0x3dea, 0x4376, { 0x96, 0x79, 0x54, 0x26, 0xba, 0x0a, 0x90, 0x7e } } },
+ { L"SETPLATFORMKEYS_GUID", { 0x9fe7de69, 0x0aea, 0x470a, { 0xb5, 0x0a, 0x13, 0x98, 0x13, 0x64, 0x91, 0x89 } } },
+ { L"SETPLATFORMKEYS_GUID", { 0xfbf95065, 0x427f, 0x47b3, { 0x80, 0x77, 0xd1, 0x3c, 0x60, 0x71, 0x09, 0x98 } } },
+ { L"SETPLATFORMKEYS_GUID", { 0x9d7a05e9, 0xf740, 0x44c3, { 0x85, 0x8b, 0x75, 0x58, 0x6a, 0x8f, 0x9c, 0x8e } } },
+ { L"Dpc_ffs_GUID", { 0x399cf3a7, 0x82c7, 0x4d9b, { 0x91, 0x23, 0xdb, 0x11, 0x84, 0x29, 0x86, 0xd3 } } },
+ { L"UefiPxeBc_ffs_GUID", { 0x0ef8a3b1, 0x388a, 0x4b62, { 0x8b, 0xe6, 0xc7, 0x87, 0x7d, 0x50, 0xae, 0xdf } } },
+ { L"Arp_ffs_GUID", { 0x8dd91798, 0xee87, 0x4f0e, { 0x8a, 0x84, 0x3f, 0x99, 0x83, 0x11, 0xf9, 0x30 } } },
+ { L"Mnp_ffs_GUID", { 0xc30b94e3, 0xc8f2, 0x4ab0, { 0x91, 0xab, 0xfa, 0x8d, 0xf6, 0x21, 0xb1, 0xc9 } } },
+ { L"NetworkStackSetupScreenBin_GUID", { 0x0029de6a, 0xe024, 0x4eb8, { 0xa9, 0x1d, 0x9f, 0x23, 0xaa, 0x1f, 0x4e, 0x92 } } },
+ { L"Snp_ffs_GUID", { 0x3dd7a87b, 0xd5bd, 0x44af, { 0x98, 0x6f, 0x2e, 0x13, 0xdb, 0x5d, 0x27, 0x4c } } },
+ { L"IpSec_ffs_GUID", { 0xfcf94301, 0x9763, 0x4a64, { 0xaa, 0x84, 0x78, 0x92, 0xc4, 0x71, 0x23, 0x67 } } },
+ { L"Tcp_ffs_GUID", { 0xb1625d3c, 0x9d2d, 0x4e0d, { 0xb8, 0x64, 0x8a, 0x76, 0x3e, 0xe4, 0xec, 0x50 } } },
+ { L"Mtftp6_ffs_GUID", { 0x61afa251, 0x8ac8, 0x4440, { 0x9a, 0xb5, 0x76, 0x2b, 0x1b, 0xf0, 0x51, 0x56 } } },
+ { L"Dhcp6_ffs_GUID", { 0x8dd9176d, 0xee87, 0x4f0e, { 0x8a, 0x84, 0x3f, 0x99, 0x83, 0x11, 0xf9, 0x30 } } },
+ { L"Ip6_ffs_GUID", { 0x8f92960e, 0x2880, 0x4659, { 0xb8, 0x57, 0x91, 0x5a, 0x89, 0x01, 0xbd, 0xc8 } } },
+ { L"Udp6_ffs_GUID", { 0x10ee54ae, 0xb207, 0x4a4f, { 0xab, 0xd8, 0xcb, 0x52, 0x2e, 0xca, 0xa3, 0xa4 } } },
+ { L"Ip4_ffs_GUID", { 0x8f92960f, 0x2880, 0x4659, { 0xb8, 0x57, 0x91, 0x5a, 0x89, 0x01, 0xbd, 0xc8 } } },
+ { L"Udp4_ffs_GUID", { 0x10ee5462, 0xb207, 0x4a4f, { 0xab, 0xd8, 0xcb, 0x52, 0x2e, 0xca, 0xa3, 0xa4 } } },
+ { L"Ip4Config_ffs_GUID", { 0x8f9296ef, 0x2880, 0x4659, { 0xb8, 0x57, 0x91, 0x5a, 0x89, 0x01, 0xbd, 0xc8 } } },
+ { L"Mtftp4_ffs_GUID", { 0x61afa223, 0x8ac8, 0x4440, { 0x9a, 0xb5, 0x76, 0x2b, 0x1b, 0xf0, 0x51, 0x56 } } },
+ { L"Dhcp4_ffs_GUID", { 0x8dd9176e, 0xee87, 0x4f0e, { 0x8a, 0x84, 0x3f, 0x99, 0x83, 0x11, 0xf9, 0x30 } } },
+ { L"TxtOneTouchDxeBin_GUID", { 0x67791e00, 0x0c05, 0x4ae7, { 0xa9, 0x21, 0xfc, 0x40, 0x57, 0x22, 0x16, 0x53 } } },
+ { L"SmmDispBin_GUID", { 0x9cc55d7d, 0xfbff, 0x431c, { 0xbc, 0x14, 0x33, 0x4e, 0xae, 0xa6, 0x05, 0x2b } } },
+ { L"SmmBasePeimBin_GUID", { 0x8b8214f9, 0x4adb, 0x47dd, { 0xac, 0x62, 0x83, 0x13, 0xc5, 0x37, 0xe9, 0xfa } } },
+ { L"SmmBaseRuntimeBin_GUID", { 0x5552575a, 0x7e00, 0x4d61, { 0xa3, 0xa4, 0xf7, 0x54, 0x73, 0x51, 0xb4, 0x9e } } },
+ { L"SmmThunkBin_GUID", { 0x8d3be215, 0xd6f6, 0x4264, { 0xbe, 0xa6, 0x28, 0x07, 0x3f, 0xb1, 0x3a, 0xea } } },
+ { L"SmmRelocDxeBin_GUID", { 0x7fed72ee, 0x0170, 0x4814, { 0x98, 0x78, 0xa8, 0xfb, 0x18, 0x64, 0xdf, 0xaf } } },
+ { L"SmmRelocPeimBin_GUID", { 0xabb74f50, 0xfd2d, 0x4072, { 0xa3, 0x21, 0xca, 0xfc, 0x72, 0x97, 0x7e, 0xfa } } },
+ { L"CpuPolicyInitDxeBin_GUID", { 0x15b9b6da, 0x00a9, 0x4de7, { 0xb8, 0xe8, 0xed, 0x7a, 0xfb, 0x88, 0xf1, 0x6e } } },
+ { L"CpuPolicyPeiBin_GUID", { 0x0ac2d35d, 0x1c77, 0x1033, { 0xa6, 0xf8, 0x7c, 0xa5, 0x5d, 0xf7, 0xd0, 0xaa } } },
+ { L"CpuS3PeimBin_GUID", { 0xc866bd71, 0x7c79, 0x4bf1, { 0xa9, 0x3b, 0x06, 0x6b, 0x83, 0x0d, 0x8f, 0x9a } } },
+ { L"CpuInitDxeBin_GUID", { 0x62d171cb, 0x78cd, 0x4480, { 0x86, 0x78, 0xc6, 0xa2, 0xa7, 0x97, 0xa8, 0xde } } },
+ { L"CpuInitPeiBin_GUID", { 0x01359d99, 0x9446, 0x456d, { 0xad, 0xa4, 0x50, 0xa7, 0x11, 0xc0, 0x3a, 0xda } } },
+ { L"SmmAccessPeimBin_GUID", { 0x6ecfce51, 0x5724, 0x450c, { 0xa3, 0x8a, 0x58, 0x55, 0x3e, 0x95, 0x44, 0x22 } } },
+ { L"BdatAccessHandlerBin_GUID", { 0x6db9486f, 0x6af6, 0x4090, { 0x98, 0x4d, 0x23, 0x84, 0x82, 0xce, 0x3e, 0xa4 } } },
+ { L"SaLateInitSmmBin_GUID", { 0x2d1e361c, 0x7b3f, 0x4d15, { 0x8b, 0x1f, 0x66, 0xe5, 0x51, 0xfa, 0xbd, 0xc7 } } },
+ { L"PchResetPeimBin_GUID", { 0xff259f16, 0x18d1, 0x4298, { 0x8d, 0xd2, 0xbd, 0x87, 0xff, 0x28, 0x94, 0xa9 } } },
+ { L"Mebx_ffs_GUID", { 0x9cfd802c, 0x09a1, 0x43d6, { 0x82, 0x17, 0xaa, 0x49, 0xc1, 0xf9, 0x0d, 0x2c } } },
+ { L"MebxSetupBrowser_ffs_GUID", { 0xb62efbbb, 0x3923, 0x4cb9, { 0xa6, 0xe8, 0xdb, 0x81, 0x8e, 0x82, 0x8a, 0x80 } } },
+ { L"HeciPeiBin_GUID", { 0x9cf30325, 0xdc5c, 0x4556, { 0xa8, 0xb0, 0x74, 0x21, 0x5c, 0x5f, 0x7f, 0xc4 } } },
+ { L"MdesStatusCodeDrvBin_GUID", { 0xdf5cd25a, 0x8e55, 0x46ba, { 0x8c, 0xda, 0xbc, 0x7d, 0xb7, 0xbf, 0x9c, 0x64 } } },
+ { L"PlatformResetBin_GUID", { 0x9a9a912b, 0x5f53, 0x4586, { 0x88, 0x20, 0x70, 0x44, 0x85, 0xa2, 0x9d, 0x21 } } },
+ { L"iFfsDxe_Bin_GUID", { 0xb6b9295f, 0xcabf, 0x4cec, { 0xbb, 0x14, 0xfe, 0x42, 0x46, 0xf2, 0x17, 0x3a } } },
+ { L"IffsSmmBin_GUID", { 0x43172851, 0xcf7e, 0x4345, { 0x9f, 0xe0, 0xd7, 0x01, 0x2b, 0xb1, 0x7b, 0x88 } } },
+ { L"iFfsPeiBin_GUID", { 0x53f019e9, 0xbb0c, 0x424b, { 0x87, 0x0a, 0x1f, 0xaf, 0x10, 0xb1, 0xcb, 0x4c } } },
+ { L"FirmwarePerformanceTableBin_GUID", { 0xaec4159d, 0xf2fc, 0x4090, { 0x95, 0xce, 0x38, 0x31, 0x7a, 0x8e, 0xd6, 0x4c } } },
+ { L"PB_DTSBin_GUID", { 0x20cbbcc9, 0x5a4d, 0x40ed, { 0xb1, 0xe0, 0x80, 0x42, 0x3a, 0xb1, 0x55, 0x4f } } },
+ { L"CLKGENPEIBin_GUID", { 0x64fa16c2, 0x5deb, 0x4254, { 0xa7, 0x9e, 0x25, 0xb7, 0x85, 0x18, 0x2a, 0x02 } } },
+ { L"CLKGENDXEBin_GUID", { 0x5640497f, 0x645e, 0x4611, { 0xb9, 0x15, 0xe6, 0x82, 0xc8, 0xbd, 0x47, 0x83 } } },
+ { L"ASM106XPEIBin_GUID", { 0xb8cacf99, 0x5c9d, 0x445b, { 0xb6, 0xac, 0x6e, 0xf3, 0x0f, 0xc8, 0x27, 0x50 } } },
+ { L"ASM106XDXEBin_GUID", { 0xf3872f18, 0x7879, 0x49aa, { 0xac, 0x8e, 0x8d, 0xf3, 0x31, 0x27, 0xa1, 0xa3 } } },
+ { L"SaveConfigMemDataBin_GUID", { 0x1faaa415, 0xf8a9, 0x4a33, { 0xb4, 0x34, 0xa7, 0x81, 0x1f, 0xbe, 0xc1, 0x45 } } },
+ { L"PciHostBridgeWrapBin_GUID", { 0x1323c999, 0xdad5, 0x5432, { 0xa5, 0x4b, 0x7a, 0x05, 0xfb, 0xf4, 0x15, 0x15 } } },
+ { L"RCSMIWrapBin_GUID", { 0xaa5c4b18, 0x0e65, 0x4969, { 0xa0, 0xae, 0xf3, 0xd3, 0xda, 0x25, 0x1b, 0xa8 } } },
+ { L"SBIDEBin_GUID", { 0x0f39fa36, 0x072f, 0x4ba3, { 0x9e, 0xab, 0x3e, 0x4f, 0x28, 0xfd, 0x18, 0xfc } } },
+ { L"SBIDEBin_GUID", { 0xed32f7e0, 0x5f9a, 0x499d, { 0xbd, 0xba, 0xb1, 0xeb, 0x58, 0xd5, 0xb0, 0xeb } } },
+ { L"SmmCommunicateBin_GUID", { 0x7e2d983f, 0xf703, 0x4a29, { 0x97, 0x61, 0x77, 0xb5, 0x1f, 0x53, 0x54, 0xed } } },
+ { L"DigitalThermalSensorSmmBin_GUID", { 0x76b048da, 0x15ea, 0x420f, { 0x9d, 0x97, 0x8e, 0x63, 0x24, 0x7d, 0x2b, 0x3c } } },
+ { L"SataControllerBin_GUID", { 0x4c5c6a74, 0xbab7, 0x46d6, { 0x86, 0x88, 0x3b, 0x2e, 0x7f, 0x24, 0x6e, 0x3f } } },
+ { L"SmmControlBin_GUID", { 0x1a2b4139, 0x0da4, 0x416c, { 0xad, 0xe3, 0x85, 0x87, 0x7b, 0x31, 0x82, 0x66 } } },
+ { L"IchInitDxeBin_GUID", { 0x5f4735f7, 0xdcf9, 0x40fd, { 0x88, 0x58, 0x02, 0x6f, 0x93, 0x19, 0x42, 0xa9 } } },
+ { L"IntelIchResetBin_GUID", { 0xe424c009, 0xcd92, 0x4fec, { 0x80, 0x29, 0xd7, 0x9d, 0x3f, 0x1c, 0xf3, 0xde } } },
+ { L"IoTrapBin_GUID", { 0x0dba19da, 0x5197, 0x4e71, { 0xa6, 0x2f, 0x4f, 0x8c, 0xb3, 0xcd, 0xb5, 0x5f } } },
+ { L"IchTptSmmDispatcherBin_GUID", { 0x35c5ab3e, 0xb77a, 0x450c, { 0x88, 0x54, 0x15, 0x9b, 0x2f, 0x0d, 0x32, 0xa6 } } },
+ { L"IntelIchLegacyInterruptBin_GUID", { 0xd3709bb4, 0xb194, 0x4b71, { 0xb9, 0xc0, 0xdb, 0xd8, 0xd2, 0xda, 0x97, 0xad } } },
+ { L"ActiveBiosBin_GUID", { 0x67ac0b1e, 0x54c2, 0x41a6, { 0xb5, 0x7e, 0xc2, 0xa3, 0x21, 0x41, 0x6a, 0xbc } } },
+ { L"PciExpressBin_GUID", { 0xa19fb0ee, 0x05f4, 0x4cd6, { 0x8f, 0x28, 0x59, 0xb7, 0x82, 0xff, 0x95, 0xc6 } } },
+ { L"SmmAccessBin_GUID", { 0x326e9cc6, 0x9839, 0x4885, { 0xb2, 0xed, 0x27, 0x59, 0x03, 0xb6, 0x68, 0xe1 } } },
+ { L"MemoryInitBin_GUID", { 0xd4ee25ea, 0x0b48, 0x43ae, { 0xa0, 0x16, 0x4d, 0x6e, 0x8b, 0x6c, 0x43, 0xb3 } } },
+ { L"PciHostBridgeBin_GUID", { 0x9fd2360e, 0x6b48, 0x11d5, { 0x8e, 0x71, 0x00, 0x90, 0x27, 0x07, 0xb3, 0x5e } } },
+ { L"PowerManagement2Bin_GUID", { 0xf7731b4c, 0x58a2, 0x4df4, { 0x89, 0x80, 0x56, 0x45, 0xd3, 0x9e, 0xce, 0x58 } } },
+ { L"PowerManagementAcpiTables2_ffs_GUID", { 0x161be597, 0xe9c5, 0x49db, { 0xae, 0x50, 0xc4, 0x62, 0xab, 0x54, 0xee, 0xda } } },
+ { L"PlatformInfoPeiBin_GUID", { 0x3870ef56, 0xe2d1, 0x43d4, { 0xab, 0x71, 0xdf, 0x30, 0xf7, 0xda, 0x65, 0x24 } } },
+ { L"DockSmmBin_GUID", { 0x854fb23e, 0xea74, 0x42bb, { 0xae, 0x7f, 0x13, 0x66, 0x4b, 0x03, 0xae, 0x4c } } },
+ { L"ZERO_GUID", { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+};
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/main.c b/plugins-extra/FirmwarePlugin/main.c
new file mode 100644
index 0000000..7b691cf
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/main.c
@@ -0,0 +1,167 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Firmware Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+PPH_PLUGIN PluginInstance;
+static PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration;
+static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+
+VOID NTAPI LoadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ HANDLE tokenHandle;
+
+ if (NT_SUCCESS(NtOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &tokenHandle)))
+ {
+ PhSetTokenPrivilege(tokenHandle, SE_SYSTEM_ENVIRONMENT_NAME, NULL, SE_PRIVILEGE_ENABLED);
+ NtClose(tokenHandle);
+ }
+}
+
+VOID NTAPI UnloadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ NOTHING;
+}
+
+VOID NTAPI MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = (PPH_PLUGIN_MENU_ITEM)Parameter;
+
+ switch (menuItem->Id)
+ {
+ case BOOT_ENTRIES_MENUITEM:
+ {
+ if (!EfiSupported())
+ {
+ PhShowError(menuItem->OwnerWindow, L"Windows was installed using legacy BIOS");
+ return;
+ }
+
+ DialogBox(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_BOOT),
+ NULL,
+ BootEntriesDlgProc
+ );
+ }
+ break;
+ }
+}
+
+VOID NTAPI MainMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM systemMenu;
+ PPH_EMENU_ITEM bootMenuItem;
+
+ if (menuInfo->u.MainMenu.SubMenuIndex != PH_MENU_ITEM_LOCATION_TOOLS)
+ return;
+
+ if (!(systemMenu = PhFindEMenuItem(menuInfo->Menu, 0, L"System", 0)))
+ {
+ PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, PH_EMENU_SEPARATOR, 0, L"", NULL), -1);
+ PhInsertEMenuItem(menuInfo->Menu, systemMenu = PhPluginCreateEMenuItem(PluginInstance, 0, 0, L"System", NULL), -1);
+ }
+
+ PhInsertEMenuItem(systemMenu, bootMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, BOOT_ENTRIES_MENUITEM, L"Firmware Table", NULL), -1);
+
+ if (!PhGetOwnTokenAttributes().Elevated)
+ {
+ bootMenuItem->Flags |= PH_EMENU_DISABLED;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { IntegerPairSettingType, SETTING_NAME_WINDOW_POSITION, L"100,100" },
+ { ScalableIntegerPairSettingType, SETTING_NAME_WINDOW_SIZE, L"@96|490,340" },
+ { StringSettingType, SETTING_NAME_LISTVIEW_COLUMNS, L"" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Firmware Table";
+ info->Author = L"dmex";
+ info->Description = L"Plugin for viewing the UEFI Firmware table via the Tools menu.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
+ LoadCallback,
+ NULL,
+ &PluginLoadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
+ UnloadCallback,
+ NULL,
+ &PluginUnloadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackMainMenuInitializing),
+ MainMenuInitializingCallback,
+ NULL,
+ &MainMenuInitializingCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &PluginMenuItemCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/main.h b/plugins-extra/FirmwarePlugin/main.h
new file mode 100644
index 0000000..c11126d
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/main.h
@@ -0,0 +1,137 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Boot Entries Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#ifndef _BOOT_H_
+#define _BOOT_H_
+
+#define BOOT_ENTRIES_MENUITEM 1000
+#define PLUGIN_NAME L"dmex.UefiFirmwareEntriesPlugin"
+#define SETTING_NAME_WINDOW_POSITION (PLUGIN_NAME L".WindowPosition")
+#define SETTING_NAME_WINDOW_SIZE (PLUGIN_NAME L".WindowSize")
+#define SETTING_NAME_LISTVIEW_COLUMNS (PLUGIN_NAME L".ListViewColumns")
+
+#define CINTERFACE
+#define COBJMACROS
+#define INITGUID
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+
+extern PPH_PLUGIN PluginInstance;
+
+typedef struct _BOOT_WINDOW_CONTEXT
+{
+ HWND ListViewHandle;
+ PH_LAYOUT_MANAGER LayoutManager;
+} BOOT_WINDOW_CONTEXT, *PBOOT_WINDOW_CONTEXT;
+
+INT_PTR CALLBACK BootEntriesDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+
+
+NTSTATUS EnumerateFirmwareValues(
+ _Out_ PVOID *Values
+ );
+
+BOOLEAN EfiSupported(
+ VOID
+ );
+
+typedef enum _SYSTEM_ENVIRONMENT_INFORMATION_CLASS
+{
+ SystemEnvironmentUnknownInformation,
+ SystemEnvironmentNameInformation, // q: VARIABLE_NAME
+ SystemEnvironmentValueInformation, // q: VARIABLE_NAME_AND_VALUE
+ MaxSystemEnvironmentInfoClass
+} SYSTEM_ENVIRONMENT_INFORMATION_CLASS;
+
+
+typedef struct _VARIABLE_NAME
+{
+ ULONG NextEntryOffset;
+ GUID VendorGuid;
+ WCHAR Name[ANYSIZE_ARRAY];
+} VARIABLE_NAME, *PVARIABLE_NAME;
+
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+
+typedef struct _VARIABLE_NAME_AND_VALUE
+{
+ ULONG NextEntryOffset;
+ ULONG ValueOffset;
+ ULONG ValueLength;
+ ULONG Attributes;
+ GUID VendorGuid;
+ WCHAR Name[ANYSIZE_ARRAY];
+} VARIABLE_NAME_AND_VALUE, *PVARIABLE_NAME_AND_VALUE;
+
+#define PH_FIRST_EFI_VARIABLE(Variables) ((PVARIABLE_NAME_AND_VALUE)(Variables))
+#define PH_NEXT_EFI_VARIABLE(Variable) ( \
+ ((PVARIABLE_NAME_AND_VALUE)(Variable))->NextEntryOffset ? \
+ (PVARIABLE_NAME_AND_VALUE)((PCHAR)(Variable) + \
+ ((PVARIABLE_NAME_AND_VALUE)(Variable))->NextEntryOffset) : \
+ NULL \
+ )
+
+#define PH_FIRST_BOOT_ENTRY(Variables) ((PBOOT_ENTRY_LIST)(Variables))
+#define PH_NEXT_BOOT_ENTRY(Variable) ( \
+ ((PBOOT_ENTRY_LIST)(Variable))->NextEntryOffset ? \
+ (PBOOT_ENTRY_LIST)((PCHAR)(Variable) + \
+ ((PBOOT_ENTRY_LIST)(Variable))->NextEntryOffset) : \
+ NULL \
+ )
+
+typedef BOOLEAN (NTAPI *PPH_BOOT_ENTRY_CALLBACK)(
+ _In_ PBOOT_ENTRY BootEntry,
+ _In_ PVOID Context
+ );
+
+#define FILE_PATH_TYPE_MIN FILE_PATH_TYPE_ARC
+#define FILE_PATH_TYPE_MAX FILE_PATH_TYPE_EFI
+
+#define WINDOWS_OS_OPTIONS_VERSION 1
+#define WINDOWS_OS_OPTIONS_SIGNATURE "WINDOWS"
+
+typedef struct _WINDOWS_OS_OPTIONS
+{
+ UCHAR Signature[8];
+ ULONG Version;
+ ULONG Length;
+ ULONG OsLoadPathOffset; //FILE_PATH OsLoadPath;
+ WCHAR OsLoadOptions[1];
+} WINDOWS_OS_OPTIONS, *PWINDOWS_OS_OPTIONS;
+
+#endif _BOOT_H_
\ No newline at end of file
diff --git a/plugins-extra/FirmwarePlugin/resource.h b/plugins-extra/FirmwarePlugin/resource.h
new file mode 100644
index 0000000..e45bc33
--- /dev/null
+++ b/plugins-extra/FirmwarePlugin/resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by FirmwarePlugin.rc
+//
+#define IDD_BOOT 101
+#define IDC_BOOT_LIST 40001
+#define IDC_BOOT_REFRESH 40002
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40005
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 102
+#endif
+#endif
diff --git a/plugins-extra/ForceShutdownPlugin/CHANGELOG.txt b/plugins-extra/ForceShutdownPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.rc b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.rc
new file mode 100644
index 0000000..e5a6464
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.rc
@@ -0,0 +1,99 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.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 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Force shutdown plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "dmex.ForceShutdownPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "ForceShutdownPlugin.dll"
+ VALUE "ProductName", "Force shutdown plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj
new file mode 100644
index 0000000..a9cc109
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj
@@ -0,0 +1,108 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {4417E8FC-5FA6-4631-B792-1872561E7DC2}
+ ForceShutdownPlugin
+ Win32Proj
+ ForceShutdownPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj.filters b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj.filters
new file mode 100644
index 0000000..c951291
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/ForceShutdownPlugin.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {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;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/ForceShutdownPlugin/main.c b/plugins-extra/ForceShutdownPlugin/main.c
new file mode 100644
index 0000000..c34cc6a
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/main.c
@@ -0,0 +1,118 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Force Shutdown Plugin
+ *
+ * Copyright (C) 2016 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
+#include "resource.h"
+
+#define REBOOT_MENU_ITEM 1
+#define SHUTDOWN_MENU_ITEM 2
+
+static PPH_PLUGIN PluginInstance;
+static PH_CALLBACK_REGISTRATION MenuItemCallbackRegistration;
+static PH_CALLBACK_REGISTRATION TrayMenuInitializingCallbackRegistration;
+
+VOID MenuItemCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_ITEM menuItem = Parameter;
+
+ switch (menuItem->Id)
+ {
+ case REBOOT_MENU_ITEM:
+ {
+ NTSTATUS status;
+
+ if (!NT_SUCCESS(status = NtShutdownSystem(ShutdownReboot)))
+ {
+ PhShowStatus(menuItem->OwnerWindow, L"Unable to reboot the machine", status, 0);
+ }
+ }
+ break;
+ case SHUTDOWN_MENU_ITEM:
+ {
+ NTSTATUS status;
+
+ if (!NT_SUCCESS(status = NtShutdownSystem(ShutdownPowerOff)))
+ {
+ PhShowStatus(menuItem->OwnerWindow, L"Unable to shutdown the machine", status, 0);
+ }
+ }
+ break;
+ }
+}
+
+VOID TrayMenuInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter;
+ PPH_EMENU_ITEM menu;
+
+ menu = PhFindEMenuItem(menuInfo->Menu, 0, L"Computer", 0);
+
+ if (!menu)
+ return;
+
+ PhInsertEMenuItem(menu, PhCreateEMenuItem(PH_EMENU_SEPARATOR, 0, NULL, NULL, NULL), -1);
+ PhInsertEMenuItem(menu, PhPluginCreateEMenuItem(PluginInstance, 0, REBOOT_MENU_ITEM, L"Force reboot", NULL), -1);
+ PhInsertEMenuItem(menu, PhPluginCreateEMenuItem(PluginInstance, 0, SHUTDOWN_MENU_ITEM, L"Force shut down", NULL), -1);
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ if (Reason == DLL_PROCESS_ATTACH)
+ {
+ PPH_PLUGIN_INFORMATION info;
+
+ PluginInstance = PhRegisterPlugin(L"dmex.ForceShutdownPlugin", Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Force Shutdown";
+ info->Author = L"dmex";
+ info->Description = L"Force a system shutdown or reboot via the Process Hacker tray menu > Computer > 'Force' shutdown or reboot menu items.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem),
+ MenuItemCallback,
+ NULL,
+ &MenuItemCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackIconMenuInitializing),
+ TrayMenuInitializingCallback,
+ NULL,
+ &TrayMenuInitializingCallbackRegistration
+ );
+ }
+
+ return TRUE;
+}
diff --git a/plugins-extra/ForceShutdownPlugin/resource.h b/plugins-extra/ForceShutdownPlugin/resource.h
new file mode 100644
index 0000000..2389623
--- /dev/null
+++ b/plugins-extra/ForceShutdownPlugin/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ForceShutdownPlugin.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins-extra/HexPidPlugin/CHANGELOG.txt b/plugins-extra/HexPidPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/HexPidPlugin/HexPidPlugin.rc b/plugins-extra/HexPidPlugin/HexPidPlugin.rc
new file mode 100644
index 0000000..36f7058
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/HexPidPlugin.rc
@@ -0,0 +1,99 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.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 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "wj32"
+ VALUE "FileDescription", "Hexadecimal PID plugin for Process Hacker"
+ VALUE "FileVersion", "1.0"
+ VALUE "InternalName", "wj32.HexPidPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "HexPidPlugin.dll"
+ VALUE "ProductName", "Hexadecimal PID plugin for Process Hacker"
+ VALUE "ProductVersion", "1.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj b/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj
new file mode 100644
index 0000000..7d5e66e
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj
@@ -0,0 +1,108 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {50691784-4EB0-4B5E-B428-BD37E52F8D2E}
+ HexPidPlugin
+ Win32Proj
+ HexPidPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj.filters b/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj.filters
new file mode 100644
index 0000000..1d93c9a
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/HexPidPlugin.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {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;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/HexPidPlugin/main.c b/plugins-extra/HexPidPlugin/main.c
new file mode 100644
index 0000000..01f1b15
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/main.c
@@ -0,0 +1,143 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Hexadecimal PID Plugin
+ *
+ * Copyright (C) 2011 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
+#include "resource.h"
+
+#define PIDHEX_COLUMN_ID 1
+
+typedef struct _PROCESS_EXTENSION
+{
+ WCHAR PidHexText[PH_PTR_STR_LEN_1];
+} PROCESS_EXTENSION, *PPROCESS_EXTENSION;
+
+PPH_PLUGIN PluginInstance;
+PH_CALLBACK_REGISTRATION TreeNewMessageCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessTreeNewInitializingCallbackRegistration;
+
+VOID TreeNewMessageCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
+
+ switch (message->Message)
+ {
+ case TreeNewGetCellText:
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
+ PPH_PROCESS_NODE node;
+
+ node = (PPH_PROCESS_NODE)getCellText->Node;
+
+ switch (message->SubId)
+ {
+ case PIDHEX_COLUMN_ID:
+ {
+ if (!PH_IS_FAKE_PROCESS_ID(node->ProcessId))
+ {
+ PPROCESS_EXTENSION extension;
+
+ extension = PhPluginGetObjectExtension(PluginInstance, node->ProcessItem, EmProcessItemType);
+ PhInitializeStringRef(&getCellText->Text, extension->PidHexText);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+}
+
+LONG NTAPI PidHexSortFunction(
+ _In_ PVOID Node1,
+ _In_ PVOID Node2,
+ _In_ ULONG SubId,
+ _In_ PVOID Context
+ )
+{
+ PPH_PROCESS_NODE node1 = Node1;
+ PPH_PROCESS_NODE node2 = Node2;
+
+ return intptrcmp((LONG_PTR)node1->ProcessId, (LONG_PTR)node2->ProcessId);
+}
+
+VOID ProcessTreeNewInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_INFORMATION info = Parameter;
+ PH_TREENEW_COLUMN column;
+
+ memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
+ column.Text = L"PID (Hex)";
+ column.Width = 50;
+ column.Alignment = PH_ALIGN_RIGHT;
+ column.TextFlags = DT_RIGHT;
+
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, PIDHEX_COLUMN_ID, NULL, PidHexSortFunction);
+}
+
+VOID ProcessItemCreateCallback(
+ _In_ PVOID Object,
+ _In_ PH_EM_OBJECT_TYPE ObjectType,
+ _In_ PVOID Extension
+ )
+{
+ PPH_PROCESS_ITEM processItem = Object;
+ PPROCESS_EXTENSION extension = Extension;
+
+ _ultow(HandleToUlong(processItem->ProcessId), extension->PidHexText, 16);
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ if (Reason == DLL_PROCESS_ATTACH)
+ {
+ PPH_PLUGIN_INFORMATION info;
+
+ PluginInstance = PhRegisterPlugin(L"wj32.HexPidPlugin", Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Hexadecimal PID";
+ info->Description = L"Adds a column to display PIDs in hexadecimal.";
+ info->Author = L"wj32";
+
+ PhRegisterCallback(PhGetPluginCallback(PluginInstance, PluginCallbackTreeNewMessage),
+ TreeNewMessageCallback, NULL, &TreeNewMessageCallbackRegistration);
+ PhRegisterCallback(PhGetGeneralCallback(GeneralCallbackProcessTreeNewInitializing),
+ ProcessTreeNewInitializingCallback, NULL, &ProcessTreeNewInitializingCallbackRegistration);
+
+ PhPluginSetObjectExtension(PluginInstance, EmProcessItemType, sizeof(PROCESS_EXTENSION),
+ ProcessItemCreateCallback, NULL);
+ }
+
+ return TRUE;
+}
diff --git a/plugins-extra/HexPidPlugin/resource.h b/plugins-extra/HexPidPlugin/resource.h
new file mode 100644
index 0000000..f7c9522
--- /dev/null
+++ b/plugins-extra/HexPidPlugin/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by HexPidPlugin.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins-extra/NetExtrasPlugin/CHANGELOG.txt b/plugins-extra/NetExtrasPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..e303498
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/CHANGELOG.txt
@@ -0,0 +1,5 @@
+1.0
+ * Initial release
+
+1.1
+ * Added Geoip support
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.rc b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.rc
new file mode 100644
index 0000000..6256066
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.rc
@@ -0,0 +1,645 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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 ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Network Extras Plugin for Process Hacker"
+ VALUE "FileVersion", "1.1"
+ VALUE "InternalName", "dmex.NetworkExtrasPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "NetExtrasPlugin.dll"
+ VALUE "ProductName", "Network Extras Plugin for Process Hacker"
+ VALUE "ProductVersion", "1.1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// PNG
+//
+
+AD_PNG PNG "resources\\ad.png"
+
+AE_PNG PNG "resources\\ae.png"
+
+AF_PNG PNG "resources\\af.png"
+
+AG_PNG PNG "resources\\ag.png"
+
+AI_PNG PNG "resources\\ai.png"
+
+AL_PNG PNG "resources\\al.png"
+
+AM_PNG PNG "resources\\am.png"
+
+AN_PNG PNG "resources\\an.png"
+
+AO_PNG PNG "resources\\ao.png"
+
+AR_PNG PNG "resources\\ar.png"
+
+AS_PNG PNG "resources\\as.png"
+
+AT_PNG PNG "resources\\at.png"
+
+AU_PNG PNG "resources\\au.png"
+
+AW_PNG PNG "resources\\aw.png"
+
+AX_PNG PNG "resources\\ax.png"
+
+AZ_PNG PNG "resources\\az.png"
+
+BA_PNG PNG "resources\\ba.png"
+
+BB_PNG PNG "resources\\bb.png"
+
+BD_PNG PNG "resources\\bd.png"
+
+BE_PNG PNG "resources\\be.png"
+
+BF_PNG PNG "resources\\bf.png"
+
+BG_PNG PNG "resources\\bg.png"
+
+BH_PNG PNG "resources\\bh.png"
+
+BI__PNG PNG "resources\\bi.png"
+
+BJ_PNG PNG "resources\\bj.png"
+
+BM_PNG PNG "resources\\bm.png"
+
+BN_PNG PNG "resources\\bn.png"
+
+BO_PNG PNG "resources\\bo.png"
+
+BR_PNG PNG "resources\\br.png"
+
+BS_PNG PNG "resources\\bs.png"
+
+BT_PNG PNG "resources\\bt.png"
+
+BV_PNG PNG "resources\\bv.png"
+
+BW_PNG PNG "resources\\bw.png"
+
+BY_PNG PNG "resources\\by.png"
+
+BZ_PNG PNG "resources\\bz.png"
+
+CA_PNG PNG "resources\\ca.png"
+
+AAC_PNG PNG "resources\\catalonia.png"
+
+CC_PNG PNG "resources\\cc.png"
+
+CD_PNG PNG "resources\\cd.png"
+
+CF_PNG PNG "resources\\cf.png"
+
+CG_PNG PNG "resources\\cg.png"
+
+CH_PNG PNG "resources\\ch.png"
+
+CI_PNG PNG "resources\\ci.png"
+
+CK_PNG PNG "resources\\ck.png"
+
+CL_PNG PNG "resources\\cl.png"
+
+CM_PNG PNG "resources\\cm.png"
+
+CN_PNG PNG "resources\\cn.png"
+
+CO_PNG PNG "resources\\co.png"
+
+CR_PNG PNG "resources\\cr.png"
+
+CS_PNG PNG "resources\\cs.png"
+
+CU_PNG PNG "resources\\cu.png"
+
+CV_PNG PNG "resources\\cv.png"
+
+CX_PNG PNG "resources\\cx.png"
+
+CY_PNG PNG "resources\\cy.png"
+
+CZ_PNG PNG "resources\\cz.png"
+
+DE_PNG PNG "resources\\de.png"
+
+DJ_PNG PNG "resources\\dj.png"
+
+DK_PNG PNG "resources\\dk.png"
+
+DM_PNG PNG "resources\\dm.png"
+
+DO_PNG PNG "resources\\do.png"
+
+DZ_PNG PNG "resources\\dz.png"
+
+EC_PNG PNG "resources\\ec.png"
+
+EE_PNG PNG "resources\\ee.png"
+
+EG_PNG PNG "resources\\eg.png"
+
+EH_PNG PNG "resources\\eh.png"
+
+AAD_PNG PNG "resources\\england.png"
+
+ER_PNG PNG "resources\\er.png"
+
+ES_PNG PNG "resources\\es.png"
+
+ET_PNG PNG "resources\\et.png"
+
+AAE_PNG PNG "resources\\europeanunion.png"
+
+AAF_PNG PNG "resources\\fam.png"
+
+FI_PNG PNG "resources\\fi.png"
+
+FJ_PNG PNG "resources\\fj.png"
+
+FK_PNG PNG "resources\\fk.png"
+
+FM_PNG PNG "resources\\fm.png"
+
+FO_PNG PNG "resources\\fo.png"
+
+FR_PNG PNG "resources\\fr.png"
+
+GA_PNG PNG "resources\\ga.png"
+
+GB_PNG PNG "resources\\gb.png"
+
+GD_PNG PNG "resources\\gd.png"
+
+GE_PNG PNG "resources\\ge.png"
+
+GF_PNG PNG "resources\\gf.png"
+
+GH_PNG PNG "resources\\gh.png"
+
+GI_PNG PNG "resources\\gi.png"
+
+GL_PNG PNG "resources\\gl.png"
+
+GM_PNG PNG "resources\\gm.png"
+
+GN_PNG PNG "resources\\gn.png"
+
+GP_PNG PNG "resources\\gp.png"
+
+GQ_PNG PNG "resources\\gq.png"
+
+GR_PNG PNG "resources\\gr.png"
+
+GS_PNG PNG "resources\\gs.png"
+
+GT_PNG PNG "resources\\gt.png"
+
+GU_PNG PNG "resources\\gu.png"
+
+GW_PNG PNG "resources\\gw.png"
+
+GY_PNG PNG "resources\\gy.png"
+
+HK_PNG PNG "resources\\hk.png"
+
+HM_PNG PNG "resources\\hm.png"
+
+HN_PNG PNG "resources\\hn.png"
+
+HR_PNG PNG "resources\\hr.png"
+
+HT_PNG PNG "resources\\ht.png"
+
+HU_PNG PNG "resources\\hu.png"
+
+ID_PNG PNG "resources\\id.png"
+
+IE_PNG PNG "resources\\ie.png"
+
+IL_PNG PNG "resources\\il.png"
+
+IN_PNG PNG "resources\\in.png"
+
+IO_PNG PNG "resources\\io.png"
+
+IQ_PNG PNG "resources\\iq.png"
+
+IR_PNG PNG "resources\\ir.png"
+
+IS_PNG PNG "resources\\is.png"
+
+IT_PNG PNG "resources\\it.png"
+
+JM_PNG PNG "resources\\jm.png"
+
+JO_PNG PNG "resources\\jo.png"
+
+JP_PNG PNG "resources\\jp.png"
+
+KE_PNG PNG "resources\\ke.png"
+
+KG_PNG PNG "resources\\kg.png"
+
+KH_PNG PNG "resources\\kh.png"
+
+KI_PNG PNG "resources\\ki.png"
+
+KM_PNG PNG "resources\\km.png"
+
+KN_PNG PNG "resources\\kn.png"
+
+KP_PNG PNG "resources\\kp.png"
+
+KR_PNG PNG "resources\\kr.png"
+
+KW_PNG PNG "resources\\kw.png"
+
+KY_PNG PNG "resources\\ky.png"
+
+KZ_PNG PNG "resources\\kz.png"
+
+LA_PNG PNG "resources\\la.png"
+
+LB_PNG PNG "resources\\lb.png"
+
+LC_PNG PNG "resources\\lc.png"
+
+LI_PNG PNG "resources\\li.png"
+
+LK_PNG PNG "resources\\lk.png"
+
+LR_PNG PNG "resources\\lr.png"
+
+LS_PNG PNG "resources\\ls.png"
+
+LT_PNG PNG "resources\\lt.png"
+
+LU_PNG PNG "resources\\lu.png"
+
+LV_PNG PNG "resources\\lv.png"
+
+LY_PNG PNG "resources\\ly.png"
+
+MA_PNG PNG "resources\\ma.png"
+
+MC_PNG PNG "resources\\mc.png"
+
+MD_PNG PNG "resources\\md.png"
+
+ME_PNG PNG "resources\\me.png"
+
+MG_PNG PNG "resources\\mg.png"
+
+MH_PNG PNG "resources\\mh.png"
+
+MK_PNG PNG "resources\\mk.png"
+
+ML_PNG PNG "resources\\ml.png"
+
+MM_PNG PNG "resources\\mm.png"
+
+MN_PNG PNG "resources\\mn.png"
+
+MO_PNG PNG "resources\\mo.png"
+
+MP_PNG PNG "resources\\mp.png"
+
+MQ_PNG PNG "resources\\mq.png"
+
+MR_PNG PNG "resources\\mr.png"
+
+MS_PNG PNG "resources\\ms.png"
+
+MT_PNG PNG "resources\\mt.png"
+
+MU_PNG PNG "resources\\mu.png"
+
+MV_PNG PNG "resources\\mv.png"
+
+MW_PNG PNG "resources\\mw.png"
+
+MX_PNG PNG "resources\\mx.png"
+
+MY_PNG PNG "resources\\my.png"
+
+MZ_PNG PNG "resources\\mz.png"
+
+NA_PNG PNG "resources\\na.png"
+
+NC_PNG PNG "resources\\nc.png"
+
+NE_PNG PNG "resources\\ne.png"
+
+NF_PNG PNG "resources\\nf.png"
+
+NG_PNG PNG "resources\\ng.png"
+
+NI_PNG PNG "resources\\ni.png"
+
+NL_PNG PNG "resources\\nl.png"
+
+NO_PNG PNG "resources\\no.png"
+
+NP_PNG PNG "resources\\np.png"
+
+NR_PNG PNG "resources\\nr.png"
+
+NU_PNG PNG "resources\\nu.png"
+
+NZ_PNG PNG "resources\\nz.png"
+
+OM_PNG PNG "resources\\om.png"
+
+PA_PNG PNG "resources\\pa.png"
+
+PE_PNG PNG "resources\\pe.png"
+
+PF_PNG PNG "resources\\pf.png"
+
+PG_PNG PNG "resources\\pg.png"
+
+PH_PNG PNG "resources\\ph.png"
+
+PK_PNG PNG "resources\\pk.png"
+
+PL_PNG PNG "resources\\pl.png"
+
+PM_PNG PNG "resources\\pm.png"
+
+PN_PNG PNG "resources\\pn.png"
+
+PR_PNG PNG "resources\\pr.png"
+
+PS_PNG PNG "resources\\ps.png"
+
+PT_PNG PNG "resources\\pt.png"
+
+PW_PNG PNG "resources\\pw.png"
+
+PY_PNG PNG "resources\\py.png"
+
+QA_PNG PNG "resources\\qa.png"
+
+RE_PNG PNG "resources\\re.png"
+
+RO_PNG PNG "resources\\ro.png"
+
+RS_PNG PNG "resources\\rs.png"
+
+RU_PNG PNG "resources\\ru.png"
+
+RW_PNG PNG "resources\\rw.png"
+
+SA_PNG PNG "resources\\sa.png"
+
+SB_PNG PNG "resources\\sb.png"
+
+SC_PNG PNG "resources\\sc.png"
+
+AAA_PNG PNG "resources\\scotland.png"
+
+SD_PNG PNG "resources\\sd.png"
+
+SE_PNG PNG "resources\\se.png"
+
+SG_PNG PNG "resources\\sg.png"
+
+SH_PNG PNG "resources\\sh.png"
+
+SI_PNG PNG "resources\\si.png"
+
+SJ_PNG PNG "resources\\sj.png"
+
+SK_PNG PNG "resources\\sk.png"
+
+SL_PNG PNG "resources\\sl.png"
+
+SM_PNG PNG "resources\\sm.png"
+
+SN_PNG PNG "resources\\sn.png"
+
+SO_PNG PNG "resources\\so.png"
+
+SR_PNG PNG "resources\\sr.png"
+
+ST_PNG PNG "resources\\st.png"
+
+SV_PNG PNG "resources\\sv.png"
+
+SY_PNG PNG "resources\\sy.png"
+
+SZ_PNG PNG "resources\\sz.png"
+
+TC_PNG PNG "resources\\tc.png"
+
+TD_PNG PNG "resources\\td.png"
+
+TF_PNG PNG "resources\\tf.png"
+
+TG_PNG PNG "resources\\tg.png"
+
+TH_PNG PNG "resources\\th.png"
+
+TJ_PNG PNG "resources\\tj.png"
+
+TK_PNG PNG "resources\\tk.png"
+
+TL_PNG PNG "resources\\tl.png"
+
+TM_PNG PNG "resources\\tm.png"
+
+TN_PNG PNG "resources\\tn.png"
+
+TO_PNG PNG "resources\\to.png"
+
+TR_PNG PNG "resources\\tr.png"
+
+TT_PNG PNG "resources\\tt.png"
+
+TV_PNG PNG "resources\\tv.png"
+
+TW_PNG PNG "resources\\tw.png"
+
+TZ_PNG PNG "resources\\tz.png"
+
+UA_PNG PNG "resources\\ua.png"
+
+UG_PNG PNG "resources\\ug.png"
+
+UM_PNG PNG "resources\\um.png"
+
+US_PNG PNG "resources\\us.png"
+
+UY_PNG PNG "resources\\uy.png"
+
+UZ_PNG PNG "resources\\uz.png"
+
+VA_PNG PNG "resources\\va.png"
+
+VC_PNG PNG "resources\\vc.png"
+
+VE_PNG PNG "resources\\ve.png"
+
+VG_PNG PNG "resources\\vg.png"
+
+VI_PNG PNG "resources\\vi.png"
+
+VN_PNG PNG "resources\\vn.png"
+
+VU_PNG PNG "resources\\vu.png"
+
+AAB_PNG PNG "resources\\wales.png"
+
+WF_PNG PNG "resources\\wf.png"
+
+WS_PNG PNG "resources\\ws.png"
+
+YE_PNG PNG "resources\\ye.png"
+
+YT_PNG PNG "resources\\yt.png"
+
+ZA_PNG PNG "resources\\za.png"
+
+ZM_PNG PNG "resources\\zm.png"
+
+ZW_PNG PNG "resources\\zw.png"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 309, 178
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,198,157,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,252,157,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 302
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 171
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_OPTIONS AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj
new file mode 100644
index 0000000..7c11f24
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj
@@ -0,0 +1,383 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {B2F55139-7984-498F-98CB-AC25A3E08CCC}
+ NetExtrasPlugin
+ Win32Proj
+ NetExtrasPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ WindowsCodecs.lib;ws2_32.lib;%(AdditionalDependencies)
+ ws2_32.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ WindowsCodecs.lib;ws2_32.lib;%(AdditionalDependencies)
+ ws2_32.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ WindowsCodecs.lib;ws2_32.lib;%(AdditionalDependencies)
+ ws2_32.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+ WindowsCodecs.lib;ws2_32.lib;%(AdditionalDependencies)
+ ws2_32.dll;%(DelayLoadDLLs)
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj.filters b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj.filters
new file mode 100644
index 0000000..5a6922a
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/NetExtrasPlugin.vcxproj.filters
@@ -0,0 +1,814 @@
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files\maxminddb
+
+
+ Header Files\maxminddb
+
+
+ Header Files\maxminddb
+
+
+
+
+ {f016dd0f-55a7-4710-b96e-233df3940081}
+
+
+ {8f9f7140-8e74-4f4c-bd2e-e18ce8633914}
+
+
+ {9dc309ac-a574-4615-b42f-421e0207238b}
+
+
+ {8a8c1d78-2fe6-452d-8dd6-fff1ee982001}
+
+
+ {db470705-8b61-4e5f-b0a7-e4e9a847ff43}
+
+
+ {675b6a82-6895-4512-86fc-e00583505b6e}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files\maxminddb
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+ Resource Files\Images
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/country.c b/plugins-extra/NetExtrasPlugin/country.c
new file mode 100644
index 0000000..5b43896
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/country.c
@@ -0,0 +1,189 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2016 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 "main.h"
+#include "maxminddb.h"
+
+BOOLEAN GeoDbLoaded = FALSE;
+static MMDB_s GeoDb = { 0 };
+
+// Copied from mstcpip.h (due to PH-SDK conflicts).
+// Note: Ipv6 versions are already available from ws2ipdef.h and did not need copying.
+
+#define INADDR_ANY (ULONG)0x00000000
+#define INADDR_LOOPBACK 0x7f000001
+
+FORCEINLINE
+BOOLEAN
+IN4_IS_ADDR_UNSPECIFIED(_In_ CONST IN_ADDR *a)
+{
+ return (BOOLEAN)(a->s_addr == INADDR_ANY);
+}
+
+FORCEINLINE
+BOOLEAN
+IN4_IS_ADDR_LOOPBACK(_In_ CONST IN_ADDR *a)
+{
+ return (BOOLEAN)(*((PUCHAR)a) == 0x7f); // 127/8
+}
+// end copy from mstcpip.h
+
+
+VOID LoadGeoLiteDb(VOID)
+{
+ PPH_STRING directory;
+ PPH_STRING path;
+
+ directory = PH_AUTO(PhGetApplicationDirectory());
+ path = PhaCreateString(DATABASE_PATH);
+ path = PH_AUTO(PhConcatStringRef2(&directory->sr, &path->sr));
+
+ if (MMDB_open(path->Buffer, MMDB_MODE_MMAP, &GeoDb) == MMDB_SUCCESS)
+ {
+ time_t systemTime;
+
+ // Query the current time
+ time(&systemTime);
+
+ // Check if the Geoip database is older than 6 months (182 days = approx. 6 months).
+ if ((systemTime - GeoDb.metadata.build_epoch) > (182 * 24 * 60 * 60))
+ {
+ // TODO: Warn about old database...
+ }
+
+ if (GeoDb.metadata.ip_version == 6)
+ {
+ // Database includes ipv6 entires.
+ }
+
+ GeoDbLoaded = TRUE;
+ }
+}
+
+VOID FreeGeoLiteDb(VOID)
+{
+ if (GeoDbLoaded)
+ {
+ MMDB_close(&GeoDb);
+ }
+}
+
+BOOLEAN LookupCountryCode(
+ _In_ PH_IP_ADDRESS RemoteAddress,
+ _Out_ PPH_STRING* CountryCode,
+ _Out_ PPH_STRING* CountryName
+ )
+{
+ PPH_STRING countryCode = NULL;
+ PPH_STRING countryName = NULL;
+ MMDB_entry_data_s mmdb_entry;
+ MMDB_lookup_result_s mmdb_lookup;
+ INT mmdb_error = 0;
+
+ if (!GeoDbLoaded)
+ return FALSE;
+
+ if (RemoteAddress.Type == PH_IPV4_NETWORK_TYPE)
+ {
+ SOCKADDR_IN ipv4SockAddr;
+
+ if (IN4_IS_ADDR_UNSPECIFIED(&RemoteAddress.InAddr))
+ return FALSE;
+
+ if (IN4_IS_ADDR_LOOPBACK(&RemoteAddress.InAddr))
+ return FALSE;
+
+ memset(&ipv4SockAddr, 0, sizeof(SOCKADDR_IN));
+ memset(&mmdb_lookup, 0, sizeof(MMDB_lookup_result_s));
+
+ ipv4SockAddr.sin_family = AF_INET;
+ ipv4SockAddr.sin_addr = RemoteAddress.InAddr;
+
+ mmdb_lookup = MMDB_lookup_sockaddr(
+ &GeoDb,
+ (struct sockaddr*)&ipv4SockAddr,
+ &mmdb_error
+ );
+ }
+ else
+ {
+ SOCKADDR_IN6 ipv6SockAddr;
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&RemoteAddress.In6Addr))
+ return FALSE;
+
+ if (IN6_IS_ADDR_LOOPBACK(&RemoteAddress.In6Addr))
+ return FALSE;
+
+ memset(&ipv6SockAddr, 0, sizeof(SOCKADDR_IN6));
+ memset(&mmdb_lookup, 0, sizeof(MMDB_lookup_result_s));
+
+ ipv6SockAddr.sin6_family = AF_INET6;
+ ipv6SockAddr.sin6_addr = RemoteAddress.In6Addr;
+
+ mmdb_lookup = MMDB_lookup_sockaddr(
+ &GeoDb,
+ (struct sockaddr*)&ipv6SockAddr,
+ &mmdb_error
+ );
+ }
+
+ if (mmdb_error == 0 && mmdb_lookup.found_entry)
+ {
+ memset(&mmdb_entry, 0, sizeof(MMDB_entry_data_s));
+
+ if (MMDB_get_value(&mmdb_lookup.entry, &mmdb_entry, "country", "iso_code", NULL) == MMDB_SUCCESS)
+ {
+ if (mmdb_entry.has_data && mmdb_entry.type == MMDB_DATA_TYPE_UTF8_STRING)
+ {
+ countryCode = PhConvertUtf8ToUtf16Ex((PCHAR)mmdb_entry.utf8_string, mmdb_entry.data_size);
+ }
+ }
+
+ if (MMDB_get_value(&mmdb_lookup.entry, &mmdb_entry, "country", "names", "en", NULL) == MMDB_SUCCESS)
+ {
+ if (mmdb_entry.has_data && mmdb_entry.type == MMDB_DATA_TYPE_UTF8_STRING)
+ {
+ countryName = PhConvertUtf8ToUtf16Ex((PCHAR)mmdb_entry.utf8_string, mmdb_entry.data_size);
+ }
+ }
+ }
+
+ if (countryCode && countryName)
+ {
+ *CountryCode = countryCode;
+ *CountryName = countryName;
+ return TRUE;
+ }
+
+ if (countryCode)
+ {
+ PhDereferenceObject(countryCode);
+ }
+
+ if (countryName)
+ {
+ PhDereferenceObject(countryName);
+ }
+
+ return FALSE;
+}
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/extra.c b/plugins-extra/NetExtrasPlugin/extra.c
new file mode 100644
index 0000000..df77c8b
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/extra.c
@@ -0,0 +1,91 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2015 dmex
+ * Copyright (C) 2015 TETYYS
+ *
+ * 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 "main.h"
+
+VOID UpdateNetworkNode(
+ _In_ NETWORK_COLUMN_ID ColumnID,
+ _In_ PPH_NETWORK_NODE Node,
+ _In_ PNETWORK_EXTENSION Extension
+ )
+{
+ switch (ColumnID)
+ {
+ case NETWORK_COLUMN_ID_LOCAL_SERVICE:
+ {
+ if (!Extension->LocalValid)
+ {
+ //PH_STRING_BUILDER stringBuilder;
+
+ //PhInitializeStringBuilder(&stringBuilder, 24);
+
+ for (ULONG x = 0; x < ARRAYSIZE(ResolvedPortsTable); x++)
+ {
+ if (Node->NetworkItem->LocalEndpoint.Port == ResolvedPortsTable[x].Port)
+ {
+ //PhAppendFormatStringBuilder(&stringBuilder, L"%s,", ResolvedPortsTable[x].Name);
+
+ PhSwapReference(&Extension->LocalServiceName, PhCreateString(ResolvedPortsTable[x].Name));
+ break;
+ }
+ }
+
+ //if (stringBuilder.String->Length != 0)
+ // PhRemoveEndStringBuilder(&stringBuilder, 1);
+
+ //PhSwapReference(&Extension->LocalServiceName, PhFinalStringBuilderString(&stringBuilder));
+
+ Extension->LocalValid = TRUE;
+ }
+ }
+ break;
+ case NETWORK_COLUMN_ID_REMOTE_SERVICE:
+ {
+ if (!Extension->RemoteValid)
+ {
+ //PH_STRING_BUILDER stringBuilder;
+
+ //PhInitializeStringBuilder(&stringBuilder, 24);
+
+ for (ULONG x = 0; x < ARRAYSIZE(ResolvedPortsTable); x++)
+ {
+ if (Node->NetworkItem->RemoteEndpoint.Port == ResolvedPortsTable[x].Port)
+ {
+ //PhAppendFormatStringBuilder(&stringBuilder, L"%s,", ResolvedPortsTable[x].Name);
+
+ PhSwapReference(&Extension->RemoteServiceName, PhCreateString(ResolvedPortsTable[x].Name));
+ break;
+ }
+ }
+
+ //if (stringBuilder.String->Length != 0)
+ // PhRemoveEndStringBuilder(&stringBuilder, 1);
+
+ //PhSwapReference(&Extension->RemoteServiceName, PhFinalStringBuilderString(&stringBuilder));
+
+ Extension->RemoteValid = TRUE;
+ }
+ }
+ break;
+ }
+}
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/main.c b/plugins-extra/NetExtrasPlugin/main.c
new file mode 100644
index 0000000..670f305
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/main.c
@@ -0,0 +1,347 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+PPH_PLUGIN PluginInstance = NULL;
+static PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
+static PH_CALLBACK_REGISTRATION NetworkTreeNewInitializingCallbackRegistration;
+static PH_CALLBACK_REGISTRATION TreeNewMessageCallbackRegistration;
+static HWND NetworkTreeNewHandle = NULL;
+
+static LONG NTAPI NetworkServiceSortFunction(
+ _In_ PVOID Node1,
+ _In_ PVOID Node2,
+ _In_ ULONG SubId,
+ _In_ PVOID Context
+ )
+{
+ PPH_NETWORK_NODE node1 = Node1;
+ PPH_NETWORK_NODE node2 = Node2;
+ PNETWORK_EXTENSION extension1 = PhPluginGetObjectExtension(PluginInstance, node1->NetworkItem, EmNetworkItemType);
+ PNETWORK_EXTENSION extension2 = PhPluginGetObjectExtension(PluginInstance, node2->NetworkItem, EmNetworkItemType);
+
+ UpdateNetworkNode(SubId, node1, extension1);
+ UpdateNetworkNode(SubId, node2, extension2);
+
+ switch (SubId)
+ {
+ case NETWORK_COLUMN_ID_LOCAL_SERVICE:
+ return PhCompareStringWithNull(extension1->LocalServiceName, extension2->LocalServiceName, TRUE);
+ case NETWORK_COLUMN_ID_REMOTE_SERVICE:
+ return PhCompareStringWithNull(extension1->RemoteServiceName, extension2->RemoteServiceName, TRUE);
+ case NETWORK_COLUMN_ID_REMOTE_COUNTRY:
+ return PhCompareStringWithNull(extension1->RemoteCountryCode, extension2->RemoteCountryCode, TRUE);
+ }
+
+ return 0;
+}
+
+VOID NTAPI LoadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ LoadGeoLiteDb();
+}
+
+VOID NTAPI UnloadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ NOTHING;
+}
+
+VOID NTAPI NetworkTreeNewInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_INFORMATION info = Parameter;
+ PH_TREENEW_COLUMN column;
+
+ *(HWND*)Context = info->TreeNewHandle;
+
+ memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
+ column.Text = L"Local Service";
+ column.Width = 140;
+ column.Alignment = PH_ALIGN_LEFT;
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, NETWORK_COLUMN_ID_LOCAL_SERVICE, NULL, NetworkServiceSortFunction);
+
+ memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
+ column.Text = L"Remote Service";
+ column.Width = 140;
+ column.Alignment = PH_ALIGN_LEFT;
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, NETWORK_COLUMN_ID_REMOTE_SERVICE, NULL, NetworkServiceSortFunction);
+
+ memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
+ column.Text = L"Country";
+ column.Width = 140;
+ column.Alignment = PH_ALIGN_LEFT;
+ column.CustomDraw = TRUE; // Owner-draw this column to show country flags
+ PhPluginAddTreeNewColumn(PluginInstance, info->CmData, &column, NETWORK_COLUMN_ID_REMOTE_COUNTRY, NULL, NetworkServiceSortFunction);
+}
+
+VOID NTAPI NetworkItemCreateCallback(
+ _In_ PVOID Object,
+ _In_ PH_EM_OBJECT_TYPE ObjectType,
+ _In_ PVOID Extension
+ )
+{
+ //PPH_NETWORK_ITEM networkItem = Object;
+ PNETWORK_EXTENSION extension = Extension;
+
+ memset(extension, 0, sizeof(NETWORK_EXTENSION));
+}
+
+VOID NTAPI NetworkItemDeleteCallback(
+ _In_ PVOID Object,
+ _In_ PH_EM_OBJECT_TYPE ObjectType,
+ _In_ PVOID Extension
+ )
+{
+ //PPH_NETWORK_ITEM networkItem = Object;
+ PNETWORK_EXTENSION extension = Extension;
+
+ PhClearReference(&extension->LocalServiceName);
+ PhClearReference(&extension->RemoteServiceName);
+ PhClearReference(&extension->RemoteCountryCode);
+ PhClearReference(&extension->RemoteCountryName);
+
+ if (extension->CountryIcon)
+ DestroyIcon(extension->CountryIcon);
+}
+
+VOID NTAPI NetworkNodeCreateCallback(
+ _In_ PVOID Object,
+ _In_ PH_EM_OBJECT_TYPE ObjectType,
+ _In_ PVOID Extension
+ )
+{
+ PPH_NETWORK_NODE networkNode = Object;
+ PNETWORK_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, networkNode->NetworkItem, EmNetworkItemType);
+
+ // Update the country data for this connection
+ if (!extension->CountryValid)
+ {
+ PPH_STRING remoteCountryCode;
+ PPH_STRING remoteCountryName;
+
+ if (LookupCountryCode(networkNode->NetworkItem->RemoteEndpoint.Address, &remoteCountryCode, &remoteCountryName))
+ {
+ PhSwapReference(&extension->RemoteCountryCode, remoteCountryCode);
+ PhSwapReference(&extension->RemoteCountryName, remoteCountryName);
+ }
+
+ extension->CountryValid = TRUE;
+ }
+}
+
+VOID NTAPI TreeNewMessageCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_TREENEW_MESSAGE message = Parameter;
+
+ switch (message->Message)
+ {
+ case TreeNewGetCellText:
+ {
+ if (message->TreeNewHandle == NetworkTreeNewHandle)
+ {
+ PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1;
+ PPH_NETWORK_NODE networkNode = (PPH_NETWORK_NODE)getCellText->Node;
+ PNETWORK_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, networkNode->NetworkItem, EmNetworkItemType);
+
+ UpdateNetworkNode(message->SubId, networkNode, extension);
+
+ switch (message->SubId)
+ {
+ case NETWORK_COLUMN_ID_LOCAL_SERVICE:
+ getCellText->Text = PhGetStringRef(extension->LocalServiceName);
+ break;
+ case NETWORK_COLUMN_ID_REMOTE_SERVICE:
+ getCellText->Text = PhGetStringRef(extension->RemoteServiceName);
+ break;
+ }
+ }
+ }
+ break;
+ case TreeNewCustomDraw:
+ {
+ PPH_TREENEW_CUSTOM_DRAW customDraw = message->Parameter1;
+ PPH_NETWORK_NODE networkNode = (PPH_NETWORK_NODE)customDraw->Node;
+ PNETWORK_EXTENSION extension = PhPluginGetObjectExtension(PluginInstance, networkNode->NetworkItem, EmNetworkItemType);
+ HDC hdc = customDraw->Dc;
+ RECT rect = customDraw->CellRect;
+
+ // Check if this is the country column
+ if (message->SubId != NETWORK_COLUMN_ID_REMOTE_COUNTRY)
+ break;
+
+ // Check if there's something to draw
+ if (rect.right - rect.left <= 1)
+ {
+ // nothing to draw
+ break;
+ }
+
+ // Padding
+ rect.left += 5;
+
+ // Draw the column data
+ if (GeoDbLoaded && extension->RemoteCountryCode && extension->RemoteCountryName)
+ {
+ if (!extension->CountryIcon)
+ {
+ HBITMAP countryBitmap;
+
+ if (countryBitmap = LoadImageFromResources(16, 11, extension->RemoteCountryCode))
+ {
+ HDC screenDc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
+ HBITMAP screenBitmap = CreateCompatibleBitmap(screenDc, 16, 11);
+
+ ICONINFO iconInfo = { 0 };
+ iconInfo.fIcon = TRUE;
+ iconInfo.hbmColor = countryBitmap;
+ iconInfo.hbmMask = screenBitmap;
+
+ extension->CountryIcon = CreateIconIndirect(&iconInfo);
+
+ DeleteObject(screenBitmap);
+ DeleteDC(screenDc);
+
+ DeleteObject(countryBitmap);
+ }
+ }
+
+ if (extension->CountryIcon)
+ {
+ DrawIconEx(
+ hdc,
+ rect.left,
+ rect.top + ((rect.bottom - rect.top) - 11) / 2,
+ extension->CountryIcon,
+ 16,
+ 11,
+ 0,
+ NULL,
+ DI_NORMAL
+ );
+
+ rect.left += 16 + 2;
+ }
+
+ DrawText(
+ hdc,
+ extension->RemoteCountryName->Buffer,
+ (INT)extension->RemoteCountryName->Length / 2,
+ &rect,
+ DT_LEFT | DT_VCENTER | DT_SINGLELINE
+ );
+ }
+
+ if (!GeoDbLoaded)
+ {
+ DrawText(
+ hdc,
+ L"Geoip database error.",
+ -1,
+ &rect,
+ DT_LEFT | DT_VCENTER | DT_SINGLELINE
+ );
+ }
+ }
+ break;
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Network Extras";
+ info->Author = L"dmex";
+ info->Description = L"Plugin for extra network information.";
+ info->HasOptions = FALSE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
+ LoadCallback,
+ NULL,
+ &PluginLoadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
+ UnloadCallback,
+ NULL,
+ &PluginUnloadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackNetworkTreeNewInitializing),
+ NetworkTreeNewInitializingCallback,
+ &NetworkTreeNewHandle,
+ &NetworkTreeNewInitializingCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackTreeNewMessage),
+ TreeNewMessageCallback,
+ NULL,
+ &TreeNewMessageCallbackRegistration
+ );
+
+ PhPluginSetObjectExtension(
+ PluginInstance,
+ EmNetworkItemType,
+ sizeof(NETWORK_EXTENSION),
+ NetworkItemCreateCallback,
+ NetworkItemDeleteCallback
+ );
+ PhPluginSetObjectExtension(
+ PluginInstance,
+ EmNetworkNodeType,
+ sizeof(NETWORK_EXTENSION),
+ NetworkNodeCreateCallback,
+ NULL
+ );
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/main.h b/plugins-extra/NetExtrasPlugin/main.h
new file mode 100644
index 0000000..471b423
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/main.h
@@ -0,0 +1,95 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#ifndef _EXTRA_H_
+#define _EXTRA_H_
+
+#define PLUGIN_NAME L"dmex.NetworkExtrasPlugin"
+#define DATABASE_PATH L"plugins\\plugindata\\GeoLite2-Country.mmdb"
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+
+typedef struct _NETWORK_EXTRA_CONTEXT
+{
+ PH_LAYOUT_MANAGER LayoutManager;
+} NETWORK_EXTRA_CONTEXT, *PNETWORK_EXTRA_CONTEXT;
+
+typedef struct _NETWORK_EXTENSION
+{
+ BOOLEAN LocalValid;
+ BOOLEAN RemoteValid;
+ BOOLEAN CountryValid;
+ PPH_STRING LocalServiceName;
+ PPH_STRING RemoteServiceName;
+
+ HICON CountryIcon;
+ PPH_STRING RemoteCountryCode;
+ PPH_STRING RemoteCountryName;
+} NETWORK_EXTENSION, *PNETWORK_EXTENSION;
+
+typedef enum _NETWORK_COLUMN_ID
+{
+ NETWORK_COLUMN_ID_LOCAL_SERVICE = 1,
+ NETWORK_COLUMN_ID_REMOTE_SERVICE = 2,
+ NETWORK_COLUMN_ID_REMOTE_COUNTRY = 3,
+} NETWORK_COLUMN_ID;
+
+typedef struct _RESOLVED_PORT
+{
+ PWSTR Name;
+ USHORT Port;
+} RESOLVED_PORT;
+
+extern PPH_PLUGIN PluginInstance;
+extern RESOLVED_PORT ResolvedPortsTable[6265];
+extern BOOLEAN GeoDbLoaded;
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PPH_STRING Name
+ );
+
+VOID UpdateNetworkNode(
+ _In_ NETWORK_COLUMN_ID ColumnID,
+ _In_ PPH_NETWORK_NODE Node,
+ _In_ PNETWORK_EXTENSION Extension
+ );
+
+VOID LoadGeoLiteDb(VOID);
+VOID FreeGeoLiteDb(VOID);
+
+BOOLEAN LookupCountryCode(
+ _In_ PH_IP_ADDRESS RemoteAddress,
+ _Out_ PPH_STRING* CountryCode,
+ _Out_ PPH_STRING* CountryName
+ );
+
+#endif
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/maxminddb-compat-util.h b/plugins-extra/NetExtrasPlugin/maxminddb-compat-util.h
new file mode 100644
index 0000000..e3f0320
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/maxminddb-compat-util.h
@@ -0,0 +1,167 @@
+#include
+#include
+
+/* *INDENT-OFF* */
+
+/* The memmem, strdup, and strndup functions were all copied from the
+ * FreeBSD source, along with the relevant copyright notice.
+ *
+ * It'd be nicer to simply use the functions available on the system if they
+ * exist, but there doesn't seem to be a good way to detect them without also
+ * defining things like _GNU_SOURCE, which we want to avoid, because then we
+ * end up _accidentally_ using GNU features without noticing, which then
+ * breaks on systems like OSX.
+ *
+ * C is fun! */
+
+/* Applies to memmem implementation */
+/*-
+ * Copyright (c) 2005 Pascal Gloor
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static void *
+mmdb_memmem(const void *l, size_t l_len, const void *s, size_t s_len)
+{
+ register char *cur, *last;
+ const char *cl = (const char *)l;
+ const char *cs = (const char *)s;
+
+ /* we need something to compare */
+ if (l_len == 0 || s_len == 0)
+ return NULL;
+
+ /* "s" must be smaller or equal to "l" */
+ if (l_len < s_len)
+ return NULL;
+
+ /* special case where s_len == 1 */
+ if (s_len == 1)
+ return memchr(l, (int)*cs, l_len);
+
+ /* the last position where its possible to find "s" in "l" */
+ last = (char *)cl + l_len - s_len;
+
+ for (cur = (char *)cl; cur <= last; cur++)
+ if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
+ return cur;
+
+ return NULL;
+}
+
+/* Applies to strnlen implementation */
+/*-
+ * Copyright (c) 2009 David Schultz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static size_t
+mmdb_strnlen(const char *s, size_t maxlen)
+{
+ size_t len;
+
+ for (len = 0; len < maxlen; len++, s++) {
+ if (!*s)
+ break;
+ }
+ return (len);
+}
+
+/* Applies to strdup and strndup implementation */
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static char *
+mmdb_strdup(const char *str)
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(str) + 1;
+ if ((copy = malloc(len)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ return (copy);
+}
+
+static char *
+mmdb_strndup(const char *str, size_t n)
+{
+ size_t len;
+ char *copy;
+
+ len = mmdb_strnlen(str, n);
+ if ((copy = malloc(len + 1)) == NULL)
+ return (NULL);
+ memcpy(copy, str, len);
+ copy[len] = '\0';
+ return (copy);
+}
+/* *INDENT-ON* */
diff --git a/plugins-extra/NetExtrasPlugin/maxminddb.c b/plugins-extra/NetExtrasPlugin/maxminddb.c
new file mode 100644
index 0000000..41788bd
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/maxminddb.c
@@ -0,0 +1,2150 @@
+#define _CRT_SECURE_NO_WARNINGS
+#pragma warning(push)
+#pragma warning(disable : 4244)
+
+#if HAVE_CONFIG_H
+#include
+#endif
+#include "maxminddb.h"
+#include "maxminddb-compat-util.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _WIN32
+#include
+#include
+#else
+#include
+#include
+#include
+#endif
+
+#define MMDB_DATA_SECTION_SEPARATOR (16)
+#define MAXIMUM_DATA_STRUCTURE_DEPTH (512)
+
+#ifdef MMDB_DEBUG
+#define LOCAL
+#define NO_PROTO
+#define DEBUG_FUNC
+#define DEBUG_MSG(msg) fprintf(stderr, msg "\n")
+#define DEBUG_MSGF(fmt, ...) fprintf(stderr, fmt "\n", __VA_ARGS__)
+#define DEBUG_BINARY(fmt, byte) \
+ do { \
+ char *binary = byte_to_binary(byte); \
+ if (NULL == binary) { \
+ fprintf(stderr, "Malloc failed in DEBUG_BINARY\n"); \
+ abort(); \
+ } \
+ fprintf(stderr, fmt "\n", binary); \
+ free(binary); \
+ } while (0)
+#define DEBUG_NL fprintf(stderr, "\n")
+#else
+#define LOCAL static
+#define NO_PROTO static
+#define DEBUG_MSG(...)
+#define DEBUG_MSGF(...)
+#define DEBUG_BINARY(...)
+#define DEBUG_NL
+#endif
+
+#ifdef MMDB_DEBUG
+DEBUG_FUNC char *byte_to_binary(uint8_t byte)
+{
+ char *bits = malloc(sizeof(char) * 9);
+ if (NULL == bits) {
+ return bits;
+ }
+
+ for (uint8_t i = 0; i < 8; i++) {
+ bits[i] = byte & (128 >> i) ? '1' : '0';
+ }
+ bits[8] = '\0';
+
+ return bits;
+}
+
+DEBUG_FUNC char *type_num_to_name(uint8_t num)
+{
+ switch (num) {
+ case 0:
+ return "extended";
+ case 1:
+ return "pointer";
+ case 2:
+ return "utf8_string";
+ case 3:
+ return "double";
+ case 4:
+ return "bytes";
+ case 5:
+ return "uint16";
+ case 6:
+ return "uint32";
+ case 7:
+ return "map";
+ case 8:
+ return "int32";
+ case 9:
+ return "uint64";
+ case 10:
+ return "uint128";
+ case 11:
+ return "array";
+ case 12:
+ return "container";
+ case 13:
+ return "end_marker";
+ case 14:
+ return "boolean";
+ case 15:
+ return "float";
+ default:
+ return "unknown type";
+ }
+}
+#endif
+
+/* None of the values we check on the lhs are bigger than uint32_t, so on
+ * platforms where SIZE_MAX is a 64-bit integer, this would be a no-op, and it
+ * makes the compiler complain if we do the check anyway. */
+#if SIZE_MAX == UINT32_MAX
+#define MAYBE_CHECK_SIZE_OVERFLOW(lhs, rhs, error) \
+ if ((lhs) > (rhs)) { \
+ return error; \
+ }
+#else
+#define MAYBE_CHECK_SIZE_OVERFLOW(...)
+#endif
+
+typedef struct record_info_s {
+ uint16_t record_length;
+ uint32_t (*left_record_getter)(const uint8_t *);
+ uint32_t (*right_record_getter)(const uint8_t *);
+ uint8_t right_record_offset;
+} record_info_s;
+
+#define METADATA_MARKER "\xab\xcd\xefMaxMind.com"
+/* This is 128kb */
+#define METADATA_BLOCK_MAX_SIZE 131072
+
+/* *INDENT-OFF* */
+/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
+LOCAL int map_file(MMDB_s *const mmdb);
+LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
+ ssize_t file_size, uint32_t *metadata_size);
+LOCAL int read_metadata(MMDB_s *mmdb);
+LOCAL MMDB_s make_fake_metadata_db(MMDB_s *mmdb);
+LOCAL int value_for_key_as_uint16(MMDB_entry_s *start, char *key,
+ uint16_t *value);
+LOCAL int value_for_key_as_uint32(MMDB_entry_s *start, char *key,
+ uint32_t *value);
+LOCAL int value_for_key_as_uint64(MMDB_entry_s *start, char *key,
+ uint64_t *value);
+LOCAL int value_for_key_as_string(MMDB_entry_s *start, char *key,
+ char const **value);
+LOCAL int populate_languages_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
+ MMDB_entry_s *metadata_start);
+LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
+ MMDB_entry_s *metadata_start);
+LOCAL int resolve_any_address(const char *ipstr, struct addrinfo **addresses);
+LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
+ sa_family_t address_family,
+ MMDB_lookup_result_s *result);
+LOCAL record_info_s record_info_for_database(MMDB_s *mmdb);
+LOCAL int find_ipv4_start_node(MMDB_s *mmdb);
+LOCAL int maybe_populate_result(MMDB_s *mmdb, uint32_t record,
+ uint16_t netmask, MMDB_lookup_result_s *result);
+LOCAL uint8_t record_type(MMDB_s *const mmdb, uint64_t record);
+LOCAL uint32_t get_left_28_bit_record(const uint8_t *record);
+LOCAL uint32_t get_right_28_bit_record(const uint8_t *record);
+LOCAL uint32_t data_section_offset_for_record(MMDB_s *const mmdb,
+ uint64_t record);
+LOCAL int path_length(va_list va_path);
+LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
+ MMDB_entry_data_s *entry_data);
+LOCAL int lookup_path_in_map(const char *path_elem, MMDB_s *mmdb,
+ MMDB_entry_data_s *entry_data);
+LOCAL int skip_map_or_array(MMDB_s *mmdb, MMDB_entry_data_s *entry_data);
+LOCAL int decode_one_follow(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_s *entry_data);
+LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_s *entry_data);
+LOCAL int get_ext_type(int raw_ext_type);
+LOCAL uint32_t get_ptr_from(uint8_t ctrl, uint8_t const *const ptr,
+ int ptr_size);
+LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_list_s *const entry_data_list,
+ int depth);
+LOCAL float get_ieee754_float(const uint8_t *restrict p);
+LOCAL double get_ieee754_double(const uint8_t *restrict p);
+LOCAL uint32_t get_uint32(const uint8_t *p);
+LOCAL uint32_t get_uint24(const uint8_t *p);
+LOCAL uint32_t get_uint16(const uint8_t *p);
+LOCAL uint64_t get_uintX(const uint8_t *p, int length);
+LOCAL int32_t get_sintX(const uint8_t *p, int length);
+LOCAL MMDB_entry_data_list_s *new_entry_data_list(void);
+LOCAL void free_mmdb_struct(MMDB_s *const mmdb);
+LOCAL void free_languages_metadata(MMDB_s *mmdb);
+LOCAL void free_descriptions_metadata(MMDB_s *mmdb);
+LOCAL MMDB_entry_data_list_s *dump_entry_data_list(
+ FILE *stream, MMDB_entry_data_list_s *entry_data_list, int indent,
+ int *status);
+LOCAL void print_indentation(FILE *stream, int i);
+LOCAL char *bytes_to_hex(uint8_t *bytes, uint32_t size);
+/* --prototypes end - don't remove this comment-- */
+/* *INDENT-ON* */
+
+#define CHECKED_DECODE_ONE(mmdb, offset, entry_data) \
+ do { \
+ int status = decode_one(mmdb, offset, entry_data); \
+ if (MMDB_SUCCESS != status) { \
+ DEBUG_MSGF("CHECKED_DECODE_ONE failed." \
+ " status = %d (%s)", status, MMDB_strerror(status)); \
+ return status; \
+ } \
+ } while (0)
+
+#define CHECKED_DECODE_ONE_FOLLOW(mmdb, offset, entry_data) \
+ do { \
+ int status = decode_one_follow(mmdb, offset, entry_data); \
+ if (MMDB_SUCCESS != status) { \
+ DEBUG_MSGF("CHECKED_DECODE_ONE_FOLLOW failed." \
+ " status = %d (%s)", status, MMDB_strerror(status)); \
+ return status; \
+ } \
+ } while (0)
+
+#define FREE_AND_SET_NULL(p) { free((void *)(p)); (p) = NULL; }
+
+int MMDB_open(const wchar_t* const filename, uint32_t flags, MMDB_s *const mmdb)
+{
+ int status = MMDB_SUCCESS;
+
+ mmdb->file_content = NULL;
+ mmdb->data_section = NULL;
+ mmdb->metadata.database_type = NULL;
+ mmdb->metadata.languages.count = 0;
+ mmdb->metadata.description.count = 0;
+
+ mmdb->filename = _wcsdup(filename); // dmex: modified for wchar_t
+ if (NULL == mmdb->filename) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ if ((flags & MMDB_MODE_MASK) == 0) {
+ flags |= MMDB_MODE_MMAP;
+ }
+ mmdb->flags = flags;
+
+ if (MMDB_SUCCESS != (status = map_file(mmdb)) ) {
+ goto cleanup;
+ }
+
+#ifdef _WIN32
+ WSADATA wsa;
+ WSAStartup(MAKEWORD(2, 2), &wsa);
+#endif
+
+ uint32_t metadata_size = 0;
+ const uint8_t *metadata = find_metadata(mmdb->file_content, mmdb->file_size,
+ &metadata_size);
+ if (NULL == metadata) {
+ status = MMDB_INVALID_METADATA_ERROR;
+ goto cleanup;
+ }
+
+ mmdb->metadata_section = metadata;
+ mmdb->metadata_section_size = metadata_size;
+
+ status = read_metadata(mmdb);
+ if (MMDB_SUCCESS != status) {
+ goto cleanup;
+ }
+
+ if (mmdb->metadata.binary_format_major_version != 2) {
+ status = MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
+ goto cleanup;
+ }
+
+ uint32_t search_tree_size = mmdb->metadata.node_count *
+ mmdb->full_record_byte_size;
+
+ mmdb->data_section = mmdb->file_content + search_tree_size
+ + MMDB_DATA_SECTION_SEPARATOR;
+ if (search_tree_size + MMDB_DATA_SECTION_SEPARATOR >
+ (uint32_t)mmdb->file_size) {
+ status = MMDB_INVALID_METADATA_ERROR;
+ goto cleanup;
+ }
+ mmdb->data_section_size = mmdb->file_size - search_tree_size -
+ MMDB_DATA_SECTION_SEPARATOR;
+ mmdb->metadata_section = metadata;
+ mmdb->ipv4_start_node.node_value = 0;
+ mmdb->ipv4_start_node.netmask = 0;
+
+ cleanup:
+ if (MMDB_SUCCESS != status) {
+ int saved_errno = errno;
+ free_mmdb_struct(mmdb);
+ errno = saved_errno;
+ }
+ return status;
+}
+
+#ifdef _WIN32
+
+LOCAL int map_file(MMDB_s *const mmdb)
+{
+ ssize_t size;
+ int status = MMDB_SUCCESS;
+ HANDLE mmh = NULL;
+ HANDLE fd = CreateFileW(mmdb->filename, GENERIC_READ, FILE_SHARE_READ, NULL, // dmex: modified for wchar_t
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (fd == INVALID_HANDLE_VALUE) {
+ status = MMDB_FILE_OPEN_ERROR;
+ goto cleanup;
+ }
+ size = GetFileSize(fd, NULL);
+ if (size == INVALID_FILE_SIZE) {
+ status = MMDB_FILE_OPEN_ERROR;
+ goto cleanup;
+ }
+ mmh = CreateFileMappingA(fd, NULL, PAGE_READONLY, 0, size, NULL);
+ /* Microsoft documentation for CreateFileMapping indicates this returns
+ NULL not INVALID_HANDLE_VALUE on error */
+ if (NULL == mmh) {
+ status = MMDB_IO_ERROR;
+ goto cleanup;
+ }
+ uint8_t *file_content =
+ (uint8_t *)MapViewOfFile(mmh, FILE_MAP_READ, 0, 0, 0);
+ if (file_content == NULL) {
+ status = MMDB_IO_ERROR;
+ goto cleanup;
+ }
+
+ mmdb->file_size = size;
+ mmdb->file_content = file_content;
+
+ cleanup:;
+ int saved_errno = errno;
+ if (INVALID_HANDLE_VALUE != fd) {
+ CloseHandle(fd);
+ }
+ if (NULL != mmh) {
+ CloseHandle(mmh);
+ }
+ errno = saved_errno;
+
+ return status;
+}
+
+#else
+
+LOCAL int map_file(MMDB_s *const mmdb)
+{
+ ssize_t size;
+ int status = MMDB_SUCCESS;
+
+ int fd = open(mmdb->filename, O_RDONLY);
+ struct stat s;
+ if (fd < 0 || fstat(fd, &s)) {
+ status = MMDB_FILE_OPEN_ERROR;
+ goto cleanup;
+ }
+
+ size = s.st_size;
+ if (size < 0 || size != s.st_size) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ uint8_t *file_content =
+ (uint8_t *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+ if (MAP_FAILED == file_content) {
+ if (ENOMEM == errno) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ } else {
+ status = MMDB_IO_ERROR;
+ }
+ goto cleanup;
+ }
+
+ mmdb->file_size = size;
+ mmdb->file_content = file_content;
+
+ cleanup:;
+ int saved_errno = errno;
+ if (fd >= 0) {
+ close(fd);
+ }
+ errno = saved_errno;
+
+ return status;
+}
+
+#endif
+
+LOCAL const uint8_t *find_metadata(const uint8_t *file_content,
+ ssize_t file_size, uint32_t *metadata_size)
+{
+ const ssize_t marker_len = sizeof(METADATA_MARKER) - 1;
+ ssize_t max_size = file_size >
+ METADATA_BLOCK_MAX_SIZE ? METADATA_BLOCK_MAX_SIZE :
+ file_size;
+
+ uint8_t *search_area = (uint8_t *)(file_content + (file_size - max_size));
+ uint8_t *start = search_area;
+ uint8_t *tmp;
+ do {
+ tmp = mmdb_memmem(search_area, max_size,
+ METADATA_MARKER, marker_len);
+
+ if (NULL != tmp) {
+ max_size -= tmp - search_area;
+ search_area = tmp;
+
+ /* Continue searching just after the marker we just read, in case
+ * there are multiple markers in the same file. This would be odd
+ * but is certainly not impossible. */
+ max_size -= marker_len;
+ search_area += marker_len;
+ }
+ } while (NULL != tmp);
+
+ if (search_area == start) {
+ return NULL;
+ }
+
+ *metadata_size = max_size;
+
+ return search_area;
+}
+
+LOCAL int read_metadata(MMDB_s *mmdb)
+{
+ /* We need to create a fake MMDB_s struct in order to decode values from
+ the metadata. The metadata is basically just like the data section, so we
+ want to use the same functions we use for the data section to get metadata
+ values. */
+ MMDB_s metadata_db = make_fake_metadata_db(mmdb);
+
+ MMDB_entry_s metadata_start = {
+ .mmdb = &metadata_db,
+ .offset = 0
+ };
+
+ int status =
+ value_for_key_as_uint32(&metadata_start, "node_count",
+ &mmdb->metadata.node_count);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (!mmdb->metadata.node_count) {
+ DEBUG_MSG("could not find node_count value in metadata");
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ status = value_for_key_as_uint16(&metadata_start, "record_size",
+ &mmdb->metadata.record_size);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (!mmdb->metadata.record_size) {
+ DEBUG_MSG("could not find record_size value in metadata");
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ if (mmdb->metadata.record_size != 24 && mmdb->metadata.record_size != 28
+ && mmdb->metadata.record_size != 32) {
+ DEBUG_MSGF("bad record size in metadata: %i",
+ mmdb->metadata.record_size);
+ return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
+ }
+
+ status = value_for_key_as_uint16(&metadata_start, "ip_version",
+ &mmdb->metadata.ip_version);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (!mmdb->metadata.ip_version) {
+ DEBUG_MSG("could not find ip_version value in metadata");
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+ if (!(mmdb->metadata.ip_version == 4 || mmdb->metadata.ip_version == 6)) {
+ DEBUG_MSGF("ip_version value in metadata is not 4 or 6 - it was %i",
+ mmdb->metadata.ip_version);
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ status = value_for_key_as_string(&metadata_start, "database_type",
+ &mmdb->metadata.database_type);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("error finding database_type value in metadata");
+ return status;
+ }
+
+ status =
+ populate_languages_metadata(mmdb, &metadata_db, &metadata_start);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("could not populate languages from metadata");
+ return status;
+ }
+
+ status = value_for_key_as_uint16(
+ &metadata_start, "binary_format_major_version",
+ &mmdb->metadata.binary_format_major_version);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (!mmdb->metadata.binary_format_major_version) {
+ DEBUG_MSG(
+ "could not find binary_format_major_version value in metadata");
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ status = value_for_key_as_uint16(
+ &metadata_start, "binary_format_minor_version",
+ &mmdb->metadata.binary_format_minor_version);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+
+ status = value_for_key_as_uint64(&metadata_start, "build_epoch",
+ &mmdb->metadata.build_epoch);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (!mmdb->metadata.build_epoch) {
+ DEBUG_MSG("could not find build_epoch value in metadata");
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ status = populate_description_metadata(mmdb, &metadata_db, &metadata_start);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("could not populate description from metadata");
+ return status;
+ }
+
+ mmdb->full_record_byte_size = mmdb->metadata.record_size * 2 / 8U;
+
+ mmdb->depth = mmdb->metadata.ip_version == 4 ? 32 : 128;
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL MMDB_s make_fake_metadata_db(MMDB_s *mmdb)
+{
+ MMDB_s fake_metadata_db = {
+ .data_section = mmdb->metadata_section,
+ .data_section_size = mmdb->metadata_section_size
+ };
+
+ return fake_metadata_db;
+}
+
+LOCAL int value_for_key_as_uint16(MMDB_entry_s *start, char *key,
+ uint16_t *value)
+{
+ MMDB_entry_data_s entry_data;
+ const char *path[] = { key, NULL };
+ int status = MMDB_aget_value(start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (MMDB_DATA_TYPE_UINT16 != entry_data.type) {
+ DEBUG_MSGF("expect uint16 for %s but received %s", key,
+ type_num_to_name(
+ entry_data.type));
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+ *value = entry_data.uint16;
+ return MMDB_SUCCESS;
+}
+
+LOCAL int value_for_key_as_uint32(MMDB_entry_s *start, char *key,
+ uint32_t *value)
+{
+ MMDB_entry_data_s entry_data;
+ const char *path[] = { key, NULL };
+ int status = MMDB_aget_value(start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (MMDB_DATA_TYPE_UINT32 != entry_data.type) {
+ DEBUG_MSGF("expect uint32 for %s but received %s", key,
+ type_num_to_name(
+ entry_data.type));
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+ *value = entry_data.uint32;
+ return MMDB_SUCCESS;
+}
+
+LOCAL int value_for_key_as_uint64(MMDB_entry_s *start, char *key,
+ uint64_t *value)
+{
+ MMDB_entry_data_s entry_data;
+ const char *path[] = { key, NULL };
+ int status = MMDB_aget_value(start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (MMDB_DATA_TYPE_UINT64 != entry_data.type) {
+ DEBUG_MSGF("expect uint64 for %s but received %s", key,
+ type_num_to_name(
+ entry_data.type));
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+ *value = entry_data.uint64;
+ return MMDB_SUCCESS;
+}
+
+LOCAL int value_for_key_as_string(MMDB_entry_s *start, char *key,
+ char const **value)
+{
+ MMDB_entry_data_s entry_data;
+ const char *path[] = { key, NULL };
+ int status = MMDB_aget_value(start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (MMDB_DATA_TYPE_UTF8_STRING != entry_data.type) {
+ DEBUG_MSGF("expect string for %s but received %s", key,
+ type_num_to_name(
+ entry_data.type));
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+ *value = mmdb_strndup((char *)entry_data.utf8_string, entry_data.data_size);
+ if (NULL == *value) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+ return MMDB_SUCCESS;
+}
+
+LOCAL int populate_languages_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
+ MMDB_entry_s *metadata_start)
+{
+ MMDB_entry_data_s entry_data;
+
+ const char *path[] = { "languages", NULL };
+ int status = MMDB_aget_value(metadata_start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ if (MMDB_DATA_TYPE_ARRAY != entry_data.type) {
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ MMDB_entry_s array_start = {
+ .mmdb = metadata_db,
+ .offset = entry_data.offset
+ };
+
+ MMDB_entry_data_list_s *member;
+ status = MMDB_get_entry_data_list(&array_start, &member);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+
+ MMDB_entry_data_list_s *first_member = member;
+
+ uint32_t array_size = member->entry_data.data_size;
+ MAYBE_CHECK_SIZE_OVERFLOW(array_size, SIZE_MAX / sizeof(char *),
+ MMDB_INVALID_METADATA_ERROR);
+
+ mmdb->metadata.languages.count = 0;
+ mmdb->metadata.languages.names = malloc(array_size * sizeof(char *));
+ if (NULL == mmdb->metadata.languages.names) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+
+ for (uint32_t i = 0; i < array_size; i++) {
+ member = member->next;
+ if (MMDB_DATA_TYPE_UTF8_STRING != member->entry_data.type) {
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ mmdb->metadata.languages.names[i] =
+ mmdb_strndup((char *)member->entry_data.utf8_string,
+ member->entry_data.data_size);
+
+ if (NULL == mmdb->metadata.languages.names[i]) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+ // We assign this as we go so that if we fail a malloc and need to
+ // free it, the count is right.
+ mmdb->metadata.languages.count = i + 1;
+ }
+
+ MMDB_free_entry_data_list(first_member);
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int populate_description_metadata(MMDB_s *mmdb, MMDB_s *metadata_db,
+ MMDB_entry_s *metadata_start)
+{
+ MMDB_entry_data_s entry_data;
+
+ const char *path[] = { "description", NULL };
+ int status = MMDB_aget_value(metadata_start, &entry_data, path);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+
+ if (MMDB_DATA_TYPE_MAP != entry_data.type) {
+ DEBUG_MSGF("Unexpected entry_data type: %d", entry_data.type);
+ return MMDB_INVALID_METADATA_ERROR;
+ }
+
+ MMDB_entry_s map_start = {
+ .mmdb = metadata_db,
+ .offset = entry_data.offset
+ };
+
+ MMDB_entry_data_list_s *member;
+ status = MMDB_get_entry_data_list(&map_start, &member);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSGF(
+ "MMDB_get_entry_data_list failed while populating description."
+ " status = %d (%s)", status, MMDB_strerror(status));
+ return status;
+ }
+
+ MMDB_entry_data_list_s *first_member = member;
+
+ uint32_t map_size = member->entry_data.data_size;
+ mmdb->metadata.description.count = 0;
+ if (0 == map_size) {
+ mmdb->metadata.description.descriptions = NULL;
+ goto cleanup;
+ }
+ MAYBE_CHECK_SIZE_OVERFLOW(map_size, SIZE_MAX / sizeof(MMDB_description_s *),
+ MMDB_INVALID_METADATA_ERROR);
+
+ mmdb->metadata.description.descriptions =
+ malloc(map_size * sizeof(MMDB_description_s *));
+ if (NULL == mmdb->metadata.description.descriptions) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ for (uint32_t i = 0; i < map_size; i++) {
+ mmdb->metadata.description.descriptions[i] =
+ malloc(sizeof(MMDB_description_s));
+ if (NULL == mmdb->metadata.description.descriptions[i]) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ mmdb->metadata.description.count = i + 1;
+ mmdb->metadata.description.descriptions[i]->language = NULL;
+ mmdb->metadata.description.descriptions[i]->description = NULL;
+
+ member = member->next;
+
+ if (MMDB_DATA_TYPE_UTF8_STRING != member->entry_data.type) {
+ status = MMDB_INVALID_METADATA_ERROR;
+ goto cleanup;
+ }
+
+ mmdb->metadata.description.descriptions[i]->language =
+ mmdb_strndup((char *)member->entry_data.utf8_string,
+ member->entry_data.data_size);
+
+ if (NULL == mmdb->metadata.description.descriptions[i]->language) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ member = member->next;
+
+ if (MMDB_DATA_TYPE_UTF8_STRING != member->entry_data.type) {
+ status = MMDB_INVALID_METADATA_ERROR;
+ goto cleanup;
+ }
+
+ mmdb->metadata.description.descriptions[i]->description =
+ mmdb_strndup((char *)member->entry_data.utf8_string,
+ member->entry_data.data_size);
+
+ if (NULL == mmdb->metadata.description.descriptions[i]->description) {
+ status = MMDB_OUT_OF_MEMORY_ERROR;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ MMDB_free_entry_data_list(first_member);
+
+ return status;
+}
+
+MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
+ const char *const ipstr,
+ int *const gai_error,
+ int *const mmdb_error)
+{
+ MMDB_lookup_result_s result = {
+ .found_entry = false,
+ .netmask = 0,
+ .entry = {
+ .mmdb = mmdb,
+ .offset = 0
+ }
+ };
+
+ struct addrinfo *addresses = NULL;
+ *gai_error = resolve_any_address(ipstr, &addresses);
+
+ if (!*gai_error) {
+ result = MMDB_lookup_sockaddr(mmdb, addresses->ai_addr, mmdb_error);
+ }
+
+ if (NULL != addresses) {
+ freeaddrinfo(addresses);
+ }
+
+ return result;
+}
+
+LOCAL int resolve_any_address(const char *ipstr, struct addrinfo **addresses)
+{
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_NUMERICHOST,
+ // We set ai_socktype so that we only get one result back
+ .ai_socktype = SOCK_STREAM
+ };
+
+ int gai_status = getaddrinfo(ipstr, NULL, &hints, addresses);
+ if (gai_status) {
+ return gai_status;
+ }
+
+ return 0;
+}
+
+MMDB_lookup_result_s MMDB_lookup_sockaddr(
+ MMDB_s *const mmdb,
+ const struct sockaddr *const sockaddr,
+ int *const mmdb_error)
+{
+ MMDB_lookup_result_s result = {
+ .found_entry = false,
+ .netmask = 0,
+ .entry = {
+ .mmdb = mmdb,
+ .offset = 0
+ }
+ };
+
+ uint8_t mapped_address[16], *address;
+ if (mmdb->metadata.ip_version == 4) {
+ if (sockaddr->sa_family == AF_INET6) {
+ *mmdb_error = MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR;
+ return result;
+ }
+ address = (uint8_t *)&((struct sockaddr_in *)sockaddr)->sin_addr.s_addr;
+ } else {
+ if (sockaddr->sa_family == AF_INET6) {
+ address =
+ (uint8_t *)&((struct sockaddr_in6 *)sockaddr)->sin6_addr.
+ s6_addr;
+ } else {
+ address = mapped_address;
+ memset(address, 0, 12);
+ memcpy(address + 12,
+ &((struct sockaddr_in *)sockaddr)->sin_addr.s_addr, 4);
+ }
+ }
+
+ *mmdb_error =
+ find_address_in_search_tree(mmdb, address, sockaddr->sa_family,
+ &result);
+
+ return result;
+}
+
+LOCAL int find_address_in_search_tree(MMDB_s *mmdb, uint8_t *address,
+ sa_family_t address_family,
+ MMDB_lookup_result_s *result)
+{
+ record_info_s record_info = record_info_for_database(mmdb);
+ if (0 == record_info.right_record_offset) {
+ return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
+ }
+
+ DEBUG_NL;
+ DEBUG_MSG("Looking for address in search tree");
+
+ uint32_t value = 0;
+ uint16_t max_depth0 = mmdb->depth - 1;
+ uint16_t start_bit = max_depth0;
+
+ if (mmdb->metadata.ip_version == 6 && address_family == AF_INET) {
+ int mmdb_error = find_ipv4_start_node(mmdb);
+ if (MMDB_SUCCESS != mmdb_error) {
+ return mmdb_error;
+ }
+ DEBUG_MSGF("IPv4 start node is %u (netmask %u)",
+ mmdb->ipv4_start_node.node_value,
+ mmdb->ipv4_start_node.netmask);
+
+ uint8_t type = maybe_populate_result(mmdb,
+ mmdb->ipv4_start_node.node_value,
+ mmdb->ipv4_start_node.netmask,
+ result);
+ if (MMDB_RECORD_TYPE_INVALID == type) {
+ return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+ }
+
+ /* We have an IPv6 database with no IPv4 data */
+ if (MMDB_RECORD_TYPE_SEARCH_NODE != type) {
+ return MMDB_SUCCESS;
+ }
+
+ value = mmdb->ipv4_start_node.node_value;
+ start_bit -= mmdb->ipv4_start_node.netmask;
+ }
+
+ const uint8_t *search_tree = mmdb->file_content;
+ const uint8_t *record_pointer;
+ for (int current_bit = start_bit; current_bit >= 0; current_bit--) {
+ uint8_t bit_is_true =
+ address[(max_depth0 - current_bit) >> 3]
+ & (1U << (~(max_depth0 - current_bit) & 7)) ? 1 : 0;
+
+ DEBUG_MSGF("Looking at bit %i - bit's value is %i", current_bit,
+ bit_is_true);
+ DEBUG_MSGF(" current node = %u", value);
+
+ record_pointer = &search_tree[value * record_info.record_length];
+ if (record_pointer + record_info.record_length > mmdb->data_section) {
+ return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+ }
+ if (bit_is_true) {
+ record_pointer += record_info.right_record_offset;
+ value = record_info.right_record_getter(record_pointer);
+ } else {
+ value = record_info.left_record_getter(record_pointer);
+ }
+
+ uint8_t type = maybe_populate_result(mmdb, value, current_bit, result);
+ if (MMDB_RECORD_TYPE_INVALID == type) {
+ return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+ }
+
+ if (MMDB_RECORD_TYPE_SEARCH_NODE != type) {
+ return MMDB_SUCCESS;
+ }
+
+ DEBUG_MSGF(" proceeding to search tree node %i", value);
+ }
+
+ DEBUG_MSG(
+ "Reached the end of the address bits without leaving the search tree");
+
+ // We should not be able to reach this return. If we do, something very bad happened.
+ return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+}
+
+LOCAL record_info_s record_info_for_database(MMDB_s *mmdb)
+{
+ record_info_s record_info = {
+ .record_length = mmdb->full_record_byte_size,
+ .right_record_offset = 0
+ };
+
+ if (record_info.record_length == 6) {
+ record_info.left_record_getter = &get_uint24;
+ record_info.right_record_getter = &get_uint24;
+ record_info.right_record_offset = 3;
+ } else if (record_info.record_length == 7) {
+ record_info.left_record_getter = &get_left_28_bit_record;
+ record_info.right_record_getter = &get_right_28_bit_record;
+ record_info.right_record_offset = 3;
+ } else if (record_info.record_length == 8) {
+ record_info.left_record_getter = &get_uint32;
+ record_info.right_record_getter = &get_uint32;
+ record_info.right_record_offset = 4;
+ } else {
+ assert(false);
+ }
+
+ return record_info;
+}
+
+LOCAL int find_ipv4_start_node(MMDB_s *mmdb)
+{
+ /* In a pathological case of a database with a single node search tree,
+ * this check will be true even after we've found the IPv4 start node, but
+ * that doesn't seem worth trying to fix. */
+ if (mmdb->ipv4_start_node.node_value != 0) {
+ return MMDB_SUCCESS;
+ }
+
+ record_info_s record_info = record_info_for_database(mmdb);
+
+ const uint8_t *search_tree = mmdb->file_content;
+ uint32_t node_value = 0;
+ const uint8_t *record_pointer;
+ uint32_t netmask;
+ for (netmask = 0; netmask < 96; netmask++) {
+ record_pointer = &search_tree[node_value * record_info.record_length];
+ if (record_pointer + record_info.record_length > mmdb->data_section) {
+ return MMDB_CORRUPT_SEARCH_TREE_ERROR;
+ }
+ node_value = record_info.left_record_getter(record_pointer);
+ /* This can happen if there's no IPv4 data _or_ if there is a subnet
+ * with data that contains the entire IPv4 range (like ::/64) */
+ if (node_value >= mmdb->metadata.node_count) {
+ break;
+ }
+ }
+
+ mmdb->ipv4_start_node.node_value = node_value;
+ mmdb->ipv4_start_node.netmask = netmask;
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int maybe_populate_result(MMDB_s *mmdb, uint32_t record,
+ uint16_t netmask, MMDB_lookup_result_s *result)
+{
+ uint8_t type = record_type(mmdb, record);
+
+ if (MMDB_RECORD_TYPE_SEARCH_NODE == type ||
+ MMDB_RECORD_TYPE_INVALID == type) {
+ return type;
+ }
+
+ result->netmask = mmdb->depth - netmask;
+
+ result->entry.offset = data_section_offset_for_record(mmdb, record);
+
+ // type is either MMDB_RECORD_TYPE_DATA or MMDB_RECORD_TYPE_EMPTY
+ // at this point
+ result->found_entry = MMDB_RECORD_TYPE_DATA == type;
+
+ return type;
+}
+
+LOCAL uint8_t record_type(MMDB_s *const mmdb, uint64_t record)
+{
+ uint32_t node_count = mmdb->metadata.node_count;
+
+ /* Ideally we'd check to make sure that a record never points to a
+ * previously seen value, but that's more complicated. For now, we can
+ * at least check that we don't end up at the top of the tree again. */
+ if (record == 0) {
+ DEBUG_MSG("record has a value of 0");
+ return MMDB_RECORD_TYPE_INVALID;
+ }
+
+ if (record < node_count) {
+ return MMDB_RECORD_TYPE_SEARCH_NODE;
+ }
+
+ if (record == node_count) {
+ return MMDB_RECORD_TYPE_EMPTY;
+ }
+
+ if (record - node_count < mmdb->data_section_size) {
+ return MMDB_RECORD_TYPE_DATA;
+ }
+
+ DEBUG_MSG("record has a value that points outside of the database");
+ return MMDB_RECORD_TYPE_INVALID;
+}
+
+LOCAL uint32_t get_left_28_bit_record(const uint8_t *record)
+{
+ return record[0] * 65536 + record[1] * 256 + record[2] +
+ ((record[3] & 0xf0) << 20);
+}
+
+LOCAL uint32_t get_right_28_bit_record(const uint8_t *record)
+{
+ uint32_t value = get_uint32(record);
+ return value & 0xfffffff;
+}
+
+int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
+ MMDB_search_node_s *const node)
+{
+ record_info_s record_info = record_info_for_database(mmdb);
+ if (0 == record_info.right_record_offset) {
+ return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
+ }
+
+ if (node_number > mmdb->metadata.node_count) {
+ return MMDB_INVALID_NODE_NUMBER_ERROR;
+ }
+
+ const uint8_t *search_tree = mmdb->file_content;
+ const uint8_t *record_pointer =
+ &search_tree[node_number * record_info.record_length];
+ node->left_record = record_info.left_record_getter(record_pointer);
+ record_pointer += record_info.right_record_offset;
+ node->right_record = record_info.right_record_getter(record_pointer);
+
+ node->left_record_type = record_type(mmdb, node->left_record);
+ node->right_record_type = record_type(mmdb, node->right_record);
+
+ // Note that offset will be invalid if the record type is not
+ // MMDB_RECORD_TYPE_DATA, but that's ok. Any use of the record entry
+ // for other data types is a programming error.
+ node->left_record_entry = (struct MMDB_entry_s) {
+ .mmdb = mmdb,
+ .offset = data_section_offset_for_record(mmdb, node->left_record),
+ };
+ node->right_record_entry = (struct MMDB_entry_s) {
+ .mmdb = mmdb,
+ .offset = data_section_offset_for_record(mmdb, node->right_record),
+ };
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL uint32_t data_section_offset_for_record(MMDB_s *const mmdb,
+ uint64_t record)
+{
+ return record - mmdb->metadata.node_count - MMDB_DATA_SECTION_SEPARATOR;
+}
+
+int MMDB_get_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ ...)
+{
+ va_list path;
+ va_start(path, entry_data);
+ int status = MMDB_vget_value(start, entry_data, path);
+ va_end(path);
+ return status;
+}
+
+int MMDB_vget_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ va_list va_path)
+{
+ int length = path_length(va_path);
+ const char *path_elem;
+ int i = 0;
+
+ MAYBE_CHECK_SIZE_OVERFLOW(length, SIZE_MAX / sizeof(const char *) - 1,
+ MMDB_INVALID_METADATA_ERROR);
+
+ const char **path = malloc((length + 1) * sizeof(const char *));
+ if (NULL == path) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+
+ while (NULL != (path_elem = va_arg(va_path, char *))) {
+ path[i] = path_elem;
+ i++;
+ }
+ path[i] = NULL;
+
+ int status = MMDB_aget_value(start, entry_data, path);
+
+ free((char **)path);
+
+ return status;
+}
+
+LOCAL int path_length(va_list va_path)
+{
+ int i = 0;
+ const char *ignore;
+ va_list path_copy;
+ va_copy(path_copy, va_path);
+
+ while (NULL != (ignore = va_arg(path_copy, char *))) {
+ i++;
+ }
+
+ va_end(path_copy);
+
+ return i;
+}
+
+int MMDB_aget_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ const char *const *const path)
+{
+ MMDB_s *mmdb = start->mmdb;
+ uint32_t offset = start->offset;
+
+ memset(entry_data, 0, sizeof(MMDB_entry_data_s));
+ DEBUG_NL;
+ DEBUG_MSG("looking up value by path");
+
+ CHECKED_DECODE_ONE_FOLLOW(mmdb, offset, entry_data);
+
+ DEBUG_NL;
+ DEBUG_MSGF("top level element is a %s", type_num_to_name(entry_data->type));
+
+ /* Can this happen? It'd probably represent a pathological case under
+ * normal use, but there's nothing preventing someone from passing an
+ * invalid MMDB_entry_s struct to this function */
+ if (!entry_data->has_data) {
+ return MMDB_INVALID_LOOKUP_PATH_ERROR;
+ }
+
+ const char *path_elem;
+ int i = 0;
+ while (NULL != (path_elem = path[i++])) {
+ DEBUG_NL;
+ DEBUG_MSGF("path elem = %s", path_elem);
+
+ /* XXX - it'd be good to find a quicker way to skip through these
+ entries that doesn't involve decoding them
+ completely. Basically we need to just use the size from the
+ control byte to advance our pointer rather than calling
+ decode_one(). */
+ if (entry_data->type == MMDB_DATA_TYPE_ARRAY) {
+ int status = lookup_path_in_array(path_elem, mmdb, entry_data);
+ if (MMDB_SUCCESS != status) {
+ memset(entry_data, 0, sizeof(MMDB_entry_data_s));
+ return status;
+ }
+ } else if (entry_data->type == MMDB_DATA_TYPE_MAP) {
+ int status = lookup_path_in_map(path_elem, mmdb, entry_data);
+ if (MMDB_SUCCESS != status) {
+ memset(entry_data, 0, sizeof(MMDB_entry_data_s));
+ return status;
+ }
+ } else {
+ /* Once we make the code traverse maps & arrays without calling
+ * decode_one() we can get rid of this. */
+ memset(entry_data, 0, sizeof(MMDB_entry_data_s));
+ return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
+ }
+ }
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int lookup_path_in_array(const char *path_elem, MMDB_s *mmdb,
+ MMDB_entry_data_s *entry_data)
+{
+ uint32_t size = entry_data->data_size;
+ char *first_invalid;
+
+ int saved_errno = errno;
+ errno = 0;
+ int array_index = strtol(path_elem, &first_invalid, 10);
+ if (array_index < 0 || ERANGE == errno) {
+ errno = saved_errno;
+ return MMDB_INVALID_LOOKUP_PATH_ERROR;
+ }
+ errno = saved_errno;
+
+ if (*first_invalid || (uint32_t)array_index >= size) {
+ return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
+ }
+
+ for (int i = 0; i < array_index; i++) {
+ /* We don't want to follow a pointer here. If the next element is a
+ * pointer we simply skip it and keep going */
+ CHECKED_DECODE_ONE(mmdb, entry_data->offset_to_next, entry_data);
+ int status = skip_map_or_array(mmdb, entry_data);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ }
+
+ MMDB_entry_data_s value;
+ CHECKED_DECODE_ONE_FOLLOW(mmdb, entry_data->offset_to_next, &value);
+ memcpy(entry_data, &value, sizeof(MMDB_entry_data_s));
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int lookup_path_in_map(const char *path_elem, MMDB_s *mmdb,
+ MMDB_entry_data_s *entry_data)
+{
+ uint32_t size = entry_data->data_size;
+ uint32_t offset = entry_data->offset_to_next;
+ size_t path_elem_len = strlen(path_elem);
+
+ while (size-- > 0) {
+ MMDB_entry_data_s key, value;
+ CHECKED_DECODE_ONE_FOLLOW(mmdb, offset, &key);
+
+ uint32_t offset_to_value = key.offset_to_next;
+
+ if (MMDB_DATA_TYPE_UTF8_STRING != key.type) {
+ return MMDB_INVALID_DATA_ERROR;
+ }
+
+ if (key.data_size == path_elem_len &&
+ !memcmp(path_elem, key.utf8_string, path_elem_len)) {
+
+ DEBUG_MSG("found key matching path elem");
+
+ CHECKED_DECODE_ONE_FOLLOW(mmdb, offset_to_value, &value);
+ memcpy(entry_data, &value, sizeof(MMDB_entry_data_s));
+ return MMDB_SUCCESS;
+ } else {
+ /* We don't want to follow a pointer here. If the next element is
+ * a pointer we simply skip it and keep going */
+ CHECKED_DECODE_ONE(mmdb, offset_to_value, &value);
+ int status = skip_map_or_array(mmdb, &value);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ offset = value.offset_to_next;
+ }
+ }
+
+ memset(entry_data, 0, sizeof(MMDB_entry_data_s));
+ return MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR;
+}
+
+LOCAL int skip_map_or_array(MMDB_s *mmdb, MMDB_entry_data_s *entry_data)
+{
+ if (entry_data->type == MMDB_DATA_TYPE_MAP) {
+ uint32_t size = entry_data->data_size;
+ while (size-- > 0) {
+ CHECKED_DECODE_ONE(mmdb, entry_data->offset_to_next, entry_data); // key
+ CHECKED_DECODE_ONE(mmdb, entry_data->offset_to_next, entry_data); // value
+ int status = skip_map_or_array(mmdb, entry_data);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ }
+ } else if (entry_data->type == MMDB_DATA_TYPE_ARRAY) {
+ uint32_t size = entry_data->data_size;
+ while (size-- > 0) {
+ CHECKED_DECODE_ONE(mmdb, entry_data->offset_to_next, entry_data); // value
+ int status = skip_map_or_array(mmdb, entry_data);
+ if (MMDB_SUCCESS != status) {
+ return status;
+ }
+ }
+ }
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int decode_one_follow(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_s *entry_data)
+{
+ CHECKED_DECODE_ONE(mmdb, offset, entry_data);
+ if (entry_data->type == MMDB_DATA_TYPE_POINTER) {
+ uint32_t next = entry_data->offset_to_next;
+ CHECKED_DECODE_ONE(mmdb, entry_data->pointer, entry_data);
+ /* Pointers to pointers are illegal under the spec */
+ if (entry_data->type == MMDB_DATA_TYPE_POINTER) {
+ DEBUG_MSG("pointer points to another pointer");
+ return MMDB_INVALID_DATA_ERROR;
+ }
+
+ /* The pointer could point to any part of the data section but the
+ * next entry for this particular offset may be the one after the
+ * pointer, not the one after whatever the pointer points to. This
+ * depends on whether the pointer points to something that is a simple
+ * value or a compound value. For a compound value, the next one is
+ * the one after the pointer result, not the one after the pointer. */
+ if (entry_data->type != MMDB_DATA_TYPE_MAP
+ && entry_data->type != MMDB_DATA_TYPE_ARRAY) {
+
+ entry_data->offset_to_next = next;
+ }
+ }
+
+ return MMDB_SUCCESS;
+}
+
+#if !MMDB_UINT128_IS_BYTE_ARRAY
+NO_PROTO mmdb_uint128_t get_uint128(const uint8_t *p, int length)
+{
+ mmdb_uint128_t value = 0;
+ while (length-- > 0) {
+ value <<= 8;
+ value += *p++;
+ }
+ return value;
+}
+#endif
+
+LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_s *entry_data)
+{
+ const uint8_t *mem = mmdb->data_section;
+
+ if (offset + 1 > mmdb->data_section_size) {
+ DEBUG_MSGF("Offset (%d) past data section (%d)", offset,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+
+ entry_data->offset = offset;
+ entry_data->has_data = true;
+
+ DEBUG_NL;
+ DEBUG_MSGF("Offset: %i", offset);
+
+ uint8_t ctrl = mem[offset++];
+ DEBUG_BINARY("Control byte: %s", ctrl);
+
+ int type = (ctrl >> 5) & 7;
+ DEBUG_MSGF("Type: %i (%s)", type, type_num_to_name(type));
+
+ if (type == MMDB_DATA_TYPE_EXTENDED) {
+ if (offset + 1 > mmdb->data_section_size) {
+ DEBUG_MSGF("Extended type offset (%d) past data section (%d)",
+ offset,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ type = get_ext_type(mem[offset++]);
+ DEBUG_MSGF("Extended type: %i (%s)", type, type_num_to_name(type));
+ }
+
+ entry_data->type = type;
+
+ if (type == MMDB_DATA_TYPE_POINTER) {
+ int psize = ((ctrl >> 3) & 3) + 1;
+ DEBUG_MSGF("Pointer size: %i", psize);
+
+ if (offset + psize > mmdb->data_section_size) {
+ DEBUG_MSGF("Pointer offset (%d) past data section (%d)", offset +
+ psize,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ entry_data->pointer = get_ptr_from(ctrl, &mem[offset], psize);
+ DEBUG_MSGF("Pointer to: %i", entry_data->pointer);
+
+ entry_data->data_size = psize;
+ entry_data->offset_to_next = offset + psize;
+ return MMDB_SUCCESS;
+ }
+
+ uint32_t size = ctrl & 31;
+ switch (size) {
+ case 29:
+ if (offset + 1 > mmdb->data_section_size) {
+ DEBUG_MSGF("String end (%d, case 29) past data section (%d)",
+ offset,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ size = 29 + mem[offset++];
+ break;
+ case 30:
+ if (offset + 2 > mmdb->data_section_size) {
+ DEBUG_MSGF("String end (%d, case 30) past data section (%d)",
+ offset,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ size = 285 + get_uint16(&mem[offset]);
+ offset += 2;
+ break;
+ case 31:
+ if (offset + 3 > mmdb->data_section_size) {
+ DEBUG_MSGF("String end (%d, case 31) past data section (%d)",
+ offset,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ size = 65821 + get_uint24(&mem[offset]);
+ offset += 3;
+ default:
+ break;
+ }
+
+ DEBUG_MSGF("Size: %i", size);
+
+ if (type == MMDB_DATA_TYPE_MAP || type == MMDB_DATA_TYPE_ARRAY) {
+ entry_data->data_size = size;
+ entry_data->offset_to_next = offset;
+ return MMDB_SUCCESS;
+ }
+
+ if (type == MMDB_DATA_TYPE_BOOLEAN) {
+ entry_data->boolean = size ? true : false;
+ entry_data->data_size = 0;
+ entry_data->offset_to_next = offset;
+ DEBUG_MSGF("boolean value: %s", entry_data->boolean ? "true" : "false");
+ return MMDB_SUCCESS;
+ }
+
+ // check that the data doesn't extend past the end of the memory
+ // buffer
+ if (offset + size > mmdb->data_section_size) {
+ DEBUG_MSGF("Data end (%d) past data section (%d)", offset + size,
+ mmdb->data_section_size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+
+ if (type == MMDB_DATA_TYPE_UINT16) {
+ if (size > 2) {
+ DEBUG_MSGF("uint16 of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ entry_data->uint16 = (uint16_t)get_uintX(&mem[offset], size);
+ DEBUG_MSGF("uint16 value: %u", entry_data->uint16);
+ } else if (type == MMDB_DATA_TYPE_UINT32) {
+ if (size > 4) {
+ DEBUG_MSGF("uint32 of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ entry_data->uint32 = (uint32_t)get_uintX(&mem[offset], size);
+ DEBUG_MSGF("uint32 value: %u", entry_data->uint32);
+ } else if (type == MMDB_DATA_TYPE_INT32) {
+ if (size > 4) {
+ DEBUG_MSGF("int32 of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ entry_data->int32 = get_sintX(&mem[offset], size);
+ DEBUG_MSGF("int32 value: %i", entry_data->int32);
+ } else if (type == MMDB_DATA_TYPE_UINT64) {
+ if (size > 8) {
+ DEBUG_MSGF("uint64 of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ entry_data->uint64 = get_uintX(&mem[offset], size);
+ DEBUG_MSGF("uint64 value: %" PRIu64, entry_data->uint64);
+ } else if (type == MMDB_DATA_TYPE_UINT128) {
+ if (size > 16) {
+ DEBUG_MSGF("uint128 of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+#if MMDB_UINT128_IS_BYTE_ARRAY
+ memset(entry_data->uint128, 0, 16);
+ if (size > 0) {
+ memcpy(entry_data->uint128 + 16 - size, &mem[offset], size);
+ }
+#else
+ entry_data->uint128 = get_uint128(&mem[offset], size);
+#endif
+ } else if (type == MMDB_DATA_TYPE_FLOAT) {
+ if (size != 4) {
+ DEBUG_MSGF("float of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ size = 4;
+ entry_data->float_value = get_ieee754_float(&mem[offset]);
+ DEBUG_MSGF("float value: %f", entry_data->float_value);
+ } else if (type == MMDB_DATA_TYPE_DOUBLE) {
+ if (size != 8) {
+ DEBUG_MSGF("double of size %d", size);
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ size = 8;
+ entry_data->double_value = get_ieee754_double(&mem[offset]);
+ DEBUG_MSGF("double value: %f", entry_data->double_value);
+ } else if (type == MMDB_DATA_TYPE_UTF8_STRING) {
+ entry_data->utf8_string = size == 0 ? "" : (char *)&mem[offset];
+ entry_data->data_size = size;
+#ifdef MMDB_DEBUG
+ char *string = mmdb_strndup(entry_data->utf8_string,
+ size > 50 ? 50 : size);
+ if (NULL == string) {
+ abort();
+ }
+ DEBUG_MSGF("string value: %s", string);
+ free(string);
+#endif
+ } else if (type == MMDB_DATA_TYPE_BYTES) {
+ entry_data->bytes = &mem[offset];
+ entry_data->data_size = size;
+ }
+
+ entry_data->offset_to_next = offset + size;
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL int get_ext_type(int raw_ext_type)
+{
+ return 7 + raw_ext_type;
+}
+
+LOCAL uint32_t get_ptr_from(uint8_t ctrl, uint8_t const *const ptr,
+ int ptr_size)
+{
+ uint32_t new_offset;
+ switch (ptr_size) {
+ case 1:
+ new_offset = ( (ctrl & 7) << 8) + ptr[0];
+ break;
+ case 2:
+ new_offset = 2048 + ( (ctrl & 7) << 16 ) + ( ptr[0] << 8) + ptr[1];
+ break;
+ case 3:
+ new_offset = 2048 + 524288 + ( (ctrl & 7) << 24 ) + get_uint24(ptr);
+ break;
+ case 4:
+ default:
+ new_offset = get_uint32(ptr);
+ break;
+ }
+ return new_offset;
+}
+
+int MMDB_get_metadata_as_entry_data_list(
+ MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list)
+{
+ MMDB_s metadata_db = make_fake_metadata_db(mmdb);
+
+ MMDB_entry_s metadata_start = {
+ .mmdb = &metadata_db,
+ .offset = 0
+ };
+
+ return MMDB_get_entry_data_list(&metadata_start, entry_data_list);
+}
+
+int MMDB_get_entry_data_list(
+ MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list)
+{
+ *entry_data_list = new_entry_data_list();
+ if (NULL == *entry_data_list) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+ return get_entry_data_list(start->mmdb, start->offset, *entry_data_list, 0);
+}
+
+LOCAL int get_entry_data_list(MMDB_s *mmdb, uint32_t offset,
+ MMDB_entry_data_list_s *const entry_data_list,
+ int depth)
+{
+ if (depth >= MAXIMUM_DATA_STRUCTURE_DEPTH) {
+ DEBUG_MSG("reached the maximum data structure depth");
+ return MMDB_INVALID_DATA_ERROR;
+ }
+ depth++;
+ CHECKED_DECODE_ONE(mmdb, offset, &entry_data_list->entry_data);
+
+ switch (entry_data_list->entry_data.type) {
+ case MMDB_DATA_TYPE_POINTER:
+ {
+ uint32_t next_offset = entry_data_list->entry_data.offset_to_next;
+ uint32_t last_offset;
+ CHECKED_DECODE_ONE(mmdb, last_offset =
+ entry_data_list->entry_data.pointer,
+ &entry_data_list->entry_data);
+
+ /* Pointers to pointers are illegal under the spec */
+ if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_POINTER) {
+ DEBUG_MSG("pointer points to another pointer");
+ return MMDB_INVALID_DATA_ERROR;
+ }
+
+ if (entry_data_list->entry_data.type == MMDB_DATA_TYPE_ARRAY
+ || entry_data_list->entry_data.type == MMDB_DATA_TYPE_MAP) {
+
+ int status =
+ get_entry_data_list(mmdb, last_offset, entry_data_list,
+ depth);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("get_entry_data_list on pointer failed.");
+ return status;
+ }
+ }
+ entry_data_list->entry_data.offset_to_next = next_offset;
+ }
+ break;
+ case MMDB_DATA_TYPE_ARRAY:
+ {
+ uint32_t array_size = entry_data_list->entry_data.data_size;
+ uint32_t array_offset = entry_data_list->entry_data.offset_to_next;
+ MMDB_entry_data_list_s *previous = entry_data_list;
+ while (array_size-- > 0) {
+ MMDB_entry_data_list_s *entry_data_list_to = previous->next =
+ new_entry_data_list();
+ if (NULL == entry_data_list_to) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+
+ int status =
+ get_entry_data_list(mmdb, array_offset, entry_data_list_to,
+ depth);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("get_entry_data_list on array element failed.");
+ return status;
+ }
+
+ array_offset = entry_data_list_to->entry_data.offset_to_next;
+ while (previous->next) {
+ previous = previous->next;
+ }
+ }
+ entry_data_list->entry_data.offset_to_next = array_offset;
+
+ }
+ break;
+ case MMDB_DATA_TYPE_MAP:
+ {
+ uint32_t size = entry_data_list->entry_data.data_size;
+
+ offset = entry_data_list->entry_data.offset_to_next;
+ MMDB_entry_data_list_s *previous = entry_data_list;
+ while (size-- > 0) {
+ MMDB_entry_data_list_s *entry_data_list_to = previous->next =
+ new_entry_data_list();
+ if (NULL == entry_data_list_to) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+
+ int status =
+ get_entry_data_list(mmdb, offset, entry_data_list_to,
+ depth);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("get_entry_data_list on map key failed.");
+ return status;
+ }
+
+ while (previous->next) {
+ previous = previous->next;
+ }
+
+ offset = entry_data_list_to->entry_data.offset_to_next;
+ entry_data_list_to = previous->next =
+ new_entry_data_list();
+
+ if (NULL == entry_data_list_to) {
+ return MMDB_OUT_OF_MEMORY_ERROR;
+ }
+
+ status = get_entry_data_list(mmdb, offset, entry_data_list_to,
+ depth);
+ if (MMDB_SUCCESS != status) {
+ DEBUG_MSG("get_entry_data_list on map element failed.");
+ return status;
+ }
+
+ while (previous->next) {
+ previous = previous->next;
+ }
+ offset = entry_data_list_to->entry_data.offset_to_next;
+ }
+ entry_data_list->entry_data.offset_to_next = offset;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return MMDB_SUCCESS;
+}
+
+LOCAL float get_ieee754_float(const uint8_t *restrict p)
+{
+ volatile float f;
+ uint8_t *q = (void *)&f;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ q[3] = p[0];
+ q[2] = p[1];
+ q[1] = p[2];
+ q[0] = p[3];
+#else
+ memcpy(q, p, 4);
+#endif
+ return f;
+}
+
+LOCAL double get_ieee754_double(const uint8_t *restrict p)
+{
+ volatile double d;
+ uint8_t *q = (void *)&d;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ q[7] = p[0];
+ q[6] = p[1];
+ q[5] = p[2];
+ q[4] = p[3];
+ q[3] = p[4];
+ q[2] = p[5];
+ q[1] = p[6];
+ q[0] = p[7];
+#else
+ memcpy(q, p, 8);
+#endif
+
+ return d;
+}
+
+LOCAL uint32_t get_uint32(const uint8_t *p)
+{
+ return p[0] * 16777216U + p[1] * 65536 + p[2] * 256 + p[3];
+}
+
+LOCAL uint32_t get_uint24(const uint8_t *p)
+{
+ return p[0] * 65536U + p[1] * 256 + p[2];
+}
+
+LOCAL uint32_t get_uint16(const uint8_t *p)
+{
+ return p[0] * 256U + p[1];
+}
+
+LOCAL uint64_t get_uintX(const uint8_t *p, int length)
+{
+ uint64_t value = 0;
+ while (length-- > 0) {
+ value <<= 8;
+ value += *p++;
+ }
+ return value;
+}
+
+LOCAL int32_t get_sintX(const uint8_t *p, int length)
+{
+ return (int32_t)get_uintX(p, length);
+}
+
+LOCAL MMDB_entry_data_list_s *new_entry_data_list(void)
+{
+ /* We need calloc here in order to ensure that the ->next pointer in the
+ * struct doesn't point to some random address. */
+ return calloc(1, sizeof(MMDB_entry_data_list_s));
+}
+
+void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list)
+{
+ if (entry_data_list == NULL) {
+ return;
+ }
+ if (entry_data_list->next) {
+ MMDB_free_entry_data_list(entry_data_list->next);
+ }
+ free(entry_data_list);
+}
+
+void MMDB_close(MMDB_s *const mmdb)
+{
+ free_mmdb_struct(mmdb);
+}
+
+LOCAL void free_mmdb_struct(MMDB_s *const mmdb)
+{
+ if (!mmdb) {
+ return;
+ }
+
+ if (NULL != mmdb->filename) {
+ FREE_AND_SET_NULL(mmdb->filename);
+ }
+ if (NULL != mmdb->file_content) {
+#ifdef _WIN32
+ UnmapViewOfFile(mmdb->file_content);
+ /* Winsock is only initialized if open was successful so we only have
+ * to cleanup then. */
+ WSACleanup();
+#else
+ munmap((void *)mmdb->file_content, mmdb->file_size);
+#endif
+ }
+
+ if (NULL != mmdb->metadata.database_type) {
+ FREE_AND_SET_NULL(mmdb->metadata.database_type);
+ }
+
+ free_languages_metadata(mmdb);
+ free_descriptions_metadata(mmdb);
+}
+
+LOCAL void free_languages_metadata(MMDB_s *mmdb)
+{
+ if (!mmdb->metadata.languages.count) {
+ return;
+ }
+
+ for (size_t i = 0; i < mmdb->metadata.languages.count; i++) {
+ FREE_AND_SET_NULL(mmdb->metadata.languages.names[i]);
+ }
+ FREE_AND_SET_NULL(mmdb->metadata.languages.names);
+}
+
+LOCAL void free_descriptions_metadata(MMDB_s *mmdb)
+{
+ if (!mmdb->metadata.description.count) {
+ return;
+ }
+
+ for (size_t i = 0; i < mmdb->metadata.description.count; i++) {
+ if (NULL != mmdb->metadata.description.descriptions[i]) {
+ if (NULL !=
+ mmdb->metadata.description.descriptions[i]->language) {
+ FREE_AND_SET_NULL(
+ mmdb->metadata.description.descriptions[i]->language);
+ }
+
+ if (NULL !=
+ mmdb->metadata.description.descriptions[i]->description) {
+ FREE_AND_SET_NULL(
+ mmdb->metadata.description.descriptions[i]->description);
+ }
+ FREE_AND_SET_NULL(mmdb->metadata.description.descriptions[i]);
+ }
+ }
+
+ FREE_AND_SET_NULL(mmdb->metadata.description.descriptions);
+}
+
+const char *MMDB_lib_version(void)
+{
+ return PACKAGE_VERSION;
+}
+
+int MMDB_dump_entry_data_list(FILE *const stream,
+ MMDB_entry_data_list_s *const entry_data_list,
+ int indent)
+{
+ int status;
+ dump_entry_data_list(stream, entry_data_list, indent, &status);
+ return status;
+}
+
+LOCAL MMDB_entry_data_list_s *dump_entry_data_list(
+ FILE *stream, MMDB_entry_data_list_s *entry_data_list, int indent,
+ int *status)
+{
+ switch (entry_data_list->entry_data.type) {
+ case MMDB_DATA_TYPE_MAP:
+ {
+ uint32_t size = entry_data_list->entry_data.data_size;
+
+ print_indentation(stream, indent);
+ fprintf(stream, "{\n");
+ indent += 2;
+
+ for (entry_data_list = entry_data_list->next;
+ size && entry_data_list; size--) {
+
+ if (MMDB_DATA_TYPE_UTF8_STRING !=
+ entry_data_list->entry_data.type) {
+ *status = MMDB_INVALID_DATA_ERROR;
+ return NULL;
+ }
+ char *key =
+ mmdb_strndup(
+ (char *)entry_data_list->entry_data.utf8_string,
+ entry_data_list->entry_data.data_size);
+ if (NULL == key) {
+ *status = MMDB_OUT_OF_MEMORY_ERROR;
+ return NULL;
+ }
+
+ print_indentation(stream, indent);
+ fprintf(stream, "\"%s\": \n", key);
+ free(key);
+
+ entry_data_list = entry_data_list->next;
+ entry_data_list =
+ dump_entry_data_list(stream, entry_data_list, indent + 2,
+ status);
+
+ if (MMDB_SUCCESS != *status) {
+ return NULL;
+ }
+ }
+
+ indent -= 2;
+ print_indentation(stream, indent);
+ fprintf(stream, "}\n");
+ }
+ break;
+ case MMDB_DATA_TYPE_ARRAY:
+ {
+ uint32_t size = entry_data_list->entry_data.data_size;
+
+ print_indentation(stream, indent);
+ fprintf(stream, "[\n");
+ indent += 2;
+
+ for (entry_data_list = entry_data_list->next;
+ size && entry_data_list; size--) {
+ entry_data_list =
+ dump_entry_data_list(stream, entry_data_list, indent,
+ status);
+ if (MMDB_SUCCESS != *status) {
+ return NULL;
+ }
+ }
+
+ indent -= 2;
+ print_indentation(stream, indent);
+ fprintf(stream, "]\n");
+ }
+ break;
+ case MMDB_DATA_TYPE_UTF8_STRING:
+ {
+ char *string =
+ mmdb_strndup((char *)entry_data_list->entry_data.utf8_string,
+ entry_data_list->entry_data.data_size);
+ if (NULL == string) {
+ *status = MMDB_OUT_OF_MEMORY_ERROR;
+ return NULL;
+ }
+ print_indentation(stream, indent);
+ fprintf(stream, "\"%s\" \n", string);
+ free(string);
+ entry_data_list = entry_data_list->next;
+ }
+ break;
+ case MMDB_DATA_TYPE_BYTES:
+ {
+ char *hex_string =
+ bytes_to_hex((uint8_t *)entry_data_list->entry_data.bytes,
+ entry_data_list->entry_data.data_size);
+ if (NULL == hex_string) {
+ *status = MMDB_OUT_OF_MEMORY_ERROR;
+ return NULL;
+ }
+
+ print_indentation(stream, indent);
+ fprintf(stream, "%s \n", hex_string);
+ free(hex_string);
+
+ entry_data_list = entry_data_list->next;
+ }
+ break;
+ case MMDB_DATA_TYPE_DOUBLE:
+ print_indentation(stream, indent);
+ fprintf(stream, "%f \n",
+ entry_data_list->entry_data.double_value);
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_FLOAT:
+ print_indentation(stream, indent);
+ fprintf(stream, "%f \n",
+ entry_data_list->entry_data.float_value);
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_UINT16:
+ print_indentation(stream, indent);
+ fprintf(stream, "%u \n", entry_data_list->entry_data.uint16);
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_UINT32:
+ print_indentation(stream, indent);
+ fprintf(stream, "%u \n", entry_data_list->entry_data.uint32);
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_BOOLEAN:
+ print_indentation(stream, indent);
+ fprintf(stream, "%s \n",
+ entry_data_list->entry_data.boolean ? "true" : "false");
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_UINT64:
+ print_indentation(stream, indent);
+ fprintf(stream, "%" PRIu64 " \n",
+ entry_data_list->entry_data.uint64);
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_UINT128:
+ print_indentation(stream, indent);
+#if MMDB_UINT128_IS_BYTE_ARRAY
+ char *hex_string =
+ bytes_to_hex((uint8_t *)entry_data_list->entry_data.uint128, 16);
+ if (NULL == hex_string) {
+ *status = MMDB_OUT_OF_MEMORY_ERROR;
+ return NULL;
+ }
+ fprintf(stream, "0x%s \n", hex_string);
+ free(hex_string);
+#else
+ uint64_t high = entry_data_list->entry_data.uint128 >> 64;
+ uint64_t low = (uint64_t)entry_data_list->entry_data.uint128;
+ fprintf(stream, "0x%016" PRIX64 "%016" PRIX64 " \n", high,
+ low);
+#endif
+ entry_data_list = entry_data_list->next;
+ break;
+ case MMDB_DATA_TYPE_INT32:
+ print_indentation(stream, indent);
+ fprintf(stream, "%d \n", entry_data_list->entry_data.int32);
+ entry_data_list = entry_data_list->next;
+ break;
+ default:
+ *status = MMDB_INVALID_DATA_ERROR;
+ return NULL;
+ }
+
+ *status = MMDB_SUCCESS;
+ return entry_data_list;
+}
+
+LOCAL void print_indentation(FILE *stream, int i)
+{
+ char buffer[1024];
+ int size = i >= 1024 ? 1023 : i;
+ memset(buffer, 32, size);
+ buffer[size] = '\0';
+ fputs(buffer, stream);
+}
+
+LOCAL char *bytes_to_hex(uint8_t *bytes, uint32_t size)
+{
+ char *hex_string;
+ MAYBE_CHECK_SIZE_OVERFLOW(size, SIZE_MAX / 2 - 1, NULL);
+
+ hex_string = malloc((size * 2) + 1);
+ if (NULL == hex_string) {
+ return NULL;
+ }
+
+ for (uint32_t i = 0; i < size; i++) {
+ sprintf(hex_string + (2 * i), "%02X", bytes[i]);
+ }
+
+ return hex_string;
+}
+
+const char *MMDB_strerror(int error_code)
+{
+ switch (error_code) {
+ case MMDB_SUCCESS:
+ return "Success (not an error)";
+ case MMDB_FILE_OPEN_ERROR:
+ return "Error opening the specified MaxMind DB file";
+ case MMDB_CORRUPT_SEARCH_TREE_ERROR:
+ return "The MaxMind DB file's search tree is corrupt";
+ case MMDB_INVALID_METADATA_ERROR:
+ return "The MaxMind DB file contains invalid metadata";
+ case MMDB_IO_ERROR:
+ return "An attempt to read data from the MaxMind DB file failed";
+ case MMDB_OUT_OF_MEMORY_ERROR:
+ return "A memory allocation call failed";
+ case MMDB_UNKNOWN_DATABASE_FORMAT_ERROR:
+ return
+ "The MaxMind DB file is in a format this library can't handle (unknown record size or binary format version)";
+ case MMDB_INVALID_DATA_ERROR:
+ return
+ "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)";
+ case MMDB_INVALID_LOOKUP_PATH_ERROR:
+ return
+ "The lookup path contained an invalid value (like a negative integer for an array index)";
+ case MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR:
+ return
+ "The lookup path does not match the data (key that doesn't exist, array index bigger than the array, expected array or map where none exists)";
+ case MMDB_INVALID_NODE_NUMBER_ERROR:
+ return
+ "The MMDB_read_node function was called with a node number that does not exist in the search tree";
+ case MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR:
+ return
+ "You attempted to look up an IPv6 address in an IPv4-only database";
+ default:
+ return "Unknown error code";
+ }
+}
+
+#pragma warning(pop)
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/maxminddb.h b/plugins-extra/NetExtrasPlugin/maxminddb.h
new file mode 100644
index 0000000..1dc6e37
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/maxminddb.h
@@ -0,0 +1,232 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAXMINDDB_H
+#define MAXMINDDB_H
+
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#include "maxminddb_config.h"
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _WIN32
+#include
+#include
+/* libmaxminddb package version from configure */
+#define PACKAGE_VERSION "1.2.0"
+
+typedef ADDRESS_FAMILY sa_family_t;
+
+#if defined(_MSC_VER)
+/* MSVC doesn't define signed size_t, copy it from configure */
+#define ssize_t int
+
+/* MSVC doesn't support restricted pointers */
+#define restrict
+#endif
+#else
+#include
+#include
+#include
+#endif
+
+#define MMDB_DATA_TYPE_EXTENDED (0)
+#define MMDB_DATA_TYPE_POINTER (1)
+#define MMDB_DATA_TYPE_UTF8_STRING (2)
+#define MMDB_DATA_TYPE_DOUBLE (3)
+#define MMDB_DATA_TYPE_BYTES (4)
+#define MMDB_DATA_TYPE_UINT16 (5)
+#define MMDB_DATA_TYPE_UINT32 (6)
+#define MMDB_DATA_TYPE_MAP (7)
+#define MMDB_DATA_TYPE_INT32 (8)
+#define MMDB_DATA_TYPE_UINT64 (9)
+#define MMDB_DATA_TYPE_UINT128 (10)
+#define MMDB_DATA_TYPE_ARRAY (11)
+#define MMDB_DATA_TYPE_CONTAINER (12)
+#define MMDB_DATA_TYPE_END_MARKER (13)
+#define MMDB_DATA_TYPE_BOOLEAN (14)
+#define MMDB_DATA_TYPE_FLOAT (15)
+
+#define MMDB_RECORD_TYPE_SEARCH_NODE (0)
+#define MMDB_RECORD_TYPE_EMPTY (1)
+#define MMDB_RECORD_TYPE_DATA (2)
+#define MMDB_RECORD_TYPE_INVALID (3)
+
+/* flags for open */
+#define MMDB_MODE_MMAP (1)
+#define MMDB_MODE_MASK (7)
+
+/* error codes */
+#define MMDB_SUCCESS (0)
+#define MMDB_FILE_OPEN_ERROR (1)
+#define MMDB_CORRUPT_SEARCH_TREE_ERROR (2)
+#define MMDB_INVALID_METADATA_ERROR (3)
+#define MMDB_IO_ERROR (4)
+#define MMDB_OUT_OF_MEMORY_ERROR (5)
+#define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR (6)
+#define MMDB_INVALID_DATA_ERROR (7)
+#define MMDB_INVALID_LOOKUP_PATH_ERROR (8)
+#define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR (9)
+#define MMDB_INVALID_NODE_NUMBER_ERROR (10)
+#define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR (11)
+
+#if !(MMDB_UINT128_IS_BYTE_ARRAY)
+#if MMDB_UINT128_USING_MODE
+typedef unsigned int mmdb_uint128_t __attribute__ ((__mode__(TI)));
+#else
+typedef unsigned __int128 mmdb_uint128_t;
+#endif
+#endif
+
+/* This is a pointer into the data section for a given IP address lookup */
+typedef struct MMDB_entry_s {
+ struct MMDB_s *mmdb;
+ uint32_t offset;
+} MMDB_entry_s;
+
+typedef struct MMDB_lookup_result_s {
+ bool found_entry;
+ MMDB_entry_s entry;
+ uint16_t netmask;
+} MMDB_lookup_result_s;
+
+typedef struct MMDB_entry_data_s {
+ bool has_data;
+ union {
+ uint32_t pointer;
+ const char *utf8_string;
+ double double_value;
+ const uint8_t *bytes;
+ uint16_t uint16;
+ uint32_t uint32;
+ int32_t int32;
+ uint64_t uint64;
+#if MMDB_UINT128_IS_BYTE_ARRAY
+ uint8_t uint128[16];
+#else
+ mmdb_uint128_t uint128;
+#endif
+ bool boolean;
+ float float_value;
+ };
+ /* This is a 0 if a given entry cannot be found. This can only happen
+ * when a call to MMDB_(v)get_value() asks for hash keys or array
+ * indices that don't exist. */
+ uint32_t offset;
+ /* This is the next entry in the data section, but it's really only
+ * relevant for entries that part of a larger map or array
+ * struct. There's no good reason for an end user to look at this
+ * directly. */
+ uint32_t offset_to_next;
+ /* This is only valid for strings, utf8_strings or binary data */
+ uint32_t data_size;
+ /* This is an MMDB_DATA_TYPE_* constant */
+ uint32_t type;
+} MMDB_entry_data_s;
+
+/* This is the return type when someone asks for all the entry data in a map or array */
+typedef struct MMDB_entry_data_list_s {
+ MMDB_entry_data_s entry_data;
+ struct MMDB_entry_data_list_s *next;
+} MMDB_entry_data_list_s;
+
+typedef struct MMDB_description_s {
+ const char *language;
+ const char *description;
+} MMDB_description_s;
+
+typedef struct MMDB_metadata_s {
+ uint32_t node_count;
+ uint16_t record_size;
+ uint16_t ip_version;
+ const char *database_type;
+ struct {
+ size_t count;
+ const char **names;
+ } languages;
+ uint16_t binary_format_major_version;
+ uint16_t binary_format_minor_version;
+ uint64_t build_epoch;
+ struct {
+ size_t count;
+ MMDB_description_s **descriptions;
+ } description;
+} MMDB_metadata_s;
+
+typedef struct MMDB_ipv4_start_node_s {
+ uint16_t netmask;
+ uint32_t node_value;
+} MMDB_ipv4_start_node_s;
+
+typedef struct MMDB_s {
+ uint32_t flags;
+ const wchar_t* filename;
+ ssize_t file_size;
+ const uint8_t *file_content;
+ const uint8_t *data_section;
+ uint32_t data_section_size;
+ const uint8_t *metadata_section;
+ uint32_t metadata_section_size;
+ uint16_t full_record_byte_size;
+ uint16_t depth;
+ MMDB_ipv4_start_node_s ipv4_start_node;
+ MMDB_metadata_s metadata;
+} MMDB_s;
+
+typedef struct MMDB_search_node_s {
+ uint64_t left_record;
+ uint64_t right_record;
+ uint8_t left_record_type;
+ uint8_t right_record_type;
+ MMDB_entry_s left_record_entry;
+ MMDB_entry_s right_record_entry;
+} MMDB_search_node_s;
+
+ /* *INDENT-OFF* */
+ /* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
+ extern int MMDB_open(const wchar_t *const filename, uint32_t flags, MMDB_s *const mmdb);
+ extern MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
+ const char *const ipstr,
+ int *const gai_error,
+ int *const mmdb_error);
+ extern MMDB_lookup_result_s MMDB_lookup_sockaddr(
+ MMDB_s *const mmdb,
+ const struct sockaddr *const sockaddr,
+ int *const mmdb_error);
+ extern int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
+ MMDB_search_node_s *const node);
+ extern int MMDB_get_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ ...);
+ extern int MMDB_vget_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ va_list va_path);
+ extern int MMDB_aget_value(MMDB_entry_s *const start,
+ MMDB_entry_data_s *const entry_data,
+ const char *const *const path);
+ extern int MMDB_get_metadata_as_entry_data_list(
+ MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list);
+ extern int MMDB_get_entry_data_list(
+ MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list);
+ extern void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list);
+ extern void MMDB_close(MMDB_s *const mmdb);
+ extern const char *MMDB_lib_version(void);
+ extern int MMDB_dump_entry_data_list(FILE *const stream,
+ MMDB_entry_data_list_s *const entry_data_list,
+ int indent);
+ extern const char *MMDB_strerror(int error_code);
+ /* --prototypes end - don't remove this comment-- */
+ /* *INDENT-ON* */
+
+#endif /* MAXMINDDB_H */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/plugins-extra/NetExtrasPlugin/maxminddb_config.h b/plugins-extra/NetExtrasPlugin/maxminddb_config.h
new file mode 100644
index 0000000..1a5c62d
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/maxminddb_config.h
@@ -0,0 +1,14 @@
+#ifndef MAXMINDDB_CONFIG_H
+#define MAXMINDDB_CONFIG_H
+
+#ifndef MMDB_UINT128_USING_MODE
+/* Define as 1 if we we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
+#define MMDB_UINT128_USING_MODE 0
+#endif
+
+#ifndef MMDB_UINT128_IS_BYTE_ARRAY
+/* Define as 1 if we don't have an unsigned __int128 type */
+#define MMDB_UINT128_IS_BYTE_ARRAY 1
+#endif
+
+#endif /* MAXMINDDB_CONFIG_H */
diff --git a/plugins-extra/NetExtrasPlugin/png.c b/plugins-extra/NetExtrasPlugin/png.c
new file mode 100644
index 0000000..dd8aa20
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/png.c
@@ -0,0 +1,496 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+struct
+{
+ PWSTR CountryCode;
+ INT ResourceID;
+}
+CountryResourceTable[] =
+{
+ { L"AD", AD_PNG },
+ { L"AE", AE_PNG },
+ { L"AF", AF_PNG },
+ { L"AG", AG_PNG },
+ { L"AI", AI_PNG },
+ { L"AL", AL_PNG },
+ { L"AM", AM_PNG },
+ { L"AN", AN_PNG },
+ { L"AO", AO_PNG },
+ { L"AR", AR_PNG },
+ { L"AS", AS_PNG },
+ { L"AT", AT_PNG },
+ { L"AU", AU_PNG },
+ { L"AW", AW_PNG },
+ { L"AX", AX_PNG },
+ { L"AZ", AZ_PNG },
+
+ { L"BA", BA_PNG },
+ { L"BB", BB_PNG },
+ { L"BD", BD_PNG },
+ { L"BE", BE_PNG },
+ { L"BF", BF_PNG },
+ { L"BG", BG_PNG },
+ { L"BH", BH_PNG },
+ { L"BI", BI__PNG },
+ { L"BJ", BJ_PNG },
+ { L"BM", BM_PNG },
+ { L"BN", BN_PNG },
+ { L"BO", BO_PNG },
+ { L"BR", BR_PNG },
+ { L"BS", BS_PNG },
+ { L"BT", BT_PNG },
+ { L"BV", BV_PNG },
+ { L"BW", BW_PNG },
+ { L"BY", BY_PNG },
+ { L"BZ", BZ_PNG },
+
+ { L"CA", CA_PNG },
+ { L"CC", CC_PNG },
+ { L"CD", CD_PNG },
+ { L"CF", CF_PNG },
+ { L"CG", CG_PNG },
+ { L"CH", CH_PNG },
+ { L"CI", CI_PNG },
+ { L"CK", CK_PNG },
+ { L"CL", CL_PNG },
+ { L"CM", CM_PNG },
+ { L"CN", CN_PNG },
+ { L"CO", CO_PNG },
+ { L"CR", CR_PNG },
+ { L"CS", CS_PNG },
+ { L"CU", CU_PNG },
+ { L"CV", CV_PNG },
+ { L"CX", CX_PNG },
+ { L"CY", CY_PNG },
+ { L"CZ", CZ_PNG },
+
+ { L"DE", DE_PNG },
+ { L"DJ", DJ_PNG },
+ { L"DK", DK_PNG },
+ { L"DM", DM_PNG },
+ { L"DO", DO_PNG },
+ { L"DZ", DZ_PNG },
+
+ { L"EC", EC_PNG },
+ { L"EE", EE_PNG },
+ { L"EG", EG_PNG },
+ { L"EH", EH_PNG },
+ { L"ER", ER_PNG },
+ { L"ES", ES_PNG },
+ { L"ET", ET_PNG },
+
+ { L"FI", FI_PNG },
+ { L"FJ", FJ_PNG },
+ { L"FK", FK_PNG },
+ { L"FO", FO_PNG },
+ { L"FR", FR_PNG },
+
+ { L"GA", GA_PNG },
+ { L"GB", GB_PNG },
+ { L"GD", GD_PNG },
+ { L"GE", GE_PNG },
+ { L"GF", GF_PNG },
+ { L"GH", GH_PNG },
+ { L"GI", GI_PNG },
+ { L"GL", GL_PNG },
+ { L"GM", GM_PNG },
+ { L"GN", GN_PNG },
+ { L"GP", GP_PNG },
+ { L"GQ", GQ_PNG },
+ { L"GR", GR_PNG },
+ { L"GS", GS_PNG },
+ { L"GT", GT_PNG },
+ { L"GU", GU_PNG },
+ { L"GW", GW_PNG },
+ { L"GY", GY_PNG },
+
+ { L"HK", HK_PNG },
+ { L"HM", HM_PNG },
+ { L"HN", HN_PNG },
+ { L"HR", HR_PNG },
+ { L"HT", HT_PNG },
+ { L"HU", HU_PNG },
+
+ { L"ID", ID_PNG },
+ { L"IE", IE_PNG },
+ { L"IL", IL_PNG },
+ { L"IN", IN_PNG },
+ { L"IO", IO_PNG },
+ { L"IQ", IQ_PNG },
+ { L"IR", IR_PNG },
+ { L"IS", IS_PNG },
+ { L"IT", IT_PNG },
+
+ { L"JM", JM_PNG },
+ { L"JO", JO_PNG },
+ { L"JP", JP_PNG },
+
+ { L"KE", KE_PNG },
+ { L"KG", KG_PNG },
+ { L"KH", KH_PNG },
+ { L"KI", KI_PNG },
+ { L"KM", KM_PNG },
+ { L"KN", KN_PNG },
+ { L"KP", KP_PNG },
+ { L"KR", KR_PNG },
+ { L"KW", KW_PNG },
+ { L"KY", KY_PNG },
+ { L"KZ", KZ_PNG },
+
+ { L"LA", LA_PNG },
+ { L"LB", LB_PNG },
+ { L"LC", LC_PNG },
+ { L"LI", LI_PNG },
+ { L"LK", LK_PNG },
+ { L"LR", LR_PNG },
+ { L"LS", LS_PNG },
+ { L"LT", LT_PNG },
+ { L"LU", LU_PNG },
+ { L"LV", LV_PNG },
+ { L"LY", LY_PNG },
+
+ { L"MA", MA_PNG },
+ { L"MC", MC_PNG },
+ { L"MD", MD_PNG },
+ { L"ME", ME_PNG },
+ { L"MG", MG_PNG },
+ { L"MH", MH_PNG },
+ { L"MK", MK_PNG },
+ { L"ML", ML_PNG },
+ { L"MM", MM_PNG },
+ { L"MN", MN_PNG },
+ { L"MO", MO_PNG },
+ { L"MP", MP_PNG },
+ { L"MQ", MQ_PNG },
+ { L"MR", MR_PNG },
+ { L"MS", MS_PNG },
+ { L"MT", MT_PNG },
+ { L"MU", MU_PNG },
+ { L"MV", MV_PNG },
+ { L"MW", MW_PNG },
+ { L"MX", MX_PNG },
+ { L"MY", MY_PNG },
+ { L"MZ", MZ_PNG },
+
+ { L"NA", NA_PNG },
+ { L"NC", NC_PNG },
+ { L"NE", NE_PNG },
+ { L"NF", NF_PNG },
+ { L"NG", NG_PNG },
+ { L"NI", NI_PNG },
+ { L"NL", NL_PNG },
+ { L"NO", NO_PNG },
+ { L"NP", NP_PNG },
+ { L"NR", NR_PNG },
+ { L"NU", NU_PNG },
+ { L"NZ", NZ_PNG },
+
+ { L"OM", OM_PNG },
+
+ { L"PA", PA_PNG },
+ { L"PE", PE_PNG },
+ { L"PF", PF_PNG },
+ { L"PG", PG_PNG },
+ { L"PH", PH_PNG },
+ { L"PK", PK_PNG },
+ { L"PL", PL_PNG },
+ { L"PM", PM_PNG },
+ { L"PN", PN_PNG },
+ { L"PR", PR_PNG },
+ { L"PS", PS_PNG },
+ { L"PT", PT_PNG },
+ { L"PW", PW_PNG },
+ { L"PY", PY_PNG },
+
+ { L"QA", QA_PNG },
+
+ { L"RE", RE_PNG },
+ { L"RO", RO_PNG },
+ { L"RS", RS_PNG },
+ { L"RU", RU_PNG },
+ { L"RW", RW_PNG },
+
+ { L"SA", SA_PNG },
+ { L"SB", SB_PNG },
+ { L"SC", SC_PNG },
+ { L"SD", SD_PNG },
+ { L"SE", SE_PNG },
+ { L"SG", SG_PNG },
+ { L"SH", SH_PNG },
+ { L"SI", SI_PNG },
+ { L"SJ", SJ_PNG },
+ { L"SK", SK_PNG },
+ { L"SL", SL_PNG },
+ { L"SM", SM_PNG },
+ { L"SN", SN_PNG },
+ { L"SO", SO_PNG },
+ { L"SR", SR_PNG },
+ { L"ST", ST_PNG },
+ { L"SV", SV_PNG },
+ { L"SY", SY_PNG },
+ { L"SZ", SZ_PNG },
+
+ { L"TC", TC_PNG },
+ { L"TD", TD_PNG },
+ { L"TF", TF_PNG },
+ { L"TG", TG_PNG },
+ { L"TH", TH_PNG },
+ { L"TJ", TJ_PNG },
+ { L"TK", TK_PNG },
+ { L"TL", TL_PNG },
+ { L"TM", TM_PNG },
+ { L"TN", TN_PNG },
+ { L"TO", TO_PNG },
+ { L"TR", TR_PNG },
+ { L"TT", TT_PNG },
+ { L"TV", TV_PNG },
+ { L"TW", TW_PNG },
+ { L"TZ", TZ_PNG },
+
+ { L"UA", UA_PNG },
+ { L"UG", UG_PNG },
+ { L"UM", UM_PNG },
+ { L"US", US_PNG },
+ { L"UY", UY_PNG },
+ { L"UZ", UZ_PNG },
+
+ { L"VA", VA_PNG },
+ { L"VC", VC_PNG },
+ { L"VE", VE_PNG },
+ { L"VG", VG_PNG },
+ { L"VI", VI_PNG },
+ { L"VN", VN_PNG },
+ { L"VU", VU_PNG },
+
+ { L"WF", WF_PNG },
+ { L"WS", WS_PNG },
+
+ { L"YE", YE_PNG },
+ { L"YT", YT_PNG },
+
+ { L"ZA", ZA_PNG },
+ { L"ZM", ZM_PNG },
+ { L"ZW", ZW_PNG }
+};
+
+INT LookupResourceCode(
+ _In_ PPH_STRING Name
+ )
+{
+ for (INT i = 0; i < ARRAYSIZE(CountryResourceTable); i++)
+ {
+ if (PhEqualString2(Name, CountryResourceTable[i].CountryCode, TRUE))
+ {
+ return CountryResourceTable[i].ResourceID;
+ }
+ }
+
+ return 0;
+}
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PPH_STRING Name
+ )
+{
+ UINT frameCount = 0;
+ BOOLEAN isSuccess = FALSE;
+ ULONG resourceLength = 0;
+ HGLOBAL resourceHandle = NULL;
+ HRSRC resourceHandleSource = NULL;
+ WICInProcPointer resourceBuffer = NULL;
+ HDC screenHdc = NULL;
+ HDC bufferDc = NULL;
+ BITMAPINFO bitmapInfo = { 0 };
+ HBITMAP bitmapHandle = NULL;
+ PBYTE bitmapBuffer = NULL;
+ IWICStream* wicStream = NULL;
+ IWICBitmapSource* wicBitmapSource = NULL;
+ IWICBitmapDecoder* wicDecoder = NULL;
+ IWICBitmapFrameDecode* wicFrame = NULL;
+ IWICImagingFactory* wicFactory = NULL;
+ IWICBitmapScaler* wicScaler = NULL;
+ WICPixelFormatGUID pixelFormat;
+ WICRect rect = { 0, 0, Width, Height };
+
+ INT resourceCode = LookupResourceCode(Name);
+
+ if (resourceCode == 0)
+ return NULL;
+
+ __try
+ {
+ // Create the ImagingFactory
+ if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory)))
+ __leave;
+
+ // Find the resource
+ if ((resourceHandleSource = FindResource(PluginInstance->DllBase, MAKEINTRESOURCE(resourceCode), L"PNG")) == NULL)
+ __leave;
+
+ // Get the resource length
+ resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource);
+
+ // Load the resource
+ if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL)
+ __leave;
+
+ if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL)
+ __leave;
+
+ // Create the Stream
+ if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream)))
+ __leave;
+
+ // Initialize the Stream from Memory
+ if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength)))
+ __leave;
+
+ if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder)))
+ __leave;
+
+ if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad)))
+ __leave;
+
+ // Get the Frame count
+ if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1)
+ __leave;
+
+ // Get the Frame
+ if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame)))
+ __leave;
+
+ // Get the WicFrame image format
+ if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat)))
+ __leave;
+
+ // Check if the image format is supported:
+ if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppPRGBA))
+ {
+ wicBitmapSource = (IWICBitmapSource*)wicFrame;
+ }
+ else
+ {
+ IWICFormatConverter* wicFormatConverter = NULL;
+
+ if (FAILED(IWICImagingFactory_CreateFormatConverter(wicFactory, &wicFormatConverter)))
+ __leave;
+
+ if (FAILED(IWICFormatConverter_Initialize(
+ wicFormatConverter,
+ (IWICBitmapSource*)wicFrame,
+ &GUID_WICPixelFormat32bppPRGBA,
+ WICBitmapDitherTypeNone,
+ NULL,
+ 0.0,
+ WICBitmapPaletteTypeCustom
+ )))
+ {
+ IWICFormatConverter_Release(wicFormatConverter);
+ __leave;
+ }
+
+ // Convert the image to the correct format:
+ IWICFormatConverter_QueryInterface(wicFormatConverter, &IID_IWICBitmapSource, &wicBitmapSource);
+
+ // Cleanup the converter.
+ IWICFormatConverter_Release(wicFormatConverter);
+
+ // Dispose the old frame now that the converted frame is in wicBitmapSource.
+ IWICBitmapFrameDecode_Release(wicFrame);
+ }
+
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = rect.Width;
+ bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height);
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ screenHdc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
+ bufferDc = CreateCompatibleDC(screenHdc);
+ bitmapHandle = CreateDIBSection(screenHdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
+
+ // Check if it's the same rect as the requested size.
+ //if (width != rect.Width || height != rect.Height)
+ if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler)))
+ __leave;
+ if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant)))
+ __leave;
+ if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer)))
+ __leave;
+
+ isSuccess = TRUE;
+ }
+ __finally
+ {
+ if (wicScaler)
+ {
+ IWICBitmapScaler_Release(wicScaler);
+ }
+
+ if (bufferDc)
+ {
+ DeleteDC(bufferDc);
+ }
+
+ if (screenHdc)
+ {
+ DeleteDC(screenHdc);
+ }
+
+ if (wicBitmapSource)
+ {
+ IWICBitmapSource_Release(wicBitmapSource);
+ }
+
+ if (wicStream)
+ {
+ IWICStream_Release(wicStream);
+ }
+
+ if (wicDecoder)
+ {
+ IWICBitmapDecoder_Release(wicDecoder);
+ }
+
+ if (wicFactory)
+ {
+ IWICImagingFactory_Release(wicFactory);
+ }
+
+ if (resourceHandle)
+ {
+ FreeResource(resourceHandle);
+ }
+ }
+
+ if (isSuccess)
+ return bitmapHandle;
+
+ DeleteObject(bitmapHandle);
+ return NULL;
+}
diff --git a/plugins-extra/NetExtrasPlugin/ports.c b/plugins-extra/NetExtrasPlugin/ports.c
new file mode 100644
index 0000000..6a1e5c4
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/ports.c
@@ -0,0 +1,1597 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Network Extras Plugin
+ *
+ * Copyright (C) 2015 dmex
+ * Copyright (C) 2015 TETYYS
+ *
+ * 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 "main.h"
+
+RESOLVED_PORT ResolvedPortsTable[] =
+{
+ { L"1ci-smcs", 3091 }, { L"2ping", 15998 }, { L"3com-amp3", 629 }, { L"3com-net-mgmt", 2391 },
+ { L"3com-njack-1", 5264 }, { L"3com-njack-2", 5265 }, { L"3Com-nsd", 1742 }, { L"3com-tsmux", 106 },
+ { L"3com-webview", 2339 }, { L"3comfaxrpc", 3446 }, { L"3comnetman", 1181 }, { L"3d-nfsd", 2323 },
+ { L"3ds-lm", 1538 }, { L"3exmp", 5221 }, { L"3gpp-cbsp", 48049 }, { L"3l-l1", 1511 },
+ { L"3link", 15363 }, { L"3m-image-lm", 1550 }, { L"3par-evts", 5781 }, { L"3par-mgmt", 5782 },
+ { L"3par-mgmt-ssl", 5783 }, { L"3par-rcopy", 5785 }, { L"4-tieropmcli", 2934 }, { L"4-tieropmgw", 2933 },
+ { L"4talk", 3284 }, { L"6a44", 1027 }, { L"802-11-iapp", 3517 }, { L"914c-g", 211 },
+ { L"9pfs", 564 }, { L"a1-bs", 5603 }, { L"a1-msc", 5602 }, { L"a13-an", 3125 },
+ { L"a14", 3597 }, { L"a15", 3598 }, { L"a16-an-an", 4598 }, { L"a17-an-an", 4599 },
+ { L"a21-an-1xbs", 4597 }, { L"a25-fap-fgw", 4502 }, { L"a26-fap-fgw", 4726 }, { L"a27-ran-ran", 28119 },
+ { L"a3-sdunode", 5604 }, { L"a4-sdunode", 5605 }, { L"aairnet-1", 3618 }, { L"aairnet-2", 3619 },
+ { L"aal-lm", 1469 }, { L"aamp", 3939 }, { L"aap", 2878 }, { L"aas", 1601 },
+ { L"abacus-remote", 2894 }, { L"abarsd", 8402 }, { L"abatemgr", 3655 }, { L"abatjss", 3656 },
+ { L"abb-escp", 6316 }, { L"abbaccuray", 1546 }, { L"abbs", 4885 }, { L"abcsoftware", 3996 },
+ { L"abcvoice-port", 3781 }, { L"about", 2019 }, { L"abr-api", 1954 }, { L"abr-secure", 1955 },
+ { L"ac-cluster", 18463 }, { L"ac-tech", 2796 }, { L"acap", 674 }, { L"acas", 62 },
+ { L"acc-raid", 2800 }, { L"accel", 4108 }, { L"accelenet", 1182 }, { L"accelenet-data", 1182 },
+ { L"accessbuilder", 888 }, { L"accessnetwork", 699 }, { L"accord-mgc", 1205 }, { L"acctopus-cc", 6868 },
+ { L"acctopus-st", 6868 }, { L"accu-lmgr", 7781 }, { L"accuracer", 12007 }, { L"accuracer-dbms", 12008 },
+ { L"acd-pm", 8793 }, { L"ace-client", 2334 }, { L"ace-proxy", 2335 }, { L"ace-server", 2475 },
+ { L"ace-svr-prop", 2476 }, { L"aci", 187 }, { L"acis,9953,tcp", 9953 }, { L"acis,9953,udp", 9953 },
+ { L"acl-manager", 4013 }, { L"acmaint-dbd", 774 }, { L"acmaint_dbd", 774 }, { L"acmaint_transd", 775 },
+ { L"acme", 9216 }, { L"acms", 3980 }, { L"acmsoda", 6969 }, { L"acnet", 6801 },
+ { L"acp", 599 }, { L"acp-conduit", 3823 }, { L"acp-discovery", 3822 }, { L"acp-policy", 3824 },
+ { L"acp-port", 2071 }, { L"acp-proto", 4046 }, { L"acplt", 7509 }, { L"acptsys", 2149 },
+ { L"acr-nema", 104 }, { L"acter", 4671 }, { L"actifio-c2c", 5103 }, { L"actifioudsagent", 5106 },
+ { L"active-net", 3322 }, { L"active-net", 3324 }, { L"active-net", 3325 }, { L"activememory", 2859 },
+ { L"activesync", 1034 }, { L"actnet", 5411 }, { L"ada-cip", 2085 }, { L"adap", 6350 },
+ { L"adapt-sna", 1365 }, { L"adaptecmgr", 2521 }, { L"adcp", 7508 }, { L"adi-gxp-srvprt", 6769 },
+ { L"admind", 3279 }, { L"admind", 8403 }, { L"admins-lms", 2692 }, { L"adobeserver-1", 1102 },
+ { L"adobeserver-2", 1103 }, { L"adobeserver-3", 3703 }, { L"adobeserver-4", 3704 }, { L"adobeserver-5", 3705 },
+ { L"adrep", 3954 }, { L"ads", 2550 }, { L"ads-c", 5913 }, { L"adtech-test", 3357 },
+ { L"adtempusclient", 3760 }, { L"advant-lm", 2295 }, { L"adws", 9389 }, { L"aed-512", 149 },
+ { L"aegate", 4549 }, { L"aequus", 23456 }, { L"aequus-alt", 23457 }, { L"aero", 8060 },
+ { L"aeroflight-ads", 1218 }, { L"aeroflight-ret", 1219 }, { L"aes-discovery", 3224 }, { L"aes-x170", 7107 },
+ { L"aesop", 8202 }, { L"af", 1411 }, { L"afesc-mc", 6628 }, { L"affiliate", 6579 },
+ { L"afore-vdp-disc", 4362 }, { L"afpovertcp", 548 }, { L"afrog", 1042 }, { L"afs", 1483 },
+ { L"afs3-bos", 7007 }, { L"afs3-callback", 7001 }, { L"afs3-errors", 7006 }, { L"afs3-fileserver", 7000 },
+ { L"afs3-kaserver", 7004 }, { L"afs3-prserver", 7002 }, { L"afs3-rmtsys", 7009 }, { L"afs3-update", 7008 },
+ { L"afs3-vlserver", 7003 }, { L"afs3-volser", 7005 }, { L"aftmux", 3917 }, { L"agcat", 3915 },
+ { L"agentsease-db", 3997 }, { L"agentview", 2331 }, { L"agentx", 705 }, { L"agpolicy", 38203 },
+ { L"agps-port", 3425 }, { L"agri-gateway", 3026 }, { L"agriserver", 3021 }, { L"agslb", 4149 },
+ { L"ah-esp-encap", 2070 }, { L"ahsp", 4333 }, { L"aiagent", 7738 }, { L"aibkup", 4071 },
+ { L"aic-np", 2785 }, { L"aic-oncrpc", 2786 }, { L"aicc-cmi", 3316 }, { L"ailith", 17555 },
+ { L"aimpp-hello", 2846 }, { L"aimpp-port-req", 2847 }, { L"aipn-auth", 3833 }, { L"aipn-reg", 4113 },
+ { L"aironetddp", 2887 }, { L"airs", 1481 }, { L"airshot", 3975 }, { L"airsync", 2175 },
+ { L"aises", 2783 }, { L"aja-ntv4-disc", 4804 }, { L"aker-cdp", 2473 }, { L"alaris-disc", 3613 },
+ { L"alarm", 2740 }, { L"alarm-clock-c", 2668 }, { L"alarm-clock-s", 2667 }, { L"alchemy", 3234 },
+ { L"alesquery", 5074 }, { L"alfin", 16003 }, { L"alias", 1187 }, { L"alljoyn", 9956 },
+ { L"alljoyn-mcm", 9955 }, { L"alljoyn-stm", 9955 }, { L"allpeers", 36001 }, { L"allstorcns", 2901 },
+ { L"almobile-system", 9209 }, { L"alpes", 463 }, { L"alpha-sms", 1849 }, { L"alphatech-lm", 1653 },
+ { L"alta-ana-lm", 1346 }, { L"altalink", 1845 }, { L"altav-remmgt", 2456 }, { L"altav-tunnel", 3265 },
+ { L"altbsdp", 7799 }, { L"altcp", 4165 }, { L"altova-lm", 35355 }, { L"altova-lm-disc", 35355 },
+ { L"altovacentral", 4689 }, { L"altserviceboot", 4011 }, { L"amahi-anywhere", 4563 }, { L"amanda", 10080 },
+ { L"amberon", 8301 }, { L"ambit-lm", 6831 }, { L"amc", 5506 }, { L"amcs", 8766 },
+ { L"amdsched", 1931 }, { L"amicon-fpsu-ra", 30003 }, { L"amicon-fpsu-s", 30004 }, { L"amiganetfs", 2100 },
+ { L"aminet", 2639 }, { L"amp", 3811 }, { L"ampify", 8040 }, { L"ampl-lic", 5195 },
+ { L"ampl-tableproxy", 5196 }, { L"ampr-info", 1535 }, { L"ampr-inter", 1536 }, { L"ampr-rcmd", 459 },
+ { L"amqp", 5672 }, { L"amqps", 5671 }, { L"ams", 1037 }, { L"amt", 2268 },
+ { L"amt-blc-port", 2848 }, { L"amt-cnf-prot", 3054 }, { L"amt-esd-prot", 1082 }, { L"amt-redir-tcp", 16994 },
+ { L"amt-redir-tls", 16995 }, { L"amt-soap-http", 16992 }, { L"amt-soap-https", 16993 }, { L"amx-axbnet", 1320 },
+ { L"amx-icsp", 1319 }, { L"amx-rms", 3839 }, { L"amx-webadmin", 2929 }, { L"amx-weblinx", 2930 },
+ { L"an-pcp", 3846 }, { L"an-signaling", 4936 }, { L"and-lm", 2646 }, { L"anet", 212 },
+ { L"anet-b", 3338 }, { L"anet-h", 3341 }, { L"anet-l", 3339 }, { L"anet-m", 3340 },
+ { L"anoto-rendezv", 3715 }, { L"ans-console", 3440 }, { L"ansanotify", 116 }, { L"ansatrader", 124 },
+ { L"ansoft-lm-1", 1083 }, { L"ansoft-lm-2", 1084 }, { L"answersoft-lm", 1781 }, { L"ansys-lm", 1800 },
+ { L"ansysli", 2325 }, { L"ansyslmd", 1055 }, { L"anthony-data", 1206 }, { L"antidotemgrsvr", 2247 },
+ { L"aocp", 2712 }, { L"aodv", 654 }, { L"aol", 5190 }, { L"aol-1", 5191 },
+ { L"aol-2", 5192 }, { L"aol-3", 5193 }, { L"ap", 47806 }, { L"apani1", 9160 },
+ { L"apani2", 9161 }, { L"apani3", 9162 }, { L"apani4", 9163 }, { L"apani5", 9164 },
+ { L"apc-2160", 2160 }, { L"apc-2161", 2161 }, { L"apc-2260", 2260 }, { L"apc-3052", 3052 },
+ { L"apc-3506", 3506 }, { L"apc-5454", 5454 }, { L"apc-5455", 5455 }, { L"apc-5456", 5456 },
+ { L"apc-6547", 6547 }, { L"apc-6548", 6548 }, { L"apc-6549", 6549 }, { L"apc-7845", 7845 },
+ { L"apc-7846", 7846 }, { L"apc-9950", 9950 }, { L"apc-9951", 9951 }, { L"apc-9952", 9952 },
+ { L"apc-necmp", 18888 }, { L"apcupsd", 3551 }, { L"apdap", 3948 }, { L"apertus-ldp", 539 },
+ { L"apex-edge", 913 }, { L"apex-mesh", 912 }, { L"aplx", 1134 }, { L"apm-link", 32483 },
+ { L"apocd", 3809 }, { L"apogeex-port", 3184 }, { L"apollo-admin", 8122 }, { L"apollo-cc", 2754 },
+ { L"apollo-data", 8121 }, { L"apollo-gms", 2759 }, { L"apollo-relay", 10252 }, { L"apollo-status", 2758 },
+ { L"apparenet-as", 3238 }, { L"apparenet-tps", 3237 }, { L"apparenet-ts", 3236 }, { L"apparenet-ui", 3239 },
+ { L"appiq-mgmt", 4674 }, { L"Apple Remote Desktop (Net Assistant)", 3283 }, { L"apple-licman", 1381 }, { L"apple-sasl", 3659 },
+ { L"apple-vpns-rp", 4112 }, { L"appleqtc", 458 }, { L"appleqtcsrvr", 545 }, { L"appleugcontrol", 2336 },
+ { L"appliance-cfg", 2898 }, { L"applix", 999 }, { L"applus", 2037 }, { L"applusservice", 4087 },
+ { L"appman-server", 3312 }, { L"appserv-http", 4848 }, { L"appserv-https", 4849 }, { L"appss-lm", 3879 },
+ { L"appswitch-emp", 2616 }, { L"appworxsrv", 2136 }, { L"apri-lm", 1447 }, { L"aprigo-cs", 5086 },
+ { L"apsolab-col", 5470 }, { L"apsolab-cols", 5471 }, { L"apsolab-data", 5475 }, { L"apsolab-rpc", 5474 },
+ { L"apsolab-tag", 5472 }, { L"apsolab-tags", 5473 }, { L"apw-registry", 3758 }, { L"apwi-disc", 4394 },
+ { L"apwi-imserver", 4391 }, { L"apwi-rxserver", 4392 }, { L"apwi-rxspooler", 4393 }, { L"apx500api-1", 2264 },
+ { L"apx500api-2", 2265 }, { L"arbortext-lm", 1557 }, { L"arcisdms", 262 }, { L"arcp", 7070 },
+ { L"arcpd", 3513 }, { L"ardt", 1826 }, { L"ardus-cntl", 1116 }, { L"ardus-mtrns", 1117 },
+ { L"ardus-trns", 1115 }, { L"ardusmul", 1835 }, { L"ardusuni", 1834 }, { L"areaguard-neo", 23546 },
+ { L"arena-server", 11321 }, { L"arepa-cas", 3030 }, { L"arepa-raft", 3025 }, { L"argis-ds", 2582 },
+ { L"argis-te", 2581 }, { L"aria", 2624 }, { L"ariel1", 419 }, { L"ariel2", 421 },
+ { L"ariel3", 422 }, { L"aries-kfinder", 7570 }, { L"ariliamulti", 3140 }, { L"arkivio", 3426 },
+ { L"armadp", 1913 }, { L"armagetronad", 4534 }, { L"armcenterhttp", 9294 }, { L"armcenterhttps", 9295 },
+ { L"armi-server", 3174 }, { L"armtechdaemon", 9292 }, { L"arns", 384 }, { L"array-manager", 3726 },
+ { L"ars-master", 3176 }, { L"ars-vista", 27782 }, { L"artifact-msg", 3518 }, { L"aruba-server", 7166 },
+ { L"as-debug", 4026 }, { L"as-servermap", 449 }, { L"asa", 386 }, { L"asam", 3451 },
+ { L"asap-sctp", 3863 }, { L"asap-sctp-tls", 3864 }, { L"asap-tcp", 3863 }, { L"asap-tcp-tls", 3864 },
+ { L"asap-udp", 3863 }, { L"asc-slmd", 4448 }, { L"asci-val", 1560 }, { L"ascomalarm", 4077 },
+ { L"asctrl-agent", 5155 }, { L"asdis", 2192 }, { L"asf-rmcp", 623 }, { L"asf-secure-rmcp", 664 },
+ { L"asgcypresstcps", 11489 }, { L"asgenf", 5727 }, { L"asi", 1827 }, { L"asia", 626 },
+ { L"asihpi", 44600 }, { L"asip-webadmin", 311 }, { L"asipregistry", 687 }, { L"asmp", 45000 },
+ { L"asmp-mon", 45000 }, { L"asmps", 45001 }, { L"asnaacceler8db", 5042 }, { L"asoki-sma", 3087 },
+ { L"aspcoordination", 7235 }, { L"aspeclmd", 1544 }, { L"aspen-services", 1749 }, { L"aspentec-lm", 6142 },
+ { L"asprovatalk", 1079 }, { L"asr", 7800 }, { L"assoc-disc", 24850 }, { L"assuria-ins", 4704 },
+ { L"assuria-slm", 4119 }, { L"assyst-dr", 4485 }, { L"astergate", 9106 }, { L"astergate-disc", 9106 },
+ { L"astergatefax", 9107 }, { L"asterix", 8600 }, { L"astrolink", 27876 }, { L"astromed-main", 2864 },
+ { L"at-3", 203 }, { L"at-5", 205 }, { L"at-7", 207 }, { L"at-8", 208 },
+ { L"at-echo", 204 }, { L"at-nbp", 202 }, { L"at-rtmp", 201 }, { L"at-zis", 206 },
+ { L"atc-appserver", 1171 }, { L"atc-lm", 1170 }, { L"atex-elmd", 1385 }, { L"athand-mmp", 20999 },
+ { L"ati-ip-to-ncpe", 3965 }, { L"atlinks", 4154 }, { L"atm-uhas", 11367 }, { L"atm-zip-office", 1520 },
+ { L"atmp", 5150 }, { L"atmtcp", 2812 }, { L"ats", 2201 }, { L"atsc-mh-ssc", 4937 },
+ { L"att-mt-sms", 5586 }, { L"attachmate-g32", 2317 }, { L"attachmate-s2s", 2419 }, { L"attachmate-uts", 2304 },
+ { L"atul", 7543 }, { L"audio-activmail", 1397 }, { L"audiojuggler", 3643 }, { L"audit", 182 },
+ { L"audit-transfer", 1146 }, { L"auditd", 48 }, { L"aura", 2066 }, { L"auriga-router", 5680 },
+ { L"auris", 2772 }, { L"aurora", 9084 }, { L"aurora-balaena", 33123 }, { L"aurora-cmgr", 364 },
+ { L"aurp", 387 }, { L"auth", 113 }, { L"authentx", 5067 }, { L"autobuild", 5115 },
+ { L"autocueds", 3437 }, { L"autocuelog", 3104 }, { L"autocuesmi", 3103 }, { L"autocuetime", 3104 },
+ { L"autodesk-lm", 1422 }, { L"autodesk-nlm", 2080 }, { L"autonoc", 1140 }, { L"autopac", 4685 },
+ { L"autotrac-acp", 31020 }, { L"av-emb-config", 2050 }, { L"availant-mgr", 1122 }, { L"avantageb2b", 2131 },
+ { L"avanti-cdp", 4065 }, { L"avauthsrvprtcl", 2068 }, { L"avdecc", 17221 }, { L"avenue", 2134 },
+ { L"avenyo", 2992 }, { L"avian", 486 }, { L"avinstalldisc", 3502 }, { L"aviva-sna", 2238 },
+ { L"avocent-adsap", 3871 }, { L"avocent-proxy", 1078 }, { L"avsecuremgmt", 3211 }, { L"avt-profile-1", 5004 },
+ { L"avt-profile-2", 5005 }, { L"avtp", 17220 }, { L"awacs-ice", 4488 }, { L"awg-proxy", 3277 },
+ { L"aws-brf", 22800 }, { L"axis-wimp-port", 10260 }, { L"axon-lm", 1548 }, { L"axon-tunnel", 16665 },
+ { L"ayiya", 5072 }, { L"azeti", 4192 }, { L"azeti-bd", 4192 }, { L"aztec", 3512 },
+ { L"b-novative-ls", 1896 }, { L"b2-license", 2204 }, { L"b2-runtime", 2203 }, { L"b2n", 1179 },
+ { L"babel", 6696 }, { L"backburner", 2635 }, { L"backroomnet", 3387 }, { L"backup-express", 6123 },
+ { L"backupedge", 3946 }, { L"bacnet", 47808 }, { L"bacula-dir", 9101 }, { L"bacula-fd", 9102 },
+ { L"bacula-sd", 9103 }, { L"badm-priv", 6505 }, { L"badm-pub", 6506 }, { L"bandwiz-system", 1929 },
+ { L"banyan-net", 2708 }, { L"banyan-rpc", 567 }, { L"banyan-vip", 573 }, { L"barracuda-bbs", 5120 },
+ { L"base", 5429 }, { L"batman", 4305 }, { L"bb", 1984 }, { L"bbars", 3327 },
+ { L"bbn-mmc", 1347 }, { L"bbn-mmx", 1348 }, { L"bccp", 4175 }, { L"bcinameservice", 3415 },
+ { L"bcs", 4677 }, { L"bcs-broker", 1704 }, { L"bcs-lmserver", 1951 }, { L"bcslogc", 13216 },
+ { L"bctp", 8999 }, { L"bctp-server", 10107 }, { L"bdir-priv", 6507 }, { L"bdir-pub", 6508 },
+ { L"bdir_pub", 6508 }, { L"bdp", 581 }, { L"beacon-port", 3124 }, { L"beacon-port-2", 4426 },
+ { L"bears-01", 2852 }, { L"bears-02", 3146 }, { L"beeyond", 2414 }, { L"beeyond-media", 1943 },
+ { L"beorl", 5633 }, { L"berknet", 2005 }, { L"BESApi", 3408 }, { L"beserver-msg-q", 3527 },
+ { L"bess", 3960 }, { L"bex-webadmin", 6122 }, { L"bex-xr", 15660 }, { L"beyond-remote", 5424 },
+ { L"bf-game", 25954 }, { L"bf-master", 25955 }, { L"bfd-control", 3784 }, { L"bfd-echo", 3785 },
+ { L"bfd-lag", 6784 }, { L"bfd-multi-ctl", 4784 }, { L"bflckmgr", 3966 }, { L"bftp", 152 },
+ { L"bgmp", 264 }, { L"bgp", 179 }, { L"bgs-nsi", 482 }, { L"bh611", 354 },
+ { L"bhevent", 357 }, { L"bhfhs", 248 }, { L"bhmds", 310 }, { L"bhoedap4", 352 },
+ { L"bhoetty", 351 }, { L"biap-mp", 1962 }, { L"biff", 512 }, { L"biimenu", 18000 },
+ { L"bilobit", 24577 }, { L"bilobit-update", 24577 }, { L"bim-pem", 3783 }, { L"binderysupport", 2302 },
+ { L"bingbang", 29999 }, { L"binkp", 24554 }, { L"bintec-admin", 2107 }, { L"bintec-capi", 2662 },
+ { L"bintec-tapi", 2663 }, { L"biolink-auth", 3411 }, { L"bioserver", 6946 }, { L"biotic", 5087 },
+ { L"bip", 4376 }, { L"bis-sync", 5585 }, { L"bis-web", 5584 }, { L"bitforestsrv", 5068 },
+ { L"bitspeer", 2178 }, { L"bl-idm", 142 }, { L"blackboard", 2032 }, { L"blackjack", 1025 },
+ { L"blaze", 1150 }, { L"blizwow", 3724 }, { L"blockade", 2911 }, { L"blockade-bpsp", 2574 },
+ { L"blocks", 10288 }, { L"blp1", 8194 }, { L"blp2", 8195 }, { L"blp3", 8292 },
+ { L"blp4", 8294 }, { L"blp5", 48129 }, { L"blueberry-lm", 1432 }, { L"bluectrlproxy", 2277 },
+ { L"bluelance", 2877 }, { L"blwnkl-port", 2625 }, { L"bmap", 3421 }, { L"bmc-ar", 2494 },
+ { L"bmc-ctd-ldap", 6301 }, { L"bmc-data-coll", 3695 }, { L"bmc-ea", 3683 }, { L"bmc-gms", 10129 },
+ { L"bmc-grx", 6300 }, { L"bmc-jmx-port", 3604 }, { L"bmc-messaging", 2059 }, { L"bmc-net-adm", 1769 },
+ { L"bmc-net-svc", 1770 }, { L"bmc-onekey", 3561 }, { L"bmc-patroldb", 1313 }, { L"bmc-perf-agent", 6767 },
+ { L"bmc-perf-mgrd", 6768 }, { L"bmc-perf-sd", 10128 }, { L"bmc-reporting", 4568 }, { L"bmcpatrolagent", 3181 },
+ { L"bmcpatrolrnvu", 3182 }, { L"bmdss", 13823 }, { L"bmpp", 632 }, { L"bnet", 415 },
+ { L"bnetfile", 1120 }, { L"bnetgame", 1119 }, { L"bngsync", 10439 }, { L"bnt-manager", 3344 },
+ { L"board-roar", 9700 }, { L"board-voip", 9750 }, { L"boe-cachesvr", 6403 }, { L"boe-cms", 6400 },
+ { L"boe-eventsrv", 6402 }, { L"boe-filesvr", 6404 }, { L"boe-pagesvr", 6405 }, { L"boe-processsvr", 6406 },
+ { L"boe-resssvr1", 6407 }, { L"boe-resssvr2", 6408 }, { L"boe-resssvr3", 6409 }, { L"boe-resssvr4", 6410 },
+ { L"boe-was", 6401 }, { L"boinc-client", 1043 }, { L"boks", 6500 }, { L"boks-clntd", 6503 },
+ { L"boks-servc", 6501 }, { L"boks-servm", 6502 }, { L"boldsoft-lm", 2961 }, { L"bones", 4914 },
+ { L"boomerang", 1304 }, { L"boosterware", 2913 }, { L"bootclient", 2017 }, { L"bootpc", 68 },
+ { L"bootps", 67 }, { L"bootserver", 2016 }, { L"borland-dsj", 707 }, { L"boscap", 2990 },
+ { L"bounzza", 2218 }, { L"boxbackupstore", 4186 }, { L"boxp", 9380 }, { L"bpcd", 13782 },
+ { L"bpcp-poll", 2844 }, { L"bpcp-trap", 2845 }, { L"bpdbm", 13721 }, { L"bpjava-msvc", 13722 },
+ { L"bpmd", 3593 }, { L"bprd", 13720 }, { L"br-channel", 5425 }, { L"brain", 2169 },
+ { L"brcd", 1323 }, { L"brcm-comm-port", 3188 }, { L"brdptc", 2155 }, { L"bre", 4096 },
+ { L"brf-gw", 22951 }, { L"bridgecontrol", 1073 }, { L"brightcore", 5682 }, { L"brlp-0", 4101 },
+ { L"brlp-1", 4102 }, { L"brlp-2", 4103 }, { L"brlp-3", 4104 }, { L"broker-service", 3014 },
+ { L"brp", 3043 }, { L"bruce", 2619 }, { L"brutus", 2003 }, { L"brvread", 1054 },
+ { L"bsfserver-zn", 5320 }, { L"bsfsvr-zn-ssl", 5321 }, { L"bspne-pcc", 1252 }, { L"bsquare-voip", 1071 },
+ { L"btpp2audctr1", 2536 }, { L"btpp2sectrans", 2444 }, { L"btprjctrl", 2803 }, { L"btrieve", 3351 },
+ { L"bts-appserver", 1961 }, { L"bts-x73", 3681 }, { L"buddy-draw", 1854 }, { L"bues-service", 2446 },
+ { L"bullant-rap", 2965 }, { L"bullant-srap", 2964 }, { L"busboy", 998 }, { L"buschtrommel", 4747 },
+ { L"business", 3107 }, { L"busycal", 4990 }, { L"bv-agent", 3993 }, { L"bv-ds", 3992 },
+ { L"bv-is", 3990 }, { L"bv-queryengine", 3989 }, { L"bv-smcsrv", 3991 }, { L"bvcdaemon-port", 3626 },
+ { L"bvcontrol", 1236 }, { L"bveapi", 10880 }, { L"bvtsonar", 1149 }, { L"bxp", 4027 },
+ { L"bytex", 1375 }, { L"bzflag", 5154 }, { L"bzr", 4155 }, { L"c-h-it-port", 3778 },
+ { L"c1222-acse", 1153 }, { L"c3", 2472 }, { L"ca-1", 5064 }, { L"ca-2", 5065 },
+ { L"ca-audit-da", 8025 }, { L"ca-audit-ds", 8026 }, { L"ca-idms", 3709 }, { L"ca-web-update", 14414 },
+ { L"caaclang2", 5249 }, { L"caacws", 5248 }, { L"cab-protocol", 595 }, { L"cableport-ax", 282 },
+ { L"cabsm-comm", 7161 }, { L"caci-lm", 1554 }, { L"cacsambroker", 7163 }, { L"cadabra-lm", 1563 },
+ { L"cadencecontrol", 2318 }, { L"cadis-1", 1441 }, { L"cadis-2", 1442 }, { L"cadkey-licman", 1399 },
+ { L"cadkey-tablet", 1400 }, { L"cadlock", 770 }, { L"cadlock2", 1000 }, { L"cadsi-lm", 1387 },
+ { L"cadview-3d", 649 }, { L"caerpc", 42510 }, { L"caevms", 5251 }, { L"caicci", 1721 },
+ { L"caiccipc", 1202 }, { L"caids-sensor", 1192 }, { L"CAIlic", 216 }, { L"caistoragemgr", 7162 },
+ { L"cajo-discovery", 1198 }, { L"cal", 588 }, { L"caldsoft-backup", 22537 }, { L"call-logging", 2552 },
+ { L"call-sig-trans", 2517 }, { L"caller9", 2906 }, { L"calltrax", 3675 }, { L"callwaveiam", 9283 },
+ { L"camac", 3545 }, { L"cambertx-lm", 1734 }, { L"camp", 4450 }, { L"can-dch", 1919 },
+ { L"can-ferret", 1920 }, { L"can-ferret-ssl", 3661 }, { L"can-nds", 1918 }, { L"can-nds-ssl", 3660 },
+ { L"canditv", 24676 }, { L"candp", 42508 }, { L"candrp", 42509 }, { L"canex-watch", 3583 },
+ { L"canit_store", 6568 }, { L"canocentral0", 1871 }, { L"canocentral1", 1872 }, { L"canon-bjnp1", 8611 },
+ { L"canon-bjnp2", 8612 }, { L"canon-bjnp3", 8613 }, { L"canon-bjnp4", 8614 }, { L"canon-capt", 3756 },
+ { L"canon-cpp-disc", 8609 }, { L"canon-mfnp", 8610 }, { L"canto-roboflow", 8998 }, { L"cap", 1026 },
+ { L"capfast-lmd", 1756 }, { L"capioverlan", 1147 }, { L"capmux", 4728 }, { L"caps-lm", 3290 },
+ { L"capwap-control", 5246 }, { L"capwap-data", 5247 }, { L"car", 5090 }, { L"cardax", 1072 },
+ { L"cardbox", 3105 }, { L"cardbox-http", 3106 }, { L"carrius-rshell", 1197 }, { L"cart-o-rama", 3292 },
+ { L"cartographerxmp", 5270 }, { L"cas", 2418 }, { L"cas-mapi", 3682 }, { L"casanswmgmt", 3669 },
+ { L"casp", 1130 }, { L"caspssl", 1131 }, { L"casrmagent", 7167 }, { L"castorproxy", 3450 },
+ { L"catalyst", 2836 }, { L"catchpole", 1185 }, { L"caupc-remote", 2122 }, { L"cautcpd", 3061 },
+ { L"cawas", 12168 }, { L"cba8", 9593 }, { L"cbos-ip-port", 3750 }, { L"cbserver", 3388 },
+ { L"cbt", 7777 }, { L"cc-tracking", 4870 }, { L"ccag-pib", 7169 }, { L"ccm-port", 3575 },
+ { L"ccmad", 3114 }, { L"ccmail", 3264 }, { L"ccmcomm", 3505 }, { L"ccmrmi", 3154 },
+ { L"ccnx", 9695 }, { L"ccowcmr", 2116 }, { L"ccp", 3947 }, { L"ccs-software", 2734 },
+ { L"ccss-qmm", 4969 }, { L"ccss-qsm", 4970 }, { L"cctv-port", 3559 }, { L"ccu-comm-1", 4053 },
+ { L"ccu-comm-2", 4054 }, { L"ccu-comm-3", 4055 }, { L"cd3o-protocol", 3616 }, { L"cdbroker", 3376 },
+ { L"cdc", 223 }, { L"cddbp", 888 }, { L"cddbp-alt", 8880 }, { L"cdfunc", 2045 },
+ { L"cdid", 3315 }, { L"cdl-server", 3056 }, { L"cdn", 2412 }, { L"cds", 4115 },
+ { L"cecsvc", 2571 }, { L"cedros-fds", 4140 }, { L"cefd-vmp", 10023 }, { L"celatalk", 3485 },
+ { L"centerline", 3987 }, { L"centra", 1709 }, { L"cequint-cityid", 4074 }, { L"cera-bcm", 1794 },
+ { L"cernsysmgmtagt", 3830 }, { L"cert-initiator", 1639 }, { L"cert-responder", 1640 }, { L"cesdcdman", 2921 },
+ { L"cesdcdtrn", 2922 }, { L"cesdinv", 2856 }, { L"cfdptkt", 120 }, { L"cfengine", 5308 },
+ { L"cfs", 7546 }, { L"cft-0", 1761 }, { L"cft-1", 1762 }, { L"cft-2", 1763 },
+ { L"cft-3", 1764 }, { L"cft-4", 1765 }, { L"cft-5", 1766 }, { L"cft-6", 1767 },
+ { L"cft-7", 1768 }, { L"cfw", 7563 }, { L"cgi-starapi", 3893 }, { L"cgms", 3003 },
+ { L"cgn-config", 2183 }, { L"cgn-stat", 2182 }, { L"chargen", 19 }, { L"charsetmgr", 3903 },
+ { L"checkoutdb", 5505 }, { L"checkpoint-rtm", 18241 }, { L"checksum", 1386 }, { L"chevinservices", 3349 },
+ { L"childkey-ctrl", 1892 }, { L"childkey-notif", 1891 }, { L"chimera-hwm", 4009 }, { L"chip-lm", 1572 },
+ { L"chipper", 17219 }, { L"chmd", 3099 }, { L"choiceview-agt", 4314 }, { L"choiceview-clt", 4316 },
+ { L"chromagrafx", 1373 }, { L"chshell", 562 }, { L"ci3-software-1", 1301 }, { L"ci3-software-2", 1302 },
+ { L"cichild-lm", 1523 }, { L"cichlid", 1377 }, { L"cifs", 3020 }, { L"cim-rs", 5993 },
+ { L"cimple", 10125 }, { L"cimplex", 673 }, { L"cimtrak", 3749 }, { L"cindycollab", 3770 },
+ { L"cinegrfx-elmd", 2891 }, { L"cinegrfx-lm", 1743 }, { L"ciphire-data", 3887 }, { L"ciphire-serv", 3888 },
+ { L"circle-x", 2931 }, { L"cis", 22305 }, { L"cis-secure", 22343 }, { L"cisco-avp", 8470 },
+ { L"cisco-fna", 130 }, { L"cisco-ipsla", 1167 }, { L"cisco-net-mgmt", 1741 }, { L"cisco-redu", 5786 },
+ { L"cisco-sccp", 2000 }, { L"cisco-snat", 15555 }, { L"cisco-sys", 132 }, { L"cisco-tdp", 711 },
+ { L"cisco-tna", 131 }, { L"cisco-vpath-tun", 6633 }, { L"cisco-wafs", 4050 }, { L"ciscocsdb", 43441 },
+ { L"citadel", 504 }, { L"citrix-rtmp", 2897 }, { L"citrixadmin", 2513 }, { L"citrixima", 2512 },
+ { L"citriximaclient", 2598 }, { L"citrixupp", 7228 }, { L"citrixuppg", 7229 }, { L"citynl", 1729 },
+ { L"citysearch", 3974 }, { L"cl-1", 172 }, { L"cl-db-attach", 4135 }, { L"cl-db-remote", 4137 },
+ { L"cl-db-request", 4136 }, { L"cl/1", 172 }, { L"clariion-evr01", 6389 }, { L"classic", 9087 },
+ { L"cleanerliverc", 3481 }, { L"clearcase", 371 }, { L"clearvisn", 2052 }, { L"clever-ctrace", 6687 },
+ { L"clever-tcpip", 6688 }, { L"cleverdetect", 6690 }, { L"client-ctrl", 3730 }, { L"client-wakeup", 9694 },
+ { L"cloanto-lm", 3397 }, { L"cloanto-net-1", 356 }, { L"close-combat", 1944 }, { L"cloudsignaling", 7550 },
+ { L"clp", 2567 }, { L"cluster-disc", 3374 }, { L"clusterxl", 18243 }, { L"clutild", 7174 },
+ { L"clvm-cfg", 1476 }, { L"cm", 5910 }, { L"cma", 1050 }, { L"cmadmin", 2617 },
+ { L"cmc-port", 3576 }, { L"cmip-agent", 164 }, { L"cmip-man", 163 }, { L"cmmdriver", 1294 },
+ { L"cmtp-av", 8501 }, { L"cmtp-mgt", 8501 }, { L"cnap", 7262 }, { L"cnckadserver", 7168 },
+ { L"cncp", 4785 }, { L"cnhrp", 1757 }, { L"cnrp", 2757 }, { L"cnrprotocol", 1096 },
+ { L"cns-srv-port", 2976 }, { L"coap", 5683 }, { L"coaps", 5684 }, { L"coauthor", 1529 },
+ { L"codaauth2", 370 }, { L"codasrv", 2432 }, { L"codasrv-se", 2433 }, { L"codemeter", 22350 },
+ { L"codemeter-cmwan", 22351 }, { L"codima-rtp", 2415 }, { L"cogitate", 3039 }, { L"cognex-dataman", 44444 },
+ { L"cognex-insight", 1069 }, { L"cognima", 3779 }, { L"cogsys-lm", 3377 }, { L"coherence", 7574 },
+ { L"coherence-disc", 7574 }, { L"collaber", 7689 }, { L"collaborator", 622 }, { L"colubris", 3490 },
+ { L"com-bardac-dw", 48556 }, { L"combox-web-acc", 2534 }, { L"comcam", 2108 }, { L"comcam-io", 3605 },
+ { L"commandport", 3416 }, { L"commerce", 542 }, { L"commlinx-avl", 1190 }, { L"commonspace", 1592 },
+ { L"commplex-link", 5001 }, { L"commplex-main", 5000 }, { L"commtact-http", 20002 }, { L"commtact-https", 20003 },
+ { L"community", 2459 }, { L"comotionback", 2262 }, { L"comotionmaster", 2261 }, { L"compaq-evm", 619 },
+ { L"compaq-https", 2381 }, { L"compaq-scp", 2766 }, { L"compaq-wcp", 2555 }, { L"composit-server", 2417 },
+ { L"compressnet", 2 }, { L"compressnet", 3 }, { L"compx-lockview", 4308 }, { L"comsat", 512 },
+ { L"comscm", 437 }, { L"con", 759 }, { L"conclave-cpp", 2491 }, { L"concomp1", 1802 },
+ { L"concurrent-lm", 1648 }, { L"condor", 9618 }, { L"conductor", 6970 }, { L"conductor-mpx", 6970 },
+ { L"conf", 2008 }, { L"conference", 531 }, { L"conferencetalk", 1713 }, { L"config-port", 3577 },
+ { L"confluent", 1484 }, { L"connect", 2137 }, { L"connect-client", 3441 }, { L"connect-server", 3442 },
+ { L"connected", 16384 }, { L"connection", 2607 }, { L"connendp", 693 }, { L"connlcli", 1358 },
+ { L"conspiracy", 4692 }, { L"consul-insight", 5992 }, { L"contamac-icm", 4846 }, { L"contclientms", 4665 },
+ { L"contentserver", 3365 }, { L"contentserver", 454 }, { L"continuus", 5412 }, { L"controlone-con", 7551 },
+ { L"coord-svr", 2565 }, { L"cops", 3288 }, { L"cops-tls", 3183 }, { L"copy", 8445 },
+ { L"copy-disc", 8445 }, { L"copycat", 9093 }, { L"corba-iiop", 683 }, { L"corba-iiop-ssl", 684 },
+ { L"corbaloc", 2809 }, { L"corel-vncadmin", 2654 }, { L"corelccam", 4300 }, { L"corelvideo", 1566 },
+ { L"corerjd", 284 }, { L"cosir", 10321 }, { L"cosmocall", 2324 }, { L"couchdb", 5984 },
+ { L"courier", 530 }, { L"covia", 64 }, { L"cp-cluster", 8116 }, { L"cp-spxdpy", 4378 },
+ { L"cp-spxrpts", 5079 }, { L"cp-spxsvr", 4377 }, { L"cpdi-pidas-cm", 3609 }, { L"cpdlc", 5911 },
+ { L"cplscrambler-al", 1088 }, { L"cplscrambler-in", 1087 }, { L"cplscrambler-lg", 1086 }, { L"cppdp", 4051 },
+ { L"cpq-tasksmart", 3201 }, { L"cpq-wbem", 2301 }, { L"cpqrpm-agent", 3256 }, { L"cpqrpm-server", 3257 },
+ { L"cps", 14250 }, { L"cpscomm", 5194 }, { L"cpsp", 17222 }, { L"cpudpencap", 2746 },
+ { L"cqg-netlan", 2823 }, { L"cqg-netlan-1", 2824 }, { L"cr-websystems", 2314 }, { L"creativepartnr", 3366 },
+ { L"creativepartnr", 455 }, { L"creativeserver", 3364 }, { L"creativeserver", 453 }, { L"cresco-control", 38002 },
+ { L"crescoctrl-disc", 38002 }, { L"crestron-cip", 41794 }, { L"crestron-cips", 41796 }, { L"crestron-ctp", 41795 },
+ { L"crestron-ctps", 41797 }, { L"crinis-hb", 3818 }, { L"crip", 6253 }, { L"crmsbits", 2422 },
+ { L"crs", 507 }, { L"cruise-config", 8378 }, { L"cruise-diags", 8379 }, { L"cruise-enum", 8376 },
+ { L"cruise-swroute", 8377 }, { L"cruise-update", 8380 }, { L"crusecontrol", 5231 }, { L"cryptoadmin", 624 },
+ { L"cs-auth-svr", 3113 }, { L"cs-live", 2129 }, { L"cs-remote-db", 3630 }, { L"cs-services", 3631 },
+ { L"csbphonemaster", 1724 }, { L"csc-proxy", 4187 }, { L"csccfirewall", 40843 }, { L"csccredir", 40842 },
+ { L"cscp", 40841 }, { L"csd-mgmt-port", 3071 }, { L"csd-monitor", 3072 }, { L"csdm", 1468 },
+ { L"csdm", 1472 }, { L"csdmbase", 1467 }, { L"csdmbase", 1471 }, { L"csedaemon", 5232 },
+ { L"csi-lfap", 3145 }, { L"csi-sgwp", 348 }, { L"cslg", 24754 }, { L"cslistener", 9000 },
+ { L"csms", 3399 }, { L"csms2", 3400 }, { L"csnet-ns", 105 }, { L"csnotify", 2955 },
+ { L"cso", 105 }, { L"csoauth", 7847 }, { L"csoft-plusclnt", 2699 }, { L"csoft-prev", 3271 },
+ { L"csoft1", 1837 }, { L"csoftragent", 3004 }, { L"cspclmulti", 2890 }, { L"cspmlockmgr", 1272 },
+ { L"cspmulti", 2807 }, { L"cspuni", 2806 }, { L"csregagent", 3022 }, { L"csrpc", 5063 },
+ { L"cssc", 5637 }, { L"cssp", 4078 }, { L"cst-port", 3742 }, { L"csvr", 3417 },
+ { L"csvr-proxy", 3190 }, { L"csvr-sslproxy", 3191 }, { L"ct2nmcs", 7023 }, { L"ctcd", 1851 },
+ { L"ctdb", 4379 }, { L"ctdhercules", 3773 }, { L"ctdp", 7022 }, { L"ctechlicensing", 9346 },
+ { L"ctf", 84 }, { L"cti-redwood", 2563 }, { L"ctiprogramload", 4452 }, { L"ctisystemmsg", 4451 },
+ { L"ctlptc", 2153 }, { L"ctp", 3772 }, { L"ctp-state", 4047 }, { L"ctsd", 5137 },
+ { L"ctt-broker", 1932 }, { L"ctx-bridge", 3127 }, { L"ctxlic", 7279 }, { L"ctxs-vpp", 4980 },
+ { L"cuelink", 5271 }, { L"cuelink-disc", 5271 }, { L"cuillamartin", 1356 }, { L"cumulus", 9287 },
+ { L"cumulus-admin", 8954 }, { L"cuseeme", 7648 }, { L"custix", 528 }, { L"cvc", 1495 },
+ { L"cvc-hostd", 442 }, { L"cvd", 8400 }, { L"cvmmon", 2300 }, { L"cvmon", 1686 },
+ { L"cvspserver", 2401 }, { L"cvsup", 5999 }, { L"cwmp", 7547 }, { L"cxtp", 5091 },
+ { L"cxws", 4673 }, { L"cyaserv", 2584 }, { L"cybercash", 551 }, { L"cyborg-systems", 9888 },
+ { L"cybro-a-bus", 8442 }, { L"cyc", 3645 }, { L"cycleserv", 763 }, { L"cycleserv2", 772 },
+ { L"cylink-c", 5420 }, { L"cymtec-port", 1898 }, { L"cypress", 2015 }, { L"cypress-stat", 2017 },
+ { L"cytel-lm", 3297 }, { L"d-cinema-csp", 4170 }, { L"d-cinema-rrp", 1173 }, { L"d-data", 4301 },
+ { L"d-data-control", 4302 }, { L"d-fence", 8555 }, { L"d-s-n", 8086 }, { L"d2000kernel", 3119 },
+ { L"d2000webserver", 3120 }, { L"d2dconfig", 9387 }, { L"d2ddatatrans", 9388 }, { L"d2k-datamover1", 2297 },
+ { L"d2k-datamover2", 2298 }, { L"d2k-tapestry1", 3393 }, { L"d2k-tapestry2", 3394 }, { L"d3winosfi", 3458 },
+ { L"daap", 3689 }, { L"dab-sti-c", 1076 }, { L"dai-shell", 45824 }, { L"daishi", 2870 },
+ { L"dali-port", 5777 }, { L"damewaremobgtwy", 6130 }, { L"dandv-tester", 3889 }, { L"danf-ak2", 1041 },
+ { L"daqstream", 7411 }, { L"darcorp-lm", 1679 }, { L"dashpas-port", 3498 }, { L"dasp", 439 },
+ { L"data-insurance", 2764 }, { L"data-port", 3578 }, { L"datacaptor", 1857 }, { L"datalens", 2229 },
+ { L"datascaler-ctl", 6625 }, { L"datascaler-db", 6624 }, { L"datasurfsrv", 461 }, { L"datasurfsrvsec", 462 },
+ { L"datex-asn", 355 }, { L"datusorb", 3282 }, { L"davsrc", 9800 }, { L"davsrcs", 9802 },
+ { L"dawn", 1908 }, { L"dayliteserver", 6113 }, { L"daylitetouch", 6117 }, { L"daytime", 13 },
+ { L"db-lsp", 17500 }, { L"db-lsp-disc", 17500 }, { L"dbabble", 8132 }, { L"dbase", 217 },
+ { L"dbbrowse", 47557 }, { L"dbcontrol-agent", 3938 }, { L"dbcontrol-oms", 1158 }, { L"dbdb", 6104 },
+ { L"dberegister", 1479 }, { L"dbisamserver1", 12005 }, { L"dbisamserver2", 12006 }, { L"dbm", 2345 },
+ { L"dbref", 2365 }, { L"dbreporter", 1379 }, { L"dbsa-lm", 1407 }, { L"dbstar", 1415 },
+ { L"dbsyncarbiter", 4953 }, { L"dc", 2001 }, { L"dca", 1456 }, { L"dcap", 22125 },
+ { L"dccm", 5679 }, { L"dccp-udp", 6511 }, { L"dcp", 93 }, { L"dcs", 1367 },
+ { L"dcs-config", 3988 }, { L"dcsl-backup", 11202 }, { L"dcsoftware", 3793 }, { L"dctp", 675 },
+ { L"dcutility", 1044 }, { L"dddp", 9131 }, { L"ddgn", 4167 }, { L"ddi-tcp-1", 8888 },
+ { L"ddi-tcp-2", 8889 }, { L"ddi-tcp-3", 8890 }, { L"ddi-tcp-4", 8891 }, { L"ddi-tcp-5", 8892 },
+ { L"ddi-tcp-6", 8893 }, { L"ddi-tcp-7", 8894 }, { L"ddi-udp-1", 8888 }, { L"ddi-udp-2", 8889 },
+ { L"ddi-udp-3", 8890 }, { L"ddi-udp-4", 8891 }, { L"ddi-udp-5", 8892 }, { L"ddi-udp-6", 8893 },
+ { L"ddi-udp-7", 8894 }, { L"ddm-dfm", 447 }, { L"ddm-rdb", 446 }, { L"ddm-ssl", 448 },
+ { L"ddns-v3", 2164 }, { L"ddrepl", 4126 }, { L"ddt", 1052 }, { L"de-cache-query", 1255 },
+ { L"de-noc", 1254 }, { L"de-server", 1256 }, { L"de-spot", 2753 }, { L"dec-dlm", 625 },
+ { L"dec-mbadmin", 1655 }, { L"dec-mbadmin-h", 1656 }, { L"dec-notes", 3333 }, { L"decap", 403 },
+ { L"decauth", 316 }, { L"decbsrv", 579 }, { L"decladebug", 410 }, { L"dectalk", 2007 },
+ { L"decvms-sysmgt", 441 }, { L"dei-icda", 618 }, { L"delibo", 2562 }, { L"dell-eql-asm", 7569 },
+ { L"dell-rm-port", 3668 }, { L"dellpwrappks", 1266 }, { L"dellwebadmin-1", 1278 }, { L"dellwebadmin-2", 1279 },
+ { L"delos-dms", 3714 }, { L"delta-mcp", 1324 }, { L"denali-server", 3444 }, { L"deos", 76 },
+ { L"deploymentmap", 4570 }, { L"derby-repli", 4851 }, { L"descent3", 2092 }, { L"deskshare", 1702 },
+ { L"desktop-dna", 2763 }, { L"deskview", 3298 }, { L"devbasic", 5426 }, { L"device", 801 },
+ { L"device2", 2030 }, { L"devshr-nts", 552 }, { L"dey-keyneg", 8750 }, { L"dey-sapi", 4330 },
+ { L"dfn", 1133 }, { L"dfoxserver", 2960 }, { L"dfserver", 21554 }, { L"dgi-serv", 33333 },
+ { L"dgpf-exchg", 6785 }, { L"dhanalakshmi", 34567 }, { L"dhcp-failover", 647 }, { L"dhcp-failover2", 847 },
+ { L"dhcpv6-client", 546 }, { L"dhcpv6-server", 547 }, { L"dhct-alerts", 4676 }, { L"dhct-status", 4675 },
+ { L"dhe", 3252 }, { L"di-ase", 3046 }, { L"di-drm", 2226 }, { L"di-msg", 2227 },
+ { L"di-traceware", 3041 }, { L"diagmond", 1508 }, { L"diagnose-proc", 6072 }, { L"dialog-port", 2098 },
+ { L"dialogic-elmd", 1945 }, { L"dialpad-voice1", 2860 }, { L"dialpad-voice2", 2861 }, { L"diameter", 3868 },
+ { L"diameters", 5868 }, { L"diamondport", 33331 }, { L"dic-aida", 1941 }, { L"dicom", 11112 },
+ { L"dicom-iscl", 2761 }, { L"dicom-tls", 2762 }, { L"dict", 2628 }, { L"dict-lookup", 2289 },
+ { L"dif-port", 2251 }, { L"digiman", 2362 }, { L"digital-notary", 1335 }, { L"digital-vrc", 466 },
+ { L"digivote", 3223 }, { L"direcpc-dll", 1844 }, { L"direcpc-si", 2464 }, { L"direcpc-video", 1825 },
+ { L"direct", 242 }, { L"directnet", 3447 }, { L"directplay", 2234 }, { L"directplay8", 6073 },
+ { L"directplaysrvr", 47624 }, { L"directv-catlg", 3337 }, { L"directv-soft", 3335 }, { L"directv-tick", 3336 },
+ { L"directv-web", 3334 }, { L"directvdata", 3287 }, { L"dirgis", 2496 }, { L"discard", 9 },
+ { L"disclose", 667 }, { L"discovery-port", 1925 }, { L"discp-client", 2601 }, { L"discp-server", 2602 },
+ { L"display", 7236 }, { L"dist-upgrade", 3624 }, { L"distcc", 3632 }, { L"distinct", 9999 },
+ { L"distinct32", 9998 }, { L"dixie", 96 }, { L"dj-ice", 5419 }, { L"dj-ilm", 3362 },
+ { L"dka", 1263 }, { L"dkmessenger", 1177 }, { L"dl-agent", 3876 }, { L"dlip", 7201 },
+ { L"dlms-cosem", 4059 }, { L"dlpx-sp", 8415 }, { L"dls", 197 }, { L"dls", 2047 },
+ { L"dls-mon", 198 }, { L"dls-monitor", 2048 }, { L"dlsrap", 1973 }, { L"dlsrpn", 2065 },
+ { L"dlswpn", 2067 }, { L"dmaf-caster", 3574 }, { L"dmaf-server", 3574 }, { L"dmdocbroker", 1489 },
+ { L"DMExpress", 32636 }, { L"dmidi", 1199 }, { L"dmod-workspace", 3199 }, { L"dmp", 5031 },
+ { L"dmt", 7683 }, { L"dn6-nlm-aud", 195 }, { L"dn6-smm-red", 196 }, { L"dna", 2287 },
+ { L"dna-cml", 436 }, { L"dnap", 1172 }, { L"dnc-port", 3448 }, { L"dnox", 4022 },
+ { L"dnp", 20000 }, { L"dnp-sec", 19999 }, { L"dns-llq", 5352 }, { L"dns2go", 1227 },
+ { L"dnsix", 90 }, { L"dnx", 3998 }, { L"doc-server", 7165 }, { L"doc1lm", 3161 },
+ { L"docent", 2151 }, { L"doceri-ctl", 7019 }, { L"doceri-view", 7019 }, { L"docker", 2375 },
+ { L"docker-s", 2376 }, { L"docstor", 1488 }, { L"documentum", 10002 }, { L"documentum_s", 10003 },
+ { L"dof-dps-mc-sec", 5567 }, { L"dof-eps", 3567 }, { L"dof-tunnel", 8567 }, { L"dof-tunnel-sec", 3568 },
+ { L"doglms", 6088 }, { L"doglms-notify", 6088 }, { L"doip-data", 13400 }, { L"doip-disc", 13400 },
+ { L"domain", 53 }, { L"domaintime", 9909 }, { L"domiq", 44544 }, { L"donnyworld", 1821 },
+ { L"doom", 666 }, { L"dossier", 1175 }, { L"down", 2022 }, { L"downtools", 5245 },
+ { L"downtools-disc", 5245 }, { L"dpap", 8770 }, { L"dpcp", 4099 }, { L"dpi-proxy", 1795 },
+ { L"dpkeyserv", 1780 }, { L"dpm", 5718 }, { L"dpm-acm", 6075 }, { L"dpm-agent", 5719 },
+ { L"dproxy", 1296 }, { L"dpserve", 7020 }, { L"dpserveadmin", 7021 }, { L"dpsi", 315 },
+ { L"dragonfly", 8913 }, { L"drip", 3949 }, { L"driveappserver", 1930 }, { L"drizzle", 4427 },
+ { L"drm-production", 7171 }, { L"drmsfsd", 4098 }, { L"drmsmc", 1878 }, { L"drp", 1974 },
+ { L"drwcs", 2193 }, { L"ds-admin", 4404 }, { L"ds-clnt", 4402 }, { L"ds-mail", 4405 },
+ { L"ds-slp", 4406 }, { L"ds-srv", 4400 }, { L"ds-srvr", 4401 }, { L"ds-user", 4403 },
+ { L"dsatp", 2111 }, { L"dsc", 3390 }, { L"dsdn", 1292 }, { L"dserver", 4309 },
+ { L"dsETOS", 378 }, { L"dsf", 555 }, { L"dsfgw", 438 }, { L"dslremote-mgmt", 2420 },
+ { L"dsm-scm-target", 9987 }, { L"dsmcc-ccp", 13822 }, { L"dsmcc-config", 13818 }, { L"dsmcc-download", 13821 },
+ { L"dsmcc-passthru", 13820 }, { L"dsmcc-session", 13819 }, { L"dsmeter-iatc", 4060 }, { L"dsmipv6", 4191 },
+ { L"dsom-server", 3053 }, { L"dsp", 33 }, { L"dsp3270", 246 }, { L"dssiapi", 1265 },
+ { L"dsx-agent", 3685 }, { L"dsx-monitor", 31685 }, { L"dt-mgmtsvc", 6325 }, { L"dt-vra", 6326 },
+ { L"dta-systems", 13929 }, { L"dtag-ste-sb", 352 }, { L"dtk", 365 }, { L"dtn-bundle", 4556 },
+ { L"dtn1", 2445 }, { L"dtp", 3663 }, { L"dtp-dia", 3489 }, { L"dtp-net", 8732 },
+ { L"dtpt", 5721 }, { L"dts", 2594 }, { L"dtserver-port", 4028 }, { L"dtspcd", 6112 },
+ { L"dtv-chan-req", 2253 }, { L"dvapps", 3831 }, { L"dvbservdsc", 3937 }, { L"dvcprov-port", 3776 },
+ { L"dvl-activemail", 1396 }, { L"dvr-esm", 2804 }, { L"dvt-data", 3247 }, { L"dvt-system", 3246 },
+ { L"dwf", 1450 }, { L"dwmsgserver", 3228 }, { L"dwnmshttp", 3227 }, { L"dwr", 644 },
+ { L"dx-instrument", 1325 }, { L"dxadmind", 1958 }, { L"dxmessagebase1", 2874 }, { L"dxmessagebase2", 2875 },
+ { L"dxspider", 8873 }, { L"dyn-site", 3932 }, { L"dyna-access", 3310 }, { L"dyna-lm", 3395 },
+ { L"dynamic3d", 2150 }, { L"dynamid", 9002 }, { L"dyniplookup", 3295 }, { L"dzdaemon", 3866 },
+ { L"dzoglserver", 3867 }, { L"e-builder", 4121 }, { L"e-design-net", 6702 }, { L"e-design-web", 6703 },
+ { L"e-dpnet", 2036 }, { L"e-mdu", 3727 }, { L"e-net", 3286 }, { L"e-woa", 3728 },
+ { L"e3consultants", 3157 }, { L"ea", 17729 }, { L"ea1", 1791 }, { L"eapsp", 2291 },
+ { L"easl", 3693 }, { L"easy-soft-mux", 2168 }, { L"easyengine", 22222 }, { L"eba", 45678 },
+ { L"ebinsite", 2651 }, { L"echo", 7 }, { L"echonet", 3610 }, { L"ecmp", 6160 },
+ { L"ecmp-data", 6160 }, { L"ecmport", 3524 }, { L"ecnp", 2858 }, { L"ecolor-imager", 3263 },
+ { L"ecomm", 3477 }, { L"ecovisiong6-1", 2896 }, { L"ecp", 3134 }, { L"ecsqdmn", 1882 },
+ { L"ecwcfg", 2263 }, { L"edb-server1", 1635 }, { L"edb-server2", 3711 }, { L"edbsrvr", 12010 },
+ { L"editbench", 1350 }, { L"edix", 3123 }, { L"edm-adm-notify", 3463 }, { L"edm-manager", 3460 },
+ { L"edm-mgr-cntrl", 3465 }, { L"edm-mgr-sync", 3464 }, { L"edm-stager", 3461 }, { L"edm-std-notify", 3462 },
+ { L"edtools", 1142 }, { L"eenet", 5234 }, { L"efb-aci", 6159 }, { L"efcp", 3671 },
+ { L"efi-lm", 3392 }, { L"efi-mg", 2224 }, { L"efidiningport", 2553 }, { L"eforward", 2181 },
+ { L"efr", 5618 }, { L"efs", 520 }, { L"eftp", 37601 }, { L"egptlm", 3328 },
+ { L"egs", 1926 }, { L"ehome-ms", 2228 }, { L"ehp-backup", 3638 }, { L"ehs", 4535 },
+ { L"ehs-ssl", 4536 }, { L"ehtp", 1295 }, { L"eicon-server", 1438 }, { L"eicon-slp", 1440 },
+ { L"eicon-x25", 1439 }, { L"eims-admin", 4199 }, { L"eis", 3982 }, { L"eisp", 3983 },
+ { L"eisport", 3525 }, { L"elad", 1893 }, { L"elan", 1378 }, { L"elanlm", 4346 },
+ { L"elatelink", 2124 }, { L"elcn", 7101 }, { L"elcsd", 704 }, { L"elektron-admin", 5398 },
+ { L"elfiq-repl", 1148 }, { L"eli", 2087 }, { L"elipse-rec", 6515 }, { L"ellpack", 2025 },
+ { L"elm-momentum", 1914 }, { L"elpro-tunnel", 4370 }, { L"els", 1315 }, { L"elvin-client", 2917 },
+ { L"elvin-server", 2916 }, { L"elxmgmt", 23333 }, { L"em7-secom", 7700 }, { L"ema-sent-lm", 2526 },
+ { L"emb-proj-cmd", 5116 }, { L"embl-ndt", 394 }, { L"embrace-dp-c", 3198 }, { L"embrace-dp-s", 3197 },
+ { L"emc-gateway", 1273 }, { L"emc-pp-mgmtsvc", 9083 }, { L"emc-vcas-tcp", 13218 }, { L"emc-vcas-udp", 13218 },
+ { L"emc-xsw-dcache", 11723 }, { L"emc-xsw-dconfig", 11623 }, { L"emcads", 3945 }, { L"emce", 2004 },
+ { L"emcrmirccd", 10004 }, { L"emcrmird", 10005 }, { L"emcsymapiport", 2707 }, { L"emfis-cntl", 141 },
+ { L"emfis-data", 140 }, { L"emgmsg", 6656 }, { L"emp-server1", 6321 }, { L"emp-server2", 6322 },
+ { L"emperion", 1282 }, { L"empire-empuma", 1691 }, { L"empowerid", 7080 }, { L"emprise-lls", 3585 },
+ { L"emprise-lsc", 3586 }, { L"ems", 4664 }, { L"emsd-port", 1928 }, { L"emwavemsg", 20480 },
+ { L"emwin", 2211 }, { L"encore", 1740 }, { L"encrypted-admin", 1138 }, { L"encrypted-llrp", 5085 },
+ { L"enfs", 5233 }, { L"enl", 1804 }, { L"enl-name", 1805 }, { L"enpc", 3289 },
+ { L"enpp", 2968 }, { L"enrp", 9901 }, { L"enrp-sctp", 9901 }, { L"enrp-sctp-tls", 9902 },
+ { L"ent-engine", 3665 }, { L"entexthigh", 12002 }, { L"entextlow", 12004 }, { L"entextmed", 12003 },
+ { L"entextnetwk", 12001 }, { L"entextxid", 12000 }, { L"entp", 1865 }, { L"entrust-aaas", 680 },
+ { L"entrust-aams", 681 }, { L"entrust-ash", 710 }, { L"entrust-kmsh", 709 }, { L"entrust-sps", 640 },
+ { L"entrusttime", 309 }, { L"eor-game", 8149 }, { L"eoss", 1210 }, { L"ep-nsp", 3621 },
+ { L"ep-pcp", 3620 }, { L"epc", 1267 }, { L"epicon", 2912 }, { L"epl-slp", 3819 },
+ { L"epmap", 135 }, { L"epmd", 4369 }, { L"epncdp2", 3259 }, { L"epnsdp", 2051 },
+ { L"eportcomm", 4666 }, { L"eportcommdata", 4669 }, { L"epp", 3044 }, { L"epp", 700 },
+ { L"eppc", 3031 }, { L"ept-machine", 3628 }, { L"eq-office-4940", 4940 }, { L"eq-office-4941", 4941 },
+ { L"eq-office-4942", 4942 }, { L"eq3-config", 43439 }, { L"eq3-update", 43439 }, { L"equationbuilder", 1351 },
+ { L"ergolight", 2109 }, { L"eristwoguns", 2650 }, { L"erp-scale", 5135 }, { L"erpc", 121 },
+ { L"erunbook-agent", 9616 }, { L"erunbook-server", 9617 }, { L"es-elmd", 1822 }, { L"esbroker", 1342 },
+ { L"Escale (Newton Dock)", 3679 }, { L"escp-ip", 621 }, { L"escvpnet", 3629 }, { L"eserver-pap", 3666 },
+ { L"esimport", 3564 }, { L"esinstall", 5599 }, { L"esip", 2950 }, { L"esl-lm", 1455 },
+ { L"esmagent", 5601 }, { L"esmmanager", 5600 }, { L"esnm-zoning", 4023 }, { L"esp-encap", 2797 },
+ { L"esp-lm", 3383 }, { L"espeech", 8416 }, { L"espeech-rtp", 8417 }, { L"esps-portal", 2867 },
+ { L"esri-sde", 5151 }, { L"esro-emsdp", 642 }, { L"esro-gen", 259 }, { L"essbase", 1423 },
+ { L"essp", 2969 }, { L"essweb-gw", 1772 }, { L"estamp", 1982 }, { L"etb4j", 16309 },
+ { L"etc-control", 6107 }, { L"etcd-client", 2379 }, { L"etcd-server", 2380 }, { L"etebac5", 1216 },
+ { L"etftp", 1818 }, { L"ethercat", 34980 }, { L"EtherNet-IP-1", 2222 }, { L"EtherNet-IP-2", 44818 },
+ { L"ethoscan", 6935 }, { L"etlservicemgr", 9001 }, { L"etp", 1798 }, { L"ets", 1569 },
+ { L"eudora-set", 592 }, { L"ev-services", 5114 }, { L"evb-elm", 1504 }, { L"event-listener", 3017 },
+ { L"event-port", 2069 }, { L"everydayrc", 2782 }, { L"evm", 1139 }, { L"evtp", 2834 },
+ { L"evtp-data", 2835 }, { L"ew-disc-cmd", 43440 }, { L"ew-mgmt", 43440 }, { L"ewall", 1328 },
+ { L"ewcappsrv", 1876 }, { L"ewctsp", 6066 }, { L"ewdgs", 4092 }, { L"ewinstaller", 4091 },
+ { L"ewnn", 2674 }, { L"exapt-lmgr", 3759 }, { L"exasoftport1", 3920 }, { L"exbit-escp", 1316 },
+ { L"exce", 2769 }, { L"excerpt", 5400 }, { L"excerpts", 5401 }, { L"excw", 1271 },
+ { L"exec", 512 }, { L"exlm-agent", 3002 }, { L"exoconfig", 26487 }, { L"exoline-tcp", 26486 },
+ { L"exoline-udp", 26486 }, { L"exonet", 26489 }, { L"exp1", 1021 }, { L"exp2", 1022 },
+ { L"expresspay", 2755 }, { L"extensis", 2666 }, { L"eye2eye", 1948 }, { L"eyelink", 589 },
+ { L"eyetv", 2170 }, { L"ezmeeting", 26261 }, { L"ezmeeting-2", 10101 }, { L"ezmessagesrv", 4085 },
+ { L"ezproxy", 26260 }, { L"ezproxy-2", 10102 }, { L"ezrelay", 10103 }, { L"f5-globalsite", 2792 },
+ { L"f5-iquery", 4353 }, { L"fac-restore", 5582 }, { L"facelink", 1915 }, { L"facilityview", 1561 },
+ { L"facsys-ntp", 2514 }, { L"facsys-router", 2515 }, { L"fagordnc", 3873 }, { L"fairview", 38202 },
+ { L"famdc", 10081 }, { L"farenet", 5557 }, { L"fast-rem-serv", 2495 }, { L"fastlynx", 2689 },
+ { L"fatpipe", 3353 }, { L"fatserv", 347 }, { L"faxcomservice", 6417 }, { L"faximum", 7437 },
+ { L"faxportwinport", 1620 }, { L"faxstfx-port", 3684 }, { L"fazzt-admin", 4039 }, { L"fazzt-ptp", 4038 },
+ { L"fc-cli", 1371 }, { L"fc-faultnotify", 2819 }, { L"fc-ser", 1372 }, { L"fcip-port", 3225 },
+ { L"fcis", 4727 }, { L"fcis-disc", 4727 }, { L"fcmsys", 2344 }, { L"fcopy-server", 5745 },
+ { L"fcopys-server", 5746 }, { L"fcp", 510 }, { L"fcp-addr-srvr1", 5500 }, { L"fcp-addr-srvr2", 5501 },
+ { L"fcp-cics-gw1", 5504 }, { L"fcp-srvr-inst1", 5502 }, { L"fcp-srvr-inst2", 5503 }, { L"fcp-udp", 810 },
+ { L"fdt-rcatp", 4320 }, { L"fdtracks", 5579 }, { L"febooti-aw", 36524 }, { L"feitianrockey", 3152 },
+ { L"femis", 1776 }, { L"ferrari-foam", 3216 }, { L"ff-annunc", 1089 }, { L"ff-fms", 1090 },
+ { L"ff-lr-port", 3622 }, { L"ff-sm", 1091 }, { L"ffserver", 3825 }, { L"fg-fps", 3293 },
+ { L"fg-gip", 3294 }, { L"fg-sysupdate", 6550 }, { L"fhc", 1499 }, { L"fhsp", 1807 },
+ { L"fibotrader-com", 6715 }, { L"filecast", 3401 }, { L"filemq", 5670 }, { L"filenet-cm", 32773 },
+ { L"filenet-nch", 32770 }, { L"filenet-obrok", 32777 }, { L"filenet-pa", 32772 }, { L"filenet-pch", 32775 },
+ { L"filenet-peior", 32776 }, { L"filenet-powsrm", 32767 }, { L"filenet-re", 32774 }, { L"filenet-rmi", 32771 },
+ { L"filenet-rpc", 32769 }, { L"filenet-tms", 32768 }, { L"filesphere", 24242 }, { L"filex-lport", 1887 },
+ { L"find", 24922 }, { L"findviatv", 3350 }, { L"finger", 79 }, { L"finisar", 4682 },
+ { L"finle-lm", 1784 }, { L"fintrx", 3787 }, { L"fio-cmgmt", 9051 }, { L"fiorano-msgsvc", 1856 },
+ { L"fiorano-rtrsvc", 1855 }, { L"firefox", 1689 }, { L"firemonrcc", 3192 }, { L"firepower", 2615 },
+ { L"first-defense", 1232 }, { L"firstcall42", 2673 }, { L"fis", 5912 }, { L"fisa-svc", 7018 },
+ { L"fiveacross", 1193 }, { L"fj-hdnet", 1717 }, { L"fjappmgrbulk", 2510 }, { L"fjcp", 3648 },
+ { L"fjdmimgr", 9374 }, { L"fjdocdist", 1848 }, { L"fjhpjp", 3067 }, { L"fjicl-tep-a", 1901 },
+ { L"fjicl-tep-b", 1902 }, { L"fjicl-tep-c", 1904 }, { L"fjinvmgr", 9396 }, { L"fjippol-cnsl", 2749 },
+ { L"fjippol-polsvr", 2748 }, { L"fjippol-port1", 2750 }, { L"fjippol-port2", 2751 }, { L"fjippol-swrly", 2747 },
+ { L"fjitsuappmgr", 2425 }, { L"fjmpcm", 2975 }, { L"fjmpjps", 1873 }, { L"fjmpss", 2509 },
+ { L"fjsv-gssagt", 3035 }, { L"fjsvmpor", 2946 }, { L"fjswapsnp", 1874 }, { L"fksp-audit", 3729 },
+ { L"flamenco-proxy", 3210 }, { L"flashfiler", 24677 }, { L"flashmsg", 2884 }, { L"flcrs", 5638 },
+ { L"flex-lm", 27000 }, { L"flex-lm", 27001 }, { L"flex-lm", 27002 }, { L"flex-lm", 27003 },
+ { L"flex-lm", 27004 }, { L"flex-lm", 27005 }, { L"flex-lm", 27006 }, { L"flex-lm", 27007 },
+ { L"flex-lm", 27008 }, { L"flex-lm", 27009 }, { L"flexlm", 744 }, { L"flirtmitmir", 3840 },
+ { L"fln-spx", 221 }, { L"florence", 1228 }, { L"flr-agent", 4901 }, { L"flukeserver", 2359 },
+ { L"fly", 4396 }, { L"fmp", 4745 }, { L"fmpro-fdal", 2399 }, { L"fmpro-internal", 5003 },
+ { L"fmpro-v6", 5013 }, { L"fmsas", 16000 }, { L"fmsascon", 16001 }, { L"fmtp", 8500 },
+ { L"fmwp", 5015 }, { L"fnet-remote-ui", 1174 }, { L"fodms", 7200 }, { L"foliocorp", 2242 },
+ { L"font-service", 7100 }, { L"foresyte-clear", 5407 }, { L"foresyte-sec", 5408 }, { L"fortisphere-vm", 4084 },
+ { L"fotogcad", 3878 }, { L"found", 4411 }, { L"fpitp", 1045 }, { L"fpo-fns", 1066 },
+ { L"fprams", 4122 }, { L"frc-hp", 6704 }, { L"frc-lp", 6706 }, { L"frc-mp", 6705 },
+ { L"frcs", 4915 }, { L"freeciv", 5556 }, { L"freezexservice", 7726 }, { L"fronet", 4130 },
+ { L"fryeserv", 2788 }, { L"fs-agent", 8042 }, { L"fs-mgmt", 8044 }, { L"fs-qos", 41111 },
+ { L"fs-rh-srv", 3488 }, { L"fs-server", 8043 }, { L"fsc-port", 9217 }, { L"fse", 7394 },
+ { L"fsportmap", 4349 }, { L"fsr", 7164 }, { L"ft-role", 2429 }, { L"ftnmtp", 8502 },
+ { L"ftp", 21 }, { L"ftp-agent", 574 }, { L"ftp-data", 20 }, { L"ftps", 990 },
+ { L"ftps-data", 989 }, { L"ftranhc", 1105 }, { L"ftrapid-1", 1746 }, { L"ftrapid-2", 1747 },
+ { L"ftsrv", 1359 }, { L"ftsync", 4086 }, { L"fujitsu-dev", 747 }, { L"fujitsu-dtc", 1513 },
+ { L"fujitsu-dtcns", 1514 }, { L"fujitsu-mmpdc", 1657 }, { L"fujitsu-neat", 3382 }, { L"funk-dialout", 2909 },
+ { L"funk-license", 1787 }, { L"funk-logger", 1786 }, { L"funkproxy", 1505 }, { L"fuscript", 1144 },
+ { L"futrix", 2358 }, { L"fxaengine-net", 3402 }, { L"fxp", 2849 }, { L"fxp", 286 },
+ { L"fxuptp", 19539 }, { L"fyre-messanger", 2731 }, { L"g-talk", 2421 }, { L"g2tag", 4110 },
+ { L"g5m", 2732 }, { L"gacp", 190 }, { L"gadgetgate1way", 2677 }, { L"gadgetgate2way", 2678 },
+ { L"gadugadu", 8074 }, { L"gaia", 4340 }, { L"galaxy-network", 5235 }, { L"galaxy-server", 3051 },
+ { L"galaxy4d", 8881 }, { L"galaxy7-data", 38201 }, { L"galileo", 3519 }, { L"galileolog", 3520 },
+ { L"gamegen1", 1738 }, { L"gamelobby", 2914 }, { L"gamesmith-port", 31765 }, { L"gammafetchsvr", 1859 },
+ { L"gandalf-lm", 1421 }, { L"gap", 10800 }, { L"garcon", 999 }, { L"gat-lmd", 1708 },
+ { L"gbjd816", 2626 }, { L"gbmt-stars", 3912 }, { L"gbs-smp", 3762 }, { L"gbs-stp", 3484 },
+ { L"gc-config", 3436 }, { L"gcm-app", 14145 }, { L"gcmonitor", 2660 }, { L"gcsp", 3429 },
+ { L"gdbremote", 2159 }, { L"gdoi", 848 }, { L"gdomap", 538 }, { L"gdp-port", 1997 },
+ { L"gdrive-sync", 37483 }, { L"gds-adppiw-db", 4550 }, { L"gds-db", 3050 }, { L"gearman", 4730 },
+ { L"gemini-lm", 1590 }, { L"geneous", 3381 }, { L"generalsync", 7962 }, { L"geneve", 6081 },
+ { L"genie", 402 }, { L"genie-lm", 1453 }, { L"genisar-port", 3475 }, { L"geniuslm", 3005 },
+ { L"genrad-mux", 176 }, { L"genstat", 7283 }, { L"geognosis", 4326 }, { L"geognosisman", 4325 },
+ { L"geolocate", 3108 }, { L"gerhcs", 4985 }, { L"gf", 3530 }, { L"ggf-ncp", 678 },
+ { L"ggz", 5688 }, { L"ghvpn", 12009 }, { L"giga-pocket", 3862 }, { L"gilatskysurfer", 3013 },
+ { L"ginad", 634 }, { L"giop", 2481 }, { L"giop-ssl", 2482 }, { L"gist", 270 },
+ { L"git", 9418 }, { L"glbp", 3222 }, { L"gld", 6267 }, { L"glishd", 2833 },
+ { L"global-cd-port", 3229 }, { L"global-dtserv", 1774 }, { L"global-wlink", 1909 }, { L"globe", 2002 },
+ { L"globecast-id", 6109 }, { L"globmsgsvc", 2519 }, { L"glogger", 2033 }, { L"glrpc", 9080 },
+ { L"gmmp", 4183 }, { L"gmrupdateserv", 1070 }, { L"gntp", 23053 }, { L"gnunet", 2086 },
+ { L"gnutella-rtr", 6347 }, { L"gnutella-svc", 6346 }, { L"go-login", 491 }, { L"goahead-fldup", 3057 },
+ { L"gog-multiplayer", 5687 }, { L"goldleaf-licman", 1401 }, { L"golem", 9005 }, { L"gopher", 70 },
+ { L"gotodevice", 2217 }, { L"gpfs", 1191 }, { L"gppitnp", 103 }, { L"gprs-cube", 3751 },
+ { L"gprs-data", 3386 }, { L"gprs-sig", 3386 }, { L"gpsd", 2947 }, { L"gradecam", 5117 },
+ { L"graphics", 41 }, { L"grcmp", 9122 }, { L"grcp", 9123 }, { L"grf-port", 3757 },
+ { L"grid", 6268 }, { L"grid-alt", 6269 }, { L"gridgen-elmd", 1542 }, { L"griffin", 2458 },
+ { L"gris", 2135 }, { L"groove", 2492 }, { L"groove-dpp", 1211 }, { L"groupwise", 1677 },
+ { L"grubd", 3136 }, { L"gsakmp", 3761 }, { L"gsi", 1850 }, { L"gsidcap", 22128 },
+ { L"gsiftp", 2811 }, { L"gsigatekeeper", 2119 }, { L"gsmp-ancp", 6068 }, { L"gsms", 16002 },
+ { L"gsmtap", 4729 }, { L"gss-http", 488 }, { L"gss-xlicen", 128 }, { L"gt-proxy", 9889 },
+ { L"gtaua", 2186 }, { L"gte-samp", 2643 }, { L"gtegsc-lm", 1452 }, { L"gtp-control", 2123 },
+ { L"gtp-user", 2152 }, { L"gtrack-ne", 3592 }, { L"gtrack-server", 3591 }, { L"gue", 6080 },
+ { L"guibase", 9321 }, { L"guttersnex", 35356 }, { L"gv-pf", 18262 }, { L"gv-us", 1369 },
+ { L"gvcp", 3956 }, { L"gw", 3010 }, { L"gw-asv", 4842 }, { L"gw-call-port", 3745 },
+ { L"gw-log", 4844 }, { L"gwen-sonya", 2778 }, { L"gwha", 1383 }, { L"gxs-data-port", 2073 },
+ { L"gxtelmd", 2356 }, { L"h2250-annex-g", 2099 }, { L"h248-binary", 2945 }, { L"h263-video", 2979 },
+ { L"h2gf-w-2m", 3179 }, { L"h323callsigalt", 11720 }, { L"h323gatedisc", 1718 }, { L"h323gatestat", 1719 },
+ { L"h323hostcall", 1720 }, { L"h323hostcallsc", 1300 }, { L"ha-cluster", 694 }, { L"hacl-cfg", 5302 },
+ { L"hacl-gs", 5301 }, { L"hacl-hb", 5300 }, { L"hacl-local", 5304 }, { L"hacl-monitor", 3542 },
+ { L"hacl-poll", 5315 }, { L"hacl-probe", 5303 }, { L"hacl-qs", 1238 }, { L"hacl-test", 5305 },
+ { L"hagel-dump", 3036 }, { L"haipe-discover", 3623 }, { L"haipe-otnk", 3769 }, { L"hao", 2245 },
+ { L"hap", 661 }, { L"harp", 1816 }, { L"hart-ip", 5094 }, { L"hassle", 375 },
+ { L"hawk", 7630 }, { L"hb-engine", 1703 }, { L"hbci", 3000 }, { L"hcp-wismar", 686 },
+ { L"hdap", 263 }, { L"hde-lcesrvr-1", 14936 }, { L"hde-lcesrvr-2", 14937 }, { L"hdl-srv", 2641 },
+ { L"health-polling", 1161 }, { L"health-trap", 1162 }, { L"healthd", 1281 }, { L"heartbeat", 3740 },
+ { L"heathview", 35000 }, { L"hecmtl-db", 1551 }, { L"helix", 10860 }, { L"hello", 1789 },
+ { L"hello-port", 652 }, { L"hems", 151 }, { L"here-lm", 1409 }, { L"hermes", 1248 },
+ { L"herodotus-net", 3921 }, { L"hexarc", 7397 }, { L"hfcs", 4900 }, { L"hfcs-manager", 4999 },
+ { L"hhb-gateway", 1136 }, { L"hhb-handheld", 4148 }, { L"hicp", 3250 }, { L"hid", 24322 },
+ { L"high-criteria", 2467 }, { L"hillrserv", 4117 }, { L"hinp", 9954 }, { L"hip-nat-t", 10500 },
+ { L"hiperscan-id", 8293 }, { L"hippad", 2988 }, { L"hiq", 1410 }, { L"hislip", 4880 },
+ { L"hivep", 12172 }, { L"hivestor", 4884 }, { L"hkp", 11371 }, { L"hks-lm", 1722 },
+ { L"hl7", 2575 }, { L"hlibmgr", 3634 }, { L"hlserver", 3047 }, { L"hmmp-ind", 612 },
+ { L"hmmp-op", 613 }, { L"hnm", 6791 }, { L"hnmp", 6790 }, { L"homeportal-web", 3941 },
+ { L"homesteadglory", 2597 }, { L"honyaku", 2744 }, { L"hostname", 101 }, { L"hotu-chat", 3449 },
+ { L"houdini-lm", 1715 }, { L"houston", 4041 }, { L"hp-3000-telnet", 2564 }, { L"hp-alarm-mgr", 383 },
+ { L"hp-clic", 3384 }, { L"hp-collector", 381 }, { L"hp-dataprotect", 3612 }, { L"hp-device-disc", 3329 },
+ { L"hp-hcip", 1782 }, { L"hp-hcip-gwy", 1803 }, { L"hp-managed-node", 382 }, { L"hp-nnm-data", 2690 },
+ { L"hp-pdl-datastr", 9100 }, { L"hp-pxpib", 3101 }, { L"hp-rda", 2371 }, { L"hp-san-mgmt", 3037 },
+ { L"hp-sca", 19411 }, { L"hp-sci", 1299 }, { L"hp-sco", 19410 }, { L"hp-server", 5225 },
+ { L"hp-sessmon", 19412 }, { L"hp-status", 5226 }, { L"hp-webadmin", 1188 }, { L"hp-webqosdb", 1877 },
+ { L"hpbladems", 5316 }, { L"hpdevms", 5317 }, { L"hpidsadmin", 2984 }, { L"hpidsagent", 2985 },
+ { L"hpiod", 2208 }, { L"hpocbus", 2206 }, { L"hpoms-ci-lstn", 5403 }, { L"hpoms-dps-lstn", 5404 },
+ { L"hpppssvr", 2448 }, { L"hppronetman", 3908 }, { L"hpss-ndapi", 1217 }, { L"hpssd", 2207 },
+ { L"hpssmgmt", 4484 }, { L"hpstgmgr", 2600 }, { L"hpstgmgr2", 2715 }, { L"hpvirtctrl", 5224 },
+ { L"hpvirtgrp", 5223 }, { L"hpvmmagent", 1125 }, { L"hpvmmcontrol", 1124 }, { L"hpvmmdata", 1126 },
+ { L"hpvroom", 5228 }, { L"hrd-ncs", 6324 }, { L"hrd-ns-disc", 6324 }, { L"hri-port", 3439 },
+ { L"hrpd-ith-at-an", 4592 }, { L"hs-port", 2570 }, { L"hsl-storm", 2113 }, { L"hsrp", 1985 },
+ { L"hsrpv6", 2029 }, { L"htcp", 4827 }, { L"htrust", 5628 }, { L"http", 80 },
+ { L"http-alt", 591 }, { L"http-alt", 8008 }, { L"http-alt", 8080 }, { L"http-mgmt", 280 },
+ { L"http-rpc-epmap", 593 }, { L"http-wmap", 8990 }, { L"https", 443 }, { L"https-wmap", 8991 },
+ { L"httpx", 4180 }, { L"htuilsrv", 5023 }, { L"hub-open-net", 8313 }, { L"hughes-ap", 5105 },
+ { L"husky", 1310 }, { L"hybrid", 1424 }, { L"hybrid-pop", 473 }, { L"hydap", 15000 },
+ { L"hydra", 2374 }, { L"hylafax", 4559 }, { L"hyper-g", 418 }, { L"hypercube-lm", 1577 },
+ { L"hyperip", 3919 }, { L"hyperscsi-port", 5674 }, { L"hyperwave-isp", 692 }, { L"i-net-2000-npr", 5069 },
+ { L"i-zipqd", 13160 }, { L"i3-sessionmgr", 3952 }, { L"iadt", 4169 }, { L"iadt-disc", 4169 },
+ { L"iadt-tls", 9614 }, { L"iafdbase", 480 }, { L"iafserver", 479 }, { L"ianywhere-dbns", 3968 },
+ { L"iapp", 2313 }, { L"ias-admind", 2141 }, { L"ias-auth", 2139 }, { L"ias-neighbor", 4596 },
+ { L"ias-paging", 4595 }, { L"ias-reg", 2140 }, { L"ias-session", 4594 }, { L"iascontrol", 1157 },
+ { L"iascontrol-oms", 1156 }, { L"iasd", 432 }, { L"iatp-highpri", 6998 }, { L"iatp-normalpri", 6999 },
+ { L"iax", 4569 }, { L"ibar", 5784 }, { L"iberiagames", 1726 }, { L"ibm-abtact", 1586 },
+ { L"ibm-app", 385 }, { L"ibm-cics", 1435 }, { L"ibm-db2", 523 }, { L"ibm-dial-out", 3267 },
+ { L"ibm-diradm", 3538 }, { L"ibm-diradm-ssl", 3539 }, { L"ibm-dt-2", 1792 }, { L"ibm-mgr", 3801 },
+ { L"ibm-mqseries", 1414 }, { L"ibm-mqseries2", 1881 }, { L"ibm-pps", 1376 }, { L"ibm-res", 1405 },
+ { L"ibm-rsyscon", 9085 }, { L"ibm-ssd", 1260 }, { L"ibm-wrless-lan", 1461 }, { L"ibm3494", 3494 },
+ { L"ibp", 2572 }, { L"ibprotocol", 6714 }, { L"ibridge-data", 2275 }, { L"ibridge-mgmt", 2276 },
+ { L"ibus", 8733 }, { L"ica", 1494 }, { L"icabrowser", 1604 }, { L"icad-el", 425 },
+ { L"icap", 1344 }, { L"iccrushmore", 6850 }, { L"ice-location", 4061 }, { L"ice-router", 4063 },
+ { L"ice-slocation", 4062 }, { L"ice-srouter", 4064 }, { L"iceedcp-rx", 31949 }, { L"iceedcp-tx", 31948 },
+ { L"icg-bridge", 2063 }, { L"icg-iprelay", 2064 }, { L"icg-swp", 2062 }, { L"ici", 2200 },
+ { L"icl-twobase1", 25000 }, { L"icl-twobase10", 25009 }, { L"icl-twobase2", 25001 }, { L"icl-twobase3", 25002 },
+ { L"icl-twobase4", 25003 }, { L"icl-twobase5", 25004 }, { L"icl-twobase6", 25005 }, { L"icl-twobase7", 25006 },
+ { L"icl-twobase8", 25007 }, { L"icl-twobase9", 25008 }, { L"iclcnet-locate", 886 }, { L"iclcnet-svinfo", 887 },
+ { L"iclid", 18242 }, { L"iclpv-dm", 1389 }, { L"iclpv-nlc", 1394 }, { L"iclpv-nls", 1393 },
+ { L"iclpv-pm", 1392 }, { L"iclpv-sas", 1391 }, { L"iclpv-sc", 1390 }, { L"iclpv-wsm", 1395 },
+ { L"icmpd", 5813 }, { L"icms", 4486 }, { L"icon-discover", 2799 }, { L"iconp", 3972 },
+ { L"iconstructsrv", 6077 }, { L"icp", 1112 }, { L"icpp", 14142 }, { L"icpv2", 3130 },
+ { L"ics", 5639 }, { L"icshostsvc", 4553 }, { L"icslap", 2869 }, { L"ida-discover1", 5741 },
+ { L"ida-discover2", 5742 }, { L"idac", 3881 }, { L"idcp", 2326 }, { L"ideafarm-door", 902 },
+ { L"ideafarm-panic", 903 }, { L"ideesrv", 2337 }, { L"iden-ralp", 1725 }, { L"ident", 113 },
+ { L"identify", 2987 }, { L"idfp", 549 }, { L"idig-mux", 4152 }, { L"idmaps", 1884 },
+ { L"idmgratm", 32896 }, { L"idonix-metanet", 2112 }, { L"idotdist", 2590 }, { L"idp", 4067 },
+ { L"idp-infotrieve", 2966 }, { L"idps", 3797 }, { L"idrs", 2995 }, { L"idtp", 25604 },
+ { L"idware-router", 2079 }, { L"idxp", 603 }, { L"iec-104", 2404 }, { L"iec-104-sec", 19998 },
+ { L"iee-qfx", 1284 }, { L"ieee-mih", 4551 }, { L"ieee-mms", 651 }, { L"ieee-mms-ssl", 695 },
+ { L"ies-lm", 1443 }, { L"ifcp-port", 3420 }, { L"ife-icorp", 5165 }, { L"ifor-protocol", 1515 },
+ { L"ifsf-hb-port", 3486 }, { L"ifsp", 4744 }, { L"igcp", 2801 }, { L"igi-lm", 1404 },
+ { L"igmpv3lite", 465 }, { L"igo-incognito", 4100 }, { L"igrid", 19000 }, { L"igrs", 3880 },
+ { L"ii-admin", 3006 }, { L"iims", 4800 }, { L"iiop", 535 }, { L"iiw-port", 3186 },
+ { L"ild", 24321 }, { L"ill", 1611 }, { L"ilss", 4802 }, { L"imagepump", 27345 },
+ { L"imagequery", 2239 }, { L"imap", 143 }, { L"imap3", 220 }, { L"imaps", 993 },
+ { L"imdocsvc", 2637 }, { L"imgames", 1077 }, { L"imink", 8615 }, { L"imip", 11319 },
+ { L"imip-channels", 11320 }, { L"immedianet-bcn", 3657 }, { L"imoguia-port", 3907 }, { L"impera", 1710 },
+ { L"imprs", 3164 }, { L"imqbrokerd", 7676 }, { L"imqstomp", 7672 }, { L"imqstomps", 7673 },
+ { L"imqtunnel", 7675 }, { L"imqtunnels", 7674 }, { L"imsldoc", 2035 }, { L"imsp", 406 },
+ { L"imtc-map", 2202 }, { L"imtc-mcs", 1503 }, { L"imyx", 1143 }, { L"inbusiness", 244 },
+ { L"incognitorv", 3139 }, { L"incp", 2932 }, { L"index-net", 2970 }, { L"index-pc-wb", 2127 },
+ { L"indi", 7624 }, { L"indigo-server", 1176 }, { L"indigo-vbcp", 8131 }, { L"indigo-vrmi", 8130 },
+ { L"indura", 3156 }, { L"indx-dds", 2454 }, { L"indy", 5963 }, { L"infi-async", 8067 },
+ { L"infiniswitchcl", 3602 }, { L"influence", 3345 }, { L"infobright", 5029 }, { L"infocrypt", 2233 },
+ { L"infoexch", 3667 }, { L"infolibria", 2319 }, { L"infoman", 1451 }, { L"infomover", 2854 },
+ { L"informatik-lm", 1428 }, { L"informer", 3856 }, { L"infoseek", 414 }, { L"infotos", 18881 },
+ { L"infowave", 2082 }, { L"ingres-net", 134 }, { L"ingreslock", 1524 }, { L"ininmessaging", 5597 },
+ { L"iniserve-port", 3560 }, { L"initlsmsad", 2793 }, { L"innosys", 1412 }, { L"innosys-acl", 1413 },
+ { L"inova-ip-disco", 2716 }, { L"inovaport1", 23000 }, { L"inovaport2", 23001 }, { L"inovaport3", 23002 },
+ { L"inovaport4", 23003 }, { L"inovaport5", 23004 }, { L"inovaport6", 23005 }, { L"insis", 9215 },
+ { L"insitu-conf", 1490 }, { L"inspect", 1602 }, { L"inst-discovery", 4878 }, { L"instantia", 1240 },
+ { L"instl-bootc", 1068 }, { L"instl-boots", 1067 }, { L"int-rcv-cntrl", 3603 }, { L"intecom-ps1", 5056 },
+ { L"intecom-ps2", 5057 }, { L"intecourier", 495 }, { L"integra-sme", 484 }, { L"integral", 3459 },
+ { L"integrius-stp", 17234 }, { L"intel-rci", 24386 }, { L"intel-rci-mp", 16991 }, { L"intellistor-lm", 1539 },
+ { L"intelsync", 3692 }, { L"intel_rci", 24386 }, { L"interact", 4052 }, { L"interactionweb", 3508 },
+ { L"interbase", 2041 }, { L"interhdl-elmd", 1454 }, { L"interintelli", 2633 }, { L"intermapper", 8181 },
+ { L"interpathpanel", 2652 }, { L"intersan", 1331 }, { L"interserver", 3060 }, { L"intersys-cache", 1972 },
+ { L"interwise", 7778 }, { L"interworld", 3548 }, { L"intraintra", 3202 }, { L"intrastar", 1907 },
+ { L"intrepid-ssl", 11751 }, { L"intrinsa", 503 }, { L"intu-ec-client", 8021 }, { L"intu-ec-svcdisc", 8020 },
+ { L"intuitive-edge", 1355 }, { L"intv", 1585 }, { L"invision", 1641 }, { L"invision-ag", 45054 },
+ { L"invokator", 2006 }, { L"io-dist-data", 5728 }, { L"io-dist-group", 5728 }, { L"ioc-sea-lm", 1579 },
+ { L"ionixnetmon", 7410 }, { L"iop", 2055 }, { L"ip-blf", 2088 }, { L"ip-provision", 43190 },
+ { L"ip-qsig", 4029 }, { L"ipass", 2549 }, { L"ipcd", 576 }, { L"ipcd3", 1209 },
+ { L"ipcore", 2215 }, { L"ipcs-command", 3743 }, { L"ipcserver", 600 }, { L"ipdcesgbs", 9214 },
+ { L"ipdd", 578 }, { L"ipdr-sp", 4737 }, { L"ipdtp-port", 20202 }, { L"ipether232port", 3497 },
+ { L"ipfix", 4739 }, { L"ipfixs", 4740 }, { L"ipfltbcst", 4068 }, { L"iph-policy-adm", 2963 },
+ { L"iph-policy-cli", 2962 }, { L"iposplanet", 7031 }, { L"ipp", 631 }, { L"ipr-dglt", 3678 },
+ { L"ipsec-nat-t", 4500 }, { L"ipsendmsg", 1992 }, { L"ipt-anri-anri", 4593 }, { L"ipulse-ics", 20222 },
+ { L"ipx", 213 }, { L"iqnet-port", 3804 }, { L"iqobject", 48619 }, { L"iqrm", 10117 },
+ { L"iqserver", 2527 }, { L"ique", 18769 }, { L"iracinghelper", 32034 }, { L"iRAPP", 4073 },
+ { L"irc", 194 }, { L"irc-serv", 529 }, { L"ircs-u", 6697 }, { L"ircu", 6665 },
+ { L"ircu", 6666 }, { L"ircu", 6667 }, { L"ircu", 6668 }, { L"ircu", 6669 },
+ { L"irdg-post", 2632 }, { L"irdmi", 8000 }, { L"irdmi2", 7999 }, { L"iris-beep", 702 },
+ { L"iris-lwz", 715 }, { L"iris-xpc", 713 }, { L"iris-xpcs", 714 }, { L"irisa", 11000 },
+ { L"ironmail", 3206 }, { L"ironstorm", 3504 }, { L"irp", 4604 }, { L"irtrans", 21000 },
+ { L"is99c", 379 }, { L"is99s", 380 }, { L"isakmp", 500 }, { L"isbconference1", 1244 },
+ { L"isbconference2", 1245 }, { L"iscape", 5047 }, { L"ischat", 1336 }, { L"iscsi", 860 },
+ { L"iscsi-target", 3260 }, { L"isdc", 1636 }, { L"isdd", 8148 }, { L"isg-uda-server", 2551 },
+ { L"isi-gl", 55 }, { L"isi-irp", 3226 }, { L"isis", 2042 }, { L"isis-am", 1642 },
+ { L"isis-ambc", 1643 }, { L"isis-bcast", 2043 }, { L"islc", 1637 }, { L"ismaeasdaqlive", 1949 },
+ { L"ismaeasdaqtest", 1950 }, { L"ismc", 1638 }, { L"ismserver", 9500 }, { L"isnetserv", 48128 },
+ { L"isns", 3205 }, { L"iso-ill", 499 }, { L"iso-ip", 147 }, { L"iso-tp0", 146 },
+ { L"iso-tp0s", 3782 }, { L"iso-tsap", 102 }, { L"iso-tsap-c2", 399 }, { L"isode-dua", 17007 },
+ { L"isoft-p2p", 3501 }, { L"isoipsigport-1", 1106 }, { L"isoipsigport-2", 1107 }, { L"isomair", 3589 },
+ { L"ispipes", 2853 }, { L"ispmmgr", 3775 }, { L"isrp-port", 3788 }, { L"iss-mgmt-ssl", 3995 },
+ { L"issd", 1600 }, { L"isysg-lm", 1609 }, { L"ita-agent", 5051 }, { L"ita-manager", 5052 },
+ { L"itach", 8184 }, { L"itactionserver1", 7280 }, { L"itactionserver2", 7281 }, { L"italk", 12345 },
+ { L"itap-ddtp", 10100 }, { L"itelserverport", 3719 }, { L"item", 3848 }, { L"itinternet", 2691 },
+ { L"itm-lm", 2828 }, { L"itm-mccs", 3084 }, { L"itm-mcell-s", 828 }, { L"itm-mcell-u", 1828 },
+ { L"ito-e-gui", 2531 }, { L"itose", 4348 }, { L"itscomm-ns", 1573 }, { L"itu-bicc-stc", 3097 },
+ { L"itv-control", 3899 }, { L"itwo-server", 4410 }, { L"iua", 9900 }, { L"iuhsctpassoc", 29169 },
+ { L"ivcollector", 1275 }, { L"ivecon-port", 3258 }, { L"ivocalize", 5049 }, { L"ivs-database", 38000 },
+ { L"ivs-insertion", 38001 }, { L"ivs-video", 2232 }, { L"ivsd", 2241 }, { L"iw-mmogame", 3596 },
+ { L"iwb-whiteboard", 2982 }, { L"iwec", 4801 }, { L"iwg1", 7071 }, { L"iwlistener", 2866 },
+ { L"iwserver", 2166 }, { L"izm", 4109 }, { L"j-ac", 4107 }, { L"j-lan-p", 2808 },
+ { L"j-link", 19020 }, { L"jacobus-lm", 1578 }, { L"jaleosnd", 1623 }, { L"jamlink", 8091 },
+ { L"jamserverport", 3627 }, { L"janus-disc", 7181 }, { L"jargon", 148 }, { L"jaugsremotec-1", 3472 },
+ { L"jaugsremotec-2", 3473 }, { L"jaus", 3794 }, { L"jaxer-manager", 4328 }, { L"jaxer-web", 4327 },
+ { L"jaxflow", 5229 }, { L"jaxflow-data", 5230 }, { L"jboss-iiop", 3528 }, { L"jboss-iiop-ssl", 3529 },
+ { L"jbroker", 2506 }, { L"jcp", 19541 }, { L"jdatastore", 2508 }, { L"jdl-dbkitchen", 3086 },
+ { L"jdmn-port", 4030 }, { L"jdp-disc", 7095 }, { L"jediserver", 2406 }, { L"jeol-nsddp-1", 6241 },
+ { L"jeol-nsddp-2", 6242 }, { L"jeol-nsddp-3", 6243 }, { L"jeol-nsddp-4", 6244 }, { L"jeol-nsdtp-1", 6241 },
+ { L"jeol-nsdtp-2", 6242 }, { L"jeol-nsdtp-3", 6243 }, { L"jeol-nsdtp-4", 6244 }, { L"jerand-lm", 1810 },
+ { L"jesmsjc", 27442 }, { L"jetcmeserver", 1936 }, { L"jetform", 1706 }, { L"jetformpreview", 2097 },
+ { L"jetstream", 6901 }, { L"jibe-eb", 3777 }, { L"jini-discovery", 4160 }, { L"jlicelmd", 1567 },
+ { L"jmact3", 6961 }, { L"jmact5", 2957 }, { L"jmact6", 2958 }, { L"jmb-cds1", 8900 },
+ { L"jmb-cds2", 8901 }, { L"jmevt2", 6962 }, { L"jmq-daemon-1", 3214 }, { L"jmq-daemon-2", 3215 },
+ { L"jms", 5673 }, { L"joaJewelSuite", 6583 }, { L"joltid", 3531 }, { L"jomamqmonitor", 4114 },
+ { L"joost", 4166 }, { L"journee", 3042 }, { L"jpegmpeg", 3155 }, { L"jprinter", 5309 },
+ { L"jps", 2205 }, { L"jstel", 1064 }, { L"jt400", 3470 }, { L"jt400-ssl", 3471 },
+ { L"jtag-server", 1309 }, { L"jute", 5883 }, { L"juxml-port", 3642 }, { L"jvclient", 1940 },
+ { L"jvl-mactalk", 47100 }, { L"jvserver", 1939 }, { L"jwalkserver", 1289 }, { L"jwclient", 1938 },
+ { L"jwpc", 16020 }, { L"jwpc-bin", 16021 }, { L"jwserver", 1937 }, { L"k-block", 287 },
+ { L"k3software-cli", 26263 }, { L"k3software-svr", 26262 }, { L"ka0wuc", 2822 }, { L"kali", 2213 },
+ { L"kana", 2656 }, { L"kar2ouche", 4661 }, { L"kastenchasepad", 2918 }, { L"kastenxpipe", 36865 },
+ { L"kazaa", 1214 }, { L"kca-service", 9878 }, { L"kdm", 2115 }, { L"kdnet", 5364 },
+ { L"kentrox-prot", 2502 }, { L"kerberos", 88 }, { L"kerberos-adm", 749 }, { L"kerberos-iv", 750 },
+ { L"kermit", 1649 }, { L"keyserver", 584 }, { L"keyshadow", 19315 }, { L"keysrvr", 19283 },
+ { L"kfserver", 5343 }, { L"kftp", 6621 }, { L"kftp-data", 6620 }, { L"kfxaclicensing", 3581 },
+ { L"kingdomsonline", 30260 }, { L"kingfisher", 4058 }, { L"kink", 910 }, { L"kiosk", 1061 },
+ { L"kis", 186 }, { L"kitim", 35354 }, { L"kjtsiteserver", 1339 }, { L"klio", 7697 },
+ { L"klogin", 543 }, { L"kme-trap-port", 2081 }, { L"kmip", 5696 }, { L"kmscontrol", 1773 },
+ { L"knet-cmp", 157 }, { L"kofax-svr", 2424 }, { L"konshus-lm", 2294 }, { L"konspire2b", 6085 },
+ { L"kopek-httphead", 27504 }, { L"kpasswd", 464 }, { L"kpdp", 5253 }, { L"kpn-icw", 3699 },
+ { L"krb524", 4444 }, { L"krb5gatekeeper", 1318 }, { L"kryptolan", 398 }, { L"kshell", 544 },
+ { L"ksysguard", 3112 }, { L"ktelnet", 6623 }, { L"kti-icad-srvr", 6701 }, { L"ktickets-rest", 4331 },
+ { L"kv-agent", 3361 }, { L"kv-server", 3360 }, { L"kvm-via-ip", 1132 }, { L"kwdb-commn", 1127 },
+ { L"kwtc", 4566 }, { L"kyoceranetdev", 1063 }, { L"kz-migr", 8102 }, { L"l-acoustics", 4432 },
+ { L"l2c-control", 4371 }, { L"l2c-data", 4372 }, { L"l2c-disc", 4371 }, { L"l2f", 1701 },
+ { L"l2tp", 1701 }, { L"l3-exprt", 2840 }, { L"l3-hawk", 2842 }, { L"l3-hbmon", 2370 },
+ { L"l3-ranger", 2841 }, { L"l3t-at-an", 4591 }, { L"l5nas-parchan", 9747 }, { L"labrat", 2560 },
+ { L"laes-bf", 9536 }, { L"lam", 2040 }, { L"lan900-remote", 2395 }, { L"landmarks", 3969 },
+ { L"lanmessenger", 2372 }, { L"lanner-lm", 4547 }, { L"lanrevagent", 3970 }, { L"lanrevserver", 3971 },
+ { L"lanschool", 11796 }, { L"lanschool-mpt", 11796 }, { L"lanserver", 637 }, { L"lansource", 1485 },
+ { L"lansurveyor", 4347 }, { L"lansurveyorxml", 3815 }, { L"lanyon-lantern", 1682 }, { L"laplink", 1547 },
+ { L"launchbird-lm", 3739 }, { L"lavenir-lm", 3373 }, { L"lazy-ptop", 7099 }, { L"lbc-control", 2780 },
+ { L"lbc-measure", 2815 }, { L"lbc-sync", 2779 }, { L"lbc-watchdog", 2816 }, { L"lbf", 2466 },
+ { L"lbm", 2465 }, { L"lcm-server", 7365 }, { L"lcs-ap", 9082 }, { L"ldap", 389 },
+ { L"ldap-admin", 3407 }, { L"ldaps", 636 }, { L"ldgateway", 9592 }, { L"ldoms-mgmt", 6482 },
+ { L"ldoms-migr", 8101 }, { L"ldp", 646 }, { L"lds-distrib", 6543 }, { L"lds-dump", 6544 },
+ { L"ldss", 6087 }, { L"ldxp", 4042 }, { L"lecroy-vicp", 1861 }, { L"leecoposserver", 2212 },
+ { L"legent-1", 373 }, { L"legent-2", 374 }, { L"leoip", 1886 }, { L"lhtp", 1983 },
+ { L"liberty-lm", 1496 }, { L"licensedaemon", 1986 }, { L"LiebDevMgmt-A", 3029 }, { L"LiebDevMgmt-C", 3027 },
+ { L"LiebDevMgmt-DM", 3028 }, { L"light", 4670 }, { L"limnerpressure", 8191 }, { L"link", 245 },
+ { L"linkname", 1903 }, { L"linktest", 3746 }, { L"linktest-s", 3747 }, { L"linogridengine", 12300 },
+ { L"linx", 1361 }, { L"lionhead", 2611 }, { L"lipsinc", 1968 }, { L"lipsinc1", 1969 },
+ { L"lisp-cons", 4342 }, { L"lisp-control", 4342 }, { L"lisp-data", 4341 }, { L"lispworks-orb", 3672 },
+ { L"listcrt-port", 3913 }, { L"listcrt-port-2", 3914 }, { L"listmgr-port", 3767 }, { L"livelan", 1555 },
+ { L"livestats", 2795 }, { L"ljk-login", 472 }, { L"lkcmserver", 3278 }, { L"llm-csv", 2814 },
+ { L"llm-pass", 2813 }, { L"llmnr", 5355 }, { L"llrp", 5084 }, { L"llsurfup-http", 1183 },
+ { L"llsurfup-https", 1184 }, { L"lm-dta", 8206 }, { L"lm-instmgr", 8205 }, { L"lm-mon", 31620 },
+ { L"lm-perfworks", 8204 }, { L"lm-sserver", 8207 }, { L"lm-webwatcher", 8208 }, { L"lm-x", 6200 },
+ { L"lmcs", 4877 }, { L"lmdp", 2623 }, { L"lmp", 701 }, { L"lms", 4056 },
+ { L"lmsocialserver", 1111 }, { L"lnvalarm", 2282 }, { L"lnvconsole", 2281 }, { L"lnvmailmon", 2285 },
+ { L"lnvmaps", 2284 }, { L"lnvpoller", 2280 }, { L"lnvstatus", 2283 }, { L"loadav", 750 },
+ { L"loaprobe", 1634 }, { L"localinfosrvr", 1487 }, { L"lockstep", 2125 }, { L"locus-con", 127 },
+ { L"locus-disc", 5058 }, { L"locus-map", 125 }, { L"lofr-lm", 1752 }, { L"logcabin", 5254 },
+ { L"login", 513 }, { L"lonewolf-lm", 6146 }, { L"lontalk-norm", 1628 }, { L"lontalk-urgnt", 1629 },
+ { L"lonworks", 2540 }, { L"lonworks2", 2541 }, { L"lorica-in", 4080 }, { L"lorica-in-sec", 4081 },
+ { L"lorica-out", 4082 }, { L"lorica-out-sec", 4083 }, { L"lot105-ds-upd", 2053 }, { L"lotusmtap", 3007 },
+ { L"lotusnote", 1352 }, { L"lpar2rrd", 8162 }, { L"lpcp", 1298 }, { L"lpdg", 10805 },
+ { L"lpsrecommender", 2620 }, { L"lrp", 2090 }, { L"lrs-paging", 3700 }, { L"ls3", 3069 },
+ { L"ls3bcast", 3068 }, { L"lsdp", 11430 }, { L"lsi-bobcat", 5574 }, { L"lsi-raid-mgmt", 2463 },
+ { L"lsp-ping", 3503 }, { L"lstp", 2559 }, { L"ltctcp", 3487 }, { L"ltcudp", 3487 },
+ { L"ltp", 4044 }, { L"ltp-deepspace", 1113 }, { L"lumimgrd", 4741 }, { L"lupa", 1212 },
+ { L"lutap", 4912 }, { L"lutcp", 4913 }, { L"lv-auth", 2147 }, { L"lv-ffx", 2144 },
+ { L"lv-frontpanel", 3079 }, { L"lv-jc", 2143 }, { L"lv-not", 2146 }, { L"lv-pici", 2145 },
+ { L"lvision-lm", 6471 }, { L"lxi-evntsvc", 5044 }, { L"lyskom", 4894 }, { L"m-wnn", 3732 },
+ { L"m2ap", 36443 }, { L"m2mservices", 8383 }, { L"m2pa", 3565 }, { L"m2ua", 2904 },
+ { L"m3ap", 36444 }, { L"m3da", 44900 }, { L"m3da-disc", 44900 }, { L"m3ua", 2905 },
+ { L"m4-network-as", 4345 }, { L"mac-srvr-admin", 660 }, { L"macbak", 4181 }, { L"macon-tcp", 456 },
+ { L"macon-udp", 456 }, { L"macromedia-fcs", 1935 }, { L"madcap", 2535 }, { L"madge-ltd", 2453 },
+ { L"magaya-network", 3691 }, { L"magbind", 3194 }, { L"magenta-logic", 313 }, { L"magiccontrol", 4902 },
+ { L"magicnotes", 3023 }, { L"magicom", 2243 }, { L"magpie", 5092 }, { L"mailbox", 2004 },
+ { L"mailbox-lm", 505 }, { L"mailprox", 3936 }, { L"mailq", 174 }, { L"maincontrol", 2516 },
+ { L"mainsoft-lm", 1593 }, { L"maitrd", 997 }, { L"manage-exec", 2342 }, { L"manet", 269 },
+ { L"manyone-http", 8910 }, { L"manyone-xml", 8911 }, { L"mao", 2908 }, { L"mapper-mapethd", 3985 },
+ { L"mapper-nodemgr", 3984 }, { L"mapper-ws-ethd", 3986 }, { L"mapx", 36700 }, { L"marcam-lm", 1444 },
+ { L"markem-dcp", 3836 }, { L"martalk", 7073 }, { L"masc", 2587 }, { L"masqdialer", 224 },
+ { L"matahari", 49000 }, { L"matip-type-a", 350 }, { L"matip-type-b", 351 }, { L"matrix-vnet", 4360 },
+ { L"max", 6074 }, { L"maxim-asics", 3276 }, { L"MaxumSP", 4179 }, { L"maytagshuffle", 2591 },
+ { L"mbap", 502 }, { L"mbap-s", 802 }, { L"mbg-ctrl", 3569 }, { L"mbl-battd", 4153 },
+ { L"mbus", 47000 }, { L"mc-appserver", 8763 }, { L"mc-brk-srv", 3180 }, { L"mc-client", 1180 },
+ { L"mc-comm", 9632 }, { L"mc-gt-srv", 2180 }, { L"mc2studios", 1899 }, { L"mc3ss", 3521 },
+ { L"mcagent", 1820 }, { L"mccwebsvr-port", 3570 }, { L"mcer-port", 6510 }, { L"mcftp", 6622 },
+ { L"mcidas", 112 }, { L"mck-ivpip", 2698 }, { L"mcns-sec", 638 }, { L"mcns-tel-ret", 3311 },
+ { L"mcntp", 5418 }, { L"mcp", 4458 }, { L"mcp-port", 3558 }, { L"mcreport", 8003 },
+ { L"mcs-calypsoicf", 3330 }, { L"mcs-fastmail", 3302 }, { L"mcs-mailsvr", 3332 }, { L"mcs-messaging", 3331 },
+ { L"mctet-gateway", 3116 }, { L"mctet-jserv", 3117 }, { L"mctet-master", 3115 }, { L"mctfeed", 5598 },
+ { L"mctp", 1100 }, { L"md-cg-http", 2688 }, { L"mdap-port", 3235 }, { L"mdbs-daemon", 800 },
+ { L"mdc-portmapper", 685 }, { L"mdm", 7871 }, { L"mdns", 5353 }, { L"mdnsresponder", 5354 },
+ { L"mdqs", 666 }, { L"mdtp", 3232 }, { L"mecomm", 668 }, { L"med-ci", 24005 },
+ { L"med-fsp-rx", 24001 }, { L"med-fsp-tx", 24002 }, { L"med-ltp", 24000 }, { L"med-net-svc", 24006 },
+ { L"med-ovw", 24004 }, { L"med-supp", 24003 }, { L"medevolve", 13930 }, { L"media-agent", 2789 },
+ { L"mediabox", 46999 }, { L"mediacntrlnfsd", 2363 }, { L"mediaspace", 3594 }, { L"mediat", 5157 },
+ { L"mediavault-gui", 3673 }, { L"medimageportal", 7720 }, { L"megaco-h248", 2944 }, { L"megardsvr-port", 3571 },
+ { L"megaregsvrport", 3572 }, { L"memcache", 11211 }, { L"menandmice-dns", 1337 }, { L"menandmice-lpm", 1231 },
+ { L"menandmice-mon", 4552 }, { L"menandmice-noh", 4151 }, { L"menandmice-upg", 4603 }, { L"mentaclient", 2117 },
+ { L"mentaserver", 2118 }, { L"mercantile", 3398 }, { L"mercury-disc", 9596 }, { L"meregister", 669 },
+ { L"mesavistaco", 1249 }, { L"messageasap", 6070 }, { L"messageservice", 2311 }, { L"meta-corp", 6141 },
+ { L"meta5", 393 }, { L"metaagent", 1897 }, { L"metaconsole", 2850 }, { L"metaedit-mu", 6360 },
+ { L"metaedit-se", 6370 }, { L"metaedit-ws", 6390 }, { L"metagram", 99 }, { L"metalbend", 7172 },
+ { L"metasage", 1207 }, { L"metastorm", 2511 }, { L"metasys", 11001 }, { L"metatude-mds", 6382 },
+ { L"meter", 570 }, { L"meter", 571 }, { L"metricadbc", 2622 }, { L"metrics-pas", 1824 },
+ { L"mevent", 7900 }, { L"mfcobol", 86 }, { L"mfserver", 2266 }, { L"mftp", 349 },
+ { L"mftp", 5402 }, { L"mgcp-callagent", 2727 }, { L"mgcp-gateway", 2427 }, { L"mgcs-mfp-port", 6509 },
+ { L"mgemanagement", 4680 }, { L"mgesupervision", 4679 }, { L"mgxswitch", 3070 }, { L"miami-bcast", 6083 },
+ { L"mib-streaming", 2292 }, { L"mice", 5022 }, { L"micom-pfs", 490 }, { L"microcom-sbp", 1680 },
+ { L"micromuse-lm", 1534 }, { L"micromuse-ncps", 7979 }, { L"micromuse-ncpw", 9600 }, { L"microsan", 20001 },
+ { L"microsoft-ds", 445 }, { L"microtalon-com", 7014 }, { L"microtalon-dis", 7013 }, { L"midnight-tech", 3008 },
+ { L"mikey", 2269 }, { L"mil-2045-47001", 1581 }, { L"miles-apart", 2621 }, { L"mimer", 1360 },
+ { L"mindarray-ca", 9445 }, { L"mindfilesys", 7391 }, { L"mindprint", 8033 }, { L"minger", 4069 },
+ { L"mini-sql", 1114 }, { L"minilock", 3798 }, { L"minipay", 2105 }, { L"minivend", 7786 },
+ { L"minotaur-sa", 5136 }, { L"mipv6tls", 7872 }, { L"mira", 3454 }, { L"miroconnect", 1532 },
+ { L"mirrtex", 4310 }, { L"mit-dov", 91 }, { L"mit-ml-dev", 83 }, { L"mit-ml-dev", 85 },
+ { L"miteksys-lm", 1482 }, { L"miva-mqs", 1277 }, { L"mkm-discovery", 3837 }, { L"ml-svnet", 4171 },
+ { L"mle", 19788 }, { L"mloadd", 1427 }, { L"mlsn", 32801 }, { L"mma-discovery", 4173 },
+ { L"mmacomm", 4667 }, { L"mmaeds", 4668 }, { L"mmcal", 2272 }, { L"mmcals", 2271 },
+ { L"mmcc", 5050 }, { L"mmpft", 1815 }, { L"mnet-discovery", 5237 }, { L"mngsuite", 9535 },
+ { L"mni-prot-rout", 3764 }, { L"mnp-exchange", 2197 }, { L"mns-mail", 2593 }, { L"mobile-file-dl", 2926 },
+ { L"mobile-p2p", 4688 }, { L"mobileanalyzer", 7869 }, { L"mobileip-agent", 434 }, { L"mobilip-mn", 435 },
+ { L"MobilitySrv", 6997 }, { L"mobrien-chat", 2031 }, { L"moldflow-lm", 1576 }, { L"molly", 1374 },
+ { L"mon", 2583 }, { L"mon", 9255 }, { L"mondex", 471 }, { L"monetra", 8665 },
+ { L"monetra-admin", 8666 }, { L"monitor", 561 }, { L"monkeycom", 9898 }, { L"monp", 3445 },
+ { L"montage-lm", 6147 }, { L"mortgageware", 367 }, { L"MOS-aux", 10542 }, { L"MOS-lower", 10540 },
+ { L"MOS-soap", 10543 }, { L"MOS-soap-opt", 10544 }, { L"MOS-upper", 10541 }, { L"mosaicsyssvc1", 1235 },
+ { L"mosaixcc", 2561 }, { L"moshebeeri", 2627 }, { L"mountd", 20048 }, { L"movaz-ssc", 5252 },
+ { L"moy-corp", 2488 }, { L"mpc-lifenet", 1213 }, { L"mpfoncl", 2579 }, { L"mpfwsas", 2952 },
+ { L"mphlpdmc", 9344 }, { L"mpidcagt", 9397 }, { L"mpidcmgr", 9343 }, { L"mpl-gprs-port", 3924 },
+ { L"mpls-pm", 6634 }, { L"mpls-udp", 6635 }, { L"mpls-udp-dtls", 6636 }, { L"mpm", 45 },
+ { L"mpm-flags", 44 }, { L"mpm-snd", 46 }, { L"mpnjsc", 1952 }, { L"mpnjsocl", 2685 },
+ { L"mpnjsomb", 2681 }, { L"mpnjsomg", 2686 }, { L"mpnjsosv", 2684 }, { L"mpp", 218 },
+ { L"mppolicy-mgr", 5969 }, { L"mppolicy-v5", 5968 }, { L"mps-raft", 1700 }, { L"mpshrsv", 1261 },
+ { L"mpsserver", 6106 }, { L"mpsysrmsvr", 3358 }, { L"mptn", 397 }, { L"mqe-agent", 3958 },
+ { L"mqe-broker", 3957 }, { L"mqtt", 1883 }, { L"mrip", 4986 }, { L"mrm", 679 },
+ { L"mrssrendezvous", 7392 }, { L"ms-alerter", 5359 }, { L"ms-cluster-net", 3343 }, { L"ms-ilm", 5725 },
+ { L"ms-ilm-sts", 5726 }, { L"ms-la", 3535 }, { L"ms-licensing", 5720 }, { L"ms-olap1", 2393 },
+ { L"ms-olap2", 2394 }, { L"ms-olap3", 2382 }, { L"ms-olap4", 2383 }, { L"ms-rome", 569 },
+ { L"ms-rule-engine", 3132 }, { L"ms-s-sideshow", 5361 }, { L"ms-shuttle", 568 }, { L"ms-sideshow", 5360 },
+ { L"ms-smlbiz", 5356 }, { L"ms-sna-base", 1478 }, { L"ms-sna-server", 1477 }, { L"ms-sql-m", 1434 },
+ { L"ms-sql-s", 1433 }, { L"ms-streaming", 1755 }, { L"ms-theater", 2460 }, { L"ms-v-worlds", 2525 },
+ { L"ms-wbt-server", 3389 }, { L"msdfsr", 5722 }, { L"msdp", 639 }, { L"msdts1", 3882 },
+ { L"msexch-routing", 691 }, { L"msfrs", 4554 }, { L"msft-dpm-cert", 6076 }, { L"msft-gc", 3268 },
+ { L"msft-gc-ssl", 3269 }, { L"msfw-array", 2174 }, { L"msfw-control", 3847 }, { L"msfw-replica", 2173 },
+ { L"msfw-s-storage", 2172 }, { L"msfw-storage", 2171 }, { L"msg-auth", 31 }, { L"msg-icp", 29 },
+ { L"msgclnt", 8786 }, { L"msgsrvr", 8787 }, { L"msgsys", 9594 }, { L"mshnet", 1989 },
+ { L"mshvlm", 6600 }, { L"msi-cps-rm", 8675 }, { L"msi-cps-rm-disc", 8675 }, { L"msi-selectplay", 2871 },
+ { L"msiccp", 1731 }, { L"msims", 1582 }, { L"msl-lmd", 1464 }, { L"msmq", 1801 },
+ { L"msnp", 1863 }, { L"msolap-ptp2", 2725 }, { L"msp", 18 }, { L"msp", 2438 },
+ { L"msp-os", 4686 }, { L"msr-plugin-port", 3931 }, { L"msrp", 2855 }, { L"msss", 7742 },
+ { L"mstmg-sstp", 6601 }, { L"msync", 2072 }, { L"mt-scaleserver", 2305 }, { L"mtcevrunqman", 4558 },
+ { L"mtcevrunqss", 4557 }, { L"mti-tcs-comm", 2469 }, { L"mtl8000-matrix", 8115 }, { L"mtn", 4691 },
+ { L"mtp", 1911 }, { L"mtport-regist", 2791 }, { L"mtportmon", 7421 }, { L"mtqp", 1038 },
+ { L"mtrgtrans", 19398 }, { L"mtsserver", 4602 }, { L"multicast-ping", 9903 }, { L"multiling-http", 777 },
+ { L"multip-msg", 3733 }, { L"multiplex", 171 }, { L"mumps", 188 }, { L"munin", 4949 },
+ { L"mupdate", 3905 }, { L"murray", 1123 }, { L"murx", 2743 }, { L"muse", 6888 },
+ { L"musiconline", 1806 }, { L"must-backplane", 3515 }, { L"must-p2p", 3514 }, { L"mvel-lm", 1574 },
+ { L"mvs-capacity", 10007 }, { L"mvx-lm", 1510 }, { L"mxi", 8005 }, { L"mxit", 9119 },
+ { L"mxodbc-connect", 6632 }, { L"mxomss", 1141 }, { L"mxxrlogin", 1035 }, { L"myblast", 3795 },
+ { L"mylex-mapd", 467 }, { L"mylxamport", 2981 }, { L"mynahautostart", 2388 }, { L"myq-termlink", 11108 },
+ { L"myrtle", 1831 }, { L"mysql", 3306 }, { L"mysql-cluster", 1186 }, { L"mysql-cm-agent", 1862 },
+ { L"mysql-im", 2273 }, { L"mysql-proxy", 6446 }, { L"mzap", 2106 }, { L"mzca-action", 7282 },
+ { L"mzca-alert", 7282 }, { L"n1-fwp", 4446 }, { L"n1-rmgmt", 4447 }, { L"n2h2server", 9285 },
+ { L"n2nremote", 1685 }, { L"n2receive", 9286 }, { L"na-er-tip", 3725 }, { L"na-localise", 5062 },
+ { L"naap", 1340 }, { L"nacagent", 4407 }, { L"nacnl", 4361 }, { L"name", 42 },
+ { L"namemunge", 3950 }, { L"nameserver", 42 }, { L"namp", 167 }, { L"nani", 2236 },
+ { L"nas", 991 }, { L"nas-metering", 2286 }, { L"nasmanager", 1960 }, { L"natdataservice", 3927 },
+ { L"nati-dstp", 3015 }, { L"nati-logos", 2343 }, { L"nati-svrloc", 3580 }, { L"nati-vi-server", 3363 },
+ { L"nattyserver", 3753 }, { L"natuslink", 2895 }, { L"nav-data", 6317 }, { L"nav-data-cmd", 6317 },
+ { L"nav-port", 3859 }, { L"navbuddy", 1288 }, { L"navegaweb-port", 3159 }, { L"navisphere", 2162 },
+ { L"navisphere-sec", 2163 }, { L"nbd", 10809 }, { L"nbdb", 13785 }, { L"nbt-pc", 5133 },
+ { L"nbt-wol", 6133 }, { L"nburn-id", 20034 }, { L"nburn_id", 20034 }, { L"nbx-au", 2094 },
+ { L"nbx-cc", 2093 }, { L"nbx-dir", 2096 }, { L"nbx-ser", 2095 }, { L"ncacn-ip-tcp", 3062 },
+ { L"ncadg-ip-udp", 3063 }, { L"ncconfig", 1888 }, { L"ncdloadbalance", 2683 }, { L"ncdmirroring", 2706 },
+ { L"nced", 404 }, { L"ncl", 2397 }, { L"ncld", 405 }, { L"ncp", 524 },
+ { L"ncpm-ft", 1744 }, { L"ncpm-hip", 1683 }, { L"ncpm-pm", 1591 }, { L"ncr-ccl", 2528 },
+ { L"ncu-1", 3195 }, { L"ncu-2", 3196 }, { L"ncube-lm", 1521 }, { L"ncxcp", 5681 },
+ { L"ndl-aas", 3128 }, { L"ndl-ahp-svc", 6064 }, { L"ndl-als", 3431 }, { L"ndl-aps", 3096 },
+ { L"ndl-tcp-ois-gw", 2738 }, { L"ndm-agent-port", 43189 }, { L"ndm-requester", 1363 }, { L"ndm-server", 1364 },
+ { L"ndmp", 10000 }, { L"ndmps", 30000 }, { L"ndn", 6363 }, { L"ndnp", 2883 },
+ { L"nds-sso", 3024 }, { L"ndsauth", 353 }, { L"ndsconnect", 3890 }, { L"ndsp", 2881 },
+ { L"ndtp", 2882 }, { L"nec-raidplus", 2730 }, { L"neckar", 37475 }, { L"necp", 3262 },
+ { L"nei-management", 3886 }, { L"neo4j", 7474 }, { L"neod1", 1047 }, { L"neod2", 1048 },
+ { L"neoiface", 1285 }, { L"neon24x7", 3213 }, { L"nerv", 1222 }, { L"nesh-broker", 3507 },
+ { L"nessus", 1241 }, { L"nest-protocol", 489 }, { L"net-device", 4350 }, { L"net-projection", 5363 },
+ { L"net-steward", 2128 }, { L"net2display", 9086 }, { L"net8-cman", 1830 }, { L"netadmin", 2450 },
+ { L"netagent", 5771 }, { L"netangel", 2442 }, { L"netapp-icdata", 11105 }, { L"netapp-icmgmt", 11104 },
+ { L"netapp-sync", 10006 }, { L"netarx", 1040 }, { L"netaspi", 2902 }, { L"netattachsdmp", 3066 },
+ { L"netbill-auth", 1615 }, { L"netbill-cred", 1614 }, { L"netbill-keyrep", 1613 }, { L"netbill-prod", 1616 },
+ { L"netbill-trans", 1612 }, { L"netbios-dgm", 138 }, { L"netbios-ns", 137 }, { L"netbios-ssn", 139 },
+ { L"netblox", 4441 }, { L"netbookmark", 3131 }, { L"netboot-pxe", 3928 }, { L"netcabinet-com", 4409 },
+ { L"netcelera", 3701 }, { L"netchat", 2451 }, { L"netcheque", 4008 }, { L"netclip", 2971 },
+ { L"netcomm1", 1676 }, { L"netcomm2", 1676 }, { L"netconf-beep", 831 }, { L"netconf-ssh", 830 },
+ { L"netconf-tls", 6513 }, { L"netconfsoapbeep", 833 }, { L"netconfsoaphttp", 832 }, { L"netcp", 395 },
+ { L"netdb-export", 1329 }, { L"neteh", 3828 }, { L"neteh-ext", 3829 }, { L"netgw", 741 },
+ { L"netinfo-local", 1033 }, { L"netiq", 2220 }, { L"netiq-endpoint", 10113 }, { L"netiq-endpt", 10115 },
+ { L"netiq-mc", 2735 }, { L"netiq-ncap", 2219 }, { L"netiq-qcheck", 10114 }, { L"netiq-voipa", 10116 },
+ { L"netlabs-lm", 1406 }, { L"netmagic", 1196 }, { L"netmap-lm", 1493 }, { L"netml", 2288 },
+ { L"netmo-default", 6841 }, { L"netmo-http", 6842 }, { L"netmon", 2606 }, { L"netmount", 2061 },
+ { L"netmpi", 3827 }, { L"netnews", 532 }, { L"neto-dcs", 3814 }, { L"neto-wol-server", 3812 },
+ { L"netobjects1", 2485 }, { L"netobjects2", 2486 }, { L"netop-rc", 1970 }, { L"netop-school", 1971 },
+ { L"netopia-vo1", 1839 }, { L"netopia-vo2", 1840 }, { L"netopia-vo3", 1841 }, { L"netopia-vo4", 1842 },
+ { L"netopia-vo5", 1843 }, { L"netops-broker", 5465 }, { L"netperf", 12865 }, { L"netplan", 2983 },
+ { L"netplay-port1", 3640 }, { L"netplay-port2", 3641 }, { L"netport-id", 3129 }, { L"netrcs", 742 },
+ { L"netrek", 2592 }, { L"netrisk", 1799 }, { L"netrix-sftm", 2328 }, { L"netrjs-1", 71 },
+ { L"netrjs-2", 72 }, { L"netrjs-3", 73 }, { L"netrjs-4", 74 }, { L"netrockey6", 4425 },
+ { L"netsc-dev", 155 }, { L"netsc-prod", 154 }, { L"netscript", 4118 }, { L"netserialext1", 16360 },
+ { L"netserialext2", 16361 }, { L"netserialext3", 16367 }, { L"netserialext4", 16368 }, { L"netspeak-acd", 21848 },
+ { L"netspeak-cps", 21849 }, { L"netspeak-cs", 21847 }, { L"netspeak-is", 21846 }, { L"netsteward", 2810 },
+ { L"netsupport", 5405 }, { L"netsupport2", 5421 }, { L"nettest", 4138 }, { L"nettgain-nms", 1879 },
+ { L"netuitive", 1286 }, { L"netview-aix-1", 1661 }, { L"netview-aix-10", 1670 }, { L"netview-aix-11", 1671 },
+ { L"netview-aix-12", 1672 }, { L"netview-aix-2", 1662 }, { L"netview-aix-3", 1663 }, { L"netview-aix-4", 1664 },
+ { L"netview-aix-5", 1665 }, { L"netview-aix-6", 1666 }, { L"netview-aix-7", 1667 }, { L"netview-aix-8", 1668 },
+ { L"netview-aix-9", 1669 }, { L"netviewdm1", 729 }, { L"netviewdm2", 730 }, { L"netviewdm3", 731 },
+ { L"netwall", 533 }, { L"netware-csp", 1366 }, { L"netware-ip", 396 }, { L"netwatcher-db", 3204 },
+ { L"netwatcher-mon", 3203 }, { L"netwave-ap-mgmt", 2411 }, { L"netwkpathengine", 3209 }, { L"networklens", 3409 },
+ { L"networklenss", 3410 }, { L"netx-agent", 2586 }, { L"netx-server", 2585 }, { L"netxms-agent", 4700 },
+ { L"netxms-mgmt", 4701 }, { L"netxms-sync", 4702 }, { L"neveroffline", 2614 }, { L"new-rwho", 550 },
+ { L"newbay-snc-mc", 16900 }, { L"newgenpay", 3165 }, { L"newheights", 2114 }, { L"newlixconfig", 2076 },
+ { L"newlixengine", 2075 }, { L"newlixreg", 2671 }, { L"newoak", 4001 }, { L"news", 2009 },
+ { L"newwavesearch", 2058 }, { L"nexentamv", 8457 }, { L"nexgen", 6627 }, { L"nexstorindltd", 2360 },
+ { L"nextstep", 178 }, { L"nexus-portal", 4021 }, { L"nfa", 1155 }, { L"nfoldman", 7393 },
+ { L"nfs", 2049 }, { L"nfsd-keepalive", 1110 }, { L"nfsrdma", 20049 }, { L"ng-umds", 1690 },
+ { L"nhci", 3842 }, { L"nhserver", 2672 }, { L"ni-ftp", 47 }, { L"ni-mail", 61 },
+ { L"ni-visa-remote", 3537 }, { L"nicelink", 1095 }, { L"nicetec-mgmt", 2557 }, { L"nicetec-nmsvc", 2556 },
+ { L"nicname", 43 }, { L"nifty-hmi", 4134 }, { L"nilinkanalyst", 25902 }, { L"nim", 1058 },
+ { L"nim-vdrshell", 6420 }, { L"nim-wan", 6421 }, { L"nimaux", 3902 }, { L"nimbusdb", 48004 },
+ { L"nimbusdbctrl", 48005 }, { L"nimcontroller", 48000 }, { L"nimgtw", 48003 }, { L"nimhub", 48002 },
+ { L"nimreg", 1059 }, { L"nimrod-agent", 1617 }, { L"nimsh", 3901 }, { L"nimspooler", 48001 },
+ { L"ninaf", 5627 }, { L"niobserver", 25901 }, { L"nip", 376 }, { L"niprobe", 25903 },
+ { L"nirp", 4043 }, { L"nitrogen", 7725 }, { L"njenet-ssl", 2252 }, { L"nkd", 1650 },
+ { L"nlg-data", 5299 }, { L"nlogin", 758 }, { L"nls-tl", 7549 }, { L"nm-asses-admin", 3150 },
+ { L"nm-assessor", 3151 }, { L"nm-game-admin", 3148 }, { L"nm-game-server", 3149 }, { L"nmap", 689 },
+ { L"nmasoverip", 1242 }, { L"nmc-disc", 10810 }, { L"nmea-0183", 10110 }, { L"nmea-onenet", 10111 },
+ { L"nmmp", 3649 }, { L"nms", 1429 }, { L"nms-dpnss", 2503 }, { L"nms-topo-serv", 1486 },
+ { L"nmsd", 1239 }, { L"nmsigport", 2817 }, { L"nmsigport", 2839 }, { L"nmsp", 1790 },
+ { L"nmsp", 537 }, { L"nmsserver", 2244 }, { L"nnp", 3780 }, { L"nnsp", 433 },
+ { L"nntp", 119 }, { L"nntps", 563 }, { L"noaaport", 2210 }, { L"noadmin", 1921 },
+ { L"noagent", 1917 }, { L"nod-client", 8981 }, { L"nod-provider", 8980 }, { L"noit-transport", 43191 },
+ { L"nokia-ann-ch1", 3405 }, { L"nokia-ann-ch2", 3406 }, { L"nomad", 5209 }, { L"nomdb", 13786 },
+ { L"norton-lambert", 2338 }, { L"notateit", 4803 }, { L"notateit-disc", 4803 }, { L"noteit", 4663 },
+ { L"noteshare", 8474 }, { L"noteza", 5215 }, { L"notezilla-lan", 21010 }, { L"notify", 773 },
+ { L"notify-srvr", 3016 }, { L"novar-alarm", 23401 }, { L"novar-dbase", 23400 }, { L"novar-global", 23402 },
+ { L"novastorbakcup", 308 }, { L"novation", 1322 }, { L"novell-ipx-cmd", 2645 }, { L"novell-lu6-2", 1416 },
+ { L"novell-zen", 2544 }, { L"nowcontact", 3167 }, { L"npdbgmngr", 2293 }, { L"npds-tracker", 3680 },
+ { L"npep-messaging", 2868 }, { L"npmp", 8450 }, { L"npmp-gui", 611 }, { L"npmp-local", 610 },
+ { L"npmp-trap", 609 }, { L"npp", 4045 }, { L"npp", 92 }, { L"nppmp", 3476 },
+ { L"npqes-test", 4703 }, { L"npsp", 4088 }, { L"nqs", 607 }, { L"nrcabq-lm", 1458 },
+ { L"ns", 760 }, { L"ns-cfg-server", 3266 }, { L"ns-server", 5415 }, { L"nsc-ccs", 2604 },
+ { L"nsc-posa", 2605 }, { L"nsdeepfreezectl", 7724 }, { L"nsesrvr", 9988 }, { L"nsiiops", 261 },
+ { L"nsjtp-ctrl", 1687 }, { L"nsjtp-data", 1688 }, { L"nsp", 5012 }, { L"nsrmp", 359 },
+ { L"nsrp", 7170 }, { L"nss", 4159 }, { L"nss-routing", 159 }, { L"nssagentmgr", 4454 },
+ { L"nssalertmgr", 4453 }, { L"nssocketport", 3522 }, { L"nsstp", 1036 }, { L"nst", 4687 },
+ { L"nsw-fe", 27 }, { L"nsws", 3049 }, { L"nta-ds", 7544 }, { L"nta-us", 7545 },
+ { L"ntalk", 518 }, { L"ntp", 123 }, { L"ntz-p2p-storage", 6778 }, { L"ntz-tracker", 6777 },
+ { L"nuauth", 4129 }, { L"nucleus", 1463 }, { L"nucleus-sand", 1201 }, { L"nufw", 4128 },
+ { L"nupaper-ss", 12121 }, { L"nut", 3493 }, { L"nuts-bootp", 4133 }, { L"nuts-dem", 4132 },
+ { L"nuxsl", 5991 }, { L"nv-video", 4444 }, { L"nvc", 8711 }, { L"nvcnet", 3999 },
+ { L"nvd", 2184 }, { L"nvd", 2329 }, { L"nvmsgd", 3519 }, { L"nw-license", 3697 },
+ { L"nxlmd", 28000 }, { L"o2server-port", 1894 }, { L"oa-system", 8022 }, { L"obex", 650 },
+ { L"objcall", 94 }, { L"objective-dbc", 1388 }, { L"objectmanager", 2038 }, { L"obrpd", 1092 },
+ { L"observium-agent", 36602 }, { L"oc-lm", 1448 }, { L"ocbinder", 183 }, { L"oce-snmp-trap", 2697 },
+ { L"oceansoft-lm", 1466 }, { L"ocs-amu", 429 }, { L"ocs-cmu", 428 }, { L"ocserver", 184 },
+ { L"octopus", 10008 }, { L"octopustentacle", 10933 }, { L"odbcpathway", 9628 }, { L"odette-ftp", 3305 },
+ { L"odette-ftps", 6619 }, { L"odeumservlink", 3523 }, { L"odi-port", 3187 }, { L"odmr", 366 },
+ { L"odn-castraq", 2498 }, { L"odnsp", 9966 }, { L"odsi", 1308 }, { L"oem-agent", 3872 },
+ { L"oemcacao-jmxmp", 11172 }, { L"oemcacao-rmi", 11174 }, { L"oemcacao-websvc", 11175 }, { L"office-tools", 7789 },
+ { L"officelink2000", 3320 }, { L"ofsd", 2322 }, { L"ogs-client", 9007 }, { L"ogs-server", 9008 },
+ { L"ohimsrv", 506 }, { L"ohmtrigger", 4732 }, { L"ohsc", 18186 }, { L"oi-2000", 2364 },
+ { L"oidocsvc", 4142 }, { L"oidsr", 4143 }, { L"oirtgsvc", 4141 }, { L"olhost", 2661 },
+ { L"olsr", 698 }, { L"olsv", 1160 }, { L"oma-dcdocbs", 7278 }, { L"oma-ilp", 7276 },
+ { L"oma-ilp-s", 7277 }, { L"oma-mlp", 9210 }, { L"oma-mlp-s", 9211 }, { L"oma-rlp", 7273 },
+ { L"oma-rlp-s", 7274 }, { L"oma-ulp", 7275 }, { L"omabcastltkm", 4359 }, { L"omasgport", 4090 },
+ { L"omginitialrefs", 900 }, { L"omhs", 5723 }, { L"omnilink-port", 3904 }, { L"omnisky", 2056 },
+ { L"omnivision", 1135 }, { L"omnivisionesx", 4395 }, { L"oms", 4662 }, { L"oms-nonsecure", 5102 },
+ { L"omscontact", 4161 }, { L"omsdk", 5724 }, { L"omserv", 764 }, { L"omstopology", 4162 },
+ { L"omviagent", 4429 }, { L"omviserver", 4428 }, { L"onbase-dds", 2185 }, { L"onehome-help", 2199 },
+ { L"onehome-remote", 2198 }, { L"onep-tls", 15002 }, { L"onesaf", 3244 }, { L"onmux", 417 },
+ { L"onpsocket", 5014 }, { L"onscreen", 5080 }, { L"ontime", 1622 }, { L"ontobroker", 2267 },
+ { L"oob-ws-http", 623 }, { L"oob-ws-https", 664 }, { L"op-probe", 7030 }, { L"opalis-rbt-ipc", 5314 },
+ { L"opalis-rdv", 536 }, { L"opalis-robot", 314 }, { L"opc-job-start", 423 }, { L"opc-job-track", 424 },
+ { L"opcon-xps", 3100 }, { L"opcua-tcp", 4840 }, { L"opcua-tls", 4843 }, { L"opcua-udp", 4840 },
+ { L"opencm", 3434 }, { L"opencore", 4089 }, { L"opendeploy", 20014 }, { L"openflow", 6653 },
+ { L"openhpid", 4743 }, { L"openmail", 5729 }, { L"openmailg", 5755 }, { L"openmailns", 5766 },
+ { L"openmailpxy", 5768 }, { L"openmath", 1473 }, { L"opennl", 1258 }, { L"opennl-voice", 1259 },
+ { L"openport", 260 }, { L"openqueue", 8764 }, { L"openremote-ctrl", 8688 }, { L"openstack-id", 35357 },
+ { L"opentable", 2368 }, { L"opentrac", 3855 }, { L"openvms-sysipc", 557 }, { L"openvpn", 1194 },
+ { L"openwebnet", 20005 }, { L"opequus-server", 2400 }, { L"opi-sock", 7429 }, { L"opnet-smp", 3433 },
+ { L"opsec-cvp", 18181 }, { L"opsec-ela", 18187 }, { L"opsec-lea", 18184 }, { L"opsec-omi", 18185 },
+ { L"opsec-sam", 18183 }, { L"opsec-uaa", 19191 }, { L"opsec-ufp", 18182 }, { L"opsession-clnt", 3303 },
+ { L"opsession-prxy", 3307 }, { L"opsession-srvr", 3304 }, { L"opsmgr", 1270 }, { L"opsview-envoy", 4125 },
+ { L"opswagent", 3976 }, { L"opswmanager", 3977 }, { L"optech-port1-lm", 2237 }, { L"optika-emedia", 1829 },
+ { L"optilogic", 2435 }, { L"optima-vnet", 1051 }, { L"optiwave-lm", 2524 }, { L"optocontrol", 22001 },
+ { L"optohost002", 22002 }, { L"optohost003", 22003 }, { L"optohost004", 22004 }, { L"optohost004", 22005 },
+ { L"opus-services", 3718 }, { L"ora-lm", 1446 }, { L"ora-oap", 5575 }, { L"oracle", 2005 },
+ { L"oracle-em1", 1748 }, { L"oracle-em2", 1754 }, { L"oracle-ms-ens", 8997 }, { L"oracle-oms", 1159 },
+ { L"oracle-vp1", 1809 }, { L"oracle-vp2", 1808 }, { L"oracleas-https", 7443 }, { L"oraclenames", 1575 },
+ { L"oraclenet8cman", 1630 }, { L"orasrv", 1525 }, { L"orbiter", 2398 }, { L"orbix-cfg-ssl", 3078 },
+ { L"orbix-config", 3076 }, { L"orbix-loc-ssl", 3077 }, { L"orbix-locator", 3075 }, { L"orbixd", 1570 },
+ { L"orbplus-iiop", 1597 }, { L"ordinox-dbase", 3355 }, { L"ordinox-server", 3274 }, { L"origo-native", 3001 },
+ { L"origo-sync", 11103 }, { L"orion", 2407 }, { L"orion-rmi-reg", 2413 }, { L"ortec-disc", 40853 },
+ { L"os-licman", 1384 }, { L"osaut", 6679 }, { L"osb-sd", 400 }, { L"osdcp", 3432 },
+ { L"osm-appsrvr", 9990 }, { L"osm-oev", 9991 }, { L"osmosis-aeea", 3034 }, { L"osp", 5045 },
+ { L"ospf-lite", 8899 }, { L"osu-nms", 192 }, { L"otlp", 6951 }, { L"otmp", 29167 },
+ { L"otp", 9390 }, { L"otpatch", 2936 }, { L"ott", 2428 }, { L"ottp", 2951 },
+ { L"otv", 8472 }, { L"outlaws", 5310 }, { L"ov-nnm-websrv", 3443 }, { L"ovalarmsrv", 2953 },
+ { L"ovalarmsrv-cmd", 2954 }, { L"ovbus", 7501 }, { L"oveadmgr", 7427 }, { L"ovhpas", 7510 },
+ { L"ovladmgr", 7428 }, { L"ovobs", 30999 }, { L"ovrimosdbman", 2956 }, { L"ovsam-d-agent", 3870 },
+ { L"ovsam-mgmt", 3869 }, { L"ovsdb", 6640 }, { L"ovsessionmgr", 2389 }, { L"ovtopmd", 2532 },
+ { L"ovwdb", 2447 }, { L"owamp-control", 861 }, { L"owms", 7878 }, { L"owserver", 4304 },
+ { L"p-net-local", 34378 }, { L"p-net-remote", 34379 }, { L"p25cai", 6082 }, { L"p2pcommunity", 3955 },
+ { L"p2pgroup", 3587 }, { L"p2pq", 1981 }, { L"p4p-portal", 6671 }, { L"p6ssmc", 4311 },
+ { L"pace-licensed", 31400 }, { L"pacerforum", 1480 }, { L"pacmand", 1307 }, { L"pacom", 3435 },
+ { L"padl2sim", 5236 }, { L"pads", 7237 }, { L"pafec-lm", 7511 }, { L"paging-port", 3771 },
+ { L"pago-services1", 30001 }, { L"pago-services2", 30002 }, { L"palace-1", 9992 }, { L"palace-2", 9993 },
+ { L"palace-3", 9994 }, { L"palace-4", 9995 }, { L"palace-5", 9996 }, { L"palace-6", 9997 },
+ { L"palcom-disc", 6657 }, { L"pammratc", 1632 }, { L"pammrpc", 1633 }, { L"pana", 716 },
+ { L"panagolin-ident", 9021 }, { L"panasas", 3095 }, { L"pando-pub", 7680 }, { L"pando-sec", 8276 },
+ { L"pangolin-laser", 3348 }, { L"paradym-31port", 1864 }, { L"paragent", 9022 }, { L"parallel", 4989 },
+ { L"park-agent", 5431 }, { L"parliant", 4681 }, { L"parsec-game", 6582 }, { L"parsec-master", 6580 },
+ { L"parsec-peer", 6581 }, { L"partimage", 4025 }, { L"passgo", 511 }, { L"passgo-tivoli", 627 },
+ { L"password-chg", 586 }, { L"passwrd-policy", 1333 }, { L"patrol", 8160 }, { L"patrol-coll", 6162 },
+ { L"patrol-ism", 6161 }, { L"patrol-mq-gm", 2664 }, { L"patrol-mq-nm", 2665 }, { L"patrol-snmp", 8161 },
+ { L"patrolview", 4097 }, { L"pawserv", 345 }, { L"pay-per-view", 1564 }, { L"paycash-online", 8128 },
+ { L"paycash-wbp", 8129 }, { L"payrouter", 1246 }, { L"pc-mta-addrmap", 2246 }, { L"pc-telecommute", 2299 },
+ { L"pcanywheredata", 5631 }, { L"pcanywherestat", 5632 }, { L"pcc-image-port", 3892 }, { L"pcc-mfp", 2256 },
+ { L"pcep", 4189 }, { L"pcia-rxp-b", 1332 }, { L"pciarray", 1552 }, { L"pcihreq", 3085 },
+ { L"pcle-infex", 3189 }, { L"pclemultimedia", 2558 }, { L"pcmail-srv", 158 }, { L"pcmk-remote", 3121 },
+ { L"pcoip", 4172 }, { L"pcoip-mgmt", 5172 }, { L"pconnectmgr", 1562 }, { L"pcp", 5351 },
+ { L"pcp-multicast", 5350 }, { L"pcptcpservice", 4182 }, { L"pcs-pcw", 2566 }, { L"pcs-sf-ui-man", 6655 },
+ { L"pcsync-http", 8444 }, { L"pcsync-https", 8443 }, { L"pctrader", 3048 }, { L"pcttunnell", 2274 },
+ { L"pd-admin", 9597 }, { L"pda-data", 3253 }, { L"pda-gate", 4012 }, { L"pda-sys", 3254 },
+ { L"pdap", 344 }, { L"pdap-np", 1526 }, { L"pdb", 3033 }, { L"pdefmns", 16311 },
+ { L"pdl-datastream", 9100 }, { L"pdnet", 2843 }, { L"pdp", 1675 }, { L"pdps", 1314 },
+ { L"pdrncs", 3299 }, { L"pds", 9595 }, { L"pdtp", 6086 }, { L"pduncs", 16310 },
+ { L"pe-mike", 1305 }, { L"pearldoc-xact", 1980 }, { L"peerbook-port", 3135 }, { L"peerwire", 9104 },
+ { L"pegasus", 9278 }, { L"pegasus-ctl", 9279 }, { L"pegboard", 1357 }, { L"pehelp", 2307 },
+ { L"pentbox-sim", 6817 }, { L"peocoll", 9631 }, { L"peoctlr", 9630 }, { L"peport", 1449 },
+ { L"perf-port", 1995 }, { L"perfd", 5227 }, { L"perimlan", 4075 }, { L"periscope", 1230 },
+ { L"permabit-cs", 5312 }, { L"perrla", 4313 }, { L"persona", 1916 }, { L"personal-agent", 5555 },
+ { L"personal-link", 281 }, { L"personalos-001", 3557 }, { L"personnel", 3109 }, { L"pftp", 662 },
+ { L"pfu-prcallback", 3208 }, { L"pgbouncer", 6432 }, { L"pgps", 9280 }, { L"ph", 481 },
+ { L"pharmasoft", 1779 }, { L"pharos", 4443 }, { L"philips-vc", 583 }, { L"phoenix-rpc", 3347 },
+ { L"phonebook", 767 }, { L"phonex-port", 3177 }, { L"photuris", 468 }, { L"phrelay", 4868 },
+ { L"phrelaydbg", 4869 }, { L"piccolo", 2787 }, { L"pichat", 9009 }, { L"picknfs", 1598 },
+ { L"picodbc", 1603 }, { L"pictrography", 1280 }, { L"pim-port", 8471 }, { L"pim-rp-disc", 496 },
+ { L"ping-pong", 3010 }, { L"pinghgl", 4306 }, { L"pip", 1321 }, { L"pip", 321 },
+ { L"pipe-server", 2010 }, { L"pipes", 1465 }, { L"pipe_server", 2010 }, { L"piranha1", 4600 },
+ { L"piranha2", 4601 }, { L"pirp", 553 }, { L"pit-vpn", 2865 }, { L"pixelpusher", 5078 },
+ { L"pjlink", 4352 }, { L"pk", 5272 }, { L"pk-electronics", 2634 }, { L"pkagent", 3118 },
+ { L"pkix-3-ca-ra", 829 }, { L"pkix-cmc", 5318 }, { L"pkix-timestamp", 318 }, { L"pkt-krb-ipsec", 1293 },
+ { L"pktcable-cops", 2126 }, { L"pktcablemmcops", 3918 }, { L"plato", 3285 }, { L"plato-lm", 1819 },
+ { L"playsta2-app", 4658 }, { L"playsta2-lob", 4659 }, { L"plbserve-port", 3933 }, { L"plcy-net-svcs", 4351 },
+ { L"plethora", 3480 }, { L"plgproxy", 2790 }, { L"pluribus", 3469 }, { L"plysrv-http", 6770 },
+ { L"plysrv-https", 6771 }, { L"pm-cmdsvr", 5112 }, { L"pmas", 4066 }, { L"pmcd", 44321 },
+ { L"pmcdproxy", 44322 }, { L"pmcp", 3821 }, { L"pmcs", 6355 }, { L"pmd", 7431 },
+ { L"pmdfmgt", 7633 }, { L"pmdmgr", 7426 }, { L"pmip6-cntl", 5436 }, { L"pmip6-data", 5437 },
+ { L"pmsm-webrctl", 2972 }, { L"pmwebapi", 44323 }, { L"pn-requester", 2717 }, { L"pn-requester2", 2718 },
+ { L"pnaconsult-lm", 2937 }, { L"pnbs", 6124 }, { L"pnbscada", 3875 }, { L"pnet-conn", 7797 },
+ { L"pnet-enc", 7798 }, { L"pnrp-port", 3540 }, { L"pns", 2487 }, { L"polestar", 1060 },
+ { L"policyserver", 3055 }, { L"pop2", 109 }, { L"pop3", 110 }, { L"pop3s", 995 },
+ { L"popup-reminders", 7787 }, { L"portgate-auth", 3710 }, { L"postgresql", 5432 }, { L"pov-ray", 494 },
+ { L"PowerAlert-nsa", 4150 }, { L"powerburst", 485 }, { L"powerclientcsf", 2443 }, { L"powerexchange", 2480 },
+ { L"powergemplus", 2899 }, { L"powerguardian", 1777 }, { L"poweronnud", 3168 }, { L"powerschool", 5071 },
+ { L"powwow-client", 13223 }, { L"powwow-server", 13224 }, { L"ppactivation", 5134 }, { L"ppcontrol", 2505 },
+ { L"ppsms", 3967 }, { L"ppsuitemsg", 5863 }, { L"pptconference", 1711 }, { L"pptp", 1723 },
+ { L"pq-lic-mgmt", 2687 }, { L"pqsflows", 9640 }, { L"pqsp", 28001 }, { L"pra-elmd", 1587 },
+ { L"prat", 1264 }, { L"prchat-server", 4456 }, { L"prchat-user", 4455 }, { L"precise-comm", 5630 },
+ { L"precise-i3", 3607 }, { L"precise-sft", 2315 }, { L"precise-vip", 2924 }, { L"predatar-comms", 1753 },
+ { L"prelude", 4690 }, { L"presence", 5298 }, { L"presonus-ucnet", 47809 }, { L"press", 3582 },
+ { L"prex-tcp", 4487 }, { L"prgp", 7747 }, { L"primaserver", 6105 }, { L"print-srv", 170 },
+ { L"printer", 515 }, { L"printer-agent", 3396 }, { L"printercare-cc", 6716 }, { L"printopia", 10631 },
+ { L"priority-e-com", 2618 }, { L"prism-deploy", 3133 }, { L"prismiq-plugin", 3650 }, { L"privateark", 1858 },
+ { L"privatechat", 1735 }, { L"privatewire", 4449 }, { L"privilege", 2588 }, { L"privoxy", 8118 },
+ { L"prizma", 2039 }, { L"prm-nm", 409 }, { L"prm-nm-np", 1403 }, { L"prm-sm", 408 },
+ { L"prm-sm-np", 1402 }, { L"prnrequest", 3910 }, { L"prnstatus", 3911 }, { L"pro-ed", 8032 },
+ { L"proactivate", 24678 }, { L"proactivesrvr", 2722 }, { L"proaxess", 3961 }, { L"procos-lm", 3248 },
+ { L"prodigy-intrnet", 1778 }, { L"productinfo", 1283 }, { L"profile", 136 }, { L"profilemac", 4749 },
+ { L"profinet-cm", 34964 }, { L"profinet-rt", 34962 }, { L"profinet-rtm", 34963 }, { L"progistics", 3973 },
+ { L"programmar", 15999 }, { L"prolink", 1678 }, { L"proofd", 1093 }, { L"propel-msgsys", 1268 },
+ { L"proremote", 8183 }, { L"proshare-mc-1", 1673 }, { L"proshare-mc-2", 1674 }, { L"proshare1", 1459 },
+ { L"proshare2", 1460 }, { L"proshareaudio", 5713 }, { L"prosharedata", 5715 }, { L"prosharenotify", 5717 },
+ { L"prosharerequest", 5716 }, { L"prosharevideo", 5714 }, { L"prospero", 191 }, { L"prospero-np", 1525 },
+ { L"proxim", 1732 }, { L"proxima-lm", 1445 }, { L"proxy-gateway", 2303 }, { L"prp", 2091 },
+ { L"prRegister", 4457 }, { L"prsvp", 3455 }, { L"ps-ams", 3658 }, { L"psbserver", 2350 },
+ { L"pscl-mgt", 4312 }, { L"pscribe", 6163 }, { L"pscupd", 3453 }, { L"psdbserver", 2355 },
+ { L"pserver", 3662 }, { L"psi-ptt", 4374 }, { L"pslicser", 4168 }, { L"pslserver", 2352 },
+ { L"psmond", 1788 }, { L"psprserver", 2354 }, { L"pspserver", 2353 }, { L"psrserver", 2351 },
+ { L"pss", 7880 }, { L"pssc", 645 }, { L"pt-tls", 271 }, { L"pt2-discover", 1101 },
+ { L"ptcnameservice", 597 }, { L"ptk-alink", 3089 }, { L"ptp", 15740 }, { L"ptp-event", 319 },
+ { L"ptp-general", 320 }, { L"publiqare-sync", 4329 }, { L"pulsonixnls", 6140 }, { L"pump", 751 },
+ { L"puparp", 998 }, { L"puppet", 8140 }, { L"puprouter", 999 }, { L"purenoise", 663 },
+ { L"purityrpc", 8117 }, { L"pushns", 7997 }, { L"pvaccess", 5075 }, { L"pvsw", 2520 },
+ { L"pvsw-inet", 2441 }, { L"pvuniwien", 1081 }, { L"pvxpluscs", 4093 }, { L"pvxplusio", 4193 },
+ { L"pwdgen", 129 }, { L"pwdis", 3735 }, { L"pwgippfax", 3951 }, { L"pwgpsi", 3800 },
+ { L"pwgwims", 4951 }, { L"pwrsevent", 2694 }, { L"pxc-epmap", 2434 }, { L"pxc-ntfy", 3009 },
+ { L"pxc-pin", 4005 }, { L"pxc-roid", 4004 }, { L"pxc-sapxom", 2680 }, { L"pxc-splr", 4007 },
+ { L"pxc-splr-ft", 4003 }, { L"pxc-spvr", 4006 }, { L"pxc-spvr-ft", 4002 }, { L"pyrrho", 5433 },
+ { L"q3ade", 7794 }, { L"q55-pcc", 1253 }, { L"qadmifevent", 2462 }, { L"qadmifoper", 2461 },
+ { L"qb-db-server", 10160 }, { L"qbdb", 8019 }, { L"qbikgdp", 368 }, { L"qcp", 5082 },
+ { L"qdb2service", 45825 }, { L"qencp", 2120 }, { L"qfp", 5083 }, { L"qft", 189 },
+ { L"qftest-lookup", 3543 }, { L"qip-audup", 2765 }, { L"qip-login", 2366 }, { L"qip-msgd", 2468 },
+ { L"qip-qdhcp", 2490 }, { L"qke-llc-v3", 2523 }, { L"qmqp", 628 }, { L"qmtp", 209 },
+ { L"qmtps", 6209 }, { L"qmvideo", 5689 }, { L"qnts-orb", 1262 }, { L"qnxnetman", 3385 },
+ { L"qo-secure", 7913 }, { L"qotd", 17 }, { L"qotps", 2724 }, { L"qpasa-agent", 2612 },
+ { L"qptlmd", 10055 }, { L"qrh", 752 }, { L"qsm-gui", 1165 }, { L"qsm-proxy", 1164 },
+ { L"qsm-remote", 1166 }, { L"qsnet-assist", 4356 }, { L"qsnet-cond", 4357 }, { L"qsnet-nucl", 4358 },
+ { L"qsnet-trans", 4354 }, { L"qsnet-workst", 4355 }, { L"qsoft", 3059 }, { L"qt-serveradmin", 1220 },
+ { L"qtms-bootstrap", 3850 }, { L"qtp", 2935 }, { L"quaddb", 2497 }, { L"quailnet", 5464 },
+ { L"quake", 26000 }, { L"quantastor", 8153 }, { L"quartus-tcl", 2589 }, { L"quasar-server", 3599 },
+ { L"qubes", 1341 }, { L"quest-agent", 3843 }, { L"quest-data-hub", 3566 }, { L"quest-disc", 7040 },
+ { L"quest-vista", 7980 }, { L"questdb2-lnchr", 5677 }, { L"questnotify", 3554 }, { L"queueadm", 2230 },
+ { L"quickbooksrds", 3790 }, { L"quicksuite", 2900 }, { L"quosa", 4841 }, { L"quotad", 762 },
+ { L"qvr", 5028 }, { L"qwave", 2177 }, { L"raadmin", 5676 }, { L"racf", 18136 },
+ { L"radan-http", 8088 }, { L"radclientport", 3178 }, { L"radec-corp", 5430 }, { L"radio", 1595 },
+ { L"radio-bc", 1596 }, { L"radio-sm", 1596 }, { L"radius", 1812 }, { L"radius-acct", 1813 },
+ { L"radius-dynauth", 3799 }, { L"radix", 2872 }, { L"radmin-port", 4899 }, { L"radmind", 6222 },
+ { L"radpdf", 18104 }, { L"rads", 12302 }, { L"radsec", 2083 }, { L"radware-rpm", 2188 },
+ { L"radware-rpm-s", 2189 }, { L"radwiz-nms-srv", 2736 }, { L"raid-ac", 2012 }, { L"raid-am", 2007 },
+ { L"raid-am", 2013 }, { L"raid-cc", 2011 }, { L"raid-cd", 2006 }, { L"raid-cd", 2013 },
+ { L"raid-cs", 2015 }, { L"raid-sf", 2014 }, { L"railgun-webaccl", 2408 }, { L"ramp", 7227 },
+ { L"rancher", 9345 }, { L"rap", 256 }, { L"rap", 38 }, { L"rap-ip", 3813 },
+ { L"rap-listen", 1531 }, { L"rap-service", 1530 }, { L"rapi", 2176 }, { L"rapidbase", 1953 },
+ { L"rapidmq-center", 3093 }, { L"rapidmq-reg", 3094 }, { L"rapido-ip", 2457 }, { L"raqmon-pdu", 7744 },
+ { L"rasadv", 9753 }, { L"ratio-adp", 1108 }, { L"ratl", 2449 }, { L"ravehd", 4037 },
+ { L"raven-rdp", 3533 }, { L"raven-rmp", 3532 }, { L"raventbs", 2713 }, { L"raventdm", 2714 },
+ { L"raw-serial", 2167 }, { L"raxa-mgmt", 6099 }, { L"razor", 3555 }, { L"rbakcup1", 2773 },
+ { L"rbakcup2", 2774 }, { L"rblcheckd", 3768 }, { L"rbr-debug", 44553 }, { L"rbr-discovery", 3553 },
+ { L"rbsystem", 5693 }, { L"rbt-smc", 7870 }, { L"rbt-wanopt", 7810 }, { L"rcc-host", 2332 },
+ { L"rcip-itu", 2225 }, { L"rcp", 469 }, { L"rcst", 3467 }, { L"rcts", 2258 },
+ { L"rda", 630 }, { L"rdb-dbs-disp", 1571 }, { L"rdc-wh-eos", 3142 }, { L"rdgs", 16385 },
+ { L"rdlap", 2321 }, { L"rdm-tfs", 21553 }, { L"rdmnet-ctrl", 5569 }, { L"rdmnet-device", 5569 },
+ { L"rdrmshc", 1075 }, { L"rds", 1540 }, { L"rds-ib", 18634 }, { L"rds-ip", 18635 },
+ { L"rds2", 1541 }, { L"re-conn-proto", 1306 }, { L"re-mail-ck", 50 }, { L"re101", 1343 },
+ { L"reachout", 43188 }, { L"realm-rusd", 688 }, { L"realsecure", 2998 }, { L"rebol", 2997 },
+ { L"recipe", 2240 }, { L"recvr-rc", 43000 }, { L"recvr-rc-disc", 43000 }, { L"redis", 6379 },
+ { L"redstone-cpss", 2928 }, { L"redstorm-diag", 2349 }, { L"redstorm-find", 2347 }, { L"redstorm-info", 2348 },
+ { L"redstorm-join", 2346 }, { L"redwood-chat", 3032 }, { L"reftek", 2543 }, { L"registrar", 1712 },
+ { L"relief", 1353 }, { L"rellpack", 2018 }, { L"reload-config", 6084 }, { L"remcap", 4731 },
+ { L"remctl", 4373 }, { L"remographlm", 2373 }, { L"remote-as", 1053 }, { L"remote-collab", 2250 },
+ { L"remote-kis", 185 }, { L"remote-winsock", 1745 }, { L"remotedeploy", 3789 }, { L"remotefs", 556 },
+ { L"remoteware-cl", 3000 }, { L"remoteware-srv", 3002 }, { L"remoteware-un", 2999 }, { L"repcmd", 641 },
+ { L"repliweb", 2837 }, { L"repscmd", 653 }, { L"repsvc", 6320 }, { L"res", 1942 },
+ { L"res-sap", 3163 }, { L"resacommunity", 1154 }, { L"rescap", 283 }, { L"resorcs", 4733 },
+ { L"resource-mgr", 3019 }, { L"responselogic", 2886 }, { L"responsenet", 3045 }, { L"retp", 32811 },
+ { L"retrospect", 497 }, { L"rets", 6103 }, { L"rets-ssl", 12109 }, { L"reversion", 5842 },
+ { L"rexecj", 8230 }, { L"rfa", 4672 }, { L"rfb", 5900 }, { L"rfe", 5002 },
+ { L"rfid-rp1", 4684 }, { L"rfile", 750 }, { L"rfio", 3147 }, { L"rfmp", 2249 },
+ { L"rfx-lm", 1497 }, { L"rgtp", 1431 }, { L"rhp-iibp", 1912 }, { L"rib-slm", 3296 },
+ { L"ricardo-lm", 1522 }, { L"ricardo-lm", 6148 }, { L"rich-cp", 2057 }, { L"rid", 4590 },
+ { L"ridgeway1", 2776 }, { L"ridgeway2", 2777 }, { L"rimf-ps", 2209 }, { L"rimsl", 2044 },
+ { L"ripng", 521 }, { L"ris", 180 }, { L"ris-cm", 748 }, { L"rise", 7473 },
+ { L"rjcdb-vcards", 9208 }, { L"rje", 5 }, { L"rkb-oscs", 1817 }, { L"rlm", 5053 },
+ { L"rlm-admin", 5054 }, { L"rlm-disc", 5053 }, { L"rlp", 39 }, { L"rlzdbase", 635 },
+ { L"rmc", 657 }, { L"rmiactivation", 1098 }, { L"rmiaux", 10990 }, { L"rmiregistry", 1099 },
+ { L"rmlnk", 2818 }, { L"rmonitor", 560 }, { L"rmonitor-secure", 5145 }, { L"rmopagt", 2959 },
+ { L"rmpp", 1121 }, { L"rmt", 411 }, { L"rmtserver", 2416 }, { L"rna", 25471 },
+ { L"rnm", 3844 }, { L"rnmap", 3418 }, { L"rnrp", 2423 }, { L"robcad-lm", 1509 },
+ { L"robix", 9599 }, { L"roboeda", 2920 }, { L"roboer", 2919 }, { L"robotraconteur", 48653 },
+ { L"roce", 4791 }, { L"rockwell-csp1", 2221 }, { L"rockwell-csp2", 2223 }, { L"rocrail", 8051 },
+ { L"roketz", 1730 }, { L"rootd", 1094 }, { L"routematch", 1287 }, { L"router", 520 },
+ { L"roverlog", 3677 }, { L"rp-reputation", 6568 }, { L"rpasswd", 774 }, { L"rpc2portmap", 369 },
+ { L"rpi", 2214 }, { L"rpki-rtr", 323 }, { L"rpki-rtr-tls", 324 }, { L"rprt", 3064 },
+ { L"rrac", 5678 }, { L"rrdp", 5313 }, { L"rrh", 753 }, { L"rrifmm", 1696 },
+ { L"rrilwm", 1695 }, { L"rrimwm", 1694 }, { L"rrirtr", 1693 }, { L"rrisat", 1697 },
+ { L"rrp", 648 }, { L"rs-pias", 13217 }, { L"rs-rmi", 3736 }, { L"rs-status", 45002 },
+ { L"rsap", 1647 }, { L"rsc-robot", 1793 }, { L"rscd", 5750 }, { L"rscs", 10201 },
+ { L"rsf-1", 1195 }, { L"rsh-spx", 222 }, { L"rsip", 4555 }, { L"rsisysaccess", 2752 },
+ { L"rsms", 10201 }, { L"rsmtp", 2390 }, { L"rsom", 2889 }, { L"rsqlserver", 4430 },
+ { L"rsvd", 168 }, { L"rsvp-encap-1", 1698 },
+ { L"rsvp-encap-2", 1699 },
+ { L"rsvp-tunnel", 363 },
+ { L"rsync", 873 }, { L"rt-classmanager", 35004 }, { L"rt-devicemapper", 35003 }, { L"rt-event", 3706 },
+ { L"rt-event-s", 3707 }, { L"rt-helper", 35006 }, { L"rt-labtracker", 35005 }, { L"rt-sound", 35002 },
+ { L"rt-viewer", 35001 }, { L"rtc-pm-port", 3891 }, { L"rtcm-sc104", 2101 }, { L"rtelnet", 107 },
+ { L"rtip", 771 }, { L"rtmp-port", 3500 }, { L"rtnt-1", 3137 }, { L"rtnt-2", 3138 },
+ { L"rtps-dd-mt", 7402 }, { L"rtps-dd-ut", 7401 }, { L"rtps-discovery", 7400 }, { L"rtraceroute", 3765 },
+ { L"rtsclient", 2501 }, { L"rtsp", 554 }, { L"rtsp-alt", 8554 }, { L"rtsps", 322 },
+ { L"rtsserv", 2500 }, { L"rugameonline", 5156 }, { L"rusb-sys-port", 3422 }, { L"rushd", 696 },
+ { L"rvs-isdn-dcp", 2578 }, { L"rwhois", 4321 }, { L"rwp", 30100 }, { L"rxapi", 10010 },
+ { L"rxe", 761 }, { L"rxmon", 1311 }, { L"s-bfd", 7784 }, { L"s-net", 166 },
+ { L"s-openmail", 5767 }, { L"s1-control", 36412 }, { L"s102", 23272 }, { L"s3db", 2278 },
+ { L"s8-client-port", 3153 }, { L"sa-msg-port", 1646 }, { L"sabams", 2760 }, { L"sabarsd", 8401 },
+ { L"sabp-signal", 3452 }, { L"sac", 8097 }, { L"sacred", 1118 }, { L"safetynetp", 40000 },
+ { L"saft", 487 }, { L"sage-best-com1", 14033 }, { L"sage-best-com2", 14034 }, { L"sagectlpanel", 3698 },
+ { L"sagxtsds", 4952 }, { L"sah-lm", 3291 }, { L"sai-sentlm", 2640 }, { L"sais", 1426 },
+ { L"saiscm", 1501 }, { L"saiseh", 1644 }, { L"saism", 1436 }, { L"salient-dtasrv", 5409 },
+ { L"salient-mux", 5422 }, { L"salient-usrmgr", 5410 }, { L"samd", 3275 }, { L"samsung-disc", 30832 },
+ { L"samsung-unidex", 4010 }, { L"sanavigator", 4033 }, { L"sane-port", 6566 }, { L"sanity", 643 },
+ { L"santak-ups", 3038 }, { L"santools", 4079 }, { L"saphostctrl", 1128 }, { L"saphostctrls", 1129 },
+ { L"sapv1", 9875 }, { L"saratoga", 7542 }, { L"saris", 4442 }, { L"sas-remote-hlp", 3755 },
+ { L"sasg", 3744 }, { L"sasggprs", 3964 }, { L"sasp", 3860 }, { L"satvid-datalnk", 3367 },
+ { L"satvid-datalnk", 3368 }, { L"satvid-datalnk", 3369 }, { L"satvid-datalnk", 3370 }, { L"satvid-datalnk", 3371 },
+ { L"sauterdongle", 25576 }, { L"savant", 3391 }, { L"sbackup", 5163 }, { L"sbcap", 29168 },
+ { L"sbi-agent", 3962 }, { L"sbl", 1039 }, { L"sbook", 1349 }, { L"scan-change", 2719 },
+ { L"scanstat-1", 1215 }, { L"scc-security", 582 }, { L"sccip-media", 3499 }, { L"sceanics", 5435 },
+ { L"scenccs", 7129 }, { L"scenidm", 7128 }, { L"scientia-sdb", 1811 }, { L"scientia-ssdb", 2121 },
+ { L"scinet", 7708 }, { L"scintilla", 19007 }, { L"scipticslsrvr", 2577 }, { L"sco-aip", 5307 },
+ { L"sco-dtmgr", 617 }, { L"sco-inetmgr", 615 }, { L"sco-peer-tta", 5427 }, { L"sco-sysmgr", 616 },
+ { L"sco-websrvrmg3", 598 }, { L"sco-websrvrmgr", 620 }, { L"scohelp", 457 }, { L"scoi2odialog", 360 },
+ { L"scol", 1200 }, { L"scoremgr", 2034 }, { L"scotty-disc", 14002 }, { L"scotty-ft", 14000 },
+ { L"scp", 3820 }, { L"scp-config", 10001 }, { L"scpi-raw", 5025 }, { L"scpi-telnet", 5024 },
+ { L"scrabble", 2026 }, { L"screencast", 1368 }, { L"scriptview", 7741 }, { L"scscp", 26133 },
+ { L"scservp", 3637 }, { L"scte104", 5167 }, { L"scte30", 5168 }, { L"sctp-tunneling", 9899 },
+ { L"scup", 6315 }, { L"scup-disc", 6315 }, { L"scx-proxy", 470 }, { L"sd", 9876 },
+ { L"sd-capacity", 2384 }, { L"sd-data", 2385 }, { L"sd-elmd", 1681 }, { L"sd-request", 2384 },
+ { L"sdbproxy", 3562 }, { L"sdclient", 2310 }, { L"sddp", 1163 }, { L"sde-discovery", 5152 },
+ { L"sdfunc", 2046 }, { L"sdhelp", 2308 }, { L"sdl-ets", 5081 }, { L"sdmmp", 5573 },
+ { L"sdnskmp", 558 }, { L"sdo", 3635 }, { L"sdo-ssh", 3897 }, { L"sdo-tls", 3896 },
+ { L"sdp-id-port", 3242 }, { L"sdp-portmapper", 3935 }, { L"sdproxy", 1297 }, { L"sdr", 9010 },
+ { L"sds", 5059 }, { L"sds-admin", 2705 }, { L"sdsc-lm", 1537 }, { L"sdserver", 2309 },
+ { L"sdt", 5568 }, { L"sdt-lmd", 3319 }, { L"sdtvwcam", 24666 }, { L"seagull-ais", 1208 },
+ { L"seagulllms", 1291 }, { L"seaodbc", 2471 }, { L"search", 2010 }, { L"search-agent", 1234 },
+ { L"seaview", 3143 }, { L"sec-ntb-clnt", 32635 }, { L"sec-pc2fax-srv", 9402 }, { L"sec-t4net-clt", 9401 },
+ { L"sec-t4net-srv", 9400 }, { L"seclayer-tcp", 3495 }, { L"seclayer-tls", 3496 }, { L"secrmmsafecopya", 38865 },
+ { L"secure-cfg-svr", 3978 }, { L"secure-mqtt", 8883 }, { L"secure-ts", 9318 }, { L"securitychase", 5399 },
+ { L"seispoc", 2254 }, { L"semantix", 361 }, { L"semaphore", 3255 }, { L"send", 169 },
+ { L"senip", 3898 }, { L"senomix01", 8052 }, { L"senomix02", 8053 }, { L"senomix03", 8054 },
+ { L"senomix04", 8055 }, { L"senomix05", 8056 }, { L"senomix06", 8057 }, { L"senomix07", 8058 },
+ { L"senomix08", 8059 }, { L"sent-lm", 2316 }, { L"sentinel", 3588 }, { L"sentinel-ent", 3712 },
+ { L"sentinel-lm", 5093 }, { L"sentinelsrm", 1947 }, { L"sentlm-srv2srv", 5099 }, { L"sep", 2089 },
+ { L"seraph", 4076 }, { L"sercomm-scadmin", 6108 }, { L"sercomm-wlink", 2235 }, { L"serialgateway", 1243 },
+ { L"server-find", 8351 }, { L"servergraph", 1251 }, { L"serverstart", 9213 }, { L"serverview-as", 3169 },
+ { L"serverview-asn", 3170 }, { L"serverview-gf", 3171 }, { L"serverview-icc", 3173 }, { L"serverview-rm", 3172 },
+ { L"serverviewdbms", 9212 }, { L"serverwsd2", 5362 }, { L"servexec", 2021 }, { L"service-ctrl", 2367 },
+ { L"servicemeter", 2603 }, { L"servicetags", 6481 }, { L"servistaitsm", 3636 }, { L"servserv", 2011 },
+ { L"servstat", 633 }, { L"sesi-lm", 1714 }, { L"set", 257 }, { L"sf-lm", 4546 },
+ { L"sflm", 3162 }, { L"sflow", 6343 }, { L"sfm-db-server", 5636 }, { L"sfmsso", 5635 },
+ { L"sfs-config", 452 }, { L"sfs-smp-net", 451 }, { L"sftdst-port", 3230 }, { L"sftp", 115 },
+ { L"sftsrv", 1303 }, { L"sftu", 3326 }, { L"sg-lm", 1659 }, { L"sgcip", 16950 },
+ { L"sgcp", 440 }, { L"sge-execd", 6445 }, { L"sge-qmaster", 6444 }, { L"sgi-arrayd", 5434 },
+ { L"sgi-dmfmgr", 11109 }, { L"sgi-esphttp", 5554 }, { L"sgi-eventmond", 5553 }, { L"sgi-lk", 11106 },
+ { L"sgi-soap", 11110 }, { L"sgi-storman", 1178 }, { L"sgmp", 153 }, { L"sgmp-traps", 160 },
+ { L"sgsap", 29118 }, { L"shadowserver", 2027 }, { L"shadowstream", 4366 }, { L"shaperai", 43210 },
+ { L"shaperai-disc", 43210 }, { L"shareapp", 3595 }, { L"sharp-server", 3617 }, { L"shell", 514 },
+ { L"shilp", 2049 }, { L"shiprush-d-ch", 5841 }, { L"shiprush-db-svr", 3841 }, { L"shiva-confsrvr", 1651 },
+ { L"shivadiscovery", 1502 }, { L"shivahose", 1549 }, { L"shivasound", 1549 }, { L"shockwave", 1626 },
+ { L"shockwave2", 1257 }, { L"shofar", 4105 }, { L"shrewd-control", 22335 }, { L"shrewd-stream", 22335 },
+ { L"shrinkwrap", 358 }, { L"sia-ctrl-plane", 4787 }, { L"siam", 498 }, { L"sicct", 4742 },
+ { L"sicct-sdp", 4742 }, { L"siebel-ns", 2320 }, { L"siemensgsm", 28240 }, { L"sieve", 4190 },
+ { L"sift-uft", 608 }, { L"sightline", 1645 }, { L"sigma-port", 3614 }, { L"signacert-agent", 5032 },
+ { L"signal", 2974 }, { L"signet-ctf", 2733 }, { L"siipat", 1733 }, { L"silc", 706 },
+ { L"silhouette", 7500 }, { L"silkmeter", 5461 }, { L"silkp1", 2829 }, { L"silkp2", 2830 },
+ { L"silkp3", 2831 }, { L"silkp4", 2832 }, { L"silverpeakcomm", 4164 }, { L"silverpeakpeer", 4163 },
+ { L"silverplatter", 416 }, { L"sim-control", 3110 }, { L"simba-cs", 1543 }, { L"simbaexpress", 1583 },
+ { L"simbaservices", 1599 }, { L"simco", 7626 }, { L"simctlp", 2857 }, { L"simon", 4753 },
+ { L"simon-disc", 4753 }, { L"simp-all", 1959 }, { L"simple-push", 3687 }, { L"simple-push-s", 3688 },
+ { L"simple-tx-rx", 2257 }, { L"simplement-tie", 2756 }, { L"simplifymedia", 8087 }, { L"simslink", 2676 },
+ { L"sip", 5060 }, { L"sips", 5061 }, { L"sis-emt", 2545 }, { L"sitaradir", 2631 },
+ { L"sitaramgmt", 2630 }, { L"sitaraserver", 2629 }, { L"sitewatch", 3792 }, { L"sitewatch-s", 3766 },
+ { L"six-degrees", 3611 }, { L"sixchat", 4605 }, { L"sixnetudr", 1658 }, { L"sixtrak", 1594 },
+ { L"sixxsconfig", 3874 }, { L"skip-cert-recv", 6455 }, { L"skip-cert-send", 6456 }, { L"skip-mc-gikreq", 1660 },
+ { L"skronk", 460 }, { L"sky-transport", 3556 }, { L"skytelnet", 1618 }, { L"slc-ctrlrloops", 2827 },
+ { L"slc-systemlog", 2826 }, { L"slim-devices", 3483 }, { L"slingshot", 1705 }, { L"slinkysearch", 1225 },
+ { L"slinterbase", 3065 }, { L"slm-api", 1606 }, { L"slp", 1605 }, { L"slp-notify", 1847 },
+ { L"slscc", 4408 }, { L"slslavemon", 3102 }, { L"slush", 1966 }, { L"sm-disc", 4174 },
+ { L"sm-pas-1", 2938 }, { L"sm-pas-2", 2939 }, { L"sm-pas-3", 2940 }, { L"sm-pas-4", 2941 },
+ { L"sm-pas-5", 2942 }, { L"sma-spw", 9522 }, { L"smaclmgr", 4660 }, { L"smakynet", 122 },
+ { L"smap", 3731 }, { L"smar-se-port1", 4987 }, { L"smar-se-port2", 4988 }, { L"smart-diagnose", 2721 },
+ { L"smart-install", 4786 }, { L"smart-lm", 1608 }, { L"smartcard-port", 3516 }, { L"smartcard-tls", 4116 },
+ { L"smartpackets", 3218 }, { L"smartsdp", 426 }, { L"smauth-port", 3929 }, { L"smbdirect", 5445 },
+ { L"smc-admin", 6787 }, { L"smc-http", 6788 }, { L"smc-https", 6789 }, { L"smc-jmx", 6786 },
+ { L"smcluster", 4174 }, { L"smile", 3670 }, { L"smip", 7734 }, { L"smntubootstrap", 2613 },
+ { L"smpnameres", 901 }, { L"smpp", 2775 }, { L"smpppd", 3185 }, { L"smpte", 420 },
+ { L"sms-chat", 2703 }, { L"sms-rcinfo", 2701 }, { L"sms-remctrl", 2704 }, { L"sms-xfer", 2702 },
+ { L"smsd", 596 }, { L"smsp", 413 }, { L"smsqp", 11201 }, { L"smtp", 25 },
+ { L"smux", 199 }, { L"smwan", 3979 }, { L"sna-cs", 1553 }, { L"snac", 3536 },
+ { L"snagas", 108 }, { L"snap", 4752 }, { L"snapd", 2599 }, { L"snapenetio", 22000 },
+ { L"snapp", 2333 }, { L"snare", 509 }, { L"snaresecure", 1684 }, { L"sncp", 7560 },
+ { L"snifferclient", 2452 }, { L"snifferdata", 2892 }, { L"snifferserver", 2533 }, { L"snip-slave", 33656 },
+ { L"snmp", 161 }, { L"snmp-tcp-port", 1993 }, { L"snmpdtls", 10161 }, { L"snmpdtls-trap", 10162 },
+ { L"snmpssh", 5161 }, { L"snmpssh-trap", 5162 }, { L"snmptls", 10161 }, { L"snmptls-trap", 10162 },
+ { L"snmptrap", 162 }, { L"snpp", 444 }, { L"sns-admin", 2658 }, { L"sns-agent", 5417 },
+ { L"sns-channels", 3380 }, { L"sns-dispatcher", 2657 }, { L"sns-gateway", 5416 }, { L"sns-protocol", 2409 },
+ { L"sns-query", 2659 }, { L"sns-quote", 1967 }, { L"snss", 11171 }, { L"sntlkeyssrvr", 9450 },
+ { L"sntp-heartbeat", 580 }, { L"soagateway", 5250 }, { L"soap-beep", 605 }, { L"soap-http", 7627 },
+ { L"socalia", 5100 }, { L"social-alarm", 5146 }, { L"socks", 1080 }, { L"socorfs", 3379 },
+ { L"socp-c", 4882 }, { L"socp-t", 4881 }, { L"softaudit", 3419 }, { L"softcm", 6110 },
+ { L"softdataphone", 1621 }, { L"softpc", 215 }, { L"softrack-meter", 3884 }, { L"solaris-audit", 16162 },
+ { L"solera-epmap", 2132 }, { L"solera-lpn", 4738 }, { L"solid-e-engine", 1964 }, { L"solid-mux", 1029 },
+ { L"solve", 2636 }, { L"sonar", 572 }, { L"sonardata", 2863 }, { L"soniqsync", 3803 },
+ { L"sonus", 2653 }, { L"sonus-logging", 2290 }, { L"sonuscallsig", 2569 }, { L"sophia-lm", 1408 },
+ { L"sops", 3944 }, { L"sor-update", 3922 }, { L"sos", 3838 }, { L"sossd-agent", 7982 },
+ { L"sossd-collect", 7981 }, { L"sossd-disc", 7982 }, { L"sossecollector", 3166 }, { L"soundsvirtual", 17185 },
+ { L"spamtrap", 2568 }, { L"spandataport", 3193 }, { L"spc", 6111 }, { L"spcsdlobby", 2888 },
+ { L"spdp", 5794 }, { L"spdy", 6121 }, { L"spearway", 2440 }, { L"spectardata", 3834 },
+ { L"spectardb", 3835 }, { L"spectraport", 3851 }, { L"speedtrace", 33334 }, { L"speedtrace-disc", 33334 },
+ { L"sphinxapi", 9312 }, { L"sphinxql", 9306 }, { L"spice", 1923 }, { L"spike", 4683 },
+ { L"spiral-admin", 3438 }, { L"splitlock", 3606 }, { L"splitlock-gw", 3647 }, { L"spmp", 656 },
+ { L"spock", 2507 }, { L"spocp", 4751 }, { L"spramsca", 5769 }, { L"spramsd", 5770 },
+ { L"spremotetablet", 46998 }, { L"sps-tunnel", 2876 }, { L"spsc", 478 }, { L"spss", 5443 },
+ { L"spss-lm", 1759 }, { L"spt-automation", 5814 }, { L"sptx", 40404 }, { L"spugna", 3807 },
+ { L"spw-dialer", 3796 }, { L"spw-dnspreload", 3849 }, { L"spytechphone", 8192 }, { L"sqdr", 2728 },
+ { L"sql-net", 150 }, { L"sql-net", 66 }, { L"sqlexec", 9088 }, { L"sqlexec-ssl", 9089 },
+ { L"sqlserv", 118 }, { L"sqlsrv", 156 }, { L"src", 200 }, { L"srcp", 4303 },
+ { L"srdp", 3942 }, { L"srmp", 193 }, { L"srp-feedback", 2737 }, { L"srssend", 362 },
+ { L"sruth", 38800 }, { L"srvc-registry", 3018 }, { L"ss-idi", 20013 }, { L"ss-idi-disc", 20012 },
+ { L"ss7ns", 477 }, { L"ssad", 4750 }, { L"ssc-agent", 2967 }, { L"sscan", 3853 },
+ { L"ssdispatch", 3430 }, { L"ssdp", 1900 }, { L"ssdtp", 6071 }, { L"sse-app-config", 3852 },
+ { L"ssh", 22 }, { L"ssh-mgmt", 17235 }, { L"sshell", 614 }, { L"sslp", 1750 },
+ { L"ssm-cssps", 2478 }, { L"ssm-cvs", 2477 }, { L"ssm-els", 2479 }, { L"ssmc", 2187 },
+ { L"ssmd", 2187 }, { L"ssmpp", 3550 }, { L"sso-control", 2711 }, { L"sso-service", 2710 },
+ { L"ssowatch", 3644 }, { L"ssp", 3249 }, { L"ssp-client", 7801 }, { L"ssql", 3352 },
+ { L"ssr-servermgr", 45966 }, { L"ssrip", 3318 }, { L"ssslic-mgr", 1203 }, { L"ssslog-mgr", 1204 },
+ { L"sst", 266 }, { L"sstp-1", 7743 }, { L"sstp-2", 9801 }, { L"sstsys-lm", 1692 },
+ { L"stanag-5066", 5066 }, { L"starbot", 2838 }, { L"starfish", 3981 }, { L"stargatealerts", 1654 },
+ { L"starquiz-port", 3526 }, { L"stars", 4131 }, { L"starschool", 2270 }, { L"start-network", 3615 },
+ { L"startron", 1057 }, { L"stat-cc", 4158 }, { L"stat-results", 4156 }, { L"stat-scanner", 4157 },
+ { L"statsci1-lm", 6144 }, { L"statsci2-lm", 6145 }, { L"statsrv", 133 }, { L"statusd", 5414 },
+ { L"stdptc", 2154 }, { L"ste-smsc", 1836 }, { L"stgxfws", 1226 }, { L"sti-envision", 1312 },
+ { L"stm-pproc", 3080 }, { L"stmf", 501 }, { L"stone-design-1", 1492 }, { L"stonefalls", 2986 },
+ { L"storman", 4178 }, { L"storview", 9293 }, { L"streamcomm-ds", 9612 }, { L"street-stream", 1736 },
+ { L"streetperfect", 1330 }, { L"streettalk", 566 }, { L"streletz", 6344 }, { L"stresstester", 5397 },
+ { L"strexec-d", 5026 }, { L"strexec-s", 5027 }, { L"stryker-com", 3854 }, { L"stss", 3090 },
+ { L"stt", 1607 }, { L"sttunnel", 7471 }, { L"stun", 3478 }, { L"stun-behavior", 3478 },
+ { L"stun-behaviors", 5349 }, { L"stun-p1", 1990 }, { L"stun-p2", 1991 }, { L"stun-p3", 1992 },
+ { L"stun-port", 1994 }, { L"stuns", 5349 }, { L"stvp", 3158 }, { L"stx", 527 },
+ { L"su-mit-tg", 89 }, { L"sua", 14001 }, { L"submission", 587 }, { L"submit", 773 },
+ { L"submitserver", 2028 }, { L"subntbcst-tftp", 247 }, { L"sugp", 1905 }, { L"suitcase", 2903 },
+ { L"suitjd", 3354 }, { L"sum", 6551 }, { L"sun-as-iiops", 3708 }, { L"sun-as-iiops-ca", 3808 },
+ { L"sun-as-jmxrmi", 8686 }, { L"sun-as-jpda", 9191 }, { L"sun-as-nodeagt", 4850 }, { L"sun-dr", 665 },
+ { L"sun-lm", 7588 }, { L"sun-mc-grp", 5306 }, { L"sun-sea-port", 16161 }, { L"sun-sr-admin", 6489 },
+ { L"sun-sr-http", 6480 }, { L"sun-sr-https", 6443 }, { L"sun-sr-iiop", 6485 }, { L"sun-sr-iiop-aut", 6487 },
+ { L"sun-sr-iiops", 6486 }, { L"sun-sr-jms", 6484 }, { L"sun-sr-jmx", 6488 }, { L"sun-user-https", 7677 },
+ { L"suncacao-csa", 11164 }, { L"suncacao-jmxmp", 11162 }, { L"suncacao-rmi", 11163 }, { L"suncacao-snmp", 11161 },
+ { L"suncacao-websvc", 11165 }, { L"sunclustergeo", 2084 }, { L"sunclustermgr", 1097 }, { L"sunfm-port", 3934 },
+ { L"sunlps-http", 3816 }, { L"sunproxyadmin", 8081 }, { L"sunrpc", 111 }, { L"sunscalar-dns", 1870 },
+ { L"sunscalar-svc", 1860 }, { L"SunVTS-RMI", 6483 }, { L"sunwebadmin", 8800 }, { L"sunwebadmins", 8989 },
+ { L"supdup", 95 }, { L"supercell", 7967 }, { L"supermon", 2709 }, { L"sur-meas", 243 },
+ { L"surebox", 5453 }, { L"surf", 1010 }, { L"surfcontrolcpa", 3909 }, { L"surfpass", 5030 },
+ { L"surveyinst", 3212 }, { L"suucp", 4031 }, { L"svbackup", 8405 }, { L"svcloud", 8404 },
+ { L"svdrp", 6419 }, { L"svdrp-disc", 6419 }, { L"svn", 3690 }, { L"svnet", 3413 },
+ { L"svnetworks", 2973 }, { L"svrloc", 427 }, { L"svs-omagent", 1625 }, { L"sw-orion", 17777 },
+ { L"swa-1", 9023 }, { L"swa-2", 9024 }, { L"swa-3", 9025 }, { L"swa-4", 9026 },
+ { L"swdtp", 10104 }, { L"swdtp-sv", 10009 }, { L"sweetware-apps", 1221 }, { L"swift-rvf", 97 },
+ { L"swiftnet", 1751 }, { L"swismgr1", 6963 }, { L"swismgr2", 6964 }, { L"swispol", 6966 },
+ { L"swistrap", 6965 }, { L"swldy-sias", 1250 }, { L"swr-port", 3491 }, { L"swrmi", 1866 },
+ { L"swtp-port1", 9281 }, { L"swtp-port2", 9282 }, { L"swx", 7300 }, { L"swx", 7301 },
+ { L"swx", 7302 }, { L"swx", 7303 }, { L"swx", 7304 }, { L"swx", 7305 },
+ { L"swx", 7306 }, { L"swx", 7307 }, { L"swx", 7308 }, { L"swx", 7309 },
+ { L"swx", 7310 }, { L"swx", 7311 }, { L"swx", 7312 }, { L"swx", 7313 },
+ { L"swx", 7314 }, { L"swx", 7315 }, { L"swx", 7316 }, { L"swx", 7317 },
+ { L"swx", 7318 }, { L"swx", 7319 }, { L"swx", 7320 }, { L"swx", 7321 },
+ { L"swx", 7322 }, { L"swx", 7323 }, { L"swx", 7324 }, { L"swx", 7325 },
+ { L"swx", 7326 }, { L"swx", 7327 }, { L"swx", 7328 }, { L"swx", 7329 },
+ { L"swx", 7330 }, { L"swx", 7331 }, { L"swx", 7332 }, { L"swx", 7333 },
+ { L"swx", 7334 }, { L"swx", 7335 }, { L"swx", 7336 }, { L"swx", 7337 },
+ { L"swx", 7338 }, { L"swx", 7339 }, { L"swx", 7340 }, { L"swx", 7341 },
+ { L"swx", 7342 }, { L"swx", 7343 }, { L"swx", 7344 }, { L"swx", 7345 },
+ { L"swx", 7346 }, { L"swx", 7347 }, { L"swx", 7348 }, { L"swx", 7349 },
+ { L"swx", 7350 }, { L"swx", 7351 }, { L"swx", 7352 }, { L"swx", 7353 },
+ { L"swx", 7354 }, { L"swx", 7355 }, { L"swx", 7356 }, { L"swx", 7357 },
+ { L"swx", 7358 }, { L"swx", 7359 }, { L"swx-gate", 4538 }, { L"swxadmin", 5043 },
+ { L"sxmp", 3273 }, { L"sxuptp", 19540 }, { L"syam-agent", 3894 }, { L"syam-smc", 3895 },
+ { L"syam-webserver", 3930 }, { L"sybase-sqlany", 1498 }, { L"sybaseanywhere", 2638 }, { L"sybasedbsynch", 2439 },
+ { L"sybasesrvmon", 4950 }, { L"sychrond", 3723 }, { L"symantec-sfdb", 5629 }, { L"symantec-sim", 3547 },
+ { L"symb-sb-port", 3923 }, { L"symplex", 1507 }, { L"synapse", 2880 }, { L"synapse-nhttp", 8280 },
+ { L"synapse-nhttps", 8243 }, { L"synapsis-edge", 5008 }, { L"sync-em7", 7707 }, { L"synchromesh", 4548 },
+ { L"synchronet-db", 6100 }, { L"synchronet-rtc", 6101 }, { L"synchronet-upd", 6102 }, { L"synchronite", 4106 },
+ { L"syncserver", 2647 }, { L"syncserverssl", 2679 }, { L"synctest", 45045 }, { L"synel-data", 3734 },
+ { L"synoptics-trap", 412 }, { L"synotics-broker", 392 }, { L"synotics-relay", 391 }, { L"sype-transport", 9911 },
+ { L"syscomlan", 1065 }, { L"syserverremote", 6418 }, { L"sysinfo-sp", 11967 }, { L"syslog", 514 },
+ { L"syslog-conn", 601 }, { L"syslog-tls", 6514 }, { L"sysopt", 3281 }, { L"sysorb", 3241 },
+ { L"sysrqd", 4094 }, { L"sysscanner", 3251 }, { L"systat", 11 }, { L"system-monitor", 2609 },
+ { L"systemics-sox", 5406 }, { L"t1-e1-over-ip", 3175 }, { L"t128-gateway", 1627 }, { L"t1distproc", 1274 },
+ { L"t1distproc60", 32249 }, { L"t2-brm", 7933 }, { L"t2-drm", 7932 }, { L"t5-straton", 11173 },
+ { L"tabula", 1437 }, { L"tacacs", 49 }, { L"tacacs-ds", 65 }, { L"tacnews", 98 },
+ { L"tacticalauth", 2392 }, { L"taep-as-svc", 5111 }, { L"tag-pm", 5073 }, { L"tag-ups-1", 3573 },
+ { L"taiclock", 4014 }, { L"tal-pod", 6149 }, { L"talarian-mcast1", 4015 }, { L"talarian-mcast2", 4016 },
+ { L"talarian-mcast3", 4017 }, { L"talarian-mcast4", 4018 }, { L"talarian-mcast5", 4019 }, { L"talarian-mqs", 2493 },
+ { L"talarian-tcp", 5101 }, { L"talarian-udp", 5101 }, { L"taligent-lm", 1475 }, { L"talikaserver", 22763 },
+ { L"talk", 517 }, { L"talnet", 1838 }, { L"talon-disc", 7011 }, { L"talon-engine", 7012 },
+ { L"talon-webserver", 7015 }, { L"tambora", 9020 }, { L"tams", 2726 }, { L"tapestry", 1922 },
+ { L"tapeware", 3817 }, { L"tappi-boxnet", 2306 }, { L"tarantella", 3144 }, { L"targus-getdata", 5200 },
+ { L"targus-getdata1", 5201 }, { L"targus-getdata2", 5202 }, { L"targus-getdata3", 5203 }, { L"tarp", 6442 },
+ { L"taserver", 3552 }, { L"taskman-port", 2470 }, { L"taskmaster2000", 2402 }, { L"taskmaster2000", 2403 },
+ { L"tasp-net", 25900 }, { L"taurus-wh", 1610 }, { L"tbrpf", 712 }, { L"tcc-http", 24680 },
+ { L"tcim-control", 2729 }, { L"tclprodebugger", 2576 }, { L"tcoaddressbook", 1977 }, { L"tcoflashagent", 1975 },
+ { L"tcoregagent", 1976 }, { L"tcp-id-port", 1999 }, { L"tcpdataserver", 3805 }, { L"tcpmux", 1 },
+ { L"tcpnethaspsrv", 475 }, { L"td-postman", 1049 }, { L"td-replica", 268 }, { L"td-service", 267 },
+ { L"tdaccess", 2910 }, { L"tdmoip", 2142 }, { L"tdp-suite", 1814 }, { L"teamcoherence", 9222 },
+ { L"tec5-sdctp", 9668 }, { L"teedtap", 559 }, { L"tekpls", 1946 }, { L"telaconsole", 5428 },
+ { L"telefinder", 1474 }, { L"telelpathattack", 5011 }, { L"telelpathstart", 5010 }, { L"teleniumdaemon", 2060 },
+ { L"telesis-licman", 1380 }, { L"telindus", 1728 }, { L"tell", 754 }, { L"tellumat-nms", 3549 },
+ { L"telnet", 23 }, { L"telnetcpcd", 3696 }, { L"telnets", 992 }, { L"telops-lmd", 7491 },
+ { L"tempest-port", 11600 }, { L"tempo", 526 }, { L"tenfold", 658 }, { L"tentacle", 41121 },
+ { L"terabase/icq", 4000 }, { L"teradataordbms", 8002 }, { L"teredo", 3544 }, { L"terminaldb", 2008 },
+ { L"terminaldb", 2018 }, { L"tesla-sys-msg", 7631 }, { L"tetrinet", 31457 }, { L"texai", 5048 },
+ { L"texar", 333 }, { L"tftp", 69 }, { L"tftp-mcast", 1758 }, { L"tftps", 3713 },
+ { L"tgcconnect", 4146 }, { L"tgp", 1223 }, { L"thermo-calc", 6201 }, { L"theta-lm", 2296 },
+ { L"thrp", 3963 }, { L"thrtx", 4139 }, { L"tht-treasure", 1832 }, { L"ticf-1", 492 },
+ { L"ticf-2", 493 }, { L"tick-port", 3200 }, { L"tidp", 7548 }, { L"tig", 3943 },
+ { L"tigv2", 4124 }, { L"timbuktu", 407 }, { L"timbuktu-srv1", 1417 }, { L"timbuktu-srv2", 1418 },
+ { L"timbuktu-srv3", 1419 }, { L"timbuktu-srv4", 1420 }, { L"time", 37 }, { L"timed", 525 },
+ { L"timeflies", 1362 }, { L"timelot", 3243 }, { L"timestenbroker", 3754 }, { L"tinc", 655 },
+ { L"tinymessage", 5104 }, { L"tip-app-server", 3160 }, { L"tip2", 3372 }, { L"tipc", 6118 },
+ { L"tivoconnect", 2190 }, { L"tivoli-npm", 1965 }, { L"tksocket", 2915 }, { L"tl-ipcproxy", 4176 },
+ { L"tl1", 2361 }, { L"tl1-lv", 3081 }, { L"tl1-raw", 3082 }, { L"tl1-raw-ssl", 6251 },
+ { L"tl1-ssh", 6252 }, { L"tl1-telnet", 3083 }, { L"tlisrv", 1527 }, { L"tmesis-upshot", 2798 },
+ { L"tmi", 8300 }, { L"tmo-icon-sync", 5583 }, { L"tmophl7mts", 20046 }, { L"tmosms0", 5580 },
+ { L"tmosms1", 5581 }, { L"tn-timing", 2739 }, { L"tn-tl-fd1", 476 }, { L"tn-tl-fd2", 1584 },
+ { L"tn-tl-r1", 1580 }, { L"tn-tl-r2", 1580 }, { L"tn-tl-w1", 474 }, { L"tn-tl-w2", 474 },
+ { L"tnETOS", 377 }, { L"tnmpv2", 3686 }, { L"tnos-dp", 7902 }, { L"tnos-dps", 7903 },
+ { L"tnos-sp", 7901 }, { L"tnp", 8321 }, { L"tnp-discover", 8320 }, { L"tnp1-port", 4024 },
+ { L"tns-adv", 3309 }, { L"tns-cml", 590 }, { L"tns-server", 3308 }, { L"toad", 2669 },
+ { L"toad-bi-appsrvr", 8066 }, { L"tolfab", 20167 }, { L"tolteces", 4375 }, { L"tomato-springs", 3040 },
+ { L"tonidods", 24465 }, { L"topflow", 2885 }, { L"topflow-ssl", 3885 }, { L"topovista-data", 3906 },
+ { L"topx", 2436 }, { L"toruxserver", 5153 }, { L"touchnetplus", 2158 }, { L"tpcsrvr", 2078 },
+ { L"tpdu", 1430 }, { L"tpip", 594 }, { L"tpmd", 1906 }, { L"tqdata", 2700 },
+ { L"tr-rsrb-p1", 1987 }, { L"tr-rsrb-p2", 1988 }, { L"tr-rsrb-p3", 1989 }, { L"tr-rsrb-port", 1996 },
+ { L"traceroute", 33434 }, { L"track", 20670 }, { L"tragic", 2642 }, { L"traingpsdata", 9277 },
+ { L"tram", 4567 }, { L"transact", 1869 }, { L"transmit-port", 5282 }, { L"trap", 4020 },
+ { L"trap-daemon", 3600 }, { L"trap-port", 3857 }, { L"trap-port-mom", 3858 }, { L"traversal", 4678 },
+ { L"travsoft-ipx-t", 2644 }, { L"trc-netpoll", 2405 }, { L"treehopper", 3959 }, { L"trendchip-dcp", 3608 },
+ { L"tributary", 2580 }, { L"trident-data", 7727 }, { L"trim", 1137 }, { L"trim-event", 4322 },
+ { L"trim-ice", 4323 }, { L"triomotion", 3240 }, { L"trip", 6069 }, { L"tripe", 4070 },
+ { L"tripwire", 1169 }, { L"triquest-lm", 1588 }, { L"trisoap", 10200 }, { L"trispen-sra", 9555 },
+ { L"tritium-can", 4876 }, { L"trivnet1", 8200 }, { L"trivnet2", 8201 }, { L"trnsprntproxy", 3346 },
+ { L"troff", 2014 }, { L"trp", 2156 }, { L"truckstar", 4725 }, { L"truecm", 8804 },
+ { L"trusted-web", 3011 }, { L"trustestablish", 2573 }, { L"tsa", 6689 }, { L"tsaf", 12753 },
+ { L"tsb", 2741 }, { L"tsb2", 2742 }, { L"tscchat", 2330 }, { L"tsdos390", 1237 },
+ { L"tserver", 450 }, { L"tsilb", 2489 }, { L"tsp", 3653 }, { L"tsrmagt", 2077 },
+ { L"tsspmap", 1568 }, { L"ttat3lb", 3579 }, { L"ttc", 2483 }, { L"ttc-etap", 2675 },
+ { L"ttc-etap-ds", 2978 }, { L"ttc-etap-ns", 2977 }, { L"ttc-ssl", 2484 }, { L"ttcmremotectrl", 3468 },
+ { L"ttg-protocol", 2862 }, { L"ttl-publisher", 5462 }, { L"ttlpriceproxy", 5463 }, { L"ttnrepository", 2943 },
+ { L"ttntspauto", 3474 }, { L"ttyinfo", 2012 }, { L"tunalyzer", 5748 }, { L"tunatic", 5747 },
+ { L"tungsten-http", 9762 }, { L"tungsten-https", 9443 }, { L"tunnel", 604 }, { L"tunstall-lwp", 5197 },
+ { L"tunstall-pnc", 1846 }, { L"turbonote-1", 39681 }, { L"turbonote-2", 34249 }, { L"turn", 3478 },
+ { L"turns", 5349 }, { L"tvbus", 2191 }, { L"tvdumtray-port", 3492 }, { L"tve-announce", 2670 },
+ { L"tvnetworkvideo", 3791 }, { L"tvpm", 21800 }, { L"tw-auth-key", 27999 }, { L"twamp-control", 862 },
+ { L"twcss", 3428 }, { L"twds", 8937 }, { L"twrpc", 3479 }, { L"twsdss", 3012 },
+ { L"u-dbap", 3584 }, { L"ua-secureagent", 19194 }, { L"uaac", 145 }, { L"uacs", 2768 },
+ { L"uadtc", 2767 }, { L"uaiact", 1470 }, { L"uarps", 219 }, { L"ub-dns-control", 8953 },
+ { L"ubroker", 7887 }, { L"ubxd", 4034 }, { L"ucentric-ds", 2879 }, { L"ucontrol", 13894 },
+ { L"udp-sr-port", 1624 }, { L"udpradio", 1833 }, { L"udrawgraph", 2542 }, { L"udrive", 1867 },
+ { L"udt-os", 1382 },
+ { L"udt-os", 3900 }, { L"uec", 8778 }, { L"ufastro-instr", 3720 }, { L"ufmp", 6306 },
+ { L"uis", 390 }, { L"ulistproc", 372 }, { L"ulp", 522 }, { L"ulpnet", 483 },
+ { L"ultimad", 1737 }, { L"ultrabac", 1910 }, { L"ultraseek-http", 8765 }, { L"ultrex", 1327 },
+ { L"uma", 144 }, { L"uma", 1797 }, { L"umm-port", 3098 }, { L"ums", 2248 },
+ { L"umsp", 2110 }, { L"unbind-cluster", 2138 }, { L"undo-lm", 5281 }, { L"unet", 1189 },
+ { L"unglue", 2655 }, { L"unicall", 4343 }, { L"unicontrol", 2437 }, { L"unicontrol", 2499 },
+ { L"unidata-ldm", 388 }, { L"unieng", 5730 }, { L"unify", 181 }, { L"unify-adapter", 1889 },
+ { L"unify-debug", 4867 }, { L"unifyadmin", 2696 }, { L"unihub-server", 2357 }, { L"unikeypro", 4127 },
+ { L"unimobilectrl", 2927 }, { L"uniport", 9629 }, { L"unisql", 1978 }, { L"unisql-java", 1979 },
+ { L"unisys-eportal", 37654 }, { L"unisys-lm", 1823 }, { L"unitary", 126 }, { L"unite", 3217 },
+ { L"univ-appserver", 1233 }, { L"universe-suite", 4184 }, { L"univision", 2820 }, { L"unix-status", 1957 },
+ { L"unizensus", 1151 }, { L"unot", 5055 }, { L"uohost", 3314 }, { L"uorb", 3313 },
+ { L"upgrade", 2537 }, { L"upnotifyp", 4445 }, { L"upnotifyps", 3356 }, { L"ups", 401 },
+ { L"ups-engine", 3664 }, { L"ups-onlinet", 7010 }, { L"upsnotifyprot", 2648 }, { L"upstriggervsw", 3786 },
+ { L"urbisnet", 2745 }, { L"urd", 465 }, { L"urld-port", 3534 }, { L"urm", 606 },
+ { L"us-cli", 8082 }, { L"us-gv", 1370 }, { L"us-srv", 8083 }, { L"user-manager", 3272 },
+ { L"usicontentpush", 7998 }, { L"utcd", 1506 }, { L"utime", 519 }, { L"utmpcd", 431 },
+ { L"utmpsd", 430 }, { L"utsftp", 2529 }, { L"uucp", 540 }, { L"uucp-path", 117 },
+ { L"uucp-rlogin", 541 }, { L"uuidgen", 697 }, { L"v-one-spp", 3845 }, { L"v2g-secc", 15118 },
+ { L"v5ua", 5675 }, { L"va-pacbase", 3676 }, { L"vacdsm-app", 671 }, { L"vacdsm-sws", 670 },
+ { L"vad", 14154 }, { L"valisys-lm", 1457 }, { L"vantronix-mgmt", 8034 }, { L"vaprtm", 3654 },
+ { L"varadero-0", 4837 }, { L"varadero-1", 4838 }, { L"varadero-2", 4839 }, { L"vat", 3456 },
+ { L"vat-control", 3457 }, { L"vatata", 4188 }, { L"vatp", 690 }, { L"vaultbase", 1771 },
+ { L"vce", 11111 }, { L"vchat", 1168 }, { L"vcmp", 2426 }, { L"vcnet-link-v10", 2554 },
+ { L"vcom-tunnel", 8001 }, { L"vcrp", 3073 }, { L"vcs-app", 14141 }, { L"vcscmd", 14150 },
+ { L"vdab", 1775 }, { L"vdmplay", 1707 }, { L"vemmi", 575 }, { L"venus", 2430 },
+ { L"venus-se", 2431 }, { L"veracity", 1062 }, { L"vergencecm", 2771 }, { L"verismart", 3270 },
+ { L"veritas-pbx", 1556 }, { L"veritas-tcp1", 2802 }, { L"veritas-ucl", 2148 }, { L"veritas-udp1", 2802 },
+ { L"veritas-vis1", 2993 }, { L"veritas-vis2", 2994 }, { L"veronica", 2770 }, { L"versa-tek", 2610 },
+ { L"versatalk", 3738 }, { L"versiera", 9050 }, { L"vestasdlp", 17184 }, { L"vettcp", 78 },
+ { L"vfbp", 6678 }, { L"vfbp-disc", 6678 }, { L"vfmobile", 5646 }, { L"vfo", 1056 },
+ { L"vhd", 3802 }, { L"vid", 769 }, { L"video-activmail", 1398 }, { L"videobeans", 3058 },
+ { L"videotex", 516 }, { L"videte-cipc", 1927 }, { L"vidigo", 3231 }, { L"vids-avtp", 1853 },
+ { L"vieo-fe", 3245 }, { L"vinainstall", 4344 }, { L"vipera", 12012 }, { L"vipera-ssl", 12013 },
+ { L"vipremoteagent", 3752 }, { L"virprot-lm", 7121 }, { L"virtual-places", 1533 }, { L"virtual-time", 1852 },
+ { L"virtualtape", 2386 }, { L"virtualuser", 5423 }, { L"visd", 9284 }, { L"visicron-vs", 4307 },
+ { L"visinet-gui", 3601 }, { L"vision-elmd", 6673 }, { L"vision-server", 6672 }, { L"visionpyramid", 1247 },
+ { L"visitview", 1631 }, { L"vista-4gl", 24249 }, { L"vistium-share", 1545 }, { L"vitalanalysis", 2474 },
+ { L"viziblebrowser", 1868 }, { L"vlsi-lm", 1500 }, { L"vmnet", 175 }, { L"vmodem", 3141 },
+ { L"vmpwscs", 214 }, { L"vmrdp", 2179 }, { L"vmsvc", 7024 }, { L"vmsvc-2", 7025 },
+ { L"vmware-fdm", 8182 }, { L"vnas", 577 }, { L"vnetd", 13724 }, { L"vns-tp", 7802 },
+ { L"vnsstr", 3321 }, { L"vnwk-prapi", 2538 }, { L"vnyx", 8699 }, { L"vocaltec-admin", 1796 },
+ { L"vocaltec-gold", 6670 }, { L"vocaltec-hos", 25793 }, { L"vocaltec-phone", 22555 }, { L"vocaltec-wconf", 22555 },
+ { L"vofr-gateway", 21590 }, { L"voispeed-port", 3541 }, { L"volley", 3625 }, { L"vop", 4433 },
+ { L"vopied", 13783 }, { L"voxelstorm", 28200 }, { L"vp2p", 8473 }, { L"vpa", 5164 },
+ { L"vpa-disc", 5164 }, { L"vpac", 1517 }, { L"vpad", 1516 }, { L"vpjp", 1345 },
+ { L"vpm-udp", 5046 }, { L"vpnz", 1224 }, { L"vpp", 677 }, { L"vpps-qua", 672 },
+ { L"vpps-via", 676 }, { L"vpsipport", 2649 }, { L"vpvc", 1519 }, { L"vpvd", 1518 },
+ { L"vqp", 1589 }, { L"vrace", 9300 }, { L"vrcommerce", 2530 }, { L"vrml-multi-use", 4200 },
+ { L"vrml-multi-use", 4201 }, { L"vrml-multi-use", 4202 }, { L"vrml-multi-use", 4203 }, { L"vrml-multi-use", 4204 },
+ { L"vrml-multi-use", 4205 }, { L"vrml-multi-use", 4206 }, { L"vrml-multi-use", 4207 }, { L"vrml-multi-use", 4208 },
+ { L"vrml-multi-use", 4209 }, { L"vrml-multi-use", 4210 }, { L"vrml-multi-use", 4211 }, { L"vrml-multi-use", 4212 },
+ { L"vrml-multi-use", 4213 }, { L"vrml-multi-use", 4214 }, { L"vrml-multi-use", 4215 }, { L"vrml-multi-use", 4216 },
+ { L"vrml-multi-use", 4217 }, { L"vrml-multi-use", 4218 }, { L"vrml-multi-use", 4219 }, { L"vrml-multi-use", 4220 },
+ { L"vrml-multi-use", 4221 }, { L"vrml-multi-use", 4222 }, { L"vrml-multi-use", 4223 }, { L"vrml-multi-use", 4224 },
+ { L"vrml-multi-use", 4225 }, { L"vrml-multi-use", 4226 }, { L"vrml-multi-use", 4227 }, { L"vrml-multi-use", 4228 },
+ { L"vrml-multi-use", 4229 }, { L"vrml-multi-use", 4230 }, { L"vrml-multi-use", 4231 }, { L"vrml-multi-use", 4232 },
+ { L"vrml-multi-use", 4233 }, { L"vrml-multi-use", 4234 }, { L"vrml-multi-use", 4235 }, { L"vrml-multi-use", 4236 },
+ { L"vrml-multi-use", 4237 }, { L"vrml-multi-use", 4238 }, { L"vrml-multi-use", 4239 }, { L"vrml-multi-use", 4240 },
+ { L"vrml-multi-use", 4241 }, { L"vrml-multi-use", 4242 }, { L"vrml-multi-use", 4243 }, { L"vrml-multi-use", 4244 },
+ { L"vrml-multi-use", 4245 }, { L"vrml-multi-use", 4246 }, { L"vrml-multi-use", 4247 }, { L"vrml-multi-use", 4248 },
+ { L"vrml-multi-use", 4249 }, { L"vrml-multi-use", 4250 }, { L"vrml-multi-use", 4251 }, { L"vrml-multi-use", 4252 },
+ { L"vrml-multi-use", 4253 }, { L"vrml-multi-use", 4254 }, { L"vrml-multi-use", 4255 }, { L"vrml-multi-use", 4256 },
+ { L"vrml-multi-use", 4257 }, { L"vrml-multi-use", 4258 }, { L"vrml-multi-use", 4259 }, { L"vrml-multi-use", 4260 },
+ { L"vrml-multi-use", 4261 }, { L"vrml-multi-use", 4262 }, { L"vrml-multi-use", 4263 }, { L"vrml-multi-use", 4264 },
+ { L"vrml-multi-use", 4265 }, { L"vrml-multi-use", 4266 }, { L"vrml-multi-use", 4267 }, { L"vrml-multi-use", 4268 },
+ { L"vrml-multi-use", 4269 }, { L"vrml-multi-use", 4270 }, { L"vrml-multi-use", 4271 }, { L"vrml-multi-use", 4272 },
+ { L"vrml-multi-use", 4273 }, { L"vrml-multi-use", 4274 }, { L"vrml-multi-use", 4275 }, { L"vrml-multi-use", 4276 },
+ { L"vrml-multi-use", 4277 }, { L"vrml-multi-use", 4278 }, { L"vrml-multi-use", 4279 }, { L"vrml-multi-use", 4280 },
+ { L"vrml-multi-use", 4281 }, { L"vrml-multi-use", 4282 }, { L"vrml-multi-use", 4283 }, { L"vrml-multi-use", 4284 },
+ { L"vrml-multi-use", 4285 }, { L"vrml-multi-use", 4286 }, { L"vrml-multi-use", 4287 }, { L"vrml-multi-use", 4288 },
+ { L"vrml-multi-use", 4289 }, { L"vrml-multi-use", 4290 }, { L"vrml-multi-use", 4291 }, { L"vrml-multi-use", 4292 },
+ { L"vrml-multi-use", 4293 }, { L"vrml-multi-use", 4294 }, { L"vrml-multi-use", 4295 }, { L"vrml-multi-use", 4296 },
+ { L"vrml-multi-use", 4297 }, { L"vrml-multi-use", 4298 }, { L"vrml-multi-use", 4299 }, { L"vrpn", 3883 },
+ { L"vrt", 4991 }, { L"vrtl-vmf-ds", 1956 }, { L"vrtl-vmf-sa", 2074 }, { L"vrtp", 2255 },
+ { L"vrts-at-port", 2821 }, { L"vrts-auth-port", 4032 }, { L"vrts-ipcserver", 1317 }, { L"vrts-registry", 2410 },
+ { L"vrts-tdd", 14149 }, { L"vrtstrapserver", 1885 }, { L"vrxpservman", 4147 }, { L"vs-server", 3280 },
+ { L"vsaiport", 3317 }, { L"vsamredirector", 2387 }, { L"vsat-control", 1880 }, { L"vscp", 9598 },
+ { L"vseconnector", 2893 }, { L"vsi-omega", 7566 }, { L"vsiadmin", 2539 }, { L"vsinet", 996 },
+ { L"vsixml", 2996 }, { L"vslmp", 312 }, { L"vsnm-agent", 3375 }, { L"vspread", 2695 },
+ { L"vstat", 7779 }, { L"vt-ssl", 3509 }, { L"vtp", 16666 }, { L"vtr-emulator", 3122 },
+ { L"vts-rpc", 5780 }, { L"vtsas", 5070 }, { L"vtu-comms", 2216 }, { L"vulture", 3482 },
+ { L"vvr-control", 4145 }, { L"vvr-data", 8199 }, { L"vx-auth-port", 3207 }, { L"vxcrnbuport", 3652 },
+ { L"vxlan", 4789 }, { L"vxlan-gpe", 4790 }, { L"vytalvaultbrtp", 2546 }, { L"vytalvaultpipe", 2548 },
+ { L"vytalvaultvsmp", 2547 }, { L"waascluster", 5787 }, { L"wacp", 3633 }, { L"wafs", 4049 },
+ { L"wag-service", 2608 }, { L"wago-io-system", 2455 }, { L"wago-service", 6626 }, { L"wanscaler", 2312 },
+ { L"wap-push", 2948 }, { L"wap-push-http", 4035 }, { L"wap-push-https", 4036 }, { L"wap-pushsecure", 2949 },
+ { L"wap-vcal", 9205 }, { L"wap-vcal-s", 9207 }, { L"wap-vcard", 9204 }, { L"wap-vcard-s", 9206 },
+ { L"wap-wsp", 9200 }, { L"wap-wsp-s", 9202 }, { L"wap-wsp-wtp", 9201 }, { L"wap-wsp-wtp-s", 9203 },
+ { L"warehouse", 12322 }, { L"warehouse-sss", 12321 }, { L"warmspotMgmt", 1074 }, { L"warmux", 3826 },
+ { L"watchdoc", 5744 }, { L"watchdoc-pod", 5743 }, { L"watchdog-nt", 2723 }, { L"watchme-7272", 7272 },
+ { L"watcomdebug", 3563 }, { L"watershed-lm", 6143 }, { L"watilapp", 1269 }, { L"wbem-exp-https", 5990 },
+ { L"wbem-http", 5988 }, { L"wbem-https", 5989 }, { L"wbem-rmi", 5987 }, { L"wcbackup", 8912 },
+ { L"wcpp", 4185 }, { L"wcr-remlib", 4845 }, { L"weandsf", 48050 }, { L"weave", 11095 },
+ { L"web2host", 1559 }, { L"webaccess", 1739 }, { L"webadmstart", 1110 }, { L"webdata", 3748 },
+ { L"webemshttp", 2851 }, { L"weblogin", 2054 }, { L"webmachine", 1963 }, { L"webmail-2", 3511 },
+ { L"webmethods-b2b", 2907 }, { L"webobjects", 1085 }, { L"webphone", 21845 }, { L"websm", 9090 },
+ { L"websphere-snmp", 3427 }, { L"webster", 765 }, { L"webtie", 3342 }, { L"webyast", 4984 },
+ { L"wello", 4177 }, { L"westec-connect", 5566 }, { L"westell-stats", 1875 }, { L"wfc", 4847 },
+ { L"wfm", 4057 }, { L"wfremotertm", 1046 }, { L"wg-netforce", 3359 }, { L"wherehoo", 5859 },
+ { L"whisker", 3233 }, { L"who", 513 }, { L"whoami", 565 }, { L"whois++", 63 },
+ { L"whoispp", 63 }, { L"whosells", 2781 }, { L"whosockami", 2009 }, { L"whosockami", 2019 },
+ { L"wibukey", 22347 }, { L"wiegand", 4390 }, { L"wifree", 11208 }, { L"wilkenlistener", 1890 },
+ { L"willy", 2518 }, { L"wimaxasncp", 2231 }, { L"wimd", 2980 }, { L"wimsic", 1326 },
+ { L"windb", 2522 }, { L"winddlb", 1565 }, { L"winddx", 1727 }, { L"windlm", 1785 },
+ { L"windream", 534 }, { L"winfs", 5009 }, { L"wininstall-ipc", 3674 }, { L"winjaserver", 1290 },
+ { L"winpcs", 5166 }, { L"winpharaoh", 6065 }, { L"winpoplanmess", 1152 }, { L"winport", 3926 },
+ { L"winqedit", 7395 }, { L"winrm", 47001 }, { L"wins", 1512 }, { L"winshadow", 3261 },
+ { L"winshadow-hd", 3861 }, { L"wip-port", 3414 }, { L"wired", 4871 }, { L"wizard", 2001 },
+ { L"wkars", 2720 }, { L"wkstn-mon", 2991 }, { L"wlanauth", 3810 }, { L"wlbs", 2504 },
+ { L"wlcp", 36411 }, { L"wmc-log-svc", 1338 }, { L"wmedistribution", 11998 }, { L"wmereceiving", 11997 },
+ { L"wmereporting", 11999 }, { L"wmlserver", 4883 }, { L"wms-messenger", 3219 }, { L"wnn6", 22273 },
+ { L"wnn6-ds", 26208 }, { L"workflow", 3466 }, { L"world-lm", 1462 }, { L"worldfusion1", 2595 },
+ { L"worldfusion2", 2596 }, { L"worldscores", 4545 }, { L"wpages", 776 }, { L"wpgs", 780 },
+ { L"writesrv", 1334 }, { L"wrs-registry", 2340 }, { L"wrspice", 6114 }, { L"ws-discovery", 3702 },
+ { L"wsdapi", 5357 }, { L"wsdapi-s", 5358 }, { L"wsdl-event", 4879 }, { L"wsicopy", 3378 },
+ { L"wsm-server", 5006 }, { L"wsm-server-ssl", 5007 }, { L"wsman", 5985 }, { L"wsmans", 5986 },
+ { L"wsmlb", 3806 }, { L"wso2esb-console", 9444 }, { L"wspipe", 4431 }, { L"wssauthsvc", 4537 },
+ { L"wsscomfrmwk", 6602 }, { L"wsynch", 3111 }, { L"wta-wsp-s", 2805 }, { L"wta-wsp-wtp-s", 2923 },
+ { L"wusage", 2396 }, { L"wv-csp-sms", 3590 }, { L"wv-csp-sms-cir", 3716 }, { L"wv-csp-udp-cir", 3717 },
+ { L"wwiotalk", 5413 }, { L"www", 80 }, { L"www-dev", 2784 }, { L"www-http", 80 },
+ { L"www-ldap-gw", 1760 }, { L"wxbrief", 4368 }, { L"wysdma", 3741 }, { L"wysdmc", 3916 },
+ { L"x-bone-api", 2165 }, { L"x-bone-ctl", 265 }, { L"x11", 6001 }, { L"x11", 6002 },
+ { L"x11", 6003 }, { L"x11", 6004 }, { L"x11", 6005 }, { L"x11", 6006 },
+ { L"x11", 6007 }, { L"x11", 6008 }, { L"x11", 6009 }, { L"x11", 6010 },
+ { L"x11", 6011 }, { L"x11", 6012 }, { L"x11", 6013 }, { L"x11", 6014 },
+ { L"x11", 6015 }, { L"x11", 6016 }, { L"x11", 6017 }, { L"x11", 6018 },
+ { L"x11", 6019 }, { L"x11", 6020 }, { L"x11", 6021 }, { L"x11", 6022 },
+ { L"x11", 6023 }, { L"x11", 6024 }, { L"x11", 6025 }, { L"x11", 6026 },
+ { L"x11", 6027 }, { L"x11", 6028 }, { L"x11", 6029 }, { L"x11", 6030 },
+ { L"x11", 6031 }, { L"x11", 6032 }, { L"x11", 6033 }, { L"x11", 6034 },
+ { L"x11", 6035 }, { L"x11", 6036 }, { L"x11", 6037 }, { L"x11", 6038 },
+ { L"x11", 6039 }, { L"x11", 6040 }, { L"x11", 6041 }, { L"x11", 6042 },
+ { L"x11", 6043 }, { L"x11", 6044 }, { L"x11", 6045 }, { L"x11", 6046 },
+ { L"x11", 6047 }, { L"x11", 6048 }, { L"x11", 6049 }, { L"x11", 6050 },
+ { L"x11", 6060 }, { L"x11", 6061 }, { L"x11", 6062 }, { L"x11", 6063 },
+ { L"x2-control", 36422 }, { L"x25-svc-port", 1998 }, { L"x2e-disc", 11877 }, { L"x500ms", 5757 },
+ { L"x9-icue", 1145 }, { L"xaapi", 1934 }, { L"xact-backup", 911 }, { L"xadmin", 9105 },
+ { L"xandros-cms", 4389 }, { L"xap-ha", 3639 }, { L"xbox", 3074 }, { L"xdas", 7629 },
+ { L"xdmcp", 177 }, { L"xds", 2130 }, { L"xdsxdm", 6558 }, { L"xdtp", 3088 },
+ { L"xecp-node", 3940 }, { L"xfer", 82 }, { L"xfr", 682 }, { L"xgrid", 4111 },
+ { L"xic", 6115 }, { L"xiip", 1924 }, { L"xingcsm", 2327 }, { L"xingmpeg", 1558 },
+ { L"xinuexpansion1", 2021 }, { L"xinuexpansion2", 2022 }, { L"xinuexpansion3", 2023 }, { L"xinuexpansion4", 2024 },
+ { L"xinupageserver", 2020 }, { L"xiostatus", 2341 }, { L"xkotodrcp", 5344 }, { L"xmapi", 1933 },
+ { L"xmcp", 4788 }, { L"xmlblaster", 3412 }, { L"xmlink-connect", 3953 }, { L"XmlIpcRegSvc", 9092 },
+ { L"xmlrpc-beep", 602 }, { L"xmltec-xmlmail", 9091 }, { L"xmms2", 9667 }, { L"xmpcr-interface", 3877 },
+ { L"xmpp-bosh", 5280 }, { L"xmpp-client", 5222 }, { L"xmpp-server", 5269 }, { L"xmpv7", 7430 },
+ { L"xmquery", 2279 }, { L"xmsg", 1716 }, { L"xnds", 2157 }, { L"xnm-clear-text", 3221 },
+ { L"xnm-ssl", 3220 }, { L"xnmp", 1652 }, { L"xns-auth", 56 }, { L"xns-ch", 54 },
+ { L"xns-courier", 165 }, { L"xns-mail", 58 }, { L"xns-time", 52 }, { L"xo-wave", 3763 },
+ { L"xoms", 16619 }, { L"xoraya", 11876 }, { L"xpanel", 3737 }, { L"xpilot", 15345 },
+ { L"xpl", 3865 }, { L"xprint-server", 8100 }, { L"xprtld", 5634 }, { L"xqosd", 31416 },
+ { L"xribs", 2025 }, { L"xrl", 1104 }, { L"xrpc-registry", 3651 }, { L"xs-openstorage", 1619 },
+ { L"xserveraid", 3722 }, { L"XSIP-network", 1354 }, { L"xsmsvc", 6936 }, { L"xss-port", 3510 },
+ { L"xss-srv-port", 3646 }, { L"xsync", 3721 }, { L"xtgui", 4095 }, { L"xtlserv", 6116 },
+ { L"xtreamx", 5793 }, { L"xtrm", 3423 }, { L"xtrms", 3424 }, { L"xvttp", 508 },
+ { L"xxnetserver", 3832 }, { L"xybrid-cloud", 9925 }, { L"xybrid-rt", 9978 }, { L"xyplex-mux", 173 },
+ { L"yawn", 31029 }, { L"yo-main", 4040 }, { L"z-wave", 4123 }, { L"z-wave-s", 44123 },
+ { L"z39-50", 210 }, { L"zabbix-agent", 10050 }, { L"zabbix-trapper", 10051 }, { L"zannet", 317 }, { L"zarkov", 2989 },
+ { L"zen-pawn", 7628 }, { L"zenginkyo-1", 5020 }, { L"zenginkyo-2", 5021 }, { L"zented", 1229 },
+ { L"zep", 17754 }, { L"zephyr-clt", 2103 }, { L"zephyr-hm", 2104 }, { L"zephyr-srv", 2102 },
+ { L"zicom", 3774 }, { L"zieto-sock", 4072 }, { L"zigbee-ip", 17755 }, { L"zigbee-ips", 17756 },
+ { L"zion-lm", 1425 }, { L"zmp", 3925 }, { L"zoomcp", 9666 }, { L"zre-disc", 5670 },
+ { L"zsecure", 7173 }, { L"zserv", 346 }, { L"zymed-zpp", 2133 }
+};
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/resource.h b/plugins-extra/NetExtrasPlugin/resource.h
new file mode 100644
index 0000000..018024e
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/resource.h
@@ -0,0 +1,264 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by NetExtrasPlugin.rc
+//
+#define AD_PNG 101
+#define AE_PNG 102
+#define AF_PNG 103
+#define AG_PNG 104
+#define AI_PNG 105
+#define AL_PNG 106
+#define AM_PNG 107
+#define AN_PNG 108
+#define AO_PNG 109
+#define AR_PNG 110
+#define AS_PNG 111
+#define AT_PNG 112
+#define AU_PNG 113
+#define AW_PNG 114
+#define AX_PNG 115
+#define AZ_PNG 116
+#define BA_PNG 117
+#define BB_PNG 118
+#define BD_PNG 119
+#define BE_PNG 120
+#define BF_PNG 121
+#define BG_PNG 122
+#define BH_PNG 123
+#define BI__PNG 124
+#define BJ_PNG 125
+#define BM_PNG 126
+#define BN_PNG 127
+#define BO_PNG 128
+#define BR_PNG 129
+#define BS_PNG 130
+#define BT_PNG 131
+#define BV_PNG 132
+#define BW_PNG 133
+#define BY_PNG 134
+#define BZ_PNG 135
+#define CA_PNG 136
+#define AAC_PNG 137
+#define CC_PNG 138
+#define CD_PNG 139
+#define CF_PNG 140
+#define CG_PNG 141
+#define CH_PNG 142
+#define CI_PNG 143
+#define CK_PNG 144
+#define CL_PNG 145
+#define CM_PNG 146
+#define CN_PNG 147
+#define CO_PNG 148
+#define CR_PNG 149
+#define CS_PNG 150
+#define CU_PNG 151
+#define CV_PNG 152
+#define CX_PNG 153
+#define CY_PNG 154
+#define CZ_PNG 155
+#define DE_PNG 156
+#define DJ_PNG 157
+#define DK_PNG 158
+#define DM_PNG 159
+#define DO_PNG 160
+#define DZ_PNG 161
+#define EC_PNG 162
+#define EE_PNG 163
+#define EG_PNG 164
+#define EH_PNG 165
+#define AAD_PNG 166
+#define ER_PNG 167
+#define ES_PNG 168
+#define ET_PNG 169
+#define AAE_PNG 170
+#define AAF_PNG 171
+#define FI_PNG 172
+#define FJ_PNG 173
+#define FK_PNG 174
+#define FM_PNG 175
+#define FO_PNG 176
+#define FR_PNG 177
+#define GA_PNG 178
+#define GB_PNG 179
+#define GD_PNG 180
+#define GE_PNG 181
+#define GF_PNG 182
+#define GH_PNG 183
+#define GI_PNG 184
+#define GL_PNG 185
+#define GM_PNG 186
+#define GN_PNG 187
+#define GP_PNG 188
+#define GQ_PNG 189
+#define GR_PNG 190
+#define GS_PNG 191
+#define GT_PNG 192
+#define GU_PNG 193
+#define GW_PNG 194
+#define GY_PNG 195
+#define HK_PNG 196
+#define HM_PNG 197
+#define HN_PNG 198
+#define HR_PNG 199
+#define HT_PNG 200
+#define ID_PNG 202
+#define IE_PNG 203
+#define IL_PNG 204
+#define IN_PNG 205
+#define IO_PNG 206
+#define IQ_PNG 207
+#define IR_PNG 208
+#define IS_PNG 209
+#define IT_PNG 210
+#define JM_PNG 211
+#define JO_PNG 212
+#define JP_PNG 213
+#define KE_PNG 214
+#define KG_PNG 215
+#define KH_PNG 216
+#define KI_PNG 217
+#define KM_PNG 218
+#define KN_PNG 219
+#define KP_PNG 220
+#define KR_PNG 221
+#define KW_PNG 222
+#define KY_PNG 223
+#define KZ_PNG 224
+#define LA_PNG 225
+#define LB_PNG 226
+#define LC_PNG 227
+#define LI_PNG 228
+#define LK_PNG 229
+#define LR_PNG 230
+#define LS_PNG 231
+#define LT_PNG 232
+#define LU_PNG 233
+#define LV_PNG 234
+#define LY_PNG 235
+#define MA_PNG 236
+#define MC_PNG 237
+#define MD_PNG 238
+#define ME_PNG 239
+#define MG_PNG 240
+#define MH_PNG 241
+#define MK_PNG 242
+#define ML_PNG 243
+#define MM_PNG 244
+#define MN_PNG 245
+#define MO_PNG 246
+#define MP_PNG 247
+#define MQ_PNG 248
+#define MR_PNG 249
+#define MS_PNG 250
+#define MT_PNG 251
+#define MU_PNG 252
+#define MV_PNG 253
+#define MW_PNG 254
+#define MX_PNG 255
+#define MY_PNG 256
+#define MZ_PNG 257
+#define NA_PNG 258
+#define NC_PNG 259
+#define NE_PNG 260
+#define NF_PNG 261
+#define NG_PNG 262
+#define NI_PNG 263
+#define NL_PNG 264
+#define NO_PNG 265
+#define NP_PNG 266
+#define NR_PNG 267
+#define NU_PNG 268
+#define NZ_PNG 269
+#define OM_PNG 270
+#define PA_PNG 271
+#define PE_PNG 272
+#define PF_PNG 273
+#define PG_PNG 274
+#define PH_PNG 275
+#define PK_PNG 276
+#define PL_PNG 277
+#define PM_PNG 278
+#define PN_PNG 279
+#define PR_PNG 280
+#define PS_PNG 281
+#define PT_PNG 282
+#define PW_PNG 283
+#define PY_PNG 284
+#define QA_PNG 285
+#define RE_PNG 286
+#define RO_PNG 287
+#define RS_PNG 288
+#define RU_PNG 289
+#define RW_PNG 290
+#define SA_PNG 291
+#define SB_PNG 292
+#define SC_PNG 293
+#define AAA_PNG 294
+#define SD_PNG 295
+#define SE_PNG 296
+#define SG_PNG 297
+#define SH_PNG 298
+#define SI_PNG 299
+#define SJ_PNG 300
+#define SK_PNG 301
+#define SL_PNG 302
+#define SM_PNG 303
+#define SN_PNG 304
+#define SO_PNG 305
+#define SR_PNG 306
+#define ST_PNG 307
+#define SV_PNG 308
+#define SY_PNG 309
+#define SZ_PNG 310
+#define TC_PNG 311
+#define TD_PNG 312
+#define TF_PNG 313
+#define TG_PNG 314
+#define TH_PNG 315
+#define TJ_PNG 316
+#define TK_PNG 317
+#define TL_PNG 318
+#define TM_PNG 319
+#define TN_PNG 320
+#define TO_PNG 321
+#define TR_PNG 322
+#define TT_PNG 323
+#define TV_PNG 324
+#define TW_PNG 325
+#define TZ_PNG 326
+#define UA_PNG 327
+#define UG_PNG 328
+#define UM_PNG 329
+#define US_PNG 330
+#define UY_PNG 331
+#define UZ_PNG 332
+#define VA_PNG 333
+#define VC_PNG 334
+#define VE_PNG 335
+#define VG_PNG 336
+#define VI_PNG 337
+#define VN_PNG 338
+#define VU_PNG 339
+#define AAB_PNG 340
+#define WF_PNG 341
+#define WS_PNG 342
+#define YE_PNG 343
+#define YT_PNG 344
+#define ZA_PNG 345
+#define ZM_PNG 346
+#define ZW_PNG 347
+#define HU_PNG 348
+#define IDD_DIALOG1 349
+#define IDD_OPTIONS 349
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 351
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 100
+#endif
+#endif
diff --git a/plugins-extra/NetExtrasPlugin/resources/ad.png b/plugins-extra/NetExtrasPlugin/resources/ad.png
new file mode 100644
index 0000000..625ca84
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ad.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ae.png b/plugins-extra/NetExtrasPlugin/resources/ae.png
new file mode 100644
index 0000000..ef3a1ec
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ae.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/af.png b/plugins-extra/NetExtrasPlugin/resources/af.png
new file mode 100644
index 0000000..a4742e2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/af.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ag.png b/plugins-extra/NetExtrasPlugin/resources/ag.png
new file mode 100644
index 0000000..556d550
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ag.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ai.png b/plugins-extra/NetExtrasPlugin/resources/ai.png
new file mode 100644
index 0000000..74ed29d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ai.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/al.png b/plugins-extra/NetExtrasPlugin/resources/al.png
new file mode 100644
index 0000000..92354cb
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/al.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/am.png b/plugins-extra/NetExtrasPlugin/resources/am.png
new file mode 100644
index 0000000..344a2a8
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/am.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/an.png b/plugins-extra/NetExtrasPlugin/resources/an.png
new file mode 100644
index 0000000..633e4b8
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/an.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ao.png b/plugins-extra/NetExtrasPlugin/resources/ao.png
new file mode 100644
index 0000000..bcbd1d6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ao.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ar.png b/plugins-extra/NetExtrasPlugin/resources/ar.png
new file mode 100644
index 0000000..e5ef8f1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ar.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/as.png b/plugins-extra/NetExtrasPlugin/resources/as.png
new file mode 100644
index 0000000..32f30e4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/as.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/at.png b/plugins-extra/NetExtrasPlugin/resources/at.png
new file mode 100644
index 0000000..0f15f34
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/at.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/au.png b/plugins-extra/NetExtrasPlugin/resources/au.png
new file mode 100644
index 0000000..a01389a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/au.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/aw.png b/plugins-extra/NetExtrasPlugin/resources/aw.png
new file mode 100644
index 0000000..a3579c2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/aw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ax.png b/plugins-extra/NetExtrasPlugin/resources/ax.png
new file mode 100644
index 0000000..1eea80a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ax.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/az.png b/plugins-extra/NetExtrasPlugin/resources/az.png
new file mode 100644
index 0000000..4ee9fe5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/az.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ba.png b/plugins-extra/NetExtrasPlugin/resources/ba.png
new file mode 100644
index 0000000..c774992
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ba.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bb.png b/plugins-extra/NetExtrasPlugin/resources/bb.png
new file mode 100644
index 0000000..0df19c7
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bb.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bd.png b/plugins-extra/NetExtrasPlugin/resources/bd.png
new file mode 100644
index 0000000..076a8bf
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bd.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/be.png b/plugins-extra/NetExtrasPlugin/resources/be.png
new file mode 100644
index 0000000..d86ebc8
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/be.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bf.png b/plugins-extra/NetExtrasPlugin/resources/bf.png
new file mode 100644
index 0000000..ab5ce8f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bg.png b/plugins-extra/NetExtrasPlugin/resources/bg.png
new file mode 100644
index 0000000..0469f06
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bh.png b/plugins-extra/NetExtrasPlugin/resources/bh.png
new file mode 100644
index 0000000..ea8ce68
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bi.png b/plugins-extra/NetExtrasPlugin/resources/bi.png
new file mode 100644
index 0000000..5cc2e30
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bi.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bj.png b/plugins-extra/NetExtrasPlugin/resources/bj.png
new file mode 100644
index 0000000..1cc8b45
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bj.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bm.png b/plugins-extra/NetExtrasPlugin/resources/bm.png
new file mode 100644
index 0000000..c0c7aea
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bn.png b/plugins-extra/NetExtrasPlugin/resources/bn.png
new file mode 100644
index 0000000..8fb0984
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bo.png b/plugins-extra/NetExtrasPlugin/resources/bo.png
new file mode 100644
index 0000000..ce7ba52
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bo.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/br.png b/plugins-extra/NetExtrasPlugin/resources/br.png
new file mode 100644
index 0000000..9b1a553
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/br.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bs.png b/plugins-extra/NetExtrasPlugin/resources/bs.png
new file mode 100644
index 0000000..639fa6c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bs.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bt.png b/plugins-extra/NetExtrasPlugin/resources/bt.png
new file mode 100644
index 0000000..1d512df
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bv.png b/plugins-extra/NetExtrasPlugin/resources/bv.png
new file mode 100644
index 0000000..160b6b5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bw.png b/plugins-extra/NetExtrasPlugin/resources/bw.png
new file mode 100644
index 0000000..fcb1039
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/by.png b/plugins-extra/NetExtrasPlugin/resources/by.png
new file mode 100644
index 0000000..504774e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/by.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/bz.png b/plugins-extra/NetExtrasPlugin/resources/bz.png
new file mode 100644
index 0000000..be63ee1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/bz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ca.png b/plugins-extra/NetExtrasPlugin/resources/ca.png
new file mode 100644
index 0000000..1f20419
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ca.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/catalonia.png b/plugins-extra/NetExtrasPlugin/resources/catalonia.png
new file mode 100644
index 0000000..5041e30
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/catalonia.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cc.png b/plugins-extra/NetExtrasPlugin/resources/cc.png
new file mode 100644
index 0000000..aed3d3b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cd.png b/plugins-extra/NetExtrasPlugin/resources/cd.png
new file mode 100644
index 0000000..5e48942
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cd.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cf.png b/plugins-extra/NetExtrasPlugin/resources/cf.png
new file mode 100644
index 0000000..da687bd
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cg.png b/plugins-extra/NetExtrasPlugin/resources/cg.png
new file mode 100644
index 0000000..a859792
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ch.png b/plugins-extra/NetExtrasPlugin/resources/ch.png
new file mode 100644
index 0000000..242ec01
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ch.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ci.png b/plugins-extra/NetExtrasPlugin/resources/ci.png
new file mode 100644
index 0000000..3f2c62e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ci.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ck.png b/plugins-extra/NetExtrasPlugin/resources/ck.png
new file mode 100644
index 0000000..746d3d6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ck.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cl.png b/plugins-extra/NetExtrasPlugin/resources/cl.png
new file mode 100644
index 0000000..29c6d61
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cm.png b/plugins-extra/NetExtrasPlugin/resources/cm.png
new file mode 100644
index 0000000..f65c5bd
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cn.png b/plugins-extra/NetExtrasPlugin/resources/cn.png
new file mode 100644
index 0000000..8914414
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/co.png b/plugins-extra/NetExtrasPlugin/resources/co.png
new file mode 100644
index 0000000..a118ff4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/co.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cr.png b/plugins-extra/NetExtrasPlugin/resources/cr.png
new file mode 100644
index 0000000..c7a3731
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cs.png b/plugins-extra/NetExtrasPlugin/resources/cs.png
new file mode 100644
index 0000000..8254790
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cs.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cu.png b/plugins-extra/NetExtrasPlugin/resources/cu.png
new file mode 100644
index 0000000..083f1d6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cv.png b/plugins-extra/NetExtrasPlugin/resources/cv.png
new file mode 100644
index 0000000..a63f7ea
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cx.png b/plugins-extra/NetExtrasPlugin/resources/cx.png
new file mode 100644
index 0000000..48e31ad
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cx.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cy.png b/plugins-extra/NetExtrasPlugin/resources/cy.png
new file mode 100644
index 0000000..5b1ad6c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cy.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/cz.png b/plugins-extra/NetExtrasPlugin/resources/cz.png
new file mode 100644
index 0000000..c8403dd
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/cz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/de.png b/plugins-extra/NetExtrasPlugin/resources/de.png
new file mode 100644
index 0000000..ac4a977
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/de.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/dj.png b/plugins-extra/NetExtrasPlugin/resources/dj.png
new file mode 100644
index 0000000..582af36
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/dj.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/dk.png b/plugins-extra/NetExtrasPlugin/resources/dk.png
new file mode 100644
index 0000000..e2993d3
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/dk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/dm.png b/plugins-extra/NetExtrasPlugin/resources/dm.png
new file mode 100644
index 0000000..5fbffcb
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/dm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/do.png b/plugins-extra/NetExtrasPlugin/resources/do.png
new file mode 100644
index 0000000..5a04932
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/do.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/dz.png b/plugins-extra/NetExtrasPlugin/resources/dz.png
new file mode 100644
index 0000000..335c239
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/dz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ec.png b/plugins-extra/NetExtrasPlugin/resources/ec.png
new file mode 100644
index 0000000..0caa0b1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ec.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ee.png b/plugins-extra/NetExtrasPlugin/resources/ee.png
new file mode 100644
index 0000000..0c82efb
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ee.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/eg.png b/plugins-extra/NetExtrasPlugin/resources/eg.png
new file mode 100644
index 0000000..8a3f7a1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/eg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/eh.png b/plugins-extra/NetExtrasPlugin/resources/eh.png
new file mode 100644
index 0000000..90a1195
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/eh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/england.png b/plugins-extra/NetExtrasPlugin/resources/england.png
new file mode 100644
index 0000000..3a7311d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/england.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/er.png b/plugins-extra/NetExtrasPlugin/resources/er.png
new file mode 100644
index 0000000..13065ae
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/er.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/es.png b/plugins-extra/NetExtrasPlugin/resources/es.png
new file mode 100644
index 0000000..c2de2d7
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/es.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/et.png b/plugins-extra/NetExtrasPlugin/resources/et.png
new file mode 100644
index 0000000..2e893fa
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/et.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/europeanunion.png b/plugins-extra/NetExtrasPlugin/resources/europeanunion.png
new file mode 100644
index 0000000..d6d8711
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/europeanunion.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fam.png b/plugins-extra/NetExtrasPlugin/resources/fam.png
new file mode 100644
index 0000000..cf50c75
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fam.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fi.png b/plugins-extra/NetExtrasPlugin/resources/fi.png
new file mode 100644
index 0000000..14ec091
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fi.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fj.png b/plugins-extra/NetExtrasPlugin/resources/fj.png
new file mode 100644
index 0000000..cee9988
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fj.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fk.png b/plugins-extra/NetExtrasPlugin/resources/fk.png
new file mode 100644
index 0000000..ceaeb27
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fm.png b/plugins-extra/NetExtrasPlugin/resources/fm.png
new file mode 100644
index 0000000..066bb24
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fo.png b/plugins-extra/NetExtrasPlugin/resources/fo.png
new file mode 100644
index 0000000..cbceb80
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fo.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/fr.png b/plugins-extra/NetExtrasPlugin/resources/fr.png
new file mode 100644
index 0000000..8332c4e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/fr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ga.png b/plugins-extra/NetExtrasPlugin/resources/ga.png
new file mode 100644
index 0000000..0e0d434
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ga.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gb.png b/plugins-extra/NetExtrasPlugin/resources/gb.png
new file mode 100644
index 0000000..ff701e1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gb.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gd.png b/plugins-extra/NetExtrasPlugin/resources/gd.png
new file mode 100644
index 0000000..9ab57f5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gd.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ge.png b/plugins-extra/NetExtrasPlugin/resources/ge.png
new file mode 100644
index 0000000..728d970
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ge.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gf.png b/plugins-extra/NetExtrasPlugin/resources/gf.png
new file mode 100644
index 0000000..8332c4e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gh.png b/plugins-extra/NetExtrasPlugin/resources/gh.png
new file mode 100644
index 0000000..4e2f896
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gi.png b/plugins-extra/NetExtrasPlugin/resources/gi.png
new file mode 100644
index 0000000..e76797f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gi.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gl.png b/plugins-extra/NetExtrasPlugin/resources/gl.png
new file mode 100644
index 0000000..ef12a73
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gm.png b/plugins-extra/NetExtrasPlugin/resources/gm.png
new file mode 100644
index 0000000..0720b66
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gn.png b/plugins-extra/NetExtrasPlugin/resources/gn.png
new file mode 100644
index 0000000..ea660b0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gp.png b/plugins-extra/NetExtrasPlugin/resources/gp.png
new file mode 100644
index 0000000..dbb086d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gp.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gq.png b/plugins-extra/NetExtrasPlugin/resources/gq.png
new file mode 100644
index 0000000..ebe20a2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gq.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gr.png b/plugins-extra/NetExtrasPlugin/resources/gr.png
new file mode 100644
index 0000000..8651ade
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gs.png b/plugins-extra/NetExtrasPlugin/resources/gs.png
new file mode 100644
index 0000000..7ef0bf5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gs.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gt.png b/plugins-extra/NetExtrasPlugin/resources/gt.png
new file mode 100644
index 0000000..c43a70d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gu.png b/plugins-extra/NetExtrasPlugin/resources/gu.png
new file mode 100644
index 0000000..92f37c0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gw.png b/plugins-extra/NetExtrasPlugin/resources/gw.png
new file mode 100644
index 0000000..b37bcf0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/gy.png b/plugins-extra/NetExtrasPlugin/resources/gy.png
new file mode 100644
index 0000000..22cbe2f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/gy.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/hk.png b/plugins-extra/NetExtrasPlugin/resources/hk.png
new file mode 100644
index 0000000..d5c380c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/hk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/hm.png b/plugins-extra/NetExtrasPlugin/resources/hm.png
new file mode 100644
index 0000000..a01389a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/hm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/hn.png b/plugins-extra/NetExtrasPlugin/resources/hn.png
new file mode 100644
index 0000000..96f8388
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/hn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/hr.png b/plugins-extra/NetExtrasPlugin/resources/hr.png
new file mode 100644
index 0000000..696b515
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/hr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ht.png b/plugins-extra/NetExtrasPlugin/resources/ht.png
new file mode 100644
index 0000000..416052a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ht.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/hu.png b/plugins-extra/NetExtrasPlugin/resources/hu.png
new file mode 100644
index 0000000..7baafe4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/hu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/id.png b/plugins-extra/NetExtrasPlugin/resources/id.png
new file mode 100644
index 0000000..c6bc0fa
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/id.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ie.png b/plugins-extra/NetExtrasPlugin/resources/ie.png
new file mode 100644
index 0000000..26baa31
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ie.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/il.png b/plugins-extra/NetExtrasPlugin/resources/il.png
new file mode 100644
index 0000000..2ca772d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/il.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/in.png b/plugins-extra/NetExtrasPlugin/resources/in.png
new file mode 100644
index 0000000..e4d7e81
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/in.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/io.png b/plugins-extra/NetExtrasPlugin/resources/io.png
new file mode 100644
index 0000000..3e74b6a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/io.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/iq.png b/plugins-extra/NetExtrasPlugin/resources/iq.png
new file mode 100644
index 0000000..878a351
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/iq.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ir.png b/plugins-extra/NetExtrasPlugin/resources/ir.png
new file mode 100644
index 0000000..c5fd136
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ir.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/is.png b/plugins-extra/NetExtrasPlugin/resources/is.png
new file mode 100644
index 0000000..b8f6d0f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/is.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/it.png b/plugins-extra/NetExtrasPlugin/resources/it.png
new file mode 100644
index 0000000..89692f7
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/it.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/jm.png b/plugins-extra/NetExtrasPlugin/resources/jm.png
new file mode 100644
index 0000000..7be119e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/jm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/jo.png b/plugins-extra/NetExtrasPlugin/resources/jo.png
new file mode 100644
index 0000000..11bd497
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/jo.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/jp.png b/plugins-extra/NetExtrasPlugin/resources/jp.png
new file mode 100644
index 0000000..325fbad
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/jp.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ke.png b/plugins-extra/NetExtrasPlugin/resources/ke.png
new file mode 100644
index 0000000..51879ad
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ke.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kg.png b/plugins-extra/NetExtrasPlugin/resources/kg.png
new file mode 100644
index 0000000..0a818f6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kh.png b/plugins-extra/NetExtrasPlugin/resources/kh.png
new file mode 100644
index 0000000..30f6bb1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ki.png b/plugins-extra/NetExtrasPlugin/resources/ki.png
new file mode 100644
index 0000000..2dcce4b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ki.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/km.png b/plugins-extra/NetExtrasPlugin/resources/km.png
new file mode 100644
index 0000000..812b2f5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/km.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kn.png b/plugins-extra/NetExtrasPlugin/resources/kn.png
new file mode 100644
index 0000000..febd5b4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kp.png b/plugins-extra/NetExtrasPlugin/resources/kp.png
new file mode 100644
index 0000000..d3d509a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kp.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kr.png b/plugins-extra/NetExtrasPlugin/resources/kr.png
new file mode 100644
index 0000000..9c0a78e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kw.png b/plugins-extra/NetExtrasPlugin/resources/kw.png
new file mode 100644
index 0000000..96546da
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ky.png b/plugins-extra/NetExtrasPlugin/resources/ky.png
new file mode 100644
index 0000000..15c5f8e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ky.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/kz.png b/plugins-extra/NetExtrasPlugin/resources/kz.png
new file mode 100644
index 0000000..45a8c88
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/kz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/la.png b/plugins-extra/NetExtrasPlugin/resources/la.png
new file mode 100644
index 0000000..e28acd0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/la.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lb.png b/plugins-extra/NetExtrasPlugin/resources/lb.png
new file mode 100644
index 0000000..d0d452b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lb.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lc.png b/plugins-extra/NetExtrasPlugin/resources/lc.png
new file mode 100644
index 0000000..a47d065
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/li.png b/plugins-extra/NetExtrasPlugin/resources/li.png
new file mode 100644
index 0000000..6469909
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/li.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/licence.txt b/plugins-extra/NetExtrasPlugin/resources/licence.txt
new file mode 100644
index 0000000..c106af9
--- /dev/null
+++ b/plugins-extra/NetExtrasPlugin/resources/licence.txt
@@ -0,0 +1,3 @@
+All country images downloaded and licenced by famfamfam.
+
+http://www.famfamfam.com/lab/icons/flags/
\ No newline at end of file
diff --git a/plugins-extra/NetExtrasPlugin/resources/lk.png b/plugins-extra/NetExtrasPlugin/resources/lk.png
new file mode 100644
index 0000000..088aad6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lr.png b/plugins-extra/NetExtrasPlugin/resources/lr.png
new file mode 100644
index 0000000..89a5bc7
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ls.png b/plugins-extra/NetExtrasPlugin/resources/ls.png
new file mode 100644
index 0000000..33fdef1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ls.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lt.png b/plugins-extra/NetExtrasPlugin/resources/lt.png
new file mode 100644
index 0000000..c8ef0da
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lu.png b/plugins-extra/NetExtrasPlugin/resources/lu.png
new file mode 100644
index 0000000..4cabba9
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/lv.png b/plugins-extra/NetExtrasPlugin/resources/lv.png
new file mode 100644
index 0000000..49b6998
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/lv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ly.png b/plugins-extra/NetExtrasPlugin/resources/ly.png
new file mode 100644
index 0000000..b163a9f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ly.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ma.png b/plugins-extra/NetExtrasPlugin/resources/ma.png
new file mode 100644
index 0000000..f386770
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ma.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mc.png b/plugins-extra/NetExtrasPlugin/resources/mc.png
new file mode 100644
index 0000000..1aa830f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/md.png b/plugins-extra/NetExtrasPlugin/resources/md.png
new file mode 100644
index 0000000..4e92c18
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/md.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/me.png b/plugins-extra/NetExtrasPlugin/resources/me.png
new file mode 100644
index 0000000..ac72535
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/me.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mg.png b/plugins-extra/NetExtrasPlugin/resources/mg.png
new file mode 100644
index 0000000..d2715b3
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mh.png b/plugins-extra/NetExtrasPlugin/resources/mh.png
new file mode 100644
index 0000000..fb523a8
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mk.png b/plugins-extra/NetExtrasPlugin/resources/mk.png
new file mode 100644
index 0000000..db173aa
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ml.png b/plugins-extra/NetExtrasPlugin/resources/ml.png
new file mode 100644
index 0000000..2cec8ba
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ml.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mm.png b/plugins-extra/NetExtrasPlugin/resources/mm.png
new file mode 100644
index 0000000..f464f67
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mn.png b/plugins-extra/NetExtrasPlugin/resources/mn.png
new file mode 100644
index 0000000..9396355
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mo.png b/plugins-extra/NetExtrasPlugin/resources/mo.png
new file mode 100644
index 0000000..deb801d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mo.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mp.png b/plugins-extra/NetExtrasPlugin/resources/mp.png
new file mode 100644
index 0000000..298d588
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mp.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mq.png b/plugins-extra/NetExtrasPlugin/resources/mq.png
new file mode 100644
index 0000000..010143b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mq.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mr.png b/plugins-extra/NetExtrasPlugin/resources/mr.png
new file mode 100644
index 0000000..319546b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ms.png b/plugins-extra/NetExtrasPlugin/resources/ms.png
new file mode 100644
index 0000000..d4cbb43
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ms.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mt.png b/plugins-extra/NetExtrasPlugin/resources/mt.png
new file mode 100644
index 0000000..00af948
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mu.png b/plugins-extra/NetExtrasPlugin/resources/mu.png
new file mode 100644
index 0000000..b7fdce1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mv.png b/plugins-extra/NetExtrasPlugin/resources/mv.png
new file mode 100644
index 0000000..5073d9e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mw.png b/plugins-extra/NetExtrasPlugin/resources/mw.png
new file mode 100644
index 0000000..13886e9
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mx.png b/plugins-extra/NetExtrasPlugin/resources/mx.png
new file mode 100644
index 0000000..5bc58ab
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mx.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/my.png b/plugins-extra/NetExtrasPlugin/resources/my.png
new file mode 100644
index 0000000..9034cba
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/my.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/mz.png b/plugins-extra/NetExtrasPlugin/resources/mz.png
new file mode 100644
index 0000000..76405e0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/mz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/na.png b/plugins-extra/NetExtrasPlugin/resources/na.png
new file mode 100644
index 0000000..63358c6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/na.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nc.png b/plugins-extra/NetExtrasPlugin/resources/nc.png
new file mode 100644
index 0000000..2cad283
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ne.png b/plugins-extra/NetExtrasPlugin/resources/ne.png
new file mode 100644
index 0000000..d85f424
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ne.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nf.png b/plugins-extra/NetExtrasPlugin/resources/nf.png
new file mode 100644
index 0000000..f9bcdda
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ng.png b/plugins-extra/NetExtrasPlugin/resources/ng.png
new file mode 100644
index 0000000..3eea2e0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ng.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ni.png b/plugins-extra/NetExtrasPlugin/resources/ni.png
new file mode 100644
index 0000000..3969aaa
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ni.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nl.png b/plugins-extra/NetExtrasPlugin/resources/nl.png
new file mode 100644
index 0000000..fe44791
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/no.png b/plugins-extra/NetExtrasPlugin/resources/no.png
new file mode 100644
index 0000000..160b6b5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/no.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/np.png b/plugins-extra/NetExtrasPlugin/resources/np.png
new file mode 100644
index 0000000..aeb058b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/np.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nr.png b/plugins-extra/NetExtrasPlugin/resources/nr.png
new file mode 100644
index 0000000..705fc33
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nu.png b/plugins-extra/NetExtrasPlugin/resources/nu.png
new file mode 100644
index 0000000..c3ce4ae
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/nz.png b/plugins-extra/NetExtrasPlugin/resources/nz.png
new file mode 100644
index 0000000..10d6306
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/nz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/om.png b/plugins-extra/NetExtrasPlugin/resources/om.png
new file mode 100644
index 0000000..2ffba7e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/om.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pa.png b/plugins-extra/NetExtrasPlugin/resources/pa.png
new file mode 100644
index 0000000..9b2ee9a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pa.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pe.png b/plugins-extra/NetExtrasPlugin/resources/pe.png
new file mode 100644
index 0000000..62a0497
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pe.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pf.png b/plugins-extra/NetExtrasPlugin/resources/pf.png
new file mode 100644
index 0000000..771a0f6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pg.png b/plugins-extra/NetExtrasPlugin/resources/pg.png
new file mode 100644
index 0000000..10d6233
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ph.png b/plugins-extra/NetExtrasPlugin/resources/ph.png
new file mode 100644
index 0000000..b89e159
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ph.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pk.png b/plugins-extra/NetExtrasPlugin/resources/pk.png
new file mode 100644
index 0000000..e9df70c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pl.png b/plugins-extra/NetExtrasPlugin/resources/pl.png
new file mode 100644
index 0000000..d413d01
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pm.png b/plugins-extra/NetExtrasPlugin/resources/pm.png
new file mode 100644
index 0000000..ba91d2c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pn.png b/plugins-extra/NetExtrasPlugin/resources/pn.png
new file mode 100644
index 0000000..aa9344f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pr.png b/plugins-extra/NetExtrasPlugin/resources/pr.png
new file mode 100644
index 0000000..82d9130
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ps.png b/plugins-extra/NetExtrasPlugin/resources/ps.png
new file mode 100644
index 0000000..f5f5477
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ps.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pt.png b/plugins-extra/NetExtrasPlugin/resources/pt.png
new file mode 100644
index 0000000..ece7980
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/pw.png b/plugins-extra/NetExtrasPlugin/resources/pw.png
new file mode 100644
index 0000000..6178b25
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/pw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/py.png b/plugins-extra/NetExtrasPlugin/resources/py.png
new file mode 100644
index 0000000..cb8723c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/py.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/qa.png b/plugins-extra/NetExtrasPlugin/resources/qa.png
new file mode 100644
index 0000000..ed4c621
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/qa.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/re.png b/plugins-extra/NetExtrasPlugin/resources/re.png
new file mode 100644
index 0000000..8332c4e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/re.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ro.png b/plugins-extra/NetExtrasPlugin/resources/ro.png
new file mode 100644
index 0000000..57e74a6
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ro.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/rs.png b/plugins-extra/NetExtrasPlugin/resources/rs.png
new file mode 100644
index 0000000..9439a5b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/rs.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ru.png b/plugins-extra/NetExtrasPlugin/resources/ru.png
new file mode 100644
index 0000000..47da421
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ru.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/rw.png b/plugins-extra/NetExtrasPlugin/resources/rw.png
new file mode 100644
index 0000000..5356491
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/rw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sa.png b/plugins-extra/NetExtrasPlugin/resources/sa.png
new file mode 100644
index 0000000..b4641c7
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sa.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sb.png b/plugins-extra/NetExtrasPlugin/resources/sb.png
new file mode 100644
index 0000000..a9937cc
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sb.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sc.png b/plugins-extra/NetExtrasPlugin/resources/sc.png
new file mode 100644
index 0000000..39ee371
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/scotland.png b/plugins-extra/NetExtrasPlugin/resources/scotland.png
new file mode 100644
index 0000000..a0e57b4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/scotland.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sd.png b/plugins-extra/NetExtrasPlugin/resources/sd.png
new file mode 100644
index 0000000..eaab69e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sd.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/se.png b/plugins-extra/NetExtrasPlugin/resources/se.png
new file mode 100644
index 0000000..1994653
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/se.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sg.png b/plugins-extra/NetExtrasPlugin/resources/sg.png
new file mode 100644
index 0000000..dd34d61
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sh.png b/plugins-extra/NetExtrasPlugin/resources/sh.png
new file mode 100644
index 0000000..4b1d2a2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sh.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/si.png b/plugins-extra/NetExtrasPlugin/resources/si.png
new file mode 100644
index 0000000..bb1476f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/si.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sj.png b/plugins-extra/NetExtrasPlugin/resources/sj.png
new file mode 100644
index 0000000..160b6b5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sj.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sk.png b/plugins-extra/NetExtrasPlugin/resources/sk.png
new file mode 100644
index 0000000..7ccbc82
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sl.png b/plugins-extra/NetExtrasPlugin/resources/sl.png
new file mode 100644
index 0000000..12d812d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sm.png b/plugins-extra/NetExtrasPlugin/resources/sm.png
new file mode 100644
index 0000000..3df2fdc
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sn.png b/plugins-extra/NetExtrasPlugin/resources/sn.png
new file mode 100644
index 0000000..eabb71d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/so.png b/plugins-extra/NetExtrasPlugin/resources/so.png
new file mode 100644
index 0000000..4a1ea4b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/so.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sr.png b/plugins-extra/NetExtrasPlugin/resources/sr.png
new file mode 100644
index 0000000..5eff927
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/st.png b/plugins-extra/NetExtrasPlugin/resources/st.png
new file mode 100644
index 0000000..2978557
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/st.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sv.png b/plugins-extra/NetExtrasPlugin/resources/sv.png
new file mode 100644
index 0000000..2498799
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sy.png b/plugins-extra/NetExtrasPlugin/resources/sy.png
new file mode 100644
index 0000000..f5ce30d
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sy.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/sz.png b/plugins-extra/NetExtrasPlugin/resources/sz.png
new file mode 100644
index 0000000..914ee86
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/sz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tc.png b/plugins-extra/NetExtrasPlugin/resources/tc.png
new file mode 100644
index 0000000..8fc1156
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/td.png b/plugins-extra/NetExtrasPlugin/resources/td.png
new file mode 100644
index 0000000..667f21f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/td.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tf.png b/plugins-extra/NetExtrasPlugin/resources/tf.png
new file mode 100644
index 0000000..80529a4
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tg.png b/plugins-extra/NetExtrasPlugin/resources/tg.png
new file mode 100644
index 0000000..3aa00ad
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/th.png b/plugins-extra/NetExtrasPlugin/resources/th.png
new file mode 100644
index 0000000..dd8ba91
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/th.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tj.png b/plugins-extra/NetExtrasPlugin/resources/tj.png
new file mode 100644
index 0000000..617bf64
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tj.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tk.png b/plugins-extra/NetExtrasPlugin/resources/tk.png
new file mode 100644
index 0000000..67b8c8c
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tk.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tl.png b/plugins-extra/NetExtrasPlugin/resources/tl.png
new file mode 100644
index 0000000..77da181
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tl.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tm.png b/plugins-extra/NetExtrasPlugin/resources/tm.png
new file mode 100644
index 0000000..828020e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tn.png b/plugins-extra/NetExtrasPlugin/resources/tn.png
new file mode 100644
index 0000000..183cdd3
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/to.png b/plugins-extra/NetExtrasPlugin/resources/to.png
new file mode 100644
index 0000000..f89b8ba
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/to.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tr.png b/plugins-extra/NetExtrasPlugin/resources/tr.png
new file mode 100644
index 0000000..be32f77
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tr.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tt.png b/plugins-extra/NetExtrasPlugin/resources/tt.png
new file mode 100644
index 0000000..2a11c1e
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tv.png b/plugins-extra/NetExtrasPlugin/resources/tv.png
new file mode 100644
index 0000000..28274c5
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tv.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tw.png b/plugins-extra/NetExtrasPlugin/resources/tw.png
new file mode 100644
index 0000000..f31c654
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tw.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/tz.png b/plugins-extra/NetExtrasPlugin/resources/tz.png
new file mode 100644
index 0000000..c00ff79
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/tz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ua.png b/plugins-extra/NetExtrasPlugin/resources/ua.png
new file mode 100644
index 0000000..09563a2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ua.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ug.png b/plugins-extra/NetExtrasPlugin/resources/ug.png
new file mode 100644
index 0000000..33f4aff
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ug.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/um.png b/plugins-extra/NetExtrasPlugin/resources/um.png
new file mode 100644
index 0000000..c1dd965
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/um.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/us.png b/plugins-extra/NetExtrasPlugin/resources/us.png
new file mode 100644
index 0000000..10f451f
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/us.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/uy.png b/plugins-extra/NetExtrasPlugin/resources/uy.png
new file mode 100644
index 0000000..31d948a
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/uy.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/uz.png b/plugins-extra/NetExtrasPlugin/resources/uz.png
new file mode 100644
index 0000000..fef5dc1
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/uz.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/va.png b/plugins-extra/NetExtrasPlugin/resources/va.png
new file mode 100644
index 0000000..b31eaf2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/va.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/vc.png b/plugins-extra/NetExtrasPlugin/resources/vc.png
new file mode 100644
index 0000000..8fa17b0
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/vc.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ve.png b/plugins-extra/NetExtrasPlugin/resources/ve.png
new file mode 100644
index 0000000..00c90f9
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ve.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/vg.png b/plugins-extra/NetExtrasPlugin/resources/vg.png
new file mode 100644
index 0000000..4156907
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/vg.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/vi.png b/plugins-extra/NetExtrasPlugin/resources/vi.png
new file mode 100644
index 0000000..ed26915
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/vi.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/vn.png b/plugins-extra/NetExtrasPlugin/resources/vn.png
new file mode 100644
index 0000000..ec7cd48
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/vn.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/vu.png b/plugins-extra/NetExtrasPlugin/resources/vu.png
new file mode 100644
index 0000000..b3397bc
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/vu.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/wales.png b/plugins-extra/NetExtrasPlugin/resources/wales.png
new file mode 100644
index 0000000..e0d7cee
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/wales.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/wf.png b/plugins-extra/NetExtrasPlugin/resources/wf.png
new file mode 100644
index 0000000..9f95587
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/wf.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ws.png b/plugins-extra/NetExtrasPlugin/resources/ws.png
new file mode 100644
index 0000000..c169508
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ws.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/ye.png b/plugins-extra/NetExtrasPlugin/resources/ye.png
new file mode 100644
index 0000000..468dfad
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/ye.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/yt.png b/plugins-extra/NetExtrasPlugin/resources/yt.png
new file mode 100644
index 0000000..c298f37
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/yt.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/za.png b/plugins-extra/NetExtrasPlugin/resources/za.png
new file mode 100644
index 0000000..57c58e2
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/za.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/zm.png b/plugins-extra/NetExtrasPlugin/resources/zm.png
new file mode 100644
index 0000000..c25b07b
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/zm.png differ
diff --git a/plugins-extra/NetExtrasPlugin/resources/zw.png b/plugins-extra/NetExtrasPlugin/resources/zw.png
new file mode 100644
index 0000000..53c9725
Binary files /dev/null and b/plugins-extra/NetExtrasPlugin/resources/zw.png differ
diff --git a/plugins-extra/NvGpuPlugin/CHANGELOG.txt b/plugins-extra/NvGpuPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..fcde986
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/CHANGELOG.txt
@@ -0,0 +1,5 @@
+1.1
+ *
+
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/NvGpuPlugin.rc b/plugins-extra/NvGpuPlugin/NvGpuPlugin.rc
new file mode 100644
index 0000000..ecdbfb1
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/NvGpuPlugin.rc
@@ -0,0 +1,225 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.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)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,0,0
+ PRODUCTVERSION 1,1,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "0c0904b0"
+ BEGIN
+ VALUE "CompanyName", "dmex"
+ VALUE "FileDescription", "Nvidia GPU plugin for Process Hacker"
+ VALUE "FileVersion", "1.1"
+ VALUE "InternalName", "dmex.NvGpuPlugin"
+ VALUE "LegalCopyright", "Licensed under the GNU GPL, v3."
+ VALUE "OriginalFilename", "NvGpuPlugin.dll"
+ VALUE "ProductName", "Nvidia GPU plugin for Process Hacker"
+ VALUE "ProductVersion", "1.1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0xc09, 1200
+ END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_GPU_DIALOG DIALOGEX 0, 0, 315, 191
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "GPU",IDC_TITLE,0,0,72,21
+ RTEXT "GPU Name",IDC_GPUNAME,83,4,232,16,SS_WORDELLIPSIS
+ LTEXT "Panel layout",IDC_PANEL_LAYOUT,0,145,315,46,NOT WS_VISIBLE
+ LTEXT "Graph layout",IDC_GRAPH_LAYOUT,0,22,315,120,NOT WS_VISIBLE
+ LTEXT "GPU:",IDC_GPU_L,73,0,17,8
+ LTEXT "Memory:",IDC_MEMORY_L,73,5,29,8
+ LTEXT "Memory Controller:",IDC_SHARED_L,74,11,62,8
+ LTEXT "Bus Interface:",IDC_BUS_L,74,18,47,8
+END
+
+IDD_GPU_PANEL DIALOGEX 0, 0, 372, 47
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Clocks",IDC_STATIC,0,0,118,43
+ LTEXT "Core",IDC_STATIC,8,10,16,8
+ LTEXT "Memory",IDC_STATIC,8,21,26,8
+ RTEXT "Static",IDC_CLOCK_CORE,55,10,54,8,SS_ENDELLIPSIS
+ RTEXT "Static",IDC_CLOCK_MEMORY,55,21,54,8,SS_ENDELLIPSIS
+ GROUPBOX "Fan",IDC_STATIC,122,0,124,22
+ LTEXT "Speed",IDC_STATIC,130,10,21,8
+ RTEXT "Static",IDC_FAN_PERCENT,158,10,78,8,SS_ENDELLIPSIS
+ LTEXT "Shader",IDC_STATIC,8,32,24,8
+ RTEXT "Static",IDC_CLOCK_SHADER,55,32,54,8,SS_ENDELLIPSIS
+ GROUPBOX "Temperature",IDC_STATIC,122,22,124,21
+ LTEXT "Core",IDC_STATIC,130,32,16,8
+ RTEXT "Static",IDC_TEMP_VALUE,158,32,78,8,SS_ENDELLIPSIS
+ GROUPBOX "Voltage",IDC_STATIC,248,0,124,22
+ LTEXT "Core",IDC_STATIC,256,10,16,8
+ RTEXT "Static",IDC_VOLTAGE,284,10,78,8,SS_ENDELLIPSIS
+ PUSHBUTTON "Details",IDC_DETAILS,249,27,50,14
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 211, 58
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,100,37,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,154,37,50,14
+ CONTROL "Enable Nvidia GPU graphs",IDC_ENABLENVIDIASUPPORT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,98,10
+END
+
+IDD_GPU_DETAILS DIALOGEX 0, 0, 265, 245
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ PUSHBUTTON "Close",IDCANCEL,208,224,50,14
+ EDITTEXT IDC_EDIT1,31,7,155,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT2,31,26,60,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT3,31,43,155,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT4,133,26,53,12,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT5,31,59,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT6,31,77,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT7,31,95,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT8,112,59,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT9,112,77,74,12,ES_AUTOHSCROLL | ES_READONLY
+ CONTROL "",IDC_NVIMAGE,"Static",SS_BITMAP,197,7,15,13
+ EDITTEXT IDC_EDIT10,111,95,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT11,31,129,179,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT12,31,148,179,12,ES_AUTOHSCROLL | ES_READONLY
+ RTEXT "Name",IDC_STATIC,7,9,20,8
+ RTEXT "GPU",IDC_STATIC,7,28,20,8
+ RTEXT "Revision",IDC_STATIC,101,28,28,8
+ RTEXT "BIOS",IDC_STATIC,7,46,20,8
+ RTEXT "ID",IDC_STATIC,7,61,20,8
+ EDITTEXT IDC_EDIT13,31,112,74,12,ES_AUTOHSCROLL | ES_READONLY
+ EDITTEXT IDC_EDIT14,111,112,74,12,ES_AUTOHSCROLL | ES_READONLY
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_GPU_DIALOG, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 183
+ END
+
+ IDD_GPU_PANEL, DIALOG
+ BEGIN
+ END
+
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 204
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 51
+ END
+
+ IDD_GPU_DETAILS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 258
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 238
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_GPU_DETAILS AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// PNG
+//
+
+IDB_NV_LOGO_PNG PNG "resources\\NVLogo_2D.png"
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj b/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj
new file mode 100644
index 0000000..13133cc
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj
@@ -0,0 +1,120 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {B509BF8F-6007-4173-B05E-5037B958C12F}
+ NvGpuPlugin
+ Win32Proj
+ NvGpuPlugin
+ 10.0.14393.0
+
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+ DynamicLibrary
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Debug32
+
+
+ $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release64
+
+
+ $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;C:\Users\AirDog46\Downloads\processhacker-2.39-src\bin\Release32
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj.filters b/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj.filters
new file mode 100644
index 0000000..e52e9e7
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/NvGpuPlugin.vcxproj.filters
@@ -0,0 +1,67 @@
+
+
+
+
+ {47359E56-A930-4DDC-A651-E2E99D48E957}
+
+
+ {4965CB7A-371A-4B22-AC3F-E70DC77C5D24}
+
+
+ {00475F04-2369-42D8-9A52-9DB77E37AE62}
+
+
+ {6ead20da-8b3b-4b7e-a987-e08ab26425f2}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files\nvapi
+
+
+ Header Files\nvapi
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/details.c b/plugins-extra/NvGpuPlugin/details.c
new file mode 100644
index 0000000..15cf896
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/details.c
@@ -0,0 +1,133 @@
+/*
+* Process Hacker Extra Plugins -
+* Nvidia GPU Plugin
+*
+* Copyright (C) 2015 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 "main.h"
+
+VOID NvUpdateDetails(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
+ )
+{
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT1, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryName()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT2, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryShortName()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT3, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryVbiosVersionString()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT4, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryRevision()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT5, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryDeviceId()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT6, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryRopsCount()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT7, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryShaderCount()))->Buffer);
+ //SetDlgItemText(Context->DetailsHandle, IDC_EDIT8, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryPciInfo()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT9, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryBusWidth()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT10, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryDriverVersion()))->Buffer);
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT11, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryPcbValue()))->Buffer);
+
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT12, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryDriverSettings()))->Buffer);
+
+
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT14, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryRamType()))->Buffer);
+ //SetDlgItemText(Context->DetailsHandle, IDC_EDIT13, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryRamMaker()))->Buffer);
+
+ //SetDlgItemText(Context->DetailsHandle, IDC_EDIT13, NvGpuDriverIsWHQL() ? L"WHQL" : L"");
+ SetDlgItemText(Context->DetailsHandle, IDC_EDIT13, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryFoundry()))->Buffer);
+}
+
+INT_PTR CALLBACK DetailsDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PPH_NVGPU_SYSINFO_CONTEXT context = NULL;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)lParam;
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_NCDESTROY)
+ {
+ RemoveProp(hwndDlg, L"Context");
+ }
+ }
+
+ if (context == NULL)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ context->DetailsHandle = hwndDlg;
+
+ PhCenterWindow(hwndDlg, GetParent(hwndDlg));
+
+ HBITMAP bitmapRefresh = NULL;
+ bitmapRefresh = LoadImageFromResources(96, 64, MAKEINTRESOURCE(IDB_NV_LOGO_PNG));
+ SendMessage(GetDlgItem(hwndDlg, IDC_NVIMAGE), STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)bitmapRefresh);
+ DeleteObject(bitmapRefresh);
+
+ NvUpdateDetails(context);
+ }
+ break;
+ case WM_DESTROY:
+ {
+ context->DetailsHandle = NULL;
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ case IDOK:
+ EndDialog(hwndDlg, IDOK);
+ break;
+ }
+ }
+ break;
+ case MSG_UPDATE:
+ {
+ NvUpdateDetails(context);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID ShowDetailsDialog(
+ _In_ HWND ParentHandle,
+ _In_ PVOID Context
+ )
+{
+ DialogBoxParam(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_GPU_DETAILS),
+ ParentHandle,
+ DetailsDlgProc,
+ (LPARAM)Context
+ );
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/graph.c b/plugins-extra/NvGpuPlugin/graph.c
new file mode 100644
index 0000000..e4efba9
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/graph.c
@@ -0,0 +1,834 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+static RECT NormalGraphTextMargin = { 5, 5, 5, 5 };
+static RECT NormalGraphTextPadding = { 3, 3, 3, 3 };
+
+INT_PTR CALLBACK NvGpuPanelDialogProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PPH_NVGPU_SYSINFO_CONTEXT context = NULL;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)lParam;
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_NCDESTROY)
+ {
+ RemoveProp(hwndDlg, L"Context");
+ }
+ }
+
+ if (context == NULL)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch (GET_WM_COMMAND_ID(wParam, lParam))
+ {
+ case IDC_DETAILS:
+ {
+ ShowDetailsDialog(GetParent(hwndDlg), context);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID NvGpuCreateGraphs(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
+ )
+{
+ Context->GpuGraphHandle = CreateWindow(
+ PH_GRAPH_CLASSNAME,
+ NULL,
+ WS_VISIBLE | WS_CHILD | WS_BORDER,
+ 0,
+ 0,
+ 3,
+ 3,
+ Context->WindowHandle,
+ NULL,
+ NULL,
+ NULL
+ );
+ Graph_SetTooltip(Context->GpuGraphHandle, TRUE);
+
+ Context->MemGraphHandle = CreateWindow(
+ PH_GRAPH_CLASSNAME,
+ NULL,
+ WS_VISIBLE | WS_CHILD | WS_BORDER,
+ 0,
+ 0,
+ 3,
+ 3,
+ Context->WindowHandle,
+ NULL,
+ NULL,
+ NULL
+ );
+ Graph_SetTooltip(Context->MemGraphHandle, TRUE);
+
+ Context->SharedGraphHandle = CreateWindow(
+ PH_GRAPH_CLASSNAME,
+ NULL,
+ WS_VISIBLE | WS_CHILD | WS_BORDER,
+ 0,
+ 0,
+ 3,
+ 3,
+ Context->WindowHandle,
+ NULL,
+ NULL,
+ NULL
+ );
+ Graph_SetTooltip(Context->SharedGraphHandle, TRUE);
+
+ Context->BusGraphHandle = CreateWindow(
+ PH_GRAPH_CLASSNAME,
+ NULL,
+ WS_VISIBLE | WS_CHILD | WS_BORDER,
+ 0,
+ 0,
+ 3,
+ 3,
+ Context->WindowHandle,
+ NULL,
+ NULL,
+ NULL
+ );
+ Graph_SetTooltip(Context->BusGraphHandle, TRUE);
+}
+
+VOID NvGpuLayoutGraphs(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
+ )
+{
+ RECT clientRect;
+ RECT labelRect;
+ ULONG graphWidth;
+ ULONG graphHeight;
+ HDWP deferHandle;
+ ULONG y;
+
+#define ET_GPU_PADDING 3
+
+ PhLayoutManagerLayout(&Context->LayoutManager);
+
+ GetClientRect(Context->WindowHandle, &clientRect);
+ GetClientRect(Context->GpuLabelHandle, &labelRect);
+
+ graphWidth = clientRect.right - Context->GpuGraphMargin.left - Context->GpuGraphMargin.right;
+ graphHeight = (clientRect.bottom - Context->GpuGraphMargin.top - Context->GpuGraphMargin.bottom - labelRect.bottom * 4 - ET_GPU_PADDING * 5) / 4;
+
+ deferHandle = BeginDeferWindowPos(8);
+ y = Context->GpuGraphMargin.top;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->GpuLabelHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += labelRect.bottom + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->GpuGraphHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ graphWidth,
+ graphHeight,
+ SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += graphHeight + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->MemLabelHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += labelRect.bottom + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->MemGraphHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ graphWidth,
+ graphHeight,
+ SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += graphHeight + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->SharedLabelHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += labelRect.bottom + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->SharedGraphHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ graphWidth,
+ graphHeight,
+ SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += graphHeight + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->BusLabelHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER
+ );
+ y += labelRect.bottom + ET_GPU_PADDING;
+
+ deferHandle = DeferWindowPos(
+ deferHandle,
+ Context->BusGraphHandle,
+ NULL,
+ Context->GpuGraphMargin.left,
+ y,
+ graphWidth,
+ clientRect.bottom - Context->GpuGraphMargin.bottom - y,
+ SWP_NOACTIVATE | SWP_NOZORDER
+ );
+
+ EndDeferWindowPos(deferHandle);
+}
+
+VOID NvGpuNotifyUsageGraph(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context,
+ _In_ NMHDR *Header
+ )
+{
+ switch (Header->code)
+ {
+ case GCN_GETDRAWINFO:
+ {
+ PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
+ PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
+
+ drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
+ Context->Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
+ PhGraphStateGetDrawInfo(&Context->GpuGraphState, getDrawInfo, GpuUtilizationHistory.Count);
+
+ if (PhGetIntegerSetting(L"GraphShowText"))
+ {
+ HDC hdc = Graph_GetBufferedContext(Context->GpuGraphHandle);
+
+ PhMoveReference(&Context->GpuGraphState.Text,
+ PhFormatString(L"%.0f%%", GpuCurrentGpuUsage * 100)
+ );
+
+ SelectObject(hdc, PhApplicationFont);
+ PhSetGraphText(hdc, drawInfo, &Context->GpuGraphState.Text->sr,
+ &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
+ }
+ else
+ {
+ drawInfo->Text.Buffer = NULL;
+ }
+
+ if (!Context->GpuGraphState.Valid)
+ {
+ PhCopyCircularBuffer_FLOAT(&GpuUtilizationHistory, Context->GpuGraphState.Data1, drawInfo->LineDataCount);
+ Context->GpuGraphState.Valid = TRUE;
+ }
+ }
+ break;
+ case GCN_GETTOOLTIPTEXT:
+ {
+ PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
+
+ if (getTooltipText->Index < getTooltipText->TotalCount)
+ {
+ if (Context->GpuGraphState.TooltipIndex != getTooltipText->Index)
+ {
+ FLOAT gpuUsageValue;
+
+ gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&GpuUtilizationHistory, getTooltipText->Index);
+
+ PhMoveReference(&Context->GpuGraphState.TooltipText, PhFormatString(
+ L"%.0f%%\n%s",
+ gpuUsageValue * 100,
+ ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
+ ));
+ }
+
+ getTooltipText->Text = Context->GpuGraphState.TooltipText->sr;
+ }
+ }
+ break;
+ }
+}
+
+VOID NvGpuNotifyMemoryGraph(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context,
+ _In_ NMHDR *Header
+ )
+{
+ switch (Header->code)
+ {
+ case GCN_GETDRAWINFO:
+ {
+ PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
+ PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
+
+ drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
+ Context->Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorPhysical"), 0);
+ PhGraphStateGetDrawInfo(&Context->MemGraphState, getDrawInfo, GpuMemoryHistory.Count);
+
+ if (PhGetIntegerSetting(L"GraphShowText"))
+ {
+ HDC hdc = Graph_GetBufferedContext(Context->MemGraphHandle);
+
+ PhMoveReference(&Context->MemGraphState.Text, PhFormatString(
+ L"%s / %s (%.2f%%)",
+ PhaFormatSize(UInt32x32To64(GpuCurrentMemUsage, 1024), -1)->Buffer,
+ PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer,
+ (FLOAT)GpuCurrentMemUsage / GpuMemoryLimit * 100
+ ));
+
+ SelectObject(hdc, PhApplicationFont);
+ PhSetGraphText(hdc, drawInfo, &Context->MemGraphState.Text->sr,
+ &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
+ }
+ else
+ {
+ drawInfo->Text.Buffer = NULL;
+ }
+
+ if (!Context->MemGraphState.Valid)
+ {
+ for (ULONG i = 0; i < drawInfo->LineDataCount; i++)
+ {
+ Context->MemGraphState.Data1[i] = (FLOAT)PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, i);
+ }
+
+ if (GpuMemoryLimit != 0)
+ {
+ // Scale the data.
+ PhDivideSinglesBySingle(
+ Context->MemGraphState.Data1,
+ (FLOAT)GpuMemoryLimit,
+ drawInfo->LineDataCount
+ );
+ }
+
+ Context->MemGraphState.Valid = TRUE;
+ }
+ }
+ break;
+ case GCN_GETTOOLTIPTEXT:
+ {
+ PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
+
+ if (getTooltipText->Index < getTooltipText->TotalCount)
+ {
+ if (Context->MemGraphState.TooltipIndex != getTooltipText->Index)
+ {
+ ULONG usedPages;
+
+ usedPages = PhGetItemCircularBuffer_ULONG(&GpuMemoryHistory, getTooltipText->Index);
+
+ PhMoveReference(&Context->MemGraphState.TooltipText, PhFormatString(
+ L"%s / %s (%.2f%%)\n%s",
+ PhaFormatSize(UInt32x32To64(usedPages, 1024), -1)->Buffer,
+ PhaFormatSize(UInt32x32To64(GpuMemoryLimit, 1024), -1)->Buffer,
+ (FLOAT)usedPages / GpuMemoryLimit * 100,
+ ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
+ ));
+ }
+
+ getTooltipText->Text = Context->MemGraphState.TooltipText->sr;
+ }
+ }
+ break;
+ }
+}
+
+VOID NvGpuNotifySharedGraph(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context,
+ _In_ NMHDR *Header
+ )
+{
+ switch (Header->code)
+ {
+ case GCN_GETDRAWINFO:
+ {
+ PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
+ PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
+
+ drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
+ Context->Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
+ PhGraphStateGetDrawInfo(&Context->SharedGraphState, getDrawInfo, GpuBoardHistory.Count);
+
+ if (PhGetIntegerSetting(L"GraphShowText"))
+ {
+ HDC hdc = Graph_GetBufferedContext(Context->SharedGraphHandle);
+
+ PhMoveReference(&Context->SharedGraphState.Text, PhFormatString(
+ L"%.0f%%",
+ (FLOAT)GpuCurrentCoreUsage * 100
+ ));
+
+ SelectObject(hdc, PhApplicationFont);
+ PhSetGraphText(hdc, drawInfo, &Context->SharedGraphState.Text->sr,
+ &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
+ }
+ else
+ {
+ drawInfo->Text.Buffer = NULL;
+ }
+
+ if (!Context->SharedGraphState.Valid)
+ {
+ PhCopyCircularBuffer_FLOAT(&GpuBoardHistory, Context->SharedGraphState.Data1, drawInfo->LineDataCount);
+ Context->SharedGraphState.Valid = TRUE;
+ }
+ }
+ break;
+ case GCN_GETTOOLTIPTEXT:
+ {
+ PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
+
+ if (getTooltipText->Index < getTooltipText->TotalCount)
+ {
+ if (Context->SharedGraphState.TooltipIndex != getTooltipText->Index)
+ {
+ FLOAT usedPages;
+
+ usedPages = PhGetItemCircularBuffer_FLOAT(&GpuBoardHistory, getTooltipText->Index);
+
+ PhMoveReference(&Context->SharedGraphState.TooltipText, PhFormatString(
+ L"%.0f%%\n%s",
+ usedPages * 100,
+ ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
+ ));
+ }
+
+ getTooltipText->Text = Context->SharedGraphState.TooltipText->sr;
+ }
+ }
+ break;
+ }
+}
+
+VOID NvGpuNotifyBusGraph(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context,
+ _In_ NMHDR *Header
+ )
+{
+ switch (Header->code)
+ {
+ case GCN_GETDRAWINFO:
+ {
+ PPH_GRAPH_GETDRAWINFO getDrawInfo = (PPH_GRAPH_GETDRAWINFO)Header;
+ PPH_GRAPH_DRAW_INFO drawInfo = getDrawInfo->DrawInfo;
+
+ drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
+ Context->Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
+ PhGraphStateGetDrawInfo(&Context->BusGraphState, getDrawInfo, GpuBusHistory.Count);
+
+ if (PhGetIntegerSetting(L"GraphShowText"))
+ {
+ HDC hdc = Graph_GetBufferedContext(Context->BusGraphHandle);
+
+ PhMoveReference(&Context->BusGraphState.Text, PhFormatString(
+ L"%.0f%%",
+ (FLOAT)GpuCurrentBusUsage * 100
+ ));
+
+ SelectObject(hdc, PhApplicationFont);
+ PhSetGraphText(hdc, drawInfo, &Context->BusGraphState.Text->sr,
+ &NormalGraphTextMargin, &NormalGraphTextPadding, PH_ALIGN_TOP | PH_ALIGN_LEFT);
+ }
+ else
+ {
+ drawInfo->Text.Buffer = NULL;
+ }
+
+ if (!Context->BusGraphState.Valid)
+ {
+ PhCopyCircularBuffer_FLOAT(&GpuBusHistory, Context->BusGraphState.Data1, drawInfo->LineDataCount);
+ Context->BusGraphState.Valid = TRUE;
+ }
+ }
+ break;
+ case GCN_GETTOOLTIPTEXT:
+ {
+ PPH_GRAPH_GETTOOLTIPTEXT getTooltipText = (PPH_GRAPH_GETTOOLTIPTEXT)Header;
+
+ if (getTooltipText->Index < getTooltipText->TotalCount)
+ {
+ if (Context->BusGraphState.TooltipIndex != getTooltipText->Index)
+ {
+ FLOAT busUsage;
+
+ busUsage = PhGetItemCircularBuffer_FLOAT(&GpuBusHistory, getTooltipText->Index);
+
+ PhMoveReference(&Context->BusGraphState.TooltipText, PhFormatString(
+ L"%.0f%%\n%s",
+ busUsage * 100,
+ ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
+ ));
+ }
+
+ getTooltipText->Text = Context->BusGraphState.TooltipText->sr;
+ }
+ }
+ break;
+ }
+}
+
+VOID NvGpuUpdateGraphs(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
+ )
+{
+ Context->GpuGraphState.Valid = FALSE;
+ Context->GpuGraphState.TooltipIndex = -1;
+ Graph_MoveGrid(Context->GpuGraphHandle, 1);
+ Graph_Draw(Context->GpuGraphHandle);
+ Graph_UpdateTooltip(Context->GpuGraphHandle);
+ InvalidateRect(Context->GpuGraphHandle, NULL, FALSE);
+
+ Context->MemGraphState.Valid = FALSE;
+ Context->MemGraphState.TooltipIndex = -1;
+ Graph_MoveGrid(Context->MemGraphHandle, 1);
+ Graph_Draw(Context->MemGraphHandle);
+ Graph_UpdateTooltip(Context->MemGraphHandle);
+ InvalidateRect(Context->MemGraphHandle, NULL, FALSE);
+
+ Context->SharedGraphState.Valid = FALSE;
+ Context->SharedGraphState.TooltipIndex = -1;
+ Graph_MoveGrid(Context->SharedGraphHandle, 1);
+ Graph_Draw(Context->SharedGraphHandle);
+ Graph_UpdateTooltip(Context->SharedGraphHandle);
+ InvalidateRect(Context->SharedGraphHandle, NULL, FALSE);
+
+ Context->BusGraphState.Valid = FALSE;
+ Context->BusGraphState.TooltipIndex = -1;
+ Graph_MoveGrid(Context->BusGraphHandle, 1);
+ Graph_Draw(Context->BusGraphHandle);
+ Graph_UpdateTooltip(Context->BusGraphHandle);
+ InvalidateRect(Context->BusGraphHandle, NULL, FALSE);
+}
+
+VOID NvGpuUpdatePanel(
+ _Inout_ PPH_NVGPU_SYSINFO_CONTEXT Context
+ )
+{
+ SetDlgItemText(Context->GpuPanel, IDC_CLOCK_CORE, PhaFormatString(L"%lu MHz", GpuCurrentCoreClock)->Buffer);
+ SetDlgItemText(Context->GpuPanel, IDC_CLOCK_MEMORY, PhaFormatString(L"%lu MHz", GpuCurrentMemoryClock)->Buffer);
+ SetDlgItemText(Context->GpuPanel, IDC_CLOCK_SHADER, PhaFormatString(L"%lu MHz", GpuCurrentShaderClock)->Buffer);
+ SetDlgItemText(Context->GpuPanel, IDC_FAN_PERCENT, ((PPH_STRING)PhAutoDereferenceObject(NvGpuQueryFanSpeed()))->Buffer);
+
+ if (PhGetIntegerSetting(SETTING_NAME_ENABLE_FAHRENHEIT))
+ {
+ FLOAT fahrenheit = (FLOAT)(GpuCurrentCoreTemp * 1.8 + 32);
+
+ SetDlgItemText(Context->GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%.1f\u00b0F", fahrenheit)->Buffer);
+ }
+ else
+ {
+ SetDlgItemText(Context->GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%lu\u00b0C", GpuCurrentCoreTemp)->Buffer);
+ }
+
+ //SetDlgItemText(Context->GpuPanel, IDC_TEMP_VALUE, PhaFormatString(L"%s\u00b0C", PhaFormatUInt64(GpuCurrentBoardTemp, TRUE)->Buffer)->Buffer);
+ SetDlgItemText(Context->GpuPanel, IDC_VOLTAGE, PhaFormatString(L"%lu mV", GpuCurrentVoltage)->Buffer);
+}
+
+INT_PTR CALLBACK NvGpuDialogProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ PPH_NVGPU_SYSINFO_CONTEXT context = NULL;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)lParam;
+
+ SetProp(hwndDlg, L"Context", (HANDLE)context);
+ }
+ else
+ {
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)GetProp(hwndDlg, L"Context");
+
+ if (uMsg == WM_NCDESTROY)
+ {
+ PhDeleteLayoutManager(&context->LayoutManager);
+
+ PhDeleteGraphState(&context->GpuGraphState);
+ PhDeleteGraphState(&context->MemGraphState);
+ PhDeleteGraphState(&context->SharedGraphState);
+ PhDeleteGraphState(&context->BusGraphState);
+
+ if (context->GpuGraphHandle)
+ DestroyWindow(context->GpuGraphHandle);
+ if (context->MemGraphHandle)
+ DestroyWindow(context->MemGraphHandle);
+ if (context->SharedGraphHandle)
+ DestroyWindow(context->SharedGraphHandle);
+ if (context->BusGraphHandle)
+ DestroyWindow(context->BusGraphHandle);
+ if (context->GpuPanel)
+ DestroyWindow(context->GpuPanel);
+
+ RemoveProp(hwndDlg, L"Context");
+ }
+ }
+
+ if (context == NULL)
+ return FALSE;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ PPH_LAYOUT_ITEM graphItem;
+ PPH_LAYOUT_ITEM panelItem;
+
+ context->WindowHandle = hwndDlg;
+
+ context->GpuLabelHandle = GetDlgItem(hwndDlg, IDC_GPU_L);
+ context->MemLabelHandle = GetDlgItem(hwndDlg, IDC_MEMORY_L);
+ context->SharedLabelHandle = GetDlgItem(hwndDlg, IDC_SHARED_L);
+ context->BusLabelHandle = GetDlgItem(hwndDlg, IDC_BUS_L);
+
+ PhInitializeGraphState(&context->GpuGraphState);
+ PhInitializeGraphState(&context->MemGraphState);
+ PhInitializeGraphState(&context->SharedGraphState);
+ PhInitializeGraphState(&context->BusGraphState);
+
+ PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
+ PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GPUNAME), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
+ graphItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GRAPH_LAYOUT), NULL, PH_ANCHOR_ALL);
+ context->GpuGraphMargin = graphItem->Margin;
+ panelItem = PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_PANEL_LAYOUT), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_TITLE), WM_SETFONT, (WPARAM)context->Section->Parameters->LargeFont, FALSE);
+ SendMessage(GetDlgItem(hwndDlg, IDC_GPUNAME), WM_SETFONT, (WPARAM)context->Section->Parameters->MediumFont, FALSE);
+ SetDlgItemText(hwndDlg, IDC_GPUNAME, context->GpuName->Buffer);
+
+ context->GpuPanel = CreateDialogParam(PluginInstance->DllBase, MAKEINTRESOURCE(IDD_GPU_PANEL), hwndDlg, NvGpuPanelDialogProc, (LPARAM)context);
+ ShowWindow(context->GpuPanel, SW_SHOW);
+ PhAddLayoutItemEx(&context->LayoutManager, context->GpuPanel, NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM, panelItem->Margin);
+
+ NvGpuCreateGraphs(context);
+
+ NvGpuUpdateValues();
+ NvGpuUpdateGraphs(context);
+ NvGpuUpdatePanel(context);
+ }
+ break;
+ case WM_SIZE:
+ NvGpuLayoutGraphs(context);
+ break;
+ case WM_NOTIFY:
+ {
+ NMHDR* header = (NMHDR*)lParam;
+
+ if (header->hwndFrom == context->GpuGraphHandle)
+ {
+ NvGpuNotifyUsageGraph(context, header);
+ }
+ else if (header->hwndFrom == context->MemGraphHandle)
+ {
+ NvGpuNotifyMemoryGraph(context, header);
+ }
+ else if (header->hwndFrom == context->SharedGraphHandle)
+ {
+ NvGpuNotifySharedGraph(context, header);
+ }
+ else if (header->hwndFrom == context->BusGraphHandle)
+ {
+ NvGpuNotifyBusGraph(context, header);
+ }
+ }
+ break;
+ case MSG_UPDATE:
+ {
+ NvGpuUpdateGraphs(context);
+ NvGpuUpdatePanel(context);
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN NvGpuSectionCallback(
+ _In_ PPH_SYSINFO_SECTION Section,
+ _In_ PH_SYSINFO_SECTION_MESSAGE Message,
+ _In_opt_ PVOID Parameter1,
+ _In_opt_ PVOID Parameter2
+ )
+{
+ PPH_NVGPU_SYSINFO_CONTEXT context = (PPH_NVGPU_SYSINFO_CONTEXT)Section->Context;
+
+ switch (Message)
+ {
+ case SysInfoCreate:
+ return TRUE;
+ case SysInfoDestroy:
+ {
+ if (context->GpuName)
+ PhDereferenceObject(context->GpuName);
+
+ PhFree(context);
+ }
+ return TRUE;
+ case SysInfoTick:
+ {
+ if (context->WindowHandle)
+ {
+ PostMessage(context->WindowHandle, MSG_UPDATE, 0, 0);
+ }
+
+ if (context->DetailsHandle)
+ {
+ PostMessage(context->DetailsHandle, MSG_UPDATE, 0, 0);
+ }
+ }
+ return TRUE;
+ case SysInfoCreateDialog:
+ {
+ PPH_SYSINFO_CREATE_DIALOG createDialog = (PPH_SYSINFO_CREATE_DIALOG)Parameter1;
+
+ createDialog->Instance = PluginInstance->DllBase;
+ createDialog->Template = MAKEINTRESOURCE(IDD_GPU_DIALOG);
+ createDialog->DialogProc = NvGpuDialogProc;
+ createDialog->Parameter = context;
+ }
+ return TRUE;
+ case SysInfoGraphGetDrawInfo:
+ {
+ PPH_GRAPH_DRAW_INFO drawInfo = (PPH_GRAPH_DRAW_INFO)Parameter1;
+
+ drawInfo->Flags = PH_GRAPH_USE_GRID_X | PH_GRAPH_USE_GRID_Y;
+ Section->Parameters->ColorSetupFunction(drawInfo, PhGetIntegerSetting(L"ColorCpuKernel"), 0);
+ PhGetDrawInfoGraphBuffers(&Section->GraphState.Buffers, drawInfo, GpuUtilizationHistory.Count);
+
+ if (!Section->GraphState.Valid)
+ {
+ PhCopyCircularBuffer_FLOAT(&GpuUtilizationHistory, Section->GraphState.Data1, drawInfo->LineDataCount);
+ Section->GraphState.Valid = TRUE;
+ }
+ }
+ return TRUE;
+ case SysInfoGraphGetTooltipText:
+ {
+ FLOAT gpuUsageValue;
+ PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT getTooltipText = (PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT)Parameter1;
+
+ gpuUsageValue = PhGetItemCircularBuffer_FLOAT(&GpuUtilizationHistory, getTooltipText->Index);
+
+ PhMoveReference(&Section->GraphState.TooltipText, PhFormatString(
+ L"%.0f%%\n%s",
+ gpuUsageValue * 100,
+ ((PPH_STRING)PhAutoDereferenceObject(PhGetStatisticsTimeString(NULL, getTooltipText->Index)))->Buffer
+ ));
+
+ getTooltipText->Text = Section->GraphState.TooltipText->sr;
+ }
+ return TRUE;
+ case SysInfoGraphDrawPanel:
+ {
+ PPH_SYSINFO_DRAW_PANEL drawPanel = (PPH_SYSINFO_DRAW_PANEL)Parameter1;
+
+ drawPanel->Title = PhCreateString(Section->Name.Buffer);
+ drawPanel->SubTitle = PhFormatString(
+ L"%.0f%%",
+ GpuCurrentGpuUsage * 100
+ );
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+VOID NvGpuSysInfoInitializing(
+ _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers
+ )
+{
+ PH_SYSINFO_SECTION section;
+ PPH_NVGPU_SYSINFO_CONTEXT context;
+
+ context = (PPH_NVGPU_SYSINFO_CONTEXT)PhAllocate(sizeof(PH_NVGPU_SYSINFO_CONTEXT));
+ memset(context, 0, sizeof(PH_NVGPU_SYSINFO_CONTEXT));
+ memset(§ion, 0, sizeof(PH_SYSINFO_SECTION));
+
+ section.Context = context;
+ section.Callback = NvGpuSectionCallback;
+
+ context->GpuName = NvGpuQueryName();
+ PhInitializeStringRef(§ion.Name, context->GpuName->Buffer);
+
+ context->Section = Pointers->CreateSection(§ion);
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/main.c b/plugins-extra/NvGpuPlugin/main.c
new file mode 100644
index 0000000..b0f16d2
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/main.c
@@ -0,0 +1,155 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+
+BOOLEAN NvApiInitialized = FALSE;
+PPH_PLUGIN PluginInstance = NULL;
+PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
+PH_CALLBACK_REGISTRATION PluginUnloadCallbackRegistration;
+PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
+PH_CALLBACK_REGISTRATION ProcessesUpdatedCallbackRegistration;
+PH_CALLBACK_REGISTRATION SystemInformationInitializingCallbackRegistration;
+
+VOID NTAPI LoadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ if (PhGetIntegerSetting(SETTING_NAME_ENABLE_MONITORING))
+ {
+ NvApiInitialized = InitializeNvApi();
+ }
+
+ if (NvApiInitialized)
+ {
+ NvGpuInitialize();
+ }
+}
+
+VOID NTAPI UnloadCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ NOTHING;
+}
+
+VOID NTAPI ShowOptionsCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ ShowOptionsDialog((HWND)Parameter);
+}
+
+VOID NTAPI ProcessesUpdatedCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ if (NvApiInitialized)
+ {
+ NvGpuUpdate();
+ }
+}
+
+VOID NTAPI SystemInformationInitializingCallback(
+ _In_opt_ PVOID Parameter,
+ _In_opt_ PVOID Context
+ )
+{
+ PPH_PLUGIN_SYSINFO_POINTERS pluginEntry = (PPH_PLUGIN_SYSINFO_POINTERS)Parameter;
+
+ if (NvApiInitialized)
+ {
+ NvGpuSysInfoInitializing(pluginEntry);
+ }
+}
+
+LOGICAL DllMain(
+ _In_ HINSTANCE Instance,
+ _In_ ULONG Reason,
+ _Reserved_ PVOID Reserved
+ )
+{
+ switch (Reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ PPH_PLUGIN_INFORMATION info;
+ PH_SETTING_CREATE settings[] =
+ {
+ { IntegerSettingType, SETTING_NAME_ENABLE_MONITORING, L"1" },
+ { IntegerSettingType, SETTING_NAME_ENABLE_FAHRENHEIT, L"0" }
+ };
+
+ PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
+
+ if (!PluginInstance)
+ return FALSE;
+
+ info->DisplayName = L"Nvidia GPU";
+ info->Author = L"dmex";
+ info->Description = L"Plugin for extended Nvidia GPU monitoring via the System Information window.";
+ info->HasOptions = TRUE;
+
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
+ LoadCallback,
+ NULL,
+ &PluginLoadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackUnload),
+ UnloadCallback,
+ NULL,
+ &PluginUnloadCallbackRegistration
+ );
+ PhRegisterCallback(
+ PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
+ ShowOptionsCallback,
+ NULL,
+ &PluginShowOptionsCallbackRegistration
+ );
+
+ PhRegisterCallback(
+ &PhProcessesUpdatedEvent,
+ ProcessesUpdatedCallback,
+ NULL,
+ &ProcessesUpdatedCallbackRegistration
+ );
+
+ PhRegisterCallback(
+ PhGetGeneralCallback(GeneralCallbackSystemInformationInitializing),
+ SystemInformationInitializingCallback,
+ NULL,
+ &SystemInformationInitializingCallbackRegistration
+ );
+
+ PhAddSettings(settings, ARRAYSIZE(settings));
+ }
+ break;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/main.h b/plugins-extra/NvGpuPlugin/main.h
new file mode 100644
index 0000000..1cfc0dc
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/main.h
@@ -0,0 +1,142 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#ifndef _NVGPU_H_
+#define _NVGPU_H_
+
+#define PLUGIN_NAME L"dmex.NvGpuPlugin"
+#define SETTING_NAME_ENABLE_MONITORING (PLUGIN_NAME L".Enabled")
+#define SETTING_NAME_ENABLE_FAHRENHEIT (PLUGIN_NAME L".EnableFahrenheit")
+
+#define CINTERFACE
+#define COBJMACROS
+#include
+#include
+#include
+#include
+
+#include "resource.h"
+
+#define MSG_UPDATE (WM_APP + 1)
+
+extern BOOLEAN NvApiInitialized;
+extern PPH_PLUGIN PluginInstance;
+
+extern ULONG GpuMemoryLimit;
+extern FLOAT GpuCurrentGpuUsage;
+extern FLOAT GpuCurrentCoreUsage;
+extern FLOAT GpuCurrentBusUsage;
+extern ULONG GpuCurrentMemUsage;
+extern ULONG GpuCurrentMemSharedUsage;
+extern ULONG GpuCurrentCoreTemp;
+extern ULONG GpuCurrentBoardTemp;
+extern ULONG GpuCurrentCoreClock;
+extern ULONG GpuCurrentMemoryClock;
+extern ULONG GpuCurrentShaderClock;
+extern ULONG GpuCurrentVoltage;
+
+BOOLEAN InitializeNvApi(VOID);
+BOOLEAN DestroyNvApi(VOID);
+
+PPH_STRING NvGpuQueryDriverVersion(VOID);
+PPH_STRING NvGpuQueryVbiosVersionString(VOID);
+PPH_STRING NvGpuQueryName(VOID);
+PPH_STRING NvGpuQueryShortName(VOID);
+PPH_STRING NvGpuQueryRevision(VOID);
+PPH_STRING NvGpuQueryRamType(VOID);
+PPH_STRING NvGpuQueryFoundry(VOID);
+PPH_STRING NvGpuQueryDeviceId(VOID);
+PPH_STRING NvGpuQueryRopsCount(VOID);
+PPH_STRING NvGpuQueryShaderCount(VOID);
+PPH_STRING NvGpuQueryPciInfo(VOID);
+PPH_STRING NvGpuQueryBusWidth(VOID);
+PPH_STRING NvGpuQueryPcbValue(VOID);
+PPH_STRING NvGpuQueryDriverSettings(VOID);
+PPH_STRING NvGpuQueryFanSpeed(VOID);
+
+BOOLEAN NvGpuDriverIsWHQL(VOID);
+
+VOID NvGpuUpdateValues(VOID);
+
+typedef struct _PH_NVGPU_SYSINFO_CONTEXT
+{
+ PPH_STRING GpuName;
+ HWND WindowHandle;
+ HWND DetailsHandle;
+ PPH_SYSINFO_SECTION Section;
+ PH_LAYOUT_MANAGER LayoutManager;
+
+ RECT GpuGraphMargin;
+ HWND GpuPanel;
+
+ HWND GpuLabelHandle;
+ HWND MemLabelHandle;
+ HWND SharedLabelHandle;
+ HWND BusLabelHandle;
+
+ HWND GpuGraphHandle;
+ HWND MemGraphHandle;
+ HWND SharedGraphHandle;
+ HWND BusGraphHandle;
+
+ PH_GRAPH_STATE GpuGraphState;
+ PH_GRAPH_STATE MemGraphState;
+ PH_GRAPH_STATE SharedGraphState;
+ PH_GRAPH_STATE BusGraphState;
+
+} PH_NVGPU_SYSINFO_CONTEXT, *PPH_NVGPU_SYSINFO_CONTEXT;
+
+
+extern PH_CIRCULAR_BUFFER_FLOAT GpuUtilizationHistory;
+extern PH_CIRCULAR_BUFFER_ULONG GpuMemoryHistory;
+extern PH_CIRCULAR_BUFFER_FLOAT GpuBoardHistory;
+extern PH_CIRCULAR_BUFFER_FLOAT GpuBusHistory;
+
+VOID NvGpuInitialize(
+ VOID
+ );
+
+VOID NvGpuUpdate(
+ VOID
+ );
+
+
+VOID NvGpuSysInfoInitializing(
+ _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers
+ );
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PCWSTR Name
+ );
+
+VOID ShowOptionsDialog(
+ _In_ HWND ParentHandle
+ );
+
+VOID ShowDetailsDialog(
+ _In_ HWND ParentHandle,
+ _In_ PVOID Context
+ );
+
+#endif _NVGPU_H_
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/nvapi/nvapi.h b/plugins-extra/NvGpuPlugin/nvapi/nvapi.h
new file mode 100644
index 0000000..387b83d
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/nvapi/nvapi.h
@@ -0,0 +1,9305 @@
+#include "nvapi_lite_common.h"
+
+ /***************************************************************************\
+|* *|
+|* Copyright 2005-2010 NVIDIA Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: *|
+|* *|
+|* This source code is subject to NVIDIA ownership rights under U.S. *|
+|* and international Copyright laws. Users and possessors of this *|
+|* source code are hereby granted a nonexclusive, royalty-free *|
+|* license to use this code in individual and commercial software. *|
+|* *|
+|* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE *|
+|* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR *|
+|* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH *|
+|* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF *|
+|* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR *|
+|* PURPOSE. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, *|
+|* INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES *|
+|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN *|
+|* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *|
+|* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE *|
+|* CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial item" *|
+|* as that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting *|
+|* of "commercial computer software" and "commercial computer software *|
+|* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) *|
+|* and is provided to the U.S. Government only as a commercial end item. *|
+|* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through *|
+|* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the *|
+|* source code with only those rights set forth herein. *|
+|* *|
+|* Any use of this source code in individual and commercial software must *|
+|* include, in the user documentation and internal comments to the code, *|
+|* the above Disclaimer and U.S. Government End Users Notice. *|
+|* *|
+|* *|
+ \***************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Date: Sep 30, 2014
+// File: nvapi.h
+//
+// NvAPI provides an interface to NVIDIA devices. This file contains the
+// interface constants, structure definitions and function prototypes.
+//
+// Target Profile: developer
+// Target Platform: windows
+//
+///////////////////////////////////////////////////////////////////////////////
+#ifndef _NVAPI_H
+#define _NVAPI_H
+
+#include // Make sure we have consistent structure packings
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ====================================================
+// Universal NvAPI Definitions
+// ====================================================
+#ifndef _WIN32
+#define __cdecl
+#endif
+
+
+
+//! @}
+
+//! \ingroup nvapistatus
+#define NVAPI_API_NOT_INTIALIZED NVAPI_API_NOT_INITIALIZED //!< Fix typo in error code
+
+//! \ingroup nvapistatus
+#define NVAPI_INVALID_USER_PRIVILEDGE NVAPI_INVALID_USER_PRIVILEGE //!< Fix typo in error code
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Initialize
+//
+//! This function initializes the NvAPI library.
+//! This must be called before calling other NvAPI_ functions.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_ERROR An error occurred during the initialization process (generic error)
+//! \retval NVAPI_LIBRARYNOTFOUND Failed to load the NVAPI support library
+//! \retval NVAPI_OK Initialized
+//! \sa nvapistatus
+//! \ingroup nvapifunctions
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_Initialize();
+
+typedef NvAPI_Status (__cdecl *_NvAPI_Initialize)(VOID);
+_NvAPI_Initialize NvAPI_Initialize;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Unload
+//
+//! DESCRIPTION: Unloads NVAPI library. This must be the last function called.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! !! This is not thread safe. In a multithreaded environment, calling NvAPI_Unload !! \n
+//! !! while another thread is executing another NvAPI_XXX function, results in !! \n
+//! !! undefined behaviour and might even cause the application to crash. Developers !! \n
+//! !! must make sure that they are not in any other function before calling NvAPI_Unload. !! \n
+//!
+//!
+//! Unloading NvAPI library is not supported when the library is in a resource locked state.
+//! Some functions in the NvAPI library initiates an operation or allocates certain resources
+//! and there are corresponding functions available, to complete the operation or free the
+//! allocated resources. All such function pairs are designed to prevent unloading NvAPI library.
+//!
+//! For example, if NvAPI_Unload is called after NvAPI_XXX which locks a resource, it fails with
+//! NVAPI_ERROR. Developers need to call the corresponding NvAPI_YYY to unlock the resources,
+//! before calling NvAPI_Unload again.
+//!
+//! \retval ::NVAPI_ERROR One or more resources are locked and hence cannot unload NVAPI library
+//! \retval ::NVAPI_OK NVAPI library unloaded
+//!
+//! \ingroup nvapifunctions
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_Unload();
+
+typedef NvAPI_Status (__cdecl *_NvAPI_Unload)(VOID);
+_NvAPI_Unload NvAPI_Unload;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetErrorMessage
+//
+//! This function converts an NvAPI error code into a null terminated string.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \param nr The error code to convert
+//! \param szDesc The string corresponding to the error code
+//!
+//! \return NULL terminated string (always, never NULL)
+//! \ingroup nvapifunctions
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GetErrorMessage(NvAPI_Status nr,NvAPI_ShortString szDesc);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GetErrorMessage)(NvAPI_Status nr, NvAPI_ShortString szDesc);
+_NvAPI_GetErrorMessage NvAPI_GetErrorMessage;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetInterfaceVersionString
+//
+//! This function returns a string describing the version of the NvAPI library.
+//! The contents of the string are human readable. Do not assume a fixed
+//! format.
+//!
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \param szDesc User readable string giving NvAPI version information
+//!
+//! \return See \ref nvapistatus for the list of possible return values.
+//! \ingroup nvapifunctions
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetInterfaceVersionString(NvAPI_ShortString szDesc);
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// All display port related data types definition starts
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// This category is intentionally added before the #ifdef. The #endif should also be in the same scope
+#ifndef DISPLAYPORT_STRUCTS_DEFINED
+#define DISPLAYPORT_STRUCTS_DEFINED
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_LINK_RATE
+{
+ NV_DP_1_62GBPS = 6,
+ NV_DP_2_70GBPS = 0xA,
+ NV_DP_5_40GBPS = 0x14
+} NV_DP_LINK_RATE;
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_LANE_COUNT
+{
+ NV_DP_1_LANE = 1,
+ NV_DP_2_LANE = 2,
+ NV_DP_4_LANE = 4,
+} NV_DP_LANE_COUNT;
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_COLOR_FORMAT
+{
+ NV_DP_COLOR_FORMAT_RGB = 0,
+ NV_DP_COLOR_FORMAT_YCbCr422,
+ NV_DP_COLOR_FORMAT_YCbCr444,
+} NV_DP_COLOR_FORMAT;
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_COLORIMETRY
+{
+ NV_DP_COLORIMETRY_RGB = 0,
+ NV_DP_COLORIMETRY_YCbCr_ITU601,
+ NV_DP_COLORIMETRY_YCbCr_ITU709,
+} NV_DP_COLORIMETRY;
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_DYNAMIC_RANGE
+{
+ NV_DP_DYNAMIC_RANGE_VESA = 0,
+ NV_DP_DYNAMIC_RANGE_CEA,
+} NV_DP_DYNAMIC_RANGE;
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PORT_INFO.
+typedef enum _NV_DP_BPC
+{
+ NV_DP_BPC_DEFAULT = 0,
+ NV_DP_BPC_6,
+ NV_DP_BPC_8,
+ NV_DP_BPC_10,
+ NV_DP_BPC_12,
+ NV_DP_BPC_16,
+} NV_DP_BPC;
+
+#endif //#ifndef DISPLAYPORT_STRUCTS_DEFINED
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// All display port related data types definitions end
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetEDID
+//
+//! \fn NvAPI_GPU_GetEDID(NvPhysicalGpuHandle hPhysicalGpu, NvU32 displayOutputId, NV_EDID *pEDID)
+//! This function returns the EDID data for the specified GPU handle and connection bit mask.
+//! displayOutputId should have exactly 1 bit set to indicate a single display. See \ref handles.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pEDID is NULL; displayOutputId has 0 or > 1 bits set
+//! \retval NVAPI_OK *pEDID contains valid data.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \retval NVAPI_DATA_NOT_FOUND The requested display does not contain an EDID.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//! \ingroup gpu
+//! @{
+
+#define NV_EDID_V1_DATA_SIZE 256
+
+#define NV_EDID_DATA_SIZE NV_EDID_V1_DATA_SIZE
+
+typedef struct
+{
+ NvU32 version; //structure version
+ NvU8 EDID_Data[NV_EDID_DATA_SIZE];
+} NV_EDID_V1;
+
+//! Used in NvAPI_GPU_GetEDID()
+typedef struct
+{
+ NvU32 version; //!< Structure version
+ NvU8 EDID_Data[NV_EDID_DATA_SIZE];
+ NvU32 sizeofEDID;
+} NV_EDID_V2;
+
+//! Used in NvAPI_GPU_GetEDID()
+typedef struct
+{
+ NvU32 version; //!< Structure version
+ NvU8 EDID_Data[NV_EDID_DATA_SIZE];
+ NvU32 sizeofEDID;
+ NvU32 edidId; //!< ID which always returned in a monotonically increasing counter.
+ //!< Across a split-EDID read we need to verify that all calls returned the same edidId.
+ //!< This counter is incremented if we get the updated EDID.
+ NvU32 offset; //!< Which 256-byte page of the EDID we want to read. Start at 0.
+ //!< If the read succeeds with edidSize > NV_EDID_DATA_SIZE,
+ //!< call back again with offset+256 until we have read the entire buffer
+} NV_EDID_V3;
+
+typedef NV_EDID_V3 NV_EDID;
+
+#define NV_EDID_VER1 MAKE_NVAPI_VERSION(NV_EDID_V1,1)
+#define NV_EDID_VER2 MAKE_NVAPI_VERSION(NV_EDID_V2,2)
+#define NV_EDID_VER3 MAKE_NVAPI_VERSION(NV_EDID_V3,3)
+#define NV_EDID_VER NV_EDID_VER3
+
+//! @}
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_GetEDID(NvPhysicalGpuHandle hPhysicalGpu, NvU32 displayOutputId, NV_EDID *pEDID);
+
+//! \ingroup gpu
+//! Used in NV_GPU_CONNECTOR_DATA
+typedef enum _NV_GPU_CONNECTOR_TYPE
+{
+ NVAPI_GPU_CONNECTOR_VGA_15_PIN = 0x00000000,
+ NVAPI_GPU_CONNECTOR_TV_COMPOSITE = 0x00000010,
+ NVAPI_GPU_CONNECTOR_TV_SVIDEO = 0x00000011,
+ NVAPI_GPU_CONNECTOR_TV_HDTV_COMPONENT = 0x00000013,
+ NVAPI_GPU_CONNECTOR_TV_SCART = 0x00000014,
+ NVAPI_GPU_CONNECTOR_TV_COMPOSITE_SCART_ON_EIAJ4120 = 0x00000016,
+ NVAPI_GPU_CONNECTOR_TV_HDTV_EIAJ4120 = 0x00000017,
+ NVAPI_GPU_CONNECTOR_PC_POD_HDTV_YPRPB = 0x00000018,
+ NVAPI_GPU_CONNECTOR_PC_POD_SVIDEO = 0x00000019,
+ NVAPI_GPU_CONNECTOR_PC_POD_COMPOSITE = 0x0000001A,
+ NVAPI_GPU_CONNECTOR_DVI_I_TV_SVIDEO = 0x00000020,
+ NVAPI_GPU_CONNECTOR_DVI_I_TV_COMPOSITE = 0x00000021,
+ NVAPI_GPU_CONNECTOR_DVI_I = 0x00000030,
+ NVAPI_GPU_CONNECTOR_DVI_D = 0x00000031,
+ NVAPI_GPU_CONNECTOR_ADC = 0x00000032,
+ NVAPI_GPU_CONNECTOR_LFH_DVI_I_1 = 0x00000038,
+ NVAPI_GPU_CONNECTOR_LFH_DVI_I_2 = 0x00000039,
+ NVAPI_GPU_CONNECTOR_SPWG = 0x00000040,
+ NVAPI_GPU_CONNECTOR_OEM = 0x00000041,
+ NVAPI_GPU_CONNECTOR_DISPLAYPORT_EXTERNAL = 0x00000046,
+ NVAPI_GPU_CONNECTOR_DISPLAYPORT_INTERNAL = 0x00000047,
+ NVAPI_GPU_CONNECTOR_DISPLAYPORT_MINI_EXT = 0x00000048,
+ NVAPI_GPU_CONNECTOR_HDMI_A = 0x00000061,
+ NVAPI_GPU_CONNECTOR_HDMI_C_MINI = 0x00000063,
+ NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_1 = 0x00000064,
+ NVAPI_GPU_CONNECTOR_LFH_DISPLAYPORT_2 = 0x00000065,
+ NVAPI_GPU_CONNECTOR_VIRTUAL_WFD = 0x00000070,
+ NVAPI_GPU_CONNECTOR_UNKNOWN = 0xFFFFFFFF,
+} NV_GPU_CONNECTOR_TYPE;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// NvAPI_TVOutput Information
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup tvapi
+//! Used in NV_DISPLAY_TV_OUTPUT_INFO
+typedef enum _NV_DISPLAY_TV_FORMAT
+{
+ NV_DISPLAY_TV_FORMAT_NONE = 0,
+ NV_DISPLAY_TV_FORMAT_SD_NTSCM = 0x00000001,
+ NV_DISPLAY_TV_FORMAT_SD_NTSCJ = 0x00000002,
+ NV_DISPLAY_TV_FORMAT_SD_PALM = 0x00000004,
+ NV_DISPLAY_TV_FORMAT_SD_PALBDGH = 0x00000008,
+ NV_DISPLAY_TV_FORMAT_SD_PALN = 0x00000010,
+ NV_DISPLAY_TV_FORMAT_SD_PALNC = 0x00000020,
+ NV_DISPLAY_TV_FORMAT_SD_576i = 0x00000100,
+ NV_DISPLAY_TV_FORMAT_SD_480i = 0x00000200,
+ NV_DISPLAY_TV_FORMAT_ED_480p = 0x00000400,
+ NV_DISPLAY_TV_FORMAT_ED_576p = 0x00000800,
+ NV_DISPLAY_TV_FORMAT_HD_720p = 0x00001000,
+ NV_DISPLAY_TV_FORMAT_HD_1080i = 0x00002000,
+ NV_DISPLAY_TV_FORMAT_HD_1080p = 0x00004000,
+ NV_DISPLAY_TV_FORMAT_HD_720p50 = 0x00008000,
+ NV_DISPLAY_TV_FORMAT_HD_1080p24 = 0x00010000,
+ NV_DISPLAY_TV_FORMAT_HD_1080i50 = 0x00020000,
+ NV_DISPLAY_TV_FORMAT_HD_1080p50 = 0x00040000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp30 = 0x00080000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp30_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp30,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp25 = 0x00100000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp25_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp25,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp24 = 0x00200000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp24_3840 = NV_DISPLAY_TV_FORMAT_UHD_4Kp24,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp24_SMPTE = 0x00400000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp50_3840 = 0x00800000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp60_3840 = 0x00900000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp30_4096 = 0x00A00000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp25_4096 = 0x00B00000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp24_4096 = 0x00C00000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp50_4096 = 0x00D00000,
+ NV_DISPLAY_TV_FORMAT_UHD_4Kp60_4096 = 0x00E00000,
+
+ NV_DISPLAY_TV_FORMAT_SD_OTHER = 0x01000000,
+ NV_DISPLAY_TV_FORMAT_ED_OTHER = 0x02000000,
+ NV_DISPLAY_TV_FORMAT_HD_OTHER = 0x04000000,
+
+ NV_DISPLAY_TV_FORMAT_ANY = 0x80000000,
+
+} NV_DISPLAY_TV_FORMAT;
+
+
+//! \ingroup dispcontrol
+//! @{
+#define NVAPI_MAX_VIEW_TARGET 2
+#define NVAPI_ADVANCED_MAX_VIEW_TARGET 4
+
+#ifndef _NV_TARGET_VIEW_MODE_
+#define _NV_TARGET_VIEW_MODE_
+
+//! Used in NvAPI_SetView().
+typedef enum _NV_TARGET_VIEW_MODE
+{
+ NV_VIEW_MODE_STANDARD = 0,
+ NV_VIEW_MODE_CLONE = 1,
+ NV_VIEW_MODE_HSPAN = 2,
+ NV_VIEW_MODE_VSPAN = 3,
+ NV_VIEW_MODE_DUALVIEW = 4,
+ NV_VIEW_MODE_MULTIVIEW = 5,
+} NV_TARGET_VIEW_MODE;
+#endif
+
+//! @}
+
+
+// Following definitions are used in NvAPI_SetViewEx.
+
+//! Scaling modes - used in NvAPI_SetViewEx().
+//! \ingroup dispcontrol
+typedef enum _NV_SCALING
+{
+ NV_SCALING_DEFAULT = 0, //!< No change
+
+ // New Scaling Declarations
+ NV_SCALING_GPU_SCALING_TO_CLOSEST = 1, //!< Balanced - Full Screen
+ NV_SCALING_GPU_SCALING_TO_NATIVE = 2, //!< Force GPU - Full Screen
+ NV_SCALING_GPU_SCANOUT_TO_NATIVE = 3, //!< Force GPU - Centered\No Scaling
+ NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_NATIVE = 5, //!< Force GPU - Aspect Ratio
+ NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_CLOSEST = 6, //!< Balanced - Aspect Ratio
+ NV_SCALING_GPU_SCANOUT_TO_CLOSEST = 7, //!< Balanced - Centered\No Scaling
+
+ // Legacy Declarations
+ NV_SCALING_MONITOR_SCALING = NV_SCALING_GPU_SCALING_TO_CLOSEST,
+ NV_SCALING_ADAPTER_SCALING = NV_SCALING_GPU_SCALING_TO_NATIVE,
+ NV_SCALING_CENTERED = NV_SCALING_GPU_SCANOUT_TO_NATIVE,
+ NV_SCALING_ASPECT_SCALING = NV_SCALING_GPU_SCALING_TO_ASPECT_SCANOUT_TO_NATIVE,
+
+ NV_SCALING_CUSTOMIZED = 255 //!< For future use
+} NV_SCALING;
+
+//! Rotate modes- used in NvAPI_SetViewEx().
+//! \ingroup dispcontrol
+typedef enum _NV_ROTATE
+{
+ NV_ROTATE_0 = 0,
+ NV_ROTATE_90 = 1,
+ NV_ROTATE_180 = 2,
+ NV_ROTATE_270 = 3,
+ NV_ROTATE_IGNORED = 4,
+} NV_ROTATE;
+
+//! Color formats- used in NvAPI_SetViewEx().
+//! \ingroup dispcontrol
+#define NVFORMAT_MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((NvU32)(NvU8)(ch0) | ((NvU32)(NvU8)(ch1) << 8) | \
+ ((NvU32)(NvU8)(ch2) << 16) | ((NvU32)(NvU8)(ch3) << 24 ))
+
+
+
+//! Color formats- used in NvAPI_SetViewEx().
+//! \ingroup dispcontrol
+typedef enum _NV_FORMAT
+{
+ NV_FORMAT_UNKNOWN = 0, //!< unknown. Driver will choose one as following value.
+ NV_FORMAT_P8 = 41, //!< for 8bpp mode
+ NV_FORMAT_R5G6B5 = 23, //!< for 16bpp mode
+ NV_FORMAT_A8R8G8B8 = 21, //!< for 32bpp mode
+ NV_FORMAT_A16B16G16R16F = 113, //!< for 64bpp(floating point) mode.
+
+} NV_FORMAT;
+
+// TV standard
+
+typedef struct
+{
+ float x; //!< x-coordinate of the viewport top-left point
+ float y; //!< y-coordinate of the viewport top-left point
+ float w; //!< Width of the viewport
+ float h; //!< Height of the viewport
+} NV_VIEWPORTF;
+
+
+
+//! \ingroup dispcontrol
+//! The timing override is not supported yet; must be set to _AUTO. \n
+
+
+typedef enum _NV_TIMING_OVERRIDE
+{
+ NV_TIMING_OVERRIDE_CURRENT = 0, //!< get the current timing
+ NV_TIMING_OVERRIDE_AUTO, //!< the timing the driver will use based the current policy
+ NV_TIMING_OVERRIDE_EDID, //!< EDID timing
+ NV_TIMING_OVERRIDE_DMT, //!< VESA DMT timing
+ NV_TIMING_OVERRIDE_DMT_RB, //!< VESA DMT timing with reduced blanking
+ NV_TIMING_OVERRIDE_CVT, //!< VESA CVT timing
+ NV_TIMING_OVERRIDE_CVT_RB, //!< VESA CVT timing with reduced blanking
+ NV_TIMING_OVERRIDE_GTF, //!< VESA GTF timing
+ NV_TIMING_OVERRIDE_EIA861, //!< EIA 861x pre-defined timing
+ NV_TIMING_OVERRIDE_ANALOG_TV, //!< analog SD/HDTV timing
+ NV_TIMING_OVERRIDE_CUST, //!< NV custom timings
+ NV_TIMING_OVERRIDE_NV_PREDEFINED, //!< NV pre-defined timing (basically the PsF timings)
+ NV_TIMING_OVERRIDE_NV_PSF = NV_TIMING_OVERRIDE_NV_PREDEFINED,
+ NV_TIMING_OVERRIDE_NV_ASPR,
+ NV_TIMING_OVERRIDE_SDI, //!< Override for SDI timing
+
+ NV_TIMING_OVRRIDE_MAX,
+}NV_TIMING_OVERRIDE;
+
+
+#ifndef NV_TIMING_STRUCTS_DEFINED
+#define NV_TIMING_STRUCTS_DEFINED
+
+//***********************
+// The Timing Structure
+//***********************
+//
+//! \ingroup dispcontrol
+//! NVIDIA-specific timing extras \n
+//! Used in NV_TIMING.
+typedef struct tagNV_TIMINGEXT
+{
+ NvU32 flag; //!< Reserved for NVIDIA hardware-based enhancement, such as double-scan.
+ NvU16 rr; //!< Logical refresh rate to present
+ NvU32 rrx1k; //!< Physical vertical refresh rate in 0.001Hz
+ NvU32 aspect; //!< Display aspect ratio Hi(aspect):horizontal-aspect, Low(aspect):vertical-aspect
+ NvU16 rep; //!< Bit-wise pixel repetition factor: 0x1:no pixel repetition; 0x2:each pixel repeats twice horizontally,..
+ NvU32 status; //!< Timing standard
+ NvU8 name[40]; //!< Timing name
+}NV_TIMINGEXT;
+
+
+
+//! \ingroup dispcontrol
+//!The very basic timing structure based on the VESA standard:
+//! \code
+//! |<----------------------------htotal--------------------------->|
+//! ---------"active" video-------->|<-------blanking------>|<-----
+//! |<-------hvisible-------->|<-hb->|<-hfp->|<-hsw->|<-hbp->|<-hb->|
+//! --------- -+-------------------------+ | | | | |
+//! A A | | | | | | |
+//! : : | | | | | | |
+//! : : | | | | | | |
+//! :vertical| addressable video | | | | | |
+//! : visible| | | | | | |
+//! : : | | | | | | |
+//! : : | | | | | | |
+//! vertical V | | | | | | |
+//! total --+-------------------------+ | | | | |
+//! : vb border | | | | |
+//! : -----------------------------------+ | | | |
+//! : vfp front porch | | | |
+//! : -------------------------------------------+ | | |
+//! : vsw sync width | | |
+//! : ---------------------------------------------------+ | |
+//! : vbp back porch | |
+//! : -----------------------------------------------------------+ |
+//! V vb border |
+//! ---------------------------------------------------------------------------+
+//! \endcode
+typedef struct _NV_TIMING
+{
+ // VESA scan out timing parameters:
+ NvU16 HVisible; //!< horizontal visible
+ NvU16 HBorder; //!< horizontal border
+ NvU16 HFrontPorch; //!< horizontal front porch
+ NvU16 HSyncWidth; //!< horizontal sync width
+ NvU16 HTotal; //!< horizontal total
+ NvU8 HSyncPol; //!< horizontal sync polarity: 1-negative, 0-positive
+
+ NvU16 VVisible; //!< vertical visible
+ NvU16 VBorder; //!< vertical border
+ NvU16 VFrontPorch; //!< vertical front porch
+ NvU16 VSyncWidth; //!< vertical sync width
+ NvU16 VTotal; //!< vertical total
+ NvU8 VSyncPol; //!< vertical sync polarity: 1-negative, 0-positive
+
+ NvU16 interlaced; //!< 1-interlaced, 0-progressive
+ NvU32 pclk; //!< pixel clock in 10 kHz
+
+ //other timing related extras
+ NV_TIMINGEXT etc;
+}NV_TIMING;
+#endif //NV_TIMING_STRUCTS_DEFINED
+
+
+//! \addtogroup dispcontrol
+//! Timing-related constants
+//! @{
+#define NV_TIMING_H_SYNC_POSITIVE 0
+#define NV_TIMING_H_SYNC_NEGATIVE 1
+#define NV_TIMING_H_SYNC_DEFAULT NV_TIMING_H_SYNC_NEGATIVE
+//
+#define NV_TIMING_V_SYNC_POSITIVE 0
+#define NV_TIMING_V_SYNC_NEGATIVE 1
+#define NV_TIMING_V_SYNC_DEFAULT NV_TIMING_V_SYNC_POSITIVE
+//
+#define NV_TIMING_PROGRESSIVE 0
+#define NV_TIMING_INTERLACED 1
+#define NV_TIMING_INTERLACED_EXTRA_VBLANK_ON_FIELD2 1
+#define NV_TIMING_INTERLACED_NO_EXTRA_VBLANK_ON_FIELD2 2
+//! @}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_SetView
+//
+//! \fn NvAPI_SetView(NvDisplayHandle hNvDisplay, NV_VIEW_TARGET_INFO *pTargetInfo, NV_TARGET_VIEW_MODE targetView)
+//! This function lets the caller modify the target display arrangement of the selected source display handle in any nView mode.
+//! It can also modify or extend the source display in Dualview mode.
+//! \note Maps the selected source to the associated target Ids.
+//! \note Display PATH with this API is limited to single GPU. DUALVIEW across GPUs cannot be enabled with this API.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_SetDisplayConfig.
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \since Release: 90
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. #NVAPI_DEFAULT_HANDLE is not allowed, it has to be a handle enumerated with NvAPI_EnumNVidiaDisplayHandle().
+//! \param [in] pTargetInfo Pointer to array of NV_VIEW_TARGET_INFO, specifying device properties in this view.
+//! The first device entry in the array is the physical primary.
+//! The device entry with the lowest source id is the desktop primary.
+//! \param [in] targetCount Count of target devices specified in pTargetInfo.
+//! \param [in] targetView Target view selected from NV_TARGET_VIEW_MODE.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_SetView() and NvAPI_GetView()
+typedef struct
+{
+ NvU32 version; //!< (IN) structure version
+ NvU32 count; //!< (IN) target count
+ struct
+ {
+ NvU32 deviceMask; //!< (IN/OUT) Device mask
+ NvU32 sourceId; //!< (IN/OUT) Source ID - values will be based on the number of heads exposed per GPU.
+ NvU32 bPrimary:1; //!< (OUT) Indicates if this is the GPU's primary view target. This is not the desktop GDI primary.
+ //!< NvAPI_SetView automatically selects the first target in NV_VIEW_TARGET_INFO index 0 as the GPU's primary view.
+ NvU32 bInterlaced:1; //!< (IN/OUT) Indicates if the timing being used on this monitor is interlaced.
+ NvU32 bGDIPrimary:1; //!< (IN/OUT) Indicates if this is the desktop GDI primary.
+ NvU32 bForceModeSet:1;//!< (IN) Used only on Win7 and higher during a call to NvAPI_SetView(). Turns off optimization & forces OS to set supplied mode.
+ } target[NVAPI_MAX_VIEW_TARGET];
+} NV_VIEW_TARGET_INFO;
+
+//! \ingroup dispcontrol
+#define NV_VIEW_TARGET_INFO_VER MAKE_NVAPI_VERSION(NV_VIEW_TARGET_INFO,2)
+
+
+//! \ingroup dispcontrol
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_SetDisplayConfig.")
+NVAPI_INTERFACE NvAPI_SetView(NvDisplayHandle hNvDisplay, NV_VIEW_TARGET_INFO *pTargetInfo, NV_TARGET_VIEW_MODE targetView);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_SetViewEx
+//
+//! \fn NvAPI_SetViewEx(NvDisplayHandle hNvDisplay, NV_DISPLAY_PATH_INFO *pPathInfo, NV_TARGET_VIEW_MODE displayView)
+//! This function lets caller to modify the display arrangement for selected source display handle in any of the nview modes.
+//! It also allows to modify or extend the source display in dualview mode.
+//! \note Maps the selected source to the associated target Ids.
+//! \note Display PATH with this API is limited to single GPU. DUALVIEW across GPUs cannot be enabled with this API.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_SetDisplayConfig.
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \since Release: 95
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. #NVAPI_DEFAULT_HANDLE is not allowed, it has to be a handle enumerated with
+//! NvAPI_EnumNVidiaDisplayHandle().
+//! \param [in] pPathInfo Pointer to array of NV_VIEW_PATH_INFO, specifying device properties in this view.
+//! The first device entry in the array is the physical primary.
+//! The device entry with the lowest source id is the desktop primary.
+//! \param [in] pathCount Count of paths specified in pPathInfo.
+//! \param [in] displayView Display view selected from NV_TARGET_VIEW_MODE.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup dispcontrol
+#define NVAPI_MAX_DISPLAY_PATH NVAPI_MAX_VIEW_TARGET
+
+//! \ingroup dispcontrol
+#define NVAPI_ADVANCED_MAX_DISPLAY_PATH NVAPI_ADVANCED_MAX_VIEW_TARGET
+
+
+
+//! \ingroup dispcontrol
+//! Used in NV_DISPLAY_PATH_INFO.
+typedef struct
+{
+ NvU32 deviceMask; //!< (IN) Device mask
+ NvU32 sourceId; //!< (IN) Values will be based on the number of heads exposed per GPU(0, 1?)
+ NvU32 bPrimary:1; //!< (IN/OUT) Indicates if this is the GPU's primary view target. This is not the desktop GDI primary.
+ //!< NvAPI_SetViewEx() automatically selects the first target in NV_DISPLAY_PATH_INFO index 0 as the GPU's primary view.
+ NV_GPU_CONNECTOR_TYPE connector; //!< (IN) Specify connector type. For TV only.
+
+ // source mode information
+ NvU32 width; //!< (IN) Width of the mode
+ NvU32 height; //!< (IN) Height of the mode
+ NvU32 depth; //!< (IN) Depth of the mode
+ NV_FORMAT colorFormat; //!< Color format if it needs to be specified. Not used now.
+
+ //rotation setting of the mode
+ NV_ROTATE rotation; //!< (IN) Rotation setting.
+
+ // the scaling mode
+ NV_SCALING scaling; //!< (IN) Scaling setting
+
+ // Timing info
+ NvU32 refreshRate; //!< (IN) Refresh rate of the mode
+ NvU32 interlaced:1; //!< (IN) Interlaced mode flag
+
+ NV_DISPLAY_TV_FORMAT tvFormat; //!< (IN) To choose the last TV format set this value to NV_DISPLAY_TV_FORMAT_NONE
+
+ // Windows desktop position
+ NvU32 posx; //!< (IN/OUT) X-offset of this display on the Windows desktop
+ NvU32 posy; //!< (IN/OUT) Y-offset of this display on the Windows desktop
+ NvU32 bGDIPrimary:1; //!< (IN/OUT) Indicates if this is the desktop GDI primary.
+
+ NvU32 bForceModeSet:1;//!< (IN) Used only on Win7 and higher during a call to NvAPI_SetViewEx(). Turns off optimization & forces OS to set supplied mode.
+ NvU32 bFocusDisplay:1;//!< (IN) If set, this display path should have the focus after the GPU topology change
+ NvU32 gpuId:24; //!< (IN) the physical display/target Gpu id which is the owner of the scan out (for SLI multimon, display from the slave Gpu)
+
+} NV_DISPLAY_PATH;
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_SetViewEx() and NvAPI_GetViewEx().
+typedef struct
+{
+ NvU32 version; //!< (IN) Structure version
+ NvU32 count; //!< (IN) Path count
+ NV_DISPLAY_PATH path[NVAPI_MAX_DISPLAY_PATH];
+} NV_DISPLAY_PATH_INFO_V3;
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_SetViewEx() and NvAPI_GetViewEx().
+typedef struct
+{
+ NvU32 version; //!< (IN) Structure version
+ NvU32 count; //!< (IN) Path count
+ NV_DISPLAY_PATH path[NVAPI_ADVANCED_MAX_DISPLAY_PATH];
+} NV_DISPLAY_PATH_INFO;
+
+//! \addtogroup dispcontrol
+//! Macro for constructing the version fields of NV_DISPLAY_PATH_INFO
+//! @{
+#define NV_DISPLAY_PATH_INFO_VER NV_DISPLAY_PATH_INFO_VER4
+#define NV_DISPLAY_PATH_INFO_VER4 MAKE_NVAPI_VERSION(NV_DISPLAY_PATH_INFO,4)
+#define NV_DISPLAY_PATH_INFO_VER3 MAKE_NVAPI_VERSION(NV_DISPLAY_PATH_INFO,3)
+#define NV_DISPLAY_PATH_INFO_VER2 MAKE_NVAPI_VERSION(NV_DISPLAY_PATH_INFO,2)
+#define NV_DISPLAY_PATH_INFO_VER1 MAKE_NVAPI_VERSION(NV_DISPLAY_PATH_INFO,1)
+//! @}
+
+
+//! \ingroup dispcontrol
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_SetDisplayConfig.")
+NVAPI_INTERFACE NvAPI_SetViewEx(NvDisplayHandle hNvDisplay, NV_DISPLAY_PATH_INFO *pPathInfo, NV_TARGET_VIEW_MODE displayView);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SetDisplayConfig/GetDisplayConfig
+///////////////////////////////////////////////////////////////////////////////
+//! \ingroup dispcontrol
+
+typedef struct _NV_POSITION
+{
+ NvS32 x;
+ NvS32 y;
+} NV_POSITION;
+
+//! \ingroup dispcontrol
+typedef struct _NV_RESOLUTION
+{
+ NvU32 width;
+ NvU32 height;
+ NvU32 colorDepth;
+} NV_RESOLUTION;
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1
+{
+ NvU32 version;
+
+ // Rotation and Scaling
+ NV_ROTATE rotation; //!< (IN) rotation setting.
+ NV_SCALING scaling; //!< (IN) scaling setting.
+
+ // Refresh Rate
+ NvU32 refreshRate1K; //!< (IN) Non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored
+ //!< This is the value which driver reports to the OS.
+ // Flags
+ NvU32 interlaced:1; //!< (IN) Interlaced mode flag, ignored if refreshRate == 0
+ NvU32 primary:1; //!< (IN) Declares primary display in clone configuration. This is *NOT* GDI Primary.
+ //!< Only one target can be primary per source. If no primary is specified, the first
+ //!< target will automatically be primary.
+#ifdef NV_PAN_AND_SCAN_DEFINED
+ NvU32 isPanAndScanTarget:1; //!< Whether on this target Pan and Scan is enabled or has to be enabled. Valid only
+ //!< when the target is part of clone topology.
+ NvU32 reserved:29;
+#else
+ NvU32 reserved:30;
+#endif
+ // TV format information
+ NV_GPU_CONNECTOR_TYPE connector; //!< Specify connector type. For TV only, ignored if tvFormat == NV_DISPLAY_TV_FORMAT_NONE
+ NV_DISPLAY_TV_FORMAT tvFormat; //!< (IN) to choose the last TV format set this value to NV_DISPLAY_TV_FORMAT_NONE
+ //!< In case of NvAPI_DISP_GetDisplayConfig(), this field will indicate the currently applied TV format;
+ //!< if no TV format is applied, this field will have NV_DISPLAY_TV_FORMAT_NONE value.
+ //!< In case of NvAPI_DISP_SetDisplayConfig(), this field should only be set in case of TVs;
+ //!< for other displays this field will be ignored and resolution & refresh rate specified in input will be used to apply the TV format.
+
+ // Backend (raster) timing standard
+ NV_TIMING_OVERRIDE timingOverride; //!< Ignored if timingOverride == NV_TIMING_OVERRIDE_CURRENT
+ NV_TIMING timing; //!< Scan out timing, valid only if timingOverride == NV_TIMING_OVERRIDE_CUST
+ //!< The value NV_TIMING::NV_TIMINGEXT::rrx1k is obtained from the EDID. The driver may
+ //!< tweak this value for HDTV, stereo, etc., before reporting it to the OS.
+} NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1;
+
+//! \ingroup dispcontrol
+typedef NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1 NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO;
+
+//! \ingroup dispcontrol
+#define NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_VER1 MAKE_NVAPI_VERSION(NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_V1,1)
+
+//! \ingroup dispcontrol
+#define NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_VER NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_VER1
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1
+{
+ NvU32 displayId; //!< Display ID
+ NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO* details; //!< May be NULL if no advanced settings are required. NULL for Non-NVIDIA Display.
+} NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1;
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2
+{
+ NvU32 displayId; //!< Display ID
+ NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO* details; //!< May be NULL if no advanced settings are required
+ NvU32 targetId; //!< Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is ignored.
+} NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2;
+
+
+//! \ingroup dispcontrol
+//! As version is not defined for this structure, we will be using version of NV_DISPLAYCONFIG_PATH_INFO
+typedef NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2 NV_DISPLAYCONFIG_PATH_TARGET_INFO;
+
+
+//! \ingroup dispcontrol
+typedef enum _NV_DISPLAYCONFIG_SPANNING_ORIENTATION
+{
+ NV_DISPLAYCONFIG_SPAN_NONE = 0,
+ NV_DISPLAYCONFIG_SPAN_HORIZONTAL = 1,
+ NV_DISPLAYCONFIG_SPAN_VERTICAL = 2,
+} NV_DISPLAYCONFIG_SPANNING_ORIENTATION;
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1
+{
+ NV_RESOLUTION resolution;
+ NV_FORMAT colorFormat; //!< Ignored at present, must be NV_FORMAT_UNKNOWN (0)
+ NV_POSITION position; //!< Is all positions are 0 or invalid, displays will be automatically
+ //!< positioned from left to right with GDI Primary at 0,0, and all
+ //!< other displays in the order of the path array.
+ NV_DISPLAYCONFIG_SPANNING_ORIENTATION spanningOrientation; //!< Spanning is only supported on XP
+ NvU32 bGDIPrimary : 1;
+ NvU32 bSLIFocus : 1;
+ NvU32 reserved : 30; //!< Must be 0
+} NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1;
+
+//! \ingroup dispcontrol
+//! As version is not defined for this structure we will be using version of NV_DISPLAYCONFIG_PATH_INFO
+typedef NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1 NV_DISPLAYCONFIG_SOURCE_MODE_INFO;
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_PATH_INFO_V1
+{
+ NvU32 version;
+ NvU32 reserved_sourceId; //!< This field is reserved. There is ongoing debate if we need this field.
+ //!< Identifies sourceIds used by Windows. If all sourceIds are 0,
+ //!< these will be computed automatically.
+ NvU32 targetInfoCount; //!< Number of elements in targetInfo array
+ NV_DISPLAYCONFIG_PATH_TARGET_INFO_V1* targetInfo;
+ NV_DISPLAYCONFIG_SOURCE_MODE_INFO* sourceModeInfo; //!< May be NULL if mode info is not important
+} NV_DISPLAYCONFIG_PATH_INFO_V1;
+
+//! \ingroup dispcontrol
+//! This define is temporary and must be removed once DVS failure is fixed.
+#define _NV_DISPLAYCONFIG_PATH_INFO_V2 _NV_DISPLAYCONFIG_PATH_INFO
+
+//! \ingroup dispcontrol
+typedef struct _NV_DISPLAYCONFIG_PATH_INFO_V2
+{
+ NvU32 version;
+ union {
+ NvU32 sourceId; //!< Identifies sourceId used by Windows CCD. This can be optionally set.
+ NvU32 reserved_sourceId; //!< Only for compatibility
+ };
+
+ NvU32 targetInfoCount; //!< Number of elements in targetInfo array
+ NV_DISPLAYCONFIG_PATH_TARGET_INFO* targetInfo;
+ NV_DISPLAYCONFIG_SOURCE_MODE_INFO* sourceModeInfo; //!< May be NULL if mode info is not important
+ NvU32 IsNonNVIDIAAdapter : 1; //!< True for non-NVIDIA adapter.
+ NvU32 reserved : 31; //!< Must be 0
+ void *pOSAdapterID; //!< Used by Non-NVIDIA adapter for pointer to OS Adapter of LUID
+ //!< type, type casted to void *.
+} NV_DISPLAYCONFIG_PATH_INFO_V2;
+
+//! \ingroup dispcontrol
+typedef NV_DISPLAYCONFIG_PATH_INFO_V2 NV_DISPLAYCONFIG_PATH_INFO;
+
+//! \ingroup dispcontrol
+#define NV_DISPLAYCONFIG_PATH_INFO_VER1 MAKE_NVAPI_VERSION(NV_DISPLAYCONFIG_PATH_INFO_V1,1)
+
+//! \ingroup dispcontrol
+#define NV_DISPLAYCONFIG_PATH_INFO_VER2 MAKE_NVAPI_VERSION(NV_DISPLAYCONFIG_PATH_INFO_V2,2)
+
+//! \ingroup dispcontrol
+#define NV_DISPLAYCONFIG_PATH_INFO_VER NV_DISPLAYCONFIG_PATH_INFO_VER2
+
+//! \ingroup dispcontrol
+typedef enum _NV_DISPLAYCONFIG_FLAGS
+{
+ NV_DISPLAYCONFIG_VALIDATE_ONLY = 0x00000001,
+ NV_DISPLAYCONFIG_SAVE_TO_PERSISTENCE = 0x00000002,
+ NV_DISPLAYCONFIG_DRIVER_RELOAD_ALLOWED = 0x00000004, //!< Driver reload is permitted if necessary
+ NV_DISPLAYCONFIG_FORCE_MODE_ENUMERATION = 0x00000008, //!< Refresh OS mode list.
+} NV_DISPLAYCONFIG_FLAGS;
+
+
+#define NVAPI_UNICODE_STRING_MAX 2048
+#define NVAPI_BINARY_DATA_MAX 4096
+
+typedef NvU16 NvAPI_UnicodeString[NVAPI_UNICODE_STRING_MAX];
+typedef const NvU16 *NvAPI_LPCWSTR;
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetDisplayDriverVersion
+//! \fn NvAPI_GetDisplayDriverVersion(NvDisplayHandle hNvDisplay, NV_DISPLAY_DRIVER_VERSION *pVersion)
+//! This function returns a struct that describes aspects of the display driver
+//! build.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_SYS_GetDriverAndBranchVersion.
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \param [in] hNvDisplay NVIDIA display handle.
+//! \param [out] pVersion Pointer to NV_DISPLAY_DRIVER_VERSION struc
+//!
+//! \retval NVAPI_ERROR
+//! \retval NVAPI_OK
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup driverapi
+//! Used in NvAPI_GetDisplayDriverVersion()
+typedef struct _NV_DISPLAY_DRIVER_VERSION
+{
+ NvU32 version; // Structure version
+ NvU32 drvVersion;
+ NvU32 bldChangeListNum;
+ NvAPI_ShortString szBuildBranchString;
+ NvAPI_ShortString szAdapterString;
+} NV_DISPLAY_DRIVER_VERSION;
+
+//! \ingroup driverapi
+#define NV_DISPLAY_DRIVER_VERSION_VER MAKE_NVAPI_VERSION(NV_DISPLAY_DRIVER_VERSION,1)
+
+
+//! \ingroup driverapi
+//__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_SYS_GetDriverAndBranchVersion.")
+typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverVersion)(NvDisplayHandle hNvDisplay, NV_DISPLAY_DRIVER_VERSION *pVersion);
+_NvAPI_GetDisplayDriverVersion NvAPI_GetDisplayDriverVersion;
+
+//NVAPI_INTERFACE NvAPI_GetDisplayDriverVersion(NvDisplayHandle hNvDisplay, NV_DISPLAY_DRIVER_VERSION *pVersion);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_OGL_ExpertModeSet[Get]
+//
+//! \name NvAPI_OGL_ExpertModeSet[Get] Functions
+//@{
+//! This function configures OpenGL Expert Mode, an API usage feedback and
+//! advice reporting mechanism. The effects of this call are
+//! applied only to the current context, and are reset to the
+//! defaults when the context is destroyed.
+//!
+//! \note This feature is valid at runtime only when GLExpert
+//! functionality has been built into the OpenGL driver
+//! installed on the system. All Windows Vista OpenGL
+//! drivers provided by NVIDIA have this instrumentation
+//! included by default. Windows XP, however, requires a
+//! special display driver available with the NVIDIA
+//! PerfSDK found at developer.nvidia.com.
+//!
+//! \note These functions are valid only for the current OpenGL
+//! context. Calling these functions prior to creating a
+//! context and calling MakeCurrent with it will result
+//! in errors and undefined behavior.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \param expertDetailMask Mask made up of NVAPI_OGLEXPERT_DETAIL bits,
+//! this parameter specifies the detail level in
+//! the feedback stream.
+//!
+//! \param expertReportMask Mask made up of NVAPI_OGLEXPERT_REPORT bits,
+//! this parameter specifies the areas of
+//! functional interest.
+//!
+//! \param expertOutputMask Mask made up of NVAPI_OGLEXPERT_OUTPUT bits,
+//! this parameter specifies the feedback output
+//! location.
+//!
+//! \param expertCallback Used in conjunction with OUTPUT_TO_CALLBACK,
+//! this is a simple callback function the user
+//! may use to obtain the feedback stream. The
+//! function will be called once per fully
+//! qualified feedback stream extry.
+//!
+//! \retval NVAPI_API_NOT_INTIALIZED NVAPI not initialized
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU found
+//! \retval NVAPI_OPENGL_CONTEXT_NOT_CURRENT No NVIDIA OpenGL context
+//! which supports GLExpert
+//! has been made current
+//! \retval NVAPI_ERROR OpenGL driver failed to load properly
+//! \retval NVAPI_OK Success
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \addtogroup oglapi
+//! @{
+#define NVAPI_OGLEXPERT_DETAIL_NONE 0x00000000
+#define NVAPI_OGLEXPERT_DETAIL_ERROR 0x00000001
+#define NVAPI_OGLEXPERT_DETAIL_SWFALLBACK 0x00000002
+#define NVAPI_OGLEXPERT_DETAIL_BASIC_INFO 0x00000004
+#define NVAPI_OGLEXPERT_DETAIL_DETAILED_INFO 0x00000008
+#define NVAPI_OGLEXPERT_DETAIL_PERFORMANCE_WARNING 0x00000010
+#define NVAPI_OGLEXPERT_DETAIL_QUALITY_WARNING 0x00000020
+#define NVAPI_OGLEXPERT_DETAIL_USAGE_WARNING 0x00000040
+#define NVAPI_OGLEXPERT_DETAIL_ALL 0xFFFFFFFF
+
+#define NVAPI_OGLEXPERT_REPORT_NONE 0x00000000
+#define NVAPI_OGLEXPERT_REPORT_ERROR 0x00000001
+#define NVAPI_OGLEXPERT_REPORT_SWFALLBACK 0x00000002
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_VERTEX 0x00000004
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_GEOMETRY 0x00000008
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_XFB 0x00000010
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_RASTER 0x00000020
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_FRAGMENT 0x00000040
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_ROP 0x00000080
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_FRAMEBUFFER 0x00000100
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_PIXEL 0x00000200
+#define NVAPI_OGLEXPERT_REPORT_PIPELINE_TEXTURE 0x00000400
+#define NVAPI_OGLEXPERT_REPORT_OBJECT_BUFFEROBJECT 0x00000800
+#define NVAPI_OGLEXPERT_REPORT_OBJECT_TEXTURE 0x00001000
+#define NVAPI_OGLEXPERT_REPORT_OBJECT_PROGRAM 0x00002000
+#define NVAPI_OGLEXPERT_REPORT_OBJECT_FBO 0x00004000
+#define NVAPI_OGLEXPERT_REPORT_FEATURE_SLI 0x00008000
+#define NVAPI_OGLEXPERT_REPORT_ALL 0xFFFFFFFF
+
+
+#define NVAPI_OGLEXPERT_OUTPUT_TO_NONE 0x00000000
+#define NVAPI_OGLEXPERT_OUTPUT_TO_CONSOLE 0x00000001
+#define NVAPI_OGLEXPERT_OUTPUT_TO_DEBUGGER 0x00000004
+#define NVAPI_OGLEXPERT_OUTPUT_TO_CALLBACK 0x00000008
+#define NVAPI_OGLEXPERT_OUTPUT_TO_ALL 0xFFFFFFFF
+
+//! @}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION TYPE: NVAPI_OGLEXPERT_CALLBACK
+//
+//! DESCRIPTION: Used in conjunction with OUTPUT_TO_CALLBACK, this is a simple
+//! callback function the user may use to obtain the feedback
+//! stream. The function will be called once per fully qualified
+//! feedback stream entry.
+//!
+//! \param categoryId Contains the bit from the NVAPI_OGLEXPERT_REPORT
+//! mask that corresponds to the current message
+//! \param messageId Unique ID for the current message
+//! \param detailLevel Contains the bit from the NVAPI_OGLEXPERT_DETAIL
+//! mask that corresponds to the current message
+//! \param objectId Unique ID of the object that corresponds to the
+//! current message
+//! \param messageStr Text string from the current message
+//!
+//! \ingroup oglapi
+///////////////////////////////////////////////////////////////////////////////
+typedef void (* NVAPI_OGLEXPERT_CALLBACK) (unsigned int categoryId, unsigned int messageId, unsigned int detailLevel, int objectId, const char *messageStr);
+
+
+
+//! \ingroup oglapi
+//! SUPPORTED OS: Windows XP and higher
+//!
+NVAPI_INTERFACE NvAPI_OGL_ExpertModeSet(NvU32 expertDetailLevel,
+ NvU32 expertReportMask,
+ NvU32 expertOutputMask,
+ NVAPI_OGLEXPERT_CALLBACK expertCallback);
+
+//! \addtogroup oglapi
+//! SUPPORTED OS: Windows XP and higher
+//!
+NVAPI_INTERFACE NvAPI_OGL_ExpertModeGet(NvU32 *pExpertDetailLevel,
+ NvU32 *pExpertReportMask,
+ NvU32 *pExpertOutputMask,
+ NVAPI_OGLEXPERT_CALLBACK *pExpertCallback);
+
+//@}
+///////////////////////////////////////////////////////////////////////////////
+//
+//! \name NvAPI_OGL_ExpertModeDefaultsSet[Get] Functions
+//!
+//@{
+//! This function configures OpenGL Expert Mode global defaults. These settings
+//! apply to any OpenGL application which starts up after these
+//! values are applied (i.e. these settings *do not* apply to
+//! currently running applications).
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \param expertDetailLevel Value which specifies the detail level in
+//! the feedback stream. This is a mask made up
+//! of NVAPI_OGLEXPERT_LEVEL bits.
+//!
+//! \param expertReportMask Mask made up of NVAPI_OGLEXPERT_REPORT bits,
+//! this parameter specifies the areas of
+//! functional interest.
+//!
+//! \param expertOutputMask Mask made up of NVAPI_OGLEXPERT_OUTPUT bits,
+//! this parameter specifies the feedback output
+//! location. Note that using OUTPUT_TO_CALLBACK
+//! here is meaningless and has no effect, but
+//! using it will not cause an error.
+//!
+//! \return ::NVAPI_ERROR or ::NVAPI_OK
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup oglapi
+//! SUPPORTED OS: Windows XP and higher
+//!
+NVAPI_INTERFACE NvAPI_OGL_ExpertModeDefaultsSet(NvU32 expertDetailLevel,
+ NvU32 expertReportMask,
+ NvU32 expertOutputMask);
+
+//! \addtogroup oglapi
+//! SUPPORTED OS: Windows XP and higher
+//!
+NVAPI_INTERFACE NvAPI_OGL_ExpertModeDefaultsGet(NvU32 *pExpertDetailLevel,
+ NvU32 *pExpertReportMask,
+ NvU32 *pExpertOutputMask);
+//@}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnumTCCPhysicalGPUs
+//
+//! This function returns an array of physical GPU handles that are in TCC Mode.
+//! Each handle represents a physical GPU present in the system in TCC Mode.
+//! That GPU may not be visible to the OS directly.
+//!
+//! The array nvGPUHandle will be filled with physical GPU handle values. The returned
+//! gpuCount determines how many entries in the array are valid.
+//!
+//! NOTE: Handles enumerated by this API are only valid for NvAPIs that are tagged as TCC_SUPPORTED
+//! If handle is passed to any other API, it will fail with NVAPI_INVALID_HANDLE
+//!
+//! For WDDM GPU handles please use NvAPI_EnumPhysicalGPUs()
+//!
+//! SUPPORTED OS: Windows Vista and higher, Mac OS X
+//!
+//!
+//!
+//! \param [out] nvGPUHandle Physical GPU array that will contain all TCC Physical GPUs
+//! \param [out] pGpuCount count represent the number of valid entries in nvGPUHandle
+//!
+//!
+//! \retval NVAPI_INVALID_ARGUMENT nvGPUHandle or pGpuCount is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_EnumTCCPhysicalGPUs( NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32 *pGpuCount);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnumLogicalGPUs
+//
+//! This function returns an array of logical GPU handles.
+//!
+//! Each handle represents one or more GPUs acting in concert as a single graphics device.
+//!
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! The array nvGPUHandle will be filled with logical GPU handle values. The returned
+//! gpuCount determines how many entries in the array are valid.
+//!
+//! \note All logical GPUs handles get invalidated on a GPU topology change, so the calling
+//! application is required to renum the logical GPU handles to get latest physical handle
+//! mapping after every GPU topology change activated by a call to NvAPI_SetGpuTopologies().
+//!
+//! To detect if SLI rendering is enabled, use NvAPI_D3D_GetCurrentSLIState().
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT nvGPUHandle or pGpuCount is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_EnumLogicalGPUs(NvLogicalGpuHandle nvGPUHandle[NVAPI_MAX_LOGICAL_GPUS], NvU32 *pGpuCount);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetPhysicalGPUsFromDisplay
+//
+//! This function returns an array of physical GPU handles associated with the specified display.
+//!
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! The array nvGPUHandle will be filled with physical GPU handle values. The returned
+//! gpuCount determines how many entries in the array are valid.
+//!
+//! If the display corresponds to more than one physical GPU, the first GPU returned
+//! is the one with the attached active output.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hNvDisp is not valid; nvGPUHandle or pGpuCount is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND no NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GetPhysicalGPUsFromDisplay(NvDisplayHandle hNvDisp, NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32 *pGpuCount);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GetPhysicalGPUsFromDisplay)(NvDisplayHandle hNvDisp, NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32 *pGpuCount);
+_NvAPI_GetPhysicalGPUsFromDisplay NvAPI_GetPhysicalGPUsFromDisplay;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetPhysicalGPUFromUnAttachedDisplay
+//
+//! This function returns a physical GPU handle associated with the specified unattached display.
+//! The source GPU is a physical render GPU which renders the frame buffer but may or may not drive the scan out.
+//!
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hNvUnAttachedDisp is not valid or pPhysicalGpu is NULL.
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetPhysicalGPUFromUnAttachedDisplay(NvUnAttachedDisplayHandle hNvUnAttachedDisp, NvPhysicalGpuHandle *pPhysicalGpu);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetLogicalGPUFromDisplay
+//
+//! This function returns the logical GPU handle associated with the specified display.
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hNvDisp is not valid; pLogicalGPU is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetLogicalGPUFromDisplay(NvDisplayHandle hNvDisp, NvLogicalGpuHandle *pLogicalGPU);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetLogicalGPUFromPhysicalGPU
+//
+//! This function returns the logical GPU handle associated with specified physical GPU handle.
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGPU is not valid; pLogicalGPU is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetLogicalGPUFromPhysicalGPU(NvPhysicalGpuHandle hPhysicalGPU, NvLogicalGpuHandle *pLogicalGPU);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetPhysicalGPUsFromLogicalGPU
+//
+//! This function returns the physical GPU handles associated with the specified logical GPU handle.
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! The array hPhysicalGPU will be filled with physical GPU handle values. The returned
+//! gpuCount determines how many entries in the array are valid.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hLogicalGPU is not valid; hPhysicalGPU is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_LOGICAL_GPU_HANDLE hLogicalGPU was not a logical GPU handle
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetPhysicalGPUsFromLogicalGPU(NvLogicalGpuHandle hLogicalGPU,NvPhysicalGpuHandle hPhysicalGPU[NVAPI_MAX_PHYSICAL_GPUS], NvU32 *pGpuCount);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetGpuCoreCount
+//
+//! DESCRIPTION: Retrieves the total number of cores defined for a GPU.
+//! Returns 0 on architectures that don't define GPU cores.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT pCount is NULL
+//! \retval ::NVAPI_OK *pCount is set
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND no NVIDIA GPU driving a display was found
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//! \retval ::NVAPI_NOT_SUPPORTED API call is not supported on current architecture
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetGpuCoreCount(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pCount);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetGpuCoreCount)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Out_ NvU32* pCount);
+_NvAPI_GPU_GetGpuCoreCount NvAPI_GPU_GetGpuCoreCount;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetAllOutputs
+//
+//! This function returns set of all GPU-output identifiers as a bitmask.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetAllDisplayIds.
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL.
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetAllDisplayIds.")
+NVAPI_INTERFACE NvAPI_GPU_GetAllOutputs(NvPhysicalGpuHandle hPhysicalGpu,NvU32 *pOutputsMask);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetConnectedOutputs
+//
+//! This function is the same as NvAPI_GPU_GetAllOutputs() but returns only the set of GPU output
+//! identifiers that are connected to display devices.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL.
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.")
+NVAPI_INTERFACE NvAPI_GPU_GetConnectedOutputs(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pOutputsMask);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetConnectedSLIOutputs
+//
+//! DESCRIPTION: This function is the same as NvAPI_GPU_GetConnectedOutputs() but returns only the set of GPU-output
+//! identifiers that can be selected in an SLI configuration.
+//! NOTE: This function matches NvAPI_GPU_GetConnectedOutputs()
+//! - On systems which are not SLI capable.
+//! - If the queried GPU is not part of a valid SLI group.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 170
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: hPhysicalGpu was not a physical GPU handle
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.")
+NVAPI_INTERFACE NvAPI_GPU_GetConnectedSLIOutputs(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pOutputsMask);
+
+
+
+
+//! \ingroup gpu
+typedef enum _NV_MONITOR_CONN_TYPE
+{
+ NV_MONITOR_CONN_TYPE_UNINITIALIZED = 0,
+ NV_MONITOR_CONN_TYPE_VGA,
+ NV_MONITOR_CONN_TYPE_COMPONENT,
+ NV_MONITOR_CONN_TYPE_SVIDEO,
+ NV_MONITOR_CONN_TYPE_HDMI,
+ NV_MONITOR_CONN_TYPE_DVI,
+ NV_MONITOR_CONN_TYPE_LVDS,
+ NV_MONITOR_CONN_TYPE_DP,
+ NV_MONITOR_CONN_TYPE_COMPOSITE,
+ NV_MONITOR_CONN_TYPE_UNKNOWN = -1
+} NV_MONITOR_CONN_TYPE;
+
+
+
+//! \addtogroup gpu
+//! @{
+#define NV_GPU_CONNECTED_IDS_FLAG_UNCACHED NV_BIT(0) //!< Get uncached connected devices
+#define NV_GPU_CONNECTED_IDS_FLAG_SLI NV_BIT(1) //!< Get devices such that those can be selected in an SLI configuration
+#define NV_GPU_CONNECTED_IDS_FLAG_LIDSTATE NV_BIT(2) //!< Get devices such that to reflect the Lid State
+#define NV_GPU_CONNECTED_IDS_FLAG_FAKE NV_BIT(3) //!< Get devices that includes the fake connected monitors
+#define NV_GPU_CONNECTED_IDS_FLAG_EXCLUDE_MST NV_BIT(4) //!< Excludes devices that are part of the multi stream topology.
+
+//! @}
+
+//! \ingroup gpu
+typedef struct _NV_GPU_DISPLAYIDS
+{
+ NvU32 version;
+ NV_MONITOR_CONN_TYPE connectorType; //!< out: vga, tv, dvi, hdmi and dp. This is reserved for future use and clients should not rely on this information. Instead get the
+ //!< GPU connector type from NvAPI_GPU_GetConnectorInfo/NvAPI_GPU_GetConnectorInfoEx
+ NvU32 displayId; //!< this is a unique identifier for each device
+ NvU32 isDynamic:1; //!< if bit is set then this display is part of MST topology and it's a dynamic
+ NvU32 isMultiStreamRootNode:1; //!< if bit is set then this displayID belongs to a multi stream enabled connector(root node). Note that when multi stream is enabled and
+ //!< a single multi stream capable monitor is connected to it, the monitor will share the display id with the RootNode.
+ //!< When there is more than one monitor connected in a multi stream topology, then the root node will have a separate displayId.
+ NvU32 isActive:1; //!< if bit is set then this display is being actively driven
+ NvU32 isCluster:1; //!< if bit is set then this display is the representative display
+ NvU32 isOSVisible:1; //!< if bit is set, then this display is reported to the OS
+ NvU32 isWFD:1; //!< if bit is set, then this display is wireless
+ NvU32 isConnected:1; //!< if bit is set, then this display is connected
+ NvU32 reserved: 22; //!< must be zero
+} NV_GPU_DISPLAYIDS;
+
+//! \ingroup gpu
+//! Macro for constructing the version field of ::_NV_GPU_DISPLAYIDS
+#define NV_GPU_DISPLAYIDS_VER1 MAKE_NVAPI_VERSION(NV_GPU_DISPLAYIDS,1)
+
+#define NV_GPU_DISPLAYIDS_VER NV_GPU_DISPLAYIDS_VER1
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetConnectedDisplayIds
+//
+//! \code
+//! DESCRIPTION: Due to space limitation NvAPI_GPU_GetConnectedOutputs can return maximum 32 devices, but
+//! this is no longer true for DPMST. NvAPI_GPU_GetConnectedDisplayIds will return all
+//! the connected display devices in the form of displayIds for the associated hPhysicalGpu.
+//! This function can accept set of flags to request cached, uncached, sli and lid to get the connected devices.
+//! Default value for flags will be cached .
+//! HOW TO USE: 1) for each PhysicalGpu, make a call to get the number of connected displayId's
+//! using NvAPI_GPU_GetConnectedDisplayIds by passing the pDisplayIds as NULL
+//! On call success:
+//! 2) Allocate memory based on pDisplayIdCount then make a call NvAPI_GPU_GetConnectedDisplayIds to populate DisplayIds
+//! SUPPORTED OS: Windows XP and higher
+//!
+//! PARAMETERS: hPhysicalGpu (IN) - GPU selection
+//! flags (IN) - One or more defines from NV_GPU_CONNECTED_IDS_FLAG_* as valid flags.
+//! pDisplayIds (IN/OUT) - Pointer to an NV_GPU_DISPLAYIDS struct, each entry represents a one displayID and its attributes
+//! pDisplayIdCount(OUT)- Number of displayId's.
+//!
+//! RETURN STATUS: NVAPI_INVALID_ARGUMENT: hPhysicalGpu or pDisplayIds or pDisplayIdCount is NULL
+//! NVAPI_OK: *pDisplayIds contains a set of GPU-output identifiers
+//! NVAPI_NVIDIA_DEVICE_NOT_FOUND: no NVIDIA GPU driving a display was found
+//! NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: hPhysicalGpu was not a physical GPU handle
+//! \endcode
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetConnectedDisplayIds(_In_ NvPhysicalGpuHandle hPhysicalGpu, __inout_ecount_part_opt(*pDisplayIdCount, *pDisplayIdCount) NV_GPU_DISPLAYIDS* pDisplayIds, _Inout_ NvU32* pDisplayIdCount, _In_ NvU32 flags);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetAllDisplayIds
+//
+//! DESCRIPTION: This API returns display IDs for all possible outputs on the GPU.
+//! For DPMST connector, it will return display IDs for all the video sinks in the topology. \n
+//! HOW TO USE: 1. The first call should be made to get the all display ID count. To get the display ID count, send in \n
+//! a) hPhysicalGpu - a valid GPU handle(enumerated using NvAPI_EnumPhysicalGPUs()) as input, \n
+//! b) pDisplayIds - NULL, as we just want to get the display ID count. \n
+//! c) pDisplayIdCount - a valid pointer to NvU32, whose value is set to ZERO. \n
+//! If all parameters are correct and this call is successful, this call will return the display ID's count. \n
+//! 2. To get the display ID array, make the second call to NvAPI_GPU_GetAllDisplayIds() with \n
+//! a) hPhysicalGpu - should be same value which was sent in first call, \n
+//! b) pDisplayIds - pointer to the display ID array allocated by caller based on display ID count, \n
+//! eg. malloc(sizeof(NV_GPU_DISPLAYIDS) * pDisplayIdCount). \n
+//! c) pDisplayIdCount - a valid pointer to NvU32. This indicates for how many display IDs \n
+//! the memory is allocated(pDisplayIds) by the caller. \n
+//! If all parameters are correct and this call is successful, this call will return the display ID array and actual
+//! display ID count (which was obtained in the first call to NvAPI_GPU_GetAllDisplayIds). If the input display ID count is
+//! less than the actual display ID count, it will overwrite the input and give the pDisplayIdCount as actual count and the
+//! API will return NVAPI_INSUFFICIENT_BUFFER.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \param [in] hPhysicalGpu GPU selection.
+//! \param [in,out] DisplayIds Pointer to an array of NV_GPU_DISPLAYIDS structures, each entry represents one displayID
+//! and its attributes.
+//! \param [in,out] pDisplayIdCount As input, this parameter indicates the number of display's id's for which caller has
+//! allocated the memory. As output, it will return the actual number of display IDs.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval NVAPI_INSUFFICIENT_BUFFER When the input buffer(pDisplayIds) is less than the actual number of display IDs, this API
+//! will return NVAPI_INSUFFICIENT_BUFFER.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetAllDisplayIds(_In_ NvPhysicalGpuHandle hPhysicalGpu, __inout_ecount_part_opt(*pDisplayIdCount, *pDisplayIdCount) NV_GPU_DISPLAYIDS* pDisplayIds, _Inout_ NvU32* pDisplayIdCount);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetConnectedOutputsWithLidState
+//
+//! This function is similar to NvAPI_GPU_GetConnectedOutputs(), and returns the connected display identifiers that are connected
+//! as an output mask but unlike NvAPI_GPU_GetConnectedOutputs() this API "always" reflects the Lid State in the output mask.
+//! Thus if you expect the LID close state to be available in the connection mask use this API.
+//! - If LID is closed then this API will remove the LID panel from the connected display identifiers.
+//! - If LID is open then this API will reflect the LID panel in the connected display identifiers.
+//!
+//! \note This API should be used on notebook systems and on systems where the LID state is required in the connection
+//! output mask. On desktop systems the returned identifiers will match NvAPI_GPU_GetConnectedOutputs().
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 95
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.")
+NVAPI_INTERFACE NvAPI_GPU_GetConnectedOutputsWithLidState(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pOutputsMask);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetConnectedSLIOutputsWithLidState
+//
+//! DESCRIPTION: This function is the same as NvAPI_GPU_GetConnectedOutputsWithLidState() but returns only the set
+//! of GPU-output identifiers that can be selected in an SLI configuration. With SLI disabled,
+//! this function matches NvAPI_GPU_GetConnectedOutputsWithLidState().
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 170
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_GPU_GetConnectedDisplayIds.")
+NVAPI_INTERFACE NvAPI_GPU_GetConnectedSLIOutputsWithLidState(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pOutputsMask);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetSystemType
+//
+//! \fn NvAPI_GPU_GetSystemType(NvPhysicalGpuHandle hPhysicalGpu, NV_SYSTEM_TYPE *pSystemType)
+//! This function identifies whether the GPU is a notebook GPU or a desktop GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 95
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL
+//! \retval NVAPI_OK *pSystemType contains the GPU system type
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: hPhysicalGpu was not a physical GPU handle
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+//! Used in NvAPI_GPU_GetSystemType()
+typedef enum _NV_SYSTEM_TYPE
+{
+ NV_SYSTEM_TYPE_UNKNOWN = 0,
+ NV_SYSTEM_TYPE_LAPTOP = 1,
+ NV_SYSTEM_TYPE_DESKTOP = 2,
+} NV_SYSTEM_TYPE;
+
+
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_GetSystemType(NvPhysicalGpuHandle hPhysicalGpu, NV_SYSTEM_TYPE *pSystemType);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetActiveOutputs
+//
+//! This function is the same as NvAPI_GPU_GetAllOutputs but returns only the set of GPU output
+//! identifiers that are actively driving display devices.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pOutputsMask is NULL.
+//! \retval NVAPI_OK *pOutputsMask contains a set of GPU-output identifiers.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetActiveOutputs(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pOutputsMask);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_SetEDID
+//
+//! Thus function sets the EDID data for the specified GPU handle and connection bit mask.
+//! displayOutputId should have exactly 1 bit set to indicate a single display. See \ref handles.
+//! \note The EDID will be cached across the boot session and will be enumerated to the OS in this call.
+//! To remove the EDID set sizeofEDID to zero.
+//! OS and NVAPI connection status APIs will reflect the newly set or removed EDID dynamically.
+//!
+//! This feature will NOT be supported on the following boards:
+//! - GeForce
+//! - Quadro VX
+//! - Tesla
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 100
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pEDID is NULL; displayOutputId has 0 or > 1 bits set
+//! \retval NVAPI_OK *pEDID data was applied to the requested displayOutputId.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: hPhysicalGpu was not a physical GPU handle.
+//! \retval NVAPI_NOT_SUPPORTED For the above mentioned GPUs
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_SetEDID(NvPhysicalGpuHandle hPhysicalGpu, NvU32 displayOutputId, NV_EDID *pEDID);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetOutputType
+//
+//! \fn NvAPI_GPU_GetOutputType(NvPhysicalGpuHandle hPhysicalGpu, NvU32 outputId, NV_GPU_OUTPUT_TYPE *pOutputType)
+//! This function returns the output type for a specific physical GPU handle and outputId (exactly 1 bit set - see \ref handles).
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \Version Earliest supported ForceWare version: 82.61
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu, outputId, or pOutputsMask is NULL; or outputId has > 1 bit set
+//! \retval NVAPI_OK *pOutputType contains a NvGpuOutputType value
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+//! used in NvAPI_GPU_GetOutputType()
+typedef enum _NV_GPU_OUTPUT_TYPE
+{
+ NVAPI_GPU_OUTPUT_UNKNOWN = 0,
+ NVAPI_GPU_OUTPUT_CRT = 1, //!< CRT display device
+ NVAPI_GPU_OUTPUT_DFP = 2, //!< Digital Flat Panel display device
+ NVAPI_GPU_OUTPUT_TV = 3, //!< TV display device
+} NV_GPU_OUTPUT_TYPE;
+
+
+
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_GetOutputType(NvPhysicalGpuHandle hPhysicalGpu, NvU32 outputId, NV_GPU_OUTPUT_TYPE *pOutputType);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_ValidateOutputCombination
+//
+//! This function determines if a set of GPU outputs can be active
+//! simultaneously. While a GPU may have outputs, typically they cannot
+//! all be active at the same time due to internal resource sharing.
+//!
+//! Given a physical GPU handle and a mask of candidate outputs, this call
+//! will return NVAPI_OK if all of the specified outputs can be driven
+//! simultaneously. It will return NVAPI_INVALID_COMBINATION if they cannot.
+//!
+//! Use NvAPI_GPU_GetAllOutputs() to determine which outputs are candidates.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \retval NVAPI_OK Combination of outputs in outputsMask are valid (can be active simultaneously).
+//! \retval NVAPI_INVALID_COMBINATION Combination of outputs in outputsMask are NOT valid.
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or outputsMask does not have at least 2 bits set.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_ValidateOutputCombination(NvPhysicalGpuHandle hPhysicalGpu, NvU32 outputsMask);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetFullName
+//
+//! This function retrieves the full GPU name as an ASCII string - for example, "Quadro FX 1400".
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \return NVAPI_ERROR or NVAPI_OK
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetFullName(NvPhysicalGpuHandle hPhysicalGpu, NvAPI_ShortString szName);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetFullName)(NvPhysicalGpuHandle hPhysicalGpu, NvAPI_ShortString szName);
+_NvAPI_GPU_GetFullName NvAPI_GPU_GetFullName;
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetPCIIdentifiers
+//
+//! This function returns the PCI identifiers associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \param DeviceId The internal PCI device identifier for the GPU.
+//! \param SubSystemId The internal PCI subsystem identifier for the GPU.
+//! \param RevisionId The internal PCI device-specific revision identifier for the GPU.
+//! \param ExtDeviceId The external PCI device identifier for the GPU.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or an argument is NULL
+//! \retval NVAPI_OK Arguments are populated with PCI identifiers
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPCIIdentifiers)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Out_ NvU32* pDeviceId, _Out_ NvU32* pSubSystemId, _Out_ NvU32* pRevisionId, _Out_ NvU32* pExtDeviceId);
+_NvAPI_GPU_GetPCIIdentifiers NvAPI_GPU_GetPCIIdentifiers;
+
+
+//! \ingroup gpu
+//! Used in NvAPI_GPU_GetGPUType().
+typedef enum _NV_GPU_TYPE
+{
+ NV_SYSTEM_TYPE_GPU_UNKNOWN = 0,
+ NV_SYSTEM_TYPE_IGPU = 1, //!< Integrated GPU
+ NV_SYSTEM_TYPE_DGPU = 2, //!< Discrete GPU
+} NV_GPU_TYPE;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetGPUType
+//
+//! DESCRIPTION: This function returns the GPU type (integrated or discrete).
+//! See ::NV_GPU_TYPE.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 173
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu
+//! \retval NVAPI_OK *pGpuType contains the GPU type
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE: hPhysicalGpu was not a physical GPU handle
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetGPUType(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_GPU_TYPE *pGpuType);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetGPUType)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_GPU_TYPE *pGpuType);
+_NvAPI_GPU_GetGPUType NvAPI_GPU_GetGPUType;
+
+
+//! \ingroup gpu
+//! Used in NvAPI_GPU_GetBusType()
+typedef enum _NV_GPU_BUS_TYPE
+{
+ NVAPI_GPU_BUS_TYPE_UNDEFINED = 0,
+ NVAPI_GPU_BUS_TYPE_PCI = 1,
+ NVAPI_GPU_BUS_TYPE_AGP = 2,
+ NVAPI_GPU_BUS_TYPE_PCI_EXPRESS = 3,
+ NVAPI_GPU_BUS_TYPE_FPCI = 4,
+ NVAPI_GPU_BUS_TYPE_AXI = 5,
+} NV_GPU_BUS_TYPE;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetBusType
+//
+//! This function returns the type of bus associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pBusType is NULL.
+//! \retval NVAPI_OK *pBusType contains bus identifier.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetBusType(NvPhysicalGpuHandle hPhysicalGpu,NV_GPU_BUS_TYPE *pBusType);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetBusType)(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_BUS_TYPE* pBusType);
+_NvAPI_GPU_GetBusType NvAPI_GPU_GetBusType;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetBusId
+//
+//! DESCRIPTION: Returns the ID of the bus associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 167
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pBusId is NULL.
+//! \retval NVAPI_OK *pBusId contains the bus ID.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetBusId)(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pBusId);
+_NvAPI_GPU_GetBusId NvAPI_GPU_GetBusId;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetBusSlotId
+//
+//! DESCRIPTION: Returns the ID of the bus slot associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 167
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pBusSlotId is NULL.
+//! \retval NVAPI_OK *pBusSlotId contains the bus slot ID.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetBusSlotId)(NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pBusSlotId);
+_NvAPI_GPU_GetBusSlotId NvAPI_GPU_GetBusSlotId;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetIRQ
+//
+//! This function returns the interrupt number associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pIRQ is NULL.
+//! \retval NVAPI_OK *pIRQ contains interrupt number.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetIRQ)(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pIRQ);
+_NvAPI_GPU_GetIRQ NvAPI_GPU_GetIRQ;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetVbiosRevision
+//
+//! This function returns the revision of the video BIOS associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pBiosRevision is NULL.
+//! \retval NVAPI_OK *pBiosRevision contains revision number.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetVbiosRevision(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pBiosRevision);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetVbiosOEMRevision
+//
+//! This function returns the OEM revision of the video BIOS associated with this GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu or pBiosRevision is NULL
+//! \retval NVAPI_OK *pBiosRevision contains revision number
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetVbiosOEMRevision(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pBiosRevision);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetVbiosVersionString
+//
+//! This function returns the full video BIOS version string in the form of xx.xx.xx.xx.yy where
+//! - xx numbers come from NvAPI_GPU_GetVbiosRevision() and
+//! - yy comes from NvAPI_GPU_GetVbiosOEMRevision().
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hPhysicalGpu is NULL.
+//! \retval NVAPI_OK szBiosRevision contains version string.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetVbiosVersionString(NvPhysicalGpuHandle hPhysicalGpu, NvAPI_ShortString szBiosRevision);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetVbiosVersionString)(NvPhysicalGpuHandle hPhysicalGpu, NvAPI_ShortString szBiosRevision);
+_NvAPI_GPU_GetVbiosVersionString NvAPI_GPU_GetVbiosVersionString;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetAGPAperture
+//
+//! This function returns the AGP aperture in megabytes.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pSize is NULL.
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetAGPAperture(NvPhysicalGpuHandle hPhysicalGpu,NvU32 *pSize);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetCurrentAGPRate
+//
+//! This function returns the current AGP Rate (0 = AGP not present, 1 = 1x, 2 = 2x, etc.).
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pRate is NULL.
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetCurrentAGPRate(NvPhysicalGpuHandle hPhysicalGpu,NvU32 *pRate);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetCurrentPCIEDownstreamWidth
+//
+//! This function returns the number of PCIE lanes being used for the PCIE interface
+//! downstream from the GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pWidth is NULL.
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetCurrentPCIEDownstreamWidth(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pWidth);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetPhysicalFrameBufferSize
+//
+//! This function returns the physical size of framebuffer in KB. This does NOT include any
+//! system RAM that may be dedicated for use by the GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pSize is NULL
+//! \retval NVAPI_OK Call successful
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetPhysicalFrameBufferSize(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pSize);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetVirtualFrameBufferSize
+//
+//! This function returns the virtual size of framebuffer in KB. This includes the physical RAM plus any
+//! system RAM that has been dedicated for use by the GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 90
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pSize is NULL.
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu was not a physical GPU handle.
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetVirtualFrameBufferSize(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pSize);
+
+
+
+//! \ingroup gpu
+typedef struct _NV_BOARD_INFO
+{
+ NvU32 version; //!< structure version
+ NvU8 BoardNum[16]; //!< Board Serial Number
+}NV_BOARD_INFO_V1;
+
+//! \ingroup gpu
+typedef NV_BOARD_INFO_V1 NV_BOARD_INFO;
+//! \ingroup gpu
+#define NV_BOARD_INFO_VER1 MAKE_NVAPI_VERSION(NV_BOARD_INFO_V1,1)
+//! \ingroup gpu
+#define NV_BOARD_INFO_VER NV_BOARD_INFO_VER1
+
+//! SUPPORTED OS: Windows XP and higher
+//!
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetBoardInfo
+//
+//! DESCRIPTION: This API Retrieves the Board information (a unique GPU Board Serial Number) stored in the InfoROM.
+//!
+//! \param [in] hPhysicalGpu Physical GPU Handle.
+//! \param [in,out] NV_BOARD_INFO Board Information.
+//!
+//! TCC_SUPPORTED
+//!
+//! \retval ::NVAPI_OK completed request
+//! \retval ::NVAPI_ERROR miscellaneous error occurred
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE handle passed is not a physical GPU handle
+//! \retval ::NVAPI_API_NOT_INTIALIZED NVAPI not initialized
+//! \retval ::NVAPI_INVALID_POINTER pBoardInfo is NULL
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION the version of the INFO struct is not supported
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetBoardInfo)(NvPhysicalGpuHandle hPhysicalGpu, NV_BOARD_INFO *pBoardInfo);
+_NvAPI_GPU_GetBoardInfo NvAPI_GPU_GetBoardInfo;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// GPU Clock Control
+//
+// These APIs allow the user to get and set individual clock domains
+// on a per-GPU basis.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//! \ingroup gpuclock
+//! @{
+#define NVAPI_MAX_GPU_CLOCKS 32
+#define NVAPI_MAX_GPU_PUBLIC_CLOCKS 32
+#define NVAPI_MAX_GPU_PERF_CLOCKS 32
+#define NVAPI_MAX_GPU_PERF_VOLTAGES 16
+#define NVAPI_MAX_GPU_PERF_PSTATES 16
+//! @}
+
+//! \ingroup gpuclock
+typedef enum _NV_GPU_PUBLIC_CLOCK_ID
+{
+ NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS = 0,
+ NVAPI_GPU_PUBLIC_CLOCK_MEMORY = 4,
+ NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR = 7,
+ NVAPI_GPU_PUBLIC_CLOCK_UNDEFINED = NVAPI_MAX_GPU_PUBLIC_CLOCKS,
+} NV_GPU_PUBLIC_CLOCK_ID;
+
+
+//! \ingroup gpuclock
+typedef enum _NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID
+{
+ NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE = 0,
+ NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_UNDEFINED = NVAPI_MAX_GPU_PERF_VOLTAGES,
+} NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID;
+
+
+
+//! \ingroup gpuclock
+//! Used in NvAPI_GPU_GetAllClockFrequencies()
+typedef struct _NV_GPU_CLOCK_FREQUENCIES_V1
+{
+ NvU32 version; //!< Structure version
+ NvU32 reserved; //!< These bits are reserved for future use.
+ struct
+ {
+ NvU32 bIsPresent:1; //!< Set if this domain is present on this GPU
+ NvU32 reserved:31; //!< These bits are reserved for future use.
+ NvU32 frequency; //!< Clock frequency (kHz)
+ }domain[NVAPI_MAX_GPU_PUBLIC_CLOCKS];
+} NV_GPU_CLOCK_FREQUENCIES_V1;
+
+//! \ingroup gpuclock
+//! Used in NvAPI_GPU_GetAllClockFrequencies()
+typedef enum _NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE
+{
+ NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ = 0,
+ NV_GPU_CLOCK_FREQUENCIES_BASE_CLOCK = 1,
+ NV_GPU_CLOCK_FREQUENCIES_BOOST_CLOCK = 2,
+ NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE_NUM = 3
+} NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE;
+
+//! \ingroup gpuclock
+//! Used in NvAPI_GPU_GetAllClockFrequencies()
+typedef struct
+{
+ NvU32 version; //!< Structure version
+ NvU32 ClockType:2; //!< One of NV_GPU_CLOCK_FREQUENCIES_CLOCK_TYPE. Used to specify the type of clock to be returned.
+ NvU32 reserved:22; //!< These bits are reserved for future use. Must be set to 0.
+ NvU32 reserved1:8; //!< These bits are reserved.
+ struct
+ {
+ NvU32 bIsPresent:1; //!< Set if this domain is present on this GPU
+ NvU32 reserved:31; //!< These bits are reserved for future use.
+ NvU32 frequency; //!< Clock frequency (kHz)
+ }domain[NVAPI_MAX_GPU_PUBLIC_CLOCKS];
+} NV_GPU_CLOCK_FREQUENCIES_V2;
+
+//! \ingroup gpuclock
+//! Used in NvAPI_GPU_GetAllClockFrequencies()
+typedef NV_GPU_CLOCK_FREQUENCIES_V2 NV_GPU_CLOCK_FREQUENCIES;
+
+//! \addtogroup gpuclock
+//! @{
+#define NV_GPU_CLOCK_FREQUENCIES_VER_1 MAKE_NVAPI_VERSION(NV_GPU_CLOCK_FREQUENCIES_V1,1)
+#define NV_GPU_CLOCK_FREQUENCIES_VER_2 MAKE_NVAPI_VERSION(NV_GPU_CLOCK_FREQUENCIES_V2,2)
+#define NV_GPU_CLOCK_FREQUENCIES_VER NV_GPU_CLOCK_FREQUENCIES_VER_2
+//! @}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetAllClockFrequencies
+//
+//! This function retrieves the NV_GPU_CLOCK_FREQUENCIES structure for the specified physical GPU.
+//!
+//! For each clock domain:
+//! - bIsPresent is set for each domain that is present on the GPU
+//! - frequency is the domain's clock freq in kHz
+//!
+//! Each domain's info is indexed in the array. For example:
+//! clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY] holds the info for the MEMORY domain.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 295
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API,
+//! they are listed below.
+//! \retval NVAPI_INVALID_ARGUMENT pClkFreqs is NULL.
+//! \ingroup gpuclock
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetAllClockFrequencies(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_GPU_CLOCK_FREQUENCIES* pClkFreqs);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetAllClockFrequencies)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_GPU_CLOCK_FREQUENCIES* pClkFreqs);
+_NvAPI_GPU_GetAllClockFrequencies NvAPI_GPU_GetAllClockFrequencies;
+
+//! \addtogroup gpupstate
+//! @{
+
+typedef enum _NV_GPU_PERF_PSTATE_ID
+{
+ NVAPI_GPU_PERF_PSTATE_P0 = 0,
+ NVAPI_GPU_PERF_PSTATE_P1,
+ NVAPI_GPU_PERF_PSTATE_P2,
+ NVAPI_GPU_PERF_PSTATE_P3,
+ NVAPI_GPU_PERF_PSTATE_P4,
+ NVAPI_GPU_PERF_PSTATE_P5,
+ NVAPI_GPU_PERF_PSTATE_P6,
+ NVAPI_GPU_PERF_PSTATE_P7,
+ NVAPI_GPU_PERF_PSTATE_P8,
+ NVAPI_GPU_PERF_PSTATE_P9,
+ NVAPI_GPU_PERF_PSTATE_P10,
+ NVAPI_GPU_PERF_PSTATE_P11,
+ NVAPI_GPU_PERF_PSTATE_P12,
+ NVAPI_GPU_PERF_PSTATE_P13,
+ NVAPI_GPU_PERF_PSTATE_P14,
+ NVAPI_GPU_PERF_PSTATE_P15,
+ NVAPI_GPU_PERF_PSTATE_UNDEFINED = NVAPI_MAX_GPU_PERF_PSTATES,
+ NVAPI_GPU_PERF_PSTATE_ALL,
+
+} NV_GPU_PERF_PSTATE_ID;
+
+//! @}
+
+
+
+//! \ingroup gpupstate
+//! Used in NvAPI_GPU_GetPstatesInfoEx()
+typedef struct _NV_GPU_PERF_PSTATES_INFO_V1
+{
+ NvU32 version;
+ NvU32 flags; //!< - bit 0 indicates if perfmon is enabled or not
+ //!< - bit 1 indicates if dynamic Pstate is capable or not
+ //!< - bit 2 indicates if dynamic Pstate is enable or not
+ //!< - all other bits must be set to 0
+ NvU32 numPstates; //!< The number of available p-states
+ NvU32 numClocks; //!< The number of clock domains supported by each P-State
+ struct
+ {
+ NV_GPU_PERF_PSTATE_ID pstateId; //!< ID of the p-state.
+ NvU32 flags; //!< - bit 0 indicates if the PCIE limit is GEN1 or GEN2
+ //!< - bit 1 indicates if the Pstate is overclocked or not
+ //!< - bit 2 indicates if the Pstate is overclockable or not
+ //!< - all other bits must be set to 0
+ struct
+ {
+ NV_GPU_PUBLIC_CLOCK_ID domainId; //!< ID of the clock domain
+ NvU32 flags; //!< Reserved. Must be set to 0
+ NvU32 freq; //!< Clock frequency in kHz
+
+ } clocks[NVAPI_MAX_GPU_PERF_CLOCKS];
+ } pstates[NVAPI_MAX_GPU_PERF_PSTATES];
+
+} NV_GPU_PERF_PSTATES_INFO_V1;
+
+
+//! \ingroup gpupstate
+typedef struct _NV_GPU_PERF_PSTATES_INFO_V2
+{
+ NvU32 version;
+ NvU32 flags; //!< - bit 0 indicates if perfmon is enabled or not
+ //!< - bit 1 indicates if dynamic Pstate is capable or not
+ //!< - bit 2 indicates if dynamic Pstate is enable or not
+ //!< - all other bits must be set to 0
+ NvU32 numPstates; //!< The number of available p-states
+ NvU32 numClocks; //!< The number of clock domains supported by each P-State
+ NvU32 numVoltages;
+ struct
+ {
+ NV_GPU_PERF_PSTATE_ID pstateId; //!< ID of the p-state.
+ NvU32 flags; //!< - bit 0 indicates if the PCIE limit is GEN1 or GEN2
+ //!< - bit 1 indicates if the Pstate is overclocked or not
+ //!< - bit 2 indicates if the Pstate is overclockable or not
+ //!< - all other bits must be set to 0
+ struct
+ {
+ NV_GPU_PUBLIC_CLOCK_ID domainId;
+ NvU32 flags; //!< bit 0 indicates if this clock is overclockable
+ //!< all other bits must be set to 0
+ NvU32 freq;
+
+ } clocks[NVAPI_MAX_GPU_PERF_CLOCKS];
+ struct
+ {
+ NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId; //!< ID of the voltage domain, containing flags and mvolt info
+ NvU32 flags; //!< Reserved for future use. Must be set to 0
+ NvU32 mvolt; //!< Voltage in mV
+
+ } voltages[NVAPI_MAX_GPU_PERF_VOLTAGES];
+
+ } pstates[NVAPI_MAX_GPU_PERF_PSTATES]; //!< Valid index range is 0 to numVoltages-1
+
+} NV_GPU_PERF_PSTATES_INFO_V2;
+
+//! \ingroup gpupstate
+typedef NV_GPU_PERF_PSTATES_INFO_V2 NV_GPU_PERF_PSTATES_INFO;
+
+
+//! \ingroup gpupstate
+//! @{
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES_INFO_V1
+#define NV_GPU_PERF_PSTATES_INFO_VER1 MAKE_NVAPI_VERSION(NV_GPU_PERF_PSTATES_INFO_V1,1)
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES_INFO_V2
+#define NV_GPU_PERF_PSTATES_INFO_VER2 MAKE_NVAPI_VERSION(NV_GPU_PERF_PSTATES_INFO_V2,2)
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES_INFO
+#define NV_GPU_PERF_PSTATES_INFO_VER NV_GPU_PERF_PSTATES_INFO_VER2
+
+//! @}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetPstatesInfoEx
+//
+//! DESCRIPTION: This API retrieves all performance states (P-States) information. This is the same as
+//! NvAPI_GPU_GetPstatesInfo(), but supports an input flag for various options.
+//!
+//! P-States are GPU active/executing performance capability and power consumption states.
+//!
+//! P-States ranges from P0 to P15, with P0 being the highest performance/power state, and
+//! P15 being the lowest performance/power state. Each P-State, if available, maps to a
+//! performance level. Not all P-States are available on a given system. The definitions
+//! of each P-State are currently as follows: \n
+//! - P0/P1 - Maximum 3D performance
+//! - P2/P3 - Balanced 3D performance-power
+//! - P8 - Basic HD video playback
+//! - P10 - DVD playback
+//! - P12 - Minimum idle power consumption
+//!
+//! \deprecated Do not use this function - it is deprecated in release 304. Instead, use NvAPI_GPU_GetPstates20.
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \param [in] hPhysicalGPU GPU selection.
+//! \param [out] pPerfPstatesInfo P-States information retrieved, as detailed below: \n
+//! - flags is reserved for future use.
+//! - numPstates is the number of available P-States
+//! - numClocks is the number of clock domains supported by each P-State
+//! - pstates has valid index range from 0 to numPstates - 1
+//! - pstates[i].pstateId is the ID of the P-State,
+//! containing the following info:
+//! - pstates[i].flags containing the following info:
+//! - bit 0 indicates if the PCIE limit is GEN1 or GEN2
+//! - bit 1 indicates if the Pstate is overclocked or not
+//! - bit 2 indicates if the Pstate is overclockable or not
+//! - pstates[i].clocks has valid index range from 0 to numClocks -1
+//! - pstates[i].clocks[j].domainId is the public ID of the clock domain,
+//! containing the following info:
+//! - pstates[i].clocks[j].flags containing the following info:
+//! bit 0 indicates if the clock domain is overclockable or not
+//! - pstates[i].clocks[j].freq is the clock frequency in kHz
+//! - pstates[i].voltages has a valid index range from 0 to numVoltages - 1
+//! - pstates[i].voltages[j].domainId is the ID of the voltage domain,
+//! containing the following info:
+//! - pstates[i].voltages[j].flags is reserved for future use.
+//! - pstates[i].voltages[j].mvolt is the voltage in mV
+//! inputFlags(IN) - This can be used to select various options:
+//! - if bit 0 is set, pPerfPstatesInfo would contain the default settings
+//! instead of the current, possibily overclocked settings.
+//! - if bit 1 is set, pPerfPstatesInfo would contain the maximum clock
+//! frequencies instead of the nominal frequencies.
+//! - if bit 2 is set, pPerfPstatesInfo would contain the minimum clock
+//! frequencies instead of the nominal frequencies.
+//! - all other bits must be set to 0.
+//!
+//! \retval ::NVAPI_OK Completed request
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred
+//! \retval ::NVAPI_HANDLE_INVALIDATED Handle passed has been invalidated (see user guide)
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE Handle passed is not a physical GPU handle
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the NV_GPU_PERF_PSTATES struct is not supported
+//!
+//! \ingroup gpupstate
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 304. Instead, use NvAPI_GPU_GetPstates20.")
+NVAPI_INTERFACE NvAPI_GPU_GetPstatesInfoEx(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_PERF_PSTATES_INFO *pPerfPstatesInfo, NvU32 inputFlags);
+
+
+//! \addtogroup gpupstate
+//! @{
+
+#define NVAPI_MAX_GPU_PSTATE20_PSTATES 16
+#define NVAPI_MAX_GPU_PSTATE20_CLOCKS 8
+#define NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES 4
+
+//! Used to identify clock type
+typedef enum _NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID
+{
+ //! Clock domains that use single frequency value within given pstate
+ NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_SINGLE = 0,
+
+ //! Clock domains that allow range of frequency values within given pstate
+ NVAPI_GPU_PERF_PSTATE20_CLOCK_TYPE_RANGE,
+} NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID;
+
+//! Used to describe both voltage and frequency deltas
+typedef struct _NV_GPU_PERF_PSTATES20_PARAM_DELTA
+{
+ //! Value of parameter delta (in respective units [kHz, uV])
+ NvS32 value;
+
+ struct
+ {
+ //! Min value allowed for parameter delta (in respective units [kHz, uV])
+ NvS32 min;
+
+ //! Max value allowed for parameter delta (in respective units [kHz, uV])
+ NvS32 max;
+ } valueRange;
+} NV_GPU_PERF_PSTATES20_PARAM_DELTA;
+
+//! Used to describe single clock entry
+typedef struct _NV_GPU_PSTATE20_CLOCK_ENTRY_V1
+{
+ //! ID of the clock domain
+ NV_GPU_PUBLIC_CLOCK_ID domainId;
+
+ //! Clock type ID
+ NV_GPU_PERF_PSTATE20_CLOCK_TYPE_ID typeId;
+ NvU32 bIsEditable : 1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved : 31;
+
+ //! Current frequency delta from nominal settings in (kHz)
+ NV_GPU_PERF_PSTATES20_PARAM_DELTA freqDelta_kHz;
+
+ //! Clock domain type dependant information
+ union
+ {
+ struct
+ {
+ //! Clock frequency within given pstate in (kHz)
+ NvU32 freq_kHz;
+ } single;
+
+ struct
+ {
+ //! Min clock frequency within given pstate in (kHz)
+ NvU32 minFreq_kHz;
+
+ //! Max clock frequency within given pstate in (kHz)
+ NvU32 maxFreq_kHz;
+
+ //! Voltage domain ID and value range in (uV) required for this clock
+ NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId;
+ NvU32 minVoltage_uV;
+ NvU32 maxVoltage_uV;
+ } range;
+ } data;
+} NV_GPU_PSTATE20_CLOCK_ENTRY_V1;
+
+//! Used to describe single base voltage entry
+typedef struct _NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1
+{
+ //! ID of the voltage domain
+ NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId;
+ NvU32 bIsEditable:1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved:31;
+
+ //! Current base voltage settings in [uV]
+ NvU32 volt_uV;
+
+ NV_GPU_PERF_PSTATES20_PARAM_DELTA voltDelta_uV; // Current base voltage delta from nominal settings in [uV]
+} NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1;
+
+//! Used in NvAPI_GPU_GetPstates20() interface call.
+
+typedef struct _NV_GPU_PERF_PSTATES20_INFO_V1
+{
+ //! Version info of the structure (NV_GPU_PERF_PSTATES20_INFO_VER)
+ NvU32 version;
+
+ NvU32 bIsEditable:1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved:31;
+
+ //! Number of populated pstates
+ NvU32 numPstates;
+
+ //! Number of populated clocks (per pstate)
+ NvU32 numClocks;
+
+ //! Number of populated base voltages (per pstate)
+ NvU32 numBaseVoltages;
+
+ //! Performance state (P-State) settings
+ //! Valid index range is 0 to numPstates-1
+ struct
+ {
+ //! ID of the P-State
+ NV_GPU_PERF_PSTATE_ID pstateId;
+
+ NvU32 bIsEditable:1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved:31;
+
+ //! Array of clock entries
+ //! Valid index range is 0 to numClocks-1
+ NV_GPU_PSTATE20_CLOCK_ENTRY_V1 clocks[NVAPI_MAX_GPU_PSTATE20_CLOCKS];
+
+ //! Array of baseVoltage entries
+ //! Valid index range is 0 to numBaseVoltages-1
+ NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 baseVoltages[NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES];
+ } pstates[NVAPI_MAX_GPU_PSTATE20_PSTATES];
+} NV_GPU_PERF_PSTATES20_INFO_V1;
+
+//! Used in NvAPI_GPU_GetPstates20() interface call.
+
+typedef struct _NV_GPU_PERF_PSTATES20_INFO_V2
+{
+ //! Version info of the structure (NV_GPU_PERF_PSTATES20_INFO_VER)
+ NvU32 version;
+
+ NvU32 bIsEditable : 1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved : 31;
+
+ //! Number of populated pstates
+ NvU32 numPstates;
+
+ //! Number of populated clocks (per pstate)
+ NvU32 numClocks;
+
+ //! Number of populated base voltages (per pstate)
+ NvU32 numBaseVoltages;
+
+ //! Performance state (P-State) settings
+ //! Valid index range is 0 to numPstates-1
+ struct
+ {
+ //! ID of the P-State
+ NV_GPU_PERF_PSTATE_ID pstateId;
+
+ NvU32 bIsEditable : 1;
+
+ //! These bits are reserved for future use (must be always 0)
+ NvU32 reserved : 31;
+
+ //! Array of clock entries
+ //! Valid index range is 0 to numClocks-1
+ NV_GPU_PSTATE20_CLOCK_ENTRY_V1 clocks[NVAPI_MAX_GPU_PSTATE20_CLOCKS];
+
+ //! Array of baseVoltage entries
+ //! Valid index range is 0 to numBaseVoltages-1
+ NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 baseVoltages[NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES];
+ } pstates[NVAPI_MAX_GPU_PSTATE20_PSTATES];
+
+ //! OV settings - Please refer to NVIDIA over-volting recommendation to understand impact of this functionality
+ //! Valid index range is 0 to numVoltages-1
+ struct
+ {
+ //! Number of populated voltages
+ NvU32 numVoltages;
+
+ //! Array of voltage entries
+ //! Valid index range is 0 to numVoltages-1
+ NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY_V1 voltages[NVAPI_MAX_GPU_PSTATE20_BASE_VOLTAGES];
+ } ov;
+} NV_GPU_PERF_PSTATES20_INFO_V2;
+
+typedef NV_GPU_PERF_PSTATES20_INFO_V2 NV_GPU_PERF_PSTATES20_INFO;
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES20_INFO_V1
+#define NV_GPU_PERF_PSTATES20_INFO_VER1 MAKE_NVAPI_VERSION(NV_GPU_PERF_PSTATES20_INFO_V1,1)
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES20_INFO_V2
+#define NV_GPU_PERF_PSTATES20_INFO_VER2 MAKE_NVAPI_VERSION(NV_GPU_PERF_PSTATES20_INFO_V2,2)
+
+//! Macro for constructing the version field of NV_GPU_PERF_PSTATES20_INFO
+#define NV_GPU_PERF_PSTATES20_INFO_VER NV_GPU_PERF_PSTATES20_INFO_VER2
+
+//! @}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetPstates20
+//
+//! DESCRIPTION: This API retrieves all performance states (P-States) 2.0 information.
+//!
+//! P-States are GPU active/executing performance capability states.
+//! They range from P0 to P15, with P0 being the highest performance state,
+//! and P15 being the lowest performance state. Each P-State, if available,
+//! maps to a performance level. Not all P-States are available on a given system.
+//! The definition of each P-States are currently as follow:
+//! - P0/P1 - Maximum 3D performance
+//! - P2/P3 - Balanced 3D performance-power
+//! - P8 - Basic HD video playback
+//! - P10 - DVD playback
+//! - P12 - Minimum idle power consumption
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 295
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \param [in] hPhysicalGPU GPU selection
+//! \param [out] pPstatesInfo P-States information retrieved, as documented in declaration above
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API,
+//! they are listed below.
+//!
+//! \ingroup gpupstate
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetPstates20(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_GPU_PERF_PSTATES20_INFO* pPstatesInfo);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPstates20)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_GPU_PERF_PSTATES20_INFO* pPstatesInfo);
+_NvAPI_GPU_GetPstates20 NvAPI_GPU_GetPstates20;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetCurrentPstate
+//
+//! DESCRIPTION: This function retrieves the current performance state (P-State).
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 165
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGPU GPU selection
+//! \param [out] pCurrentPstate The ID of the current P-State of the GPU - see \ref NV_GPU_PERF_PSTATES.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred.
+//! \retval NVAPI_HANDLE_INVALIDATED Handle passed has been invalidated (see user guide).
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE Handle passed is not a physical GPU handle.
+//! \retval NVAPI_NOT_SUPPORTED P-States is not supported on this setup.
+//!
+//! \ingroup gpupstate
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetCurrentPstate(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_PERF_PSTATE_ID *pCurrentPstate);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetCurrentPstate)(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_PERF_PSTATE_ID *pCurrentPstate);
+_NvAPI_GPU_GetCurrentPstate NvAPI_GPU_GetCurrentPstate;
+
+
+//! \ingroup gpupstate
+#define NVAPI_MAX_GPU_UTILIZATIONS 8
+
+
+
+//! \ingroup gpupstate
+//! Used in NvAPI_GPU_GetDynamicPstatesInfoEx().
+typedef struct _NV_GPU_DYNAMIC_PSTATES_INFO_EX
+{
+ NvU32 version; //!< Structure version
+ NvU32 flags; //!< bit 0 indicates if the dynamic Pstate is enabled or not
+ struct
+ {
+ NvU32 bIsPresent:1; //!< Set if this utilization domain is present on this GPU
+ NvU32 percentage; //!< Percentage of time where the domain is considered busy in the last 1 second interval
+ } utilization[NVAPI_MAX_GPU_UTILIZATIONS];
+} NV_GPU_DYNAMIC_PSTATES_INFO_EX;
+
+//! \ingroup gpupstate
+//! Macro for constructing the version field of NV_GPU_DYNAMIC_PSTATES_INFO_EX
+#define NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER MAKE_NVAPI_VERSION(NV_GPU_DYNAMIC_PSTATES_INFO_EX,1)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetDynamicPstatesInfoEx
+//
+//! DESCRIPTION: This API retrieves the NV_GPU_DYNAMIC_PSTATES_INFO_EX structure for the specified physical GPU.
+//! Each domain's info is indexed in the array. For example:
+//! - pDynamicPstatesInfo->utilization[NVAPI_GPU_UTILIZATION_DOMAIN_GPU] holds the info for the GPU domain. \p
+//! There are currently 4 domains for which GPU utilization and dynamic P-State thresholds can be retrieved:
+//! graphic engine (GPU), frame buffer (FB), video engine (VID), and bus interface (BUS).
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 185
+//!
+//! \retval ::NVAPI_OK
+//! \retval ::NVAPI_ERROR
+//! \retval ::NVAPI_INVALID_ARGUMENT pDynamicPstatesInfo is NULL
+//! \retval ::NVAPI_HANDLE_INVALIDATED
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the INFO struct is not supported
+//!
+//! \ingroup gpupstate
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetDynamicPstatesInfoEx(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_DYNAMIC_PSTATES_INFO_EX *pDynamicPstatesInfoEx);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetDynamicPstatesInfoEx)(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_DYNAMIC_PSTATES_INFO_EX* pDynamicPstatesInfoEx);
+_NvAPI_GPU_GetDynamicPstatesInfoEx NvAPI_GPU_GetDynamicPstatesInfoEx;
+
+///////////////////////////////////////////////////////////////////////////////////
+// Thermal API
+// Provides ability to get temperature levels from the various thermal sensors associated with the GPU
+
+//! \ingroup gputhermal
+#define NVAPI_MAX_THERMAL_SENSORS_PER_GPU 3
+
+//! \ingroup gputhermal
+//! Used in NV_GPU_THERMAL_SETTINGS
+typedef enum _NV_THERMAL_TARGET
+{
+ NVAPI_THERMAL_TARGET_NONE = 0,
+ NVAPI_THERMAL_TARGET_GPU = 1, //!< GPU core temperature requires NvPhysicalGpuHandle
+ NVAPI_THERMAL_TARGET_MEMORY = 2, //!< GPU memory temperature requires NvPhysicalGpuHandle
+ NVAPI_THERMAL_TARGET_POWER_SUPPLY = 4, //!< GPU power supply temperature requires NvPhysicalGpuHandle
+ NVAPI_THERMAL_TARGET_BOARD = 8, //!< GPU board ambient temperature requires NvPhysicalGpuHandle
+ NVAPI_THERMAL_TARGET_VCD_BOARD = 9, //!< Visual Computing Device Board temperature requires NvVisualComputingDeviceHandle
+ NVAPI_THERMAL_TARGET_VCD_INLET = 10, //!< Visual Computing Device Inlet temperature requires NvVisualComputingDeviceHandle
+ NVAPI_THERMAL_TARGET_VCD_OUTLET = 11, //!< Visual Computing Device Outlet temperature requires NvVisualComputingDeviceHandle
+
+ NVAPI_THERMAL_TARGET_ALL = 15,
+ NVAPI_THERMAL_TARGET_UNKNOWN = -1,
+} NV_THERMAL_TARGET;
+
+//! \ingroup gputhermal
+//! Used in NV_GPU_THERMAL_SETTINGS
+typedef enum _NV_THERMAL_CONTROLLER
+{
+ NVAPI_THERMAL_CONTROLLER_NONE = 0,
+ NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL,
+ NVAPI_THERMAL_CONTROLLER_ADM1032,
+ NVAPI_THERMAL_CONTROLLER_MAX6649,
+ NVAPI_THERMAL_CONTROLLER_MAX1617,
+ NVAPI_THERMAL_CONTROLLER_LM99,
+ NVAPI_THERMAL_CONTROLLER_LM89,
+ NVAPI_THERMAL_CONTROLLER_LM64,
+ NVAPI_THERMAL_CONTROLLER_ADT7473,
+ NVAPI_THERMAL_CONTROLLER_SBMAX6649,
+ NVAPI_THERMAL_CONTROLLER_VBIOSEVT,
+ NVAPI_THERMAL_CONTROLLER_OS,
+ NVAPI_THERMAL_CONTROLLER_UNKNOWN = -1,
+} NV_THERMAL_CONTROLLER;
+
+//! \ingroup gputhermal
+//! Used in NvAPI_GPU_GetThermalSettings()
+typedef struct _NV_GPU_THERMAL_SETTINGS_V1
+{
+ NvU32 version; //!< structure version
+ NvU32 count; //!< number of associated thermal sensors
+ struct
+ {
+ NV_THERMAL_CONTROLLER controller; //!< internal, ADM1032, MAX6649...
+ NvU32 defaultMinTemp; //!< The min default temperature value of the thermal sensor in degree Celsius
+ NvU32 defaultMaxTemp; //!< The max default temperature value of the thermal sensor in degree Celsius
+ NvU32 currentTemp; //!< The current temperature value of the thermal sensor in degree Celsius
+ NV_THERMAL_TARGET target; //!< Thermal sensor targeted @ GPU, memory, chipset, powersupply, Visual Computing Device, etc.
+ } sensor[NVAPI_MAX_THERMAL_SENSORS_PER_GPU];
+
+} NV_GPU_THERMAL_SETTINGS_V1;
+
+//! \ingroup gputhermal
+typedef struct _NV_GPU_THERMAL_SETTINGS_V2
+{
+ NvU32 version; //!< structure version
+ NvU32 count; //!< number of associated thermal sensors
+ struct
+ {
+ NV_THERMAL_CONTROLLER controller; //!< internal, ADM1032, MAX6649...
+ NvS32 defaultMinTemp; //!< Minimum default temperature value of the thermal sensor in degree Celsius
+ NvS32 defaultMaxTemp; //!< Maximum default temperature value of the thermal sensor in degree Celsius
+ NvS32 currentTemp; //!< Current temperature value of the thermal sensor in degree Celsius
+ NV_THERMAL_TARGET target; //!< Thermal sensor targeted - GPU, memory, chipset, powersupply, Visual Computing Device, etc
+ } sensor[NVAPI_MAX_THERMAL_SENSORS_PER_GPU];
+
+} NV_GPU_THERMAL_SETTINGS_V2;
+
+//! \ingroup gputhermal
+typedef NV_GPU_THERMAL_SETTINGS_V2 NV_GPU_THERMAL_SETTINGS;
+
+//! \ingroup gputhermal
+//! @{
+
+//! Macro for constructing the version field of NV_GPU_THERMAL_SETTINGS_V1
+#define NV_GPU_THERMAL_SETTINGS_VER_1 MAKE_NVAPI_VERSION(NV_GPU_THERMAL_SETTINGS_V1,1)
+
+//! Macro for constructing the version field of NV_GPU_THERMAL_SETTINGS_V2
+#define NV_GPU_THERMAL_SETTINGS_VER_2 MAKE_NVAPI_VERSION(NV_GPU_THERMAL_SETTINGS_V2,2)
+
+//! Macro for constructing the version field of NV_GPU_THERMAL_SETTINGS
+#define NV_GPU_THERMAL_SETTINGS_VER NV_GPU_THERMAL_SETTINGS_VER_2
+//! @}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetThermalSettings
+//
+//! This function retrieves the thermal information of all thermal sensors or specific thermal sensor associated with the selected GPU.
+//! Thermal sensors are indexed 0 to NVAPI_MAX_THERMAL_SENSORS_PER_GPU-1.
+//!
+//! - To retrieve specific thermal sensor info, set the sensorIndex to the required thermal sensor index.
+//! - To retrieve info for all sensors, set sensorIndex to NVAPI_THERMAL_TARGET_ALL.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 85
+//!
+//! \param [in] hPhysicalGPU GPU selection.
+//! \param [in] sensorIndex Explicit thermal sensor index selection.
+//! \param [out] pThermalSettings Array of thermal settings.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred.
+//! \retval NVAPI_INVALID_ARGUMENT pThermalInfo is NULL.
+//! \retval NVAPI_HANDLE_INVALIDATED Handle passed has been invalidated (see user guide).
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE Handle passed is not a physical GPU handle.
+//! \retval NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the INFO struct is not supported.
+//! \ingroup gputhermal
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetThermalSettings(NvPhysicalGpuHandle hPhysicalGpu, NvU32 sensorIndex, NV_GPU_THERMAL_SETTINGS *pThermalSettings);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetThermalSettings)(NvPhysicalGpuHandle hPhysicalGpu, NvU32 sensorIndex, NV_GPU_THERMAL_SETTINGS *pThermalSettings);
+_NvAPI_GPU_GetThermalSettings NvAPI_GPU_GetThermalSettings;
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// I2C API
+// Provides ability to read or write data using I2C protocol.
+// These APIs allow I2C access only to DDC monitors
+
+
+//! \addtogroup i2capi
+//! @{
+#define NVAPI_MAX_SIZEOF_I2C_DATA_BUFFER 4096
+#define NVAPI_MAX_SIZEOF_I2C_REG_ADDRESS 4
+#define NVAPI_DISPLAY_DEVICE_MASK_MAX 24
+#define NVAPI_I2C_SPEED_DEPRECATED 0xFFFF
+
+typedef enum _NV_I2C_SPEED
+{
+ NVAPI_I2C_SPEED_DEFAULT, //!< Set i2cSpeedKhz to I2C_SPEED_DEFAULT if default I2C speed is to be chosen, ie.use the current frequency setting.
+ NVAPI_I2C_SPEED_3KHZ,
+ NVAPI_I2C_SPEED_10KHZ,
+ NVAPI_I2C_SPEED_33KHZ,
+ NVAPI_I2C_SPEED_100KHZ,
+ NVAPI_I2C_SPEED_200KHZ,
+ NVAPI_I2C_SPEED_400KHZ,
+} NV_I2C_SPEED;
+
+//! Used in NvAPI_I2CRead() and NvAPI_I2CWrite()
+typedef struct
+{
+ NvU32 version; //!< The structure version.
+ NvU32 displayMask; //!< The Display Mask of the concerned display.
+ NvU8 bIsDDCPort; //!< This flag indicates either the DDC port (TRUE) or the communication port
+ //!< (FALSE) of the concerned display.
+ NvU8 i2cDevAddress; //!< The address of the I2C slave. The address should be shifted left by one. For
+ //!< example, the I2C address 0x50, often used for reading EDIDs, would be stored
+ //!< here as 0xA0. This matches the position within the byte sent by the master, as
+ //!< the last bit is reserved to specify the read or write direction.
+ NvU8* pbI2cRegAddress; //!< The I2C target register address. May be NULL, which indicates no register
+ //!< address should be sent.
+ NvU32 regAddrSize; //!< The size in bytes of target register address. If pbI2cRegAddress is NULL, this
+ //!< field must be 0.
+ NvU8* pbData; //!< The buffer of data which is to be read or written (depending on the command).
+ NvU32 cbSize; //!< The size of the data buffer, pbData, to be read or written.
+ NvU32 i2cSpeed; //!< The target speed of the transaction (between 28Kbps to 40Kbps; not guaranteed).
+} NV_I2C_INFO_V1;
+
+//! Used in NvAPI_I2CRead() and NvAPI_I2CWrite()
+typedef struct
+{
+ NvU32 version; //!< The structure version.
+ NvU32 displayMask; //!< The Display Mask of the concerned display.
+ NvU8 bIsDDCPort; //!< This flag indicates either the DDC port (TRUE) or the communication port
+ //!< (FALSE) of the concerned display.
+ NvU8 i2cDevAddress; //!< The address of the I2C slave. The address should be shifted left by one. For
+ //!< example, the I2C address 0x50, often used for reading EDIDs, would be stored
+ //!< here as 0xA0. This matches the position within the byte sent by the master, as
+ //!< the last bit is reserved to specify the read or write direction.
+ NvU8* pbI2cRegAddress; //!< The I2C target register address. May be NULL, which indicates no register
+ //!< address should be sent.
+ NvU32 regAddrSize; //!< The size in bytes of target register address. If pbI2cRegAddress is NULL, this
+ //!< field must be 0.
+ NvU8* pbData; //!< The buffer of data which is to be read or written (depending on the command).
+ NvU32 cbSize; //!< The size of the data buffer, pbData, to be read or written.
+ NvU32 i2cSpeed; //!< Deprecated, Must be set to NVAPI_I2C_SPEED_DEPRECATED.
+ NV_I2C_SPEED i2cSpeedKhz; //!< The target speed of the transaction in (kHz) (Chosen from the enum NV_I2C_SPEED).
+} NV_I2C_INFO_V2;
+
+//! Used in NvAPI_I2CRead() and NvAPI_I2CWrite()
+typedef struct
+{
+ NvU32 version; //!< The structure version.
+ NvU32 displayMask; //!< The Display Mask of the concerned display.
+ NvU8 bIsDDCPort; //!< This flag indicates either the DDC port (TRUE) or the communication port
+ //!< (FALSE) of the concerned display.
+ NvU8 i2cDevAddress; //!< The address of the I2C slave. The address should be shifted left by one. For
+ //!< example, the I2C address 0x50, often used for reading EDIDs, would be stored
+ //!< here as 0xA0. This matches the position within the byte sent by the master, as
+ //!< the last bit is reserved to specify the read or write direction.
+ NvU8* pbI2cRegAddress; //!< The I2C target register address. May be NULL, which indicates no register
+ //!< address should be sent.
+ NvU32 regAddrSize; //!< The size in bytes of target register address. If pbI2cRegAddress is NULL, this
+ //!< field must be 0.
+ NvU8* pbData; //!< The buffer of data which is to be read or written (depending on the command).
+ NvU32 cbSize; //!< The size of the data buffer, pbData, to be read or written.
+ NvU32 i2cSpeed; //!< Deprecated, Must be set to NVAPI_I2C_SPEED_DEPRECATED.
+ NV_I2C_SPEED i2cSpeedKhz; //!< The target speed of the transaction in (kHz) (Chosen from the enum NV_I2C_SPEED).
+ NvU8 portId; //!< The portid on which device is connected (remember to set bIsPortIdSet if this value is set)
+ //!< Optional for pre-Kepler
+ NvU32 bIsPortIdSet; //!< set this flag on if and only if portid value is set
+} NV_I2C_INFO_V3;
+
+typedef NV_I2C_INFO_V3 NV_I2C_INFO;
+
+#define NV_I2C_INFO_VER3 MAKE_NVAPI_VERSION(NV_I2C_INFO_V3,3)
+#define NV_I2C_INFO_VER2 MAKE_NVAPI_VERSION(NV_I2C_INFO_V2,2)
+#define NV_I2C_INFO_VER1 MAKE_NVAPI_VERSION(NV_I2C_INFO_V1,1)
+
+#define NV_I2C_INFO_VER NV_I2C_INFO_VER3
+//! @}
+
+/***********************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_I2CRead
+//
+//! This function reads the data buffer from the I2C port.
+//! The I2C request must be for a DDC port: pI2cInfo->bIsDDCPort = 1.
+//!
+//! A data buffer size larger than 16 bytes may be rejected if a register address is specified. In such a case,
+//! NVAPI_ARGUMENT_EXCEED_MAX_SIZE would be returned.
+//!
+//! If a register address is specified (i.e. regAddrSize is positive), then the transaction will be performed in
+//! the combined format described in the I2C specification. The register address will be written, followed by
+//! reading into the data buffer.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 85
+//!
+//! \param [in] hPhysicalGPU GPU selection.
+//! \param [out] NV_I2C_INFO *pI2cInfo The I2C data input structure
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred.
+//! \retval NVAPI_HANDLE_INVALIDATED Handle passed has been invalidated (see user guide).
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE Handle passed is not a physical GPU handle.
+//! \retval NVAPI_INCOMPATIBLE_STRUCT_VERSION Structure version is not supported.
+//! \retval NVAPI_INVALID_ARGUMENT - argument does not meet specified requirements
+//! \retval NVAPI_ARGUMENT_EXCEED_MAX_SIZE - an argument exceeds the maximum
+//!
+//! \ingroup i2capi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_I2CRead(NvPhysicalGpuHandle hPhysicalGpu, NV_I2C_INFO *pI2cInfo);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_I2CWrite
+//
+//! This function writes the data buffer to the I2C port.
+//!
+//! The I2C request must be for a DDC port: pI2cInfo->bIsDDCPort = 1.
+//!
+//! A data buffer size larger than 16 bytes may be rejected if a register address is specified. In such a case,
+//! NVAPI_ARGUMENT_EXCEED_MAX_SIZE would be returned.
+//!
+//! If a register address is specified (i.e. regAddrSize is positive), then the register address will be written
+//! and the data buffer will immediately follow without a restart.
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \since Release: 85
+//!
+//! \param [in] hPhysicalGPU GPU selection.
+//! \param [in] pI2cInfo The I2C data input structure
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred.
+//! \retval NVAPI_HANDLE_INVALIDATED Handle passed has been invalidated (see user guide).
+//! \retval NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE Handle passed is not a physical GPU handle.
+//! \retval NVAPI_INCOMPATIBLE_STRUCT_VERSION Structure version is not supported.
+//! \retval NVAPI_INVALID_ARGUMENT Argument does not meet specified requirements
+//! \retval NVAPI_ARGUMENT_EXCEED_MAX_SIZE Argument exceeds the maximum
+//!
+//! \ingroup i2capi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_I2CWrite(NvPhysicalGpuHandle hPhysicalGpu, NV_I2C_INFO *pI2cInfo);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_WorkstationFeatureSetup
+//
+//! \fn NvAPI_GPU_WorkstationFeatureSetup(NvPhysicalGpuHandle hPhysicalGpu, NvU32 featureEnableMask, NvU32 featureDisableMask)
+//! DESCRIPTION: This API configures the driver for a set of workstation features.
+//! The driver can allocate the memory resources accordingly.
+//!
+//! SUPPORTED OS: Windows 7
+//!
+//!
+//! \param [in] hPhysicalGpu Physical GPU Handle of the display adapter to be configured. GPU handles may be retrieved
+//! using NvAPI_EnumPhysicalGPUs. A value of NULL is permitted and applies the same operation
+//! to all GPU handles enumerated by NvAPI_EnumPhysicalGPUs.
+//! \param [in] featureEnableMask Mask of features the caller requests to enable for use
+//! \param [in] featureDisableMask Mask of features the caller requests to disable
+//!
+//! As a general rule, features in the enable and disable masks are expected to be disjoint, although the disable
+//! mask has precedence and a feature flagged in both masks will be disabled.
+//!
+//! \retval ::NVAPI_OK configuration request succeeded
+//! \retval ::NVAPI_ERROR configuration request failed
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu is not a physical GPU handle.
+//! \retval ::NVAPI_GPU_WORKSTATION_FEATURE_INCOMPLETE requested feature set does not have all resources allocated for completeness.
+//! \retval ::NVAPI_NO_IMPLEMENTATION only implemented for Win7
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+typedef enum _NVAPI_GPU_WORKSTATION_FEATURE_MASK
+{
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_SWAPGROUP = 0x00000001,
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_STEREO = 0x00000010,
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_WARPING = 0x00000100,
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_PIXINTENSITY = 0x00000200,
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_GRAYSCALE = 0x00000400,
+ NVAPI_GPU_WORKSTATION_FEATURE_MASK_BPC10 = 0x00001000
+} NVAPI_GPU_WORKSTATION_FEATURE_MASK;
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_WorkstationFeatureSetup(_In_ NvPhysicalGpuHandle hPhysicalGpu, _In_ NvU32 featureEnableMask, _In_ NvU32 featureDisableMask);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_WorkstationFeatureQuery
+//
+//! DESCRIPTION: This API queries the current set of workstation features.
+//!
+//! SUPPORTED OS: Windows 7
+//!
+//!
+//! \param [in] hPhysicalGpu Physical GPU Handle of the display adapter to be configured. GPU handles may be retrieved
+//! using NvAPI_EnumPhysicalGPUs.
+//! \param [out] pConfiguredFeatureMask Mask of features requested for use by client drivers
+//! \param [out] pConsistentFeatureMask Mask of features that have all resources allocated for completeness.
+//!
+//! \retval ::NVAPI_OK configuration request succeeded
+//! \retval ::NVAPI_ERROR configuration request failed
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE hPhysicalGpu is not a physical GPU handle.
+//! \retval ::NVAPI_NO_IMPLEMENTATION only implemented for Win7
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_WorkstationFeatureQuery(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Out_opt_ NvU32 *pConfiguredFeatureMask, _Out_opt_ NvU32 *pConsistentFeatureMask);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetHDCPSupportStatus
+//
+//! \fn NvAPI_GPU_GetHDCPSupportStatus(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_GET_HDCP_SUPPORT_STATUS *pGetHDCPSupportStatus)
+//! DESCRIPTION: This function returns a GPU's HDCP support status.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 175
+//!
+//! \retval ::NVAPI_OK
+//! \retval ::NVAPI_ERROR
+//! \retval ::NVAPI_INVALID_ARGUMENT
+//! \retval ::NVAPI_HANDLE_INVALIDATED
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+//! \addtogroup gpu
+//! @{
+
+
+//! HDCP fuse states - used in NV_GPU_GET_HDCP_SUPPORT_STATUS
+typedef enum _NV_GPU_HDCP_FUSE_STATE
+{
+ NV_GPU_HDCP_FUSE_STATE_UNKNOWN = 0,
+ NV_GPU_HDCP_FUSE_STATE_DISABLED = 1,
+ NV_GPU_HDCP_FUSE_STATE_ENABLED = 2,
+} NV_GPU_HDCP_FUSE_STATE;
+
+
+//! HDCP key sources - used in NV_GPU_GET_HDCP_SUPPORT_STATUS
+typedef enum _NV_GPU_HDCP_KEY_SOURCE
+{
+ NV_GPU_HDCP_KEY_SOURCE_UNKNOWN = 0,
+ NV_GPU_HDCP_KEY_SOURCE_NONE = 1,
+ NV_GPU_HDCP_KEY_SOURCE_CRYPTO_ROM = 2,
+ NV_GPU_HDCP_KEY_SOURCE_SBIOS = 3,
+ NV_GPU_HDCP_KEY_SOURCE_I2C_ROM = 4,
+ NV_GPU_HDCP_KEY_SOURCE_FUSES = 5,
+} NV_GPU_HDCP_KEY_SOURCE;
+
+
+//! HDCP key source states - used in NV_GPU_GET_HDCP_SUPPORT_STATUS
+typedef enum _NV_GPU_HDCP_KEY_SOURCE_STATE
+{
+ NV_GPU_HDCP_KEY_SOURCE_STATE_UNKNOWN = 0,
+ NV_GPU_HDCP_KEY_SOURCE_STATE_ABSENT = 1,
+ NV_GPU_HDCP_KEY_SOURCE_STATE_PRESENT = 2,
+} NV_GPU_HDCP_KEY_SOURCE_STATE;
+
+
+//! HDPC support status - used in NvAPI_GPU_GetHDCPSupportStatus()
+typedef struct
+{
+ NvU32 version; //! Structure version constucted by macro #NV_GPU_GET_HDCP_SUPPORT_STATUS
+ NV_GPU_HDCP_FUSE_STATE hdcpFuseState; //! GPU's HDCP fuse state
+ NV_GPU_HDCP_KEY_SOURCE hdcpKeySource; //! GPU's HDCP key source
+ NV_GPU_HDCP_KEY_SOURCE_STATE hdcpKeySourceState; //! GPU's HDCP key source state
+} NV_GPU_GET_HDCP_SUPPORT_STATUS;
+
+
+//! Macro for constructing the version for structure NV_GPU_GET_HDCP_SUPPORT_STATUS
+#define NV_GPU_GET_HDCP_SUPPORT_STATUS_VER MAKE_NVAPI_VERSION(NV_GPU_GET_HDCP_SUPPORT_STATUS,1)
+
+
+//! @}
+
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_GetHDCPSupportStatus(NvPhysicalGpuHandle hPhysicalGpu, NV_GPU_GET_HDCP_SUPPORT_STATUS *pGetHDCPSupportStatus);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetTachReading
+//
+//! DESCRIPTION: This API retrieves the fan speed tachometer reading for the specified physical GPU.
+//!
+//! HOW TO USE:
+//! - NvU32 Value = 0;
+//! - ret = NvAPI_GPU_GetTachReading(hPhysicalGpu, &Value);
+//! - On call success:
+//! - Value contains the tachometer reading
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu GPU selection.
+//! \param [out] pValue Pointer to a variable to get the tachometer reading
+//!
+//! \retval ::NVAPI_OK - completed request
+//! \retval ::NVAPI_ERROR - miscellaneous error occurred
+//! \retval ::NVAPI_NOT_SUPPORTED - functionality not supported
+//! \retval ::NVAPI_API_NOT_INTIALIZED - nvapi not initialized
+//! \retval ::NVAPI_INVALID_ARGUMENT - invalid argument passed
+//! \retval ::NVAPI_HANDLE_INVALIDATED - handle passed has been invalidated (see user guide)
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE - handle passed is not a physical GPU handle
+//!
+//! \ingroup gpucooler
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetTachReading(NvPhysicalGpuHandle hPhysicalGPU, NvU32 *pValue);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetTachReading)(NvPhysicalGpuHandle hPhysicalGPU, NvU32 *pValue);
+_NvAPI_GPU_GetTachReading NvAPI_GPU_GetTachReading;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetECCStatusInfo
+//
+//! \fn NvAPI_GPU_GetECCStatusInfo(NvPhysicalGpuHandle hPhysicalGpu,
+//! NV_GPU_ECC_STATUS_INFO *pECCStatusInfo);
+//! DESCRIPTION: This function returns ECC memory status information.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu A handle identifying the physical GPU for which ECC
+//! status information is to be retrieved.
+//! \param [out] pECCStatusInfo A pointer to an ECC status structure.
+//!
+//! \retval ::NVAPI_OK The request was completed successfully.
+//! \retval ::NVAPI_ERROR An unknown error occurred.
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE The provided GPU handle is not a physical GPU handle.
+//! \retval ::NVAPI_INVALID_HANDLE The provided GPU handle is invalid.
+//! \retval ::NVAPI_HANDLE_INVALIDATED The provided GPU handle is no longer valid.
+//! \retval ::NVAPI_INVALID_POINTER An invalid argument pointer was provided.
+//! \retval ::NVAPI_NOT_SUPPORTED The request is not supported.
+//! \retval ::NVAPI_API_NOT_INTIALIZED NvAPI was not yet initialized.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \addtogroup gpuecc
+//! Used in NV_GPU_ECC_STATUS_INFO.
+typedef enum _NV_ECC_CONFIGURATION
+{
+ NV_ECC_CONFIGURATION_NOT_SUPPORTED = 0,
+ NV_ECC_CONFIGURATION_DEFERRED, //!< Changes require a POST to take effect
+ NV_ECC_CONFIGURATION_IMMEDIATE, //!< Changes can optionally be made to take effect immediately
+} NV_ECC_CONFIGURATION;
+
+//! \ingroup gpuecc
+//! Used in NvAPI_GPU_GetECCStatusInfo().
+typedef struct _NV_GPU_ECC_STATUS_INFO
+{
+ NvU32 version; //!< Structure version
+ NvU32 isSupported : 1; //!< ECC memory feature support
+ NV_ECC_CONFIGURATION configurationOptions; //!< Supported ECC memory feature configuration options
+ NvU32 isEnabled : 1; //!< Active ECC memory setting
+} NV_GPU_ECC_STATUS_INFO;
+
+//! \ingroup gpuecc
+//! Macro for constructing the version field of NV_GPU_ECC_STATUS_INFO
+#define NV_GPU_ECC_STATUS_INFO_VER MAKE_NVAPI_VERSION(NV_GPU_ECC_STATUS_INFO, 1)
+
+//! \ingroup gpuecc
+NVAPI_INTERFACE NvAPI_GPU_GetECCStatusInfo(NvPhysicalGpuHandle hPhysicalGpu,
+ NV_GPU_ECC_STATUS_INFO *pECCStatusInfo);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetECCErrorInfo
+//
+//! \fn NvAPI_GPU_GetECCErrorInfo(NvPhysicalGpuHandle hPhysicalGpu,
+//! NV_GPU_ECC_ERROR_INFO *pECCErrorInfo);
+//!
+//! DESCRIPTION: This function returns ECC memory error information.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu A handle identifying the physical GPU for
+//! which ECC error information is to be
+//! retrieved.
+//! \param [out] pECCErrorInfo A pointer to an ECC error structure.
+//!
+//! \retval ::NVAPI_OK The request was completed successfully.
+//! \retval ::NVAPI_ERROR An unknown error occurred.
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE The provided GPU handle is not a physical GPU handle.
+//! \retval ::NVAPI_INVALID_ARGUMENT incorrect param value
+//! \retval ::NVAPI_INVALID_POINTER An invalid argument pointer was provided.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION structure version is not supported, initialize to NV_GPU_ECC_ERROR_INFO_VER.
+//! \retval ::NVAPI_HANDLE_INVALIDATED The provided GPU handle is no longer valid.
+//! \retval ::NVAPI_NOT_SUPPORTED The request is not supported.
+//! \retval ::NVAPI_API_NOT_INTIALIZED NvAPI was not yet initialized.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+//! \ingroup gpuecc
+//! Used in NvAPI_GPU_GetECCErrorInfo()/
+typedef struct _NV_GPU_ECC_ERROR_INFO
+{
+ NvU32 version; //!< Structure version
+ struct {
+ NvU64 singleBitErrors; //!< Number of single-bit ECC errors detected since last boot
+ NvU64 doubleBitErrors; //!< Number of double-bit ECC errors detected since last boot
+ } current;
+ struct {
+ NvU64 singleBitErrors; //!< Number of single-bit ECC errors detected since last counter reset
+ NvU64 doubleBitErrors; //!< Number of double-bit ECC errors detected since last counter reset
+ } aggregate;
+} NV_GPU_ECC_ERROR_INFO;
+
+//! \ingroup gpuecc
+//! Macro for constructing the version field of NV_GPU_ECC_ERROR_INFO
+#define NV_GPU_ECC_ERROR_INFO_VER MAKE_NVAPI_VERSION(NV_GPU_ECC_ERROR_INFO, 1)
+
+//! \ingroup gpuecc
+NVAPI_INTERFACE NvAPI_GPU_GetECCErrorInfo(NvPhysicalGpuHandle hPhysicalGpu,
+ NV_GPU_ECC_ERROR_INFO *pECCErrorInfo);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_ResetECCErrorInfo
+//
+//! DESCRIPTION: This function resets ECC memory error counters.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu A handle identifying the physical GPU for
+//! which ECC error information is to be
+//! cleared.
+//! \param [in] bResetCurrent Reset the current ECC error counters.
+//! \param [in] bResetAggregate Reset the aggregate ECC error counters.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval ::NVAPI_INVALID_USER_PRIVILEGE - The caller does not have administrative privileges
+//!
+//! \ingroup gpuecc
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_ResetECCErrorInfo(NvPhysicalGpuHandle hPhysicalGpu, NvU8 bResetCurrent,
+ NvU8 bResetAggregate);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetECCConfigurationInfo
+//
+//! \fn NvAPI_GPU_GetECCConfigurationInfo(NvPhysicalGpuHandle hPhysicalGpu,
+//! NV_GPU_ECC_CONFIGURATION_INFO *pECCConfigurationInfo);
+//! DESCRIPTION: This function returns ECC memory configuration information.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu A handle identifying the physical GPU for
+//! which ECC configuration information
+//! is to be retrieved.
+//! \param [out] pECCConfigurationInfo A pointer to an ECC
+//! configuration structure.
+//!
+//! \retval ::NVAPI_OK The request was completed successfully.
+//! \retval ::NVAPI_ERROR An unknown error occurred.
+//! \retval ::NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE The provided GPU handle is not a physical GPU handle.
+//! \retval ::NVAPI_INVALID_HANDLE The provided GPU handle is invalid.
+//! \retval ::NVAPI_HANDLE_INVALIDATED The provided GPU handle is no longer valid.
+//! \retval ::NVAPI_INVALID_POINTER An invalid argument pointer was provided.
+//! \retval ::NVAPI_NOT_SUPPORTED The request is not supported.
+//! \retval ::NVAPI_API_NOT_INTIALIZED NvAPI was not yet initialized.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpuecc
+//! Used in NvAPI_GPU_GetECCConfigurationInfo().
+typedef struct _NV_GPU_ECC_CONFIGURATION_INFO
+{
+ NvU32 version; //! Structure version
+ NvU32 isEnabled : 1; //! Current ECC configuration stored in non-volatile memory
+ NvU32 isEnabledByDefault : 1; //! Factory default ECC configuration (static)
+} NV_GPU_ECC_CONFIGURATION_INFO;
+
+//! \ingroup gpuecc
+//! Macro for consstructing the verion field of NV_GPU_ECC_CONFIGURATION_INFO
+#define NV_GPU_ECC_CONFIGURATION_INFO_VER MAKE_NVAPI_VERSION(NV_GPU_ECC_CONFIGURATION_INFO,1)
+
+//! \ingroup gpuecc
+NVAPI_INTERFACE NvAPI_GPU_GetECCConfigurationInfo(NvPhysicalGpuHandle hPhysicalGpu,
+ NV_GPU_ECC_CONFIGURATION_INFO *pECCConfigurationInfo);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_SetECCConfiguration
+//
+//! DESCRIPTION: This function updates the ECC memory configuration setting.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \param [in] hPhysicalGpu A handle identifying the physical GPU for
+//! which to update the ECC configuration
+//! setting.
+//! \param [in] bEnable The new ECC configuration setting.
+//! \param [in] bEnableImmediately Request that the new setting take effect immediately.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval ::NVAPI_INVALID_CONFIGURATION - Possibly SLI is enabled. Disable SLI and retry.
+//! \retval ::NVAPI_INVALID_USER_PRIVILEGE - The caller does not have administrative privileges
+//!
+//! \ingroup gpuecc
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_SetECCConfiguration(NvPhysicalGpuHandle hPhysicalGpu, NvU8 bEnable,
+ NvU8 bEnableImmediately);
+
+
+
+//! \ingroup gpu
+typedef struct
+{
+ NvU32 version; //!< version of this structure
+ NvU32 width; //!< width of the input texture
+ NvU32 height; //!< height of the input texture
+ float* blendingTexture; //!< array of floating values building an intensity RGB texture
+} NV_SCANOUT_INTENSITY_DATA_V1;
+
+//! \ingroup gpu
+typedef struct
+{
+ NvU32 version; //!< version of this structure
+ NvU32 width; //!< width of the input texture
+ NvU32 height; //!< height of the input texture
+ float* blendingTexture; //!< array of floating values building an intensity RGB texture
+ float* offsetTexture; //!< array of floating values building an offset texture
+ NvU32 offsetTexChannels; //!< number of channels per pixel in the offset texture
+} NV_SCANOUT_INTENSITY_DATA_V2;
+
+typedef NV_SCANOUT_INTENSITY_DATA_V2 NV_SCANOUT_INTENSITY_DATA;
+
+//! \ingroup gpu
+#define NV_SCANOUT_INTENSITY_DATA_VER1 MAKE_NVAPI_VERSION(NV_SCANOUT_INTENSITY_DATA_V1, 1)
+#define NV_SCANOUT_INTENSITY_DATA_VER2 MAKE_NVAPI_VERSION(NV_SCANOUT_INTENSITY_DATA_V2, 2)
+#define NV_SCANOUT_INTENSITY_DATA_VER NV_SCANOUT_INTENSITY_DATA_VER2
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_SetScanoutIntensity
+//
+//! DESCRIPTION: This API enables and sets up per-pixel intensity feature on the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \param [in] displayId combined physical display and GPU identifier of the display to apply the intensity control.
+//! \param [in] scanoutIntensityData the intensity texture info.
+//! \param [out] pbSticky(OUT) indicates whether the settings will be kept over a reboot.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input parameters.
+//! \retval ::NVAPI_API_NOT_INITIALIZED NvAPI not initialized.
+//! \retval ::NVAPI_NOT_SUPPORTED Interface not supported by the driver used, or only supported on selected GPUs
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input data.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION NV_SCANOUT_INTENSITY_DATA structure version mismatch.
+//! \retval ::NVAPI_OK Feature enabled.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_SetScanoutIntensity(NvU32 displayId, NV_SCANOUT_INTENSITY_DATA* scanoutIntensityData, int *pbSticky);
+
+
+//! \ingroup gpu
+typedef struct _NV_SCANOUT_INTENSITY_STATE_DATA
+{
+ NvU32 version; //!< version of this structure
+ NvU32 bEnabled; //!< intensity is enabled or not
+} NV_SCANOUT_INTENSITY_STATE_DATA;
+
+//! \ingroup gpu
+#define NV_SCANOUT_INTENSITY_STATE_VER MAKE_NVAPI_VERSION(NV_SCANOUT_INTENSITY_STATE_DATA, 1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_GetScanoutIntensityState
+//
+//! DESCRIPTION: This API queries current state of the intensity feature on the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \param [in] displayId combined physical display and GPU identifier of the display to query the configuration.
+//! \param [in,out] scanoutIntensityStateData intensity state data.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input parameters.
+//! \retval ::NVAPI_API_NOT_INITIALIZED NvAPI not initialized.
+//! \retval ::NVAPI_NOT_SUPPORTED Interface not supported by the driver used, or only supported on selected GPUs.
+//! \retval ::NVAPI_OK Feature enabled.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetScanoutIntensityState(_In_ NvU32 displayId, _Inout_ NV_SCANOUT_INTENSITY_STATE_DATA* scanoutIntensityStateData);
+
+
+//! \ingroup gpu
+typedef enum
+{
+ NV_GPU_WARPING_VERTICE_FORMAT_TRIANGLESTRIP_XYUVRQ = 0,
+ NV_GPU_WARPING_VERTICE_FORMAT_TRIANGLES_XYUVRQ = 1,
+} NV_GPU_WARPING_VERTICE_FORMAT;
+
+//! \ingroup gpu
+typedef struct
+{
+ NvU32 version; //!< version of this structure
+ float* vertices; //!< width of the input texture
+ NV_GPU_WARPING_VERTICE_FORMAT vertexFormat; //!< format of the input vertices
+ int numVertices; //!< number of the input vertices
+ NvSBox* textureRect; //!< rectangle in desktop coordinates describing the source area for the warping
+} NV_SCANOUT_WARPING_DATA;
+
+//! \ingroup gpu
+#define NV_SCANOUT_WARPING_VER MAKE_NVAPI_VERSION(NV_SCANOUT_WARPING_DATA, 1)
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_SetScanoutWarping
+//
+//! DESCRIPTION: This API enables and sets up the warping feature on the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \param [in] displayId Combined physical display and GPU identifier of the display to apply the intensity control
+//! \param [in] scanoutWarpingData The warping data info
+//! \param [out] pbSticky Indicates whether the settings will be kept over a reboot.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input parameters.
+//! \retval ::NVAPI_API_NOT_INITIALIZED NvAPI not initialized.
+//! \retval ::NVAPI_NOT_SUPPORTED Interface not supported by the driver used, or only supported on selected GPUs
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input data.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION NV_SCANOUT_INTENSITY_DATA structure version mismatch.
+//! \retval ::NVAPI_OK Feature enabled.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+
+NVAPI_INTERFACE NvAPI_GPU_SetScanoutWarping(NvU32 displayId, NV_SCANOUT_WARPING_DATA* scanoutWarpingData, int* piMaxNumVertices, int* pbSticky);
+
+
+//! \ingroup gpu
+typedef struct _NV_SCANOUT_WARPING_STATE_DATA
+{
+ NvU32 version; //!< version of this structure
+ NvU32 bEnabled; //!< warping is enabled or not
+} NV_SCANOUT_WARPING_STATE_DATA;
+
+//! \ingroup gpu
+#define NV_SCANOUT_WARPING_STATE_VER MAKE_NVAPI_VERSION(NV_SCANOUT_WARPING_STATE_DATA, 1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_GetScanoutWarpingState
+//
+//! DESCRIPTION: This API queries current state of the warping feature on the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \param [in] displayId combined physical display and GPU identifier of the display to query the configuration.
+//! \param [in,out] scanoutWarpingStateData warping state data.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input parameters.
+//! \retval ::NVAPI_API_NOT_INITIALIZED NvAPI not initialized.
+//! \retval ::NVAPI_NOT_SUPPORTED Interface not supported by the driver used, or only supported on selected GPUs.
+//! \retval ::NVAPI_OK Feature enabled.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetScanoutWarpingState(_In_ NvU32 displayId, _Inout_ NV_SCANOUT_WARPING_STATE_DATA* scanoutWarpingStateData);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_GetScanoutConfiguration
+//
+//! DESCRIPTION: This API queries the desktop and scanout portion of the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \param [in] displayId combined physical display and GPU identifier of the display to query the configuration.
+//! \param [in,out] desktopRect desktop area of the display in desktop coordinates.
+//! \param [in,out] scanoutRect scanout area of the display relative to desktopRect.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Invalid input parameters.
+//! \retval ::NVAPI_API_NOT_INITIALIZED NvAPI not initialized.
+//! \retval ::NVAPI_NOT_SUPPORTED Interface not supported by the driver used, or only supported on selected GPUs.
+//! \retval ::NVAPI_OK Feature enabled.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetScanoutConfiguration(NvU32 displayId, NvSBox* desktopRect, NvSBox* scanoutRect);
+
+
+
+//! \ingroup gpu
+//! Used in NvAPI_GPU_GetScanoutConfigurationEx().
+typedef struct _NV_SCANOUT_INFORMATION
+{
+ NvU32 version; //!< Structure version, needs to be initialized with NV_SCANOUT_INFORMATION_VER.
+
+ NvSBox sourceDesktopRect; //!< Operating system display device rect in desktop coordinates displayId is scanning out from.
+ NvSBox sourceViewportRect; //!< Area inside the sourceDesktopRect which is scanned out to the display.
+ NvSBox targetViewportRect; //!< Area inside the rect described by targetDisplayWidth/Height sourceViewportRect is scanned out to.
+ NvU32 targetDisplayWidth; //!< Horizontal size of the active resolution scanned out to the display.
+ NvU32 targetDisplayHeight; //!< Vertical size of the active resolution scanned out to the display.
+ NvU32 cloneImportance; //!< If targets are cloned views of the sourceDesktopRect the cloned targets have an imporantce assigned (0:primary,1 secondary,...).
+ NV_ROTATE sourceToTargetRotation; //!< Rotation performed between the sourceViewportRect and the targetViewportRect.
+} NV_SCANOUT_INFORMATION;
+
+#define NV_SCANOUT_INFORMATION_VER MAKE_NVAPI_VERSION(NV_SCANOUT_INFORMATION,1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GPU_GetScanoutConfigurationEx
+//
+//! DESCRIPTION: This API queries the desktop and scanout portion of the specified display.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//! \since Release: 331
+//!
+//! \param [in] displayId combined physical display and GPU identifier of the display to query the configuration.
+//! \param [in,out] pScanoutInformation desktop area to displayId mapping information.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GPU_GetScanoutConfigurationEx(_In_ NvU32 displayId, _Inout_ NV_SCANOUT_INFORMATION *pScanoutInformation);
+
+
+//! Used in NvAPI_GPU_GetPerfDecreaseInfo.
+//! Bit masks for knowing the exact reason for performance decrease
+typedef enum _NVAPI_GPU_PERF_DECREASE
+{
+ NV_GPU_PERF_DECREASE_NONE = 0, //!< No Slowdown detected
+ NV_GPU_PERF_DECREASE_REASON_THERMAL_PROTECTION = 0x00000001, //!< Thermal slowdown/shutdown/POR thermal protection
+ NV_GPU_PERF_DECREASE_REASON_POWER_CONTROL = 0x00000002, //!< Power capping / pstate cap
+ NV_GPU_PERF_DECREASE_REASON_AC_BATT = 0x00000004, //!< AC->BATT event
+ NV_GPU_PERF_DECREASE_REASON_API_TRIGGERED = 0x00000008, //!< API triggered slowdown
+ NV_GPU_PERF_DECREASE_REASON_INSUFFICIENT_POWER = 0x00000010, //!< Power connector missing
+ NV_GPU_PERF_DECREASE_REASON_UNKNOWN = 0x80000000, //!< Unknown reason
+} NVAPI_GPU_PERF_DECREASE;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetPerfDecreaseInfo
+//
+//! DESCRIPTION: This function retrieves - in NvU32 variable - reasons for the current performance decrease.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//! \param [in] hPhysicalGPU (IN) - GPU for which performance decrease is to be evaluated.
+//! \param [out] pPerfDecrInfo (OUT) - Pointer to a NvU32 variable containing performance decrease info
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//!
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_GPU_GetPerfDecreaseInfo(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NvU32 *pPerfDecrInfo);
+
+typedef __success(return == NVAPI_OK) NvAPI_Status (__cdecl *_NvAPI_GPU_GetPerfDecreaseInfo)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NVAPI_GPU_PERF_DECREASE* pPerfDecrInfo);
+_NvAPI_GPU_GetPerfDecreaseInfo NvAPI_GPU_GetPerfDecreaseInfo;
+
+
+//! \ingroup gpu
+typedef enum _NV_GPU_ILLUMINATION_ATTRIB
+{
+ NV_GPU_IA_LOGO_BRIGHTNESS = 0,
+ NV_GPU_IA_SLI_BRIGHTNESS = 1,
+} NV_GPU_ILLUMINATION_ATTRIB;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_QueryIlluminationSupport
+//
+//! \fn NvAPI_GPU_QueryIlluminationSupport(_Inout_ NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM *pIlluminationSupportInfo)
+//! DESCRIPTION: This function reports if the specified illumination attribute is supported.
+//!
+//! \note Only a single GPU can manage an given attribute on a given HW element,
+//! regardless of how many are attatched. I.E. only one GPU will be used to control
+//! the brightness of the LED on an SLI bridge, regardless of how many are physicaly attached.
+//! You should enumerate thru the GPUs with this call to determine which GPU is managing the attribute.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//! \since Version: 300.05
+//!
+//! \param [in] hPhysicalGpu Physical GPU handle
+//! \param Attribute An enumeration value specifying the Illumination attribute to be querried
+//! \param [out] pSupported A boolean indicating if the attribute is supported.
+//!
+//! \return See \ref nvapistatus for the list of possible return values.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+typedef struct _NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1 {
+
+ // IN
+ NvU32 version; //!< Version of this structure
+ NvPhysicalGpuHandle hPhysicalGpu; //!< The handle of the GPU that you are checking for the specified attribute.
+ //!< note that this is the GPU that is managing the attribute.
+ //!< Only a single GPU can manage an given attribute on a given HW element,
+ //!< regardless of how many are attatched.
+ //!< I.E. only one GPU will be used to control the brightness of the LED on an SLI bridge,
+ //!< regardless of how many are physicaly attached.
+ //!< You enumerate thru the GPUs with this call to determine which GPU is managing the attribute.
+ NV_GPU_ILLUMINATION_ATTRIB Attribute; //!< An enumeration value specifying the Illumination attribute to be querried.
+ //!< refer to enum \ref NV_GPU_ILLUMINATION_ATTRIB.
+
+ // OUT
+ NvU32 bSupported; //!< A boolean indicating if the attribute is supported.
+
+} NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1;
+
+//! \ingroup gpu
+typedef NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1 NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM;
+//! \ingroup gpu
+#define NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER_1 MAKE_NVAPI_VERSION(NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_V1,1)
+//! \ingroup gpu
+#define NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM_VER_1
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_QueryIlluminationSupport(_Inout_ NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM *pIlluminationSupportInfo);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetIllumination
+//
+//! \fn NvAPI_GPU_GetIllumination(NV_GPU_GET_ILLUMINATION_PARM *pIlluminationInfo)
+//! DESCRIPTION: This function reports value of the specified illumination attribute.
+//!
+//! \note Only a single GPU can manage an given attribute on a given HW element,
+//! regardless of how many are attatched. I.E. only one GPU will be used to control
+//! the brightness of the LED on an SLI bridge, regardless of how many are physicaly attached.
+//! You should enumerate thru the GPUs with the \ref NvAPI_GPU_QueryIlluminationSupport call to
+//! determine which GPU is managing the attribute.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//! \since Version: 300.05
+//!
+//! \param [in] hPhysicalGpu Physical GPU handle
+//! \param Attribute An enumeration value specifying the Illumination attribute to be querried
+//! \param [out] Value A ULONG containing the current value for the specified attribute.
+//! This is specified as a percentage of the full range of the attribute
+//! (0-100; 0 = off, 100 = full brightness)
+//!
+//! \return See \ref nvapistatus for the list of possible return values. Return values of special interest are:
+//! NVAPI_INVALID_ARGUMENT The specified attibute is not known to the driver.
+//! NVAPI_NOT_SUPPORTED: The specified attribute is not supported on the specified GPU
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+typedef struct _NV_GPU_GET_ILLUMINATION_PARM_V1 {
+
+ // IN
+ NvU32 version; //!< Version of this structure
+ NvPhysicalGpuHandle hPhysicalGpu; //!< The handle of the GPU that you are checking for the specified attribute.
+ //!< Note that this is the GPU that is managing the attribute.
+ //!< Only a single GPU can manage an given attribute on a given HW element,
+ //!< regardless of how many are attatched.
+ //!< I.E. only one GPU will be used to control the brightness of the LED on an SLI bridge,
+ //!< regardless of how many are physicaly attached.
+ //!< You enumerate thru the GPUs with this call to determine which GPU is managing the attribute.
+ NV_GPU_ILLUMINATION_ATTRIB Attribute; //!< An enumeration value specifying the Illumination attribute to be querried.
+ //!< refer to enum \ref NV_GPU_ILLUMINATION_ATTRIB.
+
+ // OUT
+ NvU32 Value; //!< A ULONG that will contain the current value of the specified attribute.
+ //! This is specified as a percentage of the full range of the attribute
+ //! (0-100; 0 = off, 100 = full brightness)
+
+} NV_GPU_GET_ILLUMINATION_PARM_V1;
+
+//! \ingroup gpu
+typedef NV_GPU_GET_ILLUMINATION_PARM_V1 NV_GPU_GET_ILLUMINATION_PARM;
+//! \ingroup gpu
+#define NV_GPU_GET_ILLUMINATION_PARM_VER_1 MAKE_NVAPI_VERSION(NV_GPU_GET_ILLUMINATION_PARM_V1,1)
+//! \ingroup gpu
+#define NV_GPU_GET_ILLUMINATION_PARM_VER NV_GPU_GET_ILLUMINATION_PARM_VER_1
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_GetIllumination(NV_GPU_GET_ILLUMINATION_PARM *pIlluminationInfo);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_SetIllumination
+//
+//! \fn NvAPI_GPU_SetIllumination(NV_GPU_SET_ILLUMINATION_PARM *pIlluminationInfo)
+//! DESCRIPTION: This function sets the value of the specified illumination attribute.
+//!
+//! \note Only a single GPU can manage an given attribute on a given HW element,
+//! regardless of how many are attatched. I.E. only one GPU will be used to control
+//! the brightness of the LED on an SLI bridge, regardless of how many are physicaly attached.
+//! You should enumerate thru the GPUs with the \ref NvAPI_GPU_QueryIlluminationSupport call to
+//! determine which GPU is managing the attribute.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//! \since Version: 300.05
+//!
+//! \param [in] hPhysicalGpu Physical GPU handle
+//! \param Attribute An enumeration value specifying the Illumination attribute to be set
+//! \param Value The new value for the specified attribute.
+//! This should be specified as a percentage of the full range of the attribute
+//! (0-100; 0 = off, 100 = full brightness)
+//! If a value is specified outside this range, NVAPI_INVALID_ARGUMENT will be returned.
+//!
+//! \return See \ref nvapistatus for the list of possible return values. Return values of special interest are:
+//! NVAPI_INVALID_ARGUMENT The specified attibute is not known to the driver, or the specified value is out of range.
+//! NVAPI_NOT_SUPPORTED The specified attribute is not supported on the specified GPU.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup gpu
+typedef struct _NV_GPU_SET_ILLUMINATION_PARM_V1 {
+
+ // IN
+ NvU32 version; //!< Version of this structure
+ NvPhysicalGpuHandle hPhysicalGpu; //!< The handle of the GPU that you are checking for the specified attribute.
+ //!< Note that this is the GPU that is managing the attribute.
+ //!< Only a single GPU can manage an given attribute on a given HW element,
+ //!< regardless of how many are attatched.
+ //!< I.E. only one GPU will be used to control the brightness of the LED on an SLI bridge,
+ //!< regardless of how many are physicaly attached.
+ //!< You enumerate thru the GPUs with this call to determine which GPU is managing the attribute.
+ NV_GPU_ILLUMINATION_ATTRIB Attribute; //!< An enumeration value specifying the Illumination attribute to be querried.
+ //!< refer to enum \ref NV_GPU_ILLUMINATION_ATTRIB.
+ NvU32 Value; //!< A ULONG containing the new value for the specified attribute.
+ //!< This should be specified as a percentage of the full range of the attribute
+ //!< (0-100; 0 = off, 100 = full brightness)
+ //!< If a value is specified outside this range, NVAPI_INVALID_ARGUMENT will be returned.
+
+ // OUT
+
+} NV_GPU_SET_ILLUMINATION_PARM_V1;
+
+//! \ingroup gpu
+typedef NV_GPU_SET_ILLUMINATION_PARM_V1 NV_GPU_SET_ILLUMINATION_PARM;
+//! \ingroup gpu
+#define NV_GPU_SET_ILLUMINATION_PARM_VER_1 MAKE_NVAPI_VERSION(NV_GPU_SET_ILLUMINATION_PARM_V1,1)
+//! \ingroup gpu
+#define NV_GPU_SET_ILLUMINATION_PARM_VER NV_GPU_SET_ILLUMINATION_PARM_VER_1
+
+//! \ingroup gpu
+NVAPI_INTERFACE NvAPI_GPU_SetIllumination(NV_GPU_SET_ILLUMINATION_PARM *pIlluminationInfo);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnumNvidiaDisplayHandle
+//
+//! This function returns the handle of the NVIDIA display specified by the enum
+//! index (thisEnum). The client should keep enumerating until it
+//! returns NVAPI_END_ENUMERATION.
+//!
+//! Note: Display handles can get invalidated on a modeset, so the calling applications need to
+//! renum the handles after every modeset.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \param [in] thisEnum The index of the NVIDIA display.
+//! \param [out] pNvDispHandle Pointer to the NVIDIA display handle.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT Either the handle pointer is NULL or enum index too big
+//! \retval NVAPI_OK Return a valid NvDisplayHandle based on the enum index
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device found in the system
+//! \retval NVAPI_END_ENUMERATION No more display device to enumerate
+//! \ingroup disphandle
+///////////////////////////////////////////////////////////////////////////////
+//NVAPI_INTERFACE NvAPI_EnumNvidiaDisplayHandle(NvU32 thisEnum, NvDisplayHandle *pNvDispHandle);
+
+typedef NvAPI_Status (__cdecl *_NvAPI_EnumNvidiaDisplayHandle)(NvU32 thisEnum, NvDisplayHandle *pNvDispHandle);
+_NvAPI_EnumNvidiaDisplayHandle NvAPI_EnumNvidiaDisplayHandle;
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnumNvidiaUnAttachedDisplayHandle
+//
+//! This function returns the handle of the NVIDIA unattached display specified by the enum
+//! index (thisEnum). The client should keep enumerating until it
+//! returns error.
+//! Note: Display handles can get invalidated on a modeset, so the calling applications need to
+//! renum the handles after every modeset.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \param [in] thisEnum The index of the NVIDIA display.
+//! \param [out] pNvUnAttachedDispHandle Pointer to the NVIDIA display handle of the unattached display.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT Either the handle pointer is NULL or enum index too big
+//! \retval NVAPI_OK Return a valid NvDisplayHandle based on the enum index
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device found in the system
+//! \retval NVAPI_END_ENUMERATION No more display device to enumerate.
+//! \ingroup disphandle
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_EnumNvidiaUnAttachedDisplayHandle(NvU32 thisEnum, NvUnAttachedDisplayHandle *pNvUnAttachedDispHandle);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_CreateDisplayFromUnAttachedDisplay
+//
+//! This function converts the unattached display handle to an active attached display handle.
+//!
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hNvUnAttachedDisp is not valid or pNvDisplay is NULL.
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_CreateDisplayFromUnAttachedDisplay(NvUnAttachedDisplayHandle hNvUnAttachedDisp, NvDisplayHandle *pNvDisplay);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetAssociatedNVidiaDisplayHandle
+//
+//! This function returns the handle of the NVIDIA display that is associated
+//! with the given display "name" (such as "\\.\DISPLAY1").
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT Either argument is NULL
+//! \retval NVAPI_OK *pNvDispHandle is now valid
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device maps to that display name
+//! \ingroup disphandle
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetAssociatedNvidiaDisplayHandle(const char *szDisplayName, NvDisplayHandle *pNvDispHandle);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_DISP_GetAssociatedUnAttachedNvidiaDisplayHandle
+//
+//! DESCRIPTION: This function returns the handle of an unattached NVIDIA display that is
+//! associated with the given display name (such as "\\DISPLAY1").
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT Either argument is NULL.
+//! \retval ::NVAPI_OK *pNvUnAttachedDispHandle is now valid.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device maps to that display name.
+//!
+//! \ingroup disphandle
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_GetAssociatedUnAttachedNvidiaDisplayHandle(const char *szDisplayName, NvUnAttachedDisplayHandle *pNvUnAttachedDispHandle);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetAssociatedNVidiaDisplayName
+//
+//! For a given NVIDIA display handle, this function returns a string (such as "\\.\DISPLAY1") to identify the display.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT Either argument is NULL
+//! \retval NVAPI_OK *pNvDispHandle is now valid
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device maps to that display name
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetAssociatedNvidiaDisplayName(NvDisplayHandle NvDispHandle, NvAPI_ShortString szDisplayName);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetUnAttachedAssociatedDisplayName
+//
+//! This function returns the display name given, for example, "\\DISPLAY1", using the unattached NVIDIA display handle
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 95
+//!
+//! \retval NVAPI_INVALID_ARGUMENT Either argument is NULL
+//! \retval NVAPI_OK *pNvDispHandle is now valid
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA device maps to that display name
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetUnAttachedAssociatedDisplayName(NvUnAttachedDisplayHandle hNvUnAttachedDisp, NvAPI_ShortString szDisplayName);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnableHWCursor
+//
+//! This function enables hardware cursor support
+//!
+//! SUPPORTED OS: Windows XP
+//!
+//!
+//!
+//! \since Release: 80
+//!
+//! \return NVAPI_ERROR or NVAPI_OK
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_EnableHWCursor(NvDisplayHandle hNvDisplay);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_DisableHWCursor
+//
+//! This function disables hardware cursor support
+//!
+//! SUPPORTED OS: Windows XP
+//!
+//!
+//! \since Release: 80
+//!
+//! \return NVAPI_ERROR or NVAPI_OK
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DisableHWCursor(NvDisplayHandle hNvDisplay);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetVBlankCounter
+//
+//! This function gets the V-blank counter
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 80
+//!
+//! \return NVAPI_ERROR or NVAPI_OK
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetVBlankCounter(NvDisplayHandle hNvDisplay, NvU32 *pCounter);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_SetRefreshRateOverride
+//
+//! This function overrides the refresh rate on the given display/outputsMask.
+//! The new refresh rate can be applied right away in this API call or deferred to be applied with the
+//! next OS modeset. The override is good for only one modeset (regardless whether it's deferred or immediate).
+//!
+//!
+//! SUPPORTED OS: Windows XP
+//!
+//!
+//! \since Release: 80
+//!
+//! \param [in] hNvDisplay The NVIDIA display handle. It can be NVAPI_DEFAULT_HANDLE or a handle
+//! enumerated from NvAPI_EnumNVidiaDisplayHandle().
+//! \param [in] outputsMask A set of bits that identify all target outputs which are associated with the NVIDIA
+//! display handle to apply the refresh rate override. When SLI is enabled, the
+//! outputsMask only applies to the GPU that is driving the display output.
+//! \param [in] refreshRate The override value. "0.0" means cancel the override.
+//! \param [in] bSetDeferred
+//! - "0": Apply the refresh rate override immediately in this API call.\p
+//! - "1": Apply refresh rate at the next OS modeset.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT hNvDisplay or outputsMask is invalid
+//! \retval NVAPI_OK The refresh rate override is correct set
+//! \retval NVAPI_ERROR The operation failed
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_SetRefreshRateOverride(NvDisplayHandle hNvDisplay, NvU32 outputsMask, float refreshRate, NvU32 bSetDeferred);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GetAssociatedDisplayOutputId
+//
+//! This function gets the active outputId associated with the display handle.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 90
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. It can be NVAPI_DEFAULT_HANDLE or a handle enumerated from NvAPI_EnumNVidiaDisplayHandle().
+//! \param [out] outputId The active display output ID associated with the selected display handle hNvDisplay.
+//! The outputid will have only one bit set. In the case of Clone or Span mode, this will indicate the
+//! display outputId of the primary display that the GPU is driving. See \ref handles.
+//!
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_EXPECTED_DISPLAY_HANDLE hNvDisplay is not a valid display handle.
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetAssociatedDisplayOutputId(NvDisplayHandle hNvDisplay, NvU32 *pOutputId);
+
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_GetDisplayPortInfo().
+typedef struct
+{
+ NvU32 version; //!< Structure version
+ NvU32 dpcd_ver; //!< DPCD version of the monitor
+ NV_DP_LINK_RATE maxLinkRate; //!< Maximum supported link rate
+ NV_DP_LANE_COUNT maxLaneCount; //!< Maximum supported lane count
+ NV_DP_LINK_RATE curLinkRate; //!< Current link rate
+ NV_DP_LANE_COUNT curLaneCount; //!< Current lane count
+ NV_DP_COLOR_FORMAT colorFormat; //!< Current color format
+ NV_DP_DYNAMIC_RANGE dynamicRange; //!< Dynamic range
+ NV_DP_COLORIMETRY colorimetry; //!< Ignored in RGB space
+ NV_DP_BPC bpc; //!< Current bit-per-component;
+ NvU32 isDp : 1; //!< If the monitor is driven by a DisplayPort
+ NvU32 isInternalDp : 1; //!< If the monitor is driven by an NV Dp transmitter
+ NvU32 isColorCtrlSupported : 1; //!< If the color format change is supported
+ NvU32 is6BPCSupported : 1; //!< If 6 bpc is supported
+ NvU32 is8BPCSupported : 1; //!< If 8 bpc is supported
+ NvU32 is10BPCSupported : 1; //!< If 10 bpc is supported
+ NvU32 is12BPCSupported : 1; //!< If 12 bpc is supported
+ NvU32 is16BPCSupported : 1; //!< If 16 bpc is supported
+ NvU32 isYCrCb422Supported : 1; //!< If YCrCb422 is supported
+ NvU32 isYCrCb444Supported : 1; //!< If YCrCb444 is supported
+
+ } NV_DISPLAY_PORT_INFO;
+
+//! Macro for constructing the version field of NV_DISPLAY_PORT_INFO.
+#define NV_DISPLAY_PORT_INFO_VER MAKE_NVAPI_VERSION(NV_DISPLAY_PORT_INFO,1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GetDisplayPortInfo
+//
+//! \fn NvAPI_GetDisplayPortInfo(_In_opt_ NvDisplayHandle hNvDisplay, _In_ NvU32 outputId, _Inout_ NV_DISPLAY_PORT_INFO *pInfo)
+//! DESCRIPTION: This function returns the current DisplayPort-related information on the specified device (monitor).
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 165
+//!
+//! \param [in] hvDisplay NVIDIA Display selection. It can be NVAPI_DEFAULT_HANDLE or a handle enumerated from NvAPI_EnumNVidiaDisplayHandle().
+//! This parameter is ignored when the outputId is a NvAPI displayId.
+//! \param [in] outputId This can either be the connection bit mask or the NvAPI displayId. When the legacy connection bit mask is passed,
+//! it should have exactly 1 bit set to indicate a single display. If it's "0" then the default outputId from
+//! NvAPI_GetAssociatedDisplayOutputId() will be used. See \ref handles.
+//! \param [out] pInfo The DisplayPort information
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//
+///////////////////////////////////////////////////////////////////////////////
+//! \ingroup dispcontrol
+NVAPI_INTERFACE NvAPI_GetDisplayPortInfo(_In_opt_ NvDisplayHandle hNvDisplay, _In_ NvU32 outputId, _Inout_ NV_DISPLAY_PORT_INFO *pInfo);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_SetDisplayPort
+//
+//! \fn NvAPI_SetDisplayPort(NvDisplayHandle hNvDisplay, NvU32 outputId, NV_DISPLAY_PORT_CONFIG *pCfg)
+//! DESCRIPTION: This function sets up DisplayPort-related configurations.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 165
+//!
+//! \param [in] hNvDisplay NVIDIA display handle. It can be NVAPI_DEFAULT_HANDLE or a handle enumerated from
+//! NvAPI_EnumNVidiaDisplayHandle().
+//! \param [in] outputId This display output ID, when it's "0" it means the default outputId generated from the return of
+//! NvAPI_GetAssociatedDisplayOutputId(). See \ref handles.
+//! \param [in] pCfg The display port config structure. If pCfg is NULL, it means to use the driver's default value to setup.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter
+///////////////////////////////////////////////////////////////////////////////
+
+
+//! \ingroup dispcontrol
+//! DisplayPort configuration settings - used in NvAPI_SetDisplayPort().
+typedef struct _NV_DISPLAY_PORT_CONFIG
+{
+ NvU32 version; //!< Structure version - 2 is the latest
+ NV_DP_LINK_RATE linkRate; //!< Link rate
+ NV_DP_LANE_COUNT laneCount; //!< Lane count
+ NV_DP_COLOR_FORMAT colorFormat; //!< Color format to set
+ NV_DP_DYNAMIC_RANGE dynamicRange; //!< Dynamic range
+ NV_DP_COLORIMETRY colorimetry; //!< Ignored in RGB space
+ NV_DP_BPC bpc; //!< Bit-per-component
+ NvU32 isHPD : 1; //!< If the control panel is making this call due to HPD
+ NvU32 isSetDeferred : 1; //!< Requires an OS modeset to finalize the setup if set
+ NvU32 isChromaLpfOff : 1; //!< Force the chroma low_pass_filter to be off
+ NvU32 isDitherOff : 1; //!< Force to turn off dither
+ NvU32 testLinkTrain : 1; //!< If testing mode, skip validation
+ NvU32 testColorChange : 1; //!< If testing mode, skip validation
+
+} NV_DISPLAY_PORT_CONFIG;
+
+//! \addtogroup dispcontrol
+//! @{
+//! Macro for constructing the version field of NV_DISPLAY_PORT_CONFIG
+#define NV_DISPLAY_PORT_CONFIG_VER MAKE_NVAPI_VERSION(NV_DISPLAY_PORT_CONFIG,2)
+//! Macro for constructing the version field of NV_DISPLAY_PORT_CONFIG
+#define NV_DISPLAY_PORT_CONFIG_VER_1 MAKE_NVAPI_VERSION(NV_DISPLAY_PORT_CONFIG,1)
+//! Macro for constructing the version field of NV_DISPLAY_PORT_CONFIG
+#define NV_DISPLAY_PORT_CONFIG_VER_2 MAKE_NVAPI_VERSION(NV_DISPLAY_PORT_CONFIG,2)
+//! @}
+
+
+//! \ingroup dispcontrol
+NVAPI_INTERFACE NvAPI_SetDisplayPort(NvDisplayHandle hNvDisplay, NvU32 outputId, NV_DISPLAY_PORT_CONFIG *pCfg);
+
+
+
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_GetHDMISupportInfo().
+typedef struct _NV_HDMI_SUPPORT_INFO_V1
+{
+ NvU32 version; //!< Structure version
+
+ NvU32 isGpuHDMICapable : 1; //!< If the GPU can handle HDMI
+ NvU32 isMonUnderscanCapable : 1; //!< If the monitor supports underscan
+ NvU32 isMonBasicAudioCapable : 1; //!< If the monitor supports basic audio
+ NvU32 isMonYCbCr444Capable : 1; //!< If YCbCr 4:4:4 is supported
+ NvU32 isMonYCbCr422Capable : 1; //!< If YCbCr 4:2:2 is supported
+ NvU32 isMonxvYCC601Capable : 1; //!< If xvYCC 601 is supported
+ NvU32 isMonxvYCC709Capable : 1; //!< If xvYCC 709 is supported
+ NvU32 isMonHDMI : 1; //!< If the monitor is HDMI (with IEEE's HDMI registry ID)
+ NvU32 reserved : 24; //!< Reserved.
+
+ NvU32 EDID861ExtRev; //!< Revision number of the EDID 861 extension
+ } NV_HDMI_SUPPORT_INFO_V1;
+
+typedef struct _NV_HDMI_SUPPORT_INFO_V2
+{
+ NvU32 version; //!< Structure version
+
+ NvU32 isGpuHDMICapable : 1; //!< If the GPU can handle HDMI
+ NvU32 isMonUnderscanCapable : 1; //!< If the monitor supports underscan
+ NvU32 isMonBasicAudioCapable : 1; //!< If the monitor supports basic audio
+ NvU32 isMonYCbCr444Capable : 1; //!< If YCbCr 4:4:4 is supported
+ NvU32 isMonYCbCr422Capable : 1; //!< If YCbCr 4:2:2 is supported
+ NvU32 isMonxvYCC601Capable : 1; //!< If xvYCC extended colorimetry 601 is supported
+ NvU32 isMonxvYCC709Capable : 1; //!< If xvYCC extended colorimetry 709 is supported
+ NvU32 isMonHDMI : 1; //!< If the monitor is HDMI (with IEEE's HDMI registry ID)
+ NvU32 isMonsYCC601Capable : 1; //!< if sYCC601 extended colorimetry is supported
+ NvU32 isMonAdobeYCC601Capable : 1; //!< if AdobeYCC601 extended colorimetry is supported
+ NvU32 isMonAdobeRGBCapable : 1; //!< if AdobeRGB extended colorimetry is supported
+ NvU32 reserved : 21; //!< Reserved.
+
+ NvU32 EDID861ExtRev; //!< Revision number of the EDID 861 extension
+ } NV_HDMI_SUPPORT_INFO_V2;
+
+#define NV_HDMI_SUPPORT_INFO_VER1 MAKE_NVAPI_VERSION(NV_HDMI_SUPPORT_INFO_V1, 1)
+#define NV_HDMI_SUPPORT_INFO_VER2 MAKE_NVAPI_VERSION(NV_HDMI_SUPPORT_INFO_V2, 2)
+
+
+
+#ifndef NV_HDMI_SUPPORT_INFO_VER
+
+typedef NV_HDMI_SUPPORT_INFO_V2 NV_HDMI_SUPPORT_INFO;
+#define NV_HDMI_SUPPORT_INFO_VER NV_HDMI_SUPPORT_INFO_VER2
+
+#endif
+
+
+//! SUPPORTED OS: Windows Vista and higher
+//!
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GetHDMISupportInfo
+//
+//! \fn NvAPI_GetHDMISupportInfo(_In_opt_ NvDisplayHandle hNvDisplay, _In_ NvU32 outputId, _Inout_ NV_HDMI_SUPPORT_INFO *pInfo)
+//! This API returns the current infoframe data on the specified device(monitor).
+//!
+//! \since Release: 95
+//!
+//! \param [in] hvDisplay NVIDIA Display selection. It can be NVAPI_DEFAULT_HANDLE or a handle enumerated from NvAPI_EnumNVidiaDisplayHandle().
+//! This parameter is ignored when the outputId is a NvAPI displayId.
+//! \param [in] outputId This can either be the connection bit mask or the NvAPI displayId. When the legacy connection bit mask is passed,
+//! it should have exactly 1 bit set to indicate a single display. If it's "0" then the default outputId from
+//! NvAPI_GetAssociatedDisplayOutputId() will be used. See \ref handles.
+//! \param [out] pInfo The monitor and GPU's HDMI support info
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+///////////////////////////////////////////////////////////////////////////////
+
+
+//! \ingroup dispcontrol
+NVAPI_INTERFACE NvAPI_GetHDMISupportInfo(_In_opt_ NvDisplayHandle hNvDisplay, _In_ NvU32 outputId, _Inout_ NV_HDMI_SUPPORT_INFO *pInfo);
+
+
+//! \ingroup dispcontrol
+
+typedef enum
+{
+ NV_INFOFRAME_CMD_GET_DEFAULT = 0, //!< Returns the fields in the infoframe with values set by the manufacturer - NVIDIA/OEM.
+ NV_INFOFRAME_CMD_RESET, //!< Sets the fields in the infoframe to auto, and infoframe to the default infoframe for use in a set.
+ NV_INFOFRAME_CMD_GET, //!< Get the current infoframe state.
+ NV_INFOFRAME_CMD_SET, //!< Set the current infoframe state (flushed to the monitor), the values are one time and do not persist.
+ NV_INFOFRAME_CMD_GET_OVERRIDE, //!< Get the override infoframe state, non-override fields will be set to value = AUTO, overridden fields will have the current override values.
+ NV_INFOFRAME_CMD_SET_OVERRIDE, //!< Set the override infoframe state, non-override fields will be set to value = AUTO, other values indicate override; persist across modeset/reboot
+ NV_INFOFRAME_CMD_GET_PROPERTY, //!< get properties associated with infoframe (each of the infoframe type will have properties)
+ NV_INFOFRAME_CMD_SET_PROPERTY, //!< set properties associated with infoframe
+} NV_INFOFRAME_CMD;
+
+
+typedef enum
+{
+ NV_INFOFRAME_PROPERTY_MODE_AUTO = 0, //!< Driver determines whether to send infoframes.
+ NV_INFOFRAME_PROPERTY_MODE_ENABLE, //!< Driver always sends infoframe.
+ NV_INFOFRAME_PROPERTY_MODE_DISABLE, //!< Driver never sends infoframe.
+ NV_INFOFRAME_PROPERTY_MODE_ALLOW_OVERRIDE, //!< Driver only sends infoframe when client requests it via infoframe escape call.
+} NV_INFOFRAME_PROPERTY_MODE;
+
+
+//! Returns whether the current monitor is in blacklist or force this monitor to be in blacklist.
+typedef enum
+{
+ NV_INFOFRAME_PROPERTY_BLACKLIST_FALSE = 0,
+ NV_INFOFRAME_PROPERTY_BLACKLIST_TRUE,
+} NV_INFOFRAME_PROPERTY_BLACKLIST;
+
+typedef struct
+{
+ NvU32 mode : 4;
+ NvU32 blackList : 2;
+ NvU32 reserved : 10;
+ NvU32 version : 8;
+ NvU32 length : 8;
+} NV_INFOFRAME_PROPERTY;
+
+//! Byte1 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_NODATA = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_OVERSCAN,
+ NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_UNDERSCAN,
+ NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_FUTURE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_SCANINFO;
+
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_NOT_PRESENT = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_VERTICAL_PRESENT,
+ NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_HORIZONTAL_PRESENT,
+ NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_BOTH_PRESENT,
+ NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_BARDATA;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_AFI_ABSENT = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_AFI_PRESENT,
+ NV_INFOFRAME_FIELD_VALUE_AVI_AFI_AUTO = 3
+} NV_INFOFRAME_FIELD_VALUE_AVI_ACTIVEFORMATINFO;
+
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_RGB = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_YCbCr422,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_YCbCr444,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_FUTURE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_COLORFORMAT;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_F17_FALSE = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_F17_TRUE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_F17_AUTO = 3
+} NV_INFOFRAME_FIELD_VALUE_AVI_F17;
+
+//! Byte2 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_NO_AFD = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE01,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE02,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE03,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_LETTERBOX_GT16x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE05,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE06,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE07,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_EQUAL_CODEDFRAME = 8,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_4x3,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_16x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_CENTER_14x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_RESERVE12,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_4x3_ON_14x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_16x9_ON_14x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_16x9_ON_4x3,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION_AUTO = 31,
+} NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOACTIVEPORTION;
+
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_NO_DATA = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_4x3,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_16x9,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_FUTURE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_ASPECTRATIOCODEDFRAME;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_NO_DATA = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_SMPTE_170M,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_ITUR_BT709,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_USE_EXTENDED_COLORIMETRY,
+ NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_COLORIMETRY;
+
+//! Byte 3 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_NO_DATA = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_HORIZONTAL,
+ NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_VERTICAL,
+ NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_BOTH,
+ NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_NONUNIFORMPICTURESCALING;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_DEFAULT = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_LIMITED_RANGE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_FULL_RANGE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_RESERVED,
+ NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_RGBQUANTIZATION;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_XVYCC601 = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_XVYCC709,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_SYCC601,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_ADOBEYCC601,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_ADOBERGB,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED05,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED06,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_RESERVED07,
+ NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY_AUTO = 15
+} NV_INFOFRAME_FIELD_VALUE_AVI_EXTENDEDCOLORIMETRY;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_ITC_VIDEO_CONTENT = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ITC_ITCONTENT,
+ NV_INFOFRAME_FIELD_VALUE_AVI_ITC_AUTO = 3
+} NV_INFOFRAME_FIELD_VALUE_AVI_ITC;
+
+//! Byte 4 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_NONE = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X02,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X03,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X04,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X05,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X06,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X07,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X08,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X09,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_X10,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED10,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED11,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED12,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED13,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED14,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_RESERVED15,
+ NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION_AUTO = 31
+} NV_INFOFRAME_FIELD_VALUE_AVI_PIXELREPETITION;
+
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_GRAPHICS = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_PHOTO,
+ NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_CINEMA,
+ NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_GAME,
+ NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_CONTENTTYPE;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_LIMITED_RANGE = 0,
+ NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_FULL_RANGE,
+ NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_RESERVED02,
+ NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_RESERVED03,
+ NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AVI_YCCQUANTIZATION;
+
+//! Adding an Auto bit to each field
+typedef struct
+{
+ NvU32 vic : 8;
+ NvU32 pixelRepeat : 5;
+ NvU32 colorSpace : 3;
+ NvU32 colorimetry : 3;
+ NvU32 extendedColorimetry : 4;
+ NvU32 rgbQuantizationRange : 3;
+ NvU32 yccQuantizationRange : 3;
+ NvU32 itContent : 2;
+ NvU32 contentTypes : 3;
+ NvU32 scanInfo : 3;
+ NvU32 activeFormatInfoPresent : 2;
+ NvU32 activeFormatAspectRatio : 5;
+ NvU32 picAspectRatio : 3;
+ NvU32 nonuniformScaling : 3;
+ NvU32 barInfo : 3;
+ NvU32 top_bar : 17;
+ NvU32 bottom_bar : 17;
+ NvU32 left_bar : 17;
+ NvU32 right_bar : 17;
+ NvU32 Future17 : 2;
+ NvU32 Future47 : 2;
+} NV_INFOFRAME_VIDEO;
+
+//! Byte 1 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_IN_HEADER = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_2,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_3,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_4,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_5,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_6,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_7,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_8,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT_AUTO = 15
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELCOUNT;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_IN_HEADER = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_PCM,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AC3,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MPEG1,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MP3,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MPEG2,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AACLC,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DTS,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_ATRAC,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DSD,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_EAC3,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DTSHD,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_MLP,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_DST,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_WMAPRO,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_USE_CODING_EXTENSION_TYPE,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE_AUTO = 31
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGTYPE;
+
+//! Byte 2 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_IN_HEADER = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_16BITS,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_20BITS,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_24BITS,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLESIZE;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_IN_HEADER = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_32000HZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_44100HZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_48000HZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_88200KHZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_96000KHZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_176400KHZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_192000KHZ,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY_AUTO = 15
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_SAMPLEFREQUENCY;
+
+
+
+//! Byte 3 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_USE_CODING_TYPE = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_HEAAC,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_HEAACV2,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_MPEGSURROUND,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE04,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE05,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE06,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE07,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE08,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE09,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE10,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE11,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE12,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE13,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE14,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE15,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE16,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE17,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE18,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE19,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE20,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE21,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE22,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE23,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE24,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE25,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE26,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE27,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE28,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE29,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE30,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_RESERVE31,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE_AUTO = 63
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_CODINGEXTENSIONTYPE;
+
+
+//! Byte 4 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_X_X_FR_FL =0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_X_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_X_RC_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_X_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_RC_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_RRC_RLC_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_X_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_X_RC_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRC_FLC_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_FCH_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_X_FCH_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_X_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_X_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_X_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_X_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_RC_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_RC_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FCH_RC_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FCH_RC_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_FCH_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_TC_FCH_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRH_FLH_RR_RL_FC_LFE_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_FC_X_FR_FL,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_FRW_FLW_RR_RL_FC_LFE_FR_FL = 0X31,
+ // all other values should default to auto
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION_AUTO = 0x1FF
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_CHANNELALLOCATION;
+
+//! Byte 5 related
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_NO_DATA = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_0DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_PLUS10DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_RESERVED03,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL_AUTO = 7
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_LFEPLAYBACKLEVEL;
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_0DB = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_1DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_2DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_3DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_4DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_5DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_6DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_7DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_8DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_9DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_10DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_11DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_12DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_13DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_14DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_15DB,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES_AUTO = 31
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_LEVELSHIFTVALUES;
+
+
+typedef enum
+{
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_PERMITTED = 0,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_PROHIBITED,
+ NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX_AUTO = 3
+} NV_INFOFRAME_FIELD_VALUE_AUDIO_DOWNMIX;
+
+typedef struct
+{
+ NvU32 codingType : 5;
+ NvU32 codingExtensionType : 6;
+ NvU32 sampleSize : 3;
+ NvU32 sampleRate : 4;
+ NvU32 channelCount : 4;
+ NvU32 speakerPlacement : 9;
+ NvU32 downmixInhibit : 2;
+ NvU32 lfePlaybackLevel : 3;
+ NvU32 levelShift : 5;
+ NvU32 Future12 : 2;
+ NvU32 Future2x : 4;
+ NvU32 Future3x : 4;
+ NvU32 Future52 : 2;
+ NvU32 Future6 : 9;
+ NvU32 Future7 : 9;
+ NvU32 Future8 : 9;
+ NvU32 Future9 : 9;
+ NvU32 Future10 : 9;
+} NV_INFOFRAME_AUDIO;
+
+typedef struct
+{
+ NvU32 version; //!< version of this structure
+ NvU16 size; //!< size of this structure
+ NvU8 cmd; //!< The actions to perform from NV_INFOFRAME_CMD
+ NvU8 type; //!< type of infoframe
+
+ union
+ {
+ NV_INFOFRAME_PROPERTY property; //!< This is NVIDIA-specific and corresponds to the property cmds and associated infoframe.
+ NV_INFOFRAME_AUDIO audio;
+ NV_INFOFRAME_VIDEO video;
+ } infoframe;
+} NV_INFOFRAME_DATA;
+
+//! Macro for constructing the version field of ::NV_INFOFRAME_DATA
+#define NV_INFOFRAME_DATA_VER MAKE_NVAPI_VERSION(NV_INFOFRAME_DATA,1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_Disp_InfoFrameControl
+//
+//! DESCRIPTION: This API controls the InfoFrame values.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in] displayId Monitor Identifier
+//! \param [in,out] pInfoframeData Contains data corresponding to InfoFrame
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Disp_InfoFrameControl(_In_ NvU32 displayId, _Inout_ NV_INFOFRAME_DATA *pInfoframeData);
+
+
+
+
+
+
+//! \ingroup dispcontrol
+//! @{
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_Disp_ColorControl
+//
+//! \fn NvAPI_Disp_ColorControl(NvU32 displayId, NV_COLOR_DATA *pColorData)
+//! DESCRIPTION: This API controls the Color values.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in] displayId Monitor Identifier
+//! \param [in,out] pColorData Contains data corresponding to color information
+//!
+//! \return RETURN STATUS:
+//! ::NVAPI_OK,
+//! ::NVAPI_ERROR,
+//! ::NVAPI_INVALID_ARGUMENT
+//
+///////////////////////////////////////////////////////////////////////////////
+
+typedef enum
+{
+ NV_COLOR_CMD_GET = 1,
+ NV_COLOR_CMD_SET,
+ NV_COLOR_CMD_IS_SUPPORTED_COLOR,
+ NV_COLOR_CMD_GET_DEFAULT
+} NV_COLOR_CMD;
+
+//! See Table 14 of CEA-861E. Not all of this is supported by the GPU.
+typedef enum
+{
+ NV_COLOR_FORMAT_RGB = 0,
+ NV_COLOR_FORMAT_YUV422,
+ NV_COLOR_FORMAT_YUV444,
+ NV_COLOR_FORMAT_DEFAULT = 0xFE,
+ NV_COLOR_FORMAT_AUTO = 0xFF
+} NV_COLOR_FORMAT;
+
+
+
+typedef enum
+{
+ NV_COLOR_COLORIMETRY_RGB = 0,
+ NV_COLOR_COLORIMETRY_YCC601,
+ NV_COLOR_COLORIMETRY_YCC709,
+ NV_COLOR_COLORIMETRY_XVYCC601,
+ NV_COLOR_COLORIMETRY_XVYCC709,
+ NV_COLOR_COLORIMETRY_SYCC601,
+ NV_COLOR_COLORIMETRY_ADOBEYCC601,
+ NV_COLOR_COLORIMETRY_ADOBERGB,
+ NV_COLOR_COLORIMETRY_DEFAULT = 0xFE,
+ NV_COLOR_COLORIMETRY_AUTO = 0xFF
+} NV_COLOR_COLORIMETRY;
+
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NvU16 size; //!< Size of this structure
+ NvU8 cmd;
+ struct
+ {
+ NvU8 colorFormat;
+ NvU8 colorimetry;
+ } data;
+} NV_COLOR_DATA;
+
+NVAPI_INTERFACE NvAPI_Disp_ColorControl(NvU32 displayId, NV_COLOR_DATA *pColorData);
+
+//! Macro for constructing the version field of ::NV_COLOR_DATA
+#define NV_COLOR_DATA_VER MAKE_NVAPI_VERSION(NV_COLOR_DATA,1)
+
+//! @}
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_DISP_GetTiming().
+typedef struct
+{
+ NvU32 isInterlaced : 4; //!< To retrieve interlaced/progressive timing
+ NvU32 reserved0 : 12;
+ union
+ {
+ NvU32 tvFormat : 8; //!< The actual analog HD/SDTV format. Used when the timing type is
+ //! NV_TIMING_OVERRIDE_ANALOG_TV and width==height==rr==0.
+ NvU32 ceaId : 8; //!< The EIA/CEA 861B/D predefined short timing descriptor ID.
+ //! Used when the timing type is NV_TIMING_OVERRIDE_EIA861
+ //! and width==height==rr==0.
+ NvU32 nvPsfId : 8; //!< The NV predefined PsF format Id.
+ //! Used when the timing type is NV_TIMING_OVERRIDE_NV_PREDEFINED.
+ };
+ NvU32 scaling : 8; //!< Define preferred scaling
+}NV_TIMING_FLAG;
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_DISP_GetTiming().
+typedef struct _NV_TIMING_INPUT
+{
+ NvU32 version; //!< (IN) structure version
+
+ NvU32 width; //!< Visible horizontal size
+ NvU32 height; //!< Visible vertical size
+ float rr; //!< Timing refresh rate
+
+ NV_TIMING_FLAG flag; //!< Flag containing additional info for timing calculation.
+
+ NV_TIMING_OVERRIDE type; //!< Timing type(formula) to use for calculating the timing
+}NV_TIMING_INPUT;
+
+#define NV_TIMING_INPUT_VER MAKE_NVAPI_VERSION(NV_TIMING_INPUT,1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_GetTiming
+//
+//! DESCRIPTION: This function calculates the timing from the visible width/height/refresh-rate and timing type info.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 313
+//!
+//!
+//! \param [in] displayId Display ID of the display.
+//! \param [in] timingInput Inputs used for calculating the timing.
+//! \param [out] pTiming Pointer to the NV_TIMING structure.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_GetTiming( _In_ NvU32 displayId,_In_ NV_TIMING_INPUT *timingInput, _Out_ NV_TIMING *pTiming);
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_GetMonitorCapabilities
+//
+//! \fn NvAPI_DISP_GetMonitorCapabilities(NvU32 displayId, NV_MONITOR_CAPABILITIES *pMonitorCapabilities)
+//! DESCRIPTION: This API returns the Monitor capabilities
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in] displayId Monitor Identifier
+//! \param [out] pMonitorCapabilities The monitor support info
+//!
+//! \return ::NVAPI_OK,
+//! ::NVAPI_ERROR,
+//! ::NVAPI_INVALID_ARGUMENT
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//! \ingroup dispcontrol
+//! @{
+
+
+//! HDMI-related and extended CAPs
+typedef enum
+{
+ // hdmi related caps
+ NV_MONITOR_CAPS_TYPE_HDMI_VSDB = 0x1000,
+ NV_MONITOR_CAPS_TYPE_HDMI_VCDB = 0x1001,
+} NV_MONITOR_CAPS_TYPE;
+
+
+
+typedef struct _NV_MONITOR_CAPS_VCDB
+{
+ NvU8 quantizationRangeYcc : 1;
+ NvU8 quantizationRangeRgb : 1;
+ NvU8 scanInfoPreferredVideoFormat : 2;
+ NvU8 scanInfoITVideoFormats : 2;
+ NvU8 scanInfoCEVideoFormats : 2;
+} NV_MONITOR_CAPS_VCDB;
+
+
+//! See NvAPI_DISP_GetMonitorCapabilities().
+typedef struct _NV_MONITOR_CAPS_VSDB
+{
+ // byte 1
+ NvU8 sourcePhysicalAddressB : 4; //!< Byte 1
+ NvU8 sourcePhysicalAddressA : 4; //!< Byte 1
+ // byte 2
+ NvU8 sourcePhysicalAddressD : 4; //!< Byte 2
+ NvU8 sourcePhysicalAddressC : 4; //!< Byte 2
+ // byte 3
+ NvU8 supportDualDviOperation : 1; //!< Byte 3
+ NvU8 reserved6 : 2; //!< Byte 3
+ NvU8 supportDeepColorYCbCr444 : 1; //!< Byte 3
+ NvU8 supportDeepColor30bits : 1; //!< Byte 3
+ NvU8 supportDeepColor36bits : 1; //!< Byte 3
+ NvU8 supportDeepColor48bits : 1; //!< Byte 3
+ NvU8 supportAI : 1; //!< Byte 3
+ // byte 4
+ NvU8 maxTmdsClock; //!< Bye 4
+ // byte 5
+ NvU8 cnc0SupportGraphicsTextContent : 1; //!< Byte 5
+ NvU8 cnc1SupportPhotoContent : 1; //!< Byte 5
+ NvU8 cnc2SupportCinemaContent : 1; //!< Byte 5
+ NvU8 cnc3SupportGameContent : 1; //!< Byte 5
+ NvU8 reserved8 : 1; //!< Byte 5
+ NvU8 hasVicEntries : 1; //!< Byte 5
+ NvU8 hasInterlacedLatencyField : 1; //!< Byte 5
+ NvU8 hasLatencyField : 1; //!< Byte 5
+ // byte 6
+ NvU8 videoLatency; //!< Byte 6
+ // byte 7
+ NvU8 audioLatency; //!< Byte 7
+ // byte 8
+ NvU8 interlacedVideoLatency; //!< Byte 8
+ // byte 9
+ NvU8 interlacedAudioLatency; //!< Byte 9
+ // byte 10
+ NvU8 reserved13 : 7; //!< Byte 10
+ NvU8 has3dEntries : 1; //!< Byte 10
+ // byte 11
+ NvU8 hdmi3dLength : 5; //!< Byte 11
+ NvU8 hdmiVicLength : 3; //!< Byte 11
+ // Remaining bytes
+ NvU8 hdmi_vic[7]; //!< Keeping maximum length for 3 bits
+ NvU8 hdmi_3d[31]; //!< Keeping maximum length for 5 bits
+} NV_MONITOR_CAPS_VSDB;
+
+
+//! See NvAPI_DISP_GetMonitorCapabilities().
+typedef struct _NV_MONITOR_CAPABILITIES
+{
+ NvU32 version;
+ NvU16 size;
+ NvU32 infoType;
+ NvU32 connectorType; //!< Out: VGA, TV, DVI, HDMI, DP
+ NvU8 bIsValidInfo : 1; //!< Boolean : Returns invalid if requested info is not present such as VCDB not present
+ union {
+ NV_MONITOR_CAPS_VSDB vsdb;
+ NV_MONITOR_CAPS_VCDB vcdb;
+ } data;
+} NV_MONITOR_CAPABILITIES;
+
+//! Macro for constructing the version field of ::NV_MONITOR_CAPABILITIES
+#define NV_MONITOR_CAPABILITIES_VER MAKE_NVAPI_VERSION(NV_MONITOR_CAPABILITIES,1)
+
+//! @}
+
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//! \ingroup dispcontrol
+NVAPI_INTERFACE NvAPI_DISP_GetMonitorCapabilities(_In_ NvU32 displayId, _Inout_ NV_MONITOR_CAPABILITIES *pMonitorCapabilities);
+
+//! \ingroup dispcontrol
+typedef struct _NV_MONITOR_COLOR_DATA
+{
+ NvU32 version;
+// We are only supporting DP monitors for now. We need to extend this to HDMI panels as well
+ NV_DP_COLOR_FORMAT colorFormat; //!< One of the supported color formats
+ NV_DP_BPC backendBitDepths; //!< One of the supported bit depths
+} NV_MONITOR_COLOR_CAPS_V1;
+
+typedef NV_MONITOR_COLOR_CAPS_V1 NV_MONITOR_COLOR_CAPS;
+
+//! \ingroup dispcontrol
+#define NV_MONITOR_COLOR_CAPS_VER1 MAKE_NVAPI_VERSION(NV_MONITOR_COLOR_CAPS_V1,1)
+#define NV_MONITOR_COLOR_CAPS_VER NV_MONITOR_COLOR_CAPS_VER1
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_GetMonitorColorCapabilities
+//
+//! DESCRIPTION: This API returns all the color formats and bit depth values supported by a given DP monitor.
+//!
+//! USAGE: Sequence of calls which caller should make to get the information.
+//! 1. First call NvAPI_DISP_GetMonitorColorCapabilities() with pMonitorColorCapabilities as NULL to get the count.
+//! 2. Allocate memory for color caps(NV_MONITOR_COLOR_CAPS) array.
+//! 3. Call NvAPI_DISP_GetMonitorColorCapabilities() again with the pointer to the memory allocated to get all the
+//! color capabilities.
+//!
+//! Note :
+//! 1. pColorCapsCount should never be NULL, else the API will fail with NVAPI_INVALID_ARGUMENT.
+//! 2. *pColorCapsCount returned from the API will always be the actual count in any/every call.
+//! 3. Memory size to be allocated should be (*pColorCapsCount * sizeof(NV_MONITOR_COLOR_CAPS)).
+//! 4. If the memory allocated is less than what is required to return all the timings, this API will return the
+//! amount of information which can fit in user provided buffer and API will return NVAPI_INSUFFICIENT_BUFFER.
+//! 5. If the caller specifies a greater value for *pColorCapsCount in second call to NvAPI_DISP_GetMonitorColorCapabilities()
+//! than what was returned from first call, the API will return only the actual number of elements in the color
+//! capabilities array and the extra buffer will remain unused.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in] displayId Monitor Identifier
+//! \param [in, out] pMonitorColorCapabilities The monitor color capabilities information
+//! \param [in, out] pColorCapsCount - During input, the number of elements allocated for the pMonitorColorCapabilities pointer
+//! - During output, the actual number of color data elements the monitor supports
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval NVAPI_INSUFFICIENT_BUFFER The input buffer size is not sufficient to hold the total contents. In this case
+//! *pColorCapsCount will hold the required amount of elements.
+//! \retval NVAPI_INVALID_DISPLAY_ID The input monitor is either not connected or is not a DP panel.
+//!
+//! \ingroup dispcontrol
+//!
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_GetMonitorColorCapabilities(_In_ NvU32 displayId, __inout_ecount_part_opt(*pColorCapsCount, *pColorCapsCount) NV_MONITOR_COLOR_CAPS *pMonitorColorCapabilities, _Inout_ NvU32 *pColorCapsCount);
+
+//! \ingroup dispcontrol
+//! Used in NvAPI_DISP_EnumCustomDisplay() and NvAPI_DISP_TryCustomDisplay().
+typedef struct
+{
+ NvU32 version;
+
+ // the source mode information
+ NvU32 width; //!< Source surface(source mode) width
+ NvU32 height; //!< Source surface(source mode) height
+ NvU32 depth; //!< Source surface color depth."0" means all 8/16/32bpp
+ NV_FORMAT colorFormat; //!< Color format (optional)
+
+ NV_VIEWPORTF srcPartition; //!< For multimon support, should be set to (0,0,1.0,1.0) for now.
+
+ float xRatio; //!< Horizontal scaling ratio
+ float yRatio; //!< Vertical scaling ratio
+
+ NV_TIMING timing; //!< Timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc.
+ NvU32 hwModeSetOnly : 1; //!< If set, it means a hardware modeset without OS update
+
+}NV_CUSTOM_DISPLAY;
+
+//! \ingroup dispcontrol
+//! Used in NV_CUSTOM_DISPLAY.
+#define NV_CUSTOM_DISPLAY_VER MAKE_NVAPI_VERSION(NV_CUSTOM_DISPLAY,1)
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_EnumCustomDisplay
+//
+//! DESCRIPTION: This API enumerates the custom timing specified by the enum index.
+//! The client should keep enumerating until it returns NVAPI_END_ENUMERATION.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] displayId Dispaly ID of the display.
+//! \param [in] index Enum index
+//! \param [inout] pCustDisp Pointer to the NV_CUSTOM_DISPLAY structure
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//! \retval NVAPI_INVALID_DISPLAY_ID: Custom Timing is not supported on the Display, whose display id is passed
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_EnumCustomDisplay( _In_ NvU32 displayId, _In_ NvU32 index, _Inout_ NV_CUSTOM_DISPLAY *pCustDisp);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_TryCustomDisplay
+//
+//! DESCRIPTION: This API is used to set up a custom display without saving the configuration on multiple displays.
+//!
+//! \note
+//! All the members of srcPartition, present in NV_CUSTOM_DISPLAY structure, should have their range in (0.0,1.0).
+//! In clone mode the timings can applied to both the target monitors but only one target at a time. \n
+//! For the secondary target the applied timings works under the following conditions:
+//! - If the secondary monitor EDID supports the selected timing, OR
+//! - If the selected custom timings can be scaled by the secondary monitor for the selected source resolution on the primary, OR
+//! - If the selected custom timings matches the existing source resolution on the primary.
+//! Setting up a custom display on non-active but connected monitors is supported only for Win7 and above.
+//!
+//! SUPPORTED OS: Windows XP, Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//!
+//! \param [in] pDisplayIds Array of the target display Dispaly IDs - See \ref handles.
+//! \param [in] count Total number of the incoming Display IDs and corresponding NV_CUSTOM_DISPLAY structure. This is for the multi-head support.
+//! \param [in] pCustDisp Pointer to the NV_CUSTOM_DISPLAY structure array.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//! \retval NVAPI_INVALID_DISPLAY_ID: Custom Timing is not supported on the Display, whose display id is passed
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_TryCustomDisplay( __in_ecount(count) NvU32 *pDisplayIds, _In_ NvU32 count, __in_ecount(count) NV_CUSTOM_DISPLAY *pCustDisp);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_DeleteCustomDisplay
+//
+//! DESCRIPTION: This function deletes the custom display configuration, specified from the registry for all the displays whose display IDs are passed.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 313
+//!
+//!
+//! \param [in] pDisplayIds Array of Dispaly IDs on which custom display configuration is to be saved.
+//! \param [in] count Total number of the incoming Dispaly IDs. This is for the multi-head support.
+//! \param [in] pCustDisp Pointer to the NV_CUSTOM_DISPLAY structure
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//! \retval NVAPI_INVALID_DISPLAY_ID: Custom Timing is not supported on the Display, whose display id is passed
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_DeleteCustomDisplay( __in_ecount(count) NvU32 *pDisplayIds, _In_ NvU32 count, _In_ NV_CUSTOM_DISPLAY *pCustDisp);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_SaveCustomDisplay
+//
+//! DESCRIPTION: This function saves the current hardware display configuration on the specified Display IDs as a custom display configuration.
+//! This function should be called right after NvAPI_DISP_TryCustomDisplay() to save the custom display from the current
+//! hardware context. This function will not do anything if the custom display configuration is not tested on the hardware.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 313
+//!
+//!
+//! \param [in] pDisplayIds Array of Dispaly IDs on which custom display configuration is to be saved.
+//! \param [in] count Total number of the incoming Dispaly IDs. This is for the multi-head support.
+//! \param [in] isThisOutputIdOnly If set, the saved custom display will only be applied on the monitor with the same outputId (see \ref handles).
+//! \param [in] isThisMonitorIdOnly If set, the saved custom display will only be applied on the monitor with the same EDID ID or
+//! the same TV connector in case of analog TV.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//! \retval NVAPI_INVALID_DISPLAY_ID: Custom Timing is not supported on the Display, whose display id is passed
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_SaveCustomDisplay( __in_ecount(count) NvU32 *pDisplayIds, _In_ NvU32 count, _In_ NvU32 isThisOutputIdOnly, _In_ NvU32 isThisMonitorIdOnly);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_RevertCustomDisplayTrial
+//
+//! DESCRIPTION: This API is used to restore the display configuration, that was changed by calling NvAPI_DISP_TryCustomDisplay(). This function
+//! must be called only after a custom display configuration is tested on the hardware, using NvAPI_DISP_TryCustomDisplay(),
+//! otherwise no action is taken. On Vista, NvAPI_DISP_RevertCustomDisplayTrial should be called with an active display that
+//! was affected during the NvAPI_DISP_TryCustomDisplay() call, per GPU.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \since Release: 313
+//!
+//!
+//! \param [in] pDisplayIds Pointer to display Id, of an active display.
+//! \param [in] count Total number of incoming Display IDs. For future use only. Currently it is expected to be passed as 1.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_RevertCustomDisplayTrial( __in_ecount(count) NvU32* pDisplayIds, _In_ NvU32 count);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GetView
+//
+//! This API lets caller retrieve the target display arrangement for selected source display handle.
+//! \note Display PATH with this API is limited to single GPU. DUALVIEW across GPUs will be returned as STANDARD VIEW.
+//! Use NvAPI_SYS_GetDisplayTopologies() to query views across GPUs.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_GetDisplayConfig.
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. It can be #NVAPI_DEFAULT_HANDLE or a handle enumerated from
+//! NvAPI_EnumNVidiaDisplayHandle().
+//! \param [out] pTargets User allocated storage to retrieve an array of NV_VIEW_TARGET_INFO. Can be NULL to retrieve
+//! the targetCount.
+//! \param [in,out] targetMaskCount Count of target device mask specified in pTargetMask.
+//! \param [out] targetView Target view selected from NV_TARGET_VIEW_MODE.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_GetDisplayConfig.")
+NVAPI_INTERFACE NvAPI_GetView(NvDisplayHandle hNvDisplay, NV_VIEW_TARGET_INFO *pTargets, NvU32 *pTargetMaskCount, NV_TARGET_VIEW_MODE *pTargetView);
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GetViewEx
+//
+//! DESCRIPTION: This API lets caller retrieve the target display arrangement for selected source display handle.
+//! \note Display PATH with this API is limited to single GPU. DUALVIEW across GPUs will be returned as STANDARD VIEW.
+//! Use NvAPI_SYS_GetDisplayTopologies() to query views across GPUs.
+//!
+//! \deprecated Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_GetDisplayConfig.
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \since Release: 165
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. #NVAPI_DEFAULT_HANDLE is not allowed, it has to be a handle enumerated with
+//! NvAPI_EnumNVidiaDisplayHandle().
+//! \param [in,out] pPathInfo Count field should be set to NVAPI_MAX_DISPLAY_PATH. Can be NULL to retrieve just the pathCount.
+//! \param [in,out] pPathCount Number of elements in array pPathInfo->path.
+//! \param [out] pTargetViewMode Display view selected from NV_TARGET_VIEW_MODE.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_API_NOT_INTIALIZED NVAPI not initialized
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//! \retval NVAPI_EXPECTED_DISPLAY_HANDLE hNvDisplay is not a valid display handle.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+__nvapi_deprecated_function("Do not use this function - it is deprecated in release 290. Instead, use NvAPI_DISP_GetDisplayConfig.")
+NVAPI_INTERFACE NvAPI_GetViewEx(NvDisplayHandle hNvDisplay, NV_DISPLAY_PATH_INFO *pPathInfo, NvU32 *pPathCount, NV_TARGET_VIEW_MODE *pTargetViewMode);
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_GetSupportedViews
+//
+//! This API lets caller enumerate all the supported NVIDIA display views - nView and Dualview modes.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 85
+//!
+//! \param [in] hNvDisplay NVIDIA Display selection. It can be #NVAPI_DEFAULT_HANDLE or a handle enumerated from
+//! NvAPI_EnumNVidiaDisplayHandle().
+//! \param [out] pTargetViews Array of supported views. Can be NULL to retrieve the pViewCount first.
+//! \param [in,out] pViewCount Count of supported views.
+//!
+//! \retval NVAPI_OK Completed request
+//! \retval NVAPI_ERROR Miscellaneous error occurred
+//! \retval NVAPI_INVALID_ARGUMENT Invalid input parameter.
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GetSupportedViews(NvDisplayHandle hNvDisplay, NV_TARGET_VIEW_MODE *pTargetViews, NvU32 *pViewCount);
+
+
+//! SUPPORTED OS: Windows XP and higher
+//!
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_DISP_GetDisplayIdByDisplayName
+//
+//! DESCRIPTION: This API retrieves the Display Id of a given display by
+//! display name. The display must be active to retrieve the
+//! displayId. In the case of clone mode or Surround gaming,
+//! the primary or top-left display will be returned.
+//!
+//! \param [in] displayName Name of display (Eg: "\\DISPLAY1" to
+//! retrieve the displayId for.
+//! \param [out] displayId Display ID of the requested display.
+//!
+//! retval ::NVAPI_OK: Capabilties have been returned.
+//! retval ::NVAPI_INVALID_ARGUMENT: One or more args passed in are invalid.
+//! retval ::NVAPI_API_NOT_INTIALIZED: The NvAPI API needs to be initialized first
+//! retval ::NVAPI_NO_IMPLEMENTATION: This entrypoint not available
+//! retval ::NVAPI_ERROR: Miscellaneous error occurred
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_GetDisplayIdByDisplayName(const char *displayName, NvU32* displayId);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_GetDisplayConfig
+//
+//! DESCRIPTION: This API lets caller retrieve the current global display
+//! configuration.
+//! USAGE: The caller might have to call this three times to fetch all the required configuration details as follows:
+//! First Pass: Caller should Call NvAPI_DISP_GetDisplayConfig() with pathInfo set to NULL to fetch pathInfoCount.
+//! Second Pass: Allocate memory for pathInfo with respect to the number of pathInfoCount(from First Pass) to fetch
+//! targetInfoCount. If sourceModeInfo is needed allocate memory or it can be initialized to NULL.
+//! Third Pass(Optional, only required if target information is required): Allocate memory for targetInfo with respect
+//! to number of targetInfoCount(from Second Pass).
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in,out] pathInfoCount Number of elements in pathInfo array, returns number of valid topologies, this cannot be null.
+//! \param [in,out] pathInfo Array of path information
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status. If there are return error codes with
+//! specific meaning for this API, they are listed below.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT - Invalid input parameter. Following can be the reason for this return value:
+//! -# pathInfoCount is NULL.
+//! -# *pathInfoCount is 0 and pathInfo is not NULL.
+//! -# *pathInfoCount is not 0 and pathInfo is NULL.
+//! \retval NVAPI_DEVICE_BUSY - ModeSet has not yet completed. Please wait and call it again.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_GetDisplayConfig(_Inout_ NvU32 *pathInfoCount, __out_ecount_full_opt(*pathInfoCount) NV_DISPLAYCONFIG_PATH_INFO *pathInfo);
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// FUNCTION NAME: NvAPI_DISP_SetDisplayConfig
+//
+//
+//! DESCRIPTION: This API lets caller apply a global display configuration
+//! across multiple GPUs.
+//!
+//! If all sourceIds are zero, then NvAPI will pick up sourceId's based on the following criteria :
+//! - If user provides sourceModeInfo then we are trying to assign 0th sourceId always to GDIPrimary.
+//! This is needed since active windows always moves along with 0th sourceId.
+//! - For rest of the paths, we are incrementally assigning the sourceId per adapter basis.
+//! - If user doesn't provide sourceModeInfo then NVAPI just picks up some default sourceId's in incremental order.
+//! Note : NVAPI will not intelligently choose the sourceIDs for any configs that does not need a modeset.
+//!
+//! SUPPORTED OS: Windows Vista and higher
+//!
+//!
+//! \param [in] pathInfoCount Number of supplied elements in pathInfo
+//! \param [in] pathInfo Array of path information
+//! \param [in] flags Flags for applying settings
+//!
+//! \retval ::NVAPI_OK - completed request
+//! \retval ::NVAPI_API_NOT_INTIALIZED - NVAPI not initialized
+//! \retval ::NVAPI_ERROR - miscellaneous error occurred
+//! \retval ::NVAPI_INVALID_ARGUMENT - Invalid input parameter.
+//!
+//! \ingroup dispcontrol
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_DISP_SetDisplayConfig(_In_ NvU32 pathInfoCount, __in_ecount(pathInfoCount) NV_DISPLAYCONFIG_PATH_INFO* pathInfo, _In_ NvU32 flags);
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+//
+// MOSAIC allows a multi display target output scanout on a single source.
+//
+// SAMPLE of MOSAIC 1x4 topo with 8 pixel horizontal overlap
+//
+//+-------------------------++-------------------------++-------------------------++-------------------------+
+//| || || || |
+//| || || || |
+//| || || || |
+//| DVI1 || DVI2 || DVI3 || DVI4 |
+//| || || || |
+//| || || || |
+//| || || || |
+//| || || || |
+//+-------------------------++-------------------------++-------------------------++-------------------------+
+
+
+//! \addtogroup mosaicapi
+//! @{
+
+#define NVAPI_MAX_MOSAIC_DISPLAY_ROWS 8
+#define NVAPI_MAX_MOSAIC_DISPLAY_COLUMNS 8
+//
+// These bits are used to describe the validity of a topo.
+//
+#define NV_MOSAIC_TOPO_VALIDITY_VALID 0x00000000 //!< The topology is valid
+#define NV_MOSAIC_TOPO_VALIDITY_MISSING_GPU 0x00000001 //!< Not enough SLI GPUs were found to fill the entire
+ //! topology. hPhysicalGPU will be 0 for these.
+#define NV_MOSAIC_TOPO_VALIDITY_MISSING_DISPLAY 0x00000002 //!< Not enough displays were found to fill the entire
+ //! topology. displayOutputId will be 0 for these.
+#define NV_MOSAIC_TOPO_VALIDITY_MIXED_DISPLAY_TYPES 0x00000004 //!< The topoogy is only possible with displays of the same
+ //! NV_GPU_OUTPUT_TYPE. Check displayOutputIds to make
+ //! sure they are all CRTs, or all DFPs.
+
+
+//
+//! This structure defines the topology details.
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NvLogicalGpuHandle hLogicalGPU; //!< Logical GPU for this topology
+ NvU32 validityMask; //!< 0 means topology is valid with the current hardware.
+ //! If not 0, inspect bits against NV_MOSAIC_TOPO_VALIDITY_*.
+ NvU32 rowCount; //!< Number of displays in a row
+ NvU32 colCount; //!< Number of displays in a column
+
+ struct
+ {
+ NvPhysicalGpuHandle hPhysicalGPU; //!< Physical GPU to be used in the topology (0 if GPU missing)
+ NvU32 displayOutputId; //!< Connected display target (0 if no display connected)
+ NvS32 overlapX; //!< Pixels of overlap on left of target: (+overlap, -gap)
+ NvS32 overlapY; //!< Pixels of overlap on top of target: (+overlap, -gap)
+
+ } gpuLayout[NVAPI_MAX_MOSAIC_DISPLAY_ROWS][NVAPI_MAX_MOSAIC_DISPLAY_COLUMNS];
+
+} NV_MOSAIC_TOPO_DETAILS;
+
+//! Macro for constructing te vesion field of NV_MOSAIC_TOPO_DETAILS
+#define NVAPI_MOSAIC_TOPO_DETAILS_VER MAKE_NVAPI_VERSION(NV_MOSAIC_TOPO_DETAILS,1)
+
+
+//
+//! These values refer to the different types of Mosaic topologies that are possible. When
+//! getting the supported Mosaic topologies, you can specify one of these types to narrow down
+//! the returned list to only those that match the given type.
+typedef enum
+{
+ NV_MOSAIC_TOPO_TYPE_ALL, //!< All mosaic topologies
+ NV_MOSAIC_TOPO_TYPE_BASIC, //!< Basic Mosaic topologies
+ NV_MOSAIC_TOPO_TYPE_PASSIVE_STEREO, //!< Passive Stereo topologies
+ NV_MOSAIC_TOPO_TYPE_SCALED_CLONE, //!< Not supported at this time
+ NV_MOSAIC_TOPO_TYPE_PASSIVE_STEREO_SCALED_CLONE, //!< Not supported at this time
+ NV_MOSAIC_TOPO_TYPE_MAX, //!< Always leave this at end of the enum
+} NV_MOSAIC_TOPO_TYPE;
+
+
+//
+//! This is a complete list of supported Mosaic topologies.
+//!
+//! Using a "Basic" topology combines multiple monitors to create a single desktop.
+//!
+//! Using a "Passive" topology combines multiples monitors to create a passive stereo desktop.
+//! In passive stereo, two identical topologies combine - one topology is used for the right eye and the other identical //! topology (targeting different displays) is used for the left eye. \n
+//! NOTE: common\inc\nvEscDef.h shadows a couple PASSIVE_STEREO enums. If this
+//! enum list changes and effects the value of NV_MOSAIC_TOPO_BEGIN_PASSIVE_STEREO
+//! please update the corresponding value in nvEscDef.h
+typedef enum
+{
+ NV_MOSAIC_TOPO_NONE,
+
+ // 'BASIC' topos start here
+ //
+ // The result of using one of these Mosaic topos is that multiple monitors
+ // will combine to create a single desktop.
+ //
+ NV_MOSAIC_TOPO_BEGIN_BASIC,
+ NV_MOSAIC_TOPO_1x2_BASIC = NV_MOSAIC_TOPO_BEGIN_BASIC,
+ NV_MOSAIC_TOPO_2x1_BASIC,
+ NV_MOSAIC_TOPO_1x3_BASIC,
+ NV_MOSAIC_TOPO_3x1_BASIC,
+ NV_MOSAIC_TOPO_1x4_BASIC,
+ NV_MOSAIC_TOPO_4x1_BASIC,
+ NV_MOSAIC_TOPO_2x2_BASIC,
+ NV_MOSAIC_TOPO_2x3_BASIC,
+ NV_MOSAIC_TOPO_2x4_BASIC,
+ NV_MOSAIC_TOPO_3x2_BASIC,
+ NV_MOSAIC_TOPO_4x2_BASIC,
+ NV_MOSAIC_TOPO_1x5_BASIC,
+ NV_MOSAIC_TOPO_1x6_BASIC,
+ NV_MOSAIC_TOPO_7x1_BASIC,
+
+ // Add padding for 10 more entries. 6 will be enough room to specify every
+ // possible topology with 8 or fewer displays, so this gives us a little
+ // extra should we need it.
+ NV_MOSAIC_TOPO_END_BASIC = NV_MOSAIC_TOPO_7x1_BASIC + 9,
+
+ // 'PASSIVE_STEREO' topos start here
+ //
+ // The result of using one of these Mosaic topos is that multiple monitors
+ // will combine to create a single PASSIVE STEREO desktop. What this means is
+ // that there will be two topos that combine to create the overall desktop.
+ // One topo will be used for the left eye, and the other topo (of the
+ // same rows x cols), will be used for the right eye. The difference between
+ // the two topos is that different GPUs and displays will be used.
+ //
+ NV_MOSAIC_TOPO_BEGIN_PASSIVE_STEREO, // value shadowed in nvEscDef.h
+ NV_MOSAIC_TOPO_1x2_PASSIVE_STEREO = NV_MOSAIC_TOPO_BEGIN_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_2x1_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_1x3_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_3x1_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_1x4_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_4x1_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_2x2_PASSIVE_STEREO,
+ NV_MOSAIC_TOPO_END_PASSIVE_STEREO = NV_MOSAIC_TOPO_2x2_PASSIVE_STEREO + 4,
+
+
+ //
+ // Total number of topos. Always leave this at the end of the enumeration.
+ //
+ NV_MOSAIC_TOPO_MAX //! Total number of topologies.
+
+} NV_MOSAIC_TOPO;
+
+
+//
+//! This is a "topology brief" structure. It tells you what you need to know about
+//! a topology at a high level. A list of these is returned when you query for the
+//! supported Mosaic information.
+//!
+//! If you need more detailed information about the topology, call
+//! NvAPI_Mosaic_GetTopoGroup() with the topology value from this structure.
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NV_MOSAIC_TOPO topo; //!< The topology
+ NvU32 enabled; //!< 1 if topo is enabled, else 0
+ NvU32 isPossible; //!< 1 if topo *can* be enabled, else 0
+
+} NV_MOSAIC_TOPO_BRIEF;
+
+//! Macro for constructing the version field of NV_MOSAIC_TOPO_BRIEF
+#define NVAPI_MOSAIC_TOPO_BRIEF_VER MAKE_NVAPI_VERSION(NV_MOSAIC_TOPO_BRIEF,1)
+
+
+//
+//! Basic per-display settings that are used in setting/getting the Mosaic mode
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NvU32 width; //!< Per-display width
+ NvU32 height; //!< Per-display height
+ NvU32 bpp; //!< Bits per pixel
+ NvU32 freq; //!< Display frequency
+} NV_MOSAIC_DISPLAY_SETTING;
+
+//! Macro for constructing the version field of NV_MOSAIC_DISPLAY_SETTING
+#define NVAPI_MOSAIC_DISPLAY_SETTING_VER MAKE_NVAPI_VERSION(NV_MOSAIC_DISPLAY_SETTING,1)
+
+
+//
+// Set a reasonable max number of display settings to support
+// so arrays are bound.
+//
+#define NV_MOSAIC_DISPLAY_SETTINGS_MAX 40 //!< Set a reasonable maximum number of display settings to support
+ //! so arrays are bound.
+
+
+//
+//! This structure is used to contain a list of supported Mosaic topologies
+//! along with the display settings that can be used.
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NvU32 topoBriefsCount; //!< Number of topologies in below array
+ NV_MOSAIC_TOPO_BRIEF topoBriefs[NV_MOSAIC_TOPO_MAX]; //!< List of supported topologies with only brief details
+ NvU32 displaySettingsCount; //!< Number of display settings in below array
+ NV_MOSAIC_DISPLAY_SETTING displaySettings[NV_MOSAIC_DISPLAY_SETTINGS_MAX]; //!< List of per display settings possible
+
+} NV_MOSAIC_SUPPORTED_TOPO_INFO;
+
+//! Macro forconstructing the version field of NV_MOSAIC_SUPPORTED_TOPO_INFO
+#define NVAPI_MOSAIC_SUPPORTED_TOPO_INFO_VER MAKE_NVAPI_VERSION(NV_MOSAIC_SUPPORTED_TOPO_INFO,1)
+
+
+//
+// Indices to use to access the topos array within the mosaic topology
+#define NV_MOSAIC_TOPO_IDX_DEFAULT 0
+
+#define NV_MOSAIC_TOPO_IDX_LEFT_EYE 0
+#define NV_MOSAIC_TOPO_IDX_RIGHT_EYE 1
+#define NV_MOSAIC_TOPO_NUM_EYES 2
+
+
+//
+//! This defines the maximum number of topos that can be in a topo group.
+//! At this time, it is set to 2 because our largest topo group (passive
+//! stereo) only needs 2 topos (left eye and right eye).
+//!
+//! If a new topo group with more than 2 topos is added above, then this
+//! number will also have to be incremented.
+#define NV_MOSAIC_MAX_TOPO_PER_TOPO_GROUP 2
+
+
+//
+//! This structure defines a group of topologies that work together to create one
+//! overall layout. All of the supported topologies are represented with this
+//! structure.
+//!
+//! For example, a 'Passive Stereo' topology would be represented with this
+//! structure, and would have separate topology details for the left and right eyes.
+//! The count would be 2. A 'Basic' topology is also represented by this structure,
+//! with a count of 1.
+//!
+//! The structure is primarily used internally, but is exposed to applications in a
+//! read-only fashion because there are some details in it that might be useful
+//! (like the number of rows/cols, or connected display information). A user can
+//! get the filled-in structure by calling NvAPI_Mosaic_GetTopoGroup().
+//!
+//! You can then look at the detailed values within the structure. There are no
+//! entrypoints which take this structure as input (effectively making it read-only).
+typedef struct
+{
+ NvU32 version; //!< Version of this structure
+ NV_MOSAIC_TOPO_BRIEF brief; //!< The brief details of this topo
+ NvU32 count; //!< Number of topos in array below
+ NV_MOSAIC_TOPO_DETAILS topos[NV_MOSAIC_MAX_TOPO_PER_TOPO_GROUP];
+
+} NV_MOSAIC_TOPO_GROUP;
+
+//! Macro for constructing the version field of NV_MOSAIC_TOPO_GROUP
+#define NVAPI_MOSAIC_TOPO_GROUP_VER MAKE_NVAPI_VERSION(NV_MOSAIC_TOPO_GROUP,1)
+
+//! @}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Mosaic_GetSupportedTopoInfo
+//
+//! DESCRIPTION: This API returns information on the topologies and display resolutions
+//! supported by Mosaic mode.
+//!
+//! NOTE: Not all topologies returned can be set immediately.
+//! See 'OUT' Notes below.
+//!
+//! Once you get the list of supported topologies, you can call
+//! NvAPI_Mosaic_GetTopoGroup() with one of the Mosaic topologies if you need
+//! more information about it.
+//!
+//! 'IN' Notes: pSupportedTopoInfo->version must be set before calling this function.
+//! If the specified version is not supported by this implementation,
+//! an error will be returned (NVAPI_INCOMPATIBLE_STRUCT_VERSION).
+//!
+//! 'OUT' Notes: Some of the topologies returned might not be valid for one reason or
+//! another. It could be due to mismatched or missing displays. It
+//! could also be because the required number of GPUs is not found.
+//! At a high level, you can see if the topology is valid and can be enabled
+//! by looking at the pSupportedTopoInfo->topoBriefs[xxx].isPossible flag.
+//! If this is true, the topology can be enabled. If it
+//! is false, you can find out why it cannot be enabled by getting the
+//! details of the topology via NvAPI_Mosaic_GetTopoGroup(). From there,
+//! look at the validityMask of the individual topologies. The bits can
+//! be tested against the NV_MOSAIC_TOPO_VALIDITY_* bits.
+//!
+//! It is possible for this function to return NVAPI_OK with no topologies
+//! listed in the return structure. If this is the case, it means that
+//! the current hardware DOES support Mosaic, but with the given configuration
+//! no valid topologies were found. This most likely means that SLI was not
+//! enabled for the hardware. Once enabled, you should see valid topologies
+//! returned from this function.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//!
+//! \param [in,out] pSupportedTopoInfo Information about what topologies and display resolutions
+//! are supported for Mosaic.
+//! \param [in] type The type of topologies the caller is interested in
+//! getting. See NV_MOSAIC_TOPO_TYPE for possible values.
+//!
+//! \retval ::NVAPI_OK No errors in returning supported topologies.
+//! \retval ::NVAPI_NOT_SUPPORTED Mosaic is not supported with the existing hardware.
+//! \retval ::NVAPI_INVALID_ARGUMENT One or more arguments passed in are invalid.
+//! \retval ::NVAPI_API_NOT_INTIALIZED The NvAPI API needs to be initialized first.
+//! \retval ::NVAPI_NO_IMPLEMENTATION This entrypoint not available.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the structure passed in is not
+// compatible with this entry point.
+//! \retval ::NVAPI_ERROR: Miscellaneous error occurred.
+//!
+//! \ingroup mosaicapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Mosaic_GetSupportedTopoInfo(NV_MOSAIC_SUPPORTED_TOPO_INFO *pSupportedTopoInfo, NV_MOSAIC_TOPO_TYPE type);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Mosaic_GetTopoGroup
+//
+//! DESCRIPTION: This API returns a structure filled with the details
+//! of the specified Mosaic topology.
+//!
+//! If the pTopoBrief passed in matches the current topology,
+//! then information in the brief and group structures
+//! will reflect what is current. Thus the brief would have
+//! the current 'enable' status, and the group would have the
+//! current overlap values. If there is no match, then the
+//! returned brief has an 'enable' status of FALSE (since it
+//! is obviously not enabled), and the overlap values will be 0.
+//!
+//! 'IN' Notes: pTopoGroup->version must be set before calling this function.
+//! If the specified version is not supported by this implementation,
+//! an error will be returned (NVAPI_INCOMPATIBLE_STRUCT_VERSION).
+//!
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//! \param [in] pTopoBrief The topology for getting the details
+//! This must be one of the topology briefs
+//! returned from NvAPI_Mosaic_GetSupportedTopoInfo().
+//! \param [in,out] pTopoGroup The topology details matching the brief
+//!
+//! \retval ::NVAPI_OK Details were retrieved successfully.
+//! \retval ::NVAPI_NOT_SUPPORTED Mosaic is not supported with the existing hardware.
+//! \retval ::NVAPI_INVALID_ARGUMENT One or more argumentss passed in are invalid.
+//! \retval ::NVAPI_API_NOT_INTIALIZED The NvAPI API needs to be initialized first.
+//! \retval ::NVAPI_NO_IMPLEMENTATION This entrypoint not available.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the structure passed in is not
+// compatible with this entry point.
+//! \retval ::NVAPI_ERROR: Miscellaneous error occurred.
+//!
+//! \ingroup mosaicapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Mosaic_GetTopoGroup(NV_MOSAIC_TOPO_BRIEF *pTopoBrief, NV_MOSAIC_TOPO_GROUP *pTopoGroup);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Mosaic_GetOverlapLimits
+//
+//! DESCRIPTION: This API returns the X and Y overlap limits required if
+//! the given Mosaic topology and display settings are to be used.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//! \param [in] pTopoBrief The topology for getting limits
+//! This must be one of the topo briefs
+//! returned from NvAPI_Mosaic_GetSupportedTopoInfo().
+//! \param [in] pDisplaySetting The display settings for getting the limits.
+//! This must be one of the settings
+//! returned from NvAPI_Mosaic_GetSupportedTopoInfo().
+//! \param [out] pMinOverlapX X overlap minimum
+//! \param [out] pMaxOverlapX X overlap maximum
+//! \param [out] pMinOverlapY Y overlap minimum
+//! \param [out] pMaxOverlapY Y overlap maximum
+//!
+//! \retval ::NVAPI_OK Details were retrieved successfully.
+//! \retval ::NVAPI_NOT_SUPPORTED Mosaic is not supported with the existing hardware.
+//! \retval ::NVAPI_INVALID_ARGUMENT One or more argumentss passed in are invalid.
+//! \retval ::NVAPI_API_NOT_INTIALIZED The NvAPI API needs to be initialized first.
+//! \retval ::NVAPI_NO_IMPLEMENTATION This entrypoint not available.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the structure passed in is not
+//! compatible with this entry point.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup mosaicapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Mosaic_GetOverlapLimits(NV_MOSAIC_TOPO_BRIEF *pTopoBrief, NV_MOSAIC_DISPLAY_SETTING *pDisplaySetting, NvS32 *pMinOverlapX, NvS32 *pMaxOverlapX, NvS32 *pMinOverlapY, NvS32 *pMaxOverlapY);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Mosaic_SetCurrentTopo
+//
+//! DESCRIPTION: This API sets the Mosaic topology and performs a mode switch
+//! using the given display settings.
+//!
+//! If NVAPI_OK is returned, the current Mosaic topology was set
+//! correctly. Any other status returned means the
+//! topology was not set, and remains what it was before this
+//! function was called.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//! \param [in] pTopoBrief The topology to set. This must be one of the topologies returned from
+//! NvAPI_Mosaic_GetSupportedTopoInfo(), and it must have an isPossible value of 1.
+//! \param [in] pDisplaySetting The per display settings to be used in the Mosaic mode. This must be one of the
+//! settings returned from NvAPI_Mosaic_GetSupportedTopoInfo().
+//! \param [in] overlapX The pixel overlap to use between horizontal displays (use positive a number for
+//! overlap, or a negative number to create a gap.) If the overlap is out of bounds
+//! for what is possible given the topo and display setting, the overlap will be clamped.
+//! \param [in] overlapY The pixel overlap to use between vertical displays (use positive a number for
+//! overlap, or a negative number to create a gap.) If the overlap is out of bounds for
+//! what is possible given the topo and display setting, the overlap will be clamped.
+//! \param [in] enable If 1, the topology being set will also be enabled, meaning that the mode set will
+//! occur. \n
+//! If 0, you don't want to be in Mosaic mode right now, but want to set the current
+//! Mosaic topology so you can enable it later with NvAPI_Mosaic_EnableCurrentTopo().
+//!
+//! \retval ::NVAPI_OK The Mosaic topology was set.
+//! \retval ::NVAPI_NOT_SUPPORTED Mosaic is not supported with the existing hardware.
+//! \retval ::NVAPI_INVALID_ARGUMENT One or more argumentss passed in are invalid.
+//! \retval ::NVAPI_TOPO_NOT_POSSIBLE The topology passed in is not currently possible.
+//! \retval ::NVAPI_API_NOT_INTIALIZED The NvAPI API needs to be initialized first.
+//! \retval ::NVAPI_NO_IMPLEMENTATION This entrypoint not available.
+//! \retval ::NVAPI_INCOMPATIBLE_STRUCT_VERSION The version of the structure passed in is not
+//! compatible with this entrypoint.
+//! \retval ::NVAPI_MODE_CHANGE_FAILED There was an error changing the display mode.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup mosaicapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Mosaic_SetCurrentTopo(NV_MOSAIC_TOPO_BRIEF *pTopoBrief, NV_MOSAIC_DISPLAY_SETTING *pDisplaySetting, NvS32 overlapX, NvS32 overlapY, NvU32 enable);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_Mosaic_GetCurrentTopo
+//
+//! DESCRIPTION: This API returns information for the current Mosaic topology.
+//! This includes topology, display settings, and overlap values.
+//!
+//! You can call NvAPI_Mosaic_GetTopoGroup() with the topology
+//! if you require more information.
+//!
+//! If there isn't a current topology, then pTopoBrief->topo will
+//! be NV_MOSAIC_TOPO_NONE.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 185
+//!
+//! \param [out] pTopoBrief The current Mosaic topology
+//! \param [out] pDisplaySetting The current per-display settings
+//! \param [out] pOverlapX The pixel overlap between horizontal displays
+//! \param [out] pOverlapY The pixel overlap between vertical displays
+//!
+//! \retval ::NVAPI_OK Success getting current info.
+//! \retval ::NVAPI_NOT_SUPPORTED Mosaic is not supported with the existing hardware.
+//! \retval ::NVAPI_INVALID_ARGUMENT One or more argumentss passed in are invalid.
+//! \retval ::NVAPI_API_NOT_INTIALIZED The NvAPI API needs to be initialized first.
+//! \retval ::NVAPI_NO_IMPLEMENTATION This entry point not available.
+//! \retval ::NVAPI_ERROR Miscellaneous error occurred.
+//!
+//! \ingroup mosaicapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_Mosaic_GetCurrentTopo(NV_MOSAIC_TOPO_BRIEF *pTopoBrief, NV_MOSAIC_DISPLAY_SETTING *pDisplaySetting, NvS32 *pOverlapX, NvS32 *pOverlapY);
+
+
+#define NVAPI_MAX_GSYNC_DEVICES 4
+
+
+// Sync Display APIs
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_EnumSyncDevices
+//
+//! DESCRIPTION: This API returns an array of Sync device handles. A Sync device handle represents a
+//! single Sync device on the system.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [out] nvGSyncHandles- The caller provides an array of handles, which must contain at least
+//! NVAPI_MAX_GSYNC_DEVICES elements. The API will zero out the entire array and then fill in one
+//! or more handles. If an error occurs, the array is invalid.
+//! \param [out] *gsyncCount- The caller provides the storage space. NvAPI_GSync_EnumSyncDevices
+//! sets *gsyncCount to indicate how many of the elements in the nvGSyncHandles[] array are valid.
+//! If an error occurs, *gsyncCount will be set to zero.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT nvGSyncHandles or gsyncCount is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_EnumSyncDevices(_Out_ NvGSyncDeviceHandle nvGSyncHandles[NVAPI_MAX_GSYNC_DEVICES], _Out_ NvU32 *gsyncCount);
+
+
+
+// GSync boardId values
+#define NVAPI_GSYNC_BOARD_ID_P358 856 //!< GSync board ID 0x358, see NV_GSYNC_CAPABILITIES
+#define NVAPI_GSYNC_BOARD_ID_P2060 8288 //!< GSync board ID 0x2060, see NV_GSYNC_CAPABILITIES
+
+
+//! Used in NvAPI_GSync_QueryCapabilities().
+typedef struct _NV_GSYNC_CAPABILITIES
+{
+ NvU32 version; //!< Version of the structure
+ NvU32 boardId; //!< Board ID
+ NvU32 revision; //!< FPGA Revision
+ NvU32 capFlags; //!< Capabilities of the Sync board. Reserved for future use
+} NV_GSYNC_CAPABILITIES;
+
+
+
+//! \ingroup gsyncapi
+//! Macro for constructing the version field of NV_GSYNC_CAPABILITIES.
+#define NV_GSYNC_CAPABILITIES_VER MAKE_NVAPI_VERSION(NV_GSYNC_CAPABILITIES,1)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_QueryCapabilities
+//
+//! DESCRIPTION: This API returns the capabilities of the Sync device.
+//!
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice- The handle for a Sync device for which the capabilities will be queried.
+//! \param [inout] *pNvGSyncCapabilities- The caller provides the storage space. NvAPI_GSync_QueryCapabilities() sets
+//! *pNvGSyncCapabilities to the version and capabilities details of the Sync device
+//! If an error occurs, *pNvGSyncCapabilities will be set to NULL.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_QueryCapabilities(_In_ NvGSyncDeviceHandle hNvGSyncDevice, _Inout_ NV_GSYNC_CAPABILITIES *pNvGSyncCapabilities);
+
+
+
+//! Connector values for a GPU. Used in NV_GSYNC_GPU.
+typedef enum _NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR
+{
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_NONE = 0,
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_PRIMARY = 1,
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_SECONDARY = 2,
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_TERTIARY = 3,
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR_QUARTERNARY = 4,
+} NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR;
+
+//! Display sync states. Used in NV_GSYNC_DISPLAY.
+typedef enum _NVAPI_GSYNC_DISPLAY_SYNC_STATE
+{
+ NVAPI_GSYNC_DISPLAY_SYNC_STATE_UNSYNCED = 0,
+ NVAPI_GSYNC_DISPLAY_SYNC_STATE_SLAVE = 1,
+ NVAPI_GSYNC_DISPLAY_SYNC_STATE_MASTER = 2,
+} NVAPI_GSYNC_DISPLAY_SYNC_STATE;
+
+typedef struct _NV_GSYNC_GPU
+{
+ NvU32 version; //!< Version of the structure
+ NvPhysicalGpuHandle hPhysicalGpu; //!< GPU handle
+ NVAPI_GSYNC_GPU_TOPOLOGY_CONNECTOR connector; //!< Indicates which connector on the device the GPU is connected to.
+ NvPhysicalGpuHandle hProxyPhysicalGpu; //!< GPU through which hPhysicalGpu is connected to the Sync device (if not directly connected)
+ //!< - this is NULL otherwise
+ NvU32 isSynced : 1; //!< Whether this GPU is sync'd or not.
+ NvU32 reserved : 31; //!< Should be set to ZERO
+} NV_GSYNC_GPU;
+
+typedef struct _NV_GSYNC_DISPLAY
+{
+ NvU32 version; //!< Version of the structure
+ NvU32 displayId; //!< display identifier for displays.The GPU to which it is connected, can be retireved from NvAPI_SYS_GetPhysicalGpuFromDisplayId
+ NvU32 isMasterable : 1; //!< Can this display be the master? (Read only)
+ NvU32 reserved : 31; //!< Should be set to ZERO
+ NVAPI_GSYNC_DISPLAY_SYNC_STATE syncState; //!< Is this display slave/master
+ //!< (Retrieved with topology or set by caller for enable/disable sync)
+} NV_GSYNC_DISPLAY;
+
+#define NV_GSYNC_DISPLAY_VER MAKE_NVAPI_VERSION(NV_GSYNC_DISPLAY,1)
+#define NV_GSYNC_GPU_VER MAKE_NVAPI_VERSION(NV_GSYNC_GPU,1)
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_GetTopology
+//
+//! DESCRIPTION: This API returns the topology for the specified Sync device.
+//!
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice- The caller provides the handle for a Sync device for which the topology will be queried.
+//! \param [in, out] gsyncGpuCount- It returns number of GPUs connected to Sync device
+//! \param [in, out] gsyncGPUs- It returns info about GPUs connected to Sync device
+//! \param [in, out] gsyncDisplayCount- It returns number of active displays that belongs to Sync device
+//! \param [in, out] gsyncDisplays- It returns info about all active displays that belongs to Sync device
+//!
+//! HOW TO USE: 1) make a call to get the number of GPUs connected OR displays synced through Sync device
+//! by passing the gsyncGPUs OR gsyncDisplays as NULL respectively. Both gsyncGpuCount and gsyncDisplayCount can be retrieved in same call by passing
+//! both gsyncGPUs and gsyncDisplays as NULL
+//! On call success:
+//! 2) Allocate memory based on gsyncGpuCount(for gsyncGPUs) and/or gsyncDisplayCount(for gsyncDisplays) then make a call to populate gsyncGPUs and/or gsyncDisplays respectively.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//! \retval ::NVAPI_INSUFFICIENT_BUFFER When the actual number of GPUs/displays in the topology exceed the number of elements allocated for SyncGPUs/SyncDisplays respectively.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_GetTopology(_In_ NvGSyncDeviceHandle hNvGSyncDevice, __inout_opt NvU32 *gsyncGpuCount, __inout_ecount_part_opt(*gsyncGpuCount, *gsyncGpuCount) NV_GSYNC_GPU *gsyncGPUs,
+ __inout_opt NvU32 *gsyncDisplayCount, __inout_ecount_part_opt(*gsyncDisplayCount, *gsyncDisplayCount) NV_GSYNC_DISPLAY *gsyncDisplays);
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_SetSyncStateSettings
+//
+//! DESCRIPTION: Sets a new sync state for the displays in system.
+//!
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] gsyncDisplayCount- The number of displays in gsyncDisplays.
+//! \param [in] pGsyncDisplays- The caller provides the structure containing all displays that need to be synchronized in the system.
+//! The displays that are not part of pGsyncDisplays, will be un-synchronized.
+//! \param [in] flags- Reserved for future use.
+//!
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT If the display topology or count not valid.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//! \retval ::NVAPI_INVALID_SYNC_TOPOLOGY 1.If any mosaic grid is partial.
+//! 2.If timing(HVisible/VVisible/refreshRate) applied of any display is different.
+//! 3.If There is a across GPU mosaic grid in system and that is not a part of pGsyncDisplays.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_SetSyncStateSettings(_In_ NvU32 gsyncDisplayCount, __in_ecount(gsyncDisplayCount) NV_GSYNC_DISPLAY *pGsyncDisplays, _In_ NvU32 flags);
+
+
+//! \ingroup gsyncapi
+
+//! Source signal edge to be used for output pulse. See NV_GSYNC_CONTROL_PARAMS.
+typedef enum _NVAPI_GSYNC_POLARITY
+{
+ NVAPI_GSYNC_POLARITY_RISING_EDGE = 0,
+ NVAPI_GSYNC_POLARITY_FALLING_EDGE = 1,
+ NVAPI_GSYNC_POLARITY_BOTH_EDGES = 2,
+} NVAPI_GSYNC_POLARITY;
+
+//! Used in NV_GSYNC_CONTROL_PARAMS.
+typedef enum _NVAPI_GSYNC_VIDEO_MODE
+{
+ NVAPI_GSYNC_VIDEO_MODE_NONE = 0,
+ NVAPI_GSYNC_VIDEO_MODE_TTL = 1,
+ NVAPI_GSYNC_VIDEO_MODE_NTSCPALSECAM = 2,
+ NVAPI_GSYNC_VIDEO_MODE_HDTV = 3,
+ NVAPI_GSYNC_VIDEO_MODE_COMPOSITE = 4,
+} NVAPI_GSYNC_VIDEO_MODE;
+
+//! Used in NV_GSYNC_CONTROL_PARAMS.
+typedef enum _NVAPI_GSYNC_SYNC_SOURCE
+{
+ NVAPI_GSYNC_SYNC_SOURCE_VSYNC = 0,
+ NVAPI_GSYNC_SYNC_SOURCE_HOUSESYNC = 1,
+} NVAPI_GSYNC_SYNC_SOURCE;
+
+//! Used in NV_GSYNC_CONTROL_PARAMS.
+typedef struct _NV_GSYNC_DELAY
+{
+ NvU32 version; //!< Version of the structure
+ NvU32 numLines; //!< delay to be induced in number of horizontal lines.
+ NvU32 numPixels; //!< delay to be induced in number of pixels.
+ NvU32 maxLines; //!< maximum number of lines supported at current display mode to induce delay. Updated by NvAPI_GSync_GetControlParameters(). Read only.
+ NvU32 minPixels; //!< minimum number of pixels required at current display mode to induce delay. Updated by NvAPI_GSync_GetControlParameters(). Read only.
+} NV_GSYNC_DELAY;
+
+#define NV_GSYNC_DELAY_VER MAKE_NVAPI_VERSION(NV_GSYNC_DELAY,1)
+
+//! Used in NvAPI_GSync_GetControlParameters() and NvAPI_GSync_SetControlParameters().
+typedef struct _NV_GSYNC_CONTROL_PARAMS
+{
+ NvU32 version; //!< Version of the structure
+ NVAPI_GSYNC_POLARITY polarity; //!< Leading edge / Falling edge / both
+ NVAPI_GSYNC_VIDEO_MODE vmode; //!< None, TTL, NTSCPALSECAM, HDTV
+ NvU32 interval; //!< Number of pulses to wait between framelock signal generation
+ NVAPI_GSYNC_SYNC_SOURCE source; //!< VSync/House sync
+ NvU32 interlaceMode:1; //!< interlace mode for a Sync device
+ NvU32 reserved:31; //!< should be set zero
+ NV_GSYNC_DELAY syncSkew; //!< The time delay between the frame sync signal and the GPUs signal.
+ NV_GSYNC_DELAY startupDelay; //!< Sync start delay for master.
+} NV_GSYNC_CONTROL_PARAMS;
+
+#define NV_GSYNC_CONTROL_PARAMS_VER MAKE_NVAPI_VERSION(NV_GSYNC_CONTROL_PARAMS,1)
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_GetControlParameters
+//
+//! DESCRIPTION: This API queries for sync control parameters as defined in NV_GSYNC_CONTROL_PARAMS.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice- The caller provides the handle of the Sync device for which to get parameters
+//! \param [inout] *pGsyncControls- The caller provides the storage space. NvAPI_GSync_GetControlParameters() populates *pGsyncControls with values.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_GetControlParameters(_In_ NvGSyncDeviceHandle hNvGSyncDevice, _Inout_ NV_GSYNC_CONTROL_PARAMS *pGsyncControls);
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_SetControlParameters
+//
+//! DESCRIPTION: This API sets control parameters as defined in NV_SYNC_CONTROL_PARAMS.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice- The caller provides the handle of the Sync device for which to get parameters
+//! \param [inout] *pGsyncControls- The caller provides NV_GSYNC_CONTROL_PARAMS. skew and startDelay will be updated to the applied values.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any Sync Device.
+//! \retval ::NVAPI_SYNC_MASTER_NOT_FOUND Control Parameters can only be set if there is a Sync Master enabled on the Gsync card.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_SetControlParameters(_In_ NvGSyncDeviceHandle hNvGSyncDevice, _Inout_ NV_GSYNC_CONTROL_PARAMS *pGsyncControls);
+
+
+
+
+//! Used in NvAPI_GSync_AdjustSyncDelay()
+typedef enum _NVAPI_GSYNC_DELAY_TYPE
+{
+ NVAPI_GSYNC_DELAY_TYPE_UNKNOWN = 0,
+ NVAPI_GSYNC_DELAY_TYPE_SYNC_SKEW = 1,
+ NVAPI_GSYNC_DELAY_TYPE_STARTUP = 2
+} NVAPI_GSYNC_DELAY_TYPE;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_AdjustSyncDelay
+//
+//! DESCRIPTION: This API adjusts the skew and startDelay to the closest possible values. Use this API before calling NvAPI_GSync_SetControlParameters for skew or startDelay.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 319
+//!
+//! \param [in] hNvGSyncDevice- The caller provides the handle of the Sync device for which to get parameters
+//! \param [in] delayType- Specifies whether the delay is syncSkew or startupDelay.
+//! \param [inout] *pGsyncDelay- The caller provides NV_GSYNC_DELAY. skew and startDelay will be adjusted and updated to the closest values.
+//! \param [out] *syncSteps- This parameter is optional. It returns the sync delay in unit steps. If 0, it means either the NV_GSYNC_DELAY::numPixels is less than NV_GSYNC_DELAY::minPixels or NV_GSYNC_DELAY::numOfLines exceeds the NV_GSYNC_DELAY::maxLines.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_AdjustSyncDelay(_In_ NvGSyncDeviceHandle hNvGSyncDevice, _In_ NVAPI_GSYNC_DELAY_TYPE delayType, _Inout_ NV_GSYNC_DELAY *pGsyncDelay, _Out_opt_ NvU32* syncSteps);
+
+
+
+//! Used in NvAPI_GSync_GetSyncStatus().
+typedef struct _NV_GSYNC_STATUS
+{
+ NvU32 version; //!< Version of the structure
+ NvU32 bIsSynced; //!< Is timing in sync?
+ NvU32 bIsStereoSynced; //!< Does the phase of the timing signal from the GPU = the phase of the master sync signal?
+ NvU32 bIsSyncSignalAvailable; //!< Is the sync signal available?
+} NV_GSYNC_STATUS;
+
+//! Macro for constructing the version field for NV_GSYNC_STATUS.
+#define NV_GSYNC_STATUS_VER MAKE_NVAPI_VERSION(NV_GSYNC_STATUS,1)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_GetSyncStatus
+//
+//! DESCRIPTION: This API queries the sync status of a GPU - timing, stereosync and sync signal availability.
+//!
+//! SUPPORTED OS: Windows 7 and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice- Handle of the Sync device
+//! \param [in] hPhysicalGpu- GPU to be queried for sync status.
+//! \param [out] *status- The caller provides the storage space. NvAPI_GSync_GetSyncStatus() populates *status with
+//! values - timing, stereosync and signal availability. On error, *status is set to NULL.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL / SyncTarget is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any G-Sync Device.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_GetSyncStatus(_In_ NvGSyncDeviceHandle hNvGSyncDevice, _In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_GSYNC_STATUS *status);
+
+
+//! \ingroup gsyncapi
+
+#define NVAPI_MAX_RJ45_PER_GSYNC 2
+
+//! Used in NV_GSYNC_STATUS_PARAMS.
+typedef enum _NVAPI_GSYNC_RJ45_IO
+{
+ NVAPI_GSYNC_RJ45_OUTPUT = 0,
+ NVAPI_GSYNC_RJ45_INPUT = 1,
+ NVAPI_GSYNC_RJ45_UNUSED = 2 //!< This field is used to notify that the framelock is not actually present.
+
+} NVAPI_GSYNC_RJ45_IO;
+
+//! \ingroup gsyncapi
+//! Used in NvAPI_GSync_GetStatusParameters().
+typedef struct _NV_GSYNC_STATUS_PARAMS
+{
+ NvU32 version;
+ NvU32 refreshRate; //!< The refresh rate
+ NVAPI_GSYNC_RJ45_IO RJ45_IO[NVAPI_MAX_RJ45_PER_GSYNC]; //!< Configured as input / output
+ NvU32 RJ45_Ethernet[NVAPI_MAX_RJ45_PER_GSYNC]; //!< Connected to ethernet hub? [ERRONEOUSLY CONNECTED!]
+ NvU32 houseSyncIncoming; //!< Incoming house sync frequency in Hz
+ NvU32 bHouseSync; //!< Is house sync connected?
+} NV_GSYNC_STATUS_PARAMS;
+
+
+//! \ingroup gsyncapi
+//! Macro for constructing the version field of NV_GSYNC_STATUS_PARAMS
+#define NV_GSYNC_STATUS_PARAMS_VER MAKE_NVAPI_VERSION(NV_GSYNC_STATUS_PARAMS,1)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GSync_GetStatusParameters
+//
+//! DESCRIPTION: This API queries for sync status parameters as defined in NV_GSYNC_STATUS_PARAMS.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \since Release: 313
+//!
+//! \param [in] hNvGSyncDevice The caller provides the handle of the GSync device for which to get parameters
+//! \param [out] *pStatusParams The caller provides the storage space. NvAPI_GSync_GetStatusParameters populates *pStatusParams with
+//! values.
+//!
+//! \return This API can return any of the error codes enumerated in #NvAPI_Status.
+//! If there are return error codes with specific meaning for this API, they are listed below.
+//! \retval ::NVAPI_INVALID_ARGUMENT hNvGSyncDevice is NULL / pStatusParams is NULL.
+//! \retval ::NVAPI_NVIDIA_DEVICE_NOT_FOUND The queried Graphics system does not have any GSync Device.
+//!
+//! \ingroup gsyncapi
+///////////////////////////////////////////////////////////////////////////////
+NVAPI_INTERFACE NvAPI_GSync_GetStatusParameters(NvGSyncDeviceHandle hNvGSyncDevice, NV_GSYNC_STATUS_PARAMS *pStatusParams);
+
+//! @}
+
+//! SUPPORTED OS: Windows Vista and higher
+//!
+
+/////////////////////////////////////////////////////////////////////////
+// Video Input Output (VIO) API
+/////////////////////////////////////////////////////////////////////////
+
+//! \ingroup vidio
+//! Unique identifier for VIO owner (process identifier or NVVIOOWNERID_NONE)
+typedef NvU32 NVVIOOWNERID;
+
+
+//! \addtogroup vidio
+//! @{
+
+
+#define NVVIOOWNERID_NONE 0 //!< Unregistered ownerId
+
+
+//! Owner type for device
+typedef enum _NVVIOOWNERTYPE
+{
+ NVVIOOWNERTYPE_NONE , //!< No owner for the device
+ NVVIOOWNERTYPE_APPLICATION , //!< Application owns the device
+ NVVIOOWNERTYPE_DESKTOP , //!< Desktop transparent mode owns the device (not applicable for video input)
+}NVVIOOWNERTYPE;
+
+// Access rights for NvAPI_VIO_Open()
+
+//! Read access (not applicable for video output)
+#define NVVIO_O_READ 0x00000000
+
+//! Write exclusive access (not applicable for video input)
+#define NVVIO_O_WRITE_EXCLUSIVE 0x00010001
+
+//!
+#define NVVIO_VALID_ACCESSRIGHTS (NVVIO_O_READ | \
+ NVVIO_O_WRITE_EXCLUSIVE )
+
+
+//! VIO_DATA.ulOwnerID high-bit is set only if device has been initialized by VIOAPI
+//! examined at NvAPI_GetCapabilities|NvAPI_VIO_Open to determine if settings need to be applied from registry or POR state read
+#define NVVIO_OWNERID_INITIALIZED 0x80000000
+
+//! VIO_DATA.ulOwnerID next-bit is set only if device is currently in exclusive write access mode from NvAPI_VIO_Open()
+#define NVVIO_OWNERID_EXCLUSIVE 0x40000000
+
+//! VIO_DATA.ulOwnerID lower bits are:
+//! NVGVOOWNERTYPE_xxx enumerations indicating use context
+#define NVVIO_OWNERID_TYPEMASK 0x0FFFFFFF //!< mask for NVVIOOWNERTYPE_xxx
+
+
+//! @}
+
+//---------------------------------------------------------------------
+// Enumerations
+//---------------------------------------------------------------------
+
+
+//! \addtogroup vidio
+//! @{
+
+//! Video signal format and resolution
+typedef enum _NVVIOSIGNALFORMAT
+{
+ NVVIOSIGNALFORMAT_NONE, //!< Invalid signal format
+ NVVIOSIGNALFORMAT_487I_59_94_SMPTE259_NTSC, //!< 01 487i 59.94Hz (SMPTE259) NTSC
+ NVVIOSIGNALFORMAT_576I_50_00_SMPTE259_PAL, //!< 02 576i 50.00Hz (SMPTE259) PAL
+ NVVIOSIGNALFORMAT_1035I_60_00_SMPTE260, //!< 03 1035i 60.00Hz (SMPTE260)
+ NVVIOSIGNALFORMAT_1035I_59_94_SMPTE260, //!< 04 1035i 59.94Hz (SMPTE260)
+ NVVIOSIGNALFORMAT_1080I_50_00_SMPTE295, //!< 05 1080i 50.00Hz (SMPTE295)
+ NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274, //!< 06 1080i 60.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274, //!< 07 1080i 59.94Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274, //!< 08 1080i 50.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274, //!< 09 1080p 30.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274, //!< 10 1080p 29.97Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274, //!< 11 1080p 25.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274, //!< 12 1080p 24.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080P_23_976_SMPTE274, //!< 13 1080p 23.976Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_720P_60_00_SMPTE296, //!< 14 720p 60.00Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_59_94_SMPTE296, //!< 15 720p 59.94Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_50_00_SMPTE296, //!< 16 720p 50.00Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_1080I_48_00_SMPTE274, //!< 17 1080I 48.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080I_47_96_SMPTE274, //!< 18 1080I 47.96Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_720P_30_00_SMPTE296, //!< 19 720p 30.00Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_29_97_SMPTE296, //!< 20 720p 29.97Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_25_00_SMPTE296, //!< 21 720p 25.00Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_24_00_SMPTE296, //!< 22 720p 24.00Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_720P_23_98_SMPTE296, //!< 23 720p 23.98Hz (SMPTE296)
+ NVVIOSIGNALFORMAT_2048P_30_00_SMPTE372, //!< 24 2048p 30.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048P_29_97_SMPTE372, //!< 25 2048p 29.97Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048I_60_00_SMPTE372, //!< 26 2048i 60.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048I_59_94_SMPTE372, //!< 27 2048i 59.94Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048P_25_00_SMPTE372, //!< 28 2048p 25.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048I_50_00_SMPTE372, //!< 29 2048i 50.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048P_24_00_SMPTE372, //!< 30 2048p 24.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048P_23_98_SMPTE372, //!< 31 2048p 23.98Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048I_48_00_SMPTE372, //!< 32 2048i 48.00Hz (SMPTE372)
+ NVVIOSIGNALFORMAT_2048I_47_96_SMPTE372, //!< 33 2048i 47.96Hz (SMPTE372)
+
+ NVVIOSIGNALFORMAT_1080PSF_25_00_SMPTE274, //!< 34 1080PsF 25.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080PSF_29_97_SMPTE274, //!< 35 1080PsF 29.97Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080PSF_30_00_SMPTE274, //!< 36 1080PsF 30.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080PSF_24_00_SMPTE274, //!< 37 1080PsF 24.00Hz (SMPTE274)
+ NVVIOSIGNALFORMAT_1080PSF_23_98_SMPTE274, //!< 38 1080PsF 23.98Hz (SMPTE274)
+
+ NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_A, //!< 39 1080P 50.00Hz (SMPTE274) 3G Level A
+ NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_A, //!< 40 1080P 59.94Hz (SMPTE274) 3G Level A
+ NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_A, //!< 41 1080P 60.00Hz (SMPTE274) 3G Level A
+
+ NVVIOSIGNALFORMAT_1080P_60_00_SMPTE274_3G_LEVEL_B, //!< 42 1080p 60.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_1080I_60_00_SMPTE274_3G_LEVEL_B, //!< 43 1080i 60.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048I_60_00_SMPTE372_3G_LEVEL_B, //!< 44 2048i 60.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_50_00_SMPTE274_3G_LEVEL_B, //!< 45 1080p 50.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_1080I_50_00_SMPTE274_3G_LEVEL_B, //!< 46 1080i 50.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048I_50_00_SMPTE372_3G_LEVEL_B, //!< 47 2048i 50.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_30_00_SMPTE274_3G_LEVEL_B, //!< 48 1080p 30.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048P_30_00_SMPTE372_3G_LEVEL_B, //!< 49 2048p 30.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_25_00_SMPTE274_3G_LEVEL_B, //!< 50 1080p 25.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048P_25_00_SMPTE372_3G_LEVEL_B, //!< 51 2048p 25.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_24_00_SMPTE274_3G_LEVEL_B, //!< 52 1080p 24.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048P_24_00_SMPTE372_3G_LEVEL_B, //!< 53 2048p 24.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080I_48_00_SMPTE274_3G_LEVEL_B, //!< 54 1080i 48.00Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048I_48_00_SMPTE372_3G_LEVEL_B, //!< 55 2048i 48.00Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_59_94_SMPTE274_3G_LEVEL_B, //!< 56 1080p 59.94Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_1080I_59_94_SMPTE274_3G_LEVEL_B, //!< 57 1080i 59.94Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048I_59_94_SMPTE372_3G_LEVEL_B, //!< 58 2048i 59.94Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_29_97_SMPTE274_3G_LEVEL_B, //!< 59 1080p 29.97Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048P_29_97_SMPTE372_3G_LEVEL_B, //!< 60 2048p 29.97Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080P_23_98_SMPTE274_3G_LEVEL_B, //!< 61 1080p 29.98Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048P_23_98_SMPTE372_3G_LEVEL_B, //!< 62 2048p 29.98Hz (SMPTE372) 3G Level B
+ NVVIOSIGNALFORMAT_1080I_47_96_SMPTE274_3G_LEVEL_B, //!< 63 1080i 47.96Hz (SMPTE274) 3G Level B
+ NVVIOSIGNALFORMAT_2048I_47_96_SMPTE372_3G_LEVEL_B, //!< 64 2048i 47.96Hz (SMPTE372) 3G Level B
+
+ NVVIOSIGNALFORMAT_END //!< 65 To indicate end of signal format list
+
+}NVVIOSIGNALFORMAT;
+
+//! SMPTE standards format
+typedef enum _NVVIOVIDEOSTANDARD
+{
+ NVVIOVIDEOSTANDARD_SMPTE259 , //!< SMPTE259
+ NVVIOVIDEOSTANDARD_SMPTE260 , //!< SMPTE260
+ NVVIOVIDEOSTANDARD_SMPTE274 , //!< SMPTE274
+ NVVIOVIDEOSTANDARD_SMPTE295 , //!< SMPTE295
+ NVVIOVIDEOSTANDARD_SMPTE296 , //!< SMPTE296
+ NVVIOVIDEOSTANDARD_SMPTE372 , //!< SMPTE372
+}NVVIOVIDEOSTANDARD;
+
+//! HD or SD video type
+typedef enum _NVVIOVIDEOTYPE
+{
+ NVVIOVIDEOTYPE_SD , //!< Standard-definition (SD)
+ NVVIOVIDEOTYPE_HD , //!< High-definition (HD)
+}NVVIOVIDEOTYPE;
+
+//! Interlace mode
+typedef enum _NVVIOINTERLACEMODE
+{
+ NVVIOINTERLACEMODE_PROGRESSIVE , //!< Progressive (p)
+ NVVIOINTERLACEMODE_INTERLACE , //!< Interlace (i)
+ NVVIOINTERLACEMODE_PSF , //!< Progressive Segment Frame (psf)
+}NVVIOINTERLACEMODE;
+
+//! Video data format
+typedef enum _NVVIODATAFORMAT
+{
+ NVVIODATAFORMAT_UNKNOWN = -1 , //!< Invalid DataFormat
+ NVVIODATAFORMAT_R8G8B8_TO_YCRCB444 , //!< R8:G8:B8 => YCrCb (4:4:4)
+ NVVIODATAFORMAT_R8G8B8A8_TO_YCRCBA4444 , //!< R8:G8:B8:A8 => YCrCbA (4:4:4:4)
+ NVVIODATAFORMAT_R8G8B8Z10_TO_YCRCBZ4444 , //!< R8:G8:B8:Z10 => YCrCbZ (4:4:4:4)
+ NVVIODATAFORMAT_R8G8B8_TO_YCRCB422 , //!< R8:G8:B8 => YCrCb (4:2:2)
+ NVVIODATAFORMAT_R8G8B8A8_TO_YCRCBA4224 , //!< R8:G8:B8:A8 => YCrCbA (4:2:2:4)
+ NVVIODATAFORMAT_R8G8B8Z10_TO_YCRCBZ4224 , //!< R8:G8:B8:Z10 => YCrCbZ (4:2:2:4)
+ NVVIODATAFORMAT_X8X8X8_444_PASSTHRU , //!< R8:G8:B8 => RGB (4:4:4)
+ NVVIODATAFORMAT_X8X8X8A8_4444_PASSTHRU , //!< R8:G8:B8:A8 => RGBA (4:4:4:4)
+ NVVIODATAFORMAT_X8X8X8Z10_4444_PASSTHRU , //!< R8:G8:B8:Z10 => RGBZ (4:4:4:4)
+ NVVIODATAFORMAT_X10X10X10_444_PASSTHRU , //!< Y10:CR10:CB10 => YCrCb (4:4:4)
+ NVVIODATAFORMAT_X10X8X8_444_PASSTHRU , //!< Y10:CR8:CB8 => YCrCb (4:4:4)
+ NVVIODATAFORMAT_X10X8X8A10_4444_PASSTHRU , //!< Y10:CR8:CB8:A10 => YCrCbA (4:4:4:4)
+ NVVIODATAFORMAT_X10X8X8Z10_4444_PASSTHRU , //!< Y10:CR8:CB8:Z10 => YCrCbZ (4:4:4:4)
+ NVVIODATAFORMAT_DUAL_R8G8B8_TO_DUAL_YCRCB422 , //!< R8:G8:B8 + R8:G8:B8 => YCrCb (4:2:2 + 4:2:2)
+ NVVIODATAFORMAT_DUAL_X8X8X8_TO_DUAL_422_PASSTHRU , //!< Y8:CR8:CB8 + Y8:CR8:CB8 => YCrCb (4:2:2 + 4:2:2)
+ NVVIODATAFORMAT_R10G10B10_TO_YCRCB422 , //!< R10:G10:B10 => YCrCb (4:2:2)
+ NVVIODATAFORMAT_R10G10B10_TO_YCRCB444 , //!< R10:G10:B10 => YCrCb (4:4:4)
+ NVVIODATAFORMAT_X12X12X12_444_PASSTHRU , //!< X12:X12:X12 => XXX (4:4:4)
+ NVVIODATAFORMAT_X12X12X12_422_PASSTHRU , //!< X12:X12:X12 => XXX (4:2:2)
+ NVVIODATAFORMAT_Y10CR10CB10_TO_YCRCB422 , //!< Y10:CR10:CB10 => YCrCb (4:2:2)
+ NVVIODATAFORMAT_Y8CR8CB8_TO_YCRCB422 , //!< Y8:CR8:CB8 => YCrCb (4:2:2)
+ NVVIODATAFORMAT_Y10CR8CB8A10_TO_YCRCBA4224 , //!< Y10:CR8:CB8:A10 => YCrCbA (4:2:2:4)
+ NVVIODATAFORMAT_R10G10B10_TO_RGB444 , //!< R10:G10:B10 => RGB (4:4:4)
+ NVVIODATAFORMAT_R12G12B12_TO_YCRCB444 , //!< R12:G12:B12 => YCrCb (4:4:4)
+ NVVIODATAFORMAT_R12G12B12_TO_YCRCB422 , //!< R12:G12:B12 => YCrCb (4:2:2)
+}NVVIODATAFORMAT;
+
+//! Video output area
+typedef enum _NVVIOOUTPUTAREA
+{
+ NVVIOOUTPUTAREA_FULLSIZE , //!< Output to entire video resolution (full size)
+ NVVIOOUTPUTAREA_SAFEACTION , //!< Output to centered 90% of video resolution (safe action)
+ NVVIOOUTPUTAREA_SAFETITLE , //!< Output to centered 80% of video resolution (safe title)
+}NVVIOOUTPUTAREA;
+
+//! Synchronization source
+typedef enum _NVVIOSYNCSOURCE
+{
+ NVVIOSYNCSOURCE_SDISYNC , //!< SDI Sync (Digital input)
+ NVVIOSYNCSOURCE_COMPSYNC , //!< COMP Sync (Composite input)
+}NVVIOSYNCSOURCE;
+
+//! Composite synchronization type
+typedef enum _NVVIOCOMPSYNCTYPE
+{
+ NVVIOCOMPSYNCTYPE_AUTO , //!< Auto-detect
+ NVVIOCOMPSYNCTYPE_BILEVEL , //!< Bi-level signal
+ NVVIOCOMPSYNCTYPE_TRILEVEL , //!< Tri-level signal
+}NVVIOCOMPSYNCTYPE;
+
+//! Video input output status
+typedef enum _NVVIOINPUTOUTPUTSTATUS
+{
+ NVINPUTOUTPUTSTATUS_OFF , //!< Not in use
+ NVINPUTOUTPUTSTATUS_ERROR , //!< Error detected
+ NVINPUTOUTPUTSTATUS_SDI_SD , //!< SDI (standard-definition)
+ NVINPUTOUTPUTSTATUS_SDI_HD , //!< SDI (high-definition)
+}NVVIOINPUTOUTPUTSTATUS;
+
+//! Synchronization input status
+typedef enum _NVVIOSYNCSTATUS
+{
+ NVVIOSYNCSTATUS_OFF , //!< Sync not detected
+ NVVIOSYNCSTATUS_ERROR , //!< Error detected
+ NVVIOSYNCSTATUS_SYNCLOSS , //!< Genlock in use, format mismatch with output
+ NVVIOSYNCSTATUS_COMPOSITE , //!< Composite sync
+ NVVIOSYNCSTATUS_SDI_SD , //!< SDI sync (standard-definition)
+ NVVIOSYNCSTATUS_SDI_HD , //!< SDI sync (high-definition)
+}NVVIOSYNCSTATUS;
+
+//! Video Capture Status
+typedef enum _NVVIOCAPTURESTATUS
+{
+ NVVIOSTATUS_STOPPED , //!< Sync not detected
+ NVVIOSTATUS_RUNNING , //!< Error detected
+ NVVIOSTATUS_ERROR , //!< Genlock in use, format mismatch with output
+}NVVIOCAPTURESTATUS;
+
+//! Video Capture Status
+typedef enum _NVVIOSTATUSTYPE
+{
+ NVVIOSTATUSTYPE_IN , //!< Input Status
+ NVVIOSTATUSTYPE_OUT , //!< Output Status
+}NVVIOSTATUSTYPE;
+
+
+//! Assumption, maximum 4 SDI input and 4 SDI output cards supported on a system
+#define NVAPI_MAX_VIO_DEVICES 8
+
+//! 4 physical jacks supported on each SDI input card.
+#define NVAPI_MAX_VIO_JACKS 4
+
+
+//! Each physical jack an on SDI input card can have
+//! two "channels" in the case of "3G" VideoFormats, as specified
+//! by SMPTE 425; for non-3G VideoFormats, only the first channel within
+//! a physical jack is valid.
+#define NVAPI_MAX_VIO_CHANNELS_PER_JACK 2
+
+//! 4 Streams, 1 per physical jack
+#define NVAPI_MAX_VIO_STREAMS 4
+
+#define NVAPI_MIN_VIO_STREAMS 1
+
+//! SDI input supports a max of 2 links per stream
+#define NVAPI_MAX_VIO_LINKS_PER_STREAM 2
+
+
+#define NVAPI_MAX_FRAMELOCK_MAPPING_MODES 20
+
+//! Min number of capture images
+#define NVAPI_GVI_MIN_RAW_CAPTURE_IMAGES 1
+
+//! Max number of capture images
+#define NVAPI_GVI_MAX_RAW_CAPTURE_IMAGES 32
+
+//! Default number of capture images
+#define NVAPI_GVI_DEFAULT_RAW_CAPTURE_IMAGES 5
+
+
+
+// Data Signal notification events. These need a event handler in RM.
+// Register/Unregister and PopEvent NVAPI's are already available.
+
+//! Device configuration
+typedef enum _NVVIOCONFIGTYPE
+{
+ NVVIOCONFIGTYPE_IN , //!< Input Status
+ NVVIOCONFIGTYPE_OUT , //!< Output Status
+}NVVIOCONFIGTYPE;
+
+typedef enum _NVVIOCOLORSPACE
+{
+ NVVIOCOLORSPACE_UNKNOWN,
+ NVVIOCOLORSPACE_YCBCR,
+ NVVIOCOLORSPACE_YCBCRA,
+ NVVIOCOLORSPACE_YCBCRD,
+ NVVIOCOLORSPACE_GBR,
+ NVVIOCOLORSPACE_GBRA,
+ NVVIOCOLORSPACE_GBRD,
+} NVVIOCOLORSPACE;
+
+//! Component sampling
+typedef enum _NVVIOCOMPONENTSAMPLING
+{
+ NVVIOCOMPONENTSAMPLING_UNKNOWN,
+ NVVIOCOMPONENTSAMPLING_4444,
+ NVVIOCOMPONENTSAMPLING_4224,
+ NVVIOCOMPONENTSAMPLING_444,
+ NVVIOCOMPONENTSAMPLING_422
+} NVVIOCOMPONENTSAMPLING;
+
+typedef enum _NVVIOBITSPERCOMPONENT
+{
+ NVVIOBITSPERCOMPONENT_UNKNOWN,
+ NVVIOBITSPERCOMPONENT_8,
+ NVVIOBITSPERCOMPONENT_10,
+ NVVIOBITSPERCOMPONENT_12,
+} NVVIOBITSPERCOMPONENT;
+
+typedef enum _NVVIOLINKID
+{
+ NVVIOLINKID_UNKNOWN,
+ NVVIOLINKID_A,
+ NVVIOLINKID_B,
+ NVVIOLINKID_C,
+ NVVIOLINKID_D
+} NVVIOLINKID;
+
+
+typedef enum _NVVIOANCPARITYCOMPUTATION
+{
+ NVVIOANCPARITYCOMPUTATION_AUTO,
+ NVVIOANCPARITYCOMPUTATION_ON,
+ NVVIOANCPARITYCOMPUTATION_OFF
+} NVVIOANCPARITYCOMPUTATION;
+
+
+
+//! @}
+
+
+//---------------------------------------------------------------------
+// Structures
+//---------------------------------------------------------------------
+
+//! \addtogroup vidio
+//! @{
+
+
+//! Supports Serial Digital Interface (SDI) output
+#define NVVIOCAPS_VIDOUT_SDI 0x00000001
+
+//! Supports Internal timing source
+#define NVVIOCAPS_SYNC_INTERNAL 0x00000100
+
+//! Supports Genlock timing source
+#define NVVIOCAPS_SYNC_GENLOCK 0x00000200
+
+//! Supports Serial Digital Interface (SDI) synchronization input
+#define NVVIOCAPS_SYNCSRC_SDI 0x00001000
+
+//! Supports Composite synchronization input
+#define NVVIOCAPS_SYNCSRC_COMP 0x00002000
+
+//! Supports Desktop transparent mode
+#define NVVIOCAPS_OUTPUTMODE_DESKTOP 0x00010000
+
+//! Supports OpenGL application mode
+#define NVVIOCAPS_OUTPUTMODE_OPENGL 0x00020000
+
+//! Supports Serial Digital Interface (SDI) input
+#define NVVIOCAPS_VIDIN_SDI 0x00100000
+
+//! Supports Packed ANC
+#define NVVIOCAPS_PACKED_ANC_SUPPORTED 0x00200000
+
+//! Supports ANC audio blanking
+#define NVVIOCAPS_AUDIO_BLANKING_SUPPORTED 0x00400000
+
+//! SDI-class interface: SDI output with two genlock inputs
+#define NVVIOCLASS_SDI 0x00000001
+
+//! Device capabilities
+typedef struct _NVVIOCAPS
+{
+ NvU32 version; //!< Structure version
+ NvAPI_String adapterName; //!< Graphics adapter name
+ NvU32 adapterClass; //!< Graphics adapter classes (NVVIOCLASS_SDI mask)
+ NvU32 adapterCaps; //!< Graphics adapter capabilities (NVVIOCAPS_* mask)
+ NvU32 dipSwitch; //!< On-board DIP switch settings bits
+ NvU32 dipSwitchReserved; //!< On-board DIP switch settings reserved bits
+ NvU32 boardID; //!< Board ID
+ //! Driver version
+ struct //
+ {
+ NvU32 majorVersion; //!< Major version. For GVI, majorVersion contains MajorVersion(HIWORD) And MinorVersion(LOWORD)
+ NvU32 minorVersion; //!< Minor version. For GVI, minorVersion contains Revison(HIWORD) And Build(LOWORD)
+ } driver; //
+ //! Firmware version
+ struct
+ {
+ NvU32 majorVersion; //!< Major version. In version 2, for both GVI and GVO, majorVersion contains MajorVersion(HIWORD) And MinorVersion(LOWORD)
+ NvU32 minorVersion; //!< Minor version. In version 2, for both GVI and GVO, minorVersion contains Revison(HIWORD) And Build(LOWORD)
+ } firmWare; //
+ NVVIOOWNERID ownerId; //!< Unique identifier for owner of video output (NVVIOOWNERID_INVALID if free running)
+ NVVIOOWNERTYPE ownerType; //!< Owner type (OpenGL application or Desktop mode)
+} NVVIOCAPS;
+
+//! Macro for constructing the version field of NVVIOCAPS
+#define NVVIOCAPS_VER1 MAKE_NVAPI_VERSION(NVVIOCAPS,1)
+#define NVVIOCAPS_VER2 MAKE_NVAPI_VERSION(NVVIOCAPS,2)
+#define NVVIOCAPS_VER NVVIOCAPS_VER2
+
+//! Input channel status
+typedef struct _NVVIOCHANNELSTATUS
+{
+ NvU32 smpte352; //!< 4-byte SMPTE 352 video payload identifier
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format
+ NVVIOBITSPERCOMPONENT bitsPerComponent; //!< Bits per component
+ NVVIOCOMPONENTSAMPLING samplingFormat; //!< Sampling format
+ NVVIOCOLORSPACE colorSpace; //!< Color space
+ NVVIOLINKID linkID; //!< Link ID
+} NVVIOCHANNELSTATUS;
+
+//! Input device status
+typedef struct _NVVIOINPUTSTATUS
+{
+ NVVIOCHANNELSTATUS vidIn[NVAPI_MAX_VIO_JACKS][NVAPI_MAX_VIO_CHANNELS_PER_JACK]; //!< Video input status per channel within a jack
+ NVVIOCAPTURESTATUS captureStatus; //!< status of video capture
+} NVVIOINPUTSTATUS;
+
+//! Output device status
+typedef struct _NVVIOOUTPUTSTATUS
+{
+ NVVIOINPUTOUTPUTSTATUS vid1Out; //!< Video 1 output status
+ NVVIOINPUTOUTPUTSTATUS vid2Out; //!< Video 2 output status
+ NVVIOSYNCSTATUS sdiSyncIn; //!< SDI sync input status
+ NVVIOSYNCSTATUS compSyncIn; //!< Composite sync input status
+ NvU32 syncEnable; //!< Sync enable (TRUE if using syncSource)
+ NVVIOSYNCSOURCE syncSource; //!< Sync source
+ NVVIOSIGNALFORMAT syncFormat; //!< Sync format
+ NvU32 frameLockEnable; //!< Framelock enable flag
+ NvU32 outputVideoLocked; //!< Output locked status
+ NvU32 dataIntegrityCheckErrorCount; //!< Data integrity check error count
+ NvU32 dataIntegrityCheckEnabled; //!< Data integrity check status enabled
+ NvU32 dataIntegrityCheckFailed; //!< Data integrity check status failed
+ NvU32 uSyncSourceLocked; //!< genlocked to framelocked to ref signal
+ NvU32 uPowerOn; //!< TRUE: indicates there is sufficient power
+} NVVIOOUTPUTSTATUS;
+
+//! Video device status.
+typedef struct _NVVIOSTATUS
+{
+ NvU32 version; //!< Structure version
+ NVVIOSTATUSTYPE nvvioStatusType; //!< Input or Output status
+ union
+ {
+ NVVIOINPUTSTATUS inStatus; //!< Input device status
+ NVVIOOUTPUTSTATUS outStatus; //!< Output device status
+ }vioStatus;
+} NVVIOSTATUS;
+
+//! Macro for constructingthe version field of NVVIOSTATUS
+#define NVVIOSTATUS_VER MAKE_NVAPI_VERSION(NVVIOSTATUS,1)
+
+//! Output region
+typedef struct _NVVIOOUTPUTREGION
+{
+ NvU32 x; //!< Horizontal origin in pixels
+ NvU32 y; //!< Vertical origin in pixels
+ NvU32 width; //!< Width of region in pixels
+ NvU32 height; //!< Height of region in pixels
+} NVVIOOUTPUTREGION;
+
+//! Gamma ramp (8-bit index)
+typedef struct _NVVIOGAMMARAMP8
+{
+ NvU16 uRed[256]; //!< Red channel gamma ramp (8-bit index, 16-bit values)
+ NvU16 uGreen[256]; //!< Green channel gamma ramp (8-bit index, 16-bit values)
+ NvU16 uBlue[256]; //!< Blue channel gamma ramp (8-bit index, 16-bit values)
+} NVVIOGAMMARAMP8;
+
+//! Gamma ramp (10-bit index)
+typedef struct _NVVIOGAMMARAMP10
+{
+ NvU16 uRed[1024]; //!< Red channel gamma ramp (10-bit index, 16-bit values)
+ NvU16 uGreen[1024]; //!< Green channel gamma ramp (10-bit index, 16-bit values)
+ NvU16 uBlue[1024]; //!< Blue channel gamma ramp (10-bit index, 16-bit values)
+} NVVIOGAMMARAMP10;
+
+
+//! Sync delay
+typedef struct _NVVIOSYNCDELAY
+{
+ NvU32 version; //!< Structure version
+ NvU32 horizontalDelay; //!< Horizontal delay in pixels
+ NvU32 verticalDelay; //!< Vertical delay in lines
+} NVVIOSYNCDELAY;
+
+//! Macro for constructing the version field of NVVIOSYNCDELAY
+#define NVVIOSYNCDELAY_VER MAKE_NVAPI_VERSION(NVVIOSYNCDELAY,1)
+
+
+//! Video mode information
+typedef struct _NVVIOVIDEOMODE
+{
+ NvU32 horizontalPixels; //!< Horizontal resolution (in pixels)
+ NvU32 verticalLines; //!< Vertical resolution for frame (in lines)
+ float fFrameRate; //!< Frame rate
+ NVVIOINTERLACEMODE interlaceMode; //!< Interlace mode
+ NVVIOVIDEOSTANDARD videoStandard; //!< SMPTE standards format
+ NVVIOVIDEOTYPE videoType; //!< HD or SD signal classification
+} NVVIOVIDEOMODE;
+
+//! Signal format details
+typedef struct _NVVIOSIGNALFORMATDETAIL
+{
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format enumerated value
+ NVVIOVIDEOMODE videoMode; //!< Video mode for signal format
+}NVVIOSIGNALFORMATDETAIL;
+
+
+//! R8:G8:B8
+#define NVVIOBUFFERFORMAT_R8G8B8 0x00000001
+
+//! R8:G8:B8:Z24
+#define NVVIOBUFFERFORMAT_R8G8B8Z24 0x00000002
+
+//! R8:G8:B8:A8
+#define NVVIOBUFFERFORMAT_R8G8B8A8 0x00000004
+
+//! R8:G8:B8:A8:Z24
+#define NVVIOBUFFERFORMAT_R8G8B8A8Z24 0x00000008
+
+//! R16FP:G16FP:B16FP
+#define NVVIOBUFFERFORMAT_R16FPG16FPB16FP 0x00000010
+
+//! R16FP:G16FP:B16FP:Z24
+#define NVVIOBUFFERFORMAT_R16FPG16FPB16FPZ24 0x00000020
+
+//! R16FP:G16FP:B16FP:A16FP
+#define NVVIOBUFFERFORMAT_R16FPG16FPB16FPA16FP 0x00000040
+
+//! R16FP:G16FP:B16FP:A16FP:Z24
+#define NVVIOBUFFERFORMAT_R16FPG16FPB16FPA16FPZ24 0x00000080
+
+
+
+//! Data format details
+typedef struct _NVVIODATAFORMATDETAIL
+{
+ NVVIODATAFORMAT dataFormat; //!< Data format enumerated value
+ NvU32 vioCaps; //!< Data format capabilities (NVVIOCAPS_* mask)
+}NVVIODATAFORMATDETAIL;
+
+//! Colorspace conversion
+typedef struct _NVVIOCOLORCONVERSION
+{
+ NvU32 version; //!< Structure version
+ float colorMatrix[3][3]; //!< Output[n] =
+ float colorOffset[3]; //!< Input[0] * colorMatrix[n][0] +
+ float colorScale[3]; //!< Input[1] * colorMatrix[n][1] +
+ //!< Input[2] * colorMatrix[n][2] +
+ //!< OutputRange * colorOffset[n]
+ //!< where OutputRange is the standard magnitude of
+ //!< Output[n][n] and colorMatrix and colorOffset
+ //!< values are within the range -1.0 to +1.0
+ NvU32 compositeSafe; //!< compositeSafe constrains luminance range when using composite output
+} NVVIOCOLORCONVERSION;
+
+//! macro for constructing the version field of _NVVIOCOLORCONVERSION.
+#define NVVIOCOLORCONVERSION_VER MAKE_NVAPI_VERSION(NVVIOCOLORCONVERSION,1)
+
+//! Gamma correction
+typedef struct _NVVIOGAMMACORRECTION
+{
+ NvU32 version; //!< Structure version
+ NvU32 vioGammaCorrectionType; //!< Gamma correction type (8-bit or 10-bit)
+ //! Gamma correction:
+ union
+ {
+ NVVIOGAMMARAMP8 gammaRamp8; //!< Gamma ramp (8-bit index, 16-bit values)
+ NVVIOGAMMARAMP10 gammaRamp10; //!< Gamma ramp (10-bit index, 16-bit values)
+ }gammaRamp;
+ float fGammaValueR; //!< Red Gamma value within gamma ranges. 0.5 - 6.0
+ float fGammaValueG; //!< Green Gamma value within gamma ranges. 0.5 - 6.0
+ float fGammaValueB; //!< Blue Gamma value within gamma ranges. 0.5 - 6.0
+} NVVIOGAMMACORRECTION;
+
+//! Macro for constructing thevesion field of _NVVIOGAMMACORRECTION
+#define NVVIOGAMMACORRECTION_VER MAKE_NVAPI_VERSION(NVVIOGAMMACORRECTION,1)
+
+//! Maximum number of ranges per channel
+#define MAX_NUM_COMPOSITE_RANGE 2
+
+
+typedef struct _NVVIOCOMPOSITERANGE
+{
+ NvU32 uRange;
+ NvU32 uEnabled;
+ NvU32 uMin;
+ NvU32 uMax;
+} NVVIOCOMPOSITERANGE;
+
+
+
+// Device configuration (fields masks indicating NVVIOCONFIG fields to use for NvAPI_VIO_GetConfig/NvAPI_VIO_SetConfig() )
+//
+#define NVVIOCONFIG_SIGNALFORMAT 0x00000001 //!< fields: signalFormat
+#define NVVIOCONFIG_DATAFORMAT 0x00000002 //!< fields: dataFormat
+#define NVVIOCONFIG_OUTPUTREGION 0x00000004 //!< fields: outputRegion
+#define NVVIOCONFIG_OUTPUTAREA 0x00000008 //!< fields: outputArea
+#define NVVIOCONFIG_COLORCONVERSION 0x00000010 //!< fields: colorConversion
+#define NVVIOCONFIG_GAMMACORRECTION 0x00000020 //!< fields: gammaCorrection
+#define NVVIOCONFIG_SYNCSOURCEENABLE 0x00000040 //!< fields: syncSource and syncEnable
+#define NVVIOCONFIG_SYNCDELAY 0x00000080 //!< fields: syncDelay
+#define NVVIOCONFIG_COMPOSITESYNCTYPE 0x00000100 //!< fields: compositeSyncType
+#define NVVIOCONFIG_FRAMELOCKENABLE 0x00000200 //!< fields: EnableFramelock
+#define NVVIOCONFIG_422FILTER 0x00000400 //!< fields: bEnable422Filter
+#define NVVIOCONFIG_COMPOSITETERMINATE 0x00000800 //!< fields: bCompositeTerminate (Not supported on Quadro FX 4000 SDI)
+#define NVVIOCONFIG_DATAINTEGRITYCHECK 0x00001000 //!< fields: bEnableDataIntegrityCheck (Not supported on Quadro FX 4000 SDI)
+#define NVVIOCONFIG_CSCOVERRIDE 0x00002000 //!< fields: colorConversion override
+#define NVVIOCONFIG_FLIPQUEUELENGTH 0x00004000 //!< fields: flipqueuelength control
+#define NVVIOCONFIG_ANCTIMECODEGENERATION 0x00008000 //!< fields: bEnableANCTimeCodeGeneration
+#define NVVIOCONFIG_COMPOSITE 0x00010000 //!< fields: bEnableComposite
+#define NVVIOCONFIG_ALPHAKEYCOMPOSITE 0x00020000 //!< fields: bEnableAlphaKeyComposite
+#define NVVIOCONFIG_COMPOSITE_Y 0x00040000 //!< fields: compRange
+#define NVVIOCONFIG_COMPOSITE_CR 0x00080000 //!< fields: compRange
+#define NVVIOCONFIG_COMPOSITE_CB 0x00100000 //!< fields: compRange
+#define NVVIOCONFIG_FULL_COLOR_RANGE 0x00200000 //!< fields: bEnableFullColorRange
+#define NVVIOCONFIG_RGB_DATA 0x00400000 //!< fields: bEnableRGBData
+#define NVVIOCONFIG_RESERVED_SDIOUTPUTENABLE 0x00800000 //!< fields: bEnableSDIOutput
+#define NVVIOCONFIG_STREAMS 0x01000000 //!< fields: streams
+#define NVVIOCONFIG_ANC_PARITY_COMPUTATION 0x02000000 //!< fields: ancParityComputation
+#define NVVIOCONFIG_ANC_AUDIO_REPEAT 0x04000000 //!< fields: enableAudioBlanking
+
+
+// Don't forget to update NVVIOCONFIG_VALIDFIELDS in nvapi.spec when NVVIOCONFIG_ALLFIELDS changes.
+#define NVVIOCONFIG_ALLFIELDS ( NVVIOCONFIG_SIGNALFORMAT | \
+ NVVIOCONFIG_DATAFORMAT | \
+ NVVIOCONFIG_OUTPUTREGION | \
+ NVVIOCONFIG_OUTPUTAREA | \
+ NVVIOCONFIG_COLORCONVERSION | \
+ NVVIOCONFIG_GAMMACORRECTION | \
+ NVVIOCONFIG_SYNCSOURCEENABLE | \
+ NVVIOCONFIG_SYNCDELAY | \
+ NVVIOCONFIG_COMPOSITESYNCTYPE | \
+ NVVIOCONFIG_FRAMELOCKENABLE | \
+ NVVIOCONFIG_422FILTER | \
+ NVVIOCONFIG_COMPOSITETERMINATE | \
+ NVVIOCONFIG_DATAINTEGRITYCHECK | \
+ NVVIOCONFIG_CSCOVERRIDE | \
+ NVVIOCONFIG_FLIPQUEUELENGTH | \
+ NVVIOCONFIG_ANCTIMECODEGENERATION | \
+ NVVIOCONFIG_COMPOSITE | \
+ NVVIOCONFIG_ALPHAKEYCOMPOSITE | \
+ NVVIOCONFIG_COMPOSITE_Y | \
+ NVVIOCONFIG_COMPOSITE_CR | \
+ NVVIOCONFIG_COMPOSITE_CB | \
+ NVVIOCONFIG_FULL_COLOR_RANGE | \
+ NVVIOCONFIG_RGB_DATA | \
+ NVVIOCONFIG_RESERVED_SDIOUTPUTENABLE | \
+ NVVIOCONFIG_STREAMS | \
+ NVVIOCONFIG_ANC_PARITY_COMPUTATION | \
+ NVVIOCONFIG_ANC_AUDIO_REPEAT )
+
+#define NVVIOCONFIG_VALIDFIELDS ( NVVIOCONFIG_SIGNALFORMAT | \
+ NVVIOCONFIG_DATAFORMAT | \
+ NVVIOCONFIG_OUTPUTREGION | \
+ NVVIOCONFIG_OUTPUTAREA | \
+ NVVIOCONFIG_COLORCONVERSION | \
+ NVVIOCONFIG_GAMMACORRECTION | \
+ NVVIOCONFIG_SYNCSOURCEENABLE | \
+ NVVIOCONFIG_SYNCDELAY | \
+ NVVIOCONFIG_COMPOSITESYNCTYPE | \
+ NVVIOCONFIG_FRAMELOCKENABLE | \
+ NVVIOCONFIG_RESERVED_SDIOUTPUTENABLE | \
+ NVVIOCONFIG_422FILTER | \
+ NVVIOCONFIG_COMPOSITETERMINATE | \
+ NVVIOCONFIG_DATAINTEGRITYCHECK | \
+ NVVIOCONFIG_CSCOVERRIDE | \
+ NVVIOCONFIG_FLIPQUEUELENGTH | \
+ NVVIOCONFIG_ANCTIMECODEGENERATION | \
+ NVVIOCONFIG_COMPOSITE | \
+ NVVIOCONFIG_ALPHAKEYCOMPOSITE | \
+ NVVIOCONFIG_COMPOSITE_Y | \
+ NVVIOCONFIG_COMPOSITE_CR | \
+ NVVIOCONFIG_COMPOSITE_CB | \
+ NVVIOCONFIG_FULL_COLOR_RANGE | \
+ NVVIOCONFIG_RGB_DATA | \
+ NVVIOCONFIG_RESERVED_SDIOUTPUTENABLE | \
+ NVVIOCONFIG_STREAMS | \
+ NVVIOCONFIG_ANC_PARITY_COMPUTATION | \
+ NVVIOCONFIG_ANC_AUDIO_REPEAT)
+
+#define NVVIOCONFIG_DRIVERFIELDS ( NVVIOCONFIG_OUTPUTREGION | \
+ NVVIOCONFIG_OUTPUTAREA | \
+ NVVIOCONFIG_COLORCONVERSION | \
+ NVVIOCONFIG_FLIPQUEUELENGTH)
+
+#define NVVIOCONFIG_GAMMAFIELDS ( NVVIOCONFIG_GAMMACORRECTION )
+
+#define NVVIOCONFIG_RMCTRLFIELDS ( NVVIOCONFIG_SIGNALFORMAT | \
+ NVVIOCONFIG_DATAFORMAT | \
+ NVVIOCONFIG_SYNCSOURCEENABLE | \
+ NVVIOCONFIG_COMPOSITESYNCTYPE | \
+ NVVIOCONFIG_FRAMELOCKENABLE | \
+ NVVIOCONFIG_422FILTER | \
+ NVVIOCONFIG_COMPOSITETERMINATE | \
+ NVVIOCONFIG_DATAINTEGRITYCHECK | \
+ NVVIOCONFIG_COMPOSITE | \
+ NVVIOCONFIG_ALPHAKEYCOMPOSITE | \
+ NVVIOCONFIG_COMPOSITE_Y | \
+ NVVIOCONFIG_COMPOSITE_CR | \
+ NVVIOCONFIG_COMPOSITE_CB)
+
+#define NVVIOCONFIG_RMSKEWFIELDS ( NVVIOCONFIG_SYNCDELAY )
+
+#define NVVIOCONFIG_ALLOWSDIRUNNING_FIELDS ( NVVIOCONFIG_DATAINTEGRITYCHECK | \
+ NVVIOCONFIG_SYNCDELAY | \
+ NVVIOCONFIG_CSCOVERRIDE | \
+ NVVIOCONFIG_ANCTIMECODEGENERATION | \
+ NVVIOCONFIG_COMPOSITE | \
+ NVVIOCONFIG_ALPHAKEYCOMPOSITE | \
+ NVVIOCONFIG_COMPOSITE_Y | \
+ NVVIOCONFIG_COMPOSITE_CR | \
+ NVVIOCONFIG_COMPOSITE_CB | \
+ NVVIOCONFIG_ANC_PARITY_COMPUTATION)
+
+
+ #define NVVIOCONFIG_RMMODESET_FIELDS ( NVVIOCONFIG_SIGNALFORMAT | \
+ NVVIOCONFIG_DATAFORMAT | \
+ NVVIOCONFIG_SYNCSOURCEENABLE | \
+ NVVIOCONFIG_FRAMELOCKENABLE | \
+ NVVIOCONFIG_COMPOSITESYNCTYPE | \
+ NVVIOCONFIG_ANC_AUDIO_REPEAT)
+
+
+//! Output device configuration
+// No members can be deleted from below structure. Only add new members at the
+// end of the structure.
+typedef struct _NVVIOOUTPUTCONFIG_V1
+{
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format for video output
+ NVVIODATAFORMAT dataFormat; //!< Data format for video output
+ NVVIOOUTPUTREGION outputRegion; //!< Region for video output (Desktop mode)
+ NVVIOOUTPUTAREA outputArea; //!< Usable resolution for video output (safe area)
+ NVVIOCOLORCONVERSION colorConversion; //!< Color conversion.
+ NVVIOGAMMACORRECTION gammaCorrection;
+ NvU32 syncEnable; //!< Sync enable (TRUE to use syncSource)
+ NVVIOSYNCSOURCE syncSource; //!< Sync source
+ NVVIOSYNCDELAY syncDelay; //!< Sync delay
+ NVVIOCOMPSYNCTYPE compositeSyncType; //!< Composite sync type
+ NvU32 frameLockEnable; //!< Flag indicating whether framelock was on/off
+ NvU32 psfSignalFormat; //!< Indicates whether contained format is PSF Signal format
+ NvU32 enable422Filter; //!< Enables/Disables 4:2:2 filter
+ NvU32 compositeTerminate; //!< Composite termination
+ NvU32 enableDataIntegrityCheck; //!< Enable data integrity check: true - enable, false - disable
+ NvU32 cscOverride; //!< Use provided CSC color matrix to overwrite
+ NvU32 flipQueueLength; //!< Number of buffers used for the internal flipqueue
+ NvU32 enableANCTimeCodeGeneration; //!< Enable SDI ANC time code generation
+ NvU32 enableComposite; //!< Enable composite
+ NvU32 enableAlphaKeyComposite; //!< Enable Alpha key composite
+ NVVIOCOMPOSITERANGE compRange; //!< Composite ranges
+ NvU8 reservedData[256]; //!< Inicates last stored SDI output state TRUE-ON / FALSE-OFF
+ NvU32 enableFullColorRange; //!< Flag indicating Full Color Range
+ NvU32 enableRGBData; //!< Indicates data is in RGB format
+} NVVIOOUTPUTCONFIG_V1;
+
+typedef struct _NVVIOOUTPUTCONFIG_V2
+{
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format for video output
+ NVVIODATAFORMAT dataFormat; //!< Data format for video output
+ NVVIOOUTPUTREGION outputRegion; //!< Region for video output (Desktop mode)
+ NVVIOOUTPUTAREA outputArea; //!< Usable resolution for video output (safe area)
+ NVVIOCOLORCONVERSION colorConversion; //!< Color conversion.
+ NVVIOGAMMACORRECTION gammaCorrection;
+ NvU32 syncEnable; //!< Sync enable (TRUE to use syncSource)
+ NVVIOSYNCSOURCE syncSource; //!< Sync source
+ NVVIOSYNCDELAY syncDelay; //!< Sync delay
+ NVVIOCOMPSYNCTYPE compositeSyncType; //!< Composite sync type
+ NvU32 frameLockEnable; //!< Flag indicating whether framelock was on/off
+ NvU32 psfSignalFormat; //!< Indicates whether contained format is PSF Signal format
+ NvU32 enable422Filter; //!< Enables/Disables 4:2:2 filter
+ NvU32 compositeTerminate; //!< Composite termination
+ NvU32 enableDataIntegrityCheck; //!< Enable data integrity check: true - enable, false - disable
+ NvU32 cscOverride; //!< Use provided CSC color matrix to overwrite
+ NvU32 flipQueueLength; //!< Number of buffers used for the internal flip queue
+ NvU32 enableANCTimeCodeGeneration; //!< Enable SDI ANC time code generation
+ NvU32 enableComposite; //!< Enable composite
+ NvU32 enableAlphaKeyComposite; //!< Enable Alpha key composite
+ NVVIOCOMPOSITERANGE compRange; //!< Composite ranges
+ NvU8 reservedData[256]; //!< Indicates last stored SDI output state TRUE-ON / FALSE-OFF
+ NvU32 enableFullColorRange; //!< Flag indicating Full Color Range
+ NvU32 enableRGBData; //!< Indicates data is in RGB format
+ NVVIOANCPARITYCOMPUTATION ancParityComputation; //!< Enable HW ANC parity bit computation (auto/on/off)
+} NVVIOOUTPUTCONFIG_V2;
+
+typedef struct _NVVIOOUTPUTCONFIG_V3
+{
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format for video output
+ NVVIODATAFORMAT dataFormat; //!< Data format for video output
+ NVVIOOUTPUTREGION outputRegion; //!< Region for video output (Desktop mode)
+ NVVIOOUTPUTAREA outputArea; //!< Usable resolution for video output (safe area)
+ NVVIOCOLORCONVERSION colorConversion; //!< Color conversion.
+ NVVIOGAMMACORRECTION gammaCorrection;
+ NvU32 syncEnable; //!< Sync enable (TRUE to use syncSource)
+ NVVIOSYNCSOURCE syncSource; //!< Sync source
+ NVVIOSYNCDELAY syncDelay; //!< Sync delay
+ NVVIOCOMPSYNCTYPE compositeSyncType; //!< Composite sync type
+ NvU32 frameLockEnable; //!< Flag indicating whether framelock was on/off
+ NvU32 psfSignalFormat; //!< Indicates whether contained format is PSF Signal format
+ NvU32 enable422Filter; //!< Enables/Disables 4:2:2 filter
+ NvU32 compositeTerminate; //!< Composite termination
+ NvU32 enableDataIntegrityCheck; //!< Enable data integrity check: true - enable, false - disable
+ NvU32 cscOverride; //!< Use provided CSC color matrix to overwrite
+ NvU32 flipQueueLength; //!< Number of buffers used for the internal flip queue
+ NvU32 enableANCTimeCodeGeneration; //!< Enable SDI ANC time code generation
+ NvU32 enableComposite; //!< Enable composite
+ NvU32 enableAlphaKeyComposite; //!< Enable Alpha key composite
+ NVVIOCOMPOSITERANGE compRange; //!< Composite ranges
+ NvU8 reservedData[256]; //!< Indicates last stored SDI output state TRUE-ON / FALSE-OFF
+ NvU32 enableFullColorRange; //!< Flag indicating Full Color Range
+ NvU32 enableRGBData; //!< Indicates data is in RGB format
+ NVVIOANCPARITYCOMPUTATION ancParityComputation; //!< Enable HW ANC parity bit computation (auto/on/off)
+ NvU32 enableAudioBlanking; //!< Enable HANC audio blanking on repeat frames
+} NVVIOOUTPUTCONFIG_V3;
+
+//! Stream configuration
+typedef struct _NVVIOSTREAM
+{
+ NvU32 bitsPerComponent; //!< Bits per component
+ NVVIOCOMPONENTSAMPLING sampling; //!< Sampling
+ NvU32 expansionEnable; //!< Enable/disable 4:2:2->4:4:4 expansion
+ NvU32 numLinks; //!< Number of active links
+ struct
+ {
+ NvU32 jack; //!< This stream's link[i] will use the specified (0-based) channel within the
+ NvU32 channel; //!< specified (0-based) jack
+ } links[NVAPI_MAX_VIO_LINKS_PER_STREAM];
+} NVVIOSTREAM;
+
+//! Input device configuration
+typedef struct _NVVIOINPUTCONFIG
+{
+ NvU32 numRawCaptureImages; //!< numRawCaptureImages is the number of frames to keep in the capture queue.
+ //!< must be between NVAPI_GVI_MIN_RAW_CAPTURE_IMAGES and NVAPI_GVI_MAX_RAW_CAPTURE_IMAGES,
+ NVVIOSIGNALFORMAT signalFormat; //!< Signal format.
+ //!< Please note that both numRawCaptureImages and signalFormat should be set together.
+ NvU32 numStreams; //!< Number of active streams.
+ NVVIOSTREAM streams[NVAPI_MAX_VIO_STREAMS]; //!< Stream configurations
+ NvU32 bTestMode; //!< This attribute controls the GVI test mode.
+ //!< Possible values 0/1. When testmode enabled, the
+ //!< GVI device will generate fake data as quickly as possible.
+} NVVIOINPUTCONFIG;
+
+typedef struct _NVVIOCONFIG_V1
+{
+ NvU32 version; //!< Structure version
+ NvU32 fields; //!< Caller sets to NVVIOCONFIG_* mask for fields to use
+ NVVIOCONFIGTYPE nvvioConfigType; //!< Input or Output configuration
+ union
+ {
+ NVVIOINPUTCONFIG inConfig; //!< Input device configuration
+ NVVIOOUTPUTCONFIG_V1 outConfig; //!< Output device configuration
+ }vioConfig;
+} NVVIOCONFIG_V1;
+
+
+typedef struct _NVVIOCONFIG_V2
+{
+ NvU32 version; //!< Structure version
+ NvU32 fields; //!< Caller sets to NVVIOCONFIG_* mask for fields to use
+ NVVIOCONFIGTYPE nvvioConfigType; //!< Input or Output configuration
+ union
+ {
+ NVVIOINPUTCONFIG inConfig; //!< Input device configuration
+ NVVIOOUTPUTCONFIG_V2 outConfig; //!< Output device configuration
+ }vioConfig;
+} NVVIOCONFIG_V2;
+
+typedef struct _NVVIOCONFIG_V3
+{
+ NvU32 version; //!< Structure version
+ NvU32 fields; //!< Caller sets to NVVIOCONFIG_* mask for fields to use
+ NVVIOCONFIGTYPE nvvioConfigType; //!< Input or Output configuration
+ union
+ {
+ NVVIOINPUTCONFIG inConfig; //!< Input device configuration
+ NVVIOOUTPUTCONFIG_V3 outConfig; //!< Output device configuration
+ }vioConfig;
+} NVVIOCONFIG_V3;
+typedef NVVIOOUTPUTCONFIG_V3 NVVIOOUTPUTCONFIG;
+typedef NVVIOCONFIG_V3 NVVIOCONFIG;
+
+#define NVVIOCONFIG_VER1 MAKE_NVAPI_VERSION(NVVIOCONFIG_V1,1)
+#define NVVIOCONFIG_VER2 MAKE_NVAPI_VERSION(NVVIOCONFIG_V2,2)
+#define NVVIOCONFIG_VER3 MAKE_NVAPI_VERSION(NVVIOCONFIG_V3,3)
+#define NVVIOCONFIG_VER NVVIOCONFIG_VER3
+
+
+typedef struct
+{
+ NvPhysicalGpuHandle hPhysicalGpu; //!< Handle to Physical GPU (This could be NULL for GVI device if its not binded)
+ NvVioHandle hVioHandle; //!
+
+#endif // _NVAPI_H
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/nvapi/nvapi_lite_common.h b/plugins-extra/NvGpuPlugin/nvapi/nvapi_lite_common.h
new file mode 100644
index 0000000..a6e6bc2
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/nvapi/nvapi_lite_common.h
@@ -0,0 +1,429 @@
+#pragma once
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER) && (_MSC_VER > 1399) && !defined(NVAPI_INTERNAL) && !defined(NVAPI_DEPRECATED_OLD)
+#ifndef __nvapi_deprecated_function
+#define __nvapi_deprecated_function(message) __declspec(deprecated(message))
+#endif
+#ifndef __nvapi_deprecated_datatype
+#define __nvapi_deprecated_datatype(FirstRelease) __declspec(deprecated("Do not use this data type - it is deprecated in release " #FirstRelease "."))
+#endif
+#else
+#ifndef __nvapi_deprecated_function
+#define __nvapi_deprecated_function(message)
+#endif
+#ifndef __nvapi_deprecated_datatype
+#define __nvapi_deprecated_datatype(FirstRelease)
+#endif
+#endif
+
+/* 64-bit types for compilers that support them, plus some obsolete variants */
+#if defined(__GNUC__) || defined(__arm) || defined(__IAR_SYSTEMS_ICC__) || defined(__ghs__) || defined(_WIN64)
+typedef unsigned long long NvU64; /* 0 to 18446744073709551615 */
+typedef long long NvS64; /* -9223372036854775808 to 9223372036854775807 */
+#else
+typedef unsigned __int64 NvU64; /* 0 to 18446744073709551615 */
+typedef __int64 NvS64; /* -9223372036854775808 to 9223372036854775807 */
+#endif
+
+// mac os 32-bit still needs this
+#if (defined(macintosh) || defined(__APPLE__)) && !defined(__LP64__)
+typedef signed long NvS32; /* -2147483648 to 2147483647 */
+#else
+typedef signed int NvS32; /* -2147483648 to 2147483647 */
+#endif
+
+// mac os 32-bit still needs this
+#if ( (defined(macintosh) && defined(__LP64__) && (__NVAPI_RESERVED0__)) || (!defined(macintosh) && defined(__NVAPI_RESERVED0__)) )
+typedef unsigned int NvU32; /* 0 to 4294967295 */
+#else
+typedef unsigned long NvU32; /* 0 to 4294967295 */
+#endif
+
+typedef signed short NvS16;
+typedef unsigned short NvU16;
+typedef unsigned char NvU8;
+typedef signed char NvS8;
+
+typedef struct _NV_RECT
+{
+ NvU32 left;
+ NvU32 top;
+ NvU32 right;
+ NvU32 bottom;
+} NV_RECT;
+
+#define NVAPI_INTERFACE extern __success(return == NVAPI_OK) NvAPI_Status __cdecl
+
+#define NV_DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
+
+//! \addtogroup nvapihandles
+//! NVAPI Handles - These handles are retrieved from various calls and passed in to others in NvAPI
+//! These are meant to be opaque types. Do not assume they correspond to indices, HDCs,
+//! display indexes or anything else.
+//!
+//! Most handles remain valid until a display re-configuration (display mode set) or GPU
+//! reconfiguration (going into or out of SLI modes) occurs. If NVAPI_HANDLE_INVALIDATED
+//! is received by an app, it should discard all handles, and re-enumerate them.
+//! @{
+NV_DECLARE_HANDLE(NvDisplayHandle); //!< Display Device driven by NVIDIA GPU(s) (an attached display)
+NV_DECLARE_HANDLE(NvMonitorHandle); //!< Monitor handle
+NV_DECLARE_HANDLE(NvUnAttachedDisplayHandle); //!< Unattached Display Device driven by NVIDIA GPU(s)
+NV_DECLARE_HANDLE(NvLogicalGpuHandle); //!< One or more physical GPUs acting in concert (SLI)
+NV_DECLARE_HANDLE(NvPhysicalGpuHandle); //!< A single physical GPU
+NV_DECLARE_HANDLE(NvEventHandle); //!< A handle to an event registration instance
+NV_DECLARE_HANDLE(NvVisualComputingDeviceHandle); //!< A handle to a Visual Computing Device
+NV_DECLARE_HANDLE(NvHICHandle); //!< A handle to a Host Interface Card
+NV_DECLARE_HANDLE(NvGSyncDeviceHandle); //!< A handle to a Sync device
+NV_DECLARE_HANDLE(NvVioHandle); //!< A handle to an SDI device
+NV_DECLARE_HANDLE(NvTransitionHandle); //!< A handle to address a single transition request
+NV_DECLARE_HANDLE(NvAudioHandle); //!< NVIDIA HD Audio Device
+NV_DECLARE_HANDLE(Nv3DVPContextHandle); //!< A handle for a 3D Vision Pro (3DVP) context
+NV_DECLARE_HANDLE(Nv3DVPTransceiverHandle); //!< A handle for a 3DVP RF transceiver
+NV_DECLARE_HANDLE(Nv3DVPGlassesHandle); //!< A handle for a pair of 3DVP RF shutter glasses
+NV_DECLARE_HANDLE(NvSourceHandle); //!< Unique source handle on the system
+NV_DECLARE_HANDLE(NvTargetHandle); //!< Unique target handle on the system
+//! @}
+
+//! \ingroup nvapihandles
+//! @{
+#define NVAPI_DEFAULT_HANDLE 0
+#define NV_BIT(x) (1 << (x))
+//! @}
+
+//! \addtogroup nvapitypes
+//! @{
+#define NVAPI_GENERIC_STRING_MAX 4096
+#define NVAPI_LONG_STRING_MAX 256
+#define NVAPI_SHORT_STRING_MAX 64
+
+typedef struct _NvSBox
+{
+ NvS32 sX;
+ NvS32 sY;
+ NvS32 sWidth;
+ NvS32 sHeight;
+} NvSBox;
+
+#ifndef NvGUID_Defined
+#define NvGUID_Defined
+
+typedef struct _NvGUID
+{
+ NvU32 data1;
+ NvU16 data2;
+ NvU16 data3;
+ NvU8 data4[8];
+} NvGUID, NvLUID;
+
+#endif //#ifndef NvGUID_Defined
+
+#define NVAPI_MAX_PHYSICAL_GPUS 64
+#define NVAPI_MAX_PHYSICAL_BRIDGES 100
+#define NVAPI_PHYSICAL_GPUS 32
+#define NVAPI_MAX_LOGICAL_GPUS 64
+#define NVAPI_MAX_AVAILABLE_GPU_TOPOLOGIES 256
+#define NVAPI_MAX_AVAILABLE_SLI_GROUPS 256
+#define NVAPI_MAX_GPU_TOPOLOGIES NVAPI_MAX_PHYSICAL_GPUS
+#define NVAPI_MAX_GPU_PER_TOPOLOGY 8
+#define NVAPI_MAX_DISPLAY_HEADS 2
+#define NVAPI_ADVANCED_DISPLAY_HEADS 4
+#define NVAPI_MAX_DISPLAYS NVAPI_PHYSICAL_GPUS * NVAPI_ADVANCED_DISPLAY_HEADS
+#define NVAPI_MAX_ACPI_IDS 16
+#define NVAPI_MAX_VIEW_MODES 8
+#define NV_MAX_HEADS 4 //!< Maximum heads, each with NVAPI_DESKTOP_RES resolution
+#define NVAPI_MAX_HEADS_PER_GPU 32
+
+#define NV_MAX_HEADS 4 //!< Maximum number of heads, each with #NVAPI_DESKTOP_RES resolution
+#define NV_MAX_VID_STREAMS 4 //!< Maximum number of input video streams, each with a #NVAPI_VIDEO_SRC_INFO
+#define NV_MAX_VID_PROFILES 4 //!< Maximum number of output video profiles supported
+
+#define NVAPI_SYSTEM_MAX_DISPLAYS NVAPI_MAX_PHYSICAL_GPUS * NV_MAX_HEADS
+
+#define NVAPI_SYSTEM_MAX_HWBCS 128
+#define NVAPI_SYSTEM_HWBC_INVALID_ID 0xffffffff
+#define NVAPI_MAX_AUDIO_DEVICES 16
+
+
+typedef char NvAPI_String[NVAPI_GENERIC_STRING_MAX];
+typedef char NvAPI_LongString[NVAPI_LONG_STRING_MAX];
+typedef char NvAPI_ShortString[NVAPI_SHORT_STRING_MAX];
+//! @}
+
+
+// =========================================================================================
+//! NvAPI Version Definition \n
+//! Maintain per structure specific version define using the MAKE_NVAPI_VERSION macro. \n
+//! Usage: #define NV_GENLOCK_STATUS_VER MAKE_NVAPI_VERSION(NV_GENLOCK_STATUS, 1)
+//! \ingroup nvapitypes
+// =========================================================================================
+#define MAKE_NVAPI_VERSION(typeName,ver) (NvU32)(sizeof(typeName) | ((ver) << 16))
+
+//! \ingroup nvapitypes
+#define GET_NVAPI_VERSION(ver) (NvU32)((ver)>>16)
+
+//! \ingroup nvapitypes
+#define GET_NVAPI_SIZE(ver) (NvU32)((ver) & 0xffff)
+
+
+// ====================================================
+//! NvAPI Status Values
+//! All NvAPI functions return one of these codes.
+//! \ingroup nvapistatus
+// ====================================================
+
+typedef enum _NvAPI_Status
+{
+ NVAPI_OK = 0, //!< Success. Request is completed.
+ NVAPI_ERROR = -1, //!< Generic error
+ NVAPI_LIBRARY_NOT_FOUND = -2, //!< NVAPI support library cannot be loaded.
+ NVAPI_NO_IMPLEMENTATION = -3, //!< not implemented in current driver installation
+ NVAPI_API_NOT_INITIALIZED = -4, //!< NvAPI_Initialize has not been called (successfully)
+ NVAPI_INVALID_ARGUMENT = -5, //!< The argument/parameter value is not valid or NULL.
+ NVAPI_NVIDIA_DEVICE_NOT_FOUND = -6, //!< No NVIDIA display driver, or NVIDIA GPU driving a display, was found.
+ NVAPI_END_ENUMERATION = -7, //!< No more items to enumerate
+ NVAPI_INVALID_HANDLE = -8, //!< Invalid handle
+ NVAPI_INCOMPATIBLE_STRUCT_VERSION = -9, //!< An argument's structure version is not supported
+ NVAPI_HANDLE_INVALIDATED = -10, //!< The handle is no longer valid (likely due to GPU or display re-configuration)
+ NVAPI_OPENGL_CONTEXT_NOT_CURRENT = -11, //!< No NVIDIA OpenGL context is current (but needs to be)
+ NVAPI_INVALID_POINTER = -14, //!< An invalid pointer, usually NULL, was passed as a parameter
+ NVAPI_NO_GL_EXPERT = -12, //!< OpenGL Expert is not supported by the current drivers
+ NVAPI_INSTRUMENTATION_DISABLED = -13, //!< OpenGL Expert is supported, but driver instrumentation is currently disabled
+ NVAPI_NO_GL_NSIGHT = -15, //!< OpenGL does not support Nsight
+
+ NVAPI_EXPECTED_LOGICAL_GPU_HANDLE = -100, //!< Expected a logical GPU handle for one or more parameters
+ NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE = -101, //!< Expected a physical GPU handle for one or more parameters
+ NVAPI_EXPECTED_DISPLAY_HANDLE = -102, //!< Expected an NV display handle for one or more parameters
+ NVAPI_INVALID_COMBINATION = -103, //!< The combination of parameters is not valid.
+ NVAPI_NOT_SUPPORTED = -104, //!< Requested feature is not supported in the selected GPU
+ NVAPI_PORTID_NOT_FOUND = -105, //!< No port ID was found for the I2C transaction
+ NVAPI_EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106, //!< Expected an unattached display handle as one of the input parameters.
+ NVAPI_INVALID_PERF_LEVEL = -107, //!< Invalid perf level
+ NVAPI_DEVICE_BUSY = -108, //!< Device is busy; request not fulfilled
+ NVAPI_NV_PERSIST_FILE_NOT_FOUND = -109, //!< NV persist file is not found
+ NVAPI_PERSIST_DATA_NOT_FOUND = -110, //!< NV persist data is not found
+ NVAPI_EXPECTED_TV_DISPLAY = -111, //!< Expected a TV output display
+ NVAPI_EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112, //!< Expected a TV output on the D Connector - HDTV_EIAJ4120.
+ NVAPI_NO_ACTIVE_SLI_TOPOLOGY = -113, //!< SLI is not active on this device.
+ NVAPI_SLI_RENDERING_MODE_NOTALLOWED = -114, //!< Setup of SLI rendering mode is not possible right now.
+ NVAPI_EXPECTED_DIGITAL_FLAT_PANEL = -115, //!< Expected a digital flat panel.
+ NVAPI_ARGUMENT_EXCEED_MAX_SIZE = -116, //!< Argument exceeds the expected size.
+ NVAPI_DEVICE_SWITCHING_NOT_ALLOWED = -117, //!< Inhibit is ON due to one of the flags in NV_GPU_DISPLAY_CHANGE_INHIBIT or SLI active.
+ NVAPI_TESTING_CLOCKS_NOT_SUPPORTED = -118, //!< Testing of clocks is not supported.
+ NVAPI_UNKNOWN_UNDERSCAN_CONFIG = -119, //!< The specified underscan config is from an unknown source (e.g. INF)
+ NVAPI_TIMEOUT_RECONFIGURING_GPU_TOPO = -120, //!< Timeout while reconfiguring GPUs
+ NVAPI_DATA_NOT_FOUND = -121, //!< Requested data was not found
+ NVAPI_EXPECTED_ANALOG_DISPLAY = -122, //!< Expected an analog display
+ NVAPI_NO_VIDLINK = -123, //!< No SLI video bridge is present
+ NVAPI_REQUIRES_REBOOT = -124, //!< NVAPI requires a reboot for the settings to take effect
+ NVAPI_INVALID_HYBRID_MODE = -125, //!< The function is not supported with the current Hybrid mode.
+ NVAPI_MIXED_TARGET_TYPES = -126, //!< The target types are not all the same
+ NVAPI_SYSWOW64_NOT_SUPPORTED = -127, //!< The function is not supported from 32-bit on a 64-bit system.
+ NVAPI_IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128, //!< There is no implicit GPU topology active. Use NVAPI_SetHybridMode to change topology.
+ NVAPI_REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129, //!< Prompt the user to close all non-migratable applications.
+ NVAPI_OUT_OF_MEMORY = -130, //!< Could not allocate sufficient memory to complete the call.
+ NVAPI_WAS_STILL_DRAWING = -131, //!< The previous operation that is transferring information to or from this surface is incomplete.
+ NVAPI_FILE_NOT_FOUND = -132, //!< The file was not found.
+ NVAPI_TOO_MANY_UNIQUE_STATE_OBJECTS = -133, //!< There are too many unique instances of a particular type of state object.
+ NVAPI_INVALID_CALL = -134, //!< The method call is invalid. For example, a method's parameter may not be a valid pointer.
+ NVAPI_D3D10_1_LIBRARY_NOT_FOUND = -135, //!< d3d10_1.dll cannot be loaded.
+ NVAPI_FUNCTION_NOT_FOUND = -136, //!< Couldn't find the function in the loaded DLL.
+ NVAPI_INVALID_USER_PRIVILEGE = -137, //!< Current User is not Admin.
+ NVAPI_EXPECTED_NON_PRIMARY_DISPLAY_HANDLE = -138, //!< The handle corresponds to GDIPrimary.
+ NVAPI_EXPECTED_COMPUTE_GPU_HANDLE = -139, //!< Setting Physx GPU requires that the GPU is compute-capable.
+ NVAPI_STEREO_NOT_INITIALIZED = -140, //!< The Stereo part of NVAPI failed to initialize completely. Check if the stereo driver is installed.
+ NVAPI_STEREO_REGISTRY_ACCESS_FAILED = -141, //!< Access to stereo-related registry keys or values has failed.
+ NVAPI_STEREO_REGISTRY_PROFILE_TYPE_NOT_SUPPORTED = -142, //!< The given registry profile type is not supported.
+ NVAPI_STEREO_REGISTRY_VALUE_NOT_SUPPORTED = -143, //!< The given registry value is not supported.
+ NVAPI_STEREO_NOT_ENABLED = -144, //!< Stereo is not enabled and the function needed it to execute completely.
+ NVAPI_STEREO_NOT_TURNED_ON = -145, //!< Stereo is not turned on and the function needed it to execute completely.
+ NVAPI_STEREO_INVALID_DEVICE_INTERFACE = -146, //!< Invalid device interface.
+ NVAPI_STEREO_PARAMETER_OUT_OF_RANGE = -147, //!< Separation percentage or JPEG image capture quality is out of [0-100] range.
+ NVAPI_STEREO_FRUSTUM_ADJUST_MODE_NOT_SUPPORTED = -148, //!< The given frustum adjust mode is not supported.
+ NVAPI_TOPO_NOT_POSSIBLE = -149, //!< The mosaic topology is not possible given the current state of the hardware.
+ NVAPI_MODE_CHANGE_FAILED = -150, //!< An attempt to do a display resolution mode change has failed.
+ NVAPI_D3D11_LIBRARY_NOT_FOUND = -151, //!< d3d11.dll/d3d11_beta.dll cannot be loaded.
+ NVAPI_INVALID_ADDRESS = -152, //!< Address is outside of valid range.
+ NVAPI_STRING_TOO_SMALL = -153, //!< The pre-allocated string is too small to hold the result.
+ NVAPI_MATCHING_DEVICE_NOT_FOUND = -154, //!< The input does not match any of the available devices.
+ NVAPI_DRIVER_RUNNING = -155, //!< Driver is running.
+ NVAPI_DRIVER_NOTRUNNING = -156, //!< Driver is not running.
+ NVAPI_ERROR_DRIVER_RELOAD_REQUIRED = -157, //!< A driver reload is required to apply these settings.
+ NVAPI_SET_NOT_ALLOWED = -158, //!< Intended setting is not allowed.
+ NVAPI_ADVANCED_DISPLAY_TOPOLOGY_REQUIRED = -159, //!< Information can't be returned due to "advanced display topology".
+ NVAPI_SETTING_NOT_FOUND = -160, //!< Setting is not found.
+ NVAPI_SETTING_SIZE_TOO_LARGE = -161, //!< Setting size is too large.
+ NVAPI_TOO_MANY_SETTINGS_IN_PROFILE = -162, //!< There are too many settings for a profile.
+ NVAPI_PROFILE_NOT_FOUND = -163, //!< Profile is not found.
+ NVAPI_PROFILE_NAME_IN_USE = -164, //!< Profile name is duplicated.
+ NVAPI_PROFILE_NAME_EMPTY = -165, //!< Profile name is empty.
+ NVAPI_EXECUTABLE_NOT_FOUND = -166, //!< Application not found in the Profile.
+ NVAPI_EXECUTABLE_ALREADY_IN_USE = -167, //!< Application already exists in the other profile.
+ NVAPI_DATATYPE_MISMATCH = -168, //!< Data Type mismatch
+ NVAPI_PROFILE_REMOVED = -169, //!< The profile passed as parameter has been removed and is no longer valid.
+ NVAPI_UNREGISTERED_RESOURCE = -170, //!< An unregistered resource was passed as a parameter.
+ NVAPI_ID_OUT_OF_RANGE = -171, //!< The DisplayId corresponds to a display which is not within the normal outputId range.
+ NVAPI_DISPLAYCONFIG_VALIDATION_FAILED = -172, //!< Display topology is not valid so the driver cannot do a mode set on this configuration.
+ NVAPI_DPMST_CHANGED = -173, //!< Display Port Multi-Stream topology has been changed.
+ NVAPI_INSUFFICIENT_BUFFER = -174, //!< Input buffer is insufficient to hold the contents.
+ NVAPI_ACCESS_DENIED = -175, //!< No access to the caller.
+ NVAPI_MOSAIC_NOT_ACTIVE = -176, //!< The requested action cannot be performed without Mosaic being enabled.
+ NVAPI_SHARE_RESOURCE_RELOCATED = -177, //!< The surface is relocated away from video memory.
+ NVAPI_REQUEST_USER_TO_DISABLE_DWM = -178, //!< The user should disable DWM before calling NvAPI.
+ NVAPI_D3D_DEVICE_LOST = -179, //!< D3D device status is D3DERR_DEVICELOST or D3DERR_DEVICENOTRESET - the user has to reset the device.
+ NVAPI_INVALID_CONFIGURATION = -180, //!< The requested action cannot be performed in the current state.
+ NVAPI_STEREO_HANDSHAKE_NOT_DONE = -181, //!< Call failed as stereo handshake not completed.
+ NVAPI_EXECUTABLE_PATH_IS_AMBIGUOUS = -182, //!< The path provided was too short to determine the correct NVDRS_APPLICATION
+ NVAPI_DEFAULT_STEREO_PROFILE_IS_NOT_DEFINED = -183, //!< Default stereo profile is not currently defined
+ NVAPI_DEFAULT_STEREO_PROFILE_DOES_NOT_EXIST = -184, //!< Default stereo profile does not exist
+ NVAPI_CLUSTER_ALREADY_EXISTS = -185, //!< A cluster is already defined with the given configuration.
+ NVAPI_DPMST_DISPLAY_ID_EXPECTED = -186, //!< The input display id is not that of a multi stream enabled connector or a display device in a multi stream topology
+ NVAPI_INVALID_DISPLAY_ID = -187, //!< The input display id is not valid or the monitor associated to it does not support the current operation
+ NVAPI_STREAM_IS_OUT_OF_SYNC = -188, //!< While playing secure audio stream, stream goes out of sync
+ NVAPI_INCOMPATIBLE_AUDIO_DRIVER = -189, //!< Older audio driver version than required
+ NVAPI_VALUE_ALREADY_SET = -190, //!< Value already set, setting again not allowed.
+ NVAPI_TIMEOUT = -191, //!< Requested operation timed out
+ NVAPI_GPU_WORKSTATION_FEATURE_INCOMPLETE = -192, //!< The requested workstation feature set has incomplete driver internal allocation resources
+ NVAPI_STEREO_INIT_ACTIVATION_NOT_DONE = -193, //!< Call failed because InitActivation was not called.
+ NVAPI_SYNC_NOT_ACTIVE = -194, //!< The requested action cannot be performed without Sync being enabled.
+ NVAPI_SYNC_MASTER_NOT_FOUND = -195, //!< The requested action cannot be performed without Sync Master being enabled.
+ NVAPI_INVALID_SYNC_TOPOLOGY = -196, //!< Invalid displays passed in the NV_GSYNC_DISPLAY pointer.
+ NVAPI_ECID_SIGN_ALGO_UNSUPPORTED = -197, //!< The specified signing algorithm is not supported. Either an incorrect value was entered or the current installed driver/hardware does not support the input value.
+ NVAPI_ECID_KEY_VERIFICATION_FAILED = -198, //!< The encrypted public key verification has failed.
+} NvAPI_Status;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_SYS_GetDriverAndBranchVersion
+//
+//! DESCRIPTION: This API returns display driver version and driver-branch string.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! \param [out] pDriverVersion Contains the driver version after successful return.
+//! \param [out] szBuildBranchString Contains the driver-branch string after successful return.
+//!
+//! \retval ::NVAPI_INVALID_ARGUMENT: either pDriverVersion is NULL or enum index too big
+//! \retval ::NVAPI_OK - completed request
+//! \retval ::NVAPI_API_NOT_INTIALIZED - NVAPI not initialized
+//! \retval ::NVAPI_ERROR - miscellaneous error occurred
+//!
+//! \ingroup driverapi
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_SYS_GetDriverAndBranchVersion)(_Out_ NvU32* pDriverVersion, _Out_ NvAPI_ShortString szBuildBranchString);
+_NvAPI_SYS_GetDriverAndBranchVersion NvAPI_SYS_GetDriverAndBranchVersion;
+
+
+//! \ingroup driverapi
+//! Used in NvAPI_GPU_GetMemoryInfo().
+typedef struct _NV_DISPLAY_DRIVER_MEMORY_INFO_V1
+{
+ NvU32 version; //!< Version info
+ NvU32 dedicatedVideoMemory; //!< Size(in kb) of the physical framebuffer.
+ NvU32 availableDedicatedVideoMemory; //!< Size(in kb) of the available physical framebuffer for allocating video memory surfaces.
+ NvU32 systemVideoMemory; //!< Size(in kb) of system memory the driver allocates at load time.
+ NvU32 sharedSystemMemory; //!< Size(in kb) of shared system memory that driver is allowed to commit for surfaces across all allocations.
+} NV_DISPLAY_DRIVER_MEMORY_INFO_V1;
+
+
+//! \ingroup driverapi
+//! Used in NvAPI_GPU_GetMemoryInfo().
+typedef struct _NV_DISPLAY_DRIVER_MEMORY_INFO_V2
+{
+ NvU32 version; //!< Version info
+ NvU32 dedicatedVideoMemory; //!< Size(in kb) of the physical framebuffer.
+ NvU32 availableDedicatedVideoMemory; //!< Size(in kb) of the available physical framebuffer for allocating video memory surfaces.
+ NvU32 systemVideoMemory; //!< Size(in kb) of system memory the driver allocates at load time.
+ NvU32 sharedSystemMemory; //!< Size(in kb) of shared system memory that driver is allowed to commit for surfaces across all allocations.
+ NvU32 curAvailableDedicatedVideoMemory; //!< Size(in kb) of the current available physical framebuffer for allocating video memory surfaces.
+} NV_DISPLAY_DRIVER_MEMORY_INFO_V2;
+
+
+//! \ingroup driverapi
+typedef NV_DISPLAY_DRIVER_MEMORY_INFO_V2 NV_DISPLAY_DRIVER_MEMORY_INFO;
+
+//! \ingroup driverapi
+//! Macro for constructing the version field of NV_DISPLAY_DRIVER_MEMORY_INFO_V1
+#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1 MAKE_NVAPI_VERSION(NV_DISPLAY_DRIVER_MEMORY_INFO_V1, 1)
+
+//! \ingroup driverapi
+//! Macro for constructing the version field of NV_DISPLAY_DRIVER_MEMORY_INFO_V2
+#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2 MAKE_NVAPI_VERSION(NV_DISPLAY_DRIVER_MEMORY_INFO_V2, 2)
+
+//! \ingroup driverapi
+#define NV_DISPLAY_DRIVER_MEMORY_INFO_VER NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetMemoryInfo
+//
+//! DESCRIPTION: This function retrieves the available driver memory footprint for the specified GPU.
+//!
+//! SUPPORTED OS: Windows XP and higher
+//!
+//!
+//! TCC_SUPPORTED
+//!
+//! \since Release: 177
+//!
+//! \param [in] hPhysicalGpu Handle of the physical GPU for which the memory information is to be extracted.
+//! \param [out] pMemoryInfo The memory footprint available in the driver. See NV_DISPLAY_DRIVER_MEMORY_INFO.
+//!
+//! \retval NVAPI_INVALID_ARGUMENT pMemoryInfo is NULL.
+//! \retval NVAPI_OK Call successful.
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found.
+//! \retval NVAPI_INCOMPATIBLE_STRUCT_VERSION NV_DISPLAY_DRIVER_MEMORY_INFO structure version mismatch.
+//!
+//! \ingroup driverapi
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetMemoryInfo)(NvDisplayHandle hNvDisplay, NV_DISPLAY_DRIVER_MEMORY_INFO *pMemoryInfo);
+_NvAPI_GPU_GetMemoryInfo NvAPI_GPU_GetMemoryInfo;
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_EnumPhysicalGPUs
+//
+//! This function returns an array of physical GPU handles.
+//! Each handle represents a physical GPU present in the system.
+//! That GPU may be part of an SLI configuration, or may not be visible to the OS directly.
+//!
+//! At least one GPU must be present in the system and running an NVIDIA display driver.
+//!
+//! The array nvGPUHandle will be filled with physical GPU handle values. The returned
+//! gpuCount determines how many entries in the array are valid.
+//!
+//! \note In drivers older than 105.00, all physical GPU handles get invalidated on a
+//! modeset. So the calling applications need to renum the handles after every modeset.\n
+//! With drivers 105.00 and up, all physical GPU handles are constant.
+//! Physical GPU handles are constant as long as the GPUs are not physically moved and
+//! the SBIOS VGA order is unchanged.
+//!
+//! For GPU handles in TCC MODE please use NvAPI_EnumTCCPhysicalGPUs()
+//!
+//! SUPPORTED OS: Windows XP and higher, Mac OS X
+//!
+//!
+//! \par Introduced in
+//! \since Release: 80
+//!
+//! \retval NVAPI_INVALID_ARGUMENT nvGPUHandle or pGpuCount is NULL
+//! \retval NVAPI_OK One or more handles were returned
+//! \retval NVAPI_NVIDIA_DEVICE_NOT_FOUND No NVIDIA GPU driving a display was found
+//! \ingroup gpu
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_EnumPhysicalGPUs)(NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS], NvU32* pGpuCount);
+_NvAPI_EnumPhysicalGPUs NvAPI_EnumPhysicalGPUs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#include
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/nvgpu.c b/plugins-extra/NvGpuPlugin/nvgpu.c
new file mode 100644
index 0000000..ad38456
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/nvgpu.c
@@ -0,0 +1,61 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2016 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 "main.h"
+
+PH_CIRCULAR_BUFFER_FLOAT GpuUtilizationHistory;
+PH_CIRCULAR_BUFFER_ULONG GpuMemoryHistory;
+PH_CIRCULAR_BUFFER_FLOAT GpuBoardHistory;
+PH_CIRCULAR_BUFFER_FLOAT GpuBusHistory;
+
+VOID NvGpuInitialize(
+ VOID
+ )
+{
+ ULONG sampleCount;
+
+ sampleCount = PhGetIntegerSetting(L"SampleCount");
+
+ PhInitializeCircularBuffer_FLOAT(&GpuUtilizationHistory, sampleCount);
+ PhInitializeCircularBuffer_ULONG(&GpuMemoryHistory, sampleCount);
+ PhInitializeCircularBuffer_FLOAT(&GpuBoardHistory, sampleCount);
+ PhInitializeCircularBuffer_FLOAT(&GpuBusHistory, sampleCount);
+}
+
+VOID NvGpuUpdate(
+ VOID
+ )
+{
+ static ULONG runCount = 0; // MUST keep in sync with runCount in process provider
+
+ if (runCount != 0)
+ {
+ NvGpuUpdateValues();
+
+ PhAddItemCircularBuffer_FLOAT(&GpuUtilizationHistory, GpuCurrentGpuUsage);
+ PhAddItemCircularBuffer_ULONG(&GpuMemoryHistory, GpuCurrentMemUsage);
+ PhAddItemCircularBuffer_FLOAT(&GpuBoardHistory, GpuCurrentCoreUsage);
+ PhAddItemCircularBuffer_FLOAT(&GpuBusHistory, GpuCurrentBusUsage);
+ }
+
+ runCount++;
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/nvidia.c b/plugins-extra/NvGpuPlugin/nvidia.c
new file mode 100644
index 0000000..ad27001
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/nvidia.c
@@ -0,0 +1,1018 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 .
+ */
+
+#define INITGUID
+#include "main.h"
+#include "nvapi\nvapi.h"
+#include "nvidia.h"
+
+#pragma comment(lib, "Setupapi.lib")
+#include
+#include
+#include
+
+static PVOID NvApiLibrary = NULL;
+static PPH_LIST NvGpuPhysicalHandleList = NULL;
+static PPH_LIST NvGpuDisplayHandleList = NULL;
+static NvU32 GpuArchType = 0;
+
+ULONG GpuMemoryLimit = 0;
+FLOAT GpuCurrentGpuUsage = 0.0f;
+FLOAT GpuCurrentCoreUsage = 0.0f;
+FLOAT GpuCurrentBusUsage = 0.0f;
+ULONG GpuCurrentMemUsage = 0;
+ULONG GpuCurrentMemSharedUsage = 0;
+ULONG GpuCurrentCoreTemp = 0;
+ULONG GpuCurrentBoardTemp = 0;
+ULONG GpuCurrentCoreClock = 0;
+ULONG GpuCurrentMemoryClock = 0;
+ULONG GpuCurrentShaderClock = 0;
+ULONG GpuCurrentVoltage = 0;
+//NVAPI_GPU_PERF_DECREASE GpuPerfDecreaseReason = NV_GPU_PERF_DECREASE_NONE;
+
+VOID NvGpuEnumPhysicalHandles(VOID)
+{
+ NvU32 gpuCount = 0;
+ NvPhysicalGpuHandle gpuHandles[NVAPI_MAX_PHYSICAL_GPUS];
+
+ memset(gpuHandles, 0, sizeof(gpuHandles));
+
+ if (NvAPI_EnumPhysicalGPUs && NvAPI_EnumPhysicalGPUs(gpuHandles, &gpuCount) == NVAPI_OK)
+ {
+ PhAddItemsList(NvGpuPhysicalHandleList, gpuHandles, gpuCount);
+ }
+}
+
+VOID NvGpuEnumDisplayHandles(VOID)
+{
+ if (!NvAPI_EnumNvidiaDisplayHandle)
+ return;
+
+ for (NvU32 i = 0; i < NVAPI_MAX_DISPLAYS; i++)
+ {
+ NvDisplayHandle displayHandle;
+
+ if (NvAPI_EnumNvidiaDisplayHandle(i, &displayHandle) == NVAPI_END_ENUMERATION)
+ {
+ break;
+ }
+
+ PhAddItemList(NvGpuDisplayHandleList, displayHandle);
+ }
+}
+
+BOOLEAN InitializeNvApi(VOID)
+{
+ NvGpuPhysicalHandleList = PhCreateList(1);
+ NvGpuDisplayHandleList = PhCreateList(1);
+
+#ifdef _M_IX86
+ if (!(NvApiLibrary = LoadLibrary(L"nvapi.dll")))
+ return FALSE;
+#else
+ if (!(NvApiLibrary = LoadLibrary(L"nvapi64.dll")))
+ return FALSE;
+#endif
+
+ // Retrieve the NvAPI_QueryInterface function address
+ if (!(NvAPI_QueryInterface = PhGetProcedureAddress(NvApiLibrary, "nvapi_QueryInterface", 0)))
+ return FALSE;
+
+ // Initialization functions
+ if (!(NvAPI_Initialize = NvAPI_QueryInterface(0x150E828UL)))
+ return FALSE;
+ if (!(NvAPI_Unload = NvAPI_QueryInterface(0xD22BDD7EUL)))
+ return FALSE;
+
+ // Error functions
+ if (!(NvAPI_GetErrorMessage = NvAPI_QueryInterface(0x6C2D048CUL)))
+ return FALSE;
+
+ // Handle functions
+ if (!(NvAPI_EnumPhysicalGPUs = NvAPI_QueryInterface(0xE5AC921FUL)))
+ return FALSE;
+ if (!(NvAPI_EnumNvidiaDisplayHandle = NvAPI_QueryInterface(0x9ABDD40DUL)))
+ return FALSE;
+
+ // Information functions
+ NvAPI_SYS_GetDriverAndBranchVersion = NvAPI_QueryInterface(0x2926AAADUL);
+ NvAPI_GPU_GetFullName = NvAPI_QueryInterface(0xCEEE8E9FUL);
+
+ // Query functions
+ NvAPI_GPU_GetMemoryInfo = NvAPI_QueryInterface(0x774AA982UL);
+ NvAPI_GPU_GetThermalSettings = NvAPI_QueryInterface(0xE3640A56UL);
+ NvAPI_GPU_GetCoolerSettings = NvAPI_QueryInterface(0xDA141340UL);
+ NvAPI_GPU_GetPerfDecreaseInfo = NvAPI_QueryInterface(0x7F7F4600UL);
+ NvAPI_GPU_GetTachReading = NvAPI_QueryInterface(0x5F608315UL);
+ NvAPI_GPU_GetAllClockFrequencies = NvAPI_QueryInterface(0xDCB616C3UL);
+
+ // Undocumented Query functions
+ NvAPI_GPU_GetUsages = NvAPI_QueryInterface(0x189A1FDFUL);
+ NvAPI_GPU_GetAllClocks = NvAPI_QueryInterface(0x1BD69F49UL);
+ NvAPI_GPU_GetVoltageDomainsStatus = NvAPI_QueryInterface(0xC16C7E2CUL);
+
+ //NvAPI_GPU_GetPerfClocks = NvAPI_QueryInterface(0x1EA54A3B);
+ //NvAPI_GPU_GetVoltages = NvAPI_QueryInterface(0x7D656244);
+ //NvAPI_GPU_QueryActiveApps = NvAPI_QueryInterface(0x65B1C5F5);
+ //NvAPI_GPU_GetShaderPipeCount = NvAPI_QueryInterface(0x63E2F56F);
+ //NvAPI_GPU_GetShaderSubPipeCount = NvAPI_QueryInterface(0x0BE17923);
+ NvAPI_GPU_GetRamBusWidth = NvAPI_QueryInterface(0x7975C581); // ADD ME
+ NvAPI_GPU_GetRamBankCount = NvAPI_QueryInterface(0x17073A3CUL);
+ NvAPI_GPU_GetRamType = NvAPI_QueryInterface(0x57F7CAACUL);
+ NvAPI_GPU_GetRamMaker = NvAPI_QueryInterface(0x42AEA16AUL);
+ NvAPI_GPU_GetFoundry = NvAPI_QueryInterface(0x5D857A00UL);
+
+
+ //NvAPI_GetDisplayDriverMemoryInfo = NvAPI_QueryInterface(0x774AA982);
+ //NvAPI_GetPhysicalGPUsFromDisplay = NvAPI_QueryInterface(0x34EF9506);
+ NvAPI_GetDisplayDriverVersion = NvAPI_QueryInterface(0xF951A4D1UL);
+ NvAPI_GetDisplayDriverRegistryPath = NvAPI_QueryInterface(0x0E24CEEEUL);
+ //NvAPI_RestartDisplayDriver = NvAPI_QueryInterface(0xB4B26B65UL);
+
+ //NvAPI_GPU_GetBoardInfo = NvAPI_QueryInterface(0x22D54523);
+ //NvAPI_GPU_GetBusType = NvAPI_QueryInterface(0x1BB18724);
+ //NvAPI_GPU_GetIRQ = NvAPI_QueryInterface(0xE4715417);
+
+ NvAPI_GPU_GetVbiosVersionString = NvAPI_QueryInterface(0xA561FD7DUL);
+ NvAPI_GPU_GetShortName = NvAPI_QueryInterface(0xD988F0F3UL);
+ NvAPI_GPU_GetArchInfo = NvAPI_QueryInterface(0xD8265D24UL);
+ NvAPI_GPU_GetPCIIdentifiers = NvAPI_QueryInterface(0x2DDFB66EUL);
+ NvAPI_GPU_GetPartitionCount = NvAPI_QueryInterface(0x86F05D7AUL);
+ NvAPI_GPU_GetGpuCoreCount = NvAPI_QueryInterface(0xC7026A87UL);
+ NvAPI_GPU_GetPCIEInfo = NvAPI_QueryInterface(0xE3795199UL);
+ NvAPI_GPU_GetFBWidthAndLocation = NvAPI_QueryInterface(0x11104158UL);
+ NvAPI_GPU_ClientPowerTopologyGetStatus = NvAPI_QueryInterface(0x0EDCF624EUL);
+
+ typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverBuildTitle)(_In_ NvDisplayHandle hNvDisplay, NvAPI_ShortString pDriverBuildTitle);
+ _NvAPI_GetDisplayDriverBuildTitle NvAPI_GetDisplayDriverBuildTitle;
+ NvAPI_GetDisplayDriverBuildTitle = NvAPI_QueryInterface(0x7562E947);
+
+ typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverCompileType)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverCompileType);
+ _NvAPI_GetDisplayDriverCompileType NvAPI_GetDisplayDriverCompileType;
+ NvAPI_GetDisplayDriverCompileType = NvAPI_QueryInterface(0x988AEA78);
+
+ typedef NvAPI_Status(__cdecl *_NvAPI_GetDisplayDriverSecurityLevel)(_In_ NvDisplayHandle hNvDisplay, NvU32* pDriverSecurityLevel);
+ _NvAPI_GetDisplayDriverSecurityLevel NvAPI_GetDisplayDriverSecurityLevel;
+ NvAPI_GetDisplayDriverSecurityLevel = NvAPI_QueryInterface(0x9D772BBA);
+
+ typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVPECount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pVPECount);
+ _NvAPI_GPU_GetVPECount NvAPI_GPU_GetVPECount;
+ NvAPI_GPU_GetVPECount = NvAPI_QueryInterface(0xD8CBF37B);
+
+ //typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetExtendedMinorRevision)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBankCount);
+ //_NvAPI_GPU_GetExtendedMinorRevision NvAPI_GPU_GetExtendedMinorRevision;
+ //NvAPI_GPU_GetExtendedMinorRevision = NvAPI_QueryInterface(0x025F17421);
+
+ //typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetSerialNumber)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount);
+ //_NvAPI_GPU_GetSerialNumber NvAPI_GPU_GetSerialNumber;
+ //NvAPI_GPU_GetSerialNumber = NvAPI_QueryInterface(0x14B83A5F);
+
+ typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetTargetID)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PBYTE pRamBankCount);
+ _NvAPI_GPU_GetTargetID NvAPI_GPU_GetTargetID;
+ NvAPI_GPU_GetTargetID = NvAPI_QueryInterface(0x35B5FD2F);
+
+ if (NvAPI_Initialize() == NVAPI_OK)
+ {
+ NvGpuEnumPhysicalHandles();
+ NvGpuEnumDisplayHandles();
+
+ BYTE buffer[260] = { 0 };
+ NvAPI_Status status = NvAPI_GPU_GetTargetID(
+ NvGpuPhysicalHandleList->Items[0],
+ buffer
+ );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN DestroyNvApi(VOID)
+{
+ NvApiInitialized = FALSE;
+
+ if (NvGpuDisplayHandleList)
+ {
+ //PhClearList(NvGpuDisplayHandleList);
+ PhDereferenceObject(NvGpuDisplayHandleList);
+ }
+
+ if (NvGpuPhysicalHandleList)
+ {
+ //PhClearList(NvGpuPhysicalHandleList);
+ PhDereferenceObject(NvGpuPhysicalHandleList);
+ }
+
+ if (NvAPI_Unload)
+ NvAPI_Unload();
+
+ if (NvApiLibrary)
+ FreeLibrary(NvApiLibrary);
+
+ return TRUE;
+}
+
+PPH_STRING NvGpuQueryDriverVersion(VOID)
+{
+ if (NvAPI_SYS_GetDriverAndBranchVersion)
+ {
+ NvU32 driverVersion = 0;
+ NvAPI_ShortString driverAndBranchString = "";
+
+ if (NvAPI_SYS_GetDriverAndBranchVersion(&driverVersion, driverAndBranchString) == NVAPI_OK)
+ {
+ return PhFormatString(
+ L"%lu.%lu [%hs]",
+ driverVersion / 100,
+ driverVersion % 100,
+ driverAndBranchString
+ );
+ }
+ }
+
+ if (NvAPI_GetDisplayDriverVersion)
+ {
+ NV_DISPLAY_DRIVER_VERSION nvDisplayDriverVersion = { NV_DISPLAY_DRIVER_VERSION_VER };
+
+ if (NvAPI_GetDisplayDriverVersion(NvGpuDisplayHandleList->Items[0], &nvDisplayDriverVersion) == NVAPI_OK)
+ {
+ return PhFormatString(
+ L"%lu.%lu [%hs]",
+ nvDisplayDriverVersion.drvVersion / 100,
+ nvDisplayDriverVersion.drvVersion % 100,
+ nvDisplayDriverVersion.szBuildBranchString
+ );
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryVbiosVersionString(VOID)
+{
+ if (NvAPI_GPU_GetVbiosVersionString)
+ {
+ NvAPI_ShortString biosRevision = "";
+
+ if (NvAPI_GPU_GetVbiosVersionString(NvGpuPhysicalHandleList->Items[0], biosRevision) == NVAPI_OK)
+ {
+ return PhConvertMultiByteToUtf16(biosRevision);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryName(VOID)
+{
+ if (NvAPI_GPU_GetFullName)
+ {
+ NvAPI_ShortString nvNameAnsiString = "";
+
+ if (NvAPI_GPU_GetFullName(NvGpuPhysicalHandleList->Items[0], nvNameAnsiString) == NVAPI_OK)
+ {
+ return PhConvertMultiByteToUtf16(nvNameAnsiString);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryShortName(VOID)
+{
+ if (NvAPI_GPU_GetShortName)
+ {
+ NvAPI_ShortString nvShortNameAnsiString = "";
+
+ if (NvAPI_GPU_GetShortName(NvGpuPhysicalHandleList->Items[0], nvShortNameAnsiString) == NVAPI_OK)
+ {
+ return PhConvertMultiByteToUtf16(nvShortNameAnsiString);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryRevision(VOID)
+{
+ if (NvAPI_GPU_GetArchInfo)
+ {
+ NV_ARCH_INFO nvArchInfo = { NV_ARCH_INFO_VER };
+
+ if (NvAPI_GPU_GetArchInfo(NvGpuPhysicalHandleList->Items[0], &nvArchInfo) == NVAPI_OK)
+ {
+ GpuArchType = nvArchInfo.unknown[0];
+
+ return PhFormatString(L"%02X", nvArchInfo.unknown[2]);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryRamType(VOID)
+{
+ PPH_STRING ramTypeString = NULL;
+ PPH_STRING ramMakerString = NULL;
+ NV_RAM_TYPE nvRamType = NV_RAM_TYPE_NONE;
+ NV_RAM_MAKER nvRamMaker = NV_RAM_MAKER_NONE;
+
+ if (NvAPI_GPU_GetRamType)
+ {
+ NvAPI_GPU_GetRamType(NvGpuPhysicalHandleList->Items[0], &nvRamType);
+ }
+
+ if (NvAPI_GPU_GetRamMaker)
+ {
+ NvAPI_GPU_GetRamMaker(NvGpuPhysicalHandleList->Items[0], &nvRamMaker);
+ }
+
+ switch (nvRamType)
+ {
+ case NV_RAM_TYPE_SDRAM:
+ ramTypeString = PhaCreateString(L"SDRAM");
+ break;
+ case NV_RAM_TYPE_DDR1:
+ ramTypeString = PhaCreateString(L"DDR1");
+ break;
+ case NV_RAM_TYPE_DDR2:
+ ramTypeString = PhaCreateString(L"DDR2");
+ break;
+ case NV_RAM_TYPE_GDDR2:
+ ramTypeString = PhaCreateString(L"GDDR2");
+ break;
+ case NV_RAM_TYPE_GDDR3:
+ ramTypeString = PhaCreateString(L"GDDR3");
+ break;
+ case NV_RAM_TYPE_GDDR4:
+ ramTypeString = PhaCreateString(L"GDDR4");
+ break;
+ case NV_RAM_TYPE_DDR3:
+ ramTypeString = PhaCreateString(L"DDR3");
+ break;
+ case NV_RAM_TYPE_GDDR5:
+ ramTypeString = PhaCreateString(L"GDDR5");
+ break;
+ case NV_RAM_TYPE_LPDDR2:
+ ramTypeString = PhaCreateString(L"LPDDR2");
+ break;
+ default:
+ ramTypeString = PhaFormatString(L"Unknown: %lu", nvRamType);
+ break;
+ }
+
+ switch (nvRamMaker)
+ {
+ case NV_RAM_MAKER_SAMSUNG:
+ ramMakerString = PhaCreateString(L"Samsung");
+ break;
+ case NV_RAM_MAKER_QIMONDA:
+ ramMakerString = PhaCreateString(L"Qimonda");
+ break;
+ case NV_RAM_MAKER_ELPIDA:
+ ramMakerString = PhaCreateString(L"Elpida");
+ break;
+ case NV_RAM_MAKER_ETRON:
+ ramMakerString = PhaCreateString(L"Etron");
+ break;
+ case NV_RAM_MAKER_NANYA:
+ ramMakerString = PhaCreateString(L"Nanya");
+ break;
+ case NV_RAM_MAKER_HYNIX:
+ ramMakerString = PhaCreateString(L"Hynix");
+ break;
+ case NV_RAM_MAKER_MOSEL:
+ ramMakerString = PhaCreateString(L"Mosel");
+ break;
+ case NV_RAM_MAKER_WINBOND:
+ ramMakerString = PhaCreateString(L"Winbond");
+ break;
+ case NV_RAM_MAKER_ELITE:
+ ramMakerString = PhaCreateString(L"Elite");
+ break;
+ case NV_RAM_MAKER_MICRON:
+ ramMakerString = PhaCreateString(L"Micron");
+ break;
+ default:
+ ramMakerString = PhaFormatString(L"Unknown: %lu", nvRamMaker);
+ break;
+ }
+
+ return PhFormatString(L"%s (%s)", ramTypeString->Buffer, ramMakerString->Buffer);
+}
+
+PPH_STRING NvGpuQueryFoundry(VOID)
+{
+ if (NvAPI_GPU_GetFoundry)
+ {
+ NV_FOUNDRY nvFoundryType = NV_FOUNDRY_NONE;
+
+ if (NvAPI_GPU_GetFoundry(NvGpuPhysicalHandleList->Items[0], &nvFoundryType) == NVAPI_OK)
+ {
+ switch (nvFoundryType)
+ {
+ case NV_FOUNDRY_TSMC:
+ return PhCreateString(L"Taiwan Semiconductor Manufacturing Company (TSMC)");
+ case NV_FOUNDRY_UMC:
+ return PhCreateString(L"United Microelectronics Corporation (UMC)");
+ case NV_FOUNDRY_IBM:
+ return PhCreateString(L"IBM Microelectronics");
+ case NV_FOUNDRY_SMIC:
+ return PhCreateString(L"Semiconductor Manufacturing International Corporation (SMIC)");
+ case NV_FOUNDRY_CSM:
+ return PhCreateString(L"Chartered Semiconductor Manufacturing (CSM)");
+ case NV_FOUNDRY_TOSHIBA:
+ return PhCreateString(L"Toshiba Corporation");
+ default:
+ return PhFormatString(L"Unknown: %lu", nvFoundryType);
+ }
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryDeviceId(VOID)
+{
+ if (NvAPI_GPU_GetPCIIdentifiers)
+ {
+ NvU32 pDeviceId = 0;
+ NvU32 pSubSystemId = 0;
+ NvU32 pRevisionId = 0;
+ NvU32 pExtDeviceId = 0;
+
+ if (NvAPI_GPU_GetPCIIdentifiers(NvGpuPhysicalHandleList->Items[0], &pDeviceId, &pSubSystemId, &pRevisionId, &pExtDeviceId) == NVAPI_OK)
+ {
+ return PhFormatString(L"%04X - %04X", pDeviceId & 65535, pDeviceId >> 16);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryRopsCount(VOID)
+{
+ if (NvAPI_GPU_GetPartitionCount)
+ {
+ NvU32 pCount = 0;
+
+ if (NvAPI_GPU_GetPartitionCount(NvGpuPhysicalHandleList->Items[0], &pCount) == NVAPI_OK)
+ {
+ if (GpuArchType >= 0x120)
+ {
+ return PhFormatString(L"%lu", pCount * 16);
+ }
+ else if (GpuArchType >= 0x0c0)
+ {
+ return PhFormatString(L"%lu", pCount * 8);
+ }
+ else
+ {
+ return PhFormatString(L"%lu", pCount * 4);
+ }
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryShaderCount(VOID)
+{
+ if (NvAPI_GPU_GetGpuCoreCount)
+ {
+ NvU32 pCount = 0;
+
+ if (NvAPI_GPU_GetGpuCoreCount(NvGpuPhysicalHandleList->Items[0], &pCount) == NVAPI_OK)
+ {
+ return PhFormatString(L"%lu Unified", pCount);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryPciInfo(VOID)
+{
+ if (NvAPI_GPU_GetPCIEInfo)
+ {
+ NV_PCIE_INFO pciInfo = { NV_PCIE_INFO_VER };
+
+ if (NvAPI_GPU_GetPCIEInfo(NvGpuPhysicalHandleList->Items[0], &pciInfo) == NVAPI_OK)
+ {
+ return PhFormatString(L"%lu @ %lu %lu",
+ pciInfo.info[1].unknown1,
+ pciInfo.info[0].unknown5,
+ pciInfo.info[0].unknown6
+ );
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+PPH_STRING NvGpuQueryBusWidth(VOID)
+{
+ if (NvAPI_GPU_GetFBWidthAndLocation)
+ {
+ NvU32 pWidth = 0;
+ NvU32 pLocation = 0;
+
+ if (NvAPI_GPU_GetFBWidthAndLocation(NvGpuPhysicalHandleList->Items[0], &pWidth, &pLocation) == NVAPI_OK)
+ {
+ return PhFormatString(L"%lu Bit", pWidth);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+
+PPH_STRING NvGpuQueryPcbValue(VOID)
+{
+ if (NvAPI_GPU_ClientPowerTopologyGetStatus)
+ {
+ NV_POWER_TOPOLOGY_STATUS nvPowerTopologyStatus = { NV_POWER_TOPOLOGY_STATUS_VER };
+
+ if (NvAPI_GPU_ClientPowerTopologyGetStatus(NvGpuPhysicalHandleList->Items[0], &nvPowerTopologyStatus) == NVAPI_OK)
+ {
+ for (NvU32 i = 0; i < nvPowerTopologyStatus.count; i++)
+ {
+ NV_POWER_TOPOLOGY_2 powerTopology = nvPowerTopologyStatus.unknown[i];
+
+ if (powerTopology.flags == NV_POWER_TOPOLOGY_FLAG_UNKNOWN2)
+ {
+ return PhFormatString(L"PMU: %.2f%%", (FLOAT)powerTopology.unknown.unknown2 / 1000);
+ }
+ }
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+
+PPH_STRING NvGpuQueryDriverSettings(VOID)
+{
+ if (NvAPI_GetDisplayDriverRegistryPath)
+ {
+ NvAPI_LongString nvKeyPathAnsiString = "";
+
+ if (NvAPI_GetDisplayDriverRegistryPath(NvGpuDisplayHandleList->Items[0], nvKeyPathAnsiString) == NVAPI_OK)
+ {
+ HANDLE keyHandle;
+ PPH_STRING keyPath;
+
+ keyPath = PhConvertMultiByteToUtf16(nvKeyPathAnsiString);
+
+ if (NT_SUCCESS(PhOpenKey(
+ &keyHandle,
+ KEY_READ,
+ PH_KEY_LOCAL_MACHINE,
+ &keyPath->sr,
+ 0
+ )))
+ {
+ PPH_STRING driverDateString = NULL;// PhQueryRegistryString(keyHandle, L"DriverDate");
+ PPH_STRING driverVersionString = PhQueryRegistryString(keyHandle, L"DriverVersion");
+
+ UNICODE_STRING valueName;
+ PKEY_VALUE_PARTIAL_INFORMATION buffer = NULL;
+ ULONG bufferSize;
+
+ RtlInitUnicodeString(&valueName, L"DriverDateData");
+
+ if (NtQueryValueKey(
+ keyHandle,
+ &valueName,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &bufferSize
+ ) == STATUS_BUFFER_TOO_SMALL)
+ {
+ buffer = PhAllocate(bufferSize);
+
+ if (NT_SUCCESS(NtQueryValueKey(
+ keyHandle,
+ &valueName,
+ KeyValuePartialInformation,
+ buffer,
+ bufferSize,
+ &bufferSize
+ )))
+ {
+ if (buffer->Type == REG_BINARY && buffer->DataLength == sizeof(FILETIME))
+ {
+ SYSTEMTIME systemTime;
+ SYSTEMTIME localTime;
+
+ FileTimeToSystemTime((CONST FILETIME*)buffer->Data, &systemTime);
+ SystemTimeToTzSpecificLocalTime(NULL, &systemTime, &localTime);
+
+ driverDateString = PhFormatDate(&localTime, NULL);
+ }
+ }
+
+ PhFree(buffer);
+ }
+
+ NtClose(keyHandle);
+ PhDereferenceObject(keyPath);
+ PhAutoDereferenceObject(driverVersionString);
+
+ if (driverDateString)
+ {
+ PhAutoDereferenceObject(driverDateString);
+ return PhFormatString(L"%s [%s]", driverVersionString->Buffer, driverDateString->Buffer);
+ }
+ else
+ {
+ return PhFormatString(L"%s", driverVersionString->Buffer);
+ }
+ }
+
+ PhDereferenceObject(keyPath);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+
+
+BOOLEAN NvGpuDriverIsWHQL(VOID)
+{
+ BOOLEAN nvGpuDriverIsWHQL = FALSE;
+ NvAPI_LongString nvNameAnsiString = "";
+
+ HANDLE keyHandle;
+ //HANDLE keySettingsHandle;
+
+ PPH_STRING keyPath;
+ PPH_STRING matchingDeviceIdString;
+ //PPH_STRING keySettingsPath;
+ PPH_STRING keyServicePath;
+
+ WCHAR displayInstancePath[MAX_PATH] = L"";
+
+ HDEVINFO deviceInfoHandle = INVALID_HANDLE_VALUE;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
+ SP_DEVINFO_DATA deviceInfoData = { sizeof(SP_DEVINFO_DATA) };
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = NULL;
+ ULONG deviceInfoLength = 0;
+
+ __try
+ {
+ if (!NvAPI_GetDisplayDriverRegistryPath)
+ __leave;
+
+ if (NvAPI_GetDisplayDriverRegistryPath(NvGpuDisplayHandleList->Items[0], nvNameAnsiString) != NVAPI_OK)
+ __leave;
+
+ keyPath = PhConvertMultiByteToUtf16(nvNameAnsiString);
+
+ if (!NT_SUCCESS(PhOpenKey(
+ &keyHandle,
+ KEY_READ,
+ PH_KEY_LOCAL_MACHINE,
+ &keyPath->sr,
+ 0
+ )))
+ {
+ __leave;
+ }
+
+ matchingDeviceIdString = PhQueryRegistryString(keyHandle, L"MatchingDeviceId");
+
+ //keySettingsPath = PhConcatStrings2(keyPath->Buffer, L"\\VolatileSettings");
+
+ //if (NT_SUCCESS(PhOpenKey(
+ // &keySettingsHandle,
+ // KEY_READ,
+ // PH_KEY_LOCAL_MACHINE,
+ // &keySettingsPath->sr,
+ // 0
+ // )))
+ //{
+ // GUID settingsKey = GUID_DEVINTERFACE_DISPLAY_ADAPTER;
+ // PPH_STRING guidString = PhFormatGuid(&settingsKey);
+ //
+ // ULONG dwType = REG_BINARY;
+ // LONG length = MAX_PATH;
+ //
+ // if (RegQueryValueEx(
+ // keySettingsHandle,
+ // guidString->Buffer,
+ // 0,
+ // &dwType,
+ // (PBYTE)displayInstancePath,
+ // &length
+ // ) != ERROR_SUCCESS)
+ // {
+ // //__leave;
+ // }
+ //
+ // NtClose(keySettingsHandle);
+ // PhDereferenceObject(guidString);
+ //}
+
+ if ((deviceInfoHandle = SetupDiGetClassDevs(
+ &GUID_DEVINTERFACE_DISPLAY_ADAPTER,
+ NULL,
+ NULL,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
+ )) == INVALID_HANDLE_VALUE)
+ {
+ __leave;
+ }
+
+ for (ULONG i = 0; i < 1000; i++)
+ {
+ ULONG devicePropertyLength = 0;
+ DEVPROPTYPE devicePropertyType = 0;
+ HANDLE keyServiceHandle;
+ WCHAR matchingDeviceId[MAX_PATH] = L"";
+ WCHAR deviceServiceName[MAX_PATH] = L"";
+
+ if (!SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &GUID_DEVINTERFACE_DISPLAY_ADAPTER, i, &deviceInterfaceData))
+ break;
+
+ if (SetupDiGetDeviceInterfaceDetail(
+ deviceInfoHandle,
+ &deviceInterfaceData,
+ 0,
+ 0,
+ &deviceInfoLength,
+ &deviceInfoData
+ ) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ continue;
+ }
+
+ deviceInterfaceDetail = PhAllocate(deviceInfoLength);
+ deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ if (!SetupDiGetDeviceInterfaceDetail(
+ deviceInfoHandle,
+ &deviceInterfaceData,
+ deviceInterfaceDetail,
+ deviceInfoLength,
+ &deviceInfoLength,
+ &deviceInfoData
+ ))
+ {
+ continue;
+ }
+
+ if (!SetupDiGetDeviceProperty(
+ deviceInfoHandle,
+ &deviceInfoData,
+ &DEVPKEY_Device_MatchingDeviceId,
+ &devicePropertyType,
+ (PBYTE)&matchingDeviceId,
+ sizeof(matchingDeviceId),
+ &devicePropertyLength,
+ 0
+ ))
+ {
+ continue;
+ }
+
+
+ //if (PhEqualStringZ(deviceInterfaceDetail->DevicePath, displayInstancePath, TRUE))
+ if (!PhEqualStringZ(matchingDeviceId, matchingDeviceIdString->Buffer, TRUE))
+ continue;
+
+ if (!SetupDiGetDeviceProperty(
+ deviceInfoHandle,
+ &deviceInfoData,
+ &DEVPKEY_Device_Service,
+ &devicePropertyType,
+ (PBYTE)&deviceServiceName,
+ sizeof(deviceServiceName),
+ &devicePropertyLength,
+ 0
+ ))
+ {
+ continue;
+ }
+
+ keyServicePath = PhConcatStrings2(L"System\\CurrentControlSet\\Services\\", deviceServiceName);
+
+ if (NT_SUCCESS(PhOpenKey(
+ &keyServiceHandle,
+ KEY_READ,
+ PH_KEY_LOCAL_MACHINE,
+ &keyServicePath->sr,
+ 0
+ )))
+ {
+ PPH_STRING driverNtPathString = NULL;
+ PPH_STRING driverDosPathString = NULL;
+
+ if (driverNtPathString = PhQueryRegistryString(keyServiceHandle, L"ImagePath"))
+ {
+ driverDosPathString = PhGetFileName(driverNtPathString);
+ PhDereferenceObject(driverNtPathString);
+ }
+
+ if (driverDosPathString)
+ {
+ PPH_STRING fileSignerName = NULL;
+ //PH_MAPPED_IMAGE fileMappedImage;
+ //
+ //if (NT_SUCCESS(PhLoadMappedImage(driverDosPathString->Buffer, NULL, TRUE, &fileMappedImage)))
+ //{
+ // LARGE_INTEGER time;
+ // SYSTEMTIME systemTime;
+ // PPH_STRING string;
+ //
+ // RtlSecondsSince1970ToTime(fileMappedImage.NtHeaders->FileHeader.TimeDateStamp, &time);
+ // PhLargeIntegerToLocalSystemTime(&systemTime, &time);
+ //
+ // string = PhFormatDateTime(&systemTime);
+ // //SetDlgItemText(hwndDlg, IDC_TIMESTAMP, string->Buffer);
+ // PhDereferenceObject(string);
+ //
+ // PhUnloadMappedImage(&fileMappedImage);
+ //}
+
+ if (PhVerifyFile(driverDosPathString->Buffer, &fileSignerName) == VrTrusted)
+ {
+ if (PhEqualString2(fileSignerName, L"Microsoft Windows Hardware Compatibility Publisher", TRUE))
+ {
+ nvGpuDriverIsWHQL = TRUE;
+ }
+ }
+
+ if (fileSignerName)
+ PhDereferenceObject(fileSignerName);
+
+ PhDereferenceObject(driverDosPathString);
+ }
+
+ NtClose(keyServiceHandle);
+ }
+ }
+ }
+ __finally
+ {
+ if (deviceInfoHandle != INVALID_HANDLE_VALUE)
+ {
+ SetupDiDestroyDeviceInfoList(deviceInfoHandle);
+ }
+
+ if (keyHandle)
+ {
+ NtClose(keyHandle);
+ }
+
+ if (deviceInterfaceDetail)
+ {
+ PhFree(deviceInterfaceDetail);
+ }
+
+ if (keyPath)
+ {
+ PhDereferenceObject(keyPath);
+ }
+ }
+
+ return nvGpuDriverIsWHQL;
+}
+
+PPH_STRING NvGpuQueryFanSpeed(VOID)
+{
+ NvU32 tachValue = 0;
+ NV_GPU_COOLER_SETTINGS coolerInfo = { NV_GPU_COOLER_SETTINGS_VER };
+
+ if (NvAPI_GPU_GetTachReading && NvAPI_GPU_GetTachReading(NvGpuPhysicalHandleList->Items[0], &tachValue) == NVAPI_OK)
+ {
+ if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK)
+ {
+ return PhFormatString(L"%lu RPM (%lu%%)", tachValue, coolerInfo.cooler[0].currentLevel);
+ }
+
+ return PhFormatString(L"%lu RPM", tachValue);
+ }
+ else
+ {
+ if (NvAPI_GPU_GetCoolerSettings && NvAPI_GPU_GetCoolerSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_COOLER_TARGET_ALL, &coolerInfo) == NVAPI_OK)
+ {
+ return PhFormatString(L"%lu%%", coolerInfo.cooler[0].currentLevel);
+ }
+ }
+
+ return PhCreateString(L"N/A");
+}
+
+VOID NvGpuUpdateValues(VOID)
+{
+ NV_USAGES_INFO usagesInfo = { NV_USAGES_INFO_VER };
+ NV_DISPLAY_DRIVER_MEMORY_INFO memoryInfo = { NV_DISPLAY_DRIVER_MEMORY_INFO_VER };
+ NV_GPU_THERMAL_SETTINGS thermalSettings = { NV_GPU_THERMAL_SETTINGS_VER };
+ NV_GPU_CLOCK_FREQUENCIES clkFreqs = { NV_GPU_CLOCK_FREQUENCIES_VER };
+ NV_CLOCKS_INFO clocksInfo = { NV_CLOCKS_INFO_VER };
+ NV_VOLTAGE_DOMAINS voltageDomains = { NV_VOLTAGE_DOMAIN_INFO_VER };
+
+ if (NvAPI_GPU_GetMemoryInfo(NvGpuDisplayHandleList->Items[0], &memoryInfo) == NVAPI_OK)
+ {
+ GpuMemoryLimit = memoryInfo.availableDedicatedVideoMemory;
+ GpuCurrentMemSharedUsage = memoryInfo.sharedSystemMemory;
+ GpuCurrentMemUsage = memoryInfo.availableDedicatedVideoMemory - memoryInfo.curAvailableDedicatedVideoMemory;
+ }
+
+ if (NvAPI_GPU_GetUsages(NvGpuPhysicalHandleList->Items[0], &usagesInfo) == NVAPI_OK)
+ {
+ GpuCurrentGpuUsage = (FLOAT)usagesInfo.usages[2] / 100;
+ GpuCurrentCoreUsage = (FLOAT)usagesInfo.usages[6] / 100;
+ GpuCurrentBusUsage = (FLOAT)usagesInfo.usages[14] / 100;
+ }
+
+ if (NvAPI_GPU_GetThermalSettings(NvGpuPhysicalHandleList->Items[0], NVAPI_THERMAL_TARGET_ALL, &thermalSettings) == NVAPI_OK)
+ {
+ GpuCurrentCoreTemp = thermalSettings.sensor[0].currentTemp;
+ GpuCurrentBoardTemp = thermalSettings.sensor[1].currentTemp;
+ }
+
+ if (NvAPI_GPU_GetAllClockFrequencies(NvGpuPhysicalHandleList->Items[0], &clkFreqs) == NVAPI_OK)
+ {
+ //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].bIsPresent)
+ GpuCurrentCoreClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency / 1000;
+
+ //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY].bIsPresent)
+ GpuCurrentMemoryClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY].frequency / 1000;
+
+ //if (clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR].bIsPresent)
+ GpuCurrentShaderClock = clkFreqs.domain[NVAPI_GPU_PUBLIC_CLOCK_PROCESSOR].frequency / 1000;
+ }
+
+ if (NvAPI_GPU_GetAllClocks(NvGpuPhysicalHandleList->Items[0], &clocksInfo) == NVAPI_OK)
+ {
+ if (GpuCurrentCoreClock == 0)
+ GpuCurrentCoreClock = clocksInfo.clocks[0] / 1000;
+
+ if (GpuCurrentMemoryClock == 0)
+ GpuCurrentMemoryClock = clocksInfo.clocks[1] / 1000;
+
+ if (GpuCurrentShaderClock == 0)
+ GpuCurrentShaderClock = clocksInfo.clocks[2] / 1000;
+
+ if (clocksInfo.clocks[30] != 0)
+ {
+ if (GpuCurrentCoreClock == 0)
+ GpuCurrentCoreClock = (ULONG)(clocksInfo.clocks[30] * 0.0005f);
+
+ if (GpuCurrentShaderClock == 0)
+ GpuCurrentShaderClock = (ULONG)(clocksInfo.clocks[30] * 0.001f);
+ }
+ }
+
+ if (NvAPI_GPU_GetVoltageDomainsStatus(NvGpuPhysicalHandleList->Items[0], &voltageDomains) == NVAPI_OK)
+ {
+ GpuCurrentVoltage = voltageDomains.domain[0].mvolt / 1000;
+
+ //for (NvU32 i = 0; i < voltageDomains.max; i++)
+ //{
+ // if (voltageDomains.domain[i].domainId == NVAPI_GPU_PERF_VOLTAGE_INFO_DOMAIN_CORE)
+ // {
+ // OutputDebugString(PhaFormatString(L"Voltage: [%lu] %lu\r\n", i, voltageDomains.domain[0].mvolt / 1000))->Buffer);
+ // }
+ //}
+ }
+
+ //if (NvAPI_GPU_GetPerfDecreaseInfo(NvGpuPhysicalHandleList->Items[0], &GpuPerfDecreaseReason) != NVAPI_OK)
+ //{
+ // GpuPerfDecreaseReason = NV_GPU_PERF_DECREASE_REASON_UNKNOWN;
+ //}
+
+ //NvU32 totalApps = 0;
+ //NV_ACTIVE_APPS activeApps[NVAPI_MAX_PROCESSES] = { NV_ACTIVE_APPS_INFO_VER };
+ //NvAPI_GPU_QueryActiveApps(NvGpuPhysicalHandleList->Items[0], activeApps, &totalApps);
+
+ //NV_VOLTAGES voltages = { NV_VOLTAGES_INFO_VER };
+ //NvAPI_GPU_GetVoltages(NvGpuPhysicalHandleList->Items[0], &voltages);
+
+ //Nv120 clockInfo = { NV_PERF_CLOCKS_INFO_VER };
+ //NvAPI_GPU_GetPerfClocks(NvGpuPhysicalHandleList->Items[0], 0, &clockInfo);
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/nvidia.h b/plugins-extra/NvGpuPlugin/nvidia.h
new file mode 100644
index 0000000..19c5a2c
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/nvidia.h
@@ -0,0 +1,604 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+#include
+
+// rev
+#define NVAPI_MAX_USAGES_PER_GPU 33
+#define NVAPI_MAX_CLOCKS_PER_GPU 0x120
+#define NVAPI_MAX_COOLERS_PER_GPU 3
+#define NVAPI_MIN_COOLER_LEVEL 0
+#define NVAPI_MAX_COOLER_LEVEL 100
+#define NVAPI_MAX_COOLER_LEVELS 24
+#define NVAPI_MAX_PROCESSES 128
+
+// rev
+typedef PVOID (__cdecl *_NvAPI_QueryInterface)(NvU32 FunctionOffset);
+_NvAPI_QueryInterface NvAPI_QueryInterface;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShaderPipeCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pShaderPipeCount);
+_NvAPI_GPU_GetShaderPipeCount NvAPI_GPU_GetShaderPipeCount;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShaderSubPipeCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pShaderSubPipeCount);
+_NvAPI_GPU_GetShaderSubPipeCount NvAPI_GPU_GetShaderSubPipeCount;
+
+
+// rev
+typedef enum _NV_RAM_TYPE
+{
+ NV_RAM_TYPE_NONE,
+ NV_RAM_TYPE_SDRAM,
+ NV_RAM_TYPE_DDR1,
+ NV_RAM_TYPE_DDR2,
+ NV_RAM_TYPE_GDDR2,
+ NV_RAM_TYPE_GDDR3,
+ NV_RAM_TYPE_GDDR4,
+ NV_RAM_TYPE_DDR3,
+ NV_RAM_TYPE_GDDR5,
+ NV_RAM_TYPE_LPDDR2
+} NV_RAM_TYPE;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetRamType)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_RAM_TYPE* pRamType);
+_NvAPI_GPU_GetRamType NvAPI_GPU_GetRamType;
+
+
+// rev
+typedef enum _NV_RAM_MAKER
+{
+ NV_RAM_MAKER_NONE,
+ NV_RAM_MAKER_SAMSUNG,
+ NV_RAM_MAKER_QIMONDA,
+ NV_RAM_MAKER_ELPIDA,
+ NV_RAM_MAKER_ETRON,
+ NV_RAM_MAKER_NANYA,
+ NV_RAM_MAKER_HYNIX,
+ NV_RAM_MAKER_MOSEL,
+ NV_RAM_MAKER_WINBOND,
+ NV_RAM_MAKER_ELITE,
+ NV_RAM_MAKER_MICRON
+} NV_RAM_MAKER;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetRamType)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_RAM_MAKER* pRamMaker);
+_NvAPI_GPU_GetRamType NvAPI_GPU_GetRamMaker;
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetRamBusWidth)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBusWidth);
+_NvAPI_GPU_GetRamBusWidth NvAPI_GPU_GetRamBusWidth;
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetRamBankCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pRamBankCount);
+_NvAPI_GPU_GetRamBankCount NvAPI_GPU_GetRamBankCount;
+
+
+
+typedef enum _NV_FOUNDRY
+{
+ NV_FOUNDRY_NONE,
+ NV_FOUNDRY_TSMC,
+ NV_FOUNDRY_UMC,
+ NV_FOUNDRY_IBM,
+ NV_FOUNDRY_SMIC,
+ NV_FOUNDRY_CSM,
+ NV_FOUNDRY_TOSHIBA
+} NV_FOUNDRY;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetFoundry)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NV_FOUNDRY* pFoundry);
+_NvAPI_GPU_GetFoundry NvAPI_GPU_GetFoundry;
+
+
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetFBWidthAndLocation)(_In_ NvPhysicalGpuHandle hPhysicalGPU, NvU32* pWidth, NvU32* pLocation);
+_NvAPI_GPU_GetFBWidthAndLocation NvAPI_GPU_GetFBWidthAndLocation;
+
+
+// rev (This has a different offset than the NvAPI_GPU_GetMemoryInfo function despite both returning the same struct).
+typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverMemoryInfo)(_In_ NvDisplayHandle NvDispHandle, _Inout_ NV_DISPLAY_DRIVER_MEMORY_INFO* pMemoryInfo);
+_NvAPI_GetDisplayDriverMemoryInfo NvAPI_GetDisplayDriverMemoryInfo;
+
+
+
+// rev
+typedef enum _NV_COOLER_TYPE
+{
+ NVAPI_COOLER_TYPE_NONE = 0,
+ NVAPI_COOLER_TYPE_FAN,
+ NVAPI_COOLER_TYPE_WATER,
+ NVAPI_COOLER_TYPE_LIQUID_NO2,
+} NV_COOLER_TYPE;
+
+// rev
+typedef enum _NV_COOLER_CONTROLLER
+{
+ NVAPI_COOLER_CONTROLLER_NONE = 0,
+ NVAPI_COOLER_CONTROLLER_ADI,
+ NVAPI_COOLER_CONTROLLER_INTERNAL,
+} NV_COOLER_CONTROLLER;
+
+// rev
+typedef enum _NV_COOLER_POLICY
+{
+ NVAPI_COOLER_POLICY_NONE = 0,
+ NVAPI_COOLER_POLICY_MANUAL, // Manual adjustment of cooler level. Gets applied right away independent of temperature or performance level.
+ NVAPI_COOLER_POLICY_PERF, // GPU performance controls the cooler level.
+ NVAPI_COOLER_POLICY_TEMPERATURE_DISCRETE = 4, // Discrete thermal levels control the cooler level.
+ NVAPI_COOLER_POLICY_TEMPERATURE_CONTINUOUS = 8, // Cooler level adjusted at continuous thermal levels.
+ NVAPI_COOLER_POLICY_HYBRID, // Hybrid of performance and temperature levels.
+} NV_COOLER_POLICY;
+
+// rev
+typedef enum _NV_COOLER_TARGET
+{
+ NVAPI_COOLER_TARGET_NONE = 0,
+ NVAPI_COOLER_TARGET_GPU,
+ NVAPI_COOLER_TARGET_MEMORY,
+ NVAPI_COOLER_TARGET_POWER_SUPPLY = 4,
+ NVAPI_COOLER_TARGET_ALL = 7 // This cooler cools all of the components related to its target gpu.
+} NV_COOLER_TARGET;
+
+// rev
+typedef enum _NV_COOLER_CONTROL
+{
+ NVAPI_COOLER_CONTROL_NONE = 0,
+ NVAPI_COOLER_CONTROL_TOGGLE, // ON/OFF
+ NVAPI_COOLER_CONTROL_VARIABLE, // Suppports variable control.
+} NV_COOLER_CONTROL;
+
+// rev
+typedef enum _NV_COOLER_ACTIVITY_LEVEL
+{
+ NVAPI_INACTIVE = 0, // inactive or unsupported
+ NVAPI_ACTIVE = 1, // active and spinning in case of fan
+} NV_COOLER_ACTIVITY_LEVEL;
+
+// rev
+typedef struct _NV_GPU_COOLER_SETTINGS
+{
+ NvU32 version; // structure version
+ NvU32 count; // number of associated coolers with the selected GPU
+ struct
+ {
+ NV_COOLER_TYPE type; // type of cooler - FAN, WATER, LIQUID_NO2...
+ NV_COOLER_CONTROLLER controller; // internal, ADI...
+ NvU32 defaultMinLevel; // the min default value % of the cooler
+ NvU32 defaultMaxLevel; // the max default value % of the cooler
+ NvU32 currentMinLevel; // the current allowed min value % of the cooler
+ NvU32 currentMaxLevel; // the current allowed max value % of the cooler
+ NvU32 currentLevel; // the current value % of the cooler
+ NV_COOLER_POLICY defaultPolicy; // cooler control policy - auto-perf, auto-thermal, manual, hybrid...
+ NV_COOLER_POLICY currentPolicy; // cooler control policy - auto-perf, auto-thermal, manual, hybrid...
+ NV_COOLER_TARGET target; // cooling target - GPU, memory, chipset, powersupply, canoas...
+ NV_COOLER_CONTROL controlType; // toggle or variable
+ NV_COOLER_ACTIVITY_LEVEL active; // is the cooler active - fan spinning...
+ } cooler[NVAPI_MAX_COOLERS_PER_GPU];
+} NV_GPU_COOLER_SETTINGS, *PNV_GPU_COOLER_SETTINGS;
+
+#define NV_GPU_COOLER_SETTINGS_VER MAKE_NVAPI_VERSION(NV_GPU_COOLER_SETTINGS, 1)
+
+// rev
+typedef struct _NV_GPU_SETCOOLER_LEVEL
+{
+ NvU32 version; //structure version
+ struct
+ {
+ NvU32 currentLevel; // the new value % of the cooler
+ NV_COOLER_POLICY currentPolicy; // the new cooler control policy - auto-perf, auto-thermal, manual, hybrid...
+ } cooler[NVAPI_MAX_COOLERS_PER_GPU];
+} NV_GPU_SETCOOLER_LEVEL;
+
+#define NV_GPU_SETCOOLER_LEVEL_VER MAKE_NVAPI_VERSION(NV_GPU_SETCOOLER_LEVEL, 1)
+
+// rev
+typedef struct _NV_GPU_COOLER_POLICY_TABLE
+{
+ NvU32 version; //structure version
+ NV_COOLER_POLICY policy; //selected policy to update the cooler levels for, example NVAPI_COOLER_POLICY_PERF
+ struct
+ {
+ NvU32 levelId; // level indicator for a policy
+ NvU32 currentLevel; // new cooler level for the selected policy level indicator.
+ NvU32 defaultLevel; // default cooler level for the selected policy level indicator.
+ } policyCoolerLevel[NVAPI_MAX_COOLER_LEVELS];
+} NV_GPU_COOLER_POLICY_TABLE;
+
+#define NV_GPU_COOLER_POLICY_TABLE_VER MAKE_NVAPI_VERSION(NV_GPU_COOLER_POLICY_TABLE, 1)
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetCoolerSettings
+//
+// DESCRIPTION: Retrieves the cooler information of all coolers or a specific cooler associated with the selected GPU.
+// Coolers are indexed 0 to NVAPI_MAX_COOLERS_PER_GPU-1.
+// To retrieve specific cooler info set the coolerIndex to the appropriate cooler index.
+// To retrieve info for all cooler set coolerIndex to NVAPI_COOLER_TARGET_ALL.
+//
+// PARAMETERS : hPhysicalGPU(IN) - GPU selection.
+// coolerIndex(IN) - Explict cooler index selection.
+// pCoolerInfo(OUT) - Array of cooler settings.
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetCoolerSettings)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_SETTINGS* pCoolerInfo);
+_NvAPI_GPU_GetCoolerSettings NvAPI_GPU_GetCoolerSettings;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_SetCoolerLevels
+//
+// DESCRIPTION: Set the cooler levels for all coolers or a specific cooler associated with the selected GPU.
+// Coolers are indexed 0 to NVAPI_MAX_COOLERS_PER_GPU-1. Every cooler level with non-zero currentpolicy gets applied.
+// The new level should be in the range of minlevel and maxlevel retrieved from GetCoolerSettings API or between
+// and NVAPI_MIN_COOLER_LEVEL to MAX_COOLER_LEVEL.
+// To set level for a specific cooler set the coolerIndex to the appropriate cooler index.
+// To set level for all coolers set coolerIndex to NVAPI_COOLER_TARGET_ALL.
+// NOTE: To lock the fan speed independent of the temperature or performance changes set the cooler currentPolicy to
+// NVAPI_COOLER_POLICY_MANUAL else set it to the current policy retrieved from the GetCoolerSettings API.
+// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
+// coolerIndex(IN) - Explict cooler index selection.
+// pCoolerLevels(IN) - Updated cooler level and cooler policy.
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_SetCoolerLevels)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_SETCOOLER_LEVEL *pCoolerLevels);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_RestoreCoolerSettings
+//
+// DESCRIPTION: Restore the modified cooler settings to NVIDIA defaults.
+//
+// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
+// pCoolerIndex(IN) - Array containing absolute cooler indexes to restore. Pass NULL restore all coolers.
+// CoolerCount - Number of coolers to restore.
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_RestoreCoolerSettings)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pCoolerIndex, NvU32 coolerCount);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_GetCoolerPolicyTable
+//
+// DESCRIPTION: Retrieves the table of cooler and policy levels for the selected policy. Supported only for NVAPI_COOLER_POLICY_PERF.
+//
+// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
+// coolerIndex(IN) - cooler index selection.
+// pCoolerTable(OUT) - Table of policy levels and associated cooler levels.
+// count(OUT) - Count of the number of valid levels for the selected policy.
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_POLICY_TABLE *pCoolerTable, NvU32 *count);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_SetCoolerPolicyTable
+//
+// DESCRIPTION: Restore the modified cooler settings to NVIDIA defaults. Supported only for NVAPI_COOLER_POLICY_PERF.
+//
+// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
+// coolerIndex(IN) - cooler index selection.
+// pCoolerTable(IN) - Updated table of policy levels and associated cooler levels. Every non-zero policy level gets updated.
+// count(IN) - Number of valid levels in the policy table.
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_SetCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 coolerIndex, NV_GPU_COOLER_POLICY_TABLE *pCoolerTable, NvU32 count);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// FUNCTION NAME: NvAPI_GPU_RestoreCoolerPolicyTable
+//
+// DESCRIPTION: Restores the perf table policy levels to the defaults.
+//
+// PARAMETERS: hPhysicalGPU(IN) - GPU selection.
+// coolerIndex(IN) - cooler index selection.
+// pCoolerIndex(IN) - Array containing absolute cooler indexes to restore. Pass NULL restore all coolers.
+// coolerCount - Number of coolers to restore.
+// policy - restore for the selected policy
+//
+///////////////////////////////////////////////////////////////////////////////
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_RestoreCoolerPolicyTable)(_In_ NvPhysicalGpuHandle hPhysicalGpu, NvU32 *pCoolerIndex, NvU32 coolerCount, NV_COOLER_POLICY policy);
+
+
+
+// rev - NvAPI_GPU_GetUsages
+typedef struct _NV_USAGES_INFO
+{
+ NvU32 version; //!< Structure version
+ NvU32 usages[NVAPI_MAX_USAGES_PER_GPU];
+} NV_USAGES_INFO;
+
+#define NV_USAGES_INFO_VER MAKE_NVAPI_VERSION(NV_USAGES_INFO, 1)
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetUsages)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_USAGES_INFO* pUsagesInfo);
+_NvAPI_GPU_GetUsages NvAPI_GPU_GetUsages;
+
+
+
+// rev - NvAPI_GPU_GetAllClocks
+typedef struct _NV_CLOCKS_INFO
+{
+ NvU32 version; //!< Structure version
+ NvU32 clocks[NVAPI_MAX_CLOCKS_PER_GPU];
+} NV_CLOCKS_INFO;
+
+#define NV_CLOCKS_INFO_VER MAKE_NVAPI_VERSION(NV_CLOCKS_INFO, 2)
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetAllClocks)(_In_ NvPhysicalGpuHandle hPhysicalGpu, _Inout_ NV_CLOCKS_INFO* pClocksInfo);
+_NvAPI_GPU_GetAllClocks NvAPI_GPU_GetAllClocks;
+
+
+
+// rev - NvAPI_GPU_GetVoltageDomainsStatus
+typedef struct _NV_VOLTAGE_DOMAINS
+{
+ NvU32 version; //!< Structure version
+ NvU32 flags; //!< Reserved for future use. Must be set to 0
+ NvU32 max;
+ struct
+ {
+ NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId; //!< ID of the voltage domain
+ NvU32 mvolt; //!< Voltage in mV
+ } domain[NVAPI_MAX_GPU_PERF_VOLTAGES];
+} NV_VOLTAGE_DOMAINS;
+
+#define NV_VOLTAGE_DOMAIN_INFO_VER MAKE_NVAPI_VERSION(NV_VOLTAGE_DOMAINS, 1)
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVoltageDomainsStatus)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_VOLTAGE_DOMAINS* pVoltageDomainsStatus);
+_NvAPI_GPU_GetVoltageDomainsStatus NvAPI_GPU_GetVoltageDomainsStatus;
+
+
+
+// rev - NvAPI_GPU_GetVoltages
+typedef struct _NV_VOLTAGES_INFO
+{
+ NV_GPU_PERF_VOLTAGE_INFO_DOMAIN_ID domainId; //!< ID of the voltage domain
+ NvU32 unknown1;
+ NvU32 max;
+
+ struct
+ {
+ NvU32 unknown2;
+ NvU32 mvolt; //!< Voltage in mV
+ } info[128];
+} NV_VOLTAGES_INFO;
+
+// rev
+typedef struct _NV_VOLTAGES
+{
+ NvU32 version; //!< Structure version
+ NvU32 flags; //!< Reserved for future use. Must be set to 0
+ NvU32 max;
+ NV_VOLTAGES_INFO voltages[NVAPI_MAX_GPU_PERF_VOLTAGES];
+} NV_VOLTAGES;
+
+#define NV_VOLTAGES_INFO_VER MAKE_NVAPI_VERSION(NV_VOLTAGES, 1)
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetVoltages)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_VOLTAGES* pPerfVoltages);
+_NvAPI_GPU_GetVoltages NvAPI_GPU_GetVoltages;
+
+
+
+// rev - NvAPI_GPU_GetPerfClocks
+typedef struct _NV_PERF_CLOCKS_UNKNOWN_2
+{
+ NvU32 unknown1;
+ NvU32 unknown2;
+ NvU32 unknown3;
+ NvU32 unknown4;
+ NvU32 unknown5;
+ NvU32 unknown6;
+ NvU32 unknown7;
+} NV_PERF_CLOCKS_UNKNOWN_2;
+
+// rev
+typedef struct _NV_PERF_CLOCKS_UNKNOWN_1
+{
+ NvU32 unknown1;
+ NvU32 unknown2;
+ NV_PERF_CLOCKS_UNKNOWN_2 unknown3[32];
+} NV_PERF_CLOCKS_UNKNOWN_1;
+
+// rev
+typedef struct _NV_PERF_CLOCKS
+{
+ NvU32 version; //!< Structure version
+ NvU32 unknown1;
+ NvU32 unknown2;
+ NvU32 unknown3;
+ NvU32 unknown4;
+ NV_PERF_CLOCKS_UNKNOWN_1 unknown5[12];
+} NV_PERF_CLOCKS;
+
+#define NV_PERF_CLOCKS_INFO_VER MAKE_NVAPI_VERSION(NV_PERF_CLOCKS, 1)
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_GetPerfClocks)(_In_ NvPhysicalGpuHandle hPhysicalGPU, INT i, _Inout_ NV_PERF_CLOCKS* pPerfClocks);
+_NvAPI_GPU_GetPerfClocks NvAPI_GPU_GetPerfClocks;
+
+
+
+// rev - NvAPI_GPU_QueryActiveApps
+typedef struct _NV_ACTIVE_APP
+{
+ NvU32 version; //!< Structure version
+ NvU32 processPID;
+ NvAPI_LongString processName;
+} NV_ACTIVE_APP;
+
+#define NV_ACTIVE_APPS_INFO_VER MAKE_NVAPI_VERSION(NV_ACTIVE_APP, 2)
+
+// rev
+typedef NvAPI_Status(__cdecl *_NvAPI_GPU_QueryActiveApps)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_ACTIVE_APP pActiveApps[NVAPI_MAX_PROCESSES], _Inout_ NvU32* pTotal);
+_NvAPI_GPU_QueryActiveApps NvAPI_GPU_QueryActiveApps;
+
+
+
+// rev - NvAPI_GPU_GetPowerMizerInfo
+typedef enum _PowerSourceInfo
+{
+ PowerSourceInfo_Unknown1 = 1,
+ PowerSourceInfo_Unknown2,
+ PowerSourceInfo_Unknown3 = 8738
+} PowerSourceInfo;
+
+// rev
+typedef enum _SelectSource
+{
+ SelectSource_Unknown1 = 1,
+ SelectSource_Unknown2,
+ SelectSource_Unknown3
+} SelectSource;
+
+// rev
+typedef enum _LevelInfo
+{
+ LevelInfo_Unknown1 = 1,
+ LevelInfo_Unknown2,
+ LevelInfo_Unknown3,
+ LevelInfo_Unknown4,
+ LevelInfo_Unknown5,
+ LevelInfo_Unknown6,
+ LevelInfo_Unknown7
+} LevelInfo;
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPowerMizerInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, PowerSourceInfo powerSourceInfo, SelectSource select, LevelInfo* pLevelInfo);
+_NvAPI_GPU_GetPowerMizerInfo NvAPI_GPU_GetPowerMizerInfo;
+
+
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GetDisplayDriverRegistryPath)(_In_ NvDisplayHandle hNvDisplay, _Inout_ NvAPI_LongString szDriverRegistryPath);
+_NvAPI_GetDisplayDriverRegistryPath NvAPI_GetDisplayDriverRegistryPath;
+
+
+
+// rev
+//typedef NvAPI_Status (__cdecl *_NvAPI_RestartDisplayDriver)(_In_ NvU32 NvDriverIndex);
+//_NvAPI_RestartDisplayDriver NvAPI_RestartDisplayDriver;
+
+
+typedef enum _NV_POWER_TOPOLOGY_FLAGS
+{
+ NV_POWER_TOPOLOGY_FLAG_UNKNOWN1,
+ NV_POWER_TOPOLOGY_FLAG_UNKNOWN2
+} NV_POWER_TOPOLOGY_FLAGS;
+
+
+typedef struct _NV_POWER_TOPOLOGY_1
+{
+ NvU32 unknown1;
+ NvU32 unknown2;
+ NvU32 unknown3;
+
+ //public uint UInt32_0
+ //{
+ // get { return this.unknown1 & 1u; }
+ //}
+
+ //public uint UInt32_1
+ //{
+ // get { return (this.unknown1 & 4294967294u) / 2u; }
+ //}
+} NV_POWER_TOPOLOGY_1;
+
+
+typedef struct _NV_POWER_TOPOLOGY_2
+{
+ NV_POWER_TOPOLOGY_FLAGS flags;
+ NV_POWER_TOPOLOGY_1 unknown;
+} NV_POWER_TOPOLOGY_2;
+
+typedef struct _NV_POWER_TOPOLOGY_STATUS
+{
+ NvU32 version; //!< Structure version
+ NvU32 count;
+
+ NV_POWER_TOPOLOGY_2 unknown[4];
+} NV_POWER_TOPOLOGY_STATUS;
+
+#define NV_POWER_TOPOLOGY_STATUS_VER MAKE_NVAPI_VERSION(NV_POWER_TOPOLOGY_STATUS, 1)
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_ClientPowerTopologyGetStatus)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_POWER_TOPOLOGY_STATUS* pClientPowerTopologyStatus);
+_NvAPI_GPU_ClientPowerTopologyGetStatus NvAPI_GPU_ClientPowerTopologyGetStatus;
+
+
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetShortName)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NvAPI_ShortString szName);
+_NvAPI_GPU_GetShortName NvAPI_GPU_GetShortName;
+
+
+// rev
+typedef struct _NV_ARCH_INFO
+{
+ NvU32 version; //!< Structure version
+ NvU32 unknown[3];
+} NV_ARCH_INFO;
+
+#define NV_ARCH_INFO_VER MAKE_NVAPI_VERSION(NV_ARCH_INFO, 2)
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetArchInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_ARCH_INFO* pArchInfo);
+_NvAPI_GPU_GetArchInfo NvAPI_GPU_GetArchInfo;
+
+
+
+// rev
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPartitionCount)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Out_ NvU32* pCount);
+_NvAPI_GPU_GetPartitionCount NvAPI_GPU_GetPartitionCount;
+
+
+
+
+typedef struct _NV_PCIE_INFO_UNKNOWN
+{
+ NvU32 unknown0;
+ NvU32 unknown1;
+ NvU32 unknown2;
+ NvU32 unknown3;
+ NvU32 unknown4;
+ NvU32 unknown5;
+ NvU32 unknown6;
+ NvU32 unknown7;
+} NV_PCIE_INFO_UNKNOWN;
+
+typedef struct _NV_PCIE_INFO
+{
+ NvU32 version; //!< Structure version
+ NV_PCIE_INFO_UNKNOWN info[5];
+} NV_PCIE_INFO;
+
+#define NV_PCIE_INFO_VER MAKE_NVAPI_VERSION(NV_PCIE_INFO, 2)
+
+typedef NvAPI_Status (__cdecl *_NvAPI_GPU_GetPCIEInfo)(_In_ NvPhysicalGpuHandle hPhysicalGPU, _Inout_ NV_PCIE_INFO* pPciInfo);
+_NvAPI_GPU_GetPCIEInfo NvAPI_GPU_GetPCIEInfo;
+
+
+#include
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/options.c b/plugins-extra/NvGpuPlugin/options.c
new file mode 100644
index 0000000..1e548f9
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/options.c
@@ -0,0 +1,263 @@
+/*
+ * Process Hacker Extra Plugins -
+ * Nvidia GPU Plugin
+ *
+ * Copyright (C) 2015 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 "main.h"
+#include
+
+#pragma comment(lib, "WindowsCodecs.lib")
+#include
+
+#define SetDlgItemCheckForSetting(hwndDlg, Id, Name) \
+ Button_SetCheck(GetDlgItem(hwndDlg, Id), PhGetIntegerSetting(Name) ? BST_CHECKED : BST_UNCHECKED)
+#define SetSettingForDlgItemCheckRestartRequired(hwndDlg, Id, Name) \
+ do { \
+ BOOLEAN __oldValue = !!PhGetIntegerSetting(Name); \
+ BOOLEAN __newValue = Button_GetCheck(GetDlgItem(hwndDlg, Id)) == BST_CHECKED; \
+ if (__newValue != __oldValue) \
+ RestartRequired = TRUE; \
+ PhSetIntegerSetting(Name, __newValue); \
+ } while (0)
+
+
+HBITMAP LoadImageFromResources(
+ _In_ UINT Width,
+ _In_ UINT Height,
+ _In_ PCWSTR Name
+ )
+{
+ UINT width = 0;
+ UINT height = 0;
+ UINT frameCount = 0;
+ BOOLEAN isSuccess = FALSE;
+ ULONG resourceLength = 0;
+ HGLOBAL resourceHandle = NULL;
+ HRSRC resourceHandleSource = NULL;
+ WICInProcPointer resourceBuffer = NULL;
+
+ BITMAPINFO bitmapInfo = { 0 };
+ HBITMAP bitmapHandle = NULL;
+ PBYTE bitmapBuffer = NULL;
+
+ IWICStream* wicStream = NULL;
+ IWICBitmapSource* wicBitmapSource = NULL;
+ IWICBitmapDecoder* wicDecoder = NULL;
+ IWICBitmapFrameDecode* wicFrame = NULL;
+ IWICImagingFactory* wicFactory = NULL;
+ IWICBitmapScaler* wicScaler = NULL;
+ WICPixelFormatGUID pixelFormat;
+
+ WICRect rect = { 0, 0, Width, Height };
+
+ __try
+ {
+ // Create the ImagingFactory
+ if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, &wicFactory)))
+ __leave;
+
+ // Find the resource
+ if ((resourceHandleSource = FindResource(PluginInstance->DllBase, Name, L"PNG")) == NULL)
+ __leave;
+
+ // Get the resource length
+ resourceLength = SizeofResource(PluginInstance->DllBase, resourceHandleSource);
+
+ // Load the resource
+ if ((resourceHandle = LoadResource(PluginInstance->DllBase, resourceHandleSource)) == NULL)
+ __leave;
+
+ if ((resourceBuffer = (WICInProcPointer)LockResource(resourceHandle)) == NULL)
+ __leave;
+
+ // Create the Stream
+ if (FAILED(IWICImagingFactory_CreateStream(wicFactory, &wicStream)))
+ __leave;
+
+ // Initialize the Stream from Memory
+ if (FAILED(IWICStream_InitializeFromMemory(wicStream, resourceBuffer, resourceLength)))
+ __leave;
+
+ if (FAILED(IWICImagingFactory_CreateDecoder(wicFactory, &GUID_ContainerFormatPng, NULL, &wicDecoder)))
+ __leave;
+
+ if (FAILED(IWICBitmapDecoder_Initialize(wicDecoder, (IStream*)wicStream, WICDecodeMetadataCacheOnLoad)))
+ __leave;
+
+ // Get the Frame count
+ if (FAILED(IWICBitmapDecoder_GetFrameCount(wicDecoder, &frameCount)) || frameCount < 1)
+ __leave;
+
+ // Get the Frame
+ if (FAILED(IWICBitmapDecoder_GetFrame(wicDecoder, 0, &wicFrame)))
+ __leave;
+
+ // Get the WicFrame image format
+ if (FAILED(IWICBitmapFrameDecode_GetPixelFormat(wicFrame, &pixelFormat)))
+ __leave;
+
+ // Check if the image format is supported:
+ if (IsEqualGUID(&pixelFormat, &GUID_WICPixelFormat32bppPBGRA)) // GUID_WICPixelFormat32bppRGB
+ {
+ wicBitmapSource = (IWICBitmapSource*)wicFrame;
+ }
+ else
+ {
+ // Convert the image to the correct format:
+ if (FAILED(WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, (IWICBitmapSource*)wicFrame, &wicBitmapSource)))
+ __leave;
+
+ IWICBitmapFrameDecode_Release(wicFrame);
+ }
+
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = rect.Width;
+ bitmapInfo.bmiHeader.biHeight = -((LONG)rect.Height);
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ HDC hdc = CreateCompatibleDC(NULL);
+ bitmapHandle = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (PVOID*)&bitmapBuffer, NULL, 0);
+ ReleaseDC(NULL, hdc);
+
+ // Check if it's the same rect as the requested size.
+ //if (width != rect.Width || height != rect.Height)
+ if (FAILED(IWICImagingFactory_CreateBitmapScaler(wicFactory, &wicScaler)))
+ __leave;
+ if (FAILED(IWICBitmapScaler_Initialize(wicScaler, wicBitmapSource, rect.Width, rect.Height, WICBitmapInterpolationModeFant)))
+ __leave;
+ if (FAILED(IWICBitmapScaler_CopyPixels(wicScaler, &rect, rect.Width * 4, rect.Width * rect.Height * 4, bitmapBuffer)))
+ __leave;
+
+ isSuccess = TRUE;
+ }
+ __finally
+ {
+ if (wicScaler)
+ {
+ IWICBitmapScaler_Release(wicScaler);
+ }
+
+ if (wicBitmapSource)
+ {
+ IWICBitmapSource_Release(wicBitmapSource);
+ }
+
+ if (wicStream)
+ {
+ IWICStream_Release(wicStream);
+ }
+
+ if (wicDecoder)
+ {
+ IWICBitmapDecoder_Release(wicDecoder);
+ }
+
+ if (wicFactory)
+ {
+ IWICImagingFactory_Release(wicFactory);
+ }
+
+ if (resourceHandle)
+ {
+ FreeResource(resourceHandle);
+ }
+ }
+
+ return bitmapHandle;
+}
+
+INT_PTR CALLBACK OptionsDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+{
+ static BOOLEAN RestartRequired;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ RestartRequired = FALSE;
+
+ PhCenterWindow(hwndDlg, GetParent(hwndDlg));
+
+ SetDlgItemCheckForSetting(hwndDlg, IDC_ENABLENVIDIASUPPORT, SETTING_NAME_ENABLE_MONITORING);
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+ case IDOK:
+ {
+ SetSettingForDlgItemCheckRestartRequired(hwndDlg, IDC_ENABLENVIDIASUPPORT, SETTING_NAME_ENABLE_MONITORING);
+
+ if (RestartRequired)
+ {
+ if (PhShowMessage(
+ PhMainWndHandle,
+ MB_ICONQUESTION | MB_YESNO,
+ L"One or more options you have changed requires a restart of Process Hacker. "
+ L"Do you want to restart Process Hacker now?"
+ ) == IDYES)
+ {
+ ProcessHacker_PrepareForEarlyShutdown(PhMainWndHandle);
+ PhShellProcessHacker(
+ PhMainWndHandle,
+ L"-v",
+ SW_SHOW,
+ 0,
+ PH_SHELL_APP_PROPAGATE_PARAMETERS | PH_SHELL_APP_PROPAGATE_PARAMETERS_IGNORE_VISIBILITY,
+ 0,
+ NULL
+ );
+ ProcessHacker_Destroy(PhMainWndHandle);
+ }
+ }
+
+ EndDialog(hwndDlg, IDOK);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+VOID ShowOptionsDialog(
+ _In_ HWND ParentHandle
+ )
+{
+ DialogBox(
+ PluginInstance->DllBase,
+ MAKEINTRESOURCE(IDD_OPTIONS),
+ ParentHandle,
+ OptionsDlgProc
+ );
+}
\ No newline at end of file
diff --git a/plugins-extra/NvGpuPlugin/resource.h b/plugins-extra/NvGpuPlugin/resource.h
new file mode 100644
index 0000000..8cbd8a0
--- /dev/null
+++ b/plugins-extra/NvGpuPlugin/resource.h
@@ -0,0 +1,53 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by NvGpuPlugin.rc
+//
+#define IDC_RESET 3
+#define IDD_GPU_PANEL 100
+#define IDD_GPU_DIALOG 101
+#define IDC_GRAPH_LAYOUT 102
+#define IDC_TITLE 103
+#define IDC_GPUNAME 104
+#define IDC_PANEL_LAYOUT 105
+#define IDC_GPU_L 106
+#define IDC_MEMORY_L 107
+#define IDC_SHARED_L 108
+#define IDC_SHARED_BUS 109
+#define IDC_BUS_L 110
+#define IDC_CLOCK_CORE 111
+#define IDC_CLOCK_MEMORY 112
+#define IDC_FAN_PERCENT 113
+#define IDC_TEMP_VALUE 114
+#define IDC_CLOCK_SHADER 115
+#define IDD_OPTIONS 116
+#define IDC_VOLTAGE 117
+#define IDD_GPU_DETAILS 117
+#define IDB_NV_LOGO_PNG 119
+#define IDC_DETAILS 1001
+#define IDC_ENABLENVIDIASUPPORT 1002
+#define IDC_EDIT1 1003
+#define IDC_EDIT2 1004
+#define IDC_EDIT3 1005
+#define IDC_EDIT4 1006
+#define IDC_EDIT5 1007
+#define IDC_EDIT6 1008
+#define IDC_EDIT7 1009
+#define IDC_EDIT8 1010
+#define IDC_EDIT9 1011
+#define IDC_NVIMAGE 1012
+#define IDC_EDIT10 1013
+#define IDC_EDIT11 1014
+#define IDC_EDIT12 1015
+#define IDC_EDIT13 1016
+#define IDC_EDIT14 1017
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 121
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1013
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins-extra/NvGpuPlugin/resources/NVLogo_2D.png b/plugins-extra/NvGpuPlugin/resources/NVLogo_2D.png
new file mode 100644
index 0000000..0921f2a
Binary files /dev/null and b/plugins-extra/NvGpuPlugin/resources/NVLogo_2D.png differ
diff --git a/plugins-extra/ObjectManagerPlugin/CHANGELOG.txt b/plugins-extra/ObjectManagerPlugin/CHANGELOG.txt
new file mode 100644
index 0000000..f9aed18
--- /dev/null
+++ b/plugins-extra/ObjectManagerPlugin/CHANGELOG.txt
@@ -0,0 +1,2 @@
+1.0
+ * Initial release
\ No newline at end of file
diff --git a/plugins-extra/ObjectManagerPlugin/ObjectManagerPlugin.vcxproj b/plugins-extra/ObjectManagerPlugin/ObjectManagerPlugin.vcxproj
new file mode 100644
index 0000000..d249a66
--- /dev/null
+++ b/plugins-extra/ObjectManagerPlugin/ObjectManagerPlugin.vcxproj
@@ -0,0 +1,124 @@
+
+
+
+