diff --git a/Source/CHANGELOG.txt b/Source/CHANGELOG.txt
index 153b4836..14d29363 100644
--- a/Source/CHANGELOG.txt
+++ b/Source/CHANGELOG.txt
@@ -1,3 +1,9 @@
+v2.1.0
+win11 25H2 compatibility improvements
+fixed incorrect object quota information dump
+more descriptions for object types
+internal rearrangement
+
v2.0.9
internal rearrangement
updated RTLs (ntos, ntsup, treelist)
diff --git a/Source/Plugins/ApiSetView/ApiSetView.vcxproj b/Source/Plugins/ApiSetView/ApiSetView.vcxproj
index 23150425..dcce0c89 100644
--- a/Source/Plugins/ApiSetView/ApiSetView.vcxproj
+++ b/Source/Plugins/ApiSetView/ApiSetView.vcxproj
@@ -96,24 +96,32 @@
+
+
+
+
+
+
+
+
diff --git a/Source/Plugins/ApiSetView/ApiSetView.vcxproj.filters b/Source/Plugins/ApiSetView/ApiSetView.vcxproj.filters
index bfcaab82..94c3a302 100644
--- a/Source/Plugins/ApiSetView/ApiSetView.vcxproj.filters
+++ b/Source/Plugins/ApiSetView/ApiSetView.vcxproj.filters
@@ -19,6 +19,9 @@
{83c6e752-f5b5-48a7-8e6f-231cba8a450d}
+
+ {315785cb-45b6-49b7-ad7e-eb6925ca5197}
+
@@ -57,6 +60,18 @@
minirtl
+
+ Source Files
+
+
+ ntos
+
+
+ minirtl
+
+
+ minirtl
+
@@ -83,6 +98,18 @@
treelist
+
+ Header Files
+
+
+ ntos
+
+
+ ntos
+
+
+ ntos
+
diff --git a/Source/Plugins/ApiSetView/Resource.rc b/Source/Plugins/ApiSetView/Resource.rc
index 0750a3a2..09de522c 100644
Binary files a/Source/Plugins/ApiSetView/Resource.rc and b/Source/Plugins/ApiSetView/Resource.rc differ
diff --git a/Source/Plugins/ApiSetView/global.h b/Source/Plugins/ApiSetView/global.h
index 59b53e89..62c3a3da 100644
--- a/Source/Plugins/ApiSetView/global.h
+++ b/Source/Plugins/ApiSetView/global.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2019 - 2021
+* (C) COPYRIGHT AUTHORS, 2019 - 2025
*
* TITLE: GLOBAL.H
*
-* VERSION: 1.11
+* VERSION: 1.20
*
-* DATE: 01 Oct 2021
+* DATE: 03 Oct 2025
*
* Common header file for the Windows Object Explorer ApiSetView plugin.
*
@@ -56,3 +56,5 @@
// Declared in main.c
//
extern GUI_CONTEXT g_ctx;
+
+#include "utils.h"
diff --git a/Source/Plugins/ApiSetView/main.c b/Source/Plugins/ApiSetView/main.c
index 51c3c5c6..782e1ec6 100644
--- a/Source/Plugins/ApiSetView/main.c
+++ b/Source/Plugins/ApiSetView/main.c
@@ -4,9 +4,9 @@
*
* TITLE: MAIN.C
*
-* VERSION: 1.15
+* VERSION: 1.20
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* WinObjEx64 ApiSetView plugin.
*
diff --git a/Source/Plugins/ApiSetView/query.c b/Source/Plugins/ApiSetView/query.c
index 94f63721..2875896a 100644
--- a/Source/Plugins/ApiSetView/query.c
+++ b/Source/Plugins/ApiSetView/query.c
@@ -4,9 +4,9 @@
*
* TITLE: QUERY.C
*
-* VERSION: 1.15
+* VERSION: 1.20
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* Query and output ApiSet specific data.
*
@@ -54,37 +54,6 @@ VOID DisplayErrorText(
#endif
}
-/*
-* TreeListAddItem
-*
-* Purpose:
-*
-* Insert new treelist item.
-*
-*/
-HTREEITEM TreeListAddItem(
- _In_ HWND TreeList,
- _In_opt_ HTREEITEM hParent,
- _In_ UINT mask,
- _In_ UINT state,
- _In_ UINT stateMask,
- _In_opt_ LPWSTR pszText,
- _In_opt_ PVOID subitems
-)
-{
- TVINSERTSTRUCT tvitem;
- PTL_SUBITEMS si = (PTL_SUBITEMS)subitems;
-
- RtlZeroMemory(&tvitem, sizeof(tvitem));
- tvitem.hParent = hParent;
- tvitem.item.mask = mask;
- tvitem.item.state = state;
- tvitem.item.stateMask = stateMask;
- tvitem.item.pszText = pszText;
- tvitem.hInsertAfter = TVI_LAST;
- return TreeList_InsertTreeItem(TreeList, &tvitem, si);
-}
-
/*
* IsRangeValid
*
@@ -212,7 +181,7 @@ HTREEITEM OutNamespaceEntry(
tlSubItems.Text[1] = T_EmptyString;
tlSubItems.Count = 2;
- h_tviRootItem = TreeListAddItem(
+ h_tviRootItem = supTreeListAddItem(
g_ctx.TreeList,
RootItem,
TVIF_TEXT | TVIF_STATE,
@@ -233,7 +202,7 @@ HTREEITEM OutNamespaceEntry(
tlSubItems.Text[1] = T_EmptyString;
tlSubItems.Count = 2;
- TreeListAddItem(
+ supTreeListAddItem(
g_ctx.TreeList,
h_tviRootItem,
TVIF_TEXT | TVIF_STATE,
@@ -255,7 +224,7 @@ HTREEITEM OutNamespaceEntry(
tlSubItems.Text[0] = szBuffer;
tlSubItems.Text[1] = T_EmptyString;
tlSubItems.Count = 2;
- TreeListAddItem(
+ supTreeListAddItem(
g_ctx.TreeList,
h_tviRootItem,
TVIF_TEXT | TVIF_STATE,
@@ -331,7 +300,7 @@ void OutNamespaceValue(
tlSubItems.Text[1] = T_EmptyString;
}
- TreeListAddItem(
+ supTreeListAddItem(
g_ctx.TreeList,
RootItem,
TVIF_TEXT | TVIF_STATE,
@@ -710,7 +679,7 @@ VOID WINAPI ListApiSetFromFileWorker(
//
// Parse and output apiset.
//
- h_tviRootItem = TreeListAddItem(
+ h_tviRootItem = supTreeListAddItem(
g_ctx.TreeList,
(HTREEITEM)NULL,
TVIF_TEXT | TVIF_STATE,
@@ -721,7 +690,7 @@ VOID WINAPI ListApiSetFromFileWorker(
if (h_tviRootItem) {
- h_tviSubItem = TreeListAddItem(
+ h_tviSubItem = supTreeListAddItem(
g_ctx.TreeList,
(HTREEITEM)h_tviRootItem,
TVIF_TEXT | TVIF_STATE,
diff --git a/Source/Plugins/ApiSetView/ui.h b/Source/Plugins/ApiSetView/ui.h
index 27e1d084..4b653e8d 100644
--- a/Source/Plugins/ApiSetView/ui.h
+++ b/Source/Plugins/ApiSetView/ui.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2019 - 2022
+* (C) COPYRIGHT AUTHORS, 2019 - 2025
*
* TITLE: UI.H
*
-* VERSION: 1.13
+* VERSION: 1.20
*
-* DATE: 10 Jun 2022
+* DATE: 03 Oct 2025
*
* WinObjEx64 ApiSetView UI constants, definitions and includes.
*
@@ -50,13 +50,3 @@ typedef struct _GUI_CONTEXT {
//
WINOBJEX_PARAM_BLOCK ParamBlock;
} GUI_CONTEXT, *PGUI_CONTEXT;
-
-typedef struct _TL_SUBITEMS_FIXED {
- ULONG Count;
- ULONG ColorFlags;
- COLORREF BgColor;
- COLORREF FontColor;
- PVOID UserParam;
- LPTSTR CustomTooltip;
- LPTSTR Text[2];
-} TL_SUBITEMS_FIXED, * PTL_SUBITEMS_FIXED;
diff --git a/Source/Plugins/ExamplePlugin/Resource.rc b/Source/Plugins/ExamplePlugin/Resource.rc
index b70f2cd2..235ca967 100644
Binary files a/Source/Plugins/ExamplePlugin/Resource.rc and b/Source/Plugins/ExamplePlugin/Resource.rc differ
diff --git a/Source/Plugins/ImageScope/ImageScope.vcxproj b/Source/Plugins/ImageScope/ImageScope.vcxproj
index fdf77fed..06497e80 100644
--- a/Source/Plugins/ImageScope/ImageScope.vcxproj
+++ b/Source/Plugins/ImageScope/ImageScope.vcxproj
@@ -107,6 +107,7 @@
+
@@ -114,13 +115,14 @@
+
+
-
@@ -132,10 +134,10 @@
+
-
diff --git a/Source/Plugins/ImageScope/ImageScope.vcxproj.filters b/Source/Plugins/ImageScope/ImageScope.vcxproj.filters
index 1cb1e6f2..fe94f440 100644
--- a/Source/Plugins/ImageScope/ImageScope.vcxproj.filters
+++ b/Source/Plugins/ImageScope/ImageScope.vcxproj.filters
@@ -57,9 +57,6 @@
minirtl
-
- Source Files
-
ntos
@@ -75,6 +72,15 @@
minirtl
+
+ Source Files
+
+
+ minirtl
+
+
+ minirtl
+
@@ -107,15 +113,15 @@
treelist
-
- Header Files
-
sdk
ntos
+
+ Header Files
+
diff --git a/Source/Plugins/ImageScope/Resource.rc b/Source/Plugins/ImageScope/Resource.rc
index f5b18572..a823669b 100644
Binary files a/Source/Plugins/ImageScope/Resource.rc and b/Source/Plugins/ImageScope/Resource.rc differ
diff --git a/Source/Plugins/ImageScope/global.h b/Source/Plugins/ImageScope/global.h
index f5fa99c2..41627fbc 100644
--- a/Source/Plugins/ImageScope/global.h
+++ b/Source/Plugins/ImageScope/global.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2020 - 2021
+* (C) COPYRIGHT AUTHORS, 2020 - 2025
*
* TITLE: GLOBAL.H
*
-* VERSION: 1.00
+* VERSION: 1.20
*
-* DATE: 01 Oct 2021
+* DATE: 03 Oct 2025
*
* Common header file for the Windows Object Explorer ImageScope plugin.
*
@@ -51,7 +51,6 @@
#include "sdk/extdef.h"
#include "resource.h"
#include "query.h"
-#include "sup.h"
#include "ui.h"
//declared in main.c
@@ -65,3 +64,4 @@ extern WINOBJEX_PLUGIN* g_plugin;
#define kdDebugPrint(f, ...)
#endif
+#include "utils.h"
diff --git a/Source/Plugins/ImageScope/main.c b/Source/Plugins/ImageScope/main.c
index 3ff33855..2f6fcdbf 100644
--- a/Source/Plugins/ImageScope/main.c
+++ b/Source/Plugins/ImageScope/main.c
@@ -4,9 +4,9 @@
*
* TITLE: MAIN.C
*
-* VERSION: 1.21
+* VERSION: 1.22
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* WinObjEx64 ImageScope plugin.
*
diff --git a/Source/Plugins/ImageScope/query.c b/Source/Plugins/ImageScope/query.c
index 49bd5a20..15638002 100644
--- a/Source/Plugins/ImageScope/query.c
+++ b/Source/Plugins/ImageScope/query.c
@@ -4,9 +4,9 @@
*
* TITLE: QUERY.C
*
-* VERSION: 1.21
+* VERSION: 1.22
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* ImageScope main logic.
*
diff --git a/Source/Plugins/ImageScope/sup.c b/Source/Plugins/ImageScope/sup.c
deleted file mode 100644
index 028be67c..00000000
--- a/Source/Plugins/ImageScope/sup.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*******************************************************************************
-*
-* (C) COPYRIGHT AUTHORS, 2020 - 2025
-*
-* TITLE: SUP.C
-*
-* VERSION: 1.11
-*
-* DATE: 22 Aug 2025
-*
-* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-* PARTICULAR PURPOSE.
-*
-*******************************************************************************/
-#include "global.h"
-
-/*
-* supHeapAlloc
-*
-* Purpose:
-*
-* RtlAllocateHeap wrapper.
-*
-*/
-PVOID supHeapAlloc(
- _In_ SIZE_T Size
-)
-{
- return RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Size);
-}
-
-/*
-* supHeapFree
-*
-* Purpose:
-*
-* RtlFreeHeap wrapper.
-*
-*/
-BOOL supHeapFree(
- _In_ PVOID Memory
-)
-{
- return RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Memory);
-}
-
-/*
-* supSetWaitCursor
-*
-* Purpose:
-*
-* Sets cursor state.
-*
-*/
-VOID supSetWaitCursor(
- _In_ BOOL fSet
-)
-{
- HCURSOR h = LoadCursor(NULL, fSet ? IDC_WAIT : IDC_ARROW);
- if (h) {
- SetCursor(h);
- }
-}
-
-/*
-* supMapSection
-*
-* Purpose:
-*
-* Return pointer to section mapped view.
-*
-*/
-NTSTATUS supMapSection(
- _In_ HANDLE SectionHandle,
- _Out_ PVOID* BaseAddress,
- _Out_ SIZE_T* ViewSize
-)
-{
- NTSTATUS ntStatus;
- SECTION_BASIC_INFORMATION sbi;
- SIZE_T bytesReturned;
-
- *BaseAddress = NULL;
- *ViewSize = 0;
-
- __try {
-
- //
- // Check if this is image mapped file.
- //
- ntStatus = NtQuerySection(SectionHandle,
- SectionBasicInformation,
- (PVOID)&sbi,
- sizeof(SECTION_BASIC_INFORMATION),
- &bytesReturned);
-
- if (!NT_SUCCESS(ntStatus))
- __leave;
-
- if (!((sbi.AllocationAttributes & SEC_IMAGE) &&
- (sbi.AllocationAttributes & SEC_FILE)))
- {
- ntStatus = STATUS_NOT_SUPPORTED;
- __leave;
- }
-
- ntStatus = NtMapViewOfSection(SectionHandle,
- NtCurrentProcess(),
- BaseAddress,
- 0,
- 0,
- NULL,
- ViewSize,
- ViewUnmap,
- 0,
- PAGE_READONLY);
-
- }
- __finally {
- if (AbnormalTermination())
- ntStatus = STATUS_ACCESS_VIOLATION;
- }
-
- return ntStatus;
-}
-
-/*
-* supSaveDialogExecute
-*
-* Purpose:
-*
-* Display SaveDialog.
-*
-*/
-BOOL supSaveDialogExecute(
- _In_ HWND OwnerWindow,
- _Inout_ LPWSTR SaveFileName,
- _In_ LPWSTR lpDialogFilter
-)
-{
- OPENFILENAME tag1;
-
- RtlSecureZeroMemory(&tag1, sizeof(OPENFILENAME));
-
- tag1.lStructSize = sizeof(OPENFILENAME);
- tag1.hwndOwner = OwnerWindow;
- tag1.lpstrFilter = lpDialogFilter;
- tag1.lpstrFile = SaveFileName;
- tag1.nMaxFile = MAX_PATH;
- tag1.lpstrInitialDir = NULL;
- tag1.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
-
- return GetSaveFileName(&tag1);
-}
-
-size_t supxEscStrlen(wchar_t* s)
-{
- size_t result = 2;
- wchar_t* s0;
- if (s == NULL)
- return 0;
-
- s0 = s;
-
- while (*s)
- {
- if (*s == L'"')
- ++result;
- ++s;
- }
-
- return result + (s - s0);
-}
-
-wchar_t* supxEscStrcpy(wchar_t* dst, wchar_t* src)
-{
- if (dst == NULL || src == NULL)
- return dst;
-
- *(dst++) = L'"';
-
- while ((*dst = *src) != L'\0')
- {
- if (*src == L'"') {
- ++src;
- ++dst;
- *(dst - 0) = L'"';
- *(dst) = L'\0';
- continue;
- }
- ++src;
- ++dst;
- }
-
- *(dst++) = L'"';
- *dst = L'\0';
-
- return dst;
-}
-
-/*
-* supxListViewExportCSV
-*
-* Purpose:
-*
-* Export listview entries into file in csv format.
-*
-*/
-BOOL supxListViewExportCSV(
- _In_ HWND List,
- _In_ PWCHAR FileName)
-{
- HWND hdr = ListView_GetHeader(List);
- int pass, i, c, col_count = Header_GetItemCount(hdr), icount = 1 + ListView_GetItemCount(List);
- HDITEM ih;
- LVITEM lvi;
- PWCHAR text, buffer0 = NULL, buffer = NULL;
- BOOL result = FALSE;
- SIZE_T total_lenght;
- DWORD iobytes;
- HANDLE f;
-
- text = (PWCHAR)ntsupVirtualAlloc(32768 * sizeof(WCHAR));
- if (!text)
- return FALSE;
-
- RtlZeroMemory(&ih, sizeof(HDITEM));
- RtlZeroMemory(&lvi, sizeof(LVITEM));
-
- ih.pszText = lvi.pszText = text;
- ih.cchTextMax = lvi.cchTextMax = 32767;
-
- for (pass = 0; pass < 2; ++pass)
- {
- total_lenght = 0;
-
- for (i = 0; i < icount; ++i)
- {
- for (c = 0; c < col_count; ++c)
- {
- text[0] = L'\0';
- if (i == 0)
- {
- ih.mask = HDI_TEXT | HDI_ORDER;
- ih.iOrder = c;
- Header_GetItem(hdr, c, &ih);
- }
- else
- {
- lvi.mask = LVIF_TEXT;
- lvi.iItem = i - 1;
- lvi.iSubItem = c;
- ListView_GetItem(List, &lvi);
- }
- total_lenght += supxEscStrlen(text) + 1;
-
- if (buffer)
- {
- buffer = supxEscStrcpy(buffer, text);
- if (c != col_count - 1)
- {
- *(buffer++) = L',';
- }
- else
- {
- *(buffer++) = L'\r';
- *(buffer++) = L'\n';
- }
- }
- }
- ++total_lenght;
- }
-
- if (buffer0 == NULL)
- {
- buffer0 = (PWCHAR)ntsupVirtualAlloc((1 + total_lenght) * sizeof(WCHAR));
- if (!buffer0)
- break;
- }
- else
- {
- f = CreateFile(FileName, GENERIC_WRITE | SYNCHRONIZE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (f != INVALID_HANDLE_VALUE)
- {
- WriteFile(f, buffer0, (DWORD)(total_lenght * sizeof(WCHAR)), &iobytes, NULL);
- CloseHandle(f);
- result = TRUE;
- }
- ntsupVirtualFree(buffer0);
- }
- buffer = buffer0;
- }
-
- ntsupVirtualFree(text);
- return result;
-}
-
-/*
-* supListViewExportToFile
-*
-* Purpose:
-*
-* Export listview contents to the specified file.
-*
-*/
-BOOL supListViewExportToFile(
- _In_ LPWSTR FileName,
- _In_ HWND WindowHandle,
- _In_ HWND ListView
-)
-{
- BOOL bResult = FALSE;
- WCHAR szExportFileName[MAX_PATH + 1];
-
- RtlSecureZeroMemory(&szExportFileName, sizeof(szExportFileName));
-
- _strcpy(szExportFileName, FileName);
- if (supSaveDialogExecute(WindowHandle,
- (LPWSTR)&szExportFileName,
- T_CSV_FILE_FILTER))
- {
- SetCapture(WindowHandle);
- supSetWaitCursor(TRUE);
-
- bResult = supxListViewExportCSV(ListView, szExportFileName);
-
- supSetWaitCursor(FALSE);
- ReleaseCapture();
- }
-
- return bResult;
-}
-
-/*
-* supStatusBarSetText
-*
-* Purpose:
-*
-* Display status in status bar part.
-*
-*/
-VOID supStatusBarSetText(
- _In_ HWND hwndStatusBar,
- _In_ WPARAM partIndex,
- _In_ LPWSTR lpText
-)
-{
- SendMessage(hwndStatusBar, SB_SETTEXT, partIndex, (LPARAM)lpText);
-}
-
-/*
-* supTreeListAddItem
-*
-* Purpose:
-*
-* Insert new treelist item.
-*
-*/
-HTREEITEM supTreeListAddItem(
- _In_ HWND TreeList,
- _In_opt_ HTREEITEM hParent,
- _In_ UINT mask,
- _In_ UINT state,
- _In_ UINT stateMask,
- _In_opt_ LPWSTR pszText,
- _In_opt_ PVOID subitems
-)
-{
- TVINSERTSTRUCT tvitem;
- PTL_SUBITEMS si = (PTL_SUBITEMS)subitems;
-
- RtlSecureZeroMemory(&tvitem, sizeof(tvitem));
- tvitem.hParent = hParent;
- tvitem.item.mask = mask;
- tvitem.item.state = state;
- tvitem.item.stateMask = stateMask;
- tvitem.item.pszText = pszText;
- tvitem.hInsertAfter = TVI_LAST;
- return TreeList_InsertTreeItem(TreeList, &tvitem, si);
-}
-
-/*
-* supAddListViewColumn
-*
-* Purpose:
-*
-* Insert list view column.
-*
-*/
-INT supAddListViewColumn(
- _In_ HWND ListViewHwnd,
- _In_ INT ColumnIndex,
- _In_ INT SubItemIndex,
- _In_ INT OrderIndex,
- _In_ INT ImageIndex,
- _In_ INT Format,
- _In_ LPWSTR Text,
- _In_ INT Width,
- _In_ INT DpiValue
-)
-{
- LVCOLUMN column;
-
- column.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT | LVCF_WIDTH | LVCF_ORDER | LVCF_IMAGE;
- column.fmt = Format;
- column.cx = ScaleDPI(Width, DpiValue);
- column.pszText = Text;
- column.iSubItem = SubItemIndex;
- column.iOrder = OrderIndex;
- column.iImage = ImageIndex;
-
- return ListView_InsertColumn(ListViewHwnd, ColumnIndex, &column);
-}
-
-/*
-* supListViewAddCopyValueItem
-*
-* Purpose:
-*
-* Add copy to clipboard menu item depending on hit column.
-*
-*/
-BOOL supListViewAddCopyValueItem(
- _In_ HMENU hMenu,
- _In_ HWND hwndLv,
- _In_ UINT uId,
- _In_ UINT uPos,
- _In_ POINT* lpPoint,
- _Out_ INT* pItemHit,
- _Out_ INT* pColumnHit
-)
-{
- LVHITTESTINFO lvht;
- LVCOLUMN lvc;
- WCHAR szItem[MAX_PATH * 2];
- WCHAR szColumn[MAX_PATH + 1];
-
- *pColumnHit = -1;
- *pItemHit = -1;
-
- RtlSecureZeroMemory(&lvht, sizeof(lvht));
- lvht.pt.x = lpPoint->x;
- lvht.pt.y = lpPoint->y;
- ScreenToClient(hwndLv, &lvht.pt);
- if (ListView_SubItemHitTest(hwndLv, &lvht) == -1)
- return FALSE;
-
- RtlSecureZeroMemory(&lvc, sizeof(lvc));
- RtlSecureZeroMemory(&szColumn, sizeof(szColumn));
-
- lvc.mask = LVCF_TEXT;
- lvc.pszText = szColumn;
- lvc.cchTextMax = MAX_PATH;
- if (ListView_GetColumn(hwndLv, lvht.iSubItem, &lvc)) {
- _strcpy(szItem, TEXT("Copy \""));
- _strcat(szItem, szColumn);
- _strcat(szItem, TEXT("\""));
- if (InsertMenu(hMenu, uPos, MF_BYCOMMAND, uId, szItem)) {
- *pColumnHit = lvht.iSubItem;
- *pItemHit = lvht.iItem;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/*
-* supGetItemText
-*
-* Purpose:
-*
-* Returns buffer with text from the given listview item.
-*
-* Returned buffer must be freed with supHeapFree after usage.
-*
-*/
-LPWSTR supGetItemText(
- _In_ HWND ListView,
- _In_ INT nItem,
- _In_ INT nSubItem,
- _Out_opt_ PSIZE_T lpSize //length in bytes
-)
-{
- INT len;
- LPARAM sz = 0;
- LV_ITEM item;
-
- RtlSecureZeroMemory(&item, sizeof(item));
-
- item.iItem = nItem;
- item.iSubItem = nSubItem;
- len = 128;
- do {
- len *= 2;
- item.cchTextMax = len;
- if (item.pszText) {
- supHeapFree(item.pszText);
- item.pszText = NULL;
- }
- item.pszText = (LPWSTR)supHeapAlloc(len * sizeof(WCHAR));
- sz = SendMessage(ListView, LVM_GETITEMTEXT, (WPARAM)item.iItem, (LPARAM)&item);
- } while (sz == (LPARAM)len - 1);
-
- //empty string
- if (sz == 0) {
- if (item.pszText) {
- supHeapFree(item.pszText);
- item.pszText = NULL;
- }
- }
-
- if (lpSize) {
- *lpSize = sz * sizeof(WCHAR);
- }
- return item.pszText;
-}
-
-/*
-* supClipboardCopy
-*
-* Purpose:
-*
-* Copy text to the clipboard.
-*
-*/
-VOID supClipboardCopy(
- _In_ LPWSTR lpText,
- _In_ SIZE_T cbText
-)
-{
- LPWSTR lptstrCopy;
- HGLOBAL hglbCopy = NULL;
- SIZE_T dwSize;
- BOOL dataSet = FALSE;
-
- if (!OpenClipboard(NULL))
- return;
-
- __try {
- EmptyClipboard();
- dwSize = cbText + sizeof(UNICODE_NULL);
- hglbCopy = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize);
- if (hglbCopy == NULL)
- __leave;
-
- lptstrCopy = (LPWSTR)GlobalLock(hglbCopy);
- if (lptstrCopy == NULL)
- __leave;
-
- RtlCopyMemory(lptstrCopy, lpText, cbText);
- GlobalUnlock(hglbCopy);
-
- dataSet = SetClipboardData(CF_UNICODETEXT, hglbCopy) != NULL;
- if (dataSet) {
- hglbCopy = NULL;
- }
- }
- __finally {
- CloseClipboard();
- if (hglbCopy != NULL) {
- GlobalFree(hglbCopy);
- }
- }
-}
-
-/*
-* supListViewCopyItemValueToClipboard
-*
-* Purpose:
-*
-* Copy selected item text to the clipboard.
-*
-*/
-BOOL supListViewCopyItemValueToClipboard(
- _In_ HWND hwndListView,
- _In_ INT iItem,
- _In_ INT iSubItem
-)
-{
- SIZE_T cbText;
- LPWSTR lpText;
-
- if ((iSubItem < 0) || (iItem < 0))
- return FALSE;
-
- lpText = supGetItemText(hwndListView,
- iItem,
- iSubItem,
- NULL);
-
- if (lpText) {
- cbText = _strlen(lpText) * sizeof(WCHAR);
- supClipboardCopy(lpText, cbText);
- supHeapFree(lpText);
- return TRUE;
- }
- else {
- if (OpenClipboard(NULL)) {
- EmptyClipboard();
- CloseClipboard();
- }
- }
-
- return FALSE;
-}
-
-/*
-* supFreeDuplicatedUnicodeString
-*
-* Purpose:
-*
-* Release memory allocated for duplicated string.
-*
-*/
-_Success_(return)
-BOOL supFreeDuplicatedUnicodeString(
- _In_ HANDLE HeapHandle,
- _Inout_ PUNICODE_STRING DuplicatedString,
- _In_ BOOL DoZeroMemory
-)
-{
- BOOL bResult = FALSE;
- if (DuplicatedString->Buffer) {
- bResult = RtlFreeHeap(HeapHandle, 0, DuplicatedString->Buffer);
- if (DoZeroMemory) {
- DuplicatedString->Buffer = NULL;
- DuplicatedString->Length = DuplicatedString->MaximumLength = 0;
- }
- }
- return bResult;
-}
-
-/*
-* supDuplicateUnicodeString
-*
-* Purpose:
-*
-* Duplicate existing UNICODE_STRING to another without RtlDuplicateUnicodeString.
-*
-* Note: Use supFreeDuplicatedUnicodeString to release allocated memory.
-*
-*/
-_Success_(return)
-BOOL supDuplicateUnicodeString(
- _In_ HANDLE HeapHandle,
- _Out_ PUNICODE_STRING DestinationString,
- _In_ PUNICODE_STRING SourceString
-)
-{
- USHORT maxLength = SourceString->MaximumLength;
- PWCHAR strBuffer;
-
- if (maxLength == 0 || maxLength < SourceString->Length)
- return FALSE;
-
- strBuffer = (PWCHAR)RtlAllocateHeap(HeapHandle, HEAP_ZERO_MEMORY, (SIZE_T)maxLength);
- if (strBuffer) {
- DestinationString->Buffer = strBuffer;
- DestinationString->MaximumLength = maxLength;
- RtlCopyUnicodeString(DestinationString, SourceString);
- return TRUE;
- }
-
- return FALSE;
-}
diff --git a/Source/Plugins/ImageScope/ui.c b/Source/Plugins/ImageScope/ui.c
index 51df6718..60d18fdf 100644
--- a/Source/Plugins/ImageScope/ui.c
+++ b/Source/Plugins/ImageScope/ui.c
@@ -4,9 +4,9 @@
*
* TITLE: UI.C
*
-* VERSION: 1.21
+* VERSION: 1.22
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* WinObjEx64 ImageScope UI.
*
@@ -1150,7 +1150,7 @@ VOID TabsDumpList(
return;
}
- supListViewExportToFile(lpFileName, hWndDlg, hwndList);
+ supListViewExportToFile(lpFileName, hWndDlg, hwndList, T_CSV_FILE_FILTER);
}
VOID TabsListViewCopyItem(
diff --git a/Source/Plugins/ImageScope/ui.h b/Source/Plugins/ImageScope/ui.h
index 26bc402b..f580331c 100644
--- a/Source/Plugins/ImageScope/ui.h
+++ b/Source/Plugins/ImageScope/ui.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2020 - 2022
+* (C) COPYRIGHT AUTHORS, 2020 - 2025
*
* TITLE: UI.H
*
-* VERSION: 1.02
+* VERSION: 1.20
*
-* DATE: 08 Jun 2022
+* DATE: 03 Oct 2025
*
* WinObjEx64 ImageScope UI constants, definitions and includes.
*
@@ -22,10 +22,6 @@
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "uxtheme.lib")
-#define DefaultSystemDpi 96
-
-#define ScaleDPI(Value, CurrentDPI) MulDiv(Value, CurrentDPI, DefaultSystemDpi)
-
#define T_PLUGIN_NAME TEXT("ImageScope")
#define IMAGESCOPE_WNDTITLE T_PLUGIN_NAME
#define T_IMS_PROP TEXT("ImsProp")
@@ -76,16 +72,6 @@ typedef struct _IMS_TAB {
LPTSTR TabCaption;
} IMS_TAB;
-typedef struct _TL_SUBITEMS_FIXED {
- ULONG Count;
- ULONG ColorFlags;
- COLORREF BgColor;
- COLORREF FontColor;
- PVOID UserParam;
- LPTSTR CustomTooltip;
- LPTSTR Text[2];
-} TL_SUBITEMS_FIXED, * PTL_SUBITEMS_FIXED;
-
typedef struct _VALUE_DESC {
LPWSTR lpDescription;
DWORD dwValue;
@@ -97,5 +83,4 @@ LRESULT CALLBACK MainWindowProc(
_In_ WPARAM wParam,
_In_ LPARAM lParam);
-BOOL RunUI(
- _In_ GUI_CONTEXT* Context);
+BOOL RunUI(_In_ GUI_CONTEXT* Context);
diff --git a/Source/Plugins/Sonar/Resource.rc b/Source/Plugins/Sonar/Resource.rc
index 35fecc26..4b96fcf1 100644
Binary files a/Source/Plugins/Sonar/Resource.rc and b/Source/Plugins/Sonar/Resource.rc differ
diff --git a/Source/Plugins/Sonar/Sonar.vcxproj b/Source/Plugins/Sonar/Sonar.vcxproj
index 7b952206..239803ba 100644
--- a/Source/Plugins/Sonar/Sonar.vcxproj
+++ b/Source/Plugins/Sonar/Sonar.vcxproj
@@ -106,9 +106,9 @@
+
-
@@ -117,11 +117,11 @@
+
-
diff --git a/Source/Plugins/Sonar/Sonar.vcxproj.filters b/Source/Plugins/Sonar/Sonar.vcxproj.filters
index f1b86ce1..7f866e0d 100644
--- a/Source/Plugins/Sonar/Sonar.vcxproj.filters
+++ b/Source/Plugins/Sonar/Sonar.vcxproj.filters
@@ -57,15 +57,15 @@
minirtl
-
- Source Files
-
minirtl
minirtl
+
+ Source Files
+
@@ -98,12 +98,12 @@
ntos
-
- Header Files
-
ntos
+
+ Header Files
+
diff --git a/Source/Plugins/Sonar/global.h b/Source/Plugins/Sonar/global.h
index e441afc9..7b7933e7 100644
--- a/Source/Plugins/Sonar/global.h
+++ b/Source/Plugins/Sonar/global.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2019 - 2021
+* (C) COPYRIGHT AUTHORS, 2019 - 2025
*
* TITLE: GLOBAL.H
*
-* VERSION: 1.03
+* VERSION: 1.20
*
-* DATE: 27 July 2021
+* DATE: 03 Oct 2025
*
* Common header file for the Windows Object Explorer Sonar plugin.
*
@@ -45,7 +45,7 @@
#include "ntos/ntsup.h"
#include "ntos/ntbuilds.h"
#include "plugin_def.h"
-#include "sup.h"
+#include "utils.h"
#include "ui.h"
#include "resource.h"
#include "ndis.h"
diff --git a/Source/Plugins/Sonar/main.c b/Source/Plugins/Sonar/main.c
index faa2bed4..c1bad8af 100644
--- a/Source/Plugins/Sonar/main.c
+++ b/Source/Plugins/Sonar/main.c
@@ -4,9 +4,9 @@
*
* TITLE: MAIN.C
*
-* VERSION: 1.17
+* VERSION: 1.20
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* WinObjEx64 Sonar plugin.
*
@@ -101,7 +101,7 @@ INT AddListViewColumn(
if (ImageIndex != I_IMAGENONE) column.mask |= LVCF_IMAGE;
column.fmt = Format;
- column.cx = SCALE_DPI_VALUE(Width, g_ctx.CurrentDPI);
+ column.cx = ScaleDPI(Width, g_ctx.CurrentDPI);
column.pszText = Text;
column.iSubItem = SubItemIndex;
column.iOrder = OrderIndex;
@@ -270,14 +270,14 @@ BOOL AddProtocolToTreeList(
&subitems);
if (lpImageName)
- HeapMemoryFree(lpImageName);
+ supHeapFree(lpImageName);
if ((ULONG_PTR)ProtoBlock->OpenQueue > g_ctx.ParamBlock.SystemRangeStart) {
bResult = ListOpenQueue(hTreeItem, (ULONG_PTR)ProtoBlock->OpenQueue);
}
- HeapMemoryFree(lpProtocolName);
+ supHeapFree(lpProtocolName);
}
return bResult;
@@ -631,8 +631,8 @@ VOID DumpProtocolInfo(
pModulesList = ntsupGetLoadedModulesListEx(
FALSE,
NULL,
- (PNTSUPMEMALLOC)HeapMemoryAlloc,
- (PNTSUPMEMFREE)HeapMemoryFree);
+ (PNTSUPMEMALLOC)supHeapAlloc,
+ (PNTSUPMEMFREE)supHeapFree);
if (pModulesList == NULL) {
StatusBarSetText(TEXT("Error, cannot query system information!"));
@@ -645,7 +645,7 @@ VOID DumpProtocolInfo(
RtlSecureZeroMemory(&ProtoBlock, sizeof(ProtoBlock));
if (!ReadAndConvertProtocolBlock(ProtocolAddress, &ProtoBlock, NULL)) {
- HeapMemoryFree(pModulesList);
+ supHeapFree(pModulesList);
StringCchPrintf(szBuffer, RTL_NUMBER_OF(szBuffer),
TEXT("Error, read NDIS_PROTOCOL_BLOCK at 0x%llX failed!"), ProtocolAddress);
@@ -676,7 +676,7 @@ VOID DumpProtocolInfo(
if (DumpedString) {
StringCchPrintf(szBuffer, 64, TEXT("0x%llX"), (ULONG_PTR)ProtoBlock.BindDeviceName);
xxxDumpProtocolBlock(TEXT("BindDeviceName"), szBuffer, DumpedString);
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
}
//
@@ -686,7 +686,7 @@ VOID DumpProtocolInfo(
if (DumpedString) {
StringCchPrintf(szBuffer, 64, TEXT("0x%llX"), (ULONG_PTR)ProtoBlock.RootDeviceName);
xxxDumpProtocolBlock(TEXT("RootDeviceName"), szBuffer, DumpedString);
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
}
//
@@ -704,7 +704,7 @@ VOID DumpProtocolInfo(
DumpHandlers(ProtocolHandlers, _countof(ProtocolHandlers), g_lpszProtocolBlockHandlers, pModulesList);
- HeapMemoryFree(pModulesList);
+ supHeapFree(pModulesList);
StatusBarSetText(TEXT("List protocol information - OK"));
}
@@ -737,8 +737,8 @@ VOID DumpOpenBlockInfo(
pModulesList = ntsupGetLoadedModulesListEx(
FALSE,
NULL,
- (PNTSUPMEMALLOC)HeapMemoryAlloc,
- (PNTSUPMEMFREE)HeapMemoryFree);
+ (PNTSUPMEMALLOC)supHeapAlloc,
+ (PNTSUPMEMFREE)supHeapFree);
if (pModulesList == NULL) {
StatusBarSetText(TEXT("Error, cannot query system information!"));
@@ -751,7 +751,7 @@ VOID DumpOpenBlockInfo(
RtlSecureZeroMemory(&OpenBlock, sizeof(OpenBlock));
if (!ReadAndConvertOpenBlock(OpenBlockAddress, &OpenBlock, NULL)) {
- HeapMemoryFree(pModulesList);
+ supHeapFree(pModulesList);
StringCchPrintf(szBuffer, RTL_NUMBER_OF(szBuffer),
TEXT("Error, read NDIS_OPEN_BLOCK at 0x%llX failed!"), OpenBlockAddress);
@@ -768,7 +768,7 @@ VOID DumpOpenBlockInfo(
if (DumpedString) {
StringCchPrintf(szBuffer, 64, TEXT("0x%llX"), (ULONG_PTR)OpenBlock.BindDeviceName);
xxxDumpProtocolBlock(TEXT("BindDeviceName"), szBuffer, DumpedString);
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
}
//
@@ -778,7 +778,7 @@ VOID DumpOpenBlockInfo(
if (DumpedString) {
StringCchPrintf(szBuffer, 64, TEXT("0x%llX"), (ULONG_PTR)OpenBlock.RootDeviceName);
xxxDumpProtocolBlock(TEXT("RootDeviceName"), szBuffer, DumpedString);
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
}
//
@@ -787,7 +787,7 @@ VOID DumpOpenBlockInfo(
RtlCopyMemory(OpenBlockHandlers, &OpenBlock.Handlers, sizeof(OpenBlockHandlers));
DumpHandlers(OpenBlockHandlers, _countof(OpenBlockHandlers), g_lpszOpenBlockHandlers, pModulesList);
- HeapMemoryFree(pModulesList);
+ supHeapFree(pModulesList);
StatusBarSetText(TEXT("List open block information - OK"));
}
@@ -1308,8 +1308,8 @@ DWORD WINAPI PluginThread(
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
- SCALE_DPI_VALUE(800, g_ctx.CurrentDPI),
- SCALE_DPI_VALUE(600, g_ctx.CurrentDPI),
+ ScaleDPI(800, g_ctx.CurrentDPI),
+ ScaleDPI(600, g_ctx.CurrentDPI),
NULL,
NULL,
g_thisDll,
@@ -1435,15 +1435,15 @@ DWORD WINAPI PluginThread(
RtlSecureZeroMemory(&hdritem, sizeof(hdritem));
hdritem.mask = HDI_FORMAT | HDI_TEXT | HDI_WIDTH;
hdritem.fmt = HDF_LEFT | HDF_BITMAP_ON_RIGHT | HDF_STRING;
- hdritem.cxy = SCALE_DPI_VALUE(300, g_ctx.CurrentDPI);
+ hdritem.cxy = ScaleDPI(300, g_ctx.CurrentDPI);
hdritem.pszText = TEXT("Protocol");
TreeList_InsertHeaderItem(g_ctx.TreeList, 0, &hdritem);
- hdritem.cxy = SCALE_DPI_VALUE(130, g_ctx.CurrentDPI);
+ hdritem.cxy = ScaleDPI(130, g_ctx.CurrentDPI);
hdritem.pszText = TEXT("Object");
TreeList_InsertHeaderItem(g_ctx.TreeList, 1, &hdritem);
- hdritem.cxy = SCALE_DPI_VALUE(200, g_ctx.CurrentDPI);
+ hdritem.cxy = ScaleDPI(200, g_ctx.CurrentDPI);
hdritem.pszText = TEXT("Additional Information");
TreeList_InsertHeaderItem(g_ctx.TreeList, 2, &hdritem);
diff --git a/Source/Plugins/Sonar/query.c b/Source/Plugins/Sonar/query.c
index 1fdcbf39..b9234c7f 100644
--- a/Source/Plugins/Sonar/query.c
+++ b/Source/Plugins/Sonar/query.c
@@ -4,9 +4,9 @@
*
* TITLE: QUERY.C
*
-* VERSION: 1.16
+* VERSION: 1.20
*
-* DATE: 14 Jun 2025
+* DATE: 03 Oct 2025
*
* Query NDIS specific data.
*
@@ -111,8 +111,8 @@ ULONG_PTR QueryProtocolList(
miSpace = ntsupGetSystemInfoEx(
SystemModuleInformation,
NULL,
- (PNTSUPMEMALLOC)HeapMemoryAlloc,
- (PNTSUPMEMFREE)HeapMemoryFree);
+ (PNTSUPMEMALLOC)supHeapAlloc,
+ (PNTSUPMEMFREE)supHeapFree);
if (miSpace == NULL)
break;
@@ -181,7 +181,7 @@ ULONG_PTR QueryProtocolList(
} while (FALSE);
if (hModule) FreeLibrary(hModule);
- if (miSpace) HeapMemoryFree(miSpace);
+ if (miSpace) supHeapFree(miSpace);
return Result;
}
@@ -193,7 +193,7 @@ ULONG_PTR QueryProtocolList(
*
* Return dumped object version aware.
*
-* Use HeapMemoryFree to free returned buffer.
+* Use supHeapFree to free returned buffer.
*
*/
PVOID DumpObjectWithSpecifiedSize(
@@ -210,7 +210,7 @@ PVOID DumpObjectWithSpecifiedSize(
if (ReadSize) *ReadSize = 0;
if (ReadVersion) *ReadVersion = 0;
- ObjectBuffer = HeapMemoryAlloc(BufferSize);
+ ObjectBuffer = supHeapAlloc(BufferSize);
if (ObjectBuffer == NULL) {
return NULL;
}
@@ -221,7 +221,7 @@ PVOID DumpObjectWithSpecifiedSize(
(ULONG)ObjectSize,
NULL))
{
- HeapMemoryFree(ObjectBuffer);
+ supHeapFree(ObjectBuffer);
return NULL;
}
@@ -240,7 +240,7 @@ PVOID DumpObjectWithSpecifiedSize(
*
* Return dumped NDIS_PROTOCOL_BLOCK version aware.
*
-* Use HeapMemoryFree to free returned buffer.
+* Use supHeapFree to free returned buffer.
*
*/
PVOID DumpProtocolBlockVersionAware(
@@ -291,6 +291,7 @@ PVOID DumpProtocolBlockVersionAware(
case NT_WIN11_22H2:
case NT_WIN11_23H2:
case NT_WIN11_24H2:
+ case NT_WIN11_25H2:
default:
ObjectSize = sizeof(NDIS_PROTOCOL_BLOCK_18362_25905);
ObjectVersion = 5;
@@ -312,7 +313,7 @@ PVOID DumpProtocolBlockVersionAware(
*
* Return dumped NDIS_OPEN_BLOCK version aware.
*
-* Use HeapMemoryFree to free returned buffer.
+* Use supHeapFree to free returned buffer.
*
*/
PVOID DumpOpenBlockVersionAware(
@@ -364,6 +365,7 @@ PVOID DumpOpenBlockVersionAware(
case NT_WIN11_22H2:
case NT_WIN11_23H2:
case NT_WIN11_24H2:
+ case NT_WIN11_25H2:
default:
ObjectSize = sizeof(NDIS_OPEN_BLOCK_22621_25905);
ObjectVersion = NDIS_OPEN_BLOCK_VERSION_WIN11_22_25H2;
@@ -384,7 +386,7 @@ PVOID DumpOpenBlockVersionAware(
*
* Read UNICODE_STRING buffer from kernel.
*
-* Use HeapMemoryFree to free returned buffer.
+* Use supHeapFree to free returned buffer.
*
*/
PVOID DumpUnicodeString(
@@ -426,19 +428,19 @@ PVOID DumpUnicodeString(
return NULL;
Size = (SIZE_T)tempString.Length + MAX_PATH;
- DumpedString = (PVOID)HeapMemoryAlloc(Size);
+ DumpedString = (PVOID)supHeapAlloc(Size);
if (DumpedString) {
if (!g_ctx.ParamBlock.ReadSystemMemoryEx((ULONG_PTR)tempString.Buffer,
DumpedString,
tempString.Length,
&readBytes))
{
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
return NULL;
}
if (readBytes != tempString.Length) {
- HeapMemoryFree(DumpedString);
+ supHeapFree(DumpedString);
return NULL;
}
}
@@ -491,6 +493,7 @@ ULONG GetNextProtocolOffset(
case NT_WIN11_22H2:
case NT_WIN11_23H2:
case NT_WIN11_24H2:
+ case NT_WIN11_25H2:
default:
Offset = FIELD_OFFSET(NDIS_PROTOCOL_BLOCK_18362_25905, NextProtocol);
break;
@@ -1209,7 +1212,7 @@ BOOL ReadAndConvertProtocolBlock(
*ObjectVersion = objectVersion;
}
- HeapMemoryFree(objectPtr);
+ supHeapFree(objectPtr);
return Result;
}
@@ -1247,7 +1250,7 @@ BOOL ReadAndConvertOpenBlock(
*ObjectVersion = objectVersion;
}
- HeapMemoryFree(objectPtr);
+ supHeapFree(objectPtr);
return Result;
}
diff --git a/Source/Plugins/Sonar/sup.h b/Source/Plugins/Sonar/sup.h
deleted file mode 100644
index d15bc0a0..00000000
--- a/Source/Plugins/Sonar/sup.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
-*
-* (C) COPYRIGHT AUTHORS, 2021 - 2024
-*
-* TITLE: SUP.H
-*
-* VERSION: 1.14
-*
-* DATE: 04 Jun 2024
-*
-* Sonar plugin support definitions and declarations.
-*
-* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-* PARTICULAR PURPOSE.
-*
-*******************************************************************************/
-
-#include "global.h"
-
-PVOID HeapMemoryAlloc(
- _In_ SIZE_T Size);
-
-BOOL HeapMemoryFree(
- _In_ PVOID Memory);
-
-BOOL supGetWin32FileName(
- _In_ LPWSTR FileName,
- _Inout_ LPWSTR Win32FileName,
- _In_ SIZE_T ccWin32FileName);
-
-VOID supClipboardCopy(
- _In_ LPWSTR lpText,
- _In_ SIZE_T cbText);
-
-BOOL supTreeListAddCopyValueItem(
- _In_ HMENU hMenu,
- _In_ HWND hwndTreeList,
- _In_ UINT uId,
- _In_ UINT uPos,
- _In_ LPARAM lParam,
- _In_ INT* pSubItemHit);
-
-LPWSTR supGetItemText(
- _In_ HWND ListView,
- _In_ INT nItem,
- _In_ INT nSubItem,
- _Out_opt_ PSIZE_T lpSize);
-
-LPWSTR supGetItemText2(
- _In_ HWND ListView,
- _In_ INT nItem,
- _In_ INT nSubItem,
- _In_ WCHAR* pszText,
- _In_ UINT cchText);
-
-BOOL supListViewAddCopyValueItem(
- _In_ HMENU hMenu,
- _In_ HWND hwndLv,
- _In_ UINT uId,
- _In_ UINT uPos,
- _In_ POINT* lpPoint,
- _Out_ INT* pItemHit,
- _Out_ INT* pColumnHit);
-
-BOOL supListViewCopyItemValueToClipboard(
- _In_ HWND hwndListView,
- _In_ INT iItem,
- _In_ INT iSubItem);
-
-BOOL supTreeListCopyItemValueToClipboard(
- _In_ HWND hwndTreeList,
- _In_ INT tlSubItemHit);
-
-INT supGetMaxCompareTwoFixedStrings(
- _In_ HWND ListView,
- _In_ LPARAM lParam1,
- _In_ LPARAM lParam2,
- _In_ LPARAM lParamSort,
- _In_ BOOL Inverse);
-
-INT supGetMaxOfTwoU64FromHex(
- _In_ HWND ListView,
- _In_ LPARAM lParam1,
- _In_ LPARAM lParam2,
- _In_ LPARAM lParamSort,
- _In_ BOOL Inverse);
diff --git a/Source/Plugins/Sonar/ui.h b/Source/Plugins/Sonar/ui.h
index d2924090..b62dcaa5 100644
--- a/Source/Plugins/Sonar/ui.h
+++ b/Source/Plugins/Sonar/ui.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2019 - 2022
+* (C) COPYRIGHT AUTHORS, 2019 - 2025
*
* TITLE: UI.H
*
-* VERSION: 1.15
+* VERSION: 1.20
*
-* DATE: 10 Jun 2022
+* DATE: 03 Oct 2025
*
* WinObjEx64 Sonar UI constants, definitions and includes.
*
@@ -36,20 +36,6 @@
#define Y_SPLITTER_SIZE 4
#define Y_SPLITTER_MIN 100
-#define DefaultSystemDpi 96
-
-#define SCALE_DPI_VALUE(Value, CurrentDPI) MulDiv(Value, CurrentDPI, DefaultSystemDpi)
-
-typedef struct _TL_SUBITEMS_FIXED {
- ULONG Count;
- ULONG ColorFlags;
- COLORREF BgColor;
- COLORREF FontColor;
- PVOID UserParam;
- LPTSTR CustomTooltip;
- LPTSTR Text[2];
-} TL_SUBITEMS_FIXED, * PTL_SUBITEMS_FIXED;
-
typedef struct _SONARCONTEXT {
//
// GUI context variables.
diff --git a/Source/Plugins/Sonar/sup.c b/Source/Plugins/utils.c
similarity index 55%
rename from Source/Plugins/Sonar/sup.c
rename to Source/Plugins/utils.c
index f177607a..62be0fdc 100644
--- a/Source/Plugins/Sonar/sup.c
+++ b/Source/Plugins/utils.c
@@ -1,12 +1,14 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2020 - 2024
+* (C) COPYRIGHT AUTHORS, 2020 - 2025
*
-* TITLE: SUP.C
+* TITLE: UTILS.C
*
-* VERSION: 1.16
+* VERSION: 1.20
*
-* DATE: 14 Jun 2024
+* DATE: 03 Oct 2025
+*
+* Shared plugins runtime support functions and prototypes.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
@@ -15,235 +17,405 @@
*
*******************************************************************************/
-#include "global.h"
-
-PVOID HeapMemoryAlloc(_In_ SIZE_T Size)
-{
- return HeapAlloc(g_ctx.PluginHeap, HEAP_ZERO_MEMORY, Size);
-}
+#include "utils.h"
-BOOL HeapMemoryFree(_In_ PVOID Memory)
+/*
+* supSetWaitCursor
+*
+* Purpose:
+*
+* Sets cursor state.
+*
+*/
+VOID supSetWaitCursor(
+ _In_ BOOL fSet
+)
{
- if (Memory == NULL) return FALSE;
- return HeapFree(g_ctx.PluginHeap, 0, Memory);
+ HCURSOR h = LoadCursor(NULL, fSet ? IDC_WAIT : IDC_ARROW);
+ if (h) {
+ SetCursor(h);
+ }
}
-//
-// Conversion buffer size
-//
-#define CONVERT_NTNAME_BUFFER_SIZE 512
-
/*
-* supConvertFileName
+* supMapSection
*
* Purpose:
*
-* Translate Nt path name to Dos path name.
+* Return pointer to section mapped view.
*
*/
-BOOL supConvertFileName(
- _In_ LPWSTR NtFileName,
- _Inout_ LPWSTR DosFileName,
- _In_ SIZE_T ccDosFileName
+NTSTATUS supMapSection(
+ _In_ HANDLE SectionHandle,
+ _Out_ PVOID* BaseAddress,
+ _Out_ SIZE_T* ViewSize
)
{
- BOOL bFound = FALSE;
+ NTSTATUS ntStatus;
+ SECTION_BASIC_INFORMATION sbi;
+ SIZE_T bytesReturned;
- SIZE_T nLen;
+ *BaseAddress = NULL;
+ *ViewSize = 0;
- WCHAR szDrive[3];
- WCHAR szName[MAX_PATH];
- WCHAR szTemp[CONVERT_NTNAME_BUFFER_SIZE];
- WCHAR* pszTemp;
+ __try {
- //
- // All input parameters are validated by caller before.
- //
+ //
+ // Check if this is image mapped file.
+ //
+ ntStatus = NtQuerySection(SectionHandle,
+ SectionBasicInformation,
+ (PVOID)&sbi,
+ sizeof(SECTION_BASIC_INFORMATION),
+ &bytesReturned);
- //
- // Drive template.
- //
- szDrive[0] = L'X';
- szDrive[1] = L':';
- szDrive[2] = 0;
+ if (!NT_SUCCESS(ntStatus))
+ __leave;
- //
- // Query array of logical disk drive strings.
- //
- szTemp[0] = 0;
- if (GetLogicalDriveStrings(RTL_NUMBER_OF(szTemp), szTemp) == 0)
- return FALSE;
+ if (!((sbi.AllocationAttributes & SEC_IMAGE) &&
+ (sbi.AllocationAttributes & SEC_FILE)))
+ {
+ ntStatus = STATUS_NOT_SUPPORTED;
+ __leave;
+ }
- pszTemp = szTemp;
+ ntStatus = NtMapViewOfSection(SectionHandle,
+ NtCurrentProcess(),
+ BaseAddress,
+ 0,
+ 0,
+ NULL,
+ ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_READONLY);
- do {
+ }
+ __finally {
+ if (AbnormalTermination())
+ ntStatus = STATUS_ACCESS_VIOLATION;
+ }
- //
- // Copy the drive letter to the template string.
- //
- *szDrive = *pszTemp;
- szName[0] = 0;
+ return ntStatus;
+}
- //
- // Lookup each device name.
- //
- if (QueryDosDevice(szDrive, szName, MAX_PATH)) {
+/*
+* supSaveDialogExecute
+*
+* Purpose:
+*
+* Display SaveDialog.
+*
+*/
+BOOL supSaveDialogExecute(
+ _In_ HWND OwnerWindow,
+ _Inout_ LPWSTR SaveFileName,
+ _In_ LPWSTR lpDialogFilter
+)
+{
+ OPENFILENAME tag1;
- nLen = _strlen(szName);
+ RtlSecureZeroMemory(&tag1, sizeof(OPENFILENAME));
- if (nLen < MAX_PATH) {
+ tag1.lStructSize = sizeof(OPENFILENAME);
+ tag1.hwndOwner = OwnerWindow;
+ tag1.lpstrFilter = lpDialogFilter;
+ tag1.lpstrFile = SaveFileName;
+ tag1.nMaxFile = MAX_PATH;
+ tag1.lpstrInitialDir = NULL;
+ tag1.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
- //
- // Match device name.
- //
- bFound = ((_strncmpi(NtFileName, szName, nLen) == 0)
- && *(NtFileName + nLen) == L'\\');
+ return GetSaveFileName(&tag1);
+}
- if (bFound) {
+size_t supxEscStrlen(wchar_t* s)
+{
+ size_t result, quoteCount;
+ wchar_t* s0;
- //
- // Build output name.
- //
- StringCchPrintf(
- DosFileName,
- ccDosFileName,
- TEXT("%ws%ws"),
- szDrive,
- NtFileName + nLen);
+ if (s == NULL)
+ return 0;
- }
+ s0 = s;
+ result = 2;
+ quoteCount = 0;
- }
+ while (*s) {
+ if (*s == L'"')
+ ++quoteCount;
+ ++s;
+ }
- }
+ return result + (s - s0) + quoteCount;
+}
- //
- // Go to the next NULL character, i.e. the next drive name.
- //
- while (*pszTemp++);
+wchar_t* supxEscStrcpy(wchar_t* dst, wchar_t* src)
+{
+ if (dst == NULL || src == NULL)
+ return dst;
- } while (!bFound && *pszTemp);
+ *(dst++) = L'"';
- return bFound;
+ while (*src != L'\0') {
+ if (*src == L'"') {
+ *(dst++) = L'"';
+ *(dst++) = L'"';
+ ++src;
+ }
+ else {
+ *(dst++) = *src;
+ ++src;
+ }
+ }
+
+ *(dst++) = L'"';
+ *dst = L'\0';
+
+ return dst;
}
/*
-* supGetWin32FileName
+* supxListViewExportCSV
*
* Purpose:
*
-* Query filename by handle.
-*
-* Input buffer must be at least MAX_PATH length.
+* Export listview entries into file in csv format.
*
*/
-BOOL supGetWin32FileName(
- _In_ LPWSTR FileName,
- _Inout_ LPWSTR Win32FileName,
- _In_ SIZE_T ccWin32FileName
-)
+BOOL supxListViewExportCSV(
+ _In_ HWND List,
+ _In_ PWCHAR FileName)
{
- BOOL bResult = FALSE;
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- HANDLE hFile = NULL;
- UNICODE_STRING NtFileName;
- OBJECT_ATTRIBUTES obja;
- IO_STATUS_BLOCK iost;
- ULONG memIO;
- BYTE* Buffer = NULL;
+ HWND hdr;
+ int pass, i, c, col_count, icount;
+ HDITEM ih;
+ LVITEM lvi;
+ PWCHAR text, buffer0, buffer;
+ BOOL result;
+ SIZE_T total_length, field_length;
+ DWORD iobytes;
+ HANDLE f;
+ WORD bom;
+
+ if (!List || !FileName)
+ return FALSE;
- if ((Win32FileName == NULL) || (ccWin32FileName < MAX_PATH)) {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ hdr = ListView_GetHeader(List);
+ if (!hdr)
return FALSE;
- }
- do {
+ col_count = Header_GetItemCount(hdr);
+ if (col_count <= 0)
+ return FALSE;
- RtlInitUnicodeString(&NtFileName, FileName);
- InitializeObjectAttributes(&obja, &NtFileName, OBJ_CASE_INSENSITIVE, 0, NULL);
+ icount = 1 + ListView_GetItemCount(List);
- status = NtCreateFile(&hFile, SYNCHRONIZE, &obja, &iost, NULL, 0,
- FILE_SHARE_VALID_FLAGS, FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
+ text = (PWCHAR)ntsupVirtualAlloc(32768 * sizeof(WCHAR));
+ if (!text)
+ return FALSE;
- if (!NT_SUCCESS(status))
- break;
+ buffer0 = NULL;
+ buffer = NULL;
+ result = FALSE;
- memIO = 0;
- status = NtQueryObject(hFile, ObjectNameInformation, NULL, 0, &memIO);
- if (status != STATUS_INFO_LENGTH_MISMATCH)
- break;
+ RtlZeroMemory(&ih, sizeof(HDITEM));
+ RtlZeroMemory(&lvi, sizeof(LVITEM));
- Buffer = (BYTE*)HeapMemoryAlloc(memIO);
- if (Buffer == NULL)
- break;
+ ih.pszText = lvi.pszText = text;
+ ih.cchTextMax = lvi.cchTextMax = 32767;
- status = NtQueryObject(hFile, ObjectNameInformation, Buffer, memIO, NULL);
- if (!NT_SUCCESS(status))
- break;
+ for (pass = 0; pass < 2; ++pass) {
+ total_length = 0;
- if (!supConvertFileName(((PUNICODE_STRING)Buffer)->Buffer, Win32FileName, ccWin32FileName))
- break;
+ for (i = 0; i < icount; ++i) {
+ for (c = 0; c < col_count; ++c) {
+ text[0] = L'\0';
- bResult = TRUE;
+ if (i == 0) {
+ ih.mask = HDI_TEXT | HDI_ORDER;
+ ih.iOrder = c;
+ Header_GetItem(hdr, c, &ih);
+ }
+ else {
+ lvi.mask = LVIF_TEXT;
+ lvi.iItem = i - 1;
+ lvi.iSubItem = c;
+ ListView_GetItem(List, &lvi);
+ }
- } while (FALSE);
+ field_length = supxEscStrlen(text);
+ total_length += field_length;
- if (hFile)
- NtClose(hFile);
+ if (buffer) {
+ buffer = supxEscStrcpy(buffer, text);
+ }
- if (Buffer != NULL)
- HeapMemoryFree(Buffer);
+ if (c != col_count - 1) {
+ total_length += 1;
+ if (buffer) {
+ *(buffer++) = L',';
+ }
+ }
+ else {
+ total_length += 2;
+ if (buffer) {
+ *(buffer++) = L'\r';
+ *(buffer++) = L'\n';
+ }
+ }
+ }
+ }
- return bResult;
+ if (buffer0 == NULL) {
+ buffer0 = (PWCHAR)ntsupVirtualAlloc((1 + total_length) * sizeof(WCHAR));
+ if (!buffer0)
+ break;
+ buffer = buffer0;
+ }
+ else {
+ f = CreateFile(FileName,
+ GENERIC_WRITE | SYNCHRONIZE,
+ FILE_SHARE_READ,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (f != INVALID_HANDLE_VALUE) {
+ bom = 0xFEFF;
+ WriteFile(f, &bom, sizeof(WORD), &iobytes, NULL);
+ WriteFile(f, buffer0, (DWORD)(total_length * sizeof(WCHAR)), &iobytes, NULL);
+ CloseHandle(f);
+ result = TRUE;
+ }
+ ntsupVirtualFree(buffer0);
+ buffer0 = NULL;
+ }
+ }
+
+ if (buffer0)
+ ntsupVirtualFree(buffer0);
+
+ ntsupVirtualFree(text);
+ return result;
}
/*
-* supClipboardCopy
+* supListViewExportToFile
*
* Purpose:
*
-* Copy text to the clipboard.
+* Export listview contents to the specified file.
*
*/
-VOID supClipboardCopy(
- _In_ LPWSTR lpText,
- _In_ SIZE_T cbText
+BOOL supListViewExportToFile(
+ _In_ LPWSTR FileName,
+ _In_ HWND WindowHandle,
+ _In_ HWND ListView,
+ _In_ LPWSTR FileFilter
)
{
- LPWSTR lptstrCopy;
- HGLOBAL hglbCopy = NULL;
- SIZE_T dwSize;
- BOOL dataSet = FALSE;
-
- if (!OpenClipboard(NULL))
- return;
+ BOOL bResult = FALSE;
+ WCHAR szExportFileName[MAX_PATH + 1];
- __try {
- EmptyClipboard();
- dwSize = cbText + sizeof(UNICODE_NULL);
- hglbCopy = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize);
- if (hglbCopy == NULL)
- __leave;
+ RtlSecureZeroMemory(&szExportFileName, sizeof(szExportFileName));
- lptstrCopy = (LPWSTR)GlobalLock(hglbCopy);
- if (lptstrCopy == NULL)
- __leave;
+ _strcpy(szExportFileName, FileName);
+ if (supSaveDialogExecute(WindowHandle,
+ (LPWSTR)&szExportFileName,
+ FileFilter))
+ {
+ SetCapture(WindowHandle);
+ supSetWaitCursor(TRUE);
- RtlCopyMemory(lptstrCopy, lpText, cbText);
- GlobalUnlock(hglbCopy);
+ bResult = supxListViewExportCSV(ListView, szExportFileName);
- dataSet = SetClipboardData(CF_UNICODETEXT, hglbCopy) != NULL;
- if (dataSet) {
- hglbCopy = NULL;
- }
- }
- __finally {
- CloseClipboard();
- if (hglbCopy != NULL) {
- GlobalFree(hglbCopy);
- }
+ supSetWaitCursor(FALSE);
+ ReleaseCapture();
}
+
+ return bResult;
+}
+
+/*
+* supStatusBarSetText
+*
+* Purpose:
+*
+* Display status in status bar part.
+*
+*/
+VOID supStatusBarSetText(
+ _In_ HWND hwndStatusBar,
+ _In_ WPARAM partIndex,
+ _In_ LPWSTR lpText
+)
+{
+ SendMessage(hwndStatusBar, SB_SETTEXT, partIndex, (LPARAM)lpText);
+}
+
+/*
+* supTreeListAddItem
+*
+* Purpose:
+*
+* Insert new treelist item.
+*
+*/
+HTREEITEM supTreeListAddItem(
+ _In_ HWND TreeList,
+ _In_opt_ HTREEITEM hParent,
+ _In_ UINT mask,
+ _In_ UINT state,
+ _In_ UINT stateMask,
+ _In_opt_ LPWSTR pszText,
+ _In_opt_ PVOID subitems
+)
+{
+ TVINSERTSTRUCT tvitem;
+ PTL_SUBITEMS si = (PTL_SUBITEMS)subitems;
+
+ RtlSecureZeroMemory(&tvitem, sizeof(tvitem));
+ tvitem.hParent = hParent;
+ tvitem.item.mask = mask;
+ tvitem.item.state = state;
+ tvitem.item.stateMask = stateMask;
+ tvitem.item.pszText = pszText;
+ tvitem.hInsertAfter = TVI_LAST;
+ return TreeList_InsertTreeItem(TreeList, &tvitem, si);
+}
+
+/*
+* supAddListViewColumn
+*
+* Purpose:
+*
+* Insert list view column.
+*
+*/
+INT supAddListViewColumn(
+ _In_ HWND ListViewHwnd,
+ _In_ INT ColumnIndex,
+ _In_ INT SubItemIndex,
+ _In_ INT OrderIndex,
+ _In_ INT ImageIndex,
+ _In_ INT Format,
+ _In_ LPWSTR Text,
+ _In_ INT Width,
+ _In_ INT DpiValue
+)
+{
+ LVCOLUMN column;
+
+ column.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT | LVCF_WIDTH | LVCF_ORDER | LVCF_IMAGE;
+ column.fmt = Format;
+ column.cx = ScaleDPI(Width, DpiValue);
+ column.pszText = Text;
+ column.iSubItem = SubItemIndex;
+ column.iOrder = OrderIndex;
+ column.iImage = ImageIndex;
+
+ return ListView_InsertColumn(ListViewHwnd, ColumnIndex, &column);
}
/*
@@ -305,18 +477,18 @@ BOOL supTreeListAddCopyValueItem(
*
* Returns buffer with text from the given listview item.
*
-* Returned buffer must be freed with HeapMemoryFree after usage.
+* Returned buffer must be freed with supHeapFree after usage.
*
*/
LPWSTR supGetItemText(
_In_ HWND ListView,
_In_ INT nItem,
_In_ INT nSubItem,
- _Out_opt_ PSIZE_T lpSize //length in bytes
+ _Out_opt_ PSIZE_T lpSize
)
{
- INT len;
- LPARAM sz = 0;
+ INT len;
+ LPARAM sz = 0;
LV_ITEM item;
RtlSecureZeroMemory(&item, sizeof(item));
@@ -324,21 +496,24 @@ LPWSTR supGetItemText(
item.iItem = nItem;
item.iSubItem = nSubItem;
len = 128;
+
do {
len *= 2;
item.cchTextMax = len;
if (item.pszText) {
- HeapMemoryFree(item.pszText);
+ supHeapFree(item.pszText);
item.pszText = NULL;
}
- item.pszText = (LPWSTR)HeapMemoryAlloc(len * sizeof(WCHAR));
+ item.pszText = (LPWSTR)supHeapAlloc(len * sizeof(WCHAR));
+ if (item.pszText == NULL)
+ break;
+
sz = SendMessage(ListView, LVM_GETITEMTEXT, (WPARAM)item.iItem, (LPARAM)&item);
} while (sz == (LPARAM)len - 1);
- //empty string
if (sz == 0) {
if (item.pszText) {
- HeapMemoryFree(item.pszText);
+ supHeapFree(item.pszText);
item.pszText = NULL;
}
}
@@ -346,6 +521,7 @@ LPWSTR supGetItemText(
if (lpSize) {
*lpSize = sz * sizeof(WCHAR);
}
+
return item.pszText;
}
@@ -379,56 +555,51 @@ LPWSTR supGetItemText2(
}
/*
-* supListViewAddCopyValueItem
+* supClipboardCopy
*
* Purpose:
*
-* Add copy to clipboard menu item depending on hit column.
+* Copy text to the clipboard.
*
*/
-BOOL supListViewAddCopyValueItem(
- _In_ HMENU hMenu,
- _In_ HWND hwndLv,
- _In_ UINT uId,
- _In_ UINT uPos,
- _In_ POINT* lpPoint,
- _Out_ INT* pItemHit,
- _Out_ INT* pColumnHit
-)
-{
- LVHITTESTINFO lvht;
- LVCOLUMN lvc;
- WCHAR szItem[MAX_PATH * 2];
- WCHAR szColumn[MAX_PATH + 1];
+VOID supClipboardCopy(
+ _In_ LPWSTR lpText,
+ _In_ SIZE_T cbText
+)
+{
+ LPWSTR lptstrCopy;
+ HGLOBAL hglbCopy = NULL;
+ SIZE_T dwSize;
+ BOOL dataSet = FALSE;
- *pColumnHit = -1;
- *pItemHit = -1;
+ if (!OpenClipboard(NULL))
+ return;
- RtlSecureZeroMemory(&lvht, sizeof(lvht));
- lvht.pt.x = lpPoint->x;
- lvht.pt.y = lpPoint->y;
- ScreenToClient(hwndLv, &lvht.pt);
- if (ListView_SubItemHitTest(hwndLv, &lvht) == -1)
- return FALSE;
+ __try {
+ EmptyClipboard();
+ dwSize = cbText + sizeof(UNICODE_NULL);
+ hglbCopy = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize);
+ if (hglbCopy == NULL)
+ __leave;
- RtlSecureZeroMemory(&lvc, sizeof(lvc));
- RtlSecureZeroMemory(&szColumn, sizeof(szColumn));
+ lptstrCopy = (LPWSTR)GlobalLock(hglbCopy);
+ if (lptstrCopy == NULL)
+ __leave;
- lvc.mask = LVCF_TEXT;
- lvc.pszText = szColumn;
- lvc.cchTextMax = MAX_PATH;
- if (ListView_GetColumn(hwndLv, lvht.iSubItem, &lvc)) {
- _strcpy(szItem, TEXT("Copy \""));
- _strcat(szItem, szColumn);
- _strcat(szItem, TEXT("\""));
- if (InsertMenu(hMenu, uPos, MF_BYCOMMAND, uId, szItem)) {
- *pColumnHit = lvht.iSubItem;
- *pItemHit = lvht.iItem;
- return TRUE;
+ RtlCopyMemory(lptstrCopy, lpText, cbText);
+ GlobalUnlock(hglbCopy);
+
+ dataSet = SetClipboardData(CF_UNICODETEXT, hglbCopy) != NULL;
+ if (dataSet) {
+ hglbCopy = NULL;
+ }
+ }
+ __finally {
+ CloseClipboard();
+ if (hglbCopy != NULL) {
+ GlobalFree(hglbCopy);
}
}
-
- return FALSE;
}
/*
@@ -459,7 +630,7 @@ BOOL supListViewCopyItemValueToClipboard(
if (lpText) {
cbText = _strlen(lpText) * sizeof(WCHAR);
supClipboardCopy(lpText, cbText);
- HeapMemoryFree(lpText);
+ supHeapFree(lpText);
return TRUE;
}
else {
@@ -473,66 +644,233 @@ BOOL supListViewCopyItemValueToClipboard(
}
/*
-* supTreeListCopyItemValueToClipboard
+* supFreeDuplicatedUnicodeString
*
* Purpose:
*
-* Copy selected treelist item text to the clipboard.
+* Release memory allocated for duplicated string.
*
*/
-BOOL supTreeListCopyItemValueToClipboard(
- _In_ HWND hwndTreeList,
- _In_ INT tlSubItemHit
+_Success_(return)
+BOOL supFreeDuplicatedUnicodeString(
+ _In_ HANDLE HeapHandle,
+ _Inout_ PUNICODE_STRING DuplicatedString,
+ _In_ BOOL DoZeroMemory
)
{
- INT nIndex;
- LPWSTR lpCopyData = NULL;
- SIZE_T cbCopyData = 0;
- TVITEMEX itemex;
- WCHAR szText[MAX_PATH + 1];
+ BOOL bResult = FALSE;
+ if (DuplicatedString->Buffer) {
+ bResult = RtlFreeHeap(HeapHandle, 0, DuplicatedString->Buffer);
+ if (DoZeroMemory) {
+ DuplicatedString->Buffer = NULL;
+ DuplicatedString->Length = DuplicatedString->MaximumLength = 0;
+ }
+ }
+ return bResult;
+}
- TL_SUBITEMS_FIXED* pSubItems = NULL;
+/*
+* supDuplicateUnicodeString
+*
+* Purpose:
+*
+* Duplicate existing UNICODE_STRING to another without RtlDuplicateUnicodeString.
+*
+* Note: Use supFreeDuplicatedUnicodeString to release allocated memory.
+*
+*/
+_Success_(return)
+BOOL supDuplicateUnicodeString(
+ _In_ HANDLE HeapHandle,
+ _Out_ PUNICODE_STRING DestinationString,
+ _In_ PUNICODE_STRING SourceString
+)
+{
+ USHORT maxLength = SourceString->MaximumLength;
+ PWCHAR strBuffer;
- szText[0] = 0;
- RtlSecureZeroMemory(&itemex, sizeof(itemex));
- itemex.mask = TVIF_TEXT;
- itemex.hItem = TreeList_GetSelection(hwndTreeList);
- itemex.pszText = szText;
- itemex.cchTextMax = MAX_PATH;
+ if (maxLength == 0 || maxLength < SourceString->Length)
+ return FALSE;
- if (TreeList_GetTreeItem(hwndTreeList, &itemex, &pSubItems)) {
+ strBuffer = (PWCHAR)RtlAllocateHeap(HeapHandle, HEAP_ZERO_MEMORY, (SIZE_T)maxLength);
+ if (strBuffer) {
+ DestinationString->Buffer = strBuffer;
+ DestinationString->MaximumLength = maxLength;
+ RtlCopyUnicodeString(DestinationString, SourceString);
+ return TRUE;
+ }
- if ((tlSubItemHit > 0) && (pSubItems != NULL)) {
+ return FALSE;
+}
- nIndex = (tlSubItemHit - 1);
- if (nIndex < (INT)pSubItems->Count) {
+//
+// Conversion buffer size
+//
+#define CONVERT_NTNAME_BUFFER_SIZE 512
- lpCopyData = pSubItems->Text[nIndex];
- cbCopyData = _strlen(lpCopyData) * sizeof(WCHAR);
+/*
+* supConvertFileName
+*
+* Purpose:
+*
+* Translate Nt path name to Dos path name.
+*
+*/
+BOOL supConvertFileName(
+ _In_ LPWSTR NtFileName,
+ _Inout_ LPWSTR DosFileName,
+ _In_ SIZE_T ccDosFileName
+)
+{
+ BOOL bFound = FALSE;
- }
+ SIZE_T nLen;
- }
- else {
- if (tlSubItemHit == 0) {
- lpCopyData = szText;
- cbCopyData = sizeof(szText); // copy everything
- }
- }
+ WCHAR szDrive[3];
+ WCHAR szName[MAX_PATH];
+ WCHAR szTemp[CONVERT_NTNAME_BUFFER_SIZE];
+ WCHAR* pszTemp;
+
+ //
+ // All input parameters are validated by caller before.
+ //
+
+ //
+ // Drive template.
+ //
+ szDrive[0] = L'X';
+ szDrive[1] = L':';
+ szDrive[2] = 0;
+
+ //
+ // Query array of logical disk drive strings.
+ //
+ szTemp[0] = 0;
+ if (GetLogicalDriveStrings(RTL_NUMBER_OF(szTemp), szTemp) == 0)
+ return FALSE;
+
+ pszTemp = szTemp;
+
+ do {
+
+ //
+ // Copy the drive letter to the template string.
+ //
+ *szDrive = *pszTemp;
+ szName[0] = 0;
+
+ //
+ // Lookup each device name.
+ //
+ if (QueryDosDevice(szDrive, szName, MAX_PATH)) {
+
+ nLen = _strlen(szName);
+
+ if (nLen < MAX_PATH) {
+
+ //
+ // Match device name.
+ //
+ bFound = ((_strncmpi(NtFileName, szName, nLen) == 0)
+ && *(NtFileName + nLen) == L'\\');
+
+ if (bFound) {
+
+ //
+ // Build output name.
+ //
+ StringCchPrintf(
+ DosFileName,
+ ccDosFileName,
+ TEXT("%ws%ws"),
+ szDrive,
+ NtFileName + nLen);
+
+ }
- if (lpCopyData && cbCopyData) {
- supClipboardCopy(lpCopyData, cbCopyData);
- return TRUE;
- }
- else {
- if (OpenClipboard(NULL)) {
- EmptyClipboard();
- CloseClipboard();
}
+
}
+
+ //
+ // Go to the next NULL character, i.e. the next drive name.
+ //
+ while (*pszTemp++);
+
+ } while (!bFound && *pszTemp);
+
+ return bFound;
+}
+
+/*
+* supGetWin32FileName
+*
+* Purpose:
+*
+* Query filename by handle.
+*
+* Input buffer must be at least MAX_PATH length.
+*
+*/
+BOOL supGetWin32FileName(
+ _In_ LPWSTR FileName,
+ _Inout_ LPWSTR Win32FileName,
+ _In_ SIZE_T ccWin32FileName
+)
+{
+ BOOL bResult = FALSE;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ HANDLE hFile = NULL;
+ UNICODE_STRING NtFileName;
+ OBJECT_ATTRIBUTES obja;
+ IO_STATUS_BLOCK iost;
+ ULONG memIO;
+ BYTE* Buffer = NULL;
+
+ if ((Win32FileName == NULL) || (ccWin32FileName < MAX_PATH)) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
}
- return FALSE;
+ do {
+
+ RtlInitUnicodeString(&NtFileName, FileName);
+ InitializeObjectAttributes(&obja, &NtFileName, OBJ_CASE_INSENSITIVE, 0, NULL);
+
+ status = NtCreateFile(&hFile, SYNCHRONIZE, &obja, &iost, NULL, 0,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
+
+ if (!NT_SUCCESS(status))
+ break;
+
+ memIO = 0;
+ status = NtQueryObject(hFile, ObjectNameInformation, NULL, 0, &memIO);
+ if (status != STATUS_INFO_LENGTH_MISMATCH)
+ break;
+
+ Buffer = (BYTE*)supHeapAlloc(memIO);
+ if (Buffer == NULL)
+ break;
+
+ status = NtQueryObject(hFile, ObjectNameInformation, Buffer, memIO, NULL);
+ if (!NT_SUCCESS(status))
+ break;
+
+ if (!supConvertFileName(((PUNICODE_STRING)Buffer)->Buffer, Win32FileName, ccWin32FileName))
+ break;
+
+ bResult = TRUE;
+
+ } while (FALSE);
+
+ if (hFile)
+ NtClose(hFile);
+
+ if (Buffer != NULL)
+ supHeapFree(Buffer);
+
+ return bResult;
}
/*
@@ -637,3 +975,119 @@ INT supGetMaxOfTwoU64FromHex(
return nResult;
}
+
+/*
+* supTreeListCopyItemValueToClipboard
+*
+* Purpose:
+*
+* Copy selected treelist item text to the clipboard.
+*
+*/
+BOOL supTreeListCopyItemValueToClipboard(
+ _In_ HWND hwndTreeList,
+ _In_ INT tlSubItemHit
+)
+{
+ INT nIndex;
+ LPWSTR lpCopyData = NULL;
+ SIZE_T cbCopyData = 0;
+ TVITEMEX itemex;
+ WCHAR szText[MAX_PATH + 1];
+
+ TL_SUBITEMS_FIXED* pSubItems = NULL;
+
+ szText[0] = 0;
+ RtlSecureZeroMemory(&itemex, sizeof(itemex));
+ itemex.mask = TVIF_TEXT;
+ itemex.hItem = TreeList_GetSelection(hwndTreeList);
+ itemex.pszText = szText;
+ itemex.cchTextMax = MAX_PATH;
+
+ if (TreeList_GetTreeItem(hwndTreeList, &itemex, &pSubItems)) {
+
+ if ((tlSubItemHit > 0) && (pSubItems != NULL)) {
+
+ nIndex = (tlSubItemHit - 1);
+ if (nIndex < (INT)pSubItems->Count) {
+
+ lpCopyData = pSubItems->Text[nIndex];
+ cbCopyData = _strlen(lpCopyData) * sizeof(WCHAR);
+
+ }
+
+ }
+ else {
+ if (tlSubItemHit == 0) {
+ lpCopyData = szText;
+ cbCopyData = sizeof(szText); // copy everything
+ }
+ }
+
+ if (lpCopyData && cbCopyData) {
+ supClipboardCopy(lpCopyData, cbCopyData);
+ return TRUE;
+ }
+ else {
+ if (OpenClipboard(NULL)) {
+ EmptyClipboard();
+ CloseClipboard();
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+* supListViewAddCopyValueItem
+*
+* Purpose:
+*
+* Add copy to clipboard menu item depending on hit column.
+*
+*/
+BOOL supListViewAddCopyValueItem(
+ _In_ HMENU hMenu,
+ _In_ HWND hwndLv,
+ _In_ UINT uId,
+ _In_ UINT uPos,
+ _In_ POINT * lpPoint,
+ _Out_ INT * pItemHit,
+ _Out_ INT * pColumnHit
+)
+{
+ LVHITTESTINFO lvht;
+ LVCOLUMN lvc;
+ WCHAR szItem[MAX_PATH * 2];
+ WCHAR szColumn[MAX_PATH + 1];
+
+ *pColumnHit = -1;
+ *pItemHit = -1;
+
+ RtlSecureZeroMemory(&lvht, sizeof(lvht));
+ lvht.pt.x = lpPoint->x;
+ lvht.pt.y = lpPoint->y;
+ ScreenToClient(hwndLv, &lvht.pt);
+ if (ListView_SubItemHitTest(hwndLv, &lvht) == -1)
+ return FALSE;
+
+ RtlSecureZeroMemory(&lvc, sizeof(lvc));
+ RtlSecureZeroMemory(&szColumn, sizeof(szColumn));
+
+ lvc.mask = LVCF_TEXT;
+ lvc.pszText = szColumn;
+ lvc.cchTextMax = MAX_PATH;
+ if (ListView_GetColumn(hwndLv, lvht.iSubItem, &lvc)) {
+ _strcpy(szItem, TEXT("Copy \""));
+ _strcat(szItem, szColumn);
+ _strcat(szItem, TEXT("\""));
+ if (InsertMenu(hMenu, uPos, MF_BYCOMMAND, uId, szItem)) {
+ *pColumnHit = lvht.iSubItem;
+ *pItemHit = lvht.iItem;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
diff --git a/Source/Plugins/ImageScope/sup.h b/Source/Plugins/utils.h
similarity index 55%
rename from Source/Plugins/ImageScope/sup.h
rename to Source/Plugins/utils.h
index 746ade6c..95f2e503 100644
--- a/Source/Plugins/ImageScope/sup.h
+++ b/Source/Plugins/utils.h
@@ -2,11 +2,11 @@
*
* (C) COPYRIGHT AUTHORS, 2020 - 2025
*
-* TITLE: SUP.H
+* TITLE: UTILS.H
*
-* VERSION: 1.11
+* VERSION: 1.20
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* Common header file for the plugin support routines.
*
@@ -16,13 +16,50 @@
* PARTICULAR PURPOSE.
*
*******************************************************************************/
+
+#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
+#endif
+
+#ifndef PLUGIN_UTILS_H
+#define PLUGIN_UTILS_H
+
+#ifndef _WINDOWS_
+#include
+#endif
+
+#pragma warning(push)
+#pragma warning(disable: 4005) //macro redefinition
+#include
+#pragma warning(pop)
+
+#include "ntos/ntos.h"
+#include "ntos/ntsup.h"
+#include
-PVOID supHeapAlloc(
- _In_ SIZE_T Size);
+#define _NTDEF_
+#include
+#undef _NTDEF_
-BOOL supHeapFree(
- _In_ PVOID Memory);
+#include "minirtl/minirtl.h"
+#include "tabs/tabsctrl.h"
+#include "treelist/treelist.h"
+
+#define supHeapAlloc ntsupHeapAlloc
+#define supHeapFree ntsupHeapFree
+
+#define DefaultSystemDpi 96
+#define ScaleDPI(Value, CurrentDPI) MulDiv(Value, CurrentDPI, DefaultSystemDpi)
+
+typedef struct _TL_SUBITEMS_FIXED {
+ ULONG Count;
+ ULONG ColorFlags;
+ COLORREF BgColor;
+ COLORREF FontColor;
+ PVOID UserParam;
+ LPTSTR CustomTooltip;
+ LPTSTR Text[2];
+} TL_SUBITEMS_FIXED, * PTL_SUBITEMS_FIXED;
VOID supSetWaitCursor(
_In_ BOOL fSet);
@@ -40,7 +77,8 @@ BOOL supSaveDialogExecute(
BOOL supListViewExportToFile(
_In_ LPWSTR FileName,
_In_ HWND WindowHandle,
- _In_ HWND ListView);
+ _In_ HWND ListView,
+ _In_ LPWSTR FileFilter);
VOID supStatusBarSetText(
_In_ HWND hwndStatusBar,
@@ -103,4 +141,35 @@ BOOL supDuplicateUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_In_ PUNICODE_STRING SourceString);
+BOOL supTreeListAddCopyValueItem(
+ _In_ HMENU hMenu,
+ _In_ HWND hwndTreeList,
+ _In_ UINT uId,
+ _In_ UINT uPos,
+ _In_ LPARAM lParam,
+ _In_ INT * pSubItemHit);
+
+BOOL supGetWin32FileName(
+ _In_ LPWSTR FileName,
+ _Inout_ LPWSTR Win32FileName,
+ _In_ SIZE_T ccWin32FileName);
+
+INT supGetMaxCompareTwoFixedStrings(
+ _In_ HWND ListView,
+ _In_ LPARAM lParam1,
+ _In_ LPARAM lParam2,
+ _In_ LPARAM lParamSort,
+ _In_ BOOL Inverse);
+
+INT supGetMaxOfTwoU64FromHex(
+ _In_ HWND ListView,
+ _In_ LPARAM lParam1,
+ _In_ LPARAM lParam2,
+ _In_ LPARAM lParamSort,
+ _In_ BOOL Inverse);
+
+BOOL supTreeListCopyItemValueToClipboard(
+ _In_ HWND hwndTreeList,
+ _In_ INT tlSubItemHit);
+#endif /* PLUGIN_UTILS_H */
diff --git a/Source/Shared/ntos/ntbuilds.h b/Source/Shared/ntos/ntbuilds.h
index a1c26887..de4c0ed4 100644
--- a/Source/Shared/ntos/ntbuilds.h
+++ b/Source/Shared/ntos/ntbuilds.h
@@ -4,9 +4,9 @@
*
* TITLE: NTBUILDS.H
*
-* VERSION: 1.27
+* VERSION: 1.28
*
-* DATE: 11 May 2025
+* DATE: 18 Sep 2025
*
* Windows NT builds definition file.
*
@@ -91,5 +91,8 @@
// Windows 11 24H2
#define NT_WIN11_24H2 26100
+// Windows 11 25H2
+#define NT_WIN11_25H2 26200
+
// Windows 11 Active Development Branch
-#define NT_WIN11_25H2 27842 //canary (25H2)
+#define NT_WIN11_ADB 27943
diff --git a/Source/TypesWithNoDesc.txt b/Source/TypesWithNoDesc.txt
index 60b64455..cbccc2bb 100644
--- a/Source/TypesWithNoDesc.txt
+++ b/Source/TypesWithNoDesc.txt
@@ -1,14 +1 @@
-CrossVmEvent - new Win11 object
-CrossVmMutant - new Win11 object
-CpuPartition - new Win11 object, unnamed objects
-EtwSessionDemuxEntry - new Win10 object
-NetworkNamespace - managed by NDIS.sys (renamed to NdisCmState in RS1)
-ProcessStateChange - new 21H1 object
-ThreadStateChange - new 21H1 object
-PsSiloContextNonPaged - new RS1 object
-PsSiloContextPaged - new RS1 object
-SchedulerSharedData - new win11 22h2+ object, unnamed objects
Silo (r3 interface removed in 10240 release, object removed in TH2 builds)
-VirtualKey - new RS1 object (not present in RS2)
-VRegConfigurationContext - new RS1 object
-DxgkDisplayMuxSwitch - new 25H2 object
diff --git a/Source/WinObjEx64/Resource.rc b/Source/WinObjEx64/Resource.rc
index b8ea84c5..b9ea73c4 100644
Binary files a/Source/WinObjEx64/Resource.rc and b/Source/WinObjEx64/Resource.rc differ
diff --git a/Source/WinObjEx64/extras/extrasSSDT.c b/Source/WinObjEx64/extras/extrasSSDT.c
index c2003a87..7acd4da4 100644
--- a/Source/WinObjEx64/extras/extrasSSDT.c
+++ b/Source/WinObjEx64/extras/extrasSSDT.c
@@ -4,9 +4,9 @@
*
* TITLE: EXTRASSSDT.C
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 22 Aug 2025
+* DATE: 03 Oct 2025
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
@@ -1001,6 +1001,7 @@ VOID SdtListCreate(
CallbackParam.lParam = 0;
CallbackParam.Value = pDlgContext->DialogMode;
ListView_SortItemsEx(pDlgContext->ListView, &SdtDlgCompareFunc, (LPARAM)&CallbackParam);
+ SetForegroundWindow(pDlgContext->hwndDlg);
SetFocus(pDlgContext->ListView);
}
}
diff --git a/Source/WinObjEx64/kldbg.c b/Source/WinObjEx64/kldbg.c
index 09e44f3c..a1b27302 100644
--- a/Source/WinObjEx64/kldbg.c
+++ b/Source/WinObjEx64/kldbg.c
@@ -4,9 +4,9 @@
*
* TITLE: KLDBG.C, based on KDSubmarine by Evilcry
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 19 Aug 2025
+* DATE: 19 Sep 2025
*
* MINIMUM SUPPORTED OS WINDOWS 7
*
@@ -1567,14 +1567,16 @@ BOOL kdpFindKiServiceTableByPattern(
LeaPattern_KeServiceDescriptorTableShadow,
sizeof(LeaPattern_KeServiceDescriptorTableShadow));
- if (kdAddressInNtOsImage((PVOID)varAddress))
+ if (kdAddressInNtOsImage((PVOID)varAddress)) {
*Address = varAddress;
+ return TRUE;
+ }
- return TRUE;
+ return FALSE;
}
/*
-* kdFindServiceTable
+* kdFindKiServiceTable
*
* Purpose:
*
@@ -1791,7 +1793,7 @@ POBEX_OBJECT_INFORMATION ObpCopyObjectBasicInfo(
&InfoHeaderAddress,
HeaderQuotaInfoFlag))
{
- kdReadSystemMemory(HeaderAddress,
+ kdReadSystemMemory(InfoHeaderAddress,
&lpData->ObjectQuotaHeader,
sizeof(OBJECT_HEADER_QUOTA_INFO));
}
@@ -2133,8 +2135,7 @@ BOOL ObpEnumeratePrivateNamespaceTable(
)
{
BOOL bStopEnumeration = FALSE;
- ULONG i, j = 0;
- ULONG dirIterLimit = OB_MAX_DIRECTORY_ENUM_ITER, chainIterLimit = OB_MAX_DIRECTORY_ENUM_ITER;
+ ULONG i, j = 0, dirIterLimit, chainIterLimit;
ULONG_PTR ObjectHeaderAddress, HeadItem, LookupItem, InfoHeaderAddress;
HANDLE ListHeap = (HANDLE)Context;
PLIST_ENTRY Next, Head;
@@ -2164,8 +2165,8 @@ BOOL ObpEnumeratePrivateNamespaceTable(
for (i = 0; i < NUMBER_HASH_BUCKETS; i++) {
+ dirIterLimit = OB_MAX_DIRECTORY_ENUM_ITER;
ListEntry = LookupTable.HashBuckets[i];
-
Head = (PLIST_ENTRY)(TableAddress + (i * sizeof(LIST_ENTRY)));
Next = ListEntry.Flink;
@@ -2193,6 +2194,8 @@ BOOL ObpEnumeratePrivateNamespaceTable(
for (j = 0; j < NUMBER_HASH_BUCKETS; j++) {
+ chainIterLimit = OB_MAX_DIRECTORY_ENUM_ITER;
+
HeadItem = (ULONG_PTR)DirObject.HashBuckets[j];
if (HeadItem != 0) {
@@ -3131,8 +3134,7 @@ BOOLEAN kdpQueryMmUnloadedDrivers(
//
// Use 19041+ specific patterns as an array allocation code has been changed.
//
- switch (g_NtBuildNumber)
- {
+ switch (g_NtBuildNumber) {
case NT_WIN11_24H2:
case NT_WIN11_25H2:
sigPattern = MiRememberUnloadedDriverPattern24H2;
@@ -3690,7 +3692,7 @@ BOOL kdGetAddressFromSymbolEx(
)
{
BOOL bResult = FALSE;
- ULONG_PTR address;
+ ULONG_PTR address = 0;
WCHAR szLog[WOBJ_MAX_MESSAGE - 1];
diff --git a/Source/WinObjEx64/list.c b/Source/WinObjEx64/list.c
index bf40eee9..644b4388 100644
--- a/Source/WinObjEx64/list.c
+++ b/Source/WinObjEx64/list.c
@@ -4,9 +4,9 @@
*
* TITLE: LIST.C
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 19 Aug 2025
+* DATE: 03 Oct 2025
*
* Program main object listing and search logic.
*
@@ -17,6 +17,7 @@
*
*******************************************************************************/
#include "global.h"
+#include "props/propTypeConsts.h"
HANDLE ListObjectsHeap = NULL;
HANDLE TreeObjectsHeap = NULL;
@@ -545,7 +546,9 @@ VOID AddListViewItem(
case OBTYPE_HASH_TYPE:
bFound = supQueryTypeInfo(&Entry->Name,
szBuffer,
- MAX_PATH);
+ MAX_PATH,
+ MAX_KNOWN_POOL_TYPES,
+ a_PoolTypes);
break;
}
}
diff --git a/Source/WinObjEx64/objects.c b/Source/WinObjEx64/objects.c
index d3b786cb..c48c5e5c 100644
--- a/Source/WinObjEx64/objects.c
+++ b/Source/WinObjEx64/objects.c
@@ -4,9 +4,9 @@
*
* TITLE: OBJECTS.C
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 19 Aug 2025
+* DATE: 03 Oct 2025
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
@@ -199,25 +199,25 @@ static WOBJ_TYPE_DESC* gpObjectTypes[] = {
};
//
-// Number of items in gpObjectTypes array, RTL_NUMBER_OF(gpObjectTypes)
+// Number of items in gpObjectTypes array
//
ULONG g_ObjectTypesCount = RTL_NUMBER_OF(gpObjectTypes);
// Lookup table for access by type index
static WOBJ_TYPE_DESC* g_TypeIndexLookup[MAX_OBJECT_TYPE_INDEX + 1];
-// Hash table for common type names (most frequently accessed)
+// Hash table for type names
typedef struct _OBTYPE_HASH_ENTRY {
ULONG NameHash;
WOBJ_TYPE_DESC* TypeDesc;
} OBTYPE_HASH_ENTRY, * POBTYPE_HASH_ENTRY;
-// Hashtable for frequently looked up types
-#define HASH_TABLE_SIZE 64
+// Hashtable for types
+#define HASH_TABLE_SIZE 256
static OBTYPE_HASH_ENTRY g_TypeHashTable[HASH_TABLE_SIZE];
-// Flag indicating if lookup tables have been initialized
-static BOOLEAN g_LookupTablesInitialized = FALSE;
+// One-time init
+static INIT_ONCE g_LookupTablesInitOnce = INIT_ONCE_STATIC_INIT;
/*
* ObManagerComparerName
@@ -235,46 +235,97 @@ INT ObManagerComparerName(
WOBJ_TYPE_DESC* firstObject = (WOBJ_TYPE_DESC*)FirstObject;
WOBJ_TYPE_DESC* secondObject = *(WOBJ_TYPE_DESC**)SecondObject;
- if (firstObject == secondObject)
- return 0;
-
return (_strcmpi(firstObject->Name, secondObject->Name));
}
/*
-* ObManagerInitLookupTables
+* ObManagerInitOnceCallback
*
* Purpose:
*
* Initialize lookup tables for faster object type searching.
*
*/
-VOID ObManagerInitLookupTables(VOID)
+BOOL CALLBACK ObManagerInitOnceCallback(
+ _Inout_ PINIT_ONCE InitOnce,
+ _Inout_opt_ PVOID Parameter,
+ _Out_opt_ PVOID* Context
+)
{
- ULONG i, hashIndex;
+ ULONG i, k;
+ ULONG hashIndex;
WOBJ_OBJECT_TYPE typeIndex;
- if (g_LookupTablesInitialized)
- return;
+ UNREFERENCED_PARAMETER(InitOnce);
+ UNREFERENCED_PARAMETER(Parameter);
RtlSecureZeroMemory(g_TypeIndexLookup, sizeof(g_TypeIndexLookup));
RtlSecureZeroMemory(g_TypeHashTable, sizeof(g_TypeHashTable));
+#if _DEBUG
+ // Verify gpObjectTypes is sorted (case-insensitive)
+ if (g_ObjectTypesCount > 1) {
+ for (k = 1; k < g_ObjectTypesCount; k++) {
+ if (_strcmpi(gpObjectTypes[k - 1]->Name, gpObjectTypes[k]->Name) > 0) {
+ kdDebugPrint("gpObjectTypes ordering error at %lu: %ws > %ws\r\n",
+ k, gpObjectTypes[k - 1]->Name, gpObjectTypes[k]->Name);
+ break;
+ }
+ }
+ }
+#endif
+
// Fill lookup tables
for (i = 0; i < g_ObjectTypesCount; i++) {
+
typeIndex = gpObjectTypes[i]->Index;
if (typeIndex >= 0 && (ULONG)typeIndex <= MAX_OBJECT_TYPE_INDEX) {
g_TypeIndexLookup[typeIndex] = gpObjectTypes[i];
}
+#if _DEBUG
+ else {
+ kdDebugPrint("Type index out of bounds for %ws (%lu)\r\n",
+ gpObjectTypes[i]->Name, (ULONG)typeIndex);
+ }
+#endif
if (gpObjectTypes[i]->NameHash != 0) {
- hashIndex = gpObjectTypes[i]->NameHash % HASH_TABLE_SIZE;
+ hashIndex = gpObjectTypes[i]->NameHash & (HASH_TABLE_SIZE - 1);
g_TypeHashTable[hashIndex].NameHash = gpObjectTypes[i]->NameHash;
g_TypeHashTable[hashIndex].TypeDesc = gpObjectTypes[i];
}
}
- g_LookupTablesInitialized = TRUE;
+ if (Context) *Context = (PVOID)1;
+ return TRUE;
+}
+
+/*
+* ObManagerEnsureInitialized
+*
+* Purpose:
+*
+* Ensure lookup tables are initialized exactly once.
+*
+*/
+VOID ObManagerEnsureInitialized(
+ VOID
+)
+{
+ InitOnceExecuteOnce(&g_LookupTablesInitOnce, ObManagerInitOnceCallback, NULL, NULL);
+}
+
+/*
+* ObManagerInitLookupTables
+*
+* Purpose:
+*
+* Initialize lookup tables for faster object type searching.
+*
+*/
+VOID ObManagerInitLookupTables(VOID)
+{
+ ObManagerEnsureInitialized();
}
/*
@@ -289,8 +340,7 @@ LPWSTR ObManagerGetNameByIndex(
_In_ WOBJ_OBJECT_TYPE TypeIndex
)
{
- if (!g_LookupTablesInitialized)
- ObManagerInitLookupTables();
+ ObManagerEnsureInitialized();
if (TypeIndex >= 0 && (ULONG)TypeIndex <= MAX_OBJECT_TYPE_INDEX &&
g_TypeIndexLookup[TypeIndex] != NULL)
@@ -313,8 +363,7 @@ WOBJ_TYPE_DESC* ObManagerGetEntryByTypeIndex(
_In_ WOBJ_OBJECT_TYPE TypeIndex
)
{
- if (!g_LookupTablesInitialized)
- ObManagerInitLookupTables();
+ ObManagerEnsureInitialized();
if (TypeIndex >= 0 && (ULONG)TypeIndex <= MAX_OBJECT_TYPE_INDEX &&
g_TypeIndexLookup[TypeIndex] != NULL)
@@ -342,7 +391,7 @@ WOBJ_TYPE_DESC* ObManagerLookupByHash(
if (NameHash == 0)
return NULL;
- hashIndex = NameHash % HASH_TABLE_SIZE;
+ hashIndex = NameHash & (HASH_TABLE_SIZE - 1);
if (g_TypeHashTable[hashIndex].NameHash == NameHash)
return g_TypeHashTable[hashIndex].TypeDesc;
@@ -371,8 +420,7 @@ WOBJ_TYPE_DESC* ObManagerGetEntryByTypeName(
return &g_TypeUnknown;
}
- if (!g_LookupTablesInitialized)
- ObManagerInitLookupTables();
+ ObManagerEnsureInitialized();
// Try fast lookup by hash first
nameHash = supHashString(lpTypeName, (ULONG)_strlen(lpTypeName));
@@ -427,7 +475,7 @@ WOBJ_OBJECT_TYPE ObManagerGetIndexByTypeName(
* Returns object image index of known type.
*
*/
-UINT ObManagerGetImageIndexByTypeName(
+INT ObManagerGetImageIndexByTypeName(
_In_opt_ LPCWSTR lpTypeName
)
{
@@ -483,8 +531,7 @@ HIMAGELIST ObManagerLoadImageList(
HIMAGELIST ImageList;
HICON hIcon;
- if (!g_LookupTablesInitialized)
- ObManagerInitLookupTables();
+ ObManagerEnsureInitialized();
ImageList = ImageList_Create(
16,
diff --git a/Source/WinObjEx64/objects.h b/Source/WinObjEx64/objects.h
index 6d26d21c..6ccf81bf 100644
--- a/Source/WinObjEx64/objects.h
+++ b/Source/WinObjEx64/objects.h
@@ -4,9 +4,9 @@
*
* TITLE: OBJECTS.H
*
-* VERSION: 2.07
+* VERSION: 2.10
*
-* DATE: 11 May 2025
+* DATE: 03 Oct 2025
*
* Header file for internal Windows object types handling.
*
@@ -21,7 +21,7 @@
//
// Object Type Indexes Used By Program Only
//
-// NOT RELATED TO REAL OBJECTS INDEXES
+// NOT RELATED TO KERNEL OBJECT TYPE INDEXES
// ObjectTypeUnknown and ObjectTypeMax always end this list
//
typedef enum _WOBJ_OBJECT_TYPE {
@@ -95,19 +95,19 @@ typedef enum _WOBJ_OBJECT_TYPE {
ObjectTypeTerminal = 67,
ObjectTypeTerminalEventQueue = 68,
ObjectTypeEnergyTracker = 69,
- ObjectTypeUnknown = 70,
- ObjectTypeEtwSessionDemuxEntry = ObjectTypeUnknown,
- ObjectTypeNdisCmState = ObjectTypeUnknown,
- ObjectTypePsSiloContextNonPaged = ObjectTypeUnknown,
- ObjectTypePsSiloContextPaged = ObjectTypeUnknown,
- ObjectTypeVirtualKey = ObjectTypeUnknown,
- ObjectTypeVRegConfigurationContext = ObjectTypeUnknown,
- ObjectTypeProcessStateChange = ObjectTypeUnknown,
- ObjectTypeThreadStateChange = ObjectTypeUnknown,
- ObjectTypeCpuPartition = ObjectTypeUnknown,
- ObjectTypeSchedulerSharedData = ObjectTypeUnknown,
- ObjectTypeCrossVmEvent = ObjectTypeUnknown,
- ObjectTypeCrossVmMutant = ObjectTypeUnknown,
+ ObjectTypeVRegConfigurationContext = 70,
+ ObjectTypePsSiloContextNonPaged = 71,
+ ObjectTypePsSiloContextPaged = 72,
+ ObjectTypeEtwSessionDemuxEntry = 73,
+ ObjectTypeNdisCmState = 74,
+ ObjectTypeProcessStateChange = 75,
+ ObjectTypeThreadStateChange = 76,
+ ObjectTypeCrossVmEvent = 77,
+ ObjectTypeCrossVmMutant = 78,
+ ObjectTypeSchedulerSharedData = 79,
+ ObjectTypeCpuPartition = 80,
+ ObjectTypeVirtualKey = 81,
+ ObjectTypeUnknown = 82,
ObjectTypeMax
} WOBJ_OBJECT_TYPE;
@@ -161,57 +161,32 @@ typedef struct _WOBJ_TYPE_DESC {
//
// Unused id's
//
-#define UNUSED_IDI_ICON IDI_ICON_UNKNOWN
-#define UNUSED_IDS_DESC IDS_DESC_UNKNOWN
-
-#define IDI_ICON_IORING UNUSED_IDI_ICON
-#define IDI_ICON_ACTIVATIONOBJECT UNUSED_IDI_ICON
-#define IDI_ICON_ACTIVITYREFERENCE UNUSED_IDI_ICON
-#define IDI_ICON_COREMESSAGING UNUSED_IDI_ICON
-#define IDI_ICON_COVERAGESAMPLER UNUSED_IDI_ICON
-#define IDI_ICON_RAWINPUTMANAGER UNUSED_IDI_ICON
-#define IDI_ICON_WAITCOMPLETIONPACKET UNUSED_IDI_ICON
-#define IDI_ICON_IOCOMPLETION_RESERVE UNUSED_IDI_ICON
-#define IDI_ICON_USERAPCRESERVE UNUSED_IDI_ICON
-#define IDI_ICON_ENERGYTRACKER UNUSED_IDI_ICON
-
-#define IDI_ICON_TERMINAL UNUSED_IDI_ICON
-#define IDI_ICON_TERMINALEVENTQUEUE UNUSED_IDI_ICON
-
-#define IDI_ICON_ETWSESSIONDEMUXENTRY UNUSED_IDI_ICON
-#define IDS_DESC_ETWSESSIONDEMUXENTRY UNUSED_IDS_DESC
-
-#define IDI_ICON_NDISCMSTATE UNUSED_IDI_ICON
-#define IDS_DESC_NDISCMSTATE UNUSED_IDS_DESC
-
-#define IDI_ICON_PSSILOCONTEXT UNUSED_IDI_ICON
-#define IDS_DESC_PSSILOCONTEXT UNUSED_IDS_DESC
-
-#define IDS_DESC_PSSILOCONTEXTNP UNUSED_IDS_DESC
-
-#define IDI_ICON_VIRTUALKEY UNUSED_IDI_ICON
-#define IDS_DESC_VIRTUALKEY UNUSED_IDS_DESC
-
-#define IDI_ICON_VREGCFGCTX UNUSED_IDI_ICON
-#define IDS_DESC_VREGCFGCTX UNUSED_IDS_DESC
-
-#define IDI_ICON_PROCESSSTATECHANGE UNUSED_IDI_ICON
-#define IDS_DESC_PROCESSSTATECHANGE UNUSED_IDS_DESC
-
-#define IDI_ICON_THREADSTATECHANGE UNUSED_IDI_ICON
-#define IDS_DESC_THREADSTATECHANGE UNUSED_IDS_DESC
-
-#define IDI_ICON_CPUPARTITION UNUSED_IDI_ICON
-#define IDS_DESC_CPUPARTITION UNUSED_IDS_DESC
-
-#define IDI_ICON_SCHEDULERSHAREDDATA UNUSED_IDI_ICON
-#define IDS_DESC_SCHEDULERSHAREDDATA UNUSED_IDS_DESC
-
-#define IDI_ICON_CROSSVMEVENT UNUSED_IDI_ICON
-#define IDS_DESC_CROSSVMEVENT UNUSED_IDS_DESC
-
-#define IDI_ICON_CROSSVMMUTANT UNUSED_IDI_ICON
-#define IDS_DESC_CROSSVMMUTANT UNUSED_IDS_DESC
+#define UNUSED_IDI_ICON IDI_ICON_UNKNOWN
+#define UNUSED_IDS_DESC IDS_DESC_UNKNOWN
+
+#define IDI_ICON_IORING UNUSED_IDI_ICON
+#define IDI_ICON_ACTIVATIONOBJECT UNUSED_IDI_ICON
+#define IDI_ICON_ACTIVITYREFERENCE UNUSED_IDI_ICON
+#define IDI_ICON_COREMESSAGING UNUSED_IDI_ICON
+#define IDI_ICON_COVERAGESAMPLER UNUSED_IDI_ICON
+#define IDI_ICON_RAWINPUTMANAGER UNUSED_IDI_ICON
+#define IDI_ICON_WAITCOMPLETIONPACKET UNUSED_IDI_ICON
+#define IDI_ICON_IOCOMPLETION_RESERVE UNUSED_IDI_ICON
+#define IDI_ICON_USERAPCRESERVE UNUSED_IDI_ICON
+#define IDI_ICON_ENERGYTRACKER UNUSED_IDI_ICON
+#define IDI_ICON_TERMINAL UNUSED_IDI_ICON
+#define IDI_ICON_TERMINALEVENTQUEUE UNUSED_IDI_ICON
+#define IDI_ICON_ETWSESSIONDEMUXENTRY UNUSED_IDI_ICON
+#define IDI_ICON_NDISCMSTATE UNUSED_IDI_ICON
+#define IDI_ICON_PSSILOCONTEXT UNUSED_IDI_ICON
+#define IDI_ICON_VIRTUALKEY UNUSED_IDI_ICON
+#define IDI_ICON_VREGCFGCTX UNUSED_IDI_ICON
+#define IDI_ICON_PROCESSSTATECHANGE UNUSED_IDI_ICON
+#define IDI_ICON_THREADSTATECHANGE UNUSED_IDI_ICON
+#define IDI_ICON_CPUPARTITION UNUSED_IDI_ICON
+#define IDI_ICON_SCHEDULERSHAREDDATA UNUSED_IDI_ICON
+#define IDI_ICON_CROSSVMEVENT UNUSED_IDI_ICON
+#define IDI_ICON_CROSSVMMUTANT UNUSED_IDI_ICON
extern WOBJ_TYPE_DESC g_TypeUnknown;
extern WOBJ_TYPE_DESC g_TypeSymbolicLink;
@@ -224,7 +199,7 @@ extern ULONG g_ObjectTypesCount;
HIMAGELIST ObManagerLoadImageList(
VOID);
-UINT ObManagerGetImageIndexByTypeName(
+INT ObManagerGetImageIndexByTypeName(
_In_opt_ LPCWSTR lpTypeName);
WOBJ_OBJECT_TYPE ObManagerGetIndexByTypeName(
diff --git a/Source/WinObjEx64/resource.h b/Source/WinObjEx64/resource.h
index c0197934..d8b7d542 100644
Binary files a/Source/WinObjEx64/resource.h and b/Source/WinObjEx64/resource.h differ
diff --git a/Source/WinObjEx64/sup/sup.c b/Source/WinObjEx64/sup/sup.c
index 4ad5d176..4ee32356 100644
--- a/Source/WinObjEx64/sup/sup.c
+++ b/Source/WinObjEx64/sup/sup.c
@@ -4,9 +4,9 @@
*
* TITLE: SUP.C
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 11 Aug 2025
+* DATE: 03 Oct 2025
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
@@ -16,7 +16,6 @@
*******************************************************************************/
#include "global.h"
#include "treelist/treelist.h"
-#include "props/propTypeConsts.h"
#ifndef OBEX_DEFINE_GUID
#define OBEX_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
@@ -2554,7 +2553,9 @@ BOOL supQueryWinstationDescription(
BOOL supQueryTypeInfo(
_In_ PUNICODE_STRING TypeName,
_Inout_ LPWSTR Buffer,
- _In_ DWORD cchBuffer //size of buffer in chars
+ _In_ DWORD BufferSize, //size of buffer in chars
+ _In_ DWORD KnownPoolTypesCount,
+ _In_ PVALUE_DESC PoolTypes
)
{
BOOL bResult = FALSE;
@@ -2564,7 +2565,7 @@ BOOL supQueryTypeInfo(
POBTYPE_ENTRY objectEntry;
if (Buffer == NULL ||
- cchBuffer < MAX_PATH)
+ BufferSize < MAX_PATH)
{
return FALSE;
}
@@ -2579,12 +2580,12 @@ BOOL supQueryTypeInfo(
if (RtlEqualUnicodeString(objectEntry->TypeName, TypeName, TRUE)) {
- for (nPool = 0; nPool < MAX_KNOWN_POOL_TYPES; nPool++) {
- if (objectEntry->PoolType == a_PoolTypes[nPool].dwValue) {
+ for (nPool = 0; nPool < KnownPoolTypesCount; nPool++) {
+ if (objectEntry->PoolType == PoolTypes[nPool].dwValue) {
_strncpy(Buffer,
- cchBuffer,
- a_PoolTypes[nPool].lpDescription,
- _strlen(a_PoolTypes[nPool].lpDescription));
+ BufferSize,
+ PoolTypes[nPool].lpDescription,
+ _strlen(PoolTypes[nPool].lpDescription));
break;
}
}
diff --git a/Source/WinObjEx64/sup/sup.h b/Source/WinObjEx64/sup/sup.h
index 6e2c3235..39d08419 100644
--- a/Source/WinObjEx64/sup/sup.h
+++ b/Source/WinObjEx64/sup/sup.h
@@ -669,7 +669,9 @@ BOOL supQuerySectionFileInfo(
BOOL supQueryTypeInfo(
_In_ PUNICODE_STRING TypeName,
_Inout_ LPWSTR Buffer,
- _In_ DWORD cchhBuffer);
+ _In_ DWORD BufferSize,
+ _In_ DWORD KnownPoolTypesCount,
+ _In_ PVALUE_DESC PoolTypes);
BOOL supQueryDriverDescription(
_In_ LPCWSTR lpDriverName,
diff --git a/Source/WinObjEx64/sup/w32k.c b/Source/WinObjEx64/sup/w32k.c
index 7854395d..9c93c938 100644
--- a/Source/WinObjEx64/sup/w32k.c
+++ b/Source/WinObjEx64/sup/w32k.c
@@ -4,9 +4,9 @@
*
* TITLE: W32K.C
*
-* VERSION: 2.08
+* VERSION: 2.10
*
-* DATE: 10 Jun 2025
+* DATE: 03 Oct 2025
*
* Win32k syscall table actual handlers resolving routines.
*
@@ -214,7 +214,7 @@ ULONG SdtpQueryW32GetWin32kApiSetTableOffset(
_In_ HMODULE hModule
)
{
- ULONG Index, c, ScanBytes, InstCount;
+ ULONG Index, matchCount, scanBytes, instCount;
PBYTE ptrCode;
hde64s hs;
@@ -224,9 +224,9 @@ ULONG SdtpQueryW32GetWin32kApiSetTableOffset(
}
Index = 0;
- c = 0;
- ScanBytes = (g_NtBuildNumber >= NT_WIN11_25H2) ? 64 : 32;
- InstCount = (g_NtBuildNumber >= NT_WIN11_25H2) ? 2 : 1;
+ matchCount = 0;
+ scanBytes = (g_NtBuildNumber > NT_WIN11_25H2) ? 64 : 32;
+ instCount = (g_NtBuildNumber > NT_WIN11_25H2) ? 2 : 1;
do {
@@ -241,14 +241,14 @@ ULONG SdtpQueryW32GetWin32kApiSetTableOffset(
(hs.flags & F_MODRM) &&
(hs.opcode == 0x8B))
{
- c += 1;
- if (c >= InstCount)
+ matchCount += 1;
+ if (matchCount >= instCount)
return hs.disp.disp32;
}
Index += hs.len;
- } while (Index < ScanBytes);
+ } while (Index < scanBytes);
return 0;
}
@@ -297,8 +297,8 @@ ULONG_PTR SdtpQueryWin32kSessionGlobals(
return 0;
}
- if (g_NtBuildNumber >= NT_WIN11_25H2)
- {
+ if (g_NtBuildNumber > NT_WIN11_25H2) {
+
Index = 0;
k = 0;
@@ -337,7 +337,7 @@ ULONG_PTR SdtpQueryWin32kSessionGlobals(
if (hs.flags & F_ERROR)
break;
- //
+ //
// Find W32GetSessionStateForSession call.
//
if ((hs.len == 5) &&
@@ -864,7 +864,7 @@ NTSTATUS SdtResolveServiceEntryModuleSessionAware(
hde64s hs;
ULONG offsets[3];
- ULONG c, k;
+ ULONG offsetIndex, k;
LONG rel;
@@ -953,7 +953,7 @@ NTSTATUS SdtResolveServiceEntryModuleSessionAware(
//
if (bFound) {
- c = 0;
+ offsetIndex = 0;
i = 0;
do {
@@ -972,16 +972,16 @@ NTSTATUS SdtResolveServiceEntryModuleSessionAware(
// Capture offset
//
if (hs.flags & F_DISP8)
- offsets[c] = hs.disp.disp8;
+ offsets[offsetIndex] = hs.disp.disp8;
else if (hs.flags & F_DISP16)
- offsets[c] = hs.disp.disp16;
+ offsets[offsetIndex] = hs.disp.disp16;
else if (hs.flags & F_DISP32)
- offsets[c] = hs.disp.disp32;
+ offsets[offsetIndex] = hs.disp.disp32;
else
- offsets[c] = 0;
+ offsets[offsetIndex] = 0;
- c += 1;
- if (c > W32CALL_MAX_OFFSET)
+ offsetIndex += 1;
+ if (offsetIndex > W32CALL_MAX_OFFSET)
break;
}
@@ -1010,6 +1010,10 @@ NTSTATUS SdtResolveServiceEntryModuleSessionAware(
//
// Offsets found and extracted, proceed with resolving.
//
+ if (Context->SessionId == 0 || Context->SessionId > 0xFFFF) {
+ resultStatus = STATUS_INVALID_PARAMETER;
+ break;
+ }
resultStatus = STATUS_PROCEDURE_NOT_FOUND;
@@ -1277,18 +1281,31 @@ ULONG SdtWin32kInitializeOnce(
}
if (g_NtBuildNumber <= NT_WIN11_24H2) {
+ //
+ // gLowSessionGlobalSlots is before any other variables, read as-is
+ //
if (!kdReadSystemMemory(varAddress, &Context->W32Globals.v1, sizeof(W32K_GLOBALS))) {
ulResult = ErrShadowWin32kGlobalsNotFound;
break;
}
}
- else {
+ else if (g_NtBuildNumber <= NT_WIN11_25H2) {
+ //
+ // gLowSessionGlobalSlots is in the middle of variables, use offset calculation
+ //
+ varAddress -= FIELD_OFFSET(W32K_GLOBALS_V2, gLowSessionGlobalSlots);
if (!kdReadSystemMemory(varAddress, &Context->W32Globals.v2, sizeof(W32K_GLOBALS_V2))) {
ulResult = ErrShadowWin32kGlobalsNotFound;
break;
}
}
-
+ else {
+ //
+ // Unknown case, need investigation and update.
+ //
+ ulResult = ErrShadowWin32kGlobalsNotFound;
+ break;
+ }
//
// Remember table offset.
diff --git a/Source/WinObjEx64/sup/w32k.h b/Source/WinObjEx64/sup/w32k.h
index 7134cd07..558bd4c4 100644
--- a/Source/WinObjEx64/sup/w32k.h
+++ b/Source/WinObjEx64/sup/w32k.h
@@ -1,12 +1,12 @@
/*******************************************************************************
*
-* (C) COPYRIGHT AUTHORS, 2023 - 2024
+* (C) COPYRIGHT AUTHORS, 2023 - 2025
*
* TITLE: W32K.H
*
-* VERSION: 2.06
+* VERSION: 2.10
*
-* DATE: 11 Oct 2024
+* DATE: 03 Oct 2025
*
* Common header file for the win32k support routines.
*
@@ -50,6 +50,7 @@ typedef struct _SGD_GLOBALS {
ULONG gAvailableSlots;
} SGD_GLOBALS, *PSGD_GLOBALS;
+// Used by 24H2
typedef struct _W32K_GLOBALS {
PVOID gLowSessionGlobalSlots; //pointer to list
ULONG gAvailableSlots;
@@ -67,6 +68,7 @@ typedef struct _W32K_GLOBALS {
PVOID gLock; //W32_PUSH_LOCK
} W32K_GLOBALS, *PW32K_GLOBALS;
+// Used by 25H2
typedef struct _W32K_GLOBALS_V2 {
PVOID gSessionGlobalSlots; //pointer to list
PVOID gpSESSIONSLOTS; //pointer to list
@@ -77,10 +79,9 @@ typedef struct _W32K_GLOBALS_V2 {
ULONGLONG TotalCount;
} gSessionApiSetHostRefCount;
PVOID gSessionApiSetHostRefCountLock;
- PVOID gSessionProcessLifetimeLock; //W32_PUSH_LOCK
PVOID gLowSessionGlobalSlots; //pointer to list
ULONG gAvailableSlots;
- ULONG Reserved0;
+ PVOID gSessionProcessLifetimeLock; //W32_PUSH_LOCK
PVOID gLock; //W32_PUSH_LOCK
} W32K_GLOBALS_V2, * PWIN32K_GLOBALS_V2;
diff --git a/Source/WinObjEx64/ui.h b/Source/WinObjEx64/ui.h
index eb0e0577..bdf5b1b8 100644
--- a/Source/WinObjEx64/ui.h
+++ b/Source/WinObjEx64/ui.h
@@ -4,9 +4,9 @@
*
* TITLE: UI.H
*
-* VERSION: 2.09
+* VERSION: 2.10
*
-* DATE: 21 Aug 2025
+* DATE: 03 Oct 2025
*
* Common header file for the user interface.
*
@@ -48,9 +48,9 @@ typedef HWND(WINAPI *pfnHtmlHelpW)(
);
#define PROGRAM_MAJOR_VERSION 2
-#define PROGRAM_MINOR_VERSION 0
-#define PROGRAM_REVISION_NUMBER 9
-#define PROGRAM_BUILD_NUMBER 2508
+#define PROGRAM_MINOR_VERSION 1
+#define PROGRAM_REVISION_NUMBER 0
+#define PROGRAM_BUILD_NUMBER 2510
#ifdef _USE_OWN_DRIVER
#define PROGRAM_NAME L"Windows Object Explorer 64-bit (Non-public version)"