From 5dbadac5c34e606ee02422dfcf948ecffba213ab Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sun, 21 Sep 2025 10:37:22 +0700 Subject: [PATCH 1/4] 2.1.0 Fixed incorrect object quota information dump Internal rearrange --- Source/WinObjEx64/kldbg.c | 26 ++++----- Source/WinObjEx64/objects.c | 103 ++++++++++++++++++++++++++---------- Source/WinObjEx64/objects.h | 6 +-- Source/WinObjEx64/ui.h | 10 ++-- 4 files changed, 97 insertions(+), 48 deletions(-) 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/objects.c b/Source/WinObjEx64/objects.c index d3b786cb..575237d3 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: 19 Sep 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..ba9aa7d5 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: 19 Sep 2025 * * Header file for internal Windows object types handling. * @@ -224,7 +224,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/ui.h b/Source/WinObjEx64/ui.h index eb0e0577..3377a4cd 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: 19 Sep 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 2509 #ifdef _USE_OWN_DRIVER #define PROGRAM_NAME L"Windows Object Explorer 64-bit (Non-public version)" From 2a5b4debd2d65d4e894cca8e1be106f8de20e28f Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Fri, 3 Oct 2025 18:06:27 +0700 Subject: [PATCH 2/4] 2.1.0 25H2 compatibility improvements --- Source/Shared/ntos/ntbuilds.h | 9 +++++--- Source/WinObjEx64/extras/extrasSSDT.c | 5 +++-- Source/WinObjEx64/sup/w32k.c | 31 +++++++++++++++++++-------- Source/WinObjEx64/sup/w32k.h | 11 +++++----- 4 files changed, 37 insertions(+), 19 deletions(-) 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/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/sup/w32k.c b/Source/WinObjEx64/sup/w32k.c index 7854395d..404672f7 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. * @@ -225,8 +225,8 @@ ULONG SdtpQueryW32GetWin32kApiSetTableOffset( Index = 0; c = 0; - ScanBytes = (g_NtBuildNumber >= NT_WIN11_25H2) ? 64 : 32; - InstCount = (g_NtBuildNumber >= NT_WIN11_25H2) ? 2 : 1; + ScanBytes = (g_NtBuildNumber > NT_WIN11_25H2) ? 64 : 32; + InstCount = (g_NtBuildNumber > NT_WIN11_25H2) ? 2 : 1; do { @@ -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) && @@ -1277,18 +1277,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; From 83e08de61fb35edca23775e2d32f7f9f6fa4e4a4 Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sat, 4 Oct 2025 12:39:26 +0700 Subject: [PATCH 3/4] 2.1.0 Added more descriptions for object types --- Source/CHANGELOG.txt | 6 ++ Source/TypesWithNoDesc.txt | 13 ----- Source/WinObjEx64/Resource.rc | Bin 164774 -> 168014 bytes Source/WinObjEx64/objects.c | 2 +- Source/WinObjEx64/objects.h | 107 +++++++++++++--------------------- Source/WinObjEx64/resource.h | Bin 44446 -> 45616 bytes Source/WinObjEx64/sup/w32k.c | 34 ++++++----- Source/WinObjEx64/ui.h | 4 +- 8 files changed, 69 insertions(+), 97 deletions(-) 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/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 b8ea84c56afe4e071db453a97413f827de77f84e..b9ea73c4dbbc3c87bc1df3a495fc3ee5f74d1c2b 100644 GIT binary patch delta 3700 zcmb_fT}&KR6uumaA{40IBCLe63x!H6KWo#}YA6fKwrqd+UkX|Z%d-5G*&kS1OM_{R zMw7mniphCug2wo0+SIU5YWi-7?>;m&KK0Ev6BG42cXk+-E-Bj(GQ;f5oqN9fedm1V z&i7vwZLAeNC~Pb9sJB%sj(5~aW{%?>*{m`;SUIsu=^D&4H_bopFBkYT;^Y zd+DRQ-uJRR{q$L9>RD&r`tPgF?-ubyHP!M;9u=j$HS}!@d*if^Hw-E*m{xJM$aTHc z$UVJOdEBKEY7zHts5v#IBDi+ph^QI-PO2qbhj5<5h!{UiQaN7I0ZCGz&3zv8Gt9%b-Xvt7lKr!Ioks9{8c)?HxNB;k#J5$afnnmK$wl!ByHgm zm4mb}xP|^u8np3(ms)rYg7LL+x{(dcOioH7s+ml-WD+n2R1tL(XB*WFK!h+loe>Ot zr}@Ecs^s+vny{hxE!uMhk|7262FaZl=8qf6$tzwuVy+sga?K89=kHjq!K_@2fLK%Y z7_N*A9c0CES7>Bhl?e? za0Ub7`z5%0WuBVNS{|69X*-gw(ucY7lBv=>VlCqk#iC%q%+Yj)@+Zfr;;8v>caBu- z(iG{;=g=9d=Zy#wIq?C#qK(&KF%(72s4l`~ZDmfOS&U3dH|?}ioiMeh4dghnWjv6I zzr?k_SVJYQFy~SWSVbIDge2W7OporKrS<%5>_u{AZwa+3Dur~cTR82Q5%0O(VGQ&w3x*Ee0YUQQ$OCKw+i^{D0OLa zZ(FnGx~M5lsBPGi2!>Wc?ult>C4kN%IjKIvy(LtGSQk{nv*|bRT1;1)SzjT%j6v)^ zMfHwhHK6?HT|RYIpNG^4d*Wy;(vR(QE*Zuvk_Fch%ixEzLDWb)zYQA1e92+lpK zkMBk4oL)e+MSb?E+;dpy*%m52ZIKm2j>dFz4*|O5)1;9Nagm+ zpmO^Lt!$W1^=>z9vBwu@XhiF28o1eV#45y3@*1eFTmS?B#|IFDfY%|q@=pfUlvz@y zhj9F#ybA6MQsry16O?^mM0?Uv5nu_0AX|y~9TE%$!|p}&Tlo7Sv&|(sskD4ECJ=NZ zdJl@iZ|75!1!DV7ViSVS583<4lH4b#rpl^KvDFyXx}<@bYt|dXUla5*@9(DlFN%KL zik|6qFB$vs2-TMlpmwB^hQYTVXH)cF463fPf^F?EGRy^fWfKPtr4iNfpAB%sE*~8z zj$++u>tW9T3IMyATBi>dV@HwX5?v*^qySFu9LH>Y+HrK$o0!~y1En_#TJ7fpKk3ZA znQW?;wCctZy8z)L{tsZ`BCd6WP`*)~ zG*G!asX5A=APz&6LXchZE$*MEmNK7wPv8)ILn^>ucA#yFE0JL7bI< z&l#=ViO~iEI!qAZF5>&guSV@Qkp3*|@R6fHZ%pJxr|yDH@@2N!7X-YnL~A2wZ{Q^F Pm*qpKBIUh9)A|1cUg)>RkAL>m)l*VIi{jd5qwZfw#;W736<%O?7rdj~`|f|<Z3uN57SWub*NjzmLD7lx2EtqL@8)2 z*D=t_ZTrG9*22-sZ=3mc{9T8RkxS<(B`-#~RlYmGbrOs72Dx#Rx7Gym*9G3#tr5=C z6!}n{!Z}Sv^6>9do=P|sA#rgEjGm9vl;k=%yxye(r+wM;vDJ^Xj@g7hUzP%(+E_Q$;Ag5;$%cTG4H0M_w z;rDO2vBuMWMp}~SSOB+KG+g^NU>cuBF!W8D5-3d9FgHs>nnzX~;7pviOJbZaug(I2 z>gATpTWh1#Cl7`>^oDUTaSXiwCOEUwU;}f=*E6hsopV`Kp#UB#X*?9%#eD`hA9Jm2 zR1Q{4k6Q`4km(?{%inR{6tNSZgH0B%zNxC(>BRdVa;J=Ccx=8OElq?xolQdl z1qP4ZO94{XyM}kLe)}+vx*8Rw+U5-hbp7dSwChkCmN&C3&#&_PP1d_f6@?FIr~Dgm zWQV$$HWjmO^uAEhR}x)+uAGZ;d*#L?->+TiNC_sfL+*N82!E%LHKk|T568qy{0qda!TwCkSS*~{_D T^*P?VW);L~to(6}OSLZnTAZv1 diff --git a/Source/WinObjEx64/objects.c b/Source/WinObjEx64/objects.c index 575237d3..c48c5e5c 100644 --- a/Source/WinObjEx64/objects.c +++ b/Source/WinObjEx64/objects.c @@ -6,7 +6,7 @@ * * VERSION: 2.10 * -* DATE: 19 Sep 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 diff --git a/Source/WinObjEx64/objects.h b/Source/WinObjEx64/objects.h index ba9aa7d5..6ccf81bf 100644 --- a/Source/WinObjEx64/objects.h +++ b/Source/WinObjEx64/objects.h @@ -6,7 +6,7 @@ * * VERSION: 2.10 * -* DATE: 19 Sep 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; diff --git a/Source/WinObjEx64/resource.h b/Source/WinObjEx64/resource.h index c019793456b0846d271a85c944a719bb49174143..d8b7d54289eb389477324f857eba1c12365cfe5a 100644 GIT binary patch delta 442 zcmZ{fJ4*vW6ooIz2E*pHVid$|b{91wq)4y{q{+io19`d0MlEecyCv8Ng4hQR7FtBH zwg{xN(#HQFHU_K&!Oqru*G{pR%M9ntH{T3j0;9LUNYQZgbq9%2@z00#nZInYZsOWv^C4TjAbgBECq3)p+)|R`p!z7!R z@PxF^rv|x9vwf~Zd-%|w#VR6cjhj_!plC1pq`S0lghMqt+hK#U?^2~L-Zk0X##j1G zZX+B0uhBBjF`CmN4jYI`kNNvS%je%4-k)q@{A5YfW3m>J*KBrksgAW<3kT-0+zGbH z#dXrc!<33Av(H^+S{xnzg}CLZKzTe?R$*Exag6miak$~KeI1hv1MQG9Hmz_7gO&Jr VkXcf3IKAojIVOa$v2p&Zb1M5 delta 132 zcmdn+glXPwrVT8zlRqf(P0o?^nQWjdGg(j04$QwI=QDYMDc|G{`DI}KGzA|p?WG8! zqrmJ$;xqYx3RrIQ9o2g*lN%%jCjT+fnH-?aGWko36v)8MC$vE;n GJ2e2y_cdGq diff --git a/Source/WinObjEx64/sup/w32k.c b/Source/WinObjEx64/sup/w32k.c index 404672f7..9c93c938 100644 --- a/Source/WinObjEx64/sup/w32k.c +++ b/Source/WinObjEx64/sup/w32k.c @@ -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; } @@ -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; diff --git a/Source/WinObjEx64/ui.h b/Source/WinObjEx64/ui.h index 3377a4cd..bdf5b1b8 100644 --- a/Source/WinObjEx64/ui.h +++ b/Source/WinObjEx64/ui.h @@ -6,7 +6,7 @@ * * VERSION: 2.10 * -* DATE: 19 Sep 2025 +* DATE: 03 Oct 2025 * * Common header file for the user interface. * @@ -50,7 +50,7 @@ typedef HWND(WINAPI *pfnHtmlHelpW)( #define PROGRAM_MAJOR_VERSION 2 #define PROGRAM_MINOR_VERSION 1 #define PROGRAM_REVISION_NUMBER 0 -#define PROGRAM_BUILD_NUMBER 2509 +#define PROGRAM_BUILD_NUMBER 2510 #ifdef _USE_OWN_DRIVER #define PROGRAM_NAME L"Windows Object Explorer 64-bit (Non-public version)" From 65ba20387790bc06e259cce22ff9c482d0281019 Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sun, 5 Oct 2025 11:08:16 +0700 Subject: [PATCH 4/4] 2.1.0 Reduced duplicate code in plugins --- Source/Plugins/ApiSetView/ApiSetView.vcxproj | 8 + .../ApiSetView/ApiSetView.vcxproj.filters | 27 + Source/Plugins/ApiSetView/Resource.rc | Bin 6604 -> 6604 bytes Source/Plugins/ApiSetView/global.h | 8 +- Source/Plugins/ApiSetView/main.c | 4 +- Source/Plugins/ApiSetView/query.c | 47 +- Source/Plugins/ApiSetView/ui.h | 16 +- Source/Plugins/ExamplePlugin/Resource.rc | Bin 4668 -> 4668 bytes Source/Plugins/ImageScope/ImageScope.vcxproj | 6 +- .../ImageScope/ImageScope.vcxproj.filters | 18 +- Source/Plugins/ImageScope/Resource.rc | Bin 7748 -> 7748 bytes Source/Plugins/ImageScope/global.h | 8 +- Source/Plugins/ImageScope/main.c | 4 +- Source/Plugins/ImageScope/query.c | 4 +- Source/Plugins/ImageScope/sup.c | 668 ------------ Source/Plugins/ImageScope/ui.c | 6 +- Source/Plugins/ImageScope/ui.h | 23 +- Source/Plugins/Sonar/Resource.rc | Bin 4650 -> 4650 bytes Source/Plugins/Sonar/Sonar.vcxproj | 4 +- Source/Plugins/Sonar/Sonar.vcxproj.filters | 12 +- Source/Plugins/Sonar/global.h | 8 +- Source/Plugins/Sonar/main.c | 44 +- Source/Plugins/Sonar/query.c | 35 +- Source/Plugins/Sonar/sup.h | 88 -- Source/Plugins/Sonar/ui.h | 20 +- Source/Plugins/{Sonar/sup.c => utils.c} | 954 +++++++++++++----- Source/Plugins/{ImageScope/sup.h => utils.h} | 85 +- Source/WinObjEx64/list.c | 9 +- Source/WinObjEx64/sup/sup.c | 21 +- Source/WinObjEx64/sup/sup.h | 4 +- 30 files changed, 941 insertions(+), 1190 deletions(-) delete mode 100644 Source/Plugins/ImageScope/sup.c delete mode 100644 Source/Plugins/Sonar/sup.h rename Source/Plugins/{Sonar/sup.c => utils.c} (55%) rename Source/Plugins/{ImageScope/sup.h => utils.h} (55%) 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 0750a3a28ccdbcfcf8f44d52106a658b3d64c6b0..09de522cda7e8e913215e1f8b89597b32e6d56f6 100644 GIT binary patch delta 62 zcmX?Oe8zagEDmNv27}3SIZVN{Jg4O5cN}+^z?_dqCfkT{ZFb=6 G;RXO)cM?MY delta 62 zcmX?Oe8zagEDmM^28+paIZVN{Jg4O5cN}+^z?_dqCfkT{ZFb=6 G;RXO;W)fcj 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 b70f2cd235adae4d95f238fd3aaddf41635bd96d..235ca96795a6ae42e2beaab31dda571d80749c36 100644 GIT binary patch delta 54 xcmdm^vPWgZEDmNv27}3SIZVN{Jg4O5cN}+^z?_d + @@ -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 f5b1857211ee87f53b01345618f62d94707fa8bd..a823669bcdca4308df63e8380224469927059c7a 100644 GIT binary patch delta 58 zcmX?NbHrxDEDmNv27}3SIZVN{Jg4O5cN}+^z?_dqHk<{T C=Md8X delta 58 zcmX?NbHrxDEDmM^28+paIZVN{Jg4O5cN}+^z?_dqHk<{X CW)SZH 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 35fecc269af405461b992bc8b4b88b169f843c55..4b96fcf1b9bb5ad3f966fb5391fa85b929352956 100644 GIT binary patch delta 50 wcmZ3bvPxycEDmNv27}3SIZVN{Jg4O5cN}+^z?_d0DE=~uK)l5 delta 50 wcmZ3bvPxycEDmM^28+paIZVN{Jg4O5cN}+^z?_d0Dct>%K!iX 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/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/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,