2022-06-08 16:23:19 +01:00
//////////////////////////////////////////////////////////////////////////////////////////
// WinSpy based window finder
//
# include <windows.h>
# include "Helpers/FindTool.h"
typedef enum DEVICE_SCALE_FACTOR {
DEVICE_SCALE_FACTOR_INVALID = 0 ,
SCALE_100_PERCENT = 100 ,
SCALE_120_PERCENT = 120 ,
SCALE_125_PERCENT = 125 ,
SCALE_140_PERCENT = 140 ,
SCALE_150_PERCENT = 150 ,
SCALE_160_PERCENT = 160 ,
SCALE_175_PERCENT = 175 ,
SCALE_180_PERCENT = 180 ,
SCALE_200_PERCENT = 200 ,
SCALE_225_PERCENT = 225 ,
SCALE_250_PERCENT = 250 ,
SCALE_300_PERCENT = 300 ,
SCALE_350_PERCENT = 350 ,
SCALE_400_PERCENT = 400 ,
SCALE_450_PERCENT = 450 ,
SCALE_500_PERCENT = 500
} DEVICE_SCALE_FACTOR ;
typedef HRESULT ( CALLBACK * P_GetScaleFactorForMonitor ) ( HMONITOR , DEVICE_SCALE_FACTOR * ) ;
UINT GetMonitorScaling ( HWND hwnd )
{
static HINSTANCE shcore = LoadLibrary ( L " Shcore.dll " ) ;
if ( shcore ! = nullptr )
{
if ( auto getScaleFactorForMonitor =
P_GetScaleFactorForMonitor ( GetProcAddress ( shcore , " GetScaleFactorForMonitor " ) ) )
{
HMONITOR monitor =
MonitorFromWindow ( hwnd , MONITOR_DEFAULTTONEAREST ) ;
DEVICE_SCALE_FACTOR Scale ;
getScaleFactorForMonitor ( monitor , & Scale ) ;
return Scale ;
}
}
return 100 ;
}
# define IDD_FINDER_TOOL 111
# define ID_FINDER_TARGET 112
# define ID_FINDER_EXPLAIN 113
# define ID_FINDER_RESULT 114
struct SFinderWndData {
int Scale ;
HFONT hFont ;
} ;
# define DS(x) ((x) * WndData.Scale / 100)
UINT CALLBACK FindProc ( HWND hwndTool , UINT uCode , HWND hwnd )
{
ULONG pid ;
if ( uCode = = WFN_END )
GetWindowThreadProcessId ( hwnd , & pid ) ;
else
pid = 0 ;
hwndTool = GetParent ( hwndTool ) ;
SFinderWndData & WndData = * ( SFinderWndData * ) GetWindowLongPtr ( hwndTool , 0 ) ;
if ( pid & & pid ! = GetCurrentProcessId ( ) )
{
RECT rc ;
GetWindowRect ( hwndTool , & rc ) ;
if ( rc . bottom - rc . top < = DS ( 150 ) )
SetWindowPos ( hwndTool , NULL , 0 , 0 , rc . right - rc . left , rc . bottom - rc . top + DS ( 70 ) , SWP_SHOWWINDOW | SWP_NOMOVE ) ;
CBoxedProcessPtr pProcess = theAPI - > GetProcessById ( pid ) ;
if ( ! pProcess . isNull ( ) )
{
2022-09-29 17:28:48 +01:00
std : : wstring result = CSandMan : : tr ( " The selected window is running as part of program %1 in sandbox %2 " ) . arg ( pProcess - > GetProcessName ( ) ) . arg ( pProcess - > GetBoxName ( ) ) . toStdWString ( ) ;
2022-06-08 16:23:19 +01:00
SetWindowText ( GetDlgItem ( hwndTool , ID_FINDER_RESULT ) , result . c_str ( ) ) ;
//::ShowWindow(GetDlgItem(hwndTool, ID_FINDER_YES_BOXED), SW_SHOW);
}
else
{
2022-09-29 17:28:48 +01:00
std : : wstring result = CSandMan : : tr ( " The selected window is not running as part of any sandboxed program. " ) . toStdWString ( ) ;
2022-06-08 16:23:19 +01:00
SetWindowText ( GetDlgItem ( hwndTool , ID_FINDER_RESULT ) , result . c_str ( ) ) ;
//::ShowWindow(GetDlgItem(hwndTool, ID_FINDER_NOT_BOXED), SW_SHOW);
}
: : ShowWindow ( GetDlgItem ( hwndTool , ID_FINDER_RESULT ) , SW_SHOW ) ;
}
else
{
RECT rc ;
GetWindowRect ( hwndTool , & rc ) ;
if ( rc . bottom - rc . top > DS ( 150 ) )
SetWindowPos ( hwndTool , NULL , 0 , 0 , rc . right - rc . left , rc . bottom - rc . top - DS ( 70 ) , SWP_SHOWWINDOW | SWP_NOMOVE ) ;
//::ShowWindow(GetDlgItem(hwndTool, ID_FINDER_YES_BOXED), SW_HIDE);
//::ShowWindow(GetDlgItem(hwndTool, ID_FINDER_NOT_BOXED), SW_HIDE);
: : ShowWindow ( GetDlgItem ( hwndTool , ID_FINDER_RESULT ) , SW_HIDE ) ;
}
return 0 ;
}
// hwnd: All window processes are passed the handle of the window
// that they belong to in hwnd.
// msg: Current message (e.g., WM_*) from the OS.
// wParam: First message parameter, note that these are more or less
// integers, but they are really just "data chunks" that
// you are expected to memcpy as raw data to float, etc.
// lParam: Second message parameter, same deal as above.
LRESULT CALLBACK WndProc ( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam )
{
switch ( msg )
{
case WM_CREATE :
{
CREATESTRUCT * createStruct = ( CREATESTRUCT * ) lParam ;
SFinderWndData & WndData = * ( SFinderWndData * ) createStruct - > lpCreateParams ;
SetWindowLongPtr ( hwnd , 0 , ( LONG_PTR ) & WndData ) ;
2022-09-29 17:28:48 +01:00
std : : wstring info = CSandMan : : tr ( " Drag the Finder Tool over a window to select it, then release the mouse to check if the window is sandboxed. " ) . toStdWString ( ) ;
2022-06-08 16:23:19 +01:00
CreateWindow ( L " Static " , L " " , SS_BITMAP | SS_NOTIFY | WS_VISIBLE | WS_CHILD , DS ( 10 ) , DS ( 10 ) , DS ( 32 ) , DS ( 32 ) , hwnd , ( HMENU ) ID_FINDER_TARGET , NULL , NULL ) ;
CreateWindow ( L " Static " , info . c_str ( ) , WS_VISIBLE | WS_CHILD , DS ( 60 ) , DS ( 10 ) , DS ( 180 ) , DS ( 85 ) , hwnd , ( HMENU ) ID_FINDER_EXPLAIN , NULL , NULL ) ;
CreateWindow ( L " Static " , L " " , WS_CHILD , DS ( 60 ) , DS ( 100 ) , DS ( 180 ) , DS ( 50 ) , hwnd , ( HMENU ) ID_FINDER_RESULT , NULL , NULL ) ;
WndData . hFont = CreateFont ( DS ( 13 ) , 0 , 0 , 0 , FW_DONTCARE , FALSE , FALSE , FALSE , ANSI_CHARSET , OUT_TT_PRECIS , CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY , DEFAULT_PITCH | FF_DONTCARE , TEXT ( " Tahoma " ) ) ;
if ( WndData . hFont ) {
SendMessage ( GetDlgItem ( hwnd , ID_FINDER_EXPLAIN ) , WM_SETFONT , ( WPARAM ) WndData . hFont , TRUE ) ;
SendMessage ( GetDlgItem ( hwnd , ID_FINDER_RESULT ) , WM_SETFONT , ( WPARAM ) WndData . hFont , TRUE ) ;
}
MakeFinderTool ( GetDlgItem ( hwnd , ID_FINDER_TARGET ) , FindProc ) ;
break ;
}
case WM_CLOSE :
SFinderWndData & WndData = * ( SFinderWndData * ) GetWindowLongPtr ( hwnd , 0 ) ;
if ( WndData . hFont ) DeleteObject ( WndData . hFont ) ;
//DestroyWindow(hwnd);
PostQuitMessage ( 0 ) ;
break ;
}
return DefWindowProc ( hwnd , msg , wParam , lParam ) ;
}
DWORD WINAPI FinderThreadFunc ( LPVOID lpParam )
{
MSG msg ;
WNDCLASS mainWindowClass = { 0 } ;
HINSTANCE hInstance = NULL ;
// You can set the main window name to anything, but
// typically you should prefix custom window classes
// with something that makes it unique.
mainWindowClass . lpszClassName = TEXT ( " SBp.WndFinder " ) ;
mainWindowClass . hInstance = hInstance ;
mainWindowClass . hbrBackground = GetSysColorBrush ( COLOR_3DFACE ) ;
mainWindowClass . lpfnWndProc = WndProc ;
mainWindowClass . hCursor = LoadCursor ( 0 , IDC_ARROW ) ;
mainWindowClass . cbWndExtra = sizeof ( void * ) ; // SFinderWndData
RegisterClass ( & mainWindowClass ) ;
// Notes:
// - The classname identifies the TYPE of the window. Not a C type.
// This is a (TCHAR*) ID that Windows uses internally.
// - The window name is really just the window text, this is
// commonly used for captions, including the title
// bar of the window itself.
// - parentHandle is considered the "owner" of this
// window. MessageBoxes can use HWND_MESSAGE to
// free them of any window.
// - menuHandle: hMenu specifies the child-window identifier,
// an integer value used by a dialog box
// control to notify its parent about events.
// The application determines the child-window
// identifier; it must be unique for all
// child windows with the same parent window.
SFinderWndData WndData ;
WndData . Scale = GetMonitorScaling ( MainWndHandle ) ;
HWND hwnd = CreateWindow ( mainWindowClass . lpszClassName , CSandMan : : tr ( " Sandboxie-Plus - Window Finder " ) . toStdWString ( ) . c_str ( )
, WS_SYSMENU | WS_CAPTION | WS_VISIBLE , CW_USEDEFAULT , CW_USEDEFAULT , DS ( 275 ) , DS ( 135 ) , NULL , 0 , hInstance , & WndData ) ;
while ( GetMessage ( & msg , NULL , 0 , 0 ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
return ( int ) msg . wParam ;
}
2022-07-11 20:12:42 +01:00
2022-06-08 16:23:19 +01:00
void CSandMan : : OnWndFinder ( )
{
m_pWndFinder - > setEnabled ( false ) ;
HANDLE hThread = CreateThread ( NULL , 0 , FinderThreadFunc , NULL , 0 , NULL ) ;
QWinEventNotifier * finishedNotifier = new QWinEventNotifier ( hThread ) ;
finishedNotifier - > setEnabled ( true ) ;
connect ( finishedNotifier , & QWinEventNotifier : : activated , this , [ finishedNotifier , this , hThread ] ( ) {
CloseHandle ( hThread ) ;
m_pWndFinder - > setEnabled ( true ) ;
finishedNotifier - > setEnabled ( false ) ;
finishedNotifier - > deleteLater ( ) ;
} ) ;
}