go my file uploader
This commit is contained in:
commit
c5fab8aa94
22
.gitattributes
vendored
Normal file
22
.gitattributes
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=crlf
|
||||||
|
|
||||||
|
# Custom for Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
*.vbproj merge=union
|
||||||
|
*.fsproj merge=union
|
||||||
|
*.dbproj merge=union
|
||||||
|
|
||||||
|
# Standard to msysgit
|
||||||
|
*.doc diff=astextplain
|
||||||
|
*.DOC diff=astextplain
|
||||||
|
*.docx diff=astextplain
|
||||||
|
*.DOCX diff=astextplain
|
||||||
|
*.dot diff=astextplain
|
||||||
|
*.DOT diff=astextplain
|
||||||
|
*.pdf diff=astextplain
|
||||||
|
*.PDF diff=astextplain
|
||||||
|
*.rtf diff=astextplain
|
||||||
|
*.RTF diff=astextplain
|
149
.gitignore
vendored
Normal file
149
.gitignore
vendored
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#################
|
||||||
|
## Visual Studio
|
||||||
|
#################
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.vspscc
|
||||||
|
.builds
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.db
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish
|
||||||
|
|
||||||
|
# Others
|
||||||
|
[Bb]in
|
||||||
|
[Oo]bj
|
||||||
|
sql
|
||||||
|
TestResults
|
||||||
|
*.Cache
|
||||||
|
ClientBin
|
||||||
|
stylecop.*
|
||||||
|
~$*
|
||||||
|
*.dbmdl
|
||||||
|
Generated_Code #added for RIA/Silverlight projects
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
#Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
############
|
||||||
|
## Windows
|
||||||
|
############
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
##########################
|
||||||
|
## Project specific rules
|
||||||
|
##########################
|
||||||
|
|
||||||
|
build/Installer/*.exe
|
||||||
|
ProcessHacker/include/phapprev.h
|
||||||
|
ProcessHacker/sdk/phapppub.h
|
||||||
|
plugins-extra/
|
||||||
|
sdk/
|
||||||
|
|
||||||
|
KProcessHacker/*.log
|
||||||
|
KProcessHacker/*.err
|
||||||
|
KProcessHacker/*.wrn
|
||||||
|
KProcessHacker/*/objchk_*
|
||||||
|
KProcessHacker/*/objfre_*
|
||||||
|
|
||||||
|
!plugins/SamplePlugin/bin/
|
||||||
|
plugins/SamplePlugin/bin/Debug32/
|
||||||
|
plugins/SamplePlugin/bin/Debug64/
|
||||||
|
plugins/SamplePlugin/bin/Release32/*
|
||||||
|
!plugins/SamplePlugin/bin/Release32/SamplePlugin.dll
|
||||||
|
plugins/SamplePlugin/bin/Release64/*
|
||||||
|
!plugins/SamplePlugin/bin/Release64/SamplePlugin.dll
|
||||||
|
|
||||||
|
!tools/CustomSignTool/bin/
|
||||||
|
tools/CustomSignTool/bin/Debug*/
|
||||||
|
tools/CustomSignTool/bin/Release*/*
|
||||||
|
!tools/CustomSignTool/bin/Release32/CustomSignTool.exe
|
||||||
|
!tools/CustomSignTool/bin/Release64/CustomSignTool.exe
|
||||||
|
|
||||||
|
!tools/fixlib/bin/
|
||||||
|
tools/fixlib/bin/Debug/
|
||||||
|
tools/fixlib/bin/Release/*
|
||||||
|
!tools/fixlib/bin/Release/fixlib.exe
|
||||||
|
|
||||||
|
!tools/GenerateHeader/GenerateHeader/bin/
|
||||||
|
tools/GenerateHeader/GenerateHeader/bin/Debug/
|
||||||
|
tools/GenerateHeader/GenerateHeader/bin/Release/*
|
||||||
|
!tools/GenerateHeader/GenerateHeader/bin/Release/GenerateHeader.exe
|
||||||
|
|
||||||
|
!tools/GenerateZw/GenerateZw/bin/
|
||||||
|
tools/GenerateZw/GenerateZw/bin/Debug/
|
||||||
|
tools/GenerateZw/GenerateZw/bin/Release/*
|
||||||
|
!tools/GenerateZw/GenerateZw/bin/Release/GenerateZw.exe
|
||||||
|
|
||||||
|
!tools/UpdateGitRevision/UpdateGitRevision/bin/
|
||||||
|
tools/UpdateGitRevision/UpdateGitRevision/bin/Debug/
|
||||||
|
tools/UpdateGitRevision/UpdateGitRevision/bin/Release/*
|
||||||
|
!tools/UpdateGitRevision/UpdateGitRevision/bin/Release/UpdateGitRevision.exe
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "plugins-extra"]
|
||||||
|
path = plugins-extra
|
||||||
|
url = https://github.com/processhacker2/plugins-extra
|
654
CHANGELOG.txt
Normal file
654
CHANGELOG.txt
Normal file
@ -0,0 +1,654 @@
|
|||||||
|
Process Hacker
|
||||||
|
|
||||||
|
2.39
|
||||||
|
* HIGHLIGHTS:
|
||||||
|
* Improved compatibility with security and anti-cheat software
|
||||||
|
* Added ability to edit process environment variables
|
||||||
|
* Fixed .NET process detection
|
||||||
|
* OTHER CHANGES:
|
||||||
|
* Improved tooltip information for dllhost.exe
|
||||||
|
* Removed Terminator
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Fixed .NET assembly tab performance issues
|
||||||
|
* Added extra .NET memory counters to the .NET performance tab
|
||||||
|
* Added "Show sizes in bytes" checkbox to the .NET performance tab
|
||||||
|
* Added right-click menu to the .NET assembly tab
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Fixed "No process" disk event bug
|
||||||
|
* Updated HardwareDevices plugin:
|
||||||
|
* Fixed incorrect drive letters
|
||||||
|
* Fixed drive letter and panel clipping issue
|
||||||
|
|
||||||
|
2.38
|
||||||
|
* HIGHLIGHTS:
|
||||||
|
* Added labels to indicate the maximum data point in each I/O graph
|
||||||
|
* Graph grids now scale correctly when resized
|
||||||
|
* Improved high DPI scaling
|
||||||
|
* Added exploit mitigation policy information to process properties (Windows 8 and above)
|
||||||
|
* Added File modified time and File size columns for processes and modules
|
||||||
|
* Added Key modified time column for services
|
||||||
|
* Clicking a tray icon now shows the pop-up UI (useful for touch-enabled devices)
|
||||||
|
* The NetAdapters plugin has been renamed to HardwareDevices
|
||||||
|
* This plugin shows network adapter and disk drive graphs
|
||||||
|
* If you are manually upgrading, please delete NetAdapters.dll from the plugins folder
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Added "Collapse by default" option for processes
|
||||||
|
* OTHER CHANGES:
|
||||||
|
* Added "Start when I log on" option
|
||||||
|
* Added "Not responding" text to tray icon rich pop-up for programs that are hung
|
||||||
|
* Added right-click menu and double-click action for environment variables
|
||||||
|
* Added dialog box to show long command line strings
|
||||||
|
* Added Time stamp column for processes
|
||||||
|
* Added -sysinfo command line parameter for opening System Information at startup
|
||||||
|
* Added 32x32 icons for high DPI displays
|
||||||
|
* Digital signature verification is now performed with very low I/O priority
|
||||||
|
* Improved performance when handling a large number of threads, modules or handles
|
||||||
|
* The pop-up UI no longer displays when double-clicking the tray icon
|
||||||
|
* Fixed ASLR state being shown as N/A in process properties
|
||||||
|
* Fixed multi monitor window placement bug
|
||||||
|
* Fixed handle enumeration bug affecting processes with PID >= 65536
|
||||||
|
* Fixed Interrupts being missing from the max CPU usage history
|
||||||
|
* Updated ToolStatus plugin:
|
||||||
|
* Added 32x32 icons for high DPI displays
|
||||||
|
* Fixed status bar crash
|
||||||
|
* NOTE:
|
||||||
|
* This release has significant internal code changes. Please make sure all plugins are up-to-date.
|
||||||
|
|
||||||
|
2.37
|
||||||
|
* HIGHLIGHTS:
|
||||||
|
* Updated for Windows 10
|
||||||
|
* The "Include CPU (and other) usage of children in collapsed processes" option now aggregates memory and I/O statistics
|
||||||
|
* Added regex search to "Find Handles or DLLs"
|
||||||
|
* Added process exit codes to log
|
||||||
|
* Fixed crash that occurred under some conditions when processes terminated
|
||||||
|
* OTHER CHANGES:
|
||||||
|
* Added warning when trying to search for handles when the system has too many handles open
|
||||||
|
* Upgraded to PCRE2
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Rewrite of .NET Performance statistics and AppDomain enumeration
|
||||||
|
* Updated OnlineChecks plugin:
|
||||||
|
* Fixed virusscan.jotti.org uploader
|
||||||
|
* Updated NetAdapters plugin:
|
||||||
|
* Added adapter details window
|
||||||
|
* Updated ToolStatus plugin:
|
||||||
|
* Added CPU, Memory and I/O graphs to the toolbar (not enabled by default)
|
||||||
|
* Added toolbar and status bar customization, as well as a new theme
|
||||||
|
* Added option to auto-hide the main menu
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Added individual process highlighting support
|
||||||
|
|
||||||
|
2.36
|
||||||
|
* HIGHLIGHTS:
|
||||||
|
* New rich pop-up UI when hovering the cursor over a tray icon, showing the most active processes
|
||||||
|
* Completely new Memory tab for processes, with heap, stack and working set usage
|
||||||
|
* Process Hacker now takes 32-bit dumps of 32-bit processes on 64-bit Windows
|
||||||
|
* NOTE: When using the portable (.zip) release, the entire archive must be extracted
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Process Hacker now displays managed stack traces for 32-bit .NET processes on 64-bit Windows
|
||||||
|
* Fixed inaccurate stack traces when clicking Refresh
|
||||||
|
* Added AppDomain column for threads in .NET programs
|
||||||
|
* OTHER CHANGES:
|
||||||
|
* Added customizable bytes per row setting for memory editor
|
||||||
|
* Dramatically faster handle listing and search when running without administrative privileges
|
||||||
|
* Improved accuracy and speed of symbol resolution, especially when new modules are loaded
|
||||||
|
* Added trigger and delayed start information to service list
|
||||||
|
* Added file information to service list tooltips
|
||||||
|
* Balloon tips for process/service notifications are now clickable
|
||||||
|
* Added handle names for unnamed File objects
|
||||||
|
* Added I/O Priority to tray icon process menu
|
||||||
|
* Added warning for users who attempt to start the 32-bit version on 64-bit Windows
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Added service protection and SID information
|
||||||
|
* Added auto-elevation when saving recovery information, triggers and other service settings
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added tray icon mini info window support
|
||||||
|
* Improved automatic GPU node selection
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Added tray icon mini info window support
|
||||||
|
* Fixed a bug in phsvc that caused hangs when automatically elevating actions
|
||||||
|
* Fixed hang when viewing handle security for certain File objects
|
||||||
|
* Fixed lack of information on startup when using slower refresh intervals
|
||||||
|
* Fixed Read/Write Address crash
|
||||||
|
* Fixed service non-polling mode on Windows 8 and above
|
||||||
|
* Fixed file dialog crash in Windows PE environments
|
||||||
|
* Fixed string scanning false positive case
|
||||||
|
* Fixed process window detection for Modern UI apps
|
||||||
|
* Fixed handle list selection bug when disabling "Hide unnamed handles"
|
||||||
|
* NOTE:
|
||||||
|
* This release has significant internal code changes. Please make sure all plugins are up-to-date.
|
||||||
|
|
||||||
|
2.35
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added Load Time and Load Reason columns for modules (Windows 8 and above)
|
||||||
|
* Added handle names for Job and Section objects
|
||||||
|
* Added Read/Write Memory for Section objects (in process Handles tab)
|
||||||
|
* Added CF Guard (Control Flow Guard) column for processes and modules
|
||||||
|
* Added highlighting for AppContainer DLLs
|
||||||
|
* Added AppContainer and CF Guard image characteristics to peview
|
||||||
|
* Added Open Key and Open File Location menu items for services
|
||||||
|
* Set priority and I/O priority for multiple processes at once
|
||||||
|
* Support for up to 64 processors when setting process/thread affinity
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added Disk and Network graphs for all processes
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Added ability to save I/O priority
|
||||||
|
* FIXED:
|
||||||
|
* Fixed memory editor copy bug
|
||||||
|
|
||||||
|
2.34
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Proper Unicode support
|
||||||
|
* CPU and GPU graphs are displayed in a grid now (thanks pavel_kv!)
|
||||||
|
* Start Task Manager now elevates when necessary
|
||||||
|
* Better names for memory regions in Memory tab (for PEBs, TEBs, thread stacks)
|
||||||
|
* Added tooltip information for user-mode driver framework (UMDF) host processes
|
||||||
|
* Added option to reduce row height (set ThinRows to 1 in settings.xml)
|
||||||
|
* Added NetAdapters plugin: adds graphs for selected network adapters to the System Information window
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added GPU graphs for all processes
|
||||||
|
* Can now use the search box in the Disk tab
|
||||||
|
* Improved kernel logger handling
|
||||||
|
* FIXED:
|
||||||
|
* Fixed touch scrolling
|
||||||
|
* Fixed EtwRegistration object names for 64-bit Windows 8.1
|
||||||
|
* Fixed tray icons being clipped in high DPI environments
|
||||||
|
* Fixed crash in memory editor
|
||||||
|
* Fixed multi monitor window placement bug
|
||||||
|
|
||||||
|
2.33
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* View digital signature information from process properties and peview
|
||||||
|
* Signatures for Windows 8 apps are now detected
|
||||||
|
* Improved file, key, process and thread handle properties
|
||||||
|
* Added DPI Awareness column
|
||||||
|
* Added new Windows 8.1 process protection information
|
||||||
|
* KProcessHacker is no longer needed for highlighting of GUI threads
|
||||||
|
* Added suspend count for threads on Windows 8.1
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Improved .NET assembly enumeration timeout handling
|
||||||
|
* FIXED:
|
||||||
|
* Service start type and error control are never updated if modified outside of Process Hacker
|
||||||
|
|
||||||
|
2.32
|
||||||
|
* NOTE:
|
||||||
|
* All executable files are now signed.
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated for Windows 8.1
|
||||||
|
* Added progress display for thread stacks
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Added new trigger data types
|
||||||
|
* Updated NetworkTools plugin:
|
||||||
|
* Updated UI
|
||||||
|
* Updated OnlineChecks plugin:
|
||||||
|
* Added file analyzed prompt
|
||||||
|
* FIXED:
|
||||||
|
* Fixed handling of long symbol names
|
||||||
|
* Fixed Run As preventing Windows 8 apps from starting
|
||||||
|
* Fixed console host information for Windows 8.1
|
||||||
|
* Fixed reflected processes not terminating on Windows 8.1
|
||||||
|
* Fixed CPU frequency on Windows 8.1
|
||||||
|
|
||||||
|
2.31
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Fixed some bugs relating to Windows 8
|
||||||
|
* Updated OnlineChecks plugin:
|
||||||
|
* Added upload progress
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Fixed bug where process priorities were not actually saved
|
||||||
|
* FIXED:
|
||||||
|
* Fixed module list not updating properly
|
||||||
|
* DLL enumeration crash
|
||||||
|
|
||||||
|
2.30
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added "Icon click toggles visibility" option
|
||||||
|
* Re-enabled powerful process termination on 32-bit Windows 8
|
||||||
|
* Updated UserNotes plugin:
|
||||||
|
* Added ability to save process priority
|
||||||
|
* Added "Only for processes with the same command line" option for process comments
|
||||||
|
* FIXED:
|
||||||
|
* Fixed crash on CPUs without SSE2
|
||||||
|
|
||||||
|
2.29
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added App ID column for processes
|
||||||
|
* Added new ASLR information for Windows 8
|
||||||
|
* Added Restart to Boot Options and Hybrid Shutdown menu items for Windows 8
|
||||||
|
* Added ability to specify processes by their names and inject and unload DLLs in command line
|
||||||
|
* Removed 512 character limit when copying text
|
||||||
|
* Moved Terminator to Miscellaneous menu
|
||||||
|
* Updated default dbghelp.dll path for Windows SDK v8
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Added new triggers for Windows 8
|
||||||
|
* Fixed bug when restarting services
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Improved support for multiple GPUs (again)
|
||||||
|
* GPU column now respects "Include CPU usage of children" option
|
||||||
|
* Updated ToolStatus plugin:
|
||||||
|
* Fixed search box fonts
|
||||||
|
* Fixed controls not being properly hidden/removed from the window when disabled
|
||||||
|
* Updated WindowExplorer plugin:
|
||||||
|
* Fixed window list not displaying Modern UI windows
|
||||||
|
* FIXED:
|
||||||
|
* Fixed Load Count column sorting bug
|
||||||
|
* Fixed signature verification on Windows 8
|
||||||
|
* Fixed task scheduler information on Windows 8
|
||||||
|
* Fixed drag bug in tree list
|
||||||
|
* Fixed KProcessHacker bug affecting TmTx objects
|
||||||
|
* Fixed Run As feature on Windows 8
|
||||||
|
* Fixed bug where -settings parameter is not propagated
|
||||||
|
* Fixed tab key behavior on main window
|
||||||
|
* Fixed recognition of Modern UI windows
|
||||||
|
|
||||||
|
2.28
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* peview now resolves .lnk targets
|
||||||
|
* Fixed Ctrl+A for processes, services and network connections and added Ctrl+A for other windows
|
||||||
|
* Changed confirmation prompts to select the destructive action by default
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Fixed inaccurate stack traces for certain .NET programs
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Fixed network graph scaling
|
||||||
|
* Updated ToolStatus plugin:
|
||||||
|
* Added search box
|
||||||
|
* Updated Updater plugin
|
||||||
|
* FIXED:
|
||||||
|
* Fixed Verification Status column sorting bug in module list
|
||||||
|
* Fixed rare System Information crash
|
||||||
|
* Fixed bug in opening process handles
|
||||||
|
* Fixed freezing when viewing stack traces of certain system threads
|
||||||
|
|
||||||
|
2.27
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated OnlineChecks plugin:
|
||||||
|
* 2012-01-16: Updated VirusTotal uploader and added hash checking
|
||||||
|
* FIXED:
|
||||||
|
* Fixed Description column sorting bug
|
||||||
|
* Fixed notification icon bug
|
||||||
|
|
||||||
|
2.26
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added option to show Commit Charge in system information summary view
|
||||||
|
* Added -priority and -selectpid command line options
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Improved support for multiple GPUs
|
||||||
|
* FIXED:
|
||||||
|
* Fixed 100% CPU when starting on some machines
|
||||||
|
|
||||||
|
2.25
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Improved CPU frequency calculation
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added GPU node selection
|
||||||
|
* Fixed incorrect GPU usage calculation
|
||||||
|
* FIXED:
|
||||||
|
* Graph tooltip position with large cursors
|
||||||
|
* Fixed .NET process detection
|
||||||
|
* Fixed incorrect values in Bits column
|
||||||
|
|
||||||
|
2.24
|
||||||
|
* NOTE:
|
||||||
|
* This release has significant internal code changes. Please make sure all plugins are up-to-date.
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Completely new system information window
|
||||||
|
* Added option to scroll to new processes
|
||||||
|
* Added option to hide driver services
|
||||||
|
* Added menu item to copy individual cells
|
||||||
|
* Improved module scanning
|
||||||
|
* Added Start Task Manager menu item
|
||||||
|
* Added Image base to peview
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added support for new system information window
|
||||||
|
* Added Disk, Network and GPU tray icons
|
||||||
|
* Added support for custom fonts in the Disk tab
|
||||||
|
* Updated Updater plugin:
|
||||||
|
* Added download speed
|
||||||
|
* Added remaining time
|
||||||
|
* FIXED:
|
||||||
|
* Fixed retrieval of version information for certain files
|
||||||
|
* Fixed driver file names on Windows XP
|
||||||
|
* Fixed Run As Administrator when used with complex commands
|
||||||
|
|
||||||
|
2.23
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added display of token capabilities, user/device claims and security attributes
|
||||||
|
* Added ability to change token integrity levels
|
||||||
|
* Added Description column to service list
|
||||||
|
* Added option to reset all settings
|
||||||
|
* Made grid color darker
|
||||||
|
* Enabled multi-selection in the hidden processes window
|
||||||
|
* Added UserNotes plugin
|
||||||
|
* Updated ExtendedNotifications plugin:
|
||||||
|
* Added Growl support
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added GPU monitoring
|
||||||
|
* Added rate columns for disk and network I/O
|
||||||
|
* FIXED:
|
||||||
|
* Fixed copying lists when plugin columns are enabled
|
||||||
|
* Freezing when viewing the tooltip for a process with a very long command line
|
||||||
|
* Disabled Hidden Processes feature on 64-bit systems
|
||||||
|
|
||||||
|
2.22
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added highlighting for metro style apps
|
||||||
|
* Added Package Name column
|
||||||
|
* Added package name to process tooltip
|
||||||
|
* Improved .NET process detection
|
||||||
|
* Updated OS Context column for Windows 8
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Updated disk monitoring for Windows 8
|
||||||
|
* Updated memory list information for Windows 8
|
||||||
|
* Updated WindowExplorer plugin:
|
||||||
|
* Fixed hook support for low integrity processes
|
||||||
|
* FIXED:
|
||||||
|
* Fixed memory leaks
|
||||||
|
* Fixed bug preventing Interrupts/DPCs from being shown as the max. CPU process on 64-bit systems
|
||||||
|
* Fixed DEP Status column on 64-bit systems
|
||||||
|
|
||||||
|
2.21
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added Private Bytes Delta, ASLR and Subsystem columns
|
||||||
|
* Added ASLR and Time Stamp columns to modules list
|
||||||
|
* Added check for debugger in Terminator
|
||||||
|
* FIXED:
|
||||||
|
* Fixed Show CPU Below 0.01 not respecting locale
|
||||||
|
* Fixed copying from network list
|
||||||
|
|
||||||
|
2.20
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added support for managed thread stacks on x64
|
||||||
|
* Added column selection for handle list
|
||||||
|
* Added CPU column to threads list
|
||||||
|
* Improved module detection
|
||||||
|
* Added Ideal Processor to Threads tab
|
||||||
|
* Added pool usage and minimum/maximum working set columns
|
||||||
|
* Implemented Properties button for Thread handles
|
||||||
|
* Set descending sort as the default for most numeric columns
|
||||||
|
* Extended header context menu
|
||||||
|
* Removed tooltip text truncation
|
||||||
|
* Improved cycle-based CPU usage calculation
|
||||||
|
* Set default KProcessHacker security level to only allow connections when Process Hacker is running as administrator.
|
||||||
|
See README.txt for instructions on how to restore the old behavior.
|
||||||
|
* Added Updater plugin
|
||||||
|
* Updated DotNetTools plugin:
|
||||||
|
* Added managed symbol resolution for thread stacks
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added Disk tab
|
||||||
|
* Added Hard Faults, Hard Faults Delta and Peak Threads columns to process tree list
|
||||||
|
* Added Firewall Status column
|
||||||
|
* FIXED:
|
||||||
|
* Fixed file name resolution bug
|
||||||
|
* Save settings on shutdown/logoff
|
||||||
|
* Fixed state highlighting bug
|
||||||
|
* Fixed command line propagation for -elevate
|
||||||
|
* Fixed tree list mouse wheel handling
|
||||||
|
* Fixed saving network list
|
||||||
|
|
||||||
|
2.19
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added cycle-based CPU usage for Windows 7
|
||||||
|
* Added Show CPU Below 0.01
|
||||||
|
* Added OS Context column
|
||||||
|
* Rewrote graph drawing code for improved performance
|
||||||
|
* Optimized retrieval of cycle time and private working set information for Windows 7
|
||||||
|
* Added Open File Location to process context menu and reorganized some items
|
||||||
|
* Added checkboxes to Terminator
|
||||||
|
* FIXED:
|
||||||
|
* Crash when sorting by Time Stamp
|
||||||
|
* GDI handle leak in drag selection
|
||||||
|
|
||||||
|
2.18
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Completely rewritten tree list control:
|
||||||
|
* Process Name column is now fixed to the left
|
||||||
|
* Tooltips for column headers
|
||||||
|
* Improved performance
|
||||||
|
* Bug fixes
|
||||||
|
* Added more process tree list columns
|
||||||
|
* Added Time stamp column to network list
|
||||||
|
* Date/time display is now swapped (so time is shown before date)
|
||||||
|
* Added W3 terminator test
|
||||||
|
* Added DotNetTools plugin
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Disabled editing of required privileges for drivers
|
||||||
|
* Updated ExtendedTools plugin:
|
||||||
|
* Added ETW columns for processes and network connections
|
||||||
|
* Updated OnlineChecks plugin:
|
||||||
|
* Added Comodo Instant Malware Analysis
|
||||||
|
* Updated WindowExplorer plugin:
|
||||||
|
* Fixed hook bugs
|
||||||
|
* FIXED:
|
||||||
|
* Fixed Run As This User
|
||||||
|
* Verification Status sorting
|
||||||
|
|
||||||
|
2.17
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added support for setting page priority
|
||||||
|
* Added elevation support for setting priority
|
||||||
|
* Added support for automatically using a settings file in the program directory (e.g. ProcessHacker.exe.settings.xml)
|
||||||
|
* Improved Run As mechanism
|
||||||
|
* Updated ExtendedServices plugin:
|
||||||
|
* Added support for editing triggers
|
||||||
|
* Added support for editing preshutdown time-out
|
||||||
|
* Added support for editing required privileges
|
||||||
|
* Added elevation support for restarting services
|
||||||
|
* Updated WindowExplorer plugin:
|
||||||
|
* Added more window properties
|
||||||
|
* FIXED:
|
||||||
|
* Handle leak
|
||||||
|
|
||||||
|
2.16
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated WindowExplorer plugin
|
||||||
|
* PE viewer: Added version string to CLR tab
|
||||||
|
* PE viewer: Added display of delay imports
|
||||||
|
* PE viewer: Added Load Config tab
|
||||||
|
* Improved wait analysis
|
||||||
|
* Added arrows to the service list to indicate whether a service is running
|
||||||
|
* FIXED:
|
||||||
|
* Fixed the IPv6-related workaround causing crashes
|
||||||
|
* Incorrect handling of window positions
|
||||||
|
|
||||||
|
2.15
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated ExtendedServices plugin
|
||||||
|
* Updated ToolStatus plugin
|
||||||
|
* Added DEP Status column
|
||||||
|
* Improved User Name column
|
||||||
|
* FIXED:
|
||||||
|
* Image file versions
|
||||||
|
* Workaround for an IPv6-related bug in Windows XP
|
||||||
|
* DPCs and Interrupts in System Information tooltips
|
||||||
|
* File dialog crash on Windows XP
|
||||||
|
* ExtendedTools plugin: WS Watch refresh bug
|
||||||
|
|
||||||
|
2.14
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* ExtendedServices plugin: Option to add a Services menu for processes
|
||||||
|
* Command line support for setting process priority and I/O priority
|
||||||
|
* Improved termination of explorer.exe
|
||||||
|
* FIXED:
|
||||||
|
* Icon should restore the main window if it is minimized
|
||||||
|
* System Information window crashes
|
||||||
|
* Hide Processes From Other Users and Hide Signed Processes settings are now saved
|
||||||
|
* Font selection on Windows XP
|
||||||
|
* ToolStatus plugin: Always on Top status being reset by Find Window
|
||||||
|
* Service-related crashes
|
||||||
|
* WindowExplorer plugin: sorting in tree list
|
||||||
|
* Process minidump creation with old versions of dbghelp.dll
|
||||||
|
|
||||||
|
2.13
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added copy support to PE viewer
|
||||||
|
* Added Connect Time, Disconnect Time and Last Input Time to session properties
|
||||||
|
* Added more working set counters to the Statistics tab
|
||||||
|
* FIXED:
|
||||||
|
* Column sort arrows
|
||||||
|
* CPU usage calculations
|
||||||
|
|
||||||
|
2.12
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Updated KProcessHacker for Windows 7 SP1
|
||||||
|
* Added elevation support for more actions
|
||||||
|
* Added ability to disable plugins
|
||||||
|
* Updated ToolStatus plugin
|
||||||
|
* Added Remote Control for sessions
|
||||||
|
* More command line options
|
||||||
|
* FIXED:
|
||||||
|
* Memory leaks
|
||||||
|
* Run As issues with different sessions
|
||||||
|
|
||||||
|
2.11
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added WS Watch and other features to ExtendedTools plugin
|
||||||
|
* Added WindowExplorer plugin
|
||||||
|
* Properties for hidden processes
|
||||||
|
* Improved menus
|
||||||
|
* Debug console can now be closed without affecting the entire program
|
||||||
|
* FIXED:
|
||||||
|
* Always on Top issues
|
||||||
|
* Hang when setting DEP status of a terminating process
|
||||||
|
* Encoding bug in NetworkTools plugin
|
||||||
|
* LSA interfacing issues
|
||||||
|
* Creating dumps of self
|
||||||
|
|
||||||
|
2.10
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* KProcessHacker is now signed, so it works on 64-bit systems. Thank you to the ReactOS Foundation.
|
||||||
|
* Added Run As Limited User
|
||||||
|
* Added CPU, private bytes and I/O history columns
|
||||||
|
* Added font selection
|
||||||
|
* Slightly improved highlighting configuration
|
||||||
|
* FIXED:
|
||||||
|
* High DPI support
|
||||||
|
* Multi-monitor support in graph tooltips
|
||||||
|
* DEP status retrieval
|
||||||
|
* ExtendedTools plugin crash
|
||||||
|
* Notification icon menu crash
|
||||||
|
* Memory leaks
|
||||||
|
* Other small bug fixes
|
||||||
|
|
||||||
|
2.9
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Added column selection for modules list
|
||||||
|
* Added wait analysis for 64-bit systems
|
||||||
|
* Added signature verification for modules
|
||||||
|
* Added ExtendedTools plugin (Vista and above only) with Disk and Network information
|
||||||
|
* Updated ExtendedNotifications plugin: added ability to log events to a file
|
||||||
|
* Updated ExtendedServices plugin: new tab on Vista and above
|
||||||
|
* Updated ToolStatus plugin: resolves ghost windows to hung windows
|
||||||
|
* Environment variables and current directory are now correctly shown for WOW64 processes
|
||||||
|
* I/O priority names are now used instead of numbers
|
||||||
|
* FIXED:
|
||||||
|
* Network list bug
|
||||||
|
* Memory leaks
|
||||||
|
|
||||||
|
2.8
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Better service list (including column selection)
|
||||||
|
* Added Peak Handles
|
||||||
|
* Process tree sorting is now preserved
|
||||||
|
* Save works for services and network connections
|
||||||
|
* Pausing now works correctly with the Network tab
|
||||||
|
* Added option to display inclusive CPU usages for collapsed processes
|
||||||
|
* Added CLR tab to peview
|
||||||
|
* Added ability to destroy heaps
|
||||||
|
* Improved process tree list appearance
|
||||||
|
* Certain command line parameters are now propagated
|
||||||
|
* FIXED:
|
||||||
|
* Icon handling bugs
|
||||||
|
* Memory leaks
|
||||||
|
* Extended tooltips for WOW64 processes
|
||||||
|
|
||||||
|
2.7
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Vastly improved startup time and lower memory usage
|
||||||
|
* Added Cycles and Cycles Delta columns
|
||||||
|
* Added option to disable address resolution for network connections
|
||||||
|
* Added Logon Time to session properties
|
||||||
|
* Added time stamp display to peview
|
||||||
|
* FIXED:
|
||||||
|
* ToolStatus layout problems
|
||||||
|
* .NET highlighting crashes
|
||||||
|
* Run As on Windows XP
|
||||||
|
|
||||||
|
2.6
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Sorting for most lists is now much faster
|
||||||
|
* Hide Signed Processes option
|
||||||
|
* Added plugin for uploading files to online virus scanners
|
||||||
|
* Added Network tools plugin
|
||||||
|
* Updated ExtendedServices plugin
|
||||||
|
* PE viewer now verifies checksums
|
||||||
|
* Performance improvements
|
||||||
|
* FIXED:
|
||||||
|
* Fixed service handle leak
|
||||||
|
|
||||||
|
2.5
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Unmap section views in Memory tab
|
||||||
|
* Plugin for extended service information (including recovery information, dependencies and dependents)
|
||||||
|
* FIXED:
|
||||||
|
* Critical bug for file dialogs on Windows XP
|
||||||
|
* Esc couldn't close Service Properties on open
|
||||||
|
* Small bug fixes
|
||||||
|
|
||||||
|
2.4
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Better Run As behaviour
|
||||||
|
* Show Processes From All Users option
|
||||||
|
* Can now unmap section views
|
||||||
|
* Control over thread affinity
|
||||||
|
* Window Title and Window Status columns
|
||||||
|
* Plugin for filtering notifications
|
||||||
|
* Plugin for toolbar and status bar
|
||||||
|
* Performance improvements
|
||||||
|
* FIXED:
|
||||||
|
* Memory leak
|
||||||
|
* SbieSupport plugin on 64-bit
|
||||||
|
* Crash when running under certain conditions
|
||||||
|
* Memory case-insensitive filter
|
||||||
|
* Process parent association bug
|
||||||
|
* REMOVED:
|
||||||
|
* Process database
|
||||||
|
|
||||||
|
2.3
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Can add processes to jobs
|
||||||
|
* Double-clicking in the system information graphs now opens information for the relevant process
|
||||||
|
* Setting I/O priority doesn't need KProcessHacker anymore
|
||||||
|
* Elevation for certain actions
|
||||||
|
* FIXED:
|
||||||
|
* HKCU key name resolution
|
||||||
|
* Network connection host resolution
|
||||||
|
* Information window resizing
|
||||||
|
* Log clearing
|
||||||
|
|
||||||
|
2.2
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Plugins support
|
||||||
|
* Can now unload 32-bit modules on 64-bit systems
|
||||||
|
* Tasks are shown in tooltips for taskeng.exe/taskhost.exe processes
|
||||||
|
* Run As can now start processes elevated
|
||||||
|
* Handle count by type
|
||||||
|
* Process priorities in notification icon menu
|
||||||
|
* CSV export
|
||||||
|
* Relative start times
|
||||||
|
* FIXED:
|
||||||
|
* Run and Run As shortcuts
|
||||||
|
* Command line handling
|
||||||
|
* Process tree selection
|
||||||
|
|
||||||
|
2.1
|
||||||
|
* NEW/IMPROVED:
|
||||||
|
* Add Pause key shortcut to pause/resume updates
|
||||||
|
* Added Ctrl+Tab and Ctrl+Shift+Tab shortcuts
|
||||||
|
* Grid is a bit darker
|
||||||
|
* Checks for digital signatures and packing is now off by default and optional
|
||||||
|
* FIXED:
|
||||||
|
* MD5 calculation code for files was wrong
|
||||||
|
* Process record bugs
|
||||||
|
|
||||||
|
2.0
|
||||||
|
* First release in the Process Hacker 2.x branch.
|
132
COPYRIGHT.txt
Normal file
132
COPYRIGHT.txt
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
== Process Hacker ==
|
||||||
|
Process Hacker is licensed under the GNU GPL v3, with exceptions. A full
|
||||||
|
copy of the license is provided in LICENSE.txt.
|
||||||
|
|
||||||
|
Copyright (C) 2009-2016 wj32 and various authors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
== Mini-XML ==
|
||||||
|
Process Hacker uses Mini-XML licensed under the following terms:
|
||||||
|
|
||||||
|
The Mini-XML library and included programs are provided under the
|
||||||
|
terms of the GNU Library General Public License (LGPL) with the
|
||||||
|
following exceptions:
|
||||||
|
|
||||||
|
1. Static linking of applications to the Mini-XML library
|
||||||
|
does not constitute a derivative work and does not require
|
||||||
|
the author to provide source code for the application, use
|
||||||
|
the shared Mini-XML libraries, or link their applications
|
||||||
|
against a user-supplied version of Mini-XML.
|
||||||
|
|
||||||
|
If you link the application to a modified version of
|
||||||
|
Mini-XML, then the changes to Mini-XML must be provided
|
||||||
|
under the terms of the LGPL in sections 1, 2, and 4.
|
||||||
|
|
||||||
|
2. You do not have to provide a copy of the Mini-XML license
|
||||||
|
with programs that are linked to the Mini-XML library, nor
|
||||||
|
do you have to identify the Mini-XML license in your
|
||||||
|
program or documentation as required by section 6 of the
|
||||||
|
LGPL.
|
||||||
|
|
||||||
|
== PCRE ==
|
||||||
|
Process Hacker uses Perl-Compatible Regular Expressions licensed under the
|
||||||
|
following terms:
|
||||||
|
|
||||||
|
PCRE is a library of functions to support regular expressions whose syntax
|
||||||
|
and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
|
Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
|
||||||
|
specified below.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the University of Cambridge nor the name of Google
|
||||||
|
Inc. nor the names of their contributors may be used to endorse or
|
||||||
|
promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
== MD5 ==
|
||||||
|
Process Hacker uses a MD5 implementation licensed under the following terms:
|
||||||
|
|
||||||
|
MD5 hash implementation and interface functions
|
||||||
|
Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License version 2 as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
== SHA ==
|
||||||
|
Process Hacker uses a SHA implementation licensed under the following terms:
|
||||||
|
|
||||||
|
Copyright 2004 Filip Navara
|
||||||
|
Based on public domain SHA code by Steve Reid <steve@edmweb.com>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
== Natural order string comparison ==
|
||||||
|
Process Hacker uses "strnatcmp.c" licensed under the following terms:
|
||||||
|
|
||||||
|
strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
|
||||||
|
Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
This code has been modified for Process Hacker.
|
205
HACKING.md
Normal file
205
HACKING.md
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
## Building
|
||||||
|
Process Hacker must be built using a Microsoft C compiler. Do not attempt to use any other compiler or be prepared to spend a long time trying to fix things. The only tested IDE is Visual Studio 2015.
|
||||||
|
|
||||||
|
The Windows SDK 10 must be installed. To create a XP-compatible driver, KProcessHacker must be built using WDK v7, not the latest WDK.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
### Names
|
||||||
|
* Functions, function parameters, and global variables use CamelCase.
|
||||||
|
* Local variables use lowerCamelCase.
|
||||||
|
* Structs, enums and unions use CAPS_WITH_UNDERSCORES.
|
||||||
|
|
||||||
|
All names must have an appropriate prefix (with some exceptions):
|
||||||
|
|
||||||
|
* "Ph" or "PH_" (structures) for public names.
|
||||||
|
* "Php" or "PHP_" for private names.
|
||||||
|
* Some variants such as "Pha".
|
||||||
|
* Private prefixes are created by appending "p" to the prefix. E.g. "Ph" -> "Php", "Pha" -> "Phap".
|
||||||
|
* Functions and global variables without a prefix must be declared "static".
|
||||||
|
* "static" names must not have a public prefix.
|
||||||
|
* Names with a private prefix do not have to be "static".
|
||||||
|
* Structures without a prefix must be declared in a ".c" file. Structures declared in a ".c" file may or may not have a prefix.
|
||||||
|
|
||||||
|
### Types
|
||||||
|
Unless used for the Win32 API, the standard types are:
|
||||||
|
|
||||||
|
* `BOOLEAN` for a 1 byte boolean, or `LOGICAL` for a 4 byte boolean.
|
||||||
|
* `UCHAR` for 1 byte.
|
||||||
|
* `SHORT`/`USHORT` for 2 bytes.
|
||||||
|
* `LONG`/`ULONG` for 4 bytes.
|
||||||
|
* `LONG64`/`ULONG64` for 8 bytes.
|
||||||
|
* `CHAR` for a 1 byte character.
|
||||||
|
* `WCHAR` for a 2 byte character.
|
||||||
|
* `PSTR` for a string of 1 byte characters.
|
||||||
|
* `PWSTR` for a string of 2 byte characters.
|
||||||
|
|
||||||
|
#### Booleans
|
||||||
|
Always use:
|
||||||
|
|
||||||
|
```
|
||||||
|
if (booleanVariable) // not "if (booleanVariable == TRUE)"
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
to test a boolean value.
|
||||||
|
|
||||||
|
### Annotations, qualifiers
|
||||||
|
* All functions use SAL annotations, such as `_In_`, `_Inout_`, `_Out_`, etc.
|
||||||
|
* Do not use `const`, unless obvious optimizations can be made by the compiler (e.g. inlining).
|
||||||
|
* Do not use `volatile` in definitions. Instead, cast to a volatile pointer when necessary.
|
||||||
|
|
||||||
|
### Function success indicators
|
||||||
|
There are three main types of indicators used:
|
||||||
|
|
||||||
|
* A `NTSTATUS` value is returned. The `NT_SUCCESS` macro checks if a status value indicates success.
|
||||||
|
* A `BOOLEAN` value is returned. `TRUE` indicates success.
|
||||||
|
* The result of the function is returned (e.g. a pointer). A special value (e.g. `NULL`) indicates failure.
|
||||||
|
|
||||||
|
Unless indicated, a function which fails is guaranteed not to modify any of its output parameters (`_Out_`, `_Out_opt_`, etc.).
|
||||||
|
|
||||||
|
For functions which are passed a callback function, it is not guaranteed that a failed function has not executed the callback function.
|
||||||
|
|
||||||
|
### Threads
|
||||||
|
Every thread start routine must have the following signature:
|
||||||
|
|
||||||
|
```
|
||||||
|
NTSTATUS NameOfRoutine(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Thread creation is done through the `PhCreateThread` function.
|
||||||
|
|
||||||
|
### Collections
|
||||||
|
The collections available are summarized below:
|
||||||
|
|
||||||
|
Name | Use | Type
|
||||||
|
--------------------- | ----------------------- | ---------------
|
||||||
|
`PH_ARRAY` | Array | Non-intrusive
|
||||||
|
`PH_LIST` | Array | Non-intrusive
|
||||||
|
`LIST_ENTRY` | Doubly linked list | Intrusive
|
||||||
|
`SINGLE_LIST_ENTRY` | Singly linked list | Intrusive
|
||||||
|
`PH_POINTER_LIST` | Array | Non-intrusive
|
||||||
|
`LIST_ENTRY` | Stack | Intrusive
|
||||||
|
`SINGLE_LIST_ENTRY` | Stack | Intrusive
|
||||||
|
`LIST_ENTRY` | Queue | Intrusive
|
||||||
|
`RTL_AVL_TABLE` | Binary tree (AVL) | Non-intrusive
|
||||||
|
`PH_AVL_LINKS` | Binary tree (AVL) | Intrusive
|
||||||
|
`RTL_GENERIC_TABLE` | Binary tree (splay) | Non-intrusive
|
||||||
|
`PH_HASHTABLE` | Hashtable | Non-intrusive
|
||||||
|
`PH_HASH_ENTRY` | Hashtable | Intrusive
|
||||||
|
`PH_CIRCULAR_BUFFER` | Circular buffer | Non-intrusive
|
||||||
|
|
||||||
|
### Synchronization
|
||||||
|
The queued lock should be used for all synchronization, due to its small size and good performance. Although the queued lock is a reader-writer lock, it can be used as a mutex simply by using the exclusive acquire/release functions.
|
||||||
|
|
||||||
|
Events can be used through `PH_EVENT`. This object does not create a kernel event object until needed, and testing its state is very fast.
|
||||||
|
|
||||||
|
Rundown protection is available through `PH_RUNDOWN_PROTECT`.
|
||||||
|
|
||||||
|
Condition variables are available using the queued lock. Simply declare and initialize a queued lock variable, and use the `PhPulse(All)Condition` and `PhWaitForCondition` functions.
|
||||||
|
|
||||||
|
Custom locking with low overhead can be built using the wake event, built on the queued lock. Test one or more conditions in a loop and use `PhQueueWakeEvent`/`PhWaitForWakeEvent` to block. When a condition is modified use `PhSetWakeEvent` to wake waiters. If after calling `PhQueueWakeEvent` it is determined that no blocking should occur, use `PhSetWakeEvent`.
|
||||||
|
|
||||||
|
### Exceptions (SEH)
|
||||||
|
The only method of error handling used in Process Hacker is the return value (`NTSTATUS`, `BOOLEAN`, etc.). Exceptions are used for exceptional situations which cannot easily be recovered from (e.g. a lock acquire function fails to block, or an object has a negative reference count.
|
||||||
|
|
||||||
|
Exceptions to this rule include:
|
||||||
|
|
||||||
|
* `PhAllocate`, which raises an exception if it fails to allocate. Checking the return value of each allocation to increase reliability is not worth the extra effort involved, as failed allocations are very rare.
|
||||||
|
* `PhProbeAddress`, which raises an exception if an address lies outside of a specified range. Raising an exception makes it possible to conduct multiple checks in one SEH block.
|
||||||
|
* `STATUS_NOT_IMPLEMENTED` exceptions triggered by code paths which should not be reached, purely due to programmer error. `assert(FALSE)` could also be used in this case.
|
||||||
|
|
||||||
|
### Memory management
|
||||||
|
Use `PhAllocate`/`PhFree` to allocate/free memory. For complex objects, use the reference counting system.
|
||||||
|
|
||||||
|
There is semi-automatic reference counting available in the form of auto-dereference pools (similar to Apple's `NSAutoreleasePool`s). Use the `PhAutoDereferenceObject` to add an object to the thread's pool, and the object will be dereferenced at an unspecified time in the future. However, the object is guaranteed to not be dereferenced while the current function is executing.
|
||||||
|
|
||||||
|
Referencing an object is necessary whenever a pointer to the object is stored in a globally visible location or passed to another thread. In most other cases, referencing is not necessary.
|
||||||
|
|
||||||
|
All objects passed to functions must have a guaranteed reference for the duration of that call. One mistake is to keep a reference which could be destroyed in a window procedure, and to use that reference implicitly inside the window procedure. Messages can still be pumped (e.g. dialog boxes) while the window procedure is executing, so the window procedure must reference the object as soon as possible.
|
||||||
|
|
||||||
|
### Names (2)
|
||||||
|
|
||||||
|
#### Object creation/deletion
|
||||||
|
* Allocate means allocate memory without initialization.
|
||||||
|
* Create means allocate memory for an object and initialize the object.
|
||||||
|
* Free can be used for objects created with Allocate or Create functions.
|
||||||
|
* Destroy can also be used for objects created with Create functions.
|
||||||
|
* Initialize means initialize an object with caller-supplied storage.
|
||||||
|
* Delete is paired with Initialize and does not free the object as it was allocated by the caller.
|
||||||
|
* Create is used when objects are being created through the reference counting system.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
* `PhAllocateFromFreeList`/`PhFreeToFreeList`
|
||||||
|
* `PhCreateFileDialog`/`PhFreeFileDialog`
|
||||||
|
* `PhInitializeWorkQueue`/`PhDeleteWorkQueue`
|
||||||
|
* `PhCreateString`/`PhDereferenceObject`
|
||||||
|
|
||||||
|
#### Element counts
|
||||||
|
* Length specifies the length in bytes. E.g. `PhCreateString` requires the length to be specified in bytes.
|
||||||
|
* Count specifies the length in elements. E.g. `PhSubstring` requires the length to be specified in characters.
|
||||||
|
* Index specifies the index in elements. E.g. `PhSubstring` requires the index to be specified in characters.
|
||||||
|
|
||||||
|
When null terminated strings are being written to output, the return count, if any, must be specified as the number of characters written including the null terminator.
|
||||||
|
|
||||||
|
### Strings
|
||||||
|
Strings use the `PH_STRING` type, managed by reference counting. To create a string object from a null-terminated string:
|
||||||
|
|
||||||
|
```
|
||||||
|
PPH_STRING myString = PhCreateString(L"My string");
|
||||||
|
|
||||||
|
wprintf(
|
||||||
|
L"My string is \"%s\", and uses %Iu bytes.\n",
|
||||||
|
myString->Buffer,
|
||||||
|
myString->Length
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
All string objects have an embedded length (always in bytes), and the string is additionally null-terminated for compatibility reasons.
|
||||||
|
|
||||||
|
String objects must be treated as immutable unless a string object is created and modified before the pointer is shared with any other functions or stored in any global variables. This exception applies only when creating a string using `PhCreateString` or `PhCreateStringEx`.
|
||||||
|
|
||||||
|
Strings can be concatenated with `PhConcatStrings`:
|
||||||
|
|
||||||
|
```
|
||||||
|
PPH_STRING newString;
|
||||||
|
|
||||||
|
newString = PhConcatStrings(
|
||||||
|
4,
|
||||||
|
L"My first string, ",
|
||||||
|
L"My second string, ",
|
||||||
|
aStringFromSomewhere,
|
||||||
|
L"My fourth string."
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Another version concatenates two strings:
|
||||||
|
|
||||||
|
```
|
||||||
|
PPH_STRING newString;
|
||||||
|
|
||||||
|
newString = PhConcatStrings2(
|
||||||
|
L"My first string, ",
|
||||||
|
L"My second string."
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Strings can be formatted:
|
||||||
|
|
||||||
|
```
|
||||||
|
PPH_STRING newString;
|
||||||
|
|
||||||
|
newString = PhFormatString(
|
||||||
|
L"%d: %s, %#x",
|
||||||
|
100,
|
||||||
|
L"test",
|
||||||
|
0xff
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tips
|
||||||
|
* Use !! to "cast" to a boolean.
|
139
KProcessHacker/KProcessHacker.vcxproj
Normal file
139
KProcessHacker/KProcessHacker.vcxproj
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Win8 Debug|Win32">
|
||||||
|
<Configuration>Win8 Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Win8 Release|Win32">
|
||||||
|
<Configuration>Win8 Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Win8 Debug|x64">
|
||||||
|
<Configuration>Win8 Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Win8 Release|x64">
|
||||||
|
<Configuration>Win8 Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{F4853009-C5D2-4A25-BE4D-BB0D9F84E2FF}</ProjectGuid>
|
||||||
|
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||||
|
<Configuration>Win8 Debug</Configuration>
|
||||||
|
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<RootNamespace>KProcessHacker</RootNamespace>
|
||||||
|
<VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VisualStudioVersion)' == '11.0'">$(VCTargetsPath11)</VCTargetsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="PropertySheets">
|
||||||
|
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
|
||||||
|
<ConfigurationType>Driver</ConfigurationType>
|
||||||
|
<DriverType>WDM</DriverType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|Win32'" Label="Configuration">
|
||||||
|
<TargetVersion>Windows8</TargetVersion>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'" Label="Configuration">
|
||||||
|
<TargetVersion>Windows8</TargetVersion>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|x64'" Label="Configuration">
|
||||||
|
<TargetVersion>Windows8</TargetVersion>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|x64'" Label="Configuration">
|
||||||
|
<TargetVersion>Windows8</TargetVersion>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)bin\$(Configuration) $(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)obj\$(Configuration) $(PlatformArchitecture)\</IntDir>
|
||||||
|
<TargetName>kprocesshacker</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)bin\$(Configuration) $(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)obj\$(Configuration) $(PlatformArchitecture)\</IntDir>
|
||||||
|
<TargetName>kprocesshacker</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|x64'">
|
||||||
|
<OutDir>$(ProjectDir)bin\$(Configuration) $(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)obj\$(Configuration) $(PlatformArchitecture)\</IntDir>
|
||||||
|
<TargetName>kprocesshacker</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|x64'">
|
||||||
|
<OutDir>$(ProjectDir)bin\$(Configuration) $(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)obj\$(Configuration) $(PlatformArchitecture)\</IntDir>
|
||||||
|
<TargetName>kprocesshacker</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>../phnt/include;../phlib/include;include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>KPH_CONFIG_CLEAN;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>../phnt/include;../phlib/include;include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>KPH_CONFIG_CLEAN;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>../phnt/include;../phlib/include;include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>KPH_CONFIG_CLEAN;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win8 Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>../phnt/include;../phlib/include;include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>KPH_CONFIG_CLEAN;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<FilesToPackage Include="$(TargetPath)" />
|
||||||
|
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="devctrl.c" />
|
||||||
|
<ClCompile Include="dyndata.c" />
|
||||||
|
<ClCompile Include="dynimp.c" />
|
||||||
|
<ClCompile Include="main.c" />
|
||||||
|
<ClCompile Include="object.c" />
|
||||||
|
<ClCompile Include="process.c" />
|
||||||
|
<ClCompile Include="qrydrv.c" />
|
||||||
|
<ClCompile Include="thread.c" />
|
||||||
|
<ClCompile Include="vm.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="resource.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\dyndata.h" />
|
||||||
|
<ClInclude Include="include\kph.h" />
|
||||||
|
<ClInclude Include="include\ntfill.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
66
KProcessHacker/KProcessHacker.vcxproj.filters
Normal file
66
KProcessHacker/KProcessHacker.vcxproj.filters
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Driver Files">
|
||||||
|
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||||
|
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="devctrl.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="dyndata.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="dynimp.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="object.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="process.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="qrydrv.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="thread.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="vm.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="resource.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\dyndata.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\kph.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ntfill.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
BIN
KProcessHacker/bin-signed/amd64/kprocesshacker.sys
Normal file
BIN
KProcessHacker/bin-signed/amd64/kprocesshacker.sys
Normal file
Binary file not shown.
BIN
KProcessHacker/bin-signed/i386/kprocesshacker.sys
Normal file
BIN
KProcessHacker/bin-signed/i386/kprocesshacker.sys
Normal file
Binary file not shown.
1
KProcessHacker/clean/makefile
Normal file
1
KProcessHacker/clean/makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
!INCLUDE $(NTMAKEENV)\makefile.def
|
7
KProcessHacker/clean/sources
Normal file
7
KProcessHacker/clean/sources
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
!IF 0
|
||||||
|
|
||||||
|
This builds a clean version of KProcessHacker suitable for driver signing.
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!include ..\sources.inc
|
566
KProcessHacker/devctrl.c
Normal file
566
KProcessHacker/devctrl.c
Normal file
@ -0,0 +1,566 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
|
||||||
|
NTSTATUS KphDispatchDeviceControl(
|
||||||
|
__in PDEVICE_OBJECT DeviceObject,
|
||||||
|
__in PIRP Irp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PIO_STACK_LOCATION stackLocation;
|
||||||
|
PFILE_OBJECT fileObject;
|
||||||
|
PKPH_CLIENT client;
|
||||||
|
PVOID originalInput;
|
||||||
|
ULONG inputLength;
|
||||||
|
ULONG ioControlCode;
|
||||||
|
KPROCESSOR_MODE accessMode;
|
||||||
|
UCHAR capturedInput[16 * sizeof(ULONG_PTR)];
|
||||||
|
PVOID capturedInputPointer;
|
||||||
|
|
||||||
|
#define VERIFY_INPUT_LENGTH \
|
||||||
|
do { \
|
||||||
|
/* Ensure at compile time that our local buffer fits this particular call. */ \
|
||||||
|
C_ASSERT(sizeof(*input) <= sizeof(capturedInput)); \
|
||||||
|
\
|
||||||
|
if (inputLength != sizeof(*input)) \
|
||||||
|
{ \
|
||||||
|
status = STATUS_INFO_LENGTH_MISMATCH; \
|
||||||
|
goto ControlEnd; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
stackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
fileObject = stackLocation->FileObject;
|
||||||
|
client = fileObject->FsContext;
|
||||||
|
|
||||||
|
originalInput = stackLocation->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
inputLength = stackLocation->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
ioControlCode = stackLocation->Parameters.DeviceIoControl.IoControlCode;
|
||||||
|
accessMode = Irp->RequestorMode;
|
||||||
|
|
||||||
|
// Make sure we have a client object.
|
||||||
|
if (!client)
|
||||||
|
{
|
||||||
|
status = STATUS_INTERNAL_ERROR;
|
||||||
|
goto ControlEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce signature requirement if necessary.
|
||||||
|
if ((ioControlCode != KPH_GETFEATURES && ioControlCode != KPH_VERIFYCLIENT) &&
|
||||||
|
(KphParameters.SecurityLevel == KphSecuritySignatureCheck ||
|
||||||
|
KphParameters.SecurityLevel == KphSecuritySignatureAndPrivilegeCheck) &&
|
||||||
|
!client->VerificationSucceeded)
|
||||||
|
{
|
||||||
|
status = STATUS_ACCESS_DENIED;
|
||||||
|
goto ControlEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we actually have input if the input length is non-zero.
|
||||||
|
if (inputLength != 0 && !originalInput)
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_BUFFER_SIZE;
|
||||||
|
goto ControlEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the caller isn't giving us a huge buffer. If they are, it can't be correct because
|
||||||
|
// we have a compile-time check that makes sure our buffer can store the arguments for all the
|
||||||
|
// calls.
|
||||||
|
if (inputLength > sizeof(capturedInput))
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_BUFFER_SIZE;
|
||||||
|
goto ControlEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probe and capture the input buffer.
|
||||||
|
if (accessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForRead(originalInput, inputLength, sizeof(UCHAR));
|
||||||
|
memcpy(capturedInput, originalInput, inputLength);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
goto ControlEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(capturedInput, originalInput, inputLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
capturedInputPointer = capturedInput; // avoid casting below
|
||||||
|
|
||||||
|
switch (ioControlCode)
|
||||||
|
{
|
||||||
|
case KPH_GETFEATURES:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PULONG Features;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiGetFeatures(
|
||||||
|
input->Features,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_VERIFYCLIENT:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PVOID CodeAddress;
|
||||||
|
PVOID Signature;
|
||||||
|
ULONG SignatureSize;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
if (accessMode == UserMode)
|
||||||
|
{
|
||||||
|
status = KpiVerifyClient(
|
||||||
|
input->CodeAddress,
|
||||||
|
input->Signature,
|
||||||
|
input->SignatureSize,
|
||||||
|
client
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_RETRIEVEKEY:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
KPH_KEY_LEVEL KeyLevel;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
if (accessMode == UserMode)
|
||||||
|
{
|
||||||
|
status = KphRetrieveKeyViaApc(
|
||||||
|
client,
|
||||||
|
input->KeyLevel,
|
||||||
|
Irp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENPROCESS:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PHANDLE ProcessHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
PCLIENT_ID ClientId;
|
||||||
|
KPH_KEY Key;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenProcess(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->ClientId,
|
||||||
|
input->Key,
|
||||||
|
client,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENPROCESSTOKEN:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
PHANDLE TokenHandle;
|
||||||
|
KPH_KEY Key;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenProcessToken(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->TokenHandle,
|
||||||
|
input->Key,
|
||||||
|
client,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENPROCESSJOB:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
PHANDLE JobHandle;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenProcessJob(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->JobHandle,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_TERMINATEPROCESS:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
NTSTATUS ExitStatus;
|
||||||
|
KPH_KEY Key;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiTerminateProcess(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->ExitStatus,
|
||||||
|
input->Key,
|
||||||
|
client,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_READVIRTUALMEMORYUNSAFE:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
PVOID Buffer;
|
||||||
|
SIZE_T BufferSize;
|
||||||
|
PSIZE_T NumberOfBytesRead;
|
||||||
|
KPH_KEY Key;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiReadVirtualMemoryUnsafe(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->BaseAddress,
|
||||||
|
input->Buffer,
|
||||||
|
input->BufferSize,
|
||||||
|
input->NumberOfBytesRead,
|
||||||
|
input->Key,
|
||||||
|
client,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_QUERYINFORMATIONPROCESS:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass;
|
||||||
|
PVOID ProcessInformation;
|
||||||
|
ULONG ProcessInformationLength;
|
||||||
|
PULONG ReturnLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiQueryInformationProcess(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->ProcessInformationClass,
|
||||||
|
input->ProcessInformation,
|
||||||
|
input->ProcessInformationLength,
|
||||||
|
input->ReturnLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_SETINFORMATIONPROCESS:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass;
|
||||||
|
PVOID ProcessInformation;
|
||||||
|
ULONG ProcessInformationLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiSetInformationProcess(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->ProcessInformationClass,
|
||||||
|
input->ProcessInformation,
|
||||||
|
input->ProcessInformationLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENTHREAD:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PHANDLE ThreadHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
PCLIENT_ID ClientId;
|
||||||
|
KPH_KEY Key;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenThread(
|
||||||
|
input->ThreadHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->ClientId,
|
||||||
|
input->Key,
|
||||||
|
client,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENTHREADPROCESS:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
PHANDLE ProcessHandle;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenThreadProcess(
|
||||||
|
input->ThreadHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->ProcessHandle,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_CAPTURESTACKBACKTRACETHREAD:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
ULONG FramesToSkip;
|
||||||
|
ULONG FramesToCapture;
|
||||||
|
PVOID *BackTrace;
|
||||||
|
PULONG CapturedFrames;
|
||||||
|
PULONG BackTraceHash;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiCaptureStackBackTraceThread(
|
||||||
|
input->ThreadHandle,
|
||||||
|
input->FramesToSkip,
|
||||||
|
input->FramesToCapture,
|
||||||
|
input->BackTrace,
|
||||||
|
input->CapturedFrames,
|
||||||
|
input->BackTraceHash,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_QUERYINFORMATIONTHREAD:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
KPH_THREAD_INFORMATION_CLASS ThreadInformationClass;
|
||||||
|
PVOID ThreadInformation;
|
||||||
|
ULONG ThreadInformationLength;
|
||||||
|
PULONG ReturnLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiQueryInformationThread(
|
||||||
|
input->ThreadHandle,
|
||||||
|
input->ThreadInformationClass,
|
||||||
|
input->ThreadInformation,
|
||||||
|
input->ThreadInformationLength,
|
||||||
|
input->ReturnLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_SETINFORMATIONTHREAD:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
KPH_THREAD_INFORMATION_CLASS ThreadInformationClass;
|
||||||
|
PVOID ThreadInformation;
|
||||||
|
ULONG ThreadInformationLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiSetInformationThread(
|
||||||
|
input->ThreadHandle,
|
||||||
|
input->ThreadInformationClass,
|
||||||
|
input->ThreadInformation,
|
||||||
|
input->ThreadInformationLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_ENUMERATEPROCESSHANDLES:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG BufferLength;
|
||||||
|
PULONG ReturnLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiEnumerateProcessHandles(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->Buffer,
|
||||||
|
input->BufferLength,
|
||||||
|
input->ReturnLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_QUERYINFORMATIONOBJECT:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
HANDLE Handle;
|
||||||
|
KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass;
|
||||||
|
PVOID ObjectInformation;
|
||||||
|
ULONG ObjectInformationLength;
|
||||||
|
PULONG ReturnLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiQueryInformationObject(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->Handle,
|
||||||
|
input->ObjectInformationClass,
|
||||||
|
input->ObjectInformation,
|
||||||
|
input->ObjectInformationLength,
|
||||||
|
input->ReturnLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_SETINFORMATIONOBJECT:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
HANDLE Handle;
|
||||||
|
KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass;
|
||||||
|
PVOID ObjectInformation;
|
||||||
|
ULONG ObjectInformationLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiSetInformationObject(
|
||||||
|
input->ProcessHandle,
|
||||||
|
input->Handle,
|
||||||
|
input->ObjectInformationClass,
|
||||||
|
input->ObjectInformation,
|
||||||
|
input->ObjectInformationLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_OPENDRIVER:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PHANDLE DriverHandle;
|
||||||
|
ACCESS_MASK DesiredAccess;
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiOpenDriver(
|
||||||
|
input->DriverHandle,
|
||||||
|
input->DesiredAccess,
|
||||||
|
input->ObjectAttributes,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KPH_QUERYINFORMATIONDRIVER:
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE DriverHandle;
|
||||||
|
DRIVER_INFORMATION_CLASS DriverInformationClass;
|
||||||
|
PVOID DriverInformation;
|
||||||
|
ULONG DriverInformationLength;
|
||||||
|
PULONG ReturnLength;
|
||||||
|
} *input = capturedInputPointer;
|
||||||
|
|
||||||
|
VERIFY_INPUT_LENGTH;
|
||||||
|
|
||||||
|
status = KpiQueryInformationDriver(
|
||||||
|
input->DriverHandle,
|
||||||
|
input->DriverInformationClass,
|
||||||
|
input->DriverInformation,
|
||||||
|
input->DriverInformationLength,
|
||||||
|
input->ReturnLength,
|
||||||
|
accessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlEnd:
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
1
KProcessHacker/dirs
Normal file
1
KProcessHacker/dirs
Normal file
@ -0,0 +1 @@
|
|||||||
|
DIRS=clean
|
167
KProcessHacker/dyndata.c
Normal file
167
KProcessHacker/dyndata.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
#define _DYNDATA_PRIVATE
|
||||||
|
#include <dyndata.h>
|
||||||
|
|
||||||
|
#define C_2sTo4(x) ((unsigned int)(signed short)(x))
|
||||||
|
|
||||||
|
NTSTATUS KphpLoadDynamicConfiguration(
|
||||||
|
__in PVOID Buffer,
|
||||||
|
__in ULONG Length
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KphDynamicDataInitialization)
|
||||||
|
#pragma alloc_text(PAGE, KphReadDynamicDataParameters)
|
||||||
|
#pragma alloc_text(PAGE, KphpLoadDynamicConfiguration)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS KphDynamicDataInitialization(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Get Windows version information.
|
||||||
|
|
||||||
|
KphDynOsVersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||||
|
status = RtlGetVersion((PRTL_OSVERSIONINFOW)&KphDynOsVersionInfo);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphReadDynamicDataParameters(
|
||||||
|
__in_opt HANDLE KeyHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
UNICODE_STRING valueName;
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION info;
|
||||||
|
ULONG resultLength;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (!KeyHandle)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&valueName, L"DynamicConfiguration");
|
||||||
|
|
||||||
|
status = ZwQueryValueKey(
|
||||||
|
KeyHandle,
|
||||||
|
&valueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&resultLength
|
||||||
|
);
|
||||||
|
|
||||||
|
if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
// Unexpected status; fail now.
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = ExAllocatePoolWithTag(PagedPool, resultLength, 'ThpK');
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
status = ZwQueryValueKey(
|
||||||
|
KeyHandle,
|
||||||
|
&valueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
info,
|
||||||
|
resultLength,
|
||||||
|
&resultLength
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (info->Type == REG_BINARY)
|
||||||
|
status = KphpLoadDynamicConfiguration(info->Data, info->DataLength);
|
||||||
|
else
|
||||||
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
dprintf("Unable to load dynamic configuration: 0x%x\n", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePoolWithTag(info, 'ThpK');
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphpLoadDynamicConfiguration(
|
||||||
|
__in PVOID Buffer,
|
||||||
|
__in ULONG Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PKPH_DYN_CONFIGURATION config;
|
||||||
|
ULONG i;
|
||||||
|
PKPH_DYN_PACKAGE package;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
config = Buffer;
|
||||||
|
|
||||||
|
if (Length < FIELD_OFFSET(KPH_DYN_CONFIGURATION, Packages))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if (config->Version != KPH_DYN_CONFIGURATION_VERSION)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if (config->NumberOfPackages > KPH_DYN_MAXIMUM_PACKAGES)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if (Length < FIELD_OFFSET(KPH_DYN_CONFIGURATION, Packages) + config->NumberOfPackages * sizeof(KPH_DYN_PACKAGE))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
dprintf("Loading dynamic configuration with %u package(s)\n", config->NumberOfPackages);
|
||||||
|
|
||||||
|
for (i = 0; i < config->NumberOfPackages; i++)
|
||||||
|
{
|
||||||
|
package = &config->Packages[i];
|
||||||
|
|
||||||
|
if (package->MajorVersion == KphDynOsVersionInfo.dwMajorVersion &&
|
||||||
|
package->MinorVersion == KphDynOsVersionInfo.dwMinorVersion &&
|
||||||
|
(package->ServicePackMajor == (USHORT)-1 || package->ServicePackMajor == KphDynOsVersionInfo.wServicePackMajor) &&
|
||||||
|
(package->BuildNumber == (USHORT)-1 || package->BuildNumber == KphDynOsVersionInfo.dwBuildNumber))
|
||||||
|
{
|
||||||
|
dprintf("Found matching package at index %u for Windows %u.%u\n", i, package->MajorVersion, package->MinorVersion);
|
||||||
|
|
||||||
|
KphDynNtVersion = package->ResultingNtVersion;
|
||||||
|
|
||||||
|
KphDynEgeGuid = C_2sTo4(package->StructData.EgeGuid);
|
||||||
|
KphDynEpObjectTable = C_2sTo4(package->StructData.EpObjectTable);
|
||||||
|
KphDynEreGuidEntry = C_2sTo4(package->StructData.EreGuidEntry);
|
||||||
|
KphDynHtHandleContentionEvent = C_2sTo4(package->StructData.HtHandleContentionEvent);
|
||||||
|
KphDynOtName = C_2sTo4(package->StructData.OtName);
|
||||||
|
KphDynOtIndex = C_2sTo4(package->StructData.OtIndex);
|
||||||
|
KphDynObDecodeShift = C_2sTo4(package->StructData.ObDecodeShift);
|
||||||
|
KphDynObAttributesShift = C_2sTo4(package->StructData.ObAttributesShift);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
60
KProcessHacker/dynimp.c
Normal file
60
KProcessHacker/dynimp.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
#include <dyndata.h>
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KphGetSystemRoutineAddress)
|
||||||
|
#pragma alloc_text(PAGE, KphDynamicImport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically imports routines.
|
||||||
|
*/
|
||||||
|
VOID KphDynamicImport(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the address of a function exported by NTOS or HAL.
|
||||||
|
*
|
||||||
|
* \param SystemRoutineName The name of the function.
|
||||||
|
*
|
||||||
|
* \return The address of the function, or NULL if the function could
|
||||||
|
* not be found.
|
||||||
|
*/
|
||||||
|
PVOID KphGetSystemRoutineAddress(
|
||||||
|
__in PWSTR SystemRoutineName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNICODE_STRING systemRoutineName;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&systemRoutineName, SystemRoutineName);
|
||||||
|
|
||||||
|
return MmGetSystemRoutineAddress(&systemRoutineName);
|
||||||
|
}
|
47
KProcessHacker/include/dyndata.h
Normal file
47
KProcessHacker/include/dyndata.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef DYNDATA_H
|
||||||
|
#define DYNDATA_H
|
||||||
|
|
||||||
|
#ifdef EXT
|
||||||
|
#undef EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DYNDATA_PRIVATE
|
||||||
|
#define EXT
|
||||||
|
#define OFFDEFAULT = -1
|
||||||
|
#else
|
||||||
|
#define EXT extern
|
||||||
|
#define OFFDEFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXT ULONG KphDynNtVersion;
|
||||||
|
EXT RTL_OSVERSIONINFOEXW KphDynOsVersionInfo;
|
||||||
|
|
||||||
|
// Structures
|
||||||
|
// Ege: ETW_GUID_ENTRY
|
||||||
|
// Ep: EPROCESS
|
||||||
|
// Ere: ETW_REG_ENTRY
|
||||||
|
// Et: ETHREAD
|
||||||
|
// Ht: HANDLE_TABLE
|
||||||
|
// Oh: OBJECT_HEADER
|
||||||
|
// Ot: OBJECT_TYPE
|
||||||
|
// Oti: OBJECT_TYPE_INITIALIZER, offset measured from an OBJECT_TYPE
|
||||||
|
// ObDecodeShift: shift value in ObpDecodeObject
|
||||||
|
// ObAttributesShift: shift value in ObpGetHandleAttributes
|
||||||
|
EXT ULONG KphDynEgeGuid OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynEpObjectTable OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynEreGuidEntry OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynHtHandleContentionEvent OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynOtName OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynOtIndex OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynObDecodeShift OFFDEFAULT;
|
||||||
|
EXT ULONG KphDynObAttributesShift OFFDEFAULT;
|
||||||
|
|
||||||
|
NTSTATUS KphDynamicDataInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphReadDynamicDataParameters(
|
||||||
|
__in_opt HANDLE KeyHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
365
KProcessHacker/include/kph.h
Normal file
365
KProcessHacker/include/kph.h
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
#ifndef KPH_H
|
||||||
|
#define KPH_H
|
||||||
|
|
||||||
|
#include <ntifs.h>
|
||||||
|
#define PHNT_MODE PHNT_MODE_KERNEL
|
||||||
|
#include <phnt.h>
|
||||||
|
#include <ntfill.h>
|
||||||
|
#include <bcrypt.h>
|
||||||
|
#include <kphapi.h>
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#define dprintf(Format, ...) DbgPrint("KProcessHacker: " Format, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _KPH_CLIENT
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG VerificationPerformed : 1;
|
||||||
|
ULONG VerificationSucceeded : 1;
|
||||||
|
ULONG KeysGenerated : 1;
|
||||||
|
ULONG SpareBits : 29;
|
||||||
|
};
|
||||||
|
FAST_MUTEX StateMutex;
|
||||||
|
NTSTATUS VerificationStatus;
|
||||||
|
PVOID VerifiedProcess; // EPROCESS (for equality checking only - do not access contents)
|
||||||
|
HANDLE VerifiedProcessId;
|
||||||
|
PVOID VerifiedRangeBase;
|
||||||
|
SIZE_T VerifiedRangeSize;
|
||||||
|
// Level 1 and 2 secret keys
|
||||||
|
FAST_MUTEX KeyBackoffMutex;
|
||||||
|
KPH_KEY L1Key;
|
||||||
|
KPH_KEY L2Key;
|
||||||
|
} KPH_CLIENT, *PKPH_CLIENT;
|
||||||
|
|
||||||
|
typedef struct _KPH_PARAMETERS
|
||||||
|
{
|
||||||
|
KPH_SECURITY_LEVEL SecurityLevel;
|
||||||
|
} KPH_PARAMETERS, *PKPH_PARAMETERS;
|
||||||
|
|
||||||
|
// main
|
||||||
|
|
||||||
|
extern ULONG KphFeatures;
|
||||||
|
extern KPH_PARAMETERS KphParameters;
|
||||||
|
|
||||||
|
NTSTATUS KpiGetFeatures(
|
||||||
|
__out PULONG Features,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// devctrl
|
||||||
|
|
||||||
|
__drv_dispatchType(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH KphDispatchDeviceControl;
|
||||||
|
|
||||||
|
NTSTATUS KphDispatchDeviceControl(
|
||||||
|
__in PDEVICE_OBJECT DeviceObject,
|
||||||
|
__in PIRP Irp
|
||||||
|
);
|
||||||
|
|
||||||
|
// dynimp
|
||||||
|
|
||||||
|
VOID KphDynamicImport(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID KphGetSystemRoutineAddress(
|
||||||
|
__in PWSTR SystemRoutineName
|
||||||
|
);
|
||||||
|
|
||||||
|
// object
|
||||||
|
|
||||||
|
PHANDLE_TABLE KphReferenceProcessHandleTable(
|
||||||
|
__in PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID KphDereferenceProcessHandleTable(
|
||||||
|
__in PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID KphUnlockHandleTableEntry(
|
||||||
|
__in PHANDLE_TABLE HandleTable,
|
||||||
|
__in PHANDLE_TABLE_ENTRY HandleTableEntry
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiEnumerateProcessHandles(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__out_bcount(BufferLength) PVOID Buffer,
|
||||||
|
__in_opt ULONG BufferLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphQueryNameObject(
|
||||||
|
__in PVOID Object,
|
||||||
|
__out_bcount(BufferLength) POBJECT_NAME_INFORMATION Buffer,
|
||||||
|
__in ULONG BufferLength,
|
||||||
|
__out PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphQueryNameFileObject(
|
||||||
|
__in PFILE_OBJECT FileObject,
|
||||||
|
__out_bcount(BufferLength) POBJECT_NAME_INFORMATION Buffer,
|
||||||
|
__in ULONG BufferLength,
|
||||||
|
__out PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiQueryInformationObject(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||||
|
__out_bcount(ObjectInformationLength) PVOID ObjectInformation,
|
||||||
|
__in ULONG ObjectInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiSetInformationObject(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||||
|
__in_bcount(ObjectInformationLength) PVOID ObjectInformation,
|
||||||
|
__in ULONG ObjectInformationLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphOpenNamedObject(
|
||||||
|
__out PHANDLE ObjectHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
__in POBJECT_TYPE ObjectType,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// process
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenProcess(
|
||||||
|
__out PHANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in PCLIENT_ID ClientId,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenProcessToken(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE TokenHandle,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenProcessJob(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE JobHandle,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiTerminateProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in NTSTATUS ExitStatus,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiQueryInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
||||||
|
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiSetInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
||||||
|
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// qrydrv
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenDriver(
|
||||||
|
__out PHANDLE DriverHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiQueryInformationDriver(
|
||||||
|
__in HANDLE DriverHandle,
|
||||||
|
__in DRIVER_INFORMATION_CLASS DriverInformationClass,
|
||||||
|
__out_bcount(DriverInformationLength) PVOID DriverInformation,
|
||||||
|
__in ULONG DriverInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// thread
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenThread(
|
||||||
|
__out PHANDLE ThreadHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in PCLIENT_ID ClientId,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenThreadProcess(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE ProcessHandle,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG KphCaptureStackBackTrace(
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__in_opt ULONG Flags,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG BackTraceHash
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphCaptureStackBackTraceThread(
|
||||||
|
__in PETHREAD Thread,
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG CapturedFrames,
|
||||||
|
__out_opt PULONG BackTraceHash,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiCaptureStackBackTraceThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG CapturedFrames,
|
||||||
|
__out_opt PULONG BackTraceHash,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiQueryInformationThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||||
|
__out_bcount(ProcessInformationLength) PVOID ThreadInformation,
|
||||||
|
__in ULONG ThreadInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiSetInformationThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||||
|
__in_bcount(ThreadInformationLength) PVOID ThreadInformation,
|
||||||
|
__in ULONG ThreadInformationLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// util
|
||||||
|
|
||||||
|
VOID KphFreeCapturedUnicodeString(
|
||||||
|
__in PUNICODE_STRING CapturedUnicodeString
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphCaptureUnicodeString(
|
||||||
|
__in PUNICODE_STRING UnicodeString,
|
||||||
|
__out PUNICODE_STRING CapturedUnicodeString
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphEnumerateSystemModules(
|
||||||
|
__out PRTL_PROCESS_MODULES *Modules
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphValidateAddressForSystemModules(
|
||||||
|
__in PVOID Address,
|
||||||
|
__in SIZE_T Length
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphGetProcessMappedFileName(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in PVOID BaseAddress,
|
||||||
|
__out PUNICODE_STRING *FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
|
||||||
|
NTSTATUS KphHashFile(
|
||||||
|
__in PUNICODE_STRING FileName,
|
||||||
|
__out PVOID *Hash,
|
||||||
|
__out PULONG HashSize
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphVerifyFile(
|
||||||
|
__in PUNICODE_STRING FileName,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID KphVerifyClient(
|
||||||
|
__inout PKPH_CLIENT Client,
|
||||||
|
__in PVOID CodeAddress,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiVerifyClient(
|
||||||
|
__in PVOID CodeAddress,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize,
|
||||||
|
__in PKPH_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID KphGenerateKeysClient(
|
||||||
|
__inout PKPH_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphRetrieveKeyViaApc(
|
||||||
|
__inout PKPH_CLIENT Client,
|
||||||
|
__in KPH_KEY_LEVEL KeyLevel,
|
||||||
|
__inout PIRP Irp
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphValidateKey(
|
||||||
|
__in KPH_KEY_LEVEL RequiredKeyLevel,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// vm
|
||||||
|
|
||||||
|
NTSTATUS KphCopyVirtualMemory(
|
||||||
|
__in PEPROCESS FromProcess,
|
||||||
|
__in PVOID FromAddress,
|
||||||
|
__in PEPROCESS ToProcess,
|
||||||
|
__in PVOID ToAddress,
|
||||||
|
__in SIZE_T BufferLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode,
|
||||||
|
__out PSIZE_T ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KpiReadVirtualMemoryUnsafe(
|
||||||
|
__in_opt HANDLE ProcessHandle,
|
||||||
|
__in PVOID BaseAddress,
|
||||||
|
__out_bcount(BufferSize) PVOID Buffer,
|
||||||
|
__in SIZE_T BufferSize,
|
||||||
|
__out_opt PSIZE_T NumberOfBytesRead,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
351
KProcessHacker/include/ntfill.h
Normal file
351
KProcessHacker/include/ntfill.h
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
#ifndef NTFILL_H
|
||||||
|
#define NTFILL_H
|
||||||
|
|
||||||
|
extern ULONG KphDynNtVersion;
|
||||||
|
extern ULONG KphDynObDecodeShift;
|
||||||
|
extern ULONG KphDynObAttributesShift;
|
||||||
|
|
||||||
|
// EX
|
||||||
|
|
||||||
|
typedef struct _EX_PUSH_LOCK_WAIT_BLOCK *PEX_PUSH_LOCK_WAIT_BLOCK;
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ExfUnblockPushLock(
|
||||||
|
__inout PEX_PUSH_LOCK PushLock,
|
||||||
|
__inout_opt PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE_ENTRY
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PVOID Object;
|
||||||
|
ULONG ObAttributes;
|
||||||
|
ULONG_PTR Value;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ACCESS_MASK GrantedAccess;
|
||||||
|
LONG NextFreeTableEntry;
|
||||||
|
};
|
||||||
|
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_TABLE HANDLE_TABLE, *PHANDLE_TABLE;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PEX_ENUM_HANDLE_CALLBACK_61)(
|
||||||
|
__inout PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
// since WIN8
|
||||||
|
typedef BOOLEAN (NTAPI *PEX_ENUM_HANDLE_CALLBACK)(
|
||||||
|
__in PHANDLE_TABLE HandleTable,
|
||||||
|
__inout PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
ExEnumHandleTable(
|
||||||
|
__in PHANDLE_TABLE HandleTable,
|
||||||
|
__in PEX_ENUM_HANDLE_CALLBACK EnumHandleProcedure,
|
||||||
|
__inout PVOID Context,
|
||||||
|
__out_opt PHANDLE Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSYSCALLAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ZwQuerySystemInformation(
|
||||||
|
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||||
|
__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
|
||||||
|
__in ULONG SystemInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
// IO
|
||||||
|
|
||||||
|
extern POBJECT_TYPE *IoDriverObjectType;
|
||||||
|
|
||||||
|
// KE
|
||||||
|
|
||||||
|
typedef enum _KAPC_ENVIRONMENT
|
||||||
|
{
|
||||||
|
OriginalApcEnvironment,
|
||||||
|
AttachedApcEnvironment,
|
||||||
|
CurrentApcEnvironment,
|
||||||
|
InsertApcEnvironment
|
||||||
|
} KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PKNORMAL_ROUTINE)(
|
||||||
|
__in PVOID NormalContext,
|
||||||
|
__in PVOID SystemArgument1,
|
||||||
|
__in PVOID SystemArgument2
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID KKERNEL_ROUTINE(
|
||||||
|
__in PRKAPC Apc,
|
||||||
|
__inout PKNORMAL_ROUTINE *NormalRoutine,
|
||||||
|
__inout PVOID *NormalContext,
|
||||||
|
__inout PVOID *SystemArgument1,
|
||||||
|
__inout PVOID *SystemArgument2
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef KKERNEL_ROUTINE (NTAPI *PKKERNEL_ROUTINE);
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PKRUNDOWN_ROUTINE)(
|
||||||
|
__in PRKAPC Apc
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KeInitializeApc(
|
||||||
|
__out PRKAPC Apc,
|
||||||
|
__in PRKTHREAD Thread,
|
||||||
|
__in KAPC_ENVIRONMENT Environment,
|
||||||
|
__in PKKERNEL_ROUTINE KernelRoutine,
|
||||||
|
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
|
||||||
|
__in_opt PKNORMAL_ROUTINE NormalRoutine,
|
||||||
|
__in_opt KPROCESSOR_MODE ProcessorMode,
|
||||||
|
__in_opt PVOID NormalContext
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeInsertQueueApc(
|
||||||
|
__inout PRKAPC Apc,
|
||||||
|
__in_opt PVOID SystemArgument1,
|
||||||
|
__in_opt PVOID SystemArgument2,
|
||||||
|
__in KPRIORITY Increment
|
||||||
|
);
|
||||||
|
|
||||||
|
// MM
|
||||||
|
|
||||||
|
NTSYSCALLAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ZwQueryVirtualMemory(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in PVOID BaseAddress,
|
||||||
|
__in MEMORY_INFORMATION_CLASS MemoryInformationClass,
|
||||||
|
__out_bcount(MemoryInformationLength) PVOID MemoryInformation,
|
||||||
|
__in SIZE_T MemoryInformationLength,
|
||||||
|
__out_opt PSIZE_T ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
// OB
|
||||||
|
|
||||||
|
// These definitions are no longer correct, but they produce correct results.
|
||||||
|
|
||||||
|
#define OBJ_PROTECT_CLOSE 0x00000001
|
||||||
|
#define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE | OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)
|
||||||
|
|
||||||
|
// This attribute is now stored in the GrantedAccess field.
|
||||||
|
#define ObpAccessProtectCloseBit 0x2000000
|
||||||
|
|
||||||
|
#define ObpDecodeGrantedAccess(Access) \
|
||||||
|
((Access) & ~ObpAccessProtectCloseBit)
|
||||||
|
|
||||||
|
FORCEINLINE PVOID ObpDecodeObject(PVOID Object)
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
if (KphDynNtVersion >= PHNT_WIN8)
|
||||||
|
{
|
||||||
|
if (KphDynObDecodeShift != -1)
|
||||||
|
return (PVOID)(((LONG_PTR)Object >> KphDynObDecodeShift) & ~(ULONG_PTR)0xf);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (PVOID)((ULONG_PTR)Object & ~OBJ_HANDLE_ATTRIBUTES);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return (PVOID)((ULONG_PTR)Object & ~OBJ_HANDLE_ATTRIBUTES);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE ULONG ObpGetHandleAttributes(PHANDLE_TABLE_ENTRY HandleTableEntry)
|
||||||
|
{
|
||||||
|
#ifdef _M_X64
|
||||||
|
if (KphDynNtVersion >= PHNT_WIN8)
|
||||||
|
{
|
||||||
|
if (KphDynObAttributesShift != -1)
|
||||||
|
return (ULONG)(HandleTableEntry->Value >> KphDynObAttributesShift) & 0x3;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (HandleTableEntry->ObAttributes & (OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)) |
|
||||||
|
((HandleTableEntry->GrantedAccess & ObpAccessProtectCloseBit) ? OBJ_PROTECT_CLOSE : 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return (HandleTableEntry->ObAttributes & (OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)) |
|
||||||
|
((HandleTableEntry->GrantedAccess & ObpAccessProtectCloseBit) ? OBJ_PROTECT_CLOSE : 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _OBJECT_CREATE_INFORMATION OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
|
||||||
|
|
||||||
|
// This is incorrect as of Windows 8.1, but the size of the structure is still correct.
|
||||||
|
typedef struct _OBJECT_HEADER
|
||||||
|
{
|
||||||
|
LONG PointerCount;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
LONG HandleCount;
|
||||||
|
PVOID NextToFree;
|
||||||
|
};
|
||||||
|
POBJECT_TYPE Type;
|
||||||
|
UCHAR NameInfoOffset;
|
||||||
|
UCHAR HandleInfoOffset;
|
||||||
|
UCHAR QuotaInfoOffset;
|
||||||
|
UCHAR Flags;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
|
PVOID QuotaBlockCharged;
|
||||||
|
};
|
||||||
|
PVOID SecurityDescriptor;
|
||||||
|
QUAD Body;
|
||||||
|
} OBJECT_HEADER, *POBJECT_HEADER;
|
||||||
|
|
||||||
|
#define OBJECT_TO_OBJECT_HEADER(Object) CONTAINING_RECORD((Object), OBJECT_HEADER, Body)
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
POBJECT_TYPE
|
||||||
|
NTAPI
|
||||||
|
ObGetObjectType(
|
||||||
|
__in PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObOpenObjectByName(
|
||||||
|
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
__in POBJECT_TYPE ObjectType,
|
||||||
|
__in KPROCESSOR_MODE PreviousMode,
|
||||||
|
__in_opt PACCESS_STATE AccessState,
|
||||||
|
__in_opt ACCESS_MASK DesiredAccess,
|
||||||
|
__in PVOID ParseContext,
|
||||||
|
__out PHANDLE Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObSetHandleAttributes(
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,
|
||||||
|
__in KPROCESSOR_MODE PreviousMode
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
ObCloseHandle(
|
||||||
|
__in HANDLE Handle,
|
||||||
|
__in KPROCESSOR_MODE PreviousMode
|
||||||
|
);
|
||||||
|
|
||||||
|
// PS
|
||||||
|
|
||||||
|
NTSYSCALLAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ZwQueryInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in PROCESSINFOCLASS ProcessInformationClass,
|
||||||
|
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSYSCALLAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ZwSetInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in PROCESSINFOCLASS ProcessInformationClass,
|
||||||
|
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSYSCALLAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ZwQueryInformationThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in THREADINFOCLASS ThreadInformationClass,
|
||||||
|
__out_bcount(ThreadInformationLength) PVOID ThreadInformation,
|
||||||
|
__in ULONG ThreadInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsLookupProcessThreadByCid(
|
||||||
|
__in PCLIENT_ID ClientId,
|
||||||
|
__out_opt PEPROCESS *Process,
|
||||||
|
__out PETHREAD *Thread
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
PsGetThreadWin32Thread(
|
||||||
|
__in PETHREAD Thread
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _EJOB *PEJOB;
|
||||||
|
|
||||||
|
extern POBJECT_TYPE *PsJobType;
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
PEJOB
|
||||||
|
NTAPI
|
||||||
|
PsGetProcessJob(
|
||||||
|
__in PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsAcquireProcessExitSynchronization(
|
||||||
|
__in PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
NTKERNELAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PsReleaseProcessExitSynchronization(
|
||||||
|
__in PEPROCESS Process
|
||||||
|
);
|
||||||
|
|
||||||
|
// RTL
|
||||||
|
|
||||||
|
// Sensible limit that may or may not correspond to the actual Windows value.
|
||||||
|
#define MAX_STACK_DEPTH 256
|
||||||
|
|
||||||
|
#define RTL_WALK_USER_MODE_STACK 0x00000001
|
||||||
|
#define RTL_WALK_VALID_FLAGS 0x00000001
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
RtlWalkFrameChain(
|
||||||
|
__out PVOID *Callers,
|
||||||
|
__in ULONG Count,
|
||||||
|
__in ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
356
KProcessHacker/main.c
Normal file
356
KProcessHacker/main.c
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
#include <dyndata.h>
|
||||||
|
|
||||||
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
DRIVER_UNLOAD DriverUnload;
|
||||||
|
__drv_dispatchType(IRP_MJ_CREATE) DRIVER_DISPATCH KphDispatchCreate;
|
||||||
|
__drv_dispatchType(IRP_MJ_CLOSE) DRIVER_DISPATCH KphDispatchClose;
|
||||||
|
|
||||||
|
ULONG KphpReadIntegerParameter(
|
||||||
|
__in_opt HANDLE KeyHandle,
|
||||||
|
__in PUNICODE_STRING ValueName,
|
||||||
|
__in ULONG DefaultValue
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS KphpReadDriverParameters(
|
||||||
|
__in PUNICODE_STRING RegistryPath
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, DriverEntry)
|
||||||
|
#pragma alloc_text(PAGE, DriverUnload)
|
||||||
|
#pragma alloc_text(PAGE, KphpReadIntegerParameter)
|
||||||
|
#pragma alloc_text(PAGE, KphpReadDriverParameters)
|
||||||
|
#pragma alloc_text(PAGE, KpiGetFeatures)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PDRIVER_OBJECT KphDriverObject;
|
||||||
|
PDEVICE_OBJECT KphDeviceObject;
|
||||||
|
ULONG KphFeatures;
|
||||||
|
KPH_PARAMETERS KphParameters;
|
||||||
|
|
||||||
|
NTSTATUS DriverEntry(
|
||||||
|
__in PDRIVER_OBJECT DriverObject,
|
||||||
|
__in PUNICODE_STRING RegistryPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
UNICODE_STRING deviceName;
|
||||||
|
PDEVICE_OBJECT deviceObject;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
KphDriverObject = DriverObject;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = KphDynamicDataInitialization()))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
KphDynamicImport();
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = KphpReadDriverParameters(RegistryPath)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Create the device.
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&deviceName, KPH_DEVICE_NAME);
|
||||||
|
|
||||||
|
status = IoCreateDevice(
|
||||||
|
DriverObject,
|
||||||
|
0,
|
||||||
|
&deviceName,
|
||||||
|
FILE_DEVICE_UNKNOWN,
|
||||||
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
|
FALSE,
|
||||||
|
&deviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
KphDeviceObject = deviceObject;
|
||||||
|
|
||||||
|
// Set up I/O.
|
||||||
|
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = KphDispatchCreate;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KphDispatchClose;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KphDispatchDeviceControl;
|
||||||
|
DriverObject->DriverUnload = DriverUnload;
|
||||||
|
|
||||||
|
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
dprintf("Driver loaded\n");
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID DriverUnload(
|
||||||
|
__in PDRIVER_OBJECT DriverObject
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
IoDeleteDevice(KphDeviceObject);
|
||||||
|
|
||||||
|
dprintf("Driver unloaded\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphDispatchCreate(
|
||||||
|
__in PDEVICE_OBJECT DeviceObject,
|
||||||
|
__in PIRP Irp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PIO_STACK_LOCATION stackLocation;
|
||||||
|
PFILE_OBJECT fileObject;
|
||||||
|
PIO_SECURITY_CONTEXT securityContext;
|
||||||
|
PKPH_CLIENT client;
|
||||||
|
|
||||||
|
stackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
fileObject = stackLocation->FileObject;
|
||||||
|
securityContext = stackLocation->Parameters.Create.SecurityContext;
|
||||||
|
|
||||||
|
dprintf("Client (PID %Iu) is connecting\n", PsGetCurrentProcessId());
|
||||||
|
|
||||||
|
if (KphParameters.SecurityLevel == KphSecurityPrivilegeCheck ||
|
||||||
|
KphParameters.SecurityLevel == KphSecuritySignatureAndPrivilegeCheck)
|
||||||
|
{
|
||||||
|
UCHAR requiredPrivilegesBuffer[FIELD_OFFSET(PRIVILEGE_SET, Privilege) + sizeof(LUID_AND_ATTRIBUTES)];
|
||||||
|
PPRIVILEGE_SET requiredPrivileges;
|
||||||
|
|
||||||
|
// Check for SeDebugPrivilege.
|
||||||
|
|
||||||
|
requiredPrivileges = (PPRIVILEGE_SET)requiredPrivilegesBuffer;
|
||||||
|
requiredPrivileges->PrivilegeCount = 1;
|
||||||
|
requiredPrivileges->Control = PRIVILEGE_SET_ALL_NECESSARY;
|
||||||
|
requiredPrivileges->Privilege[0].Luid.LowPart = SE_DEBUG_PRIVILEGE;
|
||||||
|
requiredPrivileges->Privilege[0].Luid.HighPart = 0;
|
||||||
|
requiredPrivileges->Privilege[0].Attributes = 0;
|
||||||
|
|
||||||
|
if (!SePrivilegeCheck(
|
||||||
|
requiredPrivileges,
|
||||||
|
&securityContext->AccessState->SubjectSecurityContext,
|
||||||
|
Irp->RequestorMode
|
||||||
|
))
|
||||||
|
{
|
||||||
|
status = STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
dprintf("Client (PID %Iu) was rejected\n", PsGetCurrentProcessId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
client = ExAllocatePoolWithTag(PagedPool, sizeof(KPH_CLIENT), 'ChpK');
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
memset(client, 0, sizeof(KPH_CLIENT));
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&client->StateMutex);
|
||||||
|
ExInitializeFastMutex(&client->KeyBackoffMutex);
|
||||||
|
|
||||||
|
fileObject->FsContext = client;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("Unable to allocate memory for client (PID %Iu)\n", PsGetCurrentProcessId());
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphDispatchClose(
|
||||||
|
__in PDEVICE_OBJECT DeviceObject,
|
||||||
|
__in PIRP Irp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PIO_STACK_LOCATION stackLocation;
|
||||||
|
PFILE_OBJECT fileObject;
|
||||||
|
PKPH_CLIENT client;
|
||||||
|
|
||||||
|
stackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
fileObject = stackLocation->FileObject;
|
||||||
|
client = fileObject->FsContext;
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(client, 'ChpK');
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = status;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads an integer (REG_DWORD) parameter from the registry.
|
||||||
|
*
|
||||||
|
* \param KeyHandle A handle to the Parameters key. If NULL, the function
|
||||||
|
* fails immediately and returns \a DefaultValue.
|
||||||
|
* \param ValueName The name of the parameter.
|
||||||
|
* \param DefaultValue The value that is returned if the function fails
|
||||||
|
* to retrieve the parameter from the registry.
|
||||||
|
*
|
||||||
|
* \return The parameter value, or \a DefaultValue if the function failed.
|
||||||
|
*/
|
||||||
|
ULONG KphpReadIntegerParameter(
|
||||||
|
__in_opt HANDLE KeyHandle,
|
||||||
|
__in PUNICODE_STRING ValueName,
|
||||||
|
__in ULONG DefaultValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)];
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION info;
|
||||||
|
ULONG resultLength;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (!KeyHandle)
|
||||||
|
return DefaultValue;
|
||||||
|
|
||||||
|
info = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
|
||||||
|
|
||||||
|
status = ZwQueryValueKey(
|
||||||
|
KeyHandle,
|
||||||
|
ValueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
info,
|
||||||
|
sizeof(buffer),
|
||||||
|
&resultLength
|
||||||
|
);
|
||||||
|
|
||||||
|
if (info->Type != REG_DWORD)
|
||||||
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
dprintf("Unable to query parameter %.*S: 0x%x\n", ValueName->Length / sizeof(WCHAR), ValueName->Buffer, status);
|
||||||
|
return DefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *(PULONG)info->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the driver parameters.
|
||||||
|
*
|
||||||
|
* \param RegistryPath The registry path of the driver.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphpReadDriverParameters(
|
||||||
|
__in PUNICODE_STRING RegistryPath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE parametersKeyHandle;
|
||||||
|
UNICODE_STRING parametersString;
|
||||||
|
UNICODE_STRING parametersKeyName;
|
||||||
|
OBJECT_ATTRIBUTES objectAttributes;
|
||||||
|
UNICODE_STRING valueName;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Open the Parameters key.
|
||||||
|
|
||||||
|
RtlInitUnicodeString(¶metersString, L"\\Parameters");
|
||||||
|
|
||||||
|
parametersKeyName.Length = RegistryPath->Length + parametersString.Length;
|
||||||
|
parametersKeyName.MaximumLength = parametersKeyName.Length;
|
||||||
|
parametersKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, parametersKeyName.MaximumLength, 'ThpK');
|
||||||
|
|
||||||
|
if (!parametersKeyName.Buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
memcpy(parametersKeyName.Buffer, RegistryPath->Buffer, RegistryPath->Length);
|
||||||
|
memcpy(¶metersKeyName.Buffer[RegistryPath->Length / sizeof(WCHAR)], parametersString.Buffer, parametersString.Length);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&objectAttributes,
|
||||||
|
¶metersKeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
status = ZwOpenKey(
|
||||||
|
¶metersKeyHandle,
|
||||||
|
KEY_READ,
|
||||||
|
&objectAttributes
|
||||||
|
);
|
||||||
|
ExFreePoolWithTag(parametersKeyName.Buffer, 'ThpK');
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
dprintf("Unable to open Parameters key: 0x%x\n", status);
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
parametersKeyHandle = NULL;
|
||||||
|
// Continue so we can set up defaults.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read in the parameters.
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&valueName, L"SecurityLevel");
|
||||||
|
KphParameters.SecurityLevel = KphpReadIntegerParameter(parametersKeyHandle, &valueName, KphSecurityPrivilegeCheck);
|
||||||
|
|
||||||
|
KphReadDynamicDataParameters(parametersKeyHandle);
|
||||||
|
|
||||||
|
if (parametersKeyHandle)
|
||||||
|
ZwClose(parametersKeyHandle);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KpiGetFeatures(
|
||||||
|
__out PULONG Features,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(Features, sizeof(ULONG), sizeof(ULONG));
|
||||||
|
*Features = KphFeatures;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*Features = KphFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
1295
KProcessHacker/object.c
Normal file
1295
KProcessHacker/object.c
Normal file
File diff suppressed because it is too large
Load Diff
570
KProcessHacker/process.c
Normal file
570
KProcessHacker/process.c
Normal file
@ -0,0 +1,570 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
#include <dyndata.h>
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenProcess)
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenProcessToken)
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenProcessJob)
|
||||||
|
#pragma alloc_text(PAGE, KpiTerminateProcess)
|
||||||
|
#pragma alloc_text(PAGE, KpiQueryInformationProcess)
|
||||||
|
#pragma alloc_text(PAGE, KpiSetInformationProcess)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a process.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A variable which receives the process handle.
|
||||||
|
* \param DesiredAccess The desired access to the process.
|
||||||
|
* \param ClientId The identifier of a process or thread. If \a UniqueThread is present, the process
|
||||||
|
* of the identified thread will be opened. If \a UniqueProcess is present, the identified process
|
||||||
|
* will be opened.
|
||||||
|
* \param Key An access key.
|
||||||
|
* \li If a L2 key is provided, no access checks are performed.
|
||||||
|
* \li If a L1 key is provided, only read access is permitted but no additional access checks are
|
||||||
|
* performed.
|
||||||
|
* \li If no valid key is provided, the function fails.
|
||||||
|
* \param Client The client that initiated the request.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiOpenProcess(
|
||||||
|
__out PHANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in PCLIENT_ID ClientId,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
CLIENT_ID clientId;
|
||||||
|
PEPROCESS process;
|
||||||
|
PETHREAD thread;
|
||||||
|
KPH_KEY_LEVEL requiredKeyLevel;
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(ProcessHandle, sizeof(HANDLE), sizeof(HANDLE));
|
||||||
|
ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
|
||||||
|
clientId = *ClientId;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clientId = *ClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the thread ID if it was specified.
|
||||||
|
if (clientId.UniqueThread)
|
||||||
|
{
|
||||||
|
status = PsLookupProcessThreadByCid(&clientId, &process, &thread);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
// We don't actually need the thread.
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = PsLookupProcessByProcessId(clientId.UniqueProcess, &process);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
requiredKeyLevel = KphKeyLevel1;
|
||||||
|
|
||||||
|
if ((DesiredAccess & KPH_PROCESS_READ_ACCESS) != DesiredAccess)
|
||||||
|
requiredKeyLevel = KphKeyLevel2;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = KphValidateKey(requiredKeyLevel, Key, Client, AccessMode)))
|
||||||
|
{
|
||||||
|
// Always open in KernelMode to skip ordinary access checks.
|
||||||
|
status = ObOpenObjectByPointer(
|
||||||
|
process,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
*PsProcessType,
|
||||||
|
KernelMode,
|
||||||
|
&processHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*ProcessHandle = processHandle;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ProcessHandle = processHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the token of a process.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process.
|
||||||
|
* \param DesiredAccess The desired access to the token.
|
||||||
|
* \param TokenHandle A variable which receives the token handle.
|
||||||
|
* \param Key An access key.
|
||||||
|
* \li If a L2 key is provided, no access checks are performed.
|
||||||
|
* \li If a L1 key is provided, only read access is permitted but no additional access checks are
|
||||||
|
* performed.
|
||||||
|
* \li If no valid key is provided, the function fails.
|
||||||
|
* \param Client The client that initiated the request.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiOpenProcessToken(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE TokenHandle,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
PACCESS_TOKEN primaryToken;
|
||||||
|
KPH_KEY_LEVEL requiredKeyLevel;
|
||||||
|
HANDLE tokenHandle;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(TokenHandle, sizeof(HANDLE), sizeof(HANDLE));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
0,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (primaryToken = PsReferencePrimaryToken(process))
|
||||||
|
{
|
||||||
|
requiredKeyLevel = KphKeyLevel1;
|
||||||
|
|
||||||
|
if ((DesiredAccess & KPH_TOKEN_READ_ACCESS) != DesiredAccess)
|
||||||
|
requiredKeyLevel = KphKeyLevel2;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = KphValidateKey(requiredKeyLevel, Key, Client, AccessMode)))
|
||||||
|
{
|
||||||
|
status = ObOpenObjectByPointer(
|
||||||
|
primaryToken,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
*SeTokenObjectType,
|
||||||
|
KernelMode,
|
||||||
|
&tokenHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PsDereferencePrimaryToken(primaryToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_NO_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*TokenHandle = tokenHandle;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*TokenHandle = tokenHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the job object of a process.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process.
|
||||||
|
* \param DesiredAccess The desired access to the job.
|
||||||
|
* \param JobHandle A variable which receives the job object handle.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiOpenProcessJob(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE JobHandle,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
PEJOB job;
|
||||||
|
HANDLE jobHandle = NULL;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(JobHandle, sizeof(HANDLE), sizeof(HANDLE));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
0,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
job = PsGetProcessJob(process);
|
||||||
|
|
||||||
|
if (job)
|
||||||
|
{
|
||||||
|
status = ObOpenObjectByPointer(
|
||||||
|
job,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
*PsJobType,
|
||||||
|
AccessMode,
|
||||||
|
&jobHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*JobHandle = jobHandle;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*JobHandle = jobHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates a process.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process.
|
||||||
|
* \param ExitStatus A status value which indicates why the process is being terminated.
|
||||||
|
* \param Key An access key.
|
||||||
|
* \li If a L2 key is provided, no access checks are performed.
|
||||||
|
* \li If no valid L2 key is provided, the function fails.
|
||||||
|
* \param Client The client that initiated the request.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiTerminateProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in NTSTATUS ExitStatus,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = KphValidateKey(KphKeyLevel2, Key, Client, AccessMode)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
0,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (process != PsGetCurrentProcess())
|
||||||
|
{
|
||||||
|
HANDLE newProcessHandle;
|
||||||
|
|
||||||
|
// Re-open the process to get a kernel handle.
|
||||||
|
if (NT_SUCCESS(status = ObOpenObjectByPointer(
|
||||||
|
process,
|
||||||
|
OBJ_KERNEL_HANDLE,
|
||||||
|
NULL,
|
||||||
|
PROCESS_TERMINATE,
|
||||||
|
*PsProcessType,
|
||||||
|
KernelMode,
|
||||||
|
&newProcessHandle
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
status = ZwTerminateProcess(newProcessHandle, ExitStatus);
|
||||||
|
ZwClose(newProcessHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_CANT_TERMINATE_SELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries process information.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process.
|
||||||
|
* \param ProcessInformationClass The type of information to query.
|
||||||
|
* \param ProcessInformation The buffer in which the information will be stored.
|
||||||
|
* \param ProcessInformationLength The number of bytes available in \a ProcessInformation.
|
||||||
|
* \param ReturnLength A variable which receives the number of bytes required to be available in
|
||||||
|
* \a ProcessInformation.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiQueryInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
||||||
|
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
ULONG returnLength;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
ULONG alignment;
|
||||||
|
|
||||||
|
switch (ProcessInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
alignment = sizeof(ULONG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(ProcessInformation, ProcessInformationLength, alignment);
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
ProbeForWrite(ReturnLength, sizeof(ULONG), sizeof(ULONG));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
PROCESS_QUERY_INFORMATION,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
switch (ProcessInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
returnLength = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*ReturnLength = returnLength;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
NOTHING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ReturnLength = returnLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets process information.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process.
|
||||||
|
* \param ProcessInformationClass The type of information to set.
|
||||||
|
* \param ProcessInformation A buffer which contains the information to set.
|
||||||
|
* \param ProcessInformationLength The number of bytes present in \a ProcessInformation.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiSetInformationProcess(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
||||||
|
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
||||||
|
__in ULONG ProcessInformationLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
ULONG alignment;
|
||||||
|
|
||||||
|
switch (ProcessInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
alignment = sizeof(ULONG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForRead(ProcessInformation, ProcessInformationLength, alignment);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
PROCESS_SET_INFORMATION,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
switch (ProcessInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
238
KProcessHacker/qrydrv.c
Normal file
238
KProcessHacker/qrydrv.c
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
|
||||||
|
VOID KphpCopyInfoUnicodeString(
|
||||||
|
__out PVOID Information,
|
||||||
|
__in_opt PUNICODE_STRING UnicodeString
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenDriver)
|
||||||
|
#pragma alloc_text(PAGE, KpiQueryInformationDriver)
|
||||||
|
#pragma alloc_text(PAGE, KphpCopyInfoUnicodeString)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS KpiOpenDriver(
|
||||||
|
__out PHANDLE DriverHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
return KphOpenNamedObject(
|
||||||
|
DriverHandle,
|
||||||
|
DesiredAccess,
|
||||||
|
ObjectAttributes,
|
||||||
|
*IoDriverObjectType,
|
||||||
|
AccessMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KpiQueryInformationDriver(
|
||||||
|
__in HANDLE DriverHandle,
|
||||||
|
__in DRIVER_INFORMATION_CLASS DriverInformationClass,
|
||||||
|
__out_bcount(DriverInformationLength) PVOID DriverInformation,
|
||||||
|
__in ULONG DriverInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PDRIVER_OBJECT driverObject;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(DriverInformation, DriverInformationLength, 1);
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
ProbeForWrite(ReturnLength, sizeof(ULONG), 1);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
DriverHandle,
|
||||||
|
0,
|
||||||
|
*IoDriverObjectType,
|
||||||
|
AccessMode,
|
||||||
|
&driverObject,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
switch (DriverInformationClass)
|
||||||
|
{
|
||||||
|
// Basic information such as flags, driver base and driver size.
|
||||||
|
case DriverBasicInformation:
|
||||||
|
{
|
||||||
|
if (DriverInformationLength == sizeof(DRIVER_BASIC_INFORMATION))
|
||||||
|
{
|
||||||
|
PDRIVER_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
basicInfo = (PDRIVER_BASIC_INFORMATION)DriverInformation;
|
||||||
|
basicInfo->Flags = driverObject->Flags;
|
||||||
|
basicInfo->DriverStart = driverObject->DriverStart;
|
||||||
|
basicInfo->DriverSize = driverObject->DriverSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_INFO_LENGTH_MISMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
*ReturnLength = sizeof(DRIVER_BASIC_INFORMATION);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// The name of the driver - e.g. \Driver\Null.
|
||||||
|
case DriverNameInformation:
|
||||||
|
{
|
||||||
|
if (DriverInformation)
|
||||||
|
{
|
||||||
|
/* Check buffer length. */
|
||||||
|
if (sizeof(UNICODE_STRING) + driverObject->DriverName.Length <=
|
||||||
|
DriverInformationLength)
|
||||||
|
{
|
||||||
|
KphpCopyInfoUnicodeString(
|
||||||
|
DriverInformation,
|
||||||
|
&driverObject->DriverName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
*ReturnLength = sizeof(UNICODE_STRING) + driverObject->DriverName.Length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// The name of the driver's service key - e.g. \REGISTRY\...
|
||||||
|
case DriverServiceKeyNameInformation:
|
||||||
|
{
|
||||||
|
if (driverObject->DriverExtension)
|
||||||
|
{
|
||||||
|
if (DriverInformation)
|
||||||
|
{
|
||||||
|
if (sizeof(UNICODE_STRING) +
|
||||||
|
driverObject->DriverExtension->ServiceKeyName.Length <=
|
||||||
|
DriverInformationLength)
|
||||||
|
{
|
||||||
|
KphpCopyInfoUnicodeString(
|
||||||
|
DriverInformation,
|
||||||
|
&driverObject->DriverExtension->ServiceKeyName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
{
|
||||||
|
*ReturnLength = sizeof(UNICODE_STRING) +
|
||||||
|
driverObject->DriverExtension->ServiceKeyName.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DriverInformation)
|
||||||
|
{
|
||||||
|
if (sizeof(UNICODE_STRING) <= DriverInformationLength)
|
||||||
|
{
|
||||||
|
// Zero the information buffer.
|
||||||
|
KphpCopyInfoUnicodeString(
|
||||||
|
DriverInformation,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
*ReturnLength = sizeof(UNICODE_STRING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(driverObject);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KphpCopyInfoUnicodeString(
|
||||||
|
__out PVOID Information,
|
||||||
|
__in_opt PUNICODE_STRING UnicodeString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PUNICODE_STRING targetUnicodeString = Information;
|
||||||
|
PWCHAR targetBuffer;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (UnicodeString)
|
||||||
|
{
|
||||||
|
targetBuffer = (PWCHAR)((PCHAR)Information + sizeof(UNICODE_STRING));
|
||||||
|
|
||||||
|
targetUnicodeString->Length = UnicodeString->Length;
|
||||||
|
targetUnicodeString->MaximumLength = UnicodeString->Length;
|
||||||
|
targetUnicodeString->Buffer = targetBuffer;
|
||||||
|
memcpy(targetBuffer, UnicodeString->Buffer, UnicodeString->Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetUnicodeString->Length = 0;
|
||||||
|
targetUnicodeString->MaximumLength = 0;
|
||||||
|
targetUnicodeString->Buffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
53
KProcessHacker/resource.rc
Normal file
53
KProcessHacker/resource.rc
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define VER_COMMA 3,0,0,0
|
||||||
|
#define VER_STR "3.0\0"
|
||||||
|
|
||||||
|
#define VER_FILEVERSION VER_COMMA
|
||||||
|
#define VER_FILEVERSION_STR VER_STR
|
||||||
|
#define VER_PRODUCTVERSION VER_COMMA
|
||||||
|
#define VER_PRODUCTVERSION_STR VER_STR
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
#define VER_DEBUG 0
|
||||||
|
#else
|
||||||
|
#define VER_DEBUG VS_FF_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VER_PRIVATEBUILD 0
|
||||||
|
#define VER_PRERELEASE 0
|
||||||
|
|
||||||
|
#define VER_COMPANYNAME_STR "wj32\0"
|
||||||
|
#define VER_FILEDESCRIPTION_STR "KProcessHacker\0"
|
||||||
|
#define VER_LEGALCOPYRIGHT_STR "Licensed under the GNU GPL, v3.\0"
|
||||||
|
#define VER_ORIGINALFILENAME_STR "kprocesshacker.sys\0"
|
||||||
|
#define VER_PRODUCTNAME_STR "KProcessHacker\0"
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION VER_FILEVERSION
|
||||||
|
PRODUCTVERSION VER_PRODUCTVERSION
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
FILEFLAGS (VER_PRIVATEBUILD | VER_PRERELEASE | VER_DEBUG)
|
||||||
|
FILEOS VOS__WINDOWS32
|
||||||
|
FILETYPE VFT_DRV
|
||||||
|
FILESUBTYPE VFT2_DRV_SYSTEM
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904E4"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", VER_COMPANYNAME_STR
|
||||||
|
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
|
||||||
|
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||||
|
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
|
||||||
|
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
|
||||||
|
VALUE "ProductName", VER_PRODUCTNAME_STR
|
||||||
|
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1252
|
||||||
|
END
|
||||||
|
END
|
7
KProcessHacker/sign.cmd
Normal file
7
KProcessHacker/sign.cmd
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
set PHBASE=..
|
||||||
|
set SIGN_TIMESTAMP=1
|
||||||
|
copy bin\i386\kprocesshacker.sys bin-signed\i386\kprocesshacker.sys
|
||||||
|
copy bin\amd64\kprocesshacker.sys bin-signed\amd64\kprocesshacker.sys
|
||||||
|
call ..\build\internal\sign.cmd bin-signed\i386\kprocesshacker.sys kmcs
|
||||||
|
call ..\build\internal\sign.cmd bin-signed\amd64\kprocesshacker.sys kmcs
|
28
KProcessHacker/sources.inc
Normal file
28
KProcessHacker/sources.inc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
TARGETTYPE=DRIVER
|
||||||
|
|
||||||
|
!IF !DEFINED(TARGETNAME)
|
||||||
|
TARGETNAME=kprocesshacker
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
!IF !DEFINED(TARGETPATH)
|
||||||
|
TARGETPATH=..\bin
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\ksecdd.lib
|
||||||
|
|
||||||
|
INCLUDES=$(DDK_INC_PATH);..\include;..\..\phnt\include;..\..\phlib\include
|
||||||
|
LIBS=%BUILD%\lib
|
||||||
|
|
||||||
|
SOURCES= \
|
||||||
|
..\main.c \
|
||||||
|
..\devctrl.c \
|
||||||
|
..\dyndata.c \
|
||||||
|
..\dynimp.c \
|
||||||
|
..\object.c \
|
||||||
|
..\process.c \
|
||||||
|
..\qrydrv.c \
|
||||||
|
..\thread.c \
|
||||||
|
..\util.c \
|
||||||
|
..\verify.c \
|
||||||
|
..\vm.c \
|
||||||
|
..\resource.rc
|
714
KProcessHacker/thread.c
Normal file
714
KProcessHacker/thread.c
Normal file
@ -0,0 +1,714 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
#include <dyndata.h>
|
||||||
|
|
||||||
|
typedef struct _CAPTURE_BACKTRACE_THREAD_CONTEXT
|
||||||
|
{
|
||||||
|
BOOLEAN Local;
|
||||||
|
KAPC Apc;
|
||||||
|
KEVENT CompletedEvent;
|
||||||
|
ULONG FramesToSkip;
|
||||||
|
ULONG FramesToCapture;
|
||||||
|
PVOID *BackTrace;
|
||||||
|
ULONG CapturedFrames;
|
||||||
|
ULONG BackTraceHash;
|
||||||
|
} CAPTURE_BACKTRACE_THREAD_CONTEXT, *PCAPTURE_BACKTRACE_THREAD_CONTEXT;
|
||||||
|
|
||||||
|
KKERNEL_ROUTINE KphpCaptureStackBackTraceThreadSpecialApc;
|
||||||
|
|
||||||
|
VOID KphpCaptureStackBackTraceThreadSpecialApc(
|
||||||
|
__in PRKAPC Apc,
|
||||||
|
__inout PKNORMAL_ROUTINE *NormalRoutine,
|
||||||
|
__inout PVOID *NormalContext,
|
||||||
|
__inout PVOID *SystemArgument1,
|
||||||
|
__inout PVOID *SystemArgument2
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenThread)
|
||||||
|
#pragma alloc_text(PAGE, KpiOpenThreadProcess)
|
||||||
|
#pragma alloc_text(PAGE, KphCaptureStackBackTraceThread)
|
||||||
|
#pragma alloc_text(PAGE, KphpCaptureStackBackTraceThreadSpecialApc)
|
||||||
|
#pragma alloc_text(PAGE, KpiCaptureStackBackTraceThread)
|
||||||
|
#pragma alloc_text(PAGE, KpiQueryInformationThread)
|
||||||
|
#pragma alloc_text(PAGE, KpiSetInformationThread)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a thread.
|
||||||
|
*
|
||||||
|
* \param ThreadHandle A variable which receives the thread handle.
|
||||||
|
* \param DesiredAccess The desired access to the thread.
|
||||||
|
* \param ClientId The identifier of a thread. \a UniqueThread must be present. If \a UniqueProcess
|
||||||
|
* is present, the process of the referenced thread will be checked against this identifier.
|
||||||
|
* \param Key An access key.
|
||||||
|
* \li If a L2 key is provided, no access checks are performed.
|
||||||
|
* \li If a L1 key is provided, only read access is permitted but no additional access checks are
|
||||||
|
* performed.
|
||||||
|
* \li If no valid key is provided, the function fails.
|
||||||
|
* \param Client The client that initiated the request.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiOpenThread(
|
||||||
|
__out PHANDLE ThreadHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__in PCLIENT_ID ClientId,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
CLIENT_ID clientId;
|
||||||
|
PETHREAD thread;
|
||||||
|
KPH_KEY_LEVEL requiredKeyLevel;
|
||||||
|
HANDLE threadHandle;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(ThreadHandle, sizeof(HANDLE), sizeof(HANDLE));
|
||||||
|
ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
|
||||||
|
clientId = *ClientId;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clientId = *ClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the process ID if it was specified.
|
||||||
|
if (clientId.UniqueProcess)
|
||||||
|
{
|
||||||
|
status = PsLookupProcessThreadByCid(&clientId, NULL, &thread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = PsLookupThreadByThreadId(clientId.UniqueThread, &thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
|
||||||
|
requiredKeyLevel = KphKeyLevel1;
|
||||||
|
|
||||||
|
if ((DesiredAccess & KPH_THREAD_READ_ACCESS) != DesiredAccess)
|
||||||
|
requiredKeyLevel = KphKeyLevel2;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = KphValidateKey(requiredKeyLevel, Key, Client, AccessMode)))
|
||||||
|
{
|
||||||
|
// Always open in KernelMode to skip access checks.
|
||||||
|
status = ObOpenObjectByPointer(
|
||||||
|
thread,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
*PsThreadType,
|
||||||
|
KernelMode,
|
||||||
|
&threadHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*ThreadHandle = threadHandle;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ThreadHandle = threadHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the process of a thread.
|
||||||
|
*
|
||||||
|
* \param ThreadHandle A handle to a thread.
|
||||||
|
* \param DesiredAccess The desired access to the process.
|
||||||
|
* \param ProcessHandle A variable which receives the process handle.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiOpenThreadProcess(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in ACCESS_MASK DesiredAccess,
|
||||||
|
__out PHANDLE ProcessHandle,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PETHREAD thread;
|
||||||
|
PEPROCESS process;
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(ProcessHandle, sizeof(HANDLE), sizeof(HANDLE));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ThreadHandle,
|
||||||
|
0,
|
||||||
|
*PsThreadType,
|
||||||
|
AccessMode,
|
||||||
|
&thread,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
process = IoThreadToProcess(thread);
|
||||||
|
|
||||||
|
status = ObOpenObjectByPointer(
|
||||||
|
process,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
DesiredAccess,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&processHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*ProcessHandle = processHandle;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ProcessHandle = processHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures a stack trace of the current thread.
|
||||||
|
*
|
||||||
|
* \param FramesToSkip The number of frames to skip from the bottom of the stack.
|
||||||
|
* \param FramesToCapture The number of frames to capture.
|
||||||
|
* \param Flags A combination of the following:
|
||||||
|
* \li \c RTL_WALK_USER_MODE_STACK The user-mode stack will be retrieved instead of the kernel-mode
|
||||||
|
* stack.
|
||||||
|
* \param BackTrace An array in which the stack trace will be stored.
|
||||||
|
* \param BackTraceHash A variable which receives a hash of the stack trace.
|
||||||
|
*
|
||||||
|
* \return The number of frames captured.
|
||||||
|
*/
|
||||||
|
ULONG KphCaptureStackBackTrace(
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__in_opt ULONG Flags,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG BackTraceHash
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PVOID backTrace[MAX_STACK_DEPTH];
|
||||||
|
ULONG framesFound;
|
||||||
|
ULONG hash;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
// Skip the current frame (for this function).
|
||||||
|
FramesToSkip++;
|
||||||
|
|
||||||
|
// Ensure that we won't overrun the buffer.
|
||||||
|
if (FramesToCapture + FramesToSkip > MAX_STACK_DEPTH)
|
||||||
|
return 0;
|
||||||
|
// Validate the flags.
|
||||||
|
if ((Flags & RTL_WALK_VALID_FLAGS) != Flags)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Walk the stack.
|
||||||
|
framesFound = RtlWalkFrameChain(
|
||||||
|
backTrace,
|
||||||
|
FramesToCapture + FramesToSkip,
|
||||||
|
Flags
|
||||||
|
);
|
||||||
|
// Return nothing if we found fewer frames than we wanted to skip.
|
||||||
|
if (framesFound <= FramesToSkip)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Copy over the stack trace. At the same time we calculate the stack trace hash by summing the
|
||||||
|
// addresses.
|
||||||
|
for (i = 0, hash = 0; i < FramesToCapture; i++)
|
||||||
|
{
|
||||||
|
if (FramesToSkip + i >= framesFound)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BackTrace[i] = backTrace[FramesToSkip + i];
|
||||||
|
hash += PtrToUlong(BackTrace[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BackTraceHash)
|
||||||
|
*BackTraceHash = hash;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the stack trace of a thread.
|
||||||
|
*
|
||||||
|
* \param Thread The thread to capture the stack trace of.
|
||||||
|
* \param FramesToSkip The number of frames to skip from the bottom of the stack.
|
||||||
|
* \param FramesToCapture The number of frames to capture.
|
||||||
|
* \param BackTrace An array in which the stack trace will be stored.
|
||||||
|
* \param CapturedFrames A variable which receives the number of frames captured.
|
||||||
|
* \param BackTraceHash A variable which receives a hash of the stack trace.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*
|
||||||
|
* \return The number of frames captured.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphCaptureStackBackTraceThread(
|
||||||
|
__in PETHREAD Thread,
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG CapturedFrames,
|
||||||
|
__out_opt PULONG BackTraceHash,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
CAPTURE_BACKTRACE_THREAD_CONTEXT context;
|
||||||
|
ULONG backTraceSize;
|
||||||
|
PVOID *backTrace;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Make sure the caller didn't request too many frames. This also restricts the amount of memory
|
||||||
|
// we will try to allocate later.
|
||||||
|
if (FramesToCapture > MAX_STACK_DEPTH)
|
||||||
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
|
|
||||||
|
backTraceSize = FramesToCapture * sizeof(PVOID);
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(BackTrace, backTraceSize, sizeof(PVOID));
|
||||||
|
|
||||||
|
if (CapturedFrames)
|
||||||
|
ProbeForWrite(CapturedFrames, sizeof(ULONG), sizeof(ULONG));
|
||||||
|
if (BackTraceHash)
|
||||||
|
ProbeForWrite(BackTraceHash, sizeof(ULONG), sizeof(ULONG));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the caller doesn't want to capture anything, return immediately.
|
||||||
|
if (backTraceSize == 0)
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
if (CapturedFrames)
|
||||||
|
*CapturedFrames = 0;
|
||||||
|
if (BackTraceHash)
|
||||||
|
*BackTraceHash = 0;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (CapturedFrames)
|
||||||
|
*CapturedFrames = 0;
|
||||||
|
if (BackTraceHash)
|
||||||
|
*BackTraceHash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate storage for the stack trace.
|
||||||
|
backTrace = ExAllocatePoolWithTag(NonPagedPool, backTraceSize, 'bhpK');
|
||||||
|
|
||||||
|
if (!backTrace)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
// Initialize the context structure.
|
||||||
|
context.FramesToSkip = FramesToSkip;
|
||||||
|
context.FramesToCapture = FramesToCapture;
|
||||||
|
context.BackTrace = backTrace;
|
||||||
|
|
||||||
|
// Check if we're trying to get a stack trace of the current thread.
|
||||||
|
// If so, we don't need to insert an APC.
|
||||||
|
if (Thread == PsGetCurrentThread())
|
||||||
|
{
|
||||||
|
PCAPTURE_BACKTRACE_THREAD_CONTEXT contextPtr = &context;
|
||||||
|
PVOID dummy = NULL;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
// Raise the IRQL to APC_LEVEL to simulate an APC environment,
|
||||||
|
// and call the APC routine directly.
|
||||||
|
|
||||||
|
context.Local = TRUE;
|
||||||
|
KeRaiseIrql(APC_LEVEL, &oldIrql);
|
||||||
|
KphpCaptureStackBackTraceThreadSpecialApc(
|
||||||
|
&context.Apc,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&contextPtr,
|
||||||
|
&dummy
|
||||||
|
);
|
||||||
|
KeLowerIrql(oldIrql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Local = FALSE;
|
||||||
|
KeInitializeEvent(&context.CompletedEvent, NotificationEvent, FALSE);
|
||||||
|
KeInitializeApc(
|
||||||
|
&context.Apc,
|
||||||
|
(PKTHREAD)Thread,
|
||||||
|
OriginalApcEnvironment,
|
||||||
|
KphpCaptureStackBackTraceThreadSpecialApc,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (KeInsertQueueApc(&context.Apc, &context, NULL, 2))
|
||||||
|
{
|
||||||
|
// Wait for the APC to complete.
|
||||||
|
status = KeWaitForSingleObject(
|
||||||
|
&context.CompletedEvent,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
ASSERT(context.CapturedFrames <= FramesToCapture);
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
memcpy(BackTrace, backTrace, context.CapturedFrames * sizeof(PVOID));
|
||||||
|
|
||||||
|
if (CapturedFrames)
|
||||||
|
*CapturedFrames = context.CapturedFrames;
|
||||||
|
if (BackTraceHash)
|
||||||
|
*BackTraceHash = context.BackTraceHash;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
status = GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(BackTrace, backTrace, context.CapturedFrames * sizeof(PVOID));
|
||||||
|
|
||||||
|
if (CapturedFrames)
|
||||||
|
*CapturedFrames = context.CapturedFrames;
|
||||||
|
if (BackTraceHash)
|
||||||
|
*BackTraceHash = context.BackTraceHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePoolWithTag(backTrace, 'bhpK');
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KphpCaptureStackBackTraceThreadSpecialApc(
|
||||||
|
__in PRKAPC Apc,
|
||||||
|
__inout PKNORMAL_ROUTINE *NormalRoutine,
|
||||||
|
__inout PVOID *NormalContext,
|
||||||
|
__inout PVOID *SystemArgument1,
|
||||||
|
__inout PVOID *SystemArgument2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PCAPTURE_BACKTRACE_THREAD_CONTEXT context = *SystemArgument1;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
context->CapturedFrames = KphCaptureStackBackTrace(
|
||||||
|
context->FramesToSkip,
|
||||||
|
context->FramesToCapture,
|
||||||
|
0,
|
||||||
|
context->BackTrace,
|
||||||
|
&context->BackTraceHash
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!context->Local)
|
||||||
|
{
|
||||||
|
// Notify the originating thread that we have completed.
|
||||||
|
KeSetEvent(&context->CompletedEvent, 0, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the stack trace of a thread.
|
||||||
|
*
|
||||||
|
* \param ThreadHandle A handle to the thread to capture the stack trace of.
|
||||||
|
* \param FramesToSkip The number of frames to skip from the bottom of the stack.
|
||||||
|
* \param FramesToCapture The number of frames to capture.
|
||||||
|
* \param BackTrace An array in which the stack trace will be stored.
|
||||||
|
* \param CapturedFrames A variable which receives the number of frames captured.
|
||||||
|
* \param BackTraceHash A variable which receives a hash of the stack trace.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*
|
||||||
|
* \return The number of frames captured.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiCaptureStackBackTraceThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in ULONG FramesToSkip,
|
||||||
|
__in ULONG FramesToCapture,
|
||||||
|
__out_ecount(FramesToCapture) PVOID *BackTrace,
|
||||||
|
__out_opt PULONG CapturedFrames,
|
||||||
|
__out_opt PULONG BackTraceHash,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PETHREAD thread;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ThreadHandle,
|
||||||
|
0,
|
||||||
|
*PsThreadType,
|
||||||
|
AccessMode,
|
||||||
|
&thread,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = KphCaptureStackBackTraceThread(
|
||||||
|
thread,
|
||||||
|
FramesToSkip,
|
||||||
|
FramesToCapture,
|
||||||
|
BackTrace,
|
||||||
|
CapturedFrames,
|
||||||
|
BackTraceHash,
|
||||||
|
AccessMode
|
||||||
|
);
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries thread information.
|
||||||
|
*
|
||||||
|
* \param ThreadHandle A handle to a thread.
|
||||||
|
* \param ThreadInformationClass The type of information to query.
|
||||||
|
* \param ThreadInformation The buffer in which the information will be stored.
|
||||||
|
* \param ThreadInformationLength The number of bytes available in \a ThreadInformation.
|
||||||
|
* \param ReturnLength A variable which receives the number of bytes required to be available in
|
||||||
|
* \a ThreadInformation.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiQueryInformationThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||||
|
__out_bcount(ProcessInformationLength) PVOID ThreadInformation,
|
||||||
|
__in ULONG ThreadInformationLength,
|
||||||
|
__out_opt PULONG ReturnLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PETHREAD thread;
|
||||||
|
ULONG returnLength;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(ThreadInformation, ThreadInformationLength, sizeof(ULONG));
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
ProbeForWrite(ReturnLength, sizeof(ULONG), sizeof(ULONG));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ThreadHandle,
|
||||||
|
THREAD_QUERY_INFORMATION,
|
||||||
|
*PsThreadType,
|
||||||
|
AccessMode,
|
||||||
|
&thread,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
switch (ThreadInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
returnLength = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
|
||||||
|
if (ReturnLength)
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*ReturnLength = returnLength;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
NOTHING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ReturnLength = returnLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets thread information.
|
||||||
|
*
|
||||||
|
* \param ThreadHandle A handle to a thread.
|
||||||
|
* \param ThreadInformationClass The type of information to set.
|
||||||
|
* \param ThreadInformation A buffer which contains the information to set.
|
||||||
|
* \param ThreadInformationLength The number of bytes present in \a ThreadInformation.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiSetInformationThread(
|
||||||
|
__in HANDLE ThreadHandle,
|
||||||
|
__in KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||||
|
__in_bcount(ThreadInformationLength) PVOID ThreadInformation,
|
||||||
|
__in ULONG ThreadInformationLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PETHREAD thread;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForRead(ThreadInformation, ThreadInformationLength, sizeof(ULONG));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ThreadHandle,
|
||||||
|
THREAD_SET_INFORMATION,
|
||||||
|
*PsThreadType,
|
||||||
|
AccessMode,
|
||||||
|
&thread,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
switch (ThreadInformationClass)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
status = STATUS_INVALID_INFO_CLASS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(thread);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
272
KProcessHacker/util.c
Normal file
272
KProcessHacker/util.c
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KphFreeCapturedUnicodeString)
|
||||||
|
#pragma alloc_text(PAGE, KphCaptureUnicodeString)
|
||||||
|
#pragma alloc_text(PAGE, KphEnumerateSystemModules)
|
||||||
|
#pragma alloc_text(PAGE, KphValidateAddressForSystemModules)
|
||||||
|
#pragma alloc_text(PAGE, KphGetProcessMappedFileName)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VOID KphFreeCapturedUnicodeString(
|
||||||
|
__in PUNICODE_STRING CapturedUnicodeString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (CapturedUnicodeString->Buffer)
|
||||||
|
ExFreePoolWithTag(CapturedUnicodeString->Buffer, 'UhpK');
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphCaptureUnicodeString(
|
||||||
|
__in PUNICODE_STRING UnicodeString,
|
||||||
|
__out PUNICODE_STRING CapturedUnicodeString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNICODE_STRING unicodeString;
|
||||||
|
PWCHAR userBuffer;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForRead(UnicodeString, sizeof(UNICODE_STRING), sizeof(ULONG));
|
||||||
|
unicodeString.Length = UnicodeString->Length;
|
||||||
|
unicodeString.MaximumLength = unicodeString.Length;
|
||||||
|
unicodeString.Buffer = NULL;
|
||||||
|
|
||||||
|
userBuffer = UnicodeString->Buffer;
|
||||||
|
ProbeForRead(userBuffer, unicodeString.Length, sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unicodeString.Length & 1)
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unicodeString.Length != 0)
|
||||||
|
{
|
||||||
|
unicodeString.Buffer = ExAllocatePoolWithTag(
|
||||||
|
PagedPool,
|
||||||
|
unicodeString.Length,
|
||||||
|
'UhpK'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!unicodeString.Buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
memcpy(
|
||||||
|
unicodeString.Buffer,
|
||||||
|
userBuffer,
|
||||||
|
unicodeString.Length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
KphFreeCapturedUnicodeString(&unicodeString);
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*CapturedUnicodeString = unicodeString;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates the modules loaded by the kernel.
|
||||||
|
*
|
||||||
|
* \param Modules A variable which receives a pointer to a structure containing information about
|
||||||
|
* the kernel modules. The structure must be freed with the tag 'ThpK'.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphEnumerateSystemModules(
|
||||||
|
__out PRTL_PROCESS_MODULES *Modules
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PVOID buffer;
|
||||||
|
ULONG bufferSize;
|
||||||
|
ULONG attempts;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
bufferSize = 2048;
|
||||||
|
attempts = 8;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buffer = ExAllocatePoolWithTag(PagedPool, bufferSize, 'ThpK');
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ZwQuerySystemInformation(
|
||||||
|
SystemModuleInformation,
|
||||||
|
buffer,
|
||||||
|
bufferSize,
|
||||||
|
&bufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
*Modules = buffer;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePoolWithTag(buffer, 'ThpK');
|
||||||
|
|
||||||
|
if (status != STATUS_INFO_LENGTH_MISMATCH)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (--attempts);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an address range lies within a kernel module.
|
||||||
|
*
|
||||||
|
* \param Address The beginning of the address range.
|
||||||
|
* \param Length The number of bytes in the address range.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphValidateAddressForSystemModules(
|
||||||
|
__in PVOID Address,
|
||||||
|
__in SIZE_T Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PRTL_PROCESS_MODULES modules;
|
||||||
|
ULONG i;
|
||||||
|
BOOLEAN valid;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
status = KphEnumerateSystemModules(&modules);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
valid = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < modules->NumberOfModules; i++)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(ULONG_PTR)Address + Length >= (ULONG_PTR)Address &&
|
||||||
|
(ULONG_PTR)Address >= (ULONG_PTR)modules->Modules[i].ImageBase &&
|
||||||
|
(ULONG_PTR)Address + Length <= (ULONG_PTR)modules->Modules[i].ImageBase + modules->Modules[i].ImageSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
dprintf("Validated address 0x%Ix in %s\n", Address, modules->Modules[i].FullPathName);
|
||||||
|
valid = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePoolWithTag(modules, 'ThpK');
|
||||||
|
|
||||||
|
if (valid)
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
status = STATUS_ACCESS_VIOLATION;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the file name of a mapped section.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process. The handle must have PROCESS_QUERY_INFORMATION
|
||||||
|
* access.
|
||||||
|
* \param BaseAddress The base address of the section view.
|
||||||
|
* \param Modules A variable which receives a pointer to a string containing the file name of the
|
||||||
|
* section. The structure must be freed with the tag 'ThpK'.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphGetProcessMappedFileName(
|
||||||
|
__in HANDLE ProcessHandle,
|
||||||
|
__in PVOID BaseAddress,
|
||||||
|
__out PUNICODE_STRING *FileName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PVOID buffer;
|
||||||
|
SIZE_T bufferSize;
|
||||||
|
SIZE_T returnLength;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
bufferSize = 0x100;
|
||||||
|
buffer = ExAllocatePoolWithTag(PagedPool, bufferSize, 'ThpK');
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
status = ZwQueryVirtualMemory(
|
||||||
|
ProcessHandle,
|
||||||
|
BaseAddress,
|
||||||
|
MemoryMappedFilenameInformation,
|
||||||
|
buffer,
|
||||||
|
bufferSize,
|
||||||
|
&returnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
if (status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(buffer, 'ThpK');
|
||||||
|
bufferSize = returnLength;
|
||||||
|
buffer = ExAllocatePoolWithTag(PagedPool, bufferSize, 'ThpK');
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
status = ZwQueryVirtualMemory(
|
||||||
|
ProcessHandle,
|
||||||
|
BaseAddress,
|
||||||
|
MemoryMappedFilenameInformation,
|
||||||
|
buffer,
|
||||||
|
bufferSize,
|
||||||
|
&returnLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(buffer, 'ThpK');
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*FileName = buffer;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
496
KProcessHacker/verify.c
Normal file
496
KProcessHacker/verify.c
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
|
||||||
|
#define FILE_BUFFER_SIZE (2 * PAGE_SIZE)
|
||||||
|
#define FILE_MAX_SIZE (32 * 1024 * 1024) // 32 MB
|
||||||
|
|
||||||
|
VOID KphpBackoffKey(
|
||||||
|
__in PKPH_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
static UCHAR KphpTrustedPublicKey[] =
|
||||||
|
{
|
||||||
|
0x45, 0x43, 0x53, 0x31, 0x20, 0x00, 0x00, 0x00, 0x5f, 0xe8, 0xab, 0xac, 0x01, 0xad, 0x6b, 0x48,
|
||||||
|
0xfd, 0x84, 0x7f, 0x43, 0x70, 0xb6, 0x57, 0xb0, 0x76, 0xe3, 0x10, 0x07, 0x19, 0xbd, 0x0e, 0xd4,
|
||||||
|
0x10, 0x5c, 0x1f, 0xfc, 0x40, 0x91, 0xb6, 0xed, 0x94, 0x37, 0x76, 0xb7, 0x86, 0x88, 0xf7, 0x34,
|
||||||
|
0x12, 0x91, 0xf6, 0x65, 0x23, 0x58, 0xc9, 0xeb, 0x2f, 0xcb, 0x96, 0x13, 0x8f, 0xca, 0x57, 0x7a,
|
||||||
|
0xd0, 0x7a, 0xbf, 0x22, 0xde, 0xd2, 0x15, 0xfc
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KphHashFile)
|
||||||
|
#pragma alloc_text(PAGE, KphVerifyFile)
|
||||||
|
#pragma alloc_text(PAGE, KphVerifyClient)
|
||||||
|
#pragma alloc_text(PAGE, KpiVerifyClient)
|
||||||
|
#pragma alloc_text(PAGE, KphGenerateKeysClient)
|
||||||
|
#pragma alloc_text(PAGE, KphRetrieveKeyViaApc)
|
||||||
|
#pragma alloc_text(PAGE, KphValidateKey)
|
||||||
|
#pragma alloc_text(PAGE, KphpBackoffKey)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NTSTATUS KphHashFile(
|
||||||
|
__in PUNICODE_STRING FileName,
|
||||||
|
__out PVOID *Hash,
|
||||||
|
__out PULONG HashSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
BCRYPT_ALG_HANDLE hashAlgHandle = NULL;
|
||||||
|
ULONG querySize;
|
||||||
|
ULONG hashObjectSize;
|
||||||
|
ULONG hashSize;
|
||||||
|
PVOID hashObject = NULL;
|
||||||
|
PVOID hash = NULL;
|
||||||
|
BCRYPT_HASH_HANDLE hashHandle = NULL;
|
||||||
|
OBJECT_ATTRIBUTES objectAttributes;
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
HANDLE fileHandle = NULL;
|
||||||
|
FILE_STANDARD_INFORMATION standardInfo;
|
||||||
|
ULONG remainingBytes;
|
||||||
|
ULONG bytesToRead;
|
||||||
|
PVOID buffer = NULL;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Open the hash algorithm and allocate memory for the hash object.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hashAlgHandle, KPH_HASH_ALGORITHM, NULL, 0)))
|
||||||
|
goto CleanupExit;
|
||||||
|
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_OBJECT_LENGTH,
|
||||||
|
(PUCHAR)&hashObjectSize, sizeof(ULONG), &querySize, 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(status = BCryptGetProperty(hashAlgHandle, BCRYPT_HASH_LENGTH, (PUCHAR)&hashSize,
|
||||||
|
sizeof(ULONG), &querySize, 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(hashObject = ExAllocatePoolWithTag(PagedPool, hashObjectSize, 'vhpK')))
|
||||||
|
{
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (!(hash = ExAllocatePoolWithTag(PagedPool, hashSize, 'vhpK')))
|
||||||
|
{
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptCreateHash(hashAlgHandle, &hashHandle, hashObject, hashObjectSize,
|
||||||
|
NULL, 0, 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the file and compute the hash.
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&objectAttributes, FileName, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = ZwCreateFile(&fileHandle, FILE_GENERIC_READ, &objectAttributes,
|
||||||
|
&iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN,
|
||||||
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = ZwQueryInformationFile(fileHandle, &iosb, &standardInfo,
|
||||||
|
sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (standardInfo.EndOfFile.QuadPart <= 0)
|
||||||
|
{
|
||||||
|
status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (standardInfo.EndOfFile.QuadPart > FILE_MAX_SIZE)
|
||||||
|
{
|
||||||
|
status = STATUS_FILE_TOO_LARGE;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(buffer = ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'vhpK')))
|
||||||
|
{
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingBytes = (ULONG)standardInfo.EndOfFile.QuadPart;
|
||||||
|
|
||||||
|
while (remainingBytes != 0)
|
||||||
|
{
|
||||||
|
bytesToRead = FILE_BUFFER_SIZE;
|
||||||
|
if (bytesToRead > remainingBytes)
|
||||||
|
bytesToRead = remainingBytes;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = ZwReadFile(fileHandle, NULL, NULL, NULL, &iosb, buffer, bytesToRead,
|
||||||
|
NULL, NULL)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if ((ULONG)iosb.Information != bytesToRead)
|
||||||
|
{
|
||||||
|
status = STATUS_INTERNAL_ERROR;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptHashData(hashHandle, buffer, bytesToRead, 0)))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
remainingBytes -= bytesToRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptFinishHash(hashHandle, hash, hashSize, 0)))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
*Hash = hash;
|
||||||
|
*HashSize = hashSize;
|
||||||
|
|
||||||
|
hash = NULL; // Don't free this in the cleanup section
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanupExit:
|
||||||
|
if (buffer)
|
||||||
|
ExFreePoolWithTag(buffer, 'vhpK');
|
||||||
|
if (fileHandle)
|
||||||
|
ZwClose(fileHandle);
|
||||||
|
if (hashHandle)
|
||||||
|
BCryptDestroyHash(hashHandle);
|
||||||
|
if (hash)
|
||||||
|
ExFreePoolWithTag(hash, 'vhpK');
|
||||||
|
if (hashObject)
|
||||||
|
ExFreePoolWithTag(hashObject, 'vhpK');
|
||||||
|
if (hashAlgHandle)
|
||||||
|
BCryptCloseAlgorithmProvider(hashAlgHandle, 0);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphVerifyFile(
|
||||||
|
__in PUNICODE_STRING FileName,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
BCRYPT_ALG_HANDLE signAlgHandle = NULL;
|
||||||
|
BCRYPT_KEY_HANDLE keyHandle = NULL;
|
||||||
|
PVOID hash = NULL;
|
||||||
|
ULONG hashSize;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Import the trusted public key.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&signAlgHandle, KPH_SIGN_ALGORITHM, NULL, 0)))
|
||||||
|
goto CleanupExit;
|
||||||
|
if (!NT_SUCCESS(status = BCryptImportKeyPair(signAlgHandle, NULL, KPH_BLOB_PUBLIC, &keyHandle,
|
||||||
|
KphpTrustedPublicKey, sizeof(KphpTrustedPublicKey), 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the file.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = KphHashFile(FileName, &hash, &hashSize)))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
// Verify the hash.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = BCryptVerifySignature(keyHandle, NULL, hash, hashSize, Signature,
|
||||||
|
SignatureSize, 0)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanupExit:
|
||||||
|
if (hash)
|
||||||
|
ExFreePoolWithTag(hash, 'vhpK');
|
||||||
|
if (keyHandle)
|
||||||
|
BCryptDestroyKey(keyHandle);
|
||||||
|
if (signAlgHandle)
|
||||||
|
BCryptCloseAlgorithmProvider(signAlgHandle, 0);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KphVerifyClient(
|
||||||
|
__inout PKPH_CLIENT Client,
|
||||||
|
__in PVOID CodeAddress,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PUNICODE_STRING processFileName = NULL;
|
||||||
|
MEMORY_BASIC_INFORMATION memoryBasicInfo;
|
||||||
|
PUNICODE_STRING mappedFileName = NULL;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (Client->VerificationPerformed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((ULONG_PTR)CodeAddress > (ULONG_PTR)MmHighestUserAddress)
|
||||||
|
{
|
||||||
|
status = STATUS_ACCESS_VIOLATION;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(status = SeLocateProcessImageName(PsGetCurrentProcess(), &processFileName)))
|
||||||
|
goto CleanupExit;
|
||||||
|
if (!NT_SUCCESS(status = ZwQueryVirtualMemory(NtCurrentProcess(), CodeAddress,
|
||||||
|
MemoryBasicInformation, &memoryBasicInfo, sizeof(MEMORY_BASIC_INFORMATION), NULL)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (memoryBasicInfo.Type != MEM_IMAGE || memoryBasicInfo.State != MEM_COMMIT)
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(status = KphGetProcessMappedFileName(NtCurrentProcess(), CodeAddress,
|
||||||
|
&mappedFileName)))
|
||||||
|
{
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
if (!RtlEqualUnicodeString(processFileName, mappedFileName, TRUE))
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto CleanupExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = KphVerifyFile(processFileName, Signature, SignatureSize);
|
||||||
|
|
||||||
|
CleanupExit:
|
||||||
|
if (mappedFileName)
|
||||||
|
ExFreePoolWithTag(mappedFileName, 'ThpK');
|
||||||
|
if (processFileName)
|
||||||
|
ExFreePool(processFileName);
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&Client->StateMutex);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
Client->VerifiedProcess = PsGetCurrentProcess();
|
||||||
|
Client->VerifiedProcessId = PsGetCurrentProcessId();
|
||||||
|
Client->VerifiedRangeBase = memoryBasicInfo.BaseAddress;
|
||||||
|
Client->VerifiedRangeSize = memoryBasicInfo.RegionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client->VerificationStatus = status;
|
||||||
|
MemoryBarrier();
|
||||||
|
Client->VerificationSucceeded = NT_SUCCESS(status);
|
||||||
|
Client->VerificationPerformed = TRUE;
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&Client->StateMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KpiVerifyClient(
|
||||||
|
__in PVOID CodeAddress,
|
||||||
|
__in_bcount(SignatureSize) PUCHAR Signature,
|
||||||
|
__in ULONG SignatureSize,
|
||||||
|
__in PKPH_CLIENT Client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PUCHAR signature;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForRead(Signature, SignatureSize, 1);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SignatureSize > KPH_SIGNATURE_MAX_SIZE)
|
||||||
|
return STATUS_INVALID_PARAMETER_3;
|
||||||
|
|
||||||
|
signature = ExAllocatePoolWithTag(PagedPool, SignatureSize, 'ThpK');
|
||||||
|
if (!signature)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
memcpy(signature, Signature, SignatureSize);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(signature, 'ThpK');
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
KphVerifyClient(Client, CodeAddress, Signature, SignatureSize);
|
||||||
|
ExFreePoolWithTag(signature, 'ThpK');
|
||||||
|
|
||||||
|
return Client->VerificationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KphGenerateKeysClient(
|
||||||
|
__inout PKPH_CLIENT Client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONGLONG interruptTime;
|
||||||
|
ULONG seed;
|
||||||
|
KPH_KEY l1Key;
|
||||||
|
KPH_KEY l2Key;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (Client->KeysGenerated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
interruptTime = KeQueryInterruptTime();
|
||||||
|
seed = (ULONG)(interruptTime >> 32) | (ULONG)interruptTime | PtrToUlong(Client);
|
||||||
|
l1Key = RtlRandomEx(&seed) | 0x80000000; // Make sure the key is nonzero
|
||||||
|
do
|
||||||
|
{
|
||||||
|
l2Key = RtlRandomEx(&seed) | 0x80000000;
|
||||||
|
} while (l2Key == l1Key);
|
||||||
|
|
||||||
|
ExAcquireFastMutex(&Client->StateMutex);
|
||||||
|
|
||||||
|
if (!Client->KeysGenerated)
|
||||||
|
{
|
||||||
|
Client->L1Key = l1Key;
|
||||||
|
Client->L2Key = l2Key;
|
||||||
|
MemoryBarrier();
|
||||||
|
Client->KeysGenerated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&Client->StateMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphRetrieveKeyViaApc(
|
||||||
|
__inout PKPH_CLIENT Client,
|
||||||
|
__in KPH_KEY_LEVEL KeyLevel,
|
||||||
|
__inout PIRP Irp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PIO_APC_ROUTINE userApcRoutine;
|
||||||
|
KPH_KEY key;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (!Client->VerificationSucceeded)
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
MemoryBarrier();
|
||||||
|
|
||||||
|
if (PsGetCurrentProcess() != Client->VerifiedProcess ||
|
||||||
|
PsGetCurrentProcessId() != Client->VerifiedProcessId)
|
||||||
|
{
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
userApcRoutine = Irp->Overlay.AsynchronousParameters.UserApcRoutine;
|
||||||
|
|
||||||
|
if (!userApcRoutine)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if ((ULONG_PTR)userApcRoutine < (ULONG_PTR)Client->VerifiedRangeBase ||
|
||||||
|
(ULONG_PTR)userApcRoutine >= (ULONG_PTR)Client->VerifiedRangeBase + Client->VerifiedRangeSize)
|
||||||
|
{
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
KphGenerateKeysClient(Client);
|
||||||
|
|
||||||
|
switch (KeyLevel)
|
||||||
|
{
|
||||||
|
case KphKeyLevel1:
|
||||||
|
key = Client->L1Key;
|
||||||
|
break;
|
||||||
|
case KphKeyLevel2:
|
||||||
|
key = Client->L2Key;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->Overlay.AsynchronousParameters.UserApcContext = UlongToPtr(key);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS KphValidateKey(
|
||||||
|
__in KPH_KEY_LEVEL RequiredKeyLevel,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (AccessMode == KernelMode)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (Key && Client->VerificationSucceeded && Client->KeysGenerated)
|
||||||
|
{
|
||||||
|
MemoryBarrier();
|
||||||
|
|
||||||
|
switch (RequiredKeyLevel)
|
||||||
|
{
|
||||||
|
case KphKeyLevel1:
|
||||||
|
if (Key == Client->L1Key || Key == Client->L2Key)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
KphpBackoffKey(Client);
|
||||||
|
break;
|
||||||
|
case KphKeyLevel2:
|
||||||
|
if (Key == Client->L2Key)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
KphpBackoffKey(Client);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID KphpBackoffKey(
|
||||||
|
__in PKPH_CLIENT Client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER backoffTime;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
// Serialize to make it impossible for a single client to bypass the backoff by creating
|
||||||
|
// multiple threads.
|
||||||
|
ExAcquireFastMutex(&Client->KeyBackoffMutex);
|
||||||
|
|
||||||
|
backoffTime.QuadPart = -KPH_KEY_BACKOFF_TIME;
|
||||||
|
KeDelayExecutionThread(KernelMode, FALSE, &backoffTime);
|
||||||
|
|
||||||
|
ExReleaseFastMutex(&Client->KeyBackoffMutex);
|
||||||
|
}
|
449
KProcessHacker/vm.c
Normal file
449
KProcessHacker/vm.c
Normal file
@ -0,0 +1,449 @@
|
|||||||
|
/*
|
||||||
|
* KProcessHacker
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kph.h>
|
||||||
|
|
||||||
|
ULONG KphpGetCopyExceptionInfo(
|
||||||
|
__in PEXCEPTION_POINTERS ExceptionInfo,
|
||||||
|
__out PBOOLEAN HaveBadAddress,
|
||||||
|
__out PULONG_PTR BadAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, KphCopyVirtualMemory)
|
||||||
|
#pragma alloc_text(PAGE, KpiReadVirtualMemoryUnsafe)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KPH_STACK_COPY_BYTES 0x200
|
||||||
|
#define KPH_POOL_COPY_BYTES 0x10000
|
||||||
|
#define KPH_MAPPED_COPY_PAGES 14
|
||||||
|
#define KPH_POOL_COPY_THRESHOLD 0x3ff
|
||||||
|
|
||||||
|
ULONG KphpGetCopyExceptionInfo(
|
||||||
|
__in PEXCEPTION_POINTERS ExceptionInfo,
|
||||||
|
__out PBOOLEAN HaveBadAddress,
|
||||||
|
__out PULONG_PTR BadAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PEXCEPTION_RECORD exceptionRecord;
|
||||||
|
|
||||||
|
*HaveBadAddress = FALSE;
|
||||||
|
exceptionRecord = ExceptionInfo->ExceptionRecord;
|
||||||
|
|
||||||
|
if ((exceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) ||
|
||||||
|
(exceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) ||
|
||||||
|
(exceptionRecord->ExceptionCode == STATUS_IN_PAGE_ERROR))
|
||||||
|
{
|
||||||
|
if (exceptionRecord->NumberParameters > 1)
|
||||||
|
{
|
||||||
|
/* We have the address. */
|
||||||
|
*HaveBadAddress = TRUE;
|
||||||
|
*BadAddress = exceptionRecord->ExceptionInformation[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies memory from one process to another.
|
||||||
|
*
|
||||||
|
* \param FromProcess The source process.
|
||||||
|
* \param FromAddress The source address.
|
||||||
|
* \param ToProcess The target process.
|
||||||
|
* \param ToAddress The target address.
|
||||||
|
* \param BufferLength The number of bytes to copy.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
* \param ReturnLength A variable which receives the number of bytes copied.
|
||||||
|
*/
|
||||||
|
NTSTATUS KphCopyVirtualMemory(
|
||||||
|
__in PEPROCESS FromProcess,
|
||||||
|
__in PVOID FromAddress,
|
||||||
|
__in PEPROCESS ToProcess,
|
||||||
|
__in PVOID ToAddress,
|
||||||
|
__in SIZE_T BufferLength,
|
||||||
|
__in KPROCESSOR_MODE AccessMode,
|
||||||
|
__out PSIZE_T ReturnLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UCHAR stackBuffer[KPH_STACK_COPY_BYTES];
|
||||||
|
PVOID buffer;
|
||||||
|
PFN_NUMBER mdlBuffer[(sizeof(MDL) / sizeof(PFN_NUMBER)) + KPH_MAPPED_COPY_PAGES + 1];
|
||||||
|
PMDL mdl = (PMDL)mdlBuffer;
|
||||||
|
PVOID mappedAddress;
|
||||||
|
SIZE_T mappedTotalSize;
|
||||||
|
SIZE_T blockSize;
|
||||||
|
SIZE_T stillToCopy;
|
||||||
|
KAPC_STATE apcState;
|
||||||
|
PVOID sourceAddress;
|
||||||
|
PVOID targetAddress;
|
||||||
|
BOOLEAN doMappedCopy;
|
||||||
|
BOOLEAN pagesLocked;
|
||||||
|
BOOLEAN copyingToTarget = FALSE;
|
||||||
|
BOOLEAN probing = FALSE;
|
||||||
|
BOOLEAN mapping = FALSE;
|
||||||
|
BOOLEAN haveBadAddress;
|
||||||
|
ULONG_PTR badAddress;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
sourceAddress = FromAddress;
|
||||||
|
targetAddress = ToAddress;
|
||||||
|
|
||||||
|
// We don't check if buffer == NULL when freeing. If buffer doesn't need to be freed, set to
|
||||||
|
// stackBuffer, not NULL.
|
||||||
|
buffer = stackBuffer;
|
||||||
|
|
||||||
|
mappedTotalSize = (KPH_MAPPED_COPY_PAGES - 2) * PAGE_SIZE;
|
||||||
|
|
||||||
|
if (mappedTotalSize > BufferLength)
|
||||||
|
mappedTotalSize = BufferLength;
|
||||||
|
|
||||||
|
stillToCopy = BufferLength;
|
||||||
|
blockSize = mappedTotalSize;
|
||||||
|
|
||||||
|
while (stillToCopy)
|
||||||
|
{
|
||||||
|
// If we're at the last copy block, copy the remaining bytes instead of the whole block
|
||||||
|
// size.
|
||||||
|
if (blockSize > stillToCopy)
|
||||||
|
blockSize = stillToCopy;
|
||||||
|
|
||||||
|
// Choose the best method based on the number of bytes left to copy.
|
||||||
|
if (blockSize > KPH_POOL_COPY_THRESHOLD)
|
||||||
|
{
|
||||||
|
doMappedCopy = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doMappedCopy = FALSE;
|
||||||
|
|
||||||
|
if (blockSize <= KPH_STACK_COPY_BYTES)
|
||||||
|
{
|
||||||
|
if (buffer != stackBuffer)
|
||||||
|
ExFreePoolWithTag(buffer, 'ChpK');
|
||||||
|
|
||||||
|
buffer = stackBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't allocate the buffer if we've done so already. Note that the block size
|
||||||
|
// never increases, so this allocation will always be OK.
|
||||||
|
if (buffer == stackBuffer)
|
||||||
|
{
|
||||||
|
// Keep trying to allocate a buffer.
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
buffer = ExAllocatePoolWithTag(NonPagedPool, blockSize, 'ChpK');
|
||||||
|
|
||||||
|
// Stop trying if we got a buffer.
|
||||||
|
if (buffer)
|
||||||
|
break;
|
||||||
|
|
||||||
|
blockSize /= 2;
|
||||||
|
|
||||||
|
// Use the stack buffer if we can.
|
||||||
|
if (blockSize <= KPH_STACK_COPY_BYTES)
|
||||||
|
{
|
||||||
|
buffer = stackBuffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset state.
|
||||||
|
mappedAddress = NULL;
|
||||||
|
pagesLocked = FALSE;
|
||||||
|
copyingToTarget = FALSE;
|
||||||
|
|
||||||
|
KeStackAttachProcess(FromProcess, &apcState);
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
// Probe only if this is the first time.
|
||||||
|
if (sourceAddress == FromAddress && AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
probing = TRUE;
|
||||||
|
ProbeForRead(sourceAddress, BufferLength, sizeof(UCHAR));
|
||||||
|
probing = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doMappedCopy)
|
||||||
|
{
|
||||||
|
// Initialize the MDL.
|
||||||
|
MmInitializeMdl(mdl, sourceAddress, blockSize);
|
||||||
|
MmProbeAndLockPages(mdl, AccessMode, IoReadAccess);
|
||||||
|
pagesLocked = TRUE;
|
||||||
|
|
||||||
|
// Map the pages.
|
||||||
|
mappedAddress = MmMapLockedPagesSpecifyCache(
|
||||||
|
mdl,
|
||||||
|
KernelMode,
|
||||||
|
MmCached,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
HighPagePriority
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!mappedAddress)
|
||||||
|
{
|
||||||
|
// Insufficient resources; exit.
|
||||||
|
mapping = TRUE;
|
||||||
|
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(buffer, sourceAddress, blockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeUnstackDetachProcess(&apcState);
|
||||||
|
|
||||||
|
// Attach to the target process and copy the contents out.
|
||||||
|
KeStackAttachProcess(ToProcess, &apcState);
|
||||||
|
|
||||||
|
// Probe only if this is the first time.
|
||||||
|
if (targetAddress == ToAddress && AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
probing = TRUE;
|
||||||
|
ProbeForWrite(targetAddress, BufferLength, sizeof(UCHAR));
|
||||||
|
probing = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the data.
|
||||||
|
copyingToTarget = TRUE;
|
||||||
|
|
||||||
|
if (doMappedCopy)
|
||||||
|
memcpy(targetAddress, mappedAddress, blockSize);
|
||||||
|
else
|
||||||
|
memcpy(targetAddress, buffer, blockSize);
|
||||||
|
}
|
||||||
|
__except (KphpGetCopyExceptionInfo(
|
||||||
|
GetExceptionInformation(),
|
||||||
|
&haveBadAddress,
|
||||||
|
&badAddress
|
||||||
|
))
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&apcState);
|
||||||
|
|
||||||
|
// If we mapped the pages, unmap them.
|
||||||
|
if (mappedAddress)
|
||||||
|
MmUnmapLockedPages(mappedAddress, mdl);
|
||||||
|
|
||||||
|
// If we locked the pages, unlock them.
|
||||||
|
if (pagesLocked)
|
||||||
|
MmUnlockPages(mdl);
|
||||||
|
|
||||||
|
// If we allocated pool storage, free it.
|
||||||
|
if (buffer != stackBuffer)
|
||||||
|
ExFreePoolWithTag(buffer, 'ChpK');
|
||||||
|
|
||||||
|
// If we failed when probing or mapping, return the error status.
|
||||||
|
if (probing || mapping)
|
||||||
|
return GetExceptionCode();
|
||||||
|
|
||||||
|
// Determine which copy failed.
|
||||||
|
if (copyingToTarget && haveBadAddress)
|
||||||
|
{
|
||||||
|
*ReturnLength = (ULONG)(badAddress - (ULONG_PTR)sourceAddress);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ReturnLength = BufferLength - stillToCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_PARTIAL_COPY;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeUnstackDetachProcess(&apcState);
|
||||||
|
|
||||||
|
if (doMappedCopy)
|
||||||
|
{
|
||||||
|
MmUnmapLockedPages(mappedAddress, mdl);
|
||||||
|
MmUnlockPages(mdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
stillToCopy -= blockSize;
|
||||||
|
sourceAddress = (PVOID)((ULONG_PTR)sourceAddress + blockSize);
|
||||||
|
targetAddress = (PVOID)((ULONG_PTR)targetAddress + blockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != stackBuffer)
|
||||||
|
ExFreePoolWithTag(buffer, 'ChpK');
|
||||||
|
|
||||||
|
*ReturnLength = BufferLength;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies process or kernel memory into the current process.
|
||||||
|
*
|
||||||
|
* \param ProcessHandle A handle to a process. The handle must have PROCESS_VM_READ access. This
|
||||||
|
* parameter may be NULL if \a BaseAddress lies above the user-mode range.
|
||||||
|
* \param BaseAddress The address from which memory is to be copied.
|
||||||
|
* \param Buffer A buffer which receives the copied memory.
|
||||||
|
* \param BufferSize The number of bytes to copy.
|
||||||
|
* \param NumberOfBytesRead A variable which receives the number of bytes copied to the buffer.
|
||||||
|
* \param Key An access key. If no valid L2 key is provided, the function fails.
|
||||||
|
* \param Client The client that initiated the request.
|
||||||
|
* \param AccessMode The mode in which to perform access checks.
|
||||||
|
*/
|
||||||
|
NTSTATUS KpiReadVirtualMemoryUnsafe(
|
||||||
|
__in_opt HANDLE ProcessHandle,
|
||||||
|
__in PVOID BaseAddress,
|
||||||
|
__out_bcount(BufferSize) PVOID Buffer,
|
||||||
|
__in SIZE_T BufferSize,
|
||||||
|
__out_opt PSIZE_T NumberOfBytesRead,
|
||||||
|
__in_opt KPH_KEY Key,
|
||||||
|
__in PKPH_CLIENT Client,
|
||||||
|
__in KPROCESSOR_MODE AccessMode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PEPROCESS process;
|
||||||
|
SIZE_T numberOfBytesRead;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = KphValidateKey(KphKeyLevel2, Key, Client, AccessMode)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(ULONG_PTR)BaseAddress + BufferSize < (ULONG_PTR)BaseAddress ||
|
||||||
|
(ULONG_PTR)Buffer + BufferSize < (ULONG_PTR)Buffer ||
|
||||||
|
(ULONG_PTR)Buffer + BufferSize > (ULONG_PTR)MmHighestUserAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return STATUS_ACCESS_VIOLATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumberOfBytesRead)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
ProbeForWrite(NumberOfBytesRead, sizeof(SIZE_T), sizeof(SIZE_T));
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BufferSize != 0)
|
||||||
|
{
|
||||||
|
// Select the appropriate copy method.
|
||||||
|
if ((ULONG_PTR)BaseAddress + BufferSize > (ULONG_PTR)MmHighestUserAddress)
|
||||||
|
{
|
||||||
|
ULONG_PTR page;
|
||||||
|
ULONG_PTR pageEnd;
|
||||||
|
|
||||||
|
status = KphValidateAddressForSystemModules(BaseAddress, BufferSize);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Kernel memory copy (unsafe)
|
||||||
|
|
||||||
|
page = (ULONG_PTR)BaseAddress & ~(PAGE_SIZE - 1);
|
||||||
|
pageEnd = ((ULONG_PTR)BaseAddress + BufferSize - 1) & ~(PAGE_SIZE - 1);
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
// This will obviously fail if any of the pages aren't resident.
|
||||||
|
for (; page <= pageEnd; page += PAGE_SIZE)
|
||||||
|
{
|
||||||
|
if (!MmIsAddressValid((PVOID)page))
|
||||||
|
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(Buffer, BaseAddress, BufferSize);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return GetExceptionCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
numberOfBytesRead = BufferSize;
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// User memory copy (safe)
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
ProcessHandle,
|
||||||
|
PROCESS_VM_READ,
|
||||||
|
*PsProcessType,
|
||||||
|
AccessMode,
|
||||||
|
&process,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
status = KphCopyVirtualMemory(
|
||||||
|
process,
|
||||||
|
BaseAddress,
|
||||||
|
PsGetCurrentProcess(),
|
||||||
|
Buffer,
|
||||||
|
BufferSize,
|
||||||
|
AccessMode,
|
||||||
|
&numberOfBytesRead
|
||||||
|
);
|
||||||
|
ObDereferenceObject(process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numberOfBytesRead = 0;
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumberOfBytesRead)
|
||||||
|
{
|
||||||
|
if (AccessMode != KernelMode)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
*NumberOfBytesRead = numberOfBytesRead;
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
// Don't mess with the status.
|
||||||
|
NOTHING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*NumberOfBytesRead = numberOfBytesRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
685
LICENSE.txt
Normal file
685
LICENSE.txt
Normal file
@ -0,0 +1,685 @@
|
|||||||
|
Process Hacker is distributed under the GNU GPL version 3, with the
|
||||||
|
following exception:
|
||||||
|
|
||||||
|
Permission is granted to dynamically (but not statically) link this
|
||||||
|
program with independent modules, regardless of the license terms of
|
||||||
|
these independent modules, provided that this program is not modified
|
||||||
|
in any way. An independent module is a module which is not derived
|
||||||
|
from or based on this program. If you modify this program, this
|
||||||
|
additional permission no longer applies unless authorized by the
|
||||||
|
copyright holders.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
81
ProcessHacker.sln
Normal file
81
ProcessHacker.sln
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.24720.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2758DC86-368B-430C-9D29-F1EF20032A71}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProcessHacker", "ProcessHacker\ProcessHacker.vcxproj", "{0271DD27-6707-4290-8DFE-285702B7115D}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17} = {477D0215-F252-41A1-874B-F27E3EA1ED17}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "phlib", "phlib\phlib.vcxproj", "{477D0215-F252-41A1-874B-F27E3EA1ED17}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fixlib", "tools\fixlib\fixlib.vcxproj", "{31F4AA06-7ED5-4A6D-B901-19AD4BD16175}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peview", "tools\peview\peview.vcxproj", "{72C124A2-3C80-41C6-ABA1-C4948B713204}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FD3C278D-BD40-4551-AE67-4DE196F8D7F6}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "phlib-test", "tests\phlib-test\phlib-test.vcxproj", "{0C21014E-BC90-4AE5-AA32-398445C13B28}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomSignTool", "tools\CustomSignTool\CustomSignTool.vcxproj", "{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{0271DD27-6707-4290-8DFE-285702B7115D}.Release|x64.Build.0 = Release|x64
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{477D0215-F252-41A1-874B-F27E3EA1ED17}.Release|x64.Build.0 = Release|x64
|
||||||
|
{31F4AA06-7ED5-4A6D-B901-19AD4BD16175}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{31F4AA06-7ED5-4A6D-B901-19AD4BD16175}.Debug|x64.ActiveCfg = Debug|Win32
|
||||||
|
{31F4AA06-7ED5-4A6D-B901-19AD4BD16175}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{31F4AA06-7ED5-4A6D-B901-19AD4BD16175}.Release|x64.ActiveCfg = Release|Win32
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204}.Release|x64.Build.0 = Release|x64
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Debug|x64.ActiveCfg = Debug|Win32
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28}.Release|x64.ActiveCfg = Release|Win32
|
||||||
|
{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{E8CD0A41-1537-4EA6-98AC-E80CD59C478E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{31F4AA06-7ED5-4A6D-B901-19AD4BD16175} = {2758DC86-368B-430C-9D29-F1EF20032A71}
|
||||||
|
{72C124A2-3C80-41C6-ABA1-C4948B713204} = {2758DC86-368B-430C-9D29-F1EF20032A71}
|
||||||
|
{0C21014E-BC90-4AE5-AA32-398445C13B28} = {FD3C278D-BD40-4551-AE67-4DE196F8D7F6}
|
||||||
|
{E8CD0A41-1537-4EA6-98AC-E80CD59C478E} = {2758DC86-368B-430C-9D29-F1EF20032A71}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
569
ProcessHacker/ProcessHacker.def
Normal file
569
ProcessHacker/ProcessHacker.def
Normal file
@ -0,0 +1,569 @@
|
|||||||
|
EXPORTS
|
||||||
|
|
||||||
|
;
|
||||||
|
; phlib exports
|
||||||
|
;
|
||||||
|
|
||||||
|
; ref
|
||||||
|
PhAutoDereferenceObject
|
||||||
|
PhCreateAlloc
|
||||||
|
PhCreateObject
|
||||||
|
PhCreateObjectType
|
||||||
|
PhCreateObjectTypeEx
|
||||||
|
PhDeleteAutoPool
|
||||||
|
PhDereferenceObject
|
||||||
|
PhDereferenceObjectDeferDelete
|
||||||
|
PhDereferenceObjectEx
|
||||||
|
PhDrainAutoPool
|
||||||
|
PhGetObjectType
|
||||||
|
PhGetObjectTypeInformation
|
||||||
|
PhInitializeAutoPool
|
||||||
|
PhReferenceObject
|
||||||
|
PhReferenceObjectEx
|
||||||
|
PhReferenceObjectSafe
|
||||||
|
|
||||||
|
; queuedlock
|
||||||
|
PhfAcquireQueuedLockExclusive
|
||||||
|
PhfAcquireQueuedLockShared
|
||||||
|
PhfPulseAllCondition
|
||||||
|
PhfPulseCondition
|
||||||
|
PhfQueueWakeEvent
|
||||||
|
PhfReleaseQueuedLockExclusive
|
||||||
|
PhfReleaseQueuedLockShared
|
||||||
|
PhfSetWakeEvent
|
||||||
|
PhfWaitForCondition
|
||||||
|
PhfWaitForConditionEx
|
||||||
|
PhfWaitForWakeEvent
|
||||||
|
PhfWakeForReleaseQueuedLock
|
||||||
|
|
||||||
|
; phconfig
|
||||||
|
PhGlobalDpi DATA
|
||||||
|
PhHeapHandle DATA
|
||||||
|
PhIsExecutingInWow64
|
||||||
|
PhLibImageBase DATA
|
||||||
|
PhOsVersion DATA
|
||||||
|
PhSystemBasicInformation DATA
|
||||||
|
ProcessAllAccess DATA
|
||||||
|
ProcessQueryAccess DATA
|
||||||
|
ThreadAllAccess DATA
|
||||||
|
ThreadQueryAccess DATA
|
||||||
|
ThreadSetAccess DATA
|
||||||
|
WindowsVersion DATA
|
||||||
|
|
||||||
|
; phbasesup
|
||||||
|
PhAddElementAvlTree
|
||||||
|
PhAddEntryHashtable
|
||||||
|
PhAddEntryHashtableEx
|
||||||
|
PhAddItemArray
|
||||||
|
PhAddItemList
|
||||||
|
PhAddItemPointerList
|
||||||
|
PhAddItemsArray
|
||||||
|
PhAddItemSimpleHashtable
|
||||||
|
PhAddItemsList
|
||||||
|
PhAllocate
|
||||||
|
PhAllocateExSafe
|
||||||
|
PhAllocateFromFreeList
|
||||||
|
PhAllocatePage
|
||||||
|
PhAllocateSafe
|
||||||
|
PhAppendBytesBuilder
|
||||||
|
PhAppendBytesBuilder2
|
||||||
|
PhAppendBytesBuilderEx
|
||||||
|
PhAppendCharStringBuilder
|
||||||
|
PhAppendCharStringBuilder2
|
||||||
|
PhAppendFormatStringBuilder
|
||||||
|
PhAppendFormatStringBuilder_V
|
||||||
|
PhAppendStringBuilder
|
||||||
|
PhAppendStringBuilder2
|
||||||
|
PhAppendStringBuilderEx
|
||||||
|
PhBufferToHexString
|
||||||
|
PhBufferToHexStringEx
|
||||||
|
PhClearArray
|
||||||
|
PhClearHashtable
|
||||||
|
PhClearList
|
||||||
|
PhCompareStringRef
|
||||||
|
PhCompareStringZNatural
|
||||||
|
PhConcatStringRef2
|
||||||
|
PhConcatStringRef3
|
||||||
|
PhConcatStrings
|
||||||
|
PhConcatStrings_V
|
||||||
|
PhConcatStrings2
|
||||||
|
PhConvertMultiByteToUtf16
|
||||||
|
PhConvertMultiByteToUtf16Ex
|
||||||
|
PhConvertUtf16ToAsciiEx
|
||||||
|
PhConvertUtf16ToMultiByte
|
||||||
|
PhConvertUtf16ToMultiByteEx
|
||||||
|
PhConvertUtf16ToUtf8
|
||||||
|
PhConvertUtf16ToUtf8Buffer
|
||||||
|
PhConvertUtf16ToUtf8Ex
|
||||||
|
PhConvertUtf16ToUtf8Size
|
||||||
|
PhConvertUtf8ToUtf16
|
||||||
|
PhConvertUtf8ToUtf16Buffer
|
||||||
|
PhConvertUtf8ToUtf16Ex
|
||||||
|
PhConvertUtf8ToUtf16Size
|
||||||
|
PhCopyBytesZ
|
||||||
|
PhCopyStringZ
|
||||||
|
PhCopyStringZFromBytes
|
||||||
|
PhCopyStringZFromMultiByte
|
||||||
|
PhCountStringZ
|
||||||
|
PhCreateBytes
|
||||||
|
PhCreateBytesEx
|
||||||
|
PhCreateHashtable
|
||||||
|
PhCreateList
|
||||||
|
PhCreatePointerList
|
||||||
|
PhCreateSimpleHashtable
|
||||||
|
PhCreateString
|
||||||
|
PhCreateStringEx
|
||||||
|
PhCreateThread
|
||||||
|
PhDecodeUnicodeDecoder
|
||||||
|
PhDeleteArray
|
||||||
|
PhDeleteBytesBuilder
|
||||||
|
PhDeleteCallback
|
||||||
|
PhDeleteFreeList
|
||||||
|
PhDeleteStringBuilder
|
||||||
|
PhDivideSinglesBySingle
|
||||||
|
PhDosErrorToNtStatus
|
||||||
|
PhDuplicateBytesZ
|
||||||
|
PhDuplicateBytesZSafe
|
||||||
|
PhDuplicateStringZ
|
||||||
|
PhEncodeUnicode
|
||||||
|
PhEnumAvlTree
|
||||||
|
PhEnumHashtable
|
||||||
|
PhEnumPointerListEx
|
||||||
|
PhEqualStringRef
|
||||||
|
PhExponentiate
|
||||||
|
PhExponentiate64
|
||||||
|
PhfAcquireRundownProtection
|
||||||
|
PhfBeginInitOnce
|
||||||
|
PhfEndInitOnce
|
||||||
|
PhFillMemoryUlong
|
||||||
|
PhFinalArrayItems
|
||||||
|
PhFinalBytesBuilderBytes
|
||||||
|
PhFinalStringBuilderString
|
||||||
|
PhFindCharInStringRef
|
||||||
|
PhFindElementAvlTree
|
||||||
|
PhFindEntryHashtable
|
||||||
|
PhFindItemList
|
||||||
|
PhFindItemPointerList
|
||||||
|
PhFindItemSimpleHashtable
|
||||||
|
PhFindLastCharInStringRef
|
||||||
|
PhFindStringInStringRef
|
||||||
|
PhfInitializeBarrier
|
||||||
|
PhfInitializeEvent
|
||||||
|
PhfInitializeInitOnce
|
||||||
|
PhfInitializeRundownProtection
|
||||||
|
PhFormat
|
||||||
|
PhFormatString
|
||||||
|
PhFormatString_V
|
||||||
|
PhFormatToBuffer
|
||||||
|
PhFree
|
||||||
|
PhFreePage
|
||||||
|
PhFreeToFreeList
|
||||||
|
PhfReleaseRundownProtection
|
||||||
|
PhfResetEvent
|
||||||
|
PhfSetEvent
|
||||||
|
PhfWaitForBarrier
|
||||||
|
PhfWaitForEvent
|
||||||
|
PhfWaitForRundownProtection
|
||||||
|
PhGetPrimeNumber
|
||||||
|
PhHashBytes
|
||||||
|
PhHashStringRef
|
||||||
|
PhHexStringToBuffer
|
||||||
|
PhInitializeArray
|
||||||
|
PhInitializeAvlTree
|
||||||
|
PhInitializeBytesBuilder
|
||||||
|
PhInitializeCallback
|
||||||
|
PhInitializeFreeList
|
||||||
|
PhInitializeStringBuilder
|
||||||
|
PhInsertItemList
|
||||||
|
PhInsertItemsList
|
||||||
|
PhInsertStringBuilder
|
||||||
|
PhInsertStringBuilder2
|
||||||
|
PhInsertStringBuilderEx
|
||||||
|
PhIntegerToString64
|
||||||
|
PhInvokeCallback
|
||||||
|
PhLocalTimeToSystemTime
|
||||||
|
PhLowerBoundElementAvlTree
|
||||||
|
PhLowerDualBoundElementAvlTree
|
||||||
|
PhMaximumElementAvlTree
|
||||||
|
PhMinimumElementAvlTree
|
||||||
|
PhNtStatusFileNotFound
|
||||||
|
PhNtStatusToDosError
|
||||||
|
PhPredecessorElementAvlTree
|
||||||
|
PhPrintTimeSpan
|
||||||
|
PhQuerySystemTime
|
||||||
|
PhQueryTimeZoneBias
|
||||||
|
PhReAllocate
|
||||||
|
PhReAllocateSafe
|
||||||
|
PhReferenceEmptyString
|
||||||
|
PhRegisterCallback
|
||||||
|
PhRegisterCallbackEx
|
||||||
|
PhRemoveElementAvlTree
|
||||||
|
PhRemoveEntryHashtable
|
||||||
|
PhRemoveItemArray
|
||||||
|
PhRemoveItemList
|
||||||
|
PhRemoveItemPointerList
|
||||||
|
PhRemoveItemsArray
|
||||||
|
PhRemoveItemSimpleHashtable
|
||||||
|
PhRemoveItemsList
|
||||||
|
PhRemoveStringBuilder
|
||||||
|
PhResizeArray
|
||||||
|
PhResizeList
|
||||||
|
PhRoundUpToPowerOfTwo
|
||||||
|
PhSplitStringRefAtChar
|
||||||
|
PhSplitStringRefAtLastChar
|
||||||
|
PhSplitStringRefAtString
|
||||||
|
PhSplitStringRefEx
|
||||||
|
PhStringToDouble
|
||||||
|
PhStringToInteger64
|
||||||
|
PhSuccessorElementAvlTree
|
||||||
|
PhSystemTimeToLocalTime
|
||||||
|
PhTrimStringRef
|
||||||
|
PhUnregisterCallback
|
||||||
|
PhUpperBoundElementAvlTree
|
||||||
|
PhUpperDualBoundElementAvlTree
|
||||||
|
PhWriteUnicodeDecoder
|
||||||
|
PhZeroExtendToUtf16Buffer
|
||||||
|
PhZeroExtendToUtf16Ex
|
||||||
|
|
||||||
|
; phnative
|
||||||
|
PhCreateFileWin32
|
||||||
|
PhCreateFileWin32Ex
|
||||||
|
PhCreateKey
|
||||||
|
PhDeleteFileWin32
|
||||||
|
PhDisconnectNamedPipe
|
||||||
|
PhEnumDirectoryFile
|
||||||
|
PhEnumDirectoryObjects
|
||||||
|
PhEnumFileStreams
|
||||||
|
PhEnumGenericModules
|
||||||
|
PhEnumHandles
|
||||||
|
PhEnumHandlesEx
|
||||||
|
PhEnumKernelModules
|
||||||
|
PhEnumPagefiles
|
||||||
|
PhEnumProcessEnvironmentVariables
|
||||||
|
PhEnumProcesses
|
||||||
|
PhEnumProcessesEx
|
||||||
|
PhEnumProcessesForSession
|
||||||
|
PhEnumProcessModules
|
||||||
|
PhEnumProcessModules32
|
||||||
|
PhEnumProcessModules32Ex
|
||||||
|
PhEnumProcessModulesEx
|
||||||
|
PhFindProcessInformation
|
||||||
|
PhFindProcessInformationByImageName
|
||||||
|
PhGetFileName
|
||||||
|
PhGetFileSize
|
||||||
|
PhGetJobProcessIdList
|
||||||
|
PhGetKernelFileName
|
||||||
|
PhGetObjectSecurity
|
||||||
|
PhGetOwnTokenAttributes
|
||||||
|
PhGetProcedureAddressRemote
|
||||||
|
PhGetProcessCommandLine
|
||||||
|
PhGetProcessDepStatus
|
||||||
|
PhGetProcessEnvironment
|
||||||
|
PhGetProcessImageFileName
|
||||||
|
PhGetProcessImageFileNameByProcessId
|
||||||
|
PhGetProcessImageFileNameWin32
|
||||||
|
PhGetProcessIsDotNet
|
||||||
|
PhGetProcessIsDotNetEx
|
||||||
|
PhGetProcessMappedFileName
|
||||||
|
PhGetProcessPebString
|
||||||
|
PhGetProcessWindowTitle
|
||||||
|
PhGetProcessWorkingSetInformation
|
||||||
|
PhGetProcessWsCounters
|
||||||
|
PhGetTokenGroups
|
||||||
|
PhGetTokenIntegrityLevel
|
||||||
|
PhGetTokenOwner
|
||||||
|
PhGetTokenPrimaryGroup
|
||||||
|
PhGetTokenPrivileges
|
||||||
|
PhGetTokenUser
|
||||||
|
PhImpersonateClientOfNamedPipe
|
||||||
|
PhInjectDllProcess
|
||||||
|
PhListenNamedPipe
|
||||||
|
PhOpenKey
|
||||||
|
PhOpenProcess = PhOpenProcessPublic
|
||||||
|
PhOpenThread = PhOpenThreadPublic
|
||||||
|
PhOpenThreadProcess
|
||||||
|
PhPeekNamedPipe
|
||||||
|
PhQueryFullAttributesFileWin32
|
||||||
|
PhQueryKey
|
||||||
|
PhQueryValueKey
|
||||||
|
PhResolveDevicePrefix
|
||||||
|
PhSetFileSize
|
||||||
|
PhSetObjectSecurity
|
||||||
|
PhSetTokenIsVirtualizationEnabled
|
||||||
|
PhSetTokenPrivilege
|
||||||
|
PhSetTokenPrivilege2
|
||||||
|
PhSetTokenSessionId
|
||||||
|
PhTerminateProcess = PhTerminateProcessPublic
|
||||||
|
PhTransceiveNamedPipe
|
||||||
|
PhUnloadDllProcess
|
||||||
|
PhUnloadDriver
|
||||||
|
PhUpdateDosDevicePrefixes
|
||||||
|
PhUpdateMupDevicePrefixes
|
||||||
|
PhWaitForNamedPipe
|
||||||
|
|
||||||
|
; phutil
|
||||||
|
PhAdjustRectangleToBounds
|
||||||
|
PhAdjustRectangleToWorkingArea
|
||||||
|
PhCenterRectangle
|
||||||
|
PhCenterWindow
|
||||||
|
PhCompareUnicodeStringZIgnoreMenuPrefix
|
||||||
|
PhCreateOpenFileDialog
|
||||||
|
PhCreateProcess
|
||||||
|
PhCreateProcessAsUser
|
||||||
|
PhCreateProcessWin32
|
||||||
|
PhCreateProcessWin32Ex
|
||||||
|
PhCreateSaveFileDialog
|
||||||
|
PhDeleteImageVersionInfo
|
||||||
|
PhDereferenceObjects
|
||||||
|
PhEllipsisString
|
||||||
|
PhEllipsisStringPath
|
||||||
|
PhEscapeCommandLinePart
|
||||||
|
PhEscapeStringForMenuPrefix
|
||||||
|
PhExpandEnvironmentStrings
|
||||||
|
PhFinalHash
|
||||||
|
PhFindIntegerSiKeyValuePairs
|
||||||
|
PhFindLoaderEntry
|
||||||
|
PhFindStringSiKeyValuePairs
|
||||||
|
PhFormatDate
|
||||||
|
PhFormatDateTime
|
||||||
|
PhFormatDecimal
|
||||||
|
PhFormatGuid
|
||||||
|
PhFormatImageVersionInfo
|
||||||
|
PhFormatSize
|
||||||
|
PhFormatTime
|
||||||
|
PhFormatTimeSpan
|
||||||
|
PhFormatTimeSpanRelative
|
||||||
|
PhFormatUInt64
|
||||||
|
PhFreeFileDialog
|
||||||
|
PhGenerateGuid
|
||||||
|
PhGenerateGuidFromName
|
||||||
|
PhGenerateRandomAlphaString
|
||||||
|
PhGetApplicationDirectory
|
||||||
|
PhGetApplicationFileName
|
||||||
|
PhGetBaseName
|
||||||
|
PhGetDllFileName
|
||||||
|
PhGetFileDialogFileName
|
||||||
|
PhGetFileDialogFilterIndex
|
||||||
|
PhGetFileDialogOptions
|
||||||
|
PhGetFileVersionInfo
|
||||||
|
PhGetFileVersionInfoLangCodePage
|
||||||
|
PhGetFileVersionInfoString
|
||||||
|
PhGetFileVersionInfoString2
|
||||||
|
PhGetFullPath
|
||||||
|
PhGetKnownLocation
|
||||||
|
PhGetMessage
|
||||||
|
PhGetNtMessage
|
||||||
|
PhGetSystemDirectory
|
||||||
|
PhGetSystemRoot
|
||||||
|
PhGetWin32Message
|
||||||
|
PhInitializeHash
|
||||||
|
PhInitializeImageVersionInfo
|
||||||
|
PhIsExecutablePacked
|
||||||
|
PhMapFlags1
|
||||||
|
PhMapFlags2
|
||||||
|
PhMatchWildcards
|
||||||
|
PhParseCommandLine
|
||||||
|
PhParseCommandLineFuzzy
|
||||||
|
PhParseCommandLinePart
|
||||||
|
PhQueryRegistryString
|
||||||
|
PhReferenceObjects
|
||||||
|
PhSetFileDialogFileName
|
||||||
|
PhSetFileDialogFilter
|
||||||
|
PhSetFileDialogOptions
|
||||||
|
PhShellExecute
|
||||||
|
PhShellExecuteEx
|
||||||
|
PhShellExploreFile
|
||||||
|
PhShellOpenKey
|
||||||
|
PhShellProperties
|
||||||
|
PhShowConfirmMessage
|
||||||
|
PhShowContinueStatus
|
||||||
|
PhShowFileDialog
|
||||||
|
PhShowMessage
|
||||||
|
PhShowMessage_V
|
||||||
|
PhShowStatus
|
||||||
|
PhUpdateHash
|
||||||
|
|
||||||
|
; circbuf
|
||||||
|
PhClearCircularBuffer_FLOAT
|
||||||
|
PhClearCircularBuffer_PVOID
|
||||||
|
PhClearCircularBuffer_ULONG
|
||||||
|
PhClearCircularBuffer_ULONG64
|
||||||
|
PhCopyCircularBuffer_FLOAT
|
||||||
|
PhCopyCircularBuffer_PVOID
|
||||||
|
PhCopyCircularBuffer_ULONG
|
||||||
|
PhCopyCircularBuffer_ULONG64
|
||||||
|
PhDeleteCircularBuffer_FLOAT
|
||||||
|
PhDeleteCircularBuffer_PVOID
|
||||||
|
PhDeleteCircularBuffer_ULONG
|
||||||
|
PhDeleteCircularBuffer_ULONG64
|
||||||
|
PhInitializeCircularBuffer_FLOAT
|
||||||
|
PhInitializeCircularBuffer_PVOID
|
||||||
|
PhInitializeCircularBuffer_ULONG
|
||||||
|
PhInitializeCircularBuffer_ULONG64
|
||||||
|
PhResizeCircularBuffer_FLOAT
|
||||||
|
PhResizeCircularBuffer_PVOID
|
||||||
|
PhResizeCircularBuffer_ULONG
|
||||||
|
PhResizeCircularBuffer_ULONG64
|
||||||
|
|
||||||
|
; cpysave
|
||||||
|
PhGetGenericTreeNewLines
|
||||||
|
PhGetTreeNewText
|
||||||
|
|
||||||
|
; emenu
|
||||||
|
PhCreateEMenu
|
||||||
|
PhCreateEMenuItem
|
||||||
|
PhDestroyEMenu
|
||||||
|
PhDestroyEMenuItem
|
||||||
|
PhFindEMenuItem
|
||||||
|
PhIndexOfEMenuItem
|
||||||
|
PhInsertEMenuItem
|
||||||
|
PhLoadResourceEMenuItem
|
||||||
|
PhModifyEMenuItem
|
||||||
|
PhRemoveAllEMenuItems
|
||||||
|
PhRemoveEMenuItem
|
||||||
|
PhSetFlagsAllEMenuItems
|
||||||
|
PhSetFlagsEMenuItem
|
||||||
|
PhShowEMenu
|
||||||
|
|
||||||
|
; fastlock
|
||||||
|
PhDeleteFastLock
|
||||||
|
PhfAcquireFastLockExclusive
|
||||||
|
PhfAcquireFastLockShared
|
||||||
|
PhfReleaseFastLockExclusive
|
||||||
|
PhfReleaseFastLockShared
|
||||||
|
PhfTryAcquireFastLockExclusive
|
||||||
|
PhfTryAcquireFastLockShared
|
||||||
|
PhInitializeFastLock
|
||||||
|
|
||||||
|
; filestream
|
||||||
|
PhCreateFileStream
|
||||||
|
PhCreateFileStream2
|
||||||
|
PhFlushFileStream
|
||||||
|
PhGetPositionFileStream
|
||||||
|
PhLockFileStream
|
||||||
|
PhReadFileStream
|
||||||
|
PhSeekFileStream
|
||||||
|
PhUnlockFileStream
|
||||||
|
PhVerifyFileStream
|
||||||
|
PhWriteFileStream
|
||||||
|
PhWriteStringAsUtf8FileStream
|
||||||
|
PhWriteStringAsUtf8FileStream2
|
||||||
|
PhWriteStringAsUtf8FileStreamEx
|
||||||
|
PhWriteStringFormatAsUtf8FileStream
|
||||||
|
PhWriteStringFormatAsUtf8FileStream_V
|
||||||
|
|
||||||
|
; graph
|
||||||
|
PhDeleteGraphState
|
||||||
|
PhDrawGraphDirect
|
||||||
|
PhGetDrawInfoGraphBuffers
|
||||||
|
PhGraphStateGetDrawInfo
|
||||||
|
PhInitializeGraphState
|
||||||
|
PhSetGraphText
|
||||||
|
|
||||||
|
; guisup
|
||||||
|
PhAddComboBoxStrings
|
||||||
|
PhAddLayoutItem
|
||||||
|
PhAddLayoutItemEx
|
||||||
|
PhAddListViewColumn
|
||||||
|
PhAddListViewItem
|
||||||
|
PhAddTabControlTab
|
||||||
|
PhDeleteLayoutManager
|
||||||
|
PhFindListViewItemByFlags
|
||||||
|
PhFindListViewItemByParam
|
||||||
|
PhGetComboBoxString
|
||||||
|
PhGetFileShellIcon
|
||||||
|
PhGetListBoxString
|
||||||
|
PhGetListViewItemImageIndex
|
||||||
|
PhGetListViewItemParam
|
||||||
|
PhGetSelectedListViewItemParam
|
||||||
|
PhGetSelectedListViewItemParams
|
||||||
|
PhGetStockApplicationIcon
|
||||||
|
PhGetWindowText
|
||||||
|
PhGetWindowTextEx
|
||||||
|
PhIconToBitmap
|
||||||
|
PhInitializeLayoutManager
|
||||||
|
PhLayoutManagerLayout
|
||||||
|
PhLoadIcon
|
||||||
|
PhLoadListViewColumnSettings
|
||||||
|
PhModalPropertySheet
|
||||||
|
PhRemoveListViewItem
|
||||||
|
PhSaveListViewColumnSettings
|
||||||
|
PhSelectComboBoxString
|
||||||
|
PhSetClipboardString
|
||||||
|
PhSetControlTheme
|
||||||
|
PhSetExtendedListView
|
||||||
|
PhSetHeaderSortIcon
|
||||||
|
PhSetImageListBitmap
|
||||||
|
PhSetListViewItemImageIndex
|
||||||
|
PhSetListViewSubItem
|
||||||
|
PhSetStateAllListViewItems
|
||||||
|
|
||||||
|
; hndlinfo
|
||||||
|
PhEnumObjectTypes
|
||||||
|
PhFormatNativeKeyName
|
||||||
|
PhGetHandleInformation
|
||||||
|
PhGetHandleInformationEx
|
||||||
|
PhStdGetClientIdName
|
||||||
|
|
||||||
|
; lsasup
|
||||||
|
PhGetSidFullName
|
||||||
|
PhLookupName
|
||||||
|
PhLookupPrivilegeDisplayName
|
||||||
|
PhLookupPrivilegeName
|
||||||
|
PhLookupPrivilegeValue
|
||||||
|
PhLookupSid
|
||||||
|
PhOpenLsaPolicy
|
||||||
|
PhSidToStringSid
|
||||||
|
|
||||||
|
; secedit
|
||||||
|
PhCreateSecurityPage
|
||||||
|
PhEditSecurity
|
||||||
|
PhGetAccessEntries
|
||||||
|
PhGetAccessString
|
||||||
|
PhGetSeObjectSecurity
|
||||||
|
PhSetSeObjectSecurity
|
||||||
|
PhStdGetObjectSecurity
|
||||||
|
PhStdSetObjectSecurity
|
||||||
|
|
||||||
|
; svcsup
|
||||||
|
PhEnumServices
|
||||||
|
PhGetServiceConfig
|
||||||
|
PhGetServiceDelayedAutoStart
|
||||||
|
PhGetServiceDescription
|
||||||
|
PhGetServiceErrorControlInteger
|
||||||
|
PhGetServiceErrorControlString
|
||||||
|
PhGetServiceNameFromTag
|
||||||
|
PhGetServiceStartTypeInteger
|
||||||
|
PhGetServiceStartTypeString
|
||||||
|
PhGetServiceStateString
|
||||||
|
PhGetServiceTypeInteger
|
||||||
|
PhGetServiceTypeString
|
||||||
|
PhGetThreadServiceTag
|
||||||
|
PhOpenService
|
||||||
|
PhQueryServiceVariableSize
|
||||||
|
PhSetServiceDelayedAutoStart
|
||||||
|
|
||||||
|
; symprv
|
||||||
|
PhCreateSymbolProvider
|
||||||
|
PhGetLineFromAddress
|
||||||
|
PhGetModuleFromAddress
|
||||||
|
PhGetSymbolFromAddress
|
||||||
|
PhGetSymbolFromName
|
||||||
|
PhLoadModuleSymbolProvider
|
||||||
|
PhSetOptionsSymbolProvider
|
||||||
|
PhSetSearchPathSymbolProvider
|
||||||
|
PhStackWalk
|
||||||
|
PhWalkThreadStack
|
||||||
|
PhWriteMiniDumpProcess
|
||||||
|
|
||||||
|
; verify
|
||||||
|
PhVerifyFile
|
||||||
|
|
||||||
|
; workqueue
|
||||||
|
PhDeleteWorkQueue
|
||||||
|
PhGetGlobalWorkQueue
|
||||||
|
PhInitializeWorkQueue
|
||||||
|
PhInitializeWorkQueueEnvironment
|
||||||
|
PhQueueItemWorkQueue
|
||||||
|
PhQueueItemWorkQueueEx
|
||||||
|
PhWaitForWorkQueue
|
BIN
ProcessHacker/ProcessHacker.ico
Normal file
BIN
ProcessHacker/ProcessHacker.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
46
ProcessHacker/ProcessHacker.manifest
Normal file
46
ProcessHacker/ProcessHacker.manifest
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<assemblyIdentity
|
||||||
|
name="Process Hacker"
|
||||||
|
processorArchitecture="*"
|
||||||
|
version="2.0.0.0"
|
||||||
|
type="win32"
|
||||||
|
/>
|
||||||
|
<description>Process Hacker</description>
|
||||||
|
<dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges>
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||||
|
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||||
|
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||||
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||||
|
<dpiAware>true</dpiAware>
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings">
|
||||||
|
<disableWindowFiltering>true</disableWindowFiltering>
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
</asmv3:application>
|
||||||
|
</assembly>
|
2606
ProcessHacker/ProcessHacker.rc
Normal file
2606
ProcessHacker/ProcessHacker.rc
Normal file
File diff suppressed because it is too large
Load Diff
421
ProcessHacker/ProcessHacker.vcxproj
Normal file
421
ProcessHacker/ProcessHacker.vcxproj
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{0271DD27-6707-4290-8DFE-285702B7115D}</ProjectGuid>
|
||||||
|
<RootNamespace>ProcessHacker</RootNamespace>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\$(Configuration)$(PlatformArchitecture)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)obj\$(Configuration)$(PlatformArchitecture)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||||
|
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
|
||||||
|
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
|
||||||
|
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
|
||||||
|
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\phnt\include;..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_PHLIB_;_PHAPP_;_WINDOWS;WIN32;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>StdCall</CallingConvention>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>phlib.lib;ntdll.lib;winsta.lib;comctl32.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||||
|
<AdditionalLibraryDirectories>..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>ProcessHacker.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>update_rev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Generating revision number...</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\phnt\include;..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_PHLIB_;_PHAPP_;_WINDOWS;WIN64;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>StdCall</CallingConvention>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>phlib.lib;ntdll.lib;winsta.lib;comctl32.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
|
<AdditionalLibraryDirectories>..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>ProcessHacker.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>update_rev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Generating revision number...</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\phnt\include;..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_PHLIB_;_PHAPP_;_WINDOWS;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>StdCall</CallingConvention>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>phlib.lib;ntdll.lib;winsta.lib;comctl32.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<SetChecksum>true</SetChecksum>
|
||||||
|
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
|
||||||
|
<AdditionalLibraryDirectories>..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>ProcessHacker.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>update_rev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Generating revision number...</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\phnt\include;..\phlib\include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_PHLIB_;_PHAPP_;_WINDOWS;WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<StringPooling>true</StringPooling>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CallingConvention>StdCall</CallingConvention>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>phlib.lib;ntdll.lib;winsta.lib;comctl32.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
<SetChecksum>true</SetChecksum>
|
||||||
|
<MinimumRequiredVersion>5.02</MinimumRequiredVersion>
|
||||||
|
<AdditionalLibraryDirectories>..\phlib\bin\$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<ModuleDefinitionFile>ProcessHacker.def</ModuleDefinitionFile>
|
||||||
|
</Link>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Command>update_rev.bat</Command>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PreBuildEvent>
|
||||||
|
<Message>Generating revision number...</Message>
|
||||||
|
</PreBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="about.c" />
|
||||||
|
<ClCompile Include="actions.c" />
|
||||||
|
<ClCompile Include="affinity.c" />
|
||||||
|
<ClCompile Include="anawait.c" />
|
||||||
|
<ClCompile Include="appsup.c" />
|
||||||
|
<ClCompile Include="chcol.c" />
|
||||||
|
<ClCompile Include="chdlg.c" />
|
||||||
|
<ClCompile Include="chproc.c" />
|
||||||
|
<ClCompile Include="cmdmode.c" />
|
||||||
|
<ClCompile Include="colmgr.c" />
|
||||||
|
<ClCompile Include="dbgcon.c" />
|
||||||
|
<ClCompile Include="extmgr.c" />
|
||||||
|
<ClCompile Include="findobj.c" />
|
||||||
|
<ClCompile Include="gdihndl.c" />
|
||||||
|
<ClCompile Include="hidnproc.c" />
|
||||||
|
<ClCompile Include="hndllist.c" />
|
||||||
|
<ClCompile Include="hndlmenu.c" />
|
||||||
|
<ClCompile Include="hndlprp.c" />
|
||||||
|
<ClCompile Include="hndlprv.c" />
|
||||||
|
<ClCompile Include="hndlstat.c" />
|
||||||
|
<ClCompile Include="infodlg.c" />
|
||||||
|
<ClCompile Include="itemtips.c" />
|
||||||
|
<ClCompile Include="jobprp.c" />
|
||||||
|
<ClCompile Include="log.c" />
|
||||||
|
<ClCompile Include="logwnd.c" />
|
||||||
|
<ClCompile Include="main.c" />
|
||||||
|
<ClCompile Include="mainwnd.c" />
|
||||||
|
<ClCompile Include="mdump.c" />
|
||||||
|
<ClCompile Include="memedit.c" />
|
||||||
|
<ClCompile Include="memlist.c" />
|
||||||
|
<ClCompile Include="memlists.c" />
|
||||||
|
<ClCompile Include="memprot.c" />
|
||||||
|
<ClCompile Include="memprv.c" />
|
||||||
|
<ClCompile Include="memrslt.c" />
|
||||||
|
<ClCompile Include="memsrch.c" />
|
||||||
|
<ClCompile Include="miniinfo.c" />
|
||||||
|
<ClCompile Include="modlist.c" />
|
||||||
|
<ClCompile Include="modprv.c" />
|
||||||
|
<ClCompile Include="mtgndlg.c" />
|
||||||
|
<ClCompile Include="netlist.c" />
|
||||||
|
<ClCompile Include="netprv.c" />
|
||||||
|
<ClCompile Include="netstk.c" />
|
||||||
|
<ClCompile Include="notifico.c" />
|
||||||
|
<ClCompile Include="ntobjprp.c" />
|
||||||
|
<ClCompile Include="options.c" />
|
||||||
|
<ClCompile Include="pagfiles.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2posix.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_auto_possess.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_chartables.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_compile.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_config.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_context.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_dfa_match.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_error.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_find_bracket.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_jit_compile.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_maketables.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_match.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_match_data.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_newline.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_ord2utf.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_pattern_info.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_serialize.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_string_utils.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_study.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_substitute.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_substring.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_tables.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_ucd.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_valid_utf.c" />
|
||||||
|
<ClCompile Include="pcre\pcre2_xclass.c" />
|
||||||
|
<ClCompile Include="phsvc\clapi.c" />
|
||||||
|
<ClCompile Include="phsvc\svcapi.c" />
|
||||||
|
<ClCompile Include="phsvc\svcapiport.c" />
|
||||||
|
<ClCompile Include="phsvc\svcclient.c" />
|
||||||
|
<ClCompile Include="phsvc\svcmain.c" />
|
||||||
|
<ClCompile Include="plugin.c" />
|
||||||
|
<ClCompile Include="plugman.c" />
|
||||||
|
<ClCompile Include="procgrp.c" />
|
||||||
|
<ClCompile Include="procmtgn.c" />
|
||||||
|
<ClCompile Include="procprp.c" />
|
||||||
|
<ClCompile Include="procprv.c" />
|
||||||
|
<ClCompile Include="procrec.c" />
|
||||||
|
<ClCompile Include="proctree.c" />
|
||||||
|
<ClCompile Include="prpgenv.c" />
|
||||||
|
<ClCompile Include="prpggen.c" />
|
||||||
|
<ClCompile Include="prpghndl.c" />
|
||||||
|
<ClCompile Include="prpgjob.c" />
|
||||||
|
<ClCompile Include="prpgmem.c" />
|
||||||
|
<ClCompile Include="prpgmod.c" />
|
||||||
|
<ClCompile Include="prpgperf.c" />
|
||||||
|
<ClCompile Include="prpgsrv.c" />
|
||||||
|
<ClCompile Include="prpgstat.c" />
|
||||||
|
<ClCompile Include="prpgthrd.c" />
|
||||||
|
<ClCompile Include="prpgtok.c" />
|
||||||
|
<ClCompile Include="runas.c" />
|
||||||
|
<ClCompile Include="sessprp.c" />
|
||||||
|
<ClCompile Include="sessshad.c" />
|
||||||
|
<ClCompile Include="settings.c" />
|
||||||
|
<ClCompile Include="srvcr.c" />
|
||||||
|
<ClCompile Include="srvctl.c" />
|
||||||
|
<ClCompile Include="srvlist.c" />
|
||||||
|
<ClCompile Include="srvprp.c" />
|
||||||
|
<ClCompile Include="srvprv.c" />
|
||||||
|
<ClCompile Include="sessmsg.c" />
|
||||||
|
<ClCompile Include="sysinfo.c" />
|
||||||
|
<ClCompile Include="syssccpu.c" />
|
||||||
|
<ClCompile Include="sysscio.c" />
|
||||||
|
<ClCompile Include="sysscmem.c" />
|
||||||
|
<ClCompile Include="thrdlist.c" />
|
||||||
|
<ClCompile Include="thrdprv.c" />
|
||||||
|
<ClCompile Include="thrdstk.c" />
|
||||||
|
<ClCompile Include="tokprp.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-attr.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-entity.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-file.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-index.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-node.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-private.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-search.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-set.c" />
|
||||||
|
<ClCompile Include="mxml\mxml-string.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\actions.h" />
|
||||||
|
<ClInclude Include="include\colmgr.h" />
|
||||||
|
<ClInclude Include="include\extmgr.h" />
|
||||||
|
<ClInclude Include="include\extmgri.h" />
|
||||||
|
<ClInclude Include="include\heapstruct.h" />
|
||||||
|
<ClInclude Include="include\hndllist.h" />
|
||||||
|
<ClInclude Include="include\hndlmenu.h" />
|
||||||
|
<ClInclude Include="include\hndlprv.h" />
|
||||||
|
<ClInclude Include="include\mainwndp.h" />
|
||||||
|
<ClInclude Include="include\memlist.h" />
|
||||||
|
<ClInclude Include="include\miniinfop.h" />
|
||||||
|
<ClInclude Include="include\modlist.h" />
|
||||||
|
<ClInclude Include="include\modprv.h" />
|
||||||
|
<ClInclude Include="include\netlist.h" />
|
||||||
|
<ClInclude Include="include\netprv.h" />
|
||||||
|
<ClInclude Include="include\notifico.h" />
|
||||||
|
<ClInclude Include="include\notificop.h" />
|
||||||
|
<ClInclude Include="include\phfwddef.h" />
|
||||||
|
<ClInclude Include="include\phsvccl.h" />
|
||||||
|
<ClInclude Include="include\procmtgn.h" />
|
||||||
|
<ClInclude Include="include\procprv.h" />
|
||||||
|
<ClInclude Include="include\proctree.h" />
|
||||||
|
<ClInclude Include="include\srvlist.h" />
|
||||||
|
<ClInclude Include="include\srvprv.h" />
|
||||||
|
<ClInclude Include="include\sysinfo.h" />
|
||||||
|
<ClInclude Include="include\thrdlist.h" />
|
||||||
|
<ClInclude Include="include\thrdprv.h" />
|
||||||
|
<ClInclude Include="include\phuisup.h" />
|
||||||
|
<ClInclude Include="include\miniinfo.h" />
|
||||||
|
<ClInclude Include="mxml\config.h" />
|
||||||
|
<ClInclude Include="include\hidnproc.h" />
|
||||||
|
<ClInclude Include="include\memsrch.h" />
|
||||||
|
<ClInclude Include="mxml\mxml-private.h" />
|
||||||
|
<ClInclude Include="mxml\mxml.h" />
|
||||||
|
<ClInclude Include="include\phapp.h" />
|
||||||
|
<ClInclude Include="include\phsvc.h" />
|
||||||
|
<ClInclude Include="include\phsvcapi.h" />
|
||||||
|
<ClInclude Include="include\phappres.h" />
|
||||||
|
<ClInclude Include="pcre\config.h" />
|
||||||
|
<ClInclude Include="pcre\pcre2.h" />
|
||||||
|
<ClInclude Include="pcre\pcre2posix.h" />
|
||||||
|
<ClInclude Include="pcre\pcre2_internal.h" />
|
||||||
|
<ClInclude Include="pcre\pcre2_intmodedep.h" />
|
||||||
|
<ClInclude Include="pcre\pcre2_ucp.h" />
|
||||||
|
<ClInclude Include="include\procgrp.h" />
|
||||||
|
<ClInclude Include="sdk\phdk.h" />
|
||||||
|
<ClInclude Include="include\phplug.h" />
|
||||||
|
<ClInclude Include="include\procprpp.h" />
|
||||||
|
<ClInclude Include="include\memprv.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="include\settings.h" />
|
||||||
|
<ClInclude Include="include\settingsp.h" />
|
||||||
|
<ClInclude Include="include\sysinfop.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="ProcessHacker.def" />
|
||||||
|
<None Include="resources\application.ico" />
|
||||||
|
<None Include="resources\application_go.ico" />
|
||||||
|
<None Include="resources\cog.ico" />
|
||||||
|
<None Include="resources\cog_go.ico" />
|
||||||
|
<None Include="resources\cross.bmp" />
|
||||||
|
<None Include="ProcessHacker.ico" />
|
||||||
|
<None Include="resources\ProcessHacker.png" />
|
||||||
|
<None Include="resources\tick.bmp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="ProcessHacker.rc" />
|
||||||
|
<ResourceCompile Include="version.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Manifest Include="ProcessHacker.manifest">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Manifest>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="resources\folder.ico" />
|
||||||
|
<Image Include="resources\magnifier.ico" />
|
||||||
|
<Image Include="resources\pencil.ico" />
|
||||||
|
<Image Include="resources\pin.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
620
ProcessHacker/ProcessHacker.vcxproj.filters
Normal file
620
ProcessHacker/ProcessHacker.vcxproj.filters
Normal file
@ -0,0 +1,620 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Headers">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resources">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Process Hacker">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="PCRE">
|
||||||
|
<UniqueIdentifier>{3fa0b151-12c1-4832-94fb-e16c52584b65}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Mini-XML">
|
||||||
|
<UniqueIdentifier>{eaabb14f-9091-4b18-8764-45c8350f4887}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="phsvc">
|
||||||
|
<UniqueIdentifier>{84a3be0b-42cf-42ae-bcd3-16f165caa0db}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="PCRE\Headers">
|
||||||
|
<UniqueIdentifier>{e72b6c69-b510-4578-9ed5-34a16d8dffc1}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Mini-XML\Headers">
|
||||||
|
<UniqueIdentifier>{c4b014d0-6bd0-4848-a23f-e639563d998e}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Module">
|
||||||
|
<UniqueIdentifier>{67c40321-0b28-4c16-8c48-dc0b64c148d7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="about.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="actions.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="affinity.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="anawait.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="appsup.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="chcol.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="chdlg.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="chproc.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="cmdmode.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="dbgcon.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="findobj.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="gdihndl.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hidnproc.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hndlprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hndlprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hndlstat.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="infodlg.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="itemtips.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="jobprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="log.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="logwnd.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mainwnd.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mdump.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memedit.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memprot.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memrslt.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memsrch.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="modprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="netprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="netstk.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="notifico.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ntobjprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="options.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pagfiles.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="plugin.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="plugman.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="procprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="procprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="procrec.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="proctree.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="runas.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sessprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="settings.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="srvcr.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="srvprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="srvprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sysinfo.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="thrdprv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="thrdstk.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="tokprp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-attr.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-entity.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-file.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-index.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-node.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-private.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-search.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-set.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mxml\mxml-string.c">
|
||||||
|
<Filter>Mini-XML</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="srvctl.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="srvlist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="modlist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="phsvc\svcmain.c">
|
||||||
|
<Filter>phsvc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="phsvc\svcclient.c">
|
||||||
|
<Filter>phsvc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="phsvc\svcapiport.c">
|
||||||
|
<Filter>phsvc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="phsvc\svcapi.c">
|
||||||
|
<Filter>phsvc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="phsvc\clapi.c">
|
||||||
|
<Filter>phsvc</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sessmsg.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sessshad.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="colmgr.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="netlist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="extmgr.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="thrdlist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hndllist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memlists.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="memlist.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="miniinfo.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="procgrp.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_compile.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_config.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_context.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_dfa_match.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_error.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_maketables.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_match.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_match_data.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_newline.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_ord2utf.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_pattern_info.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_serialize.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_string_utils.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_study.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_substitute.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_substring.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_tables.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_ucd.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_valid_utf.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_xclass.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_auto_possess.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_chartables.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_jit_compile.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2posix.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pcre\pcre2_find_bracket.c">
|
||||||
|
<Filter>PCRE</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="procmtgn.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="mtgndlg.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="hndlmenu.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="syssccpu.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sysscmem.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="sysscio.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpggen.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgstat.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgperf.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgthrd.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgtok.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgmod.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgmem.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgenv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpghndl.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgjob.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="prpgsrv.c">
|
||||||
|
<Filter>Process Hacker</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\hidnproc.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\memsrch.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phapp.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="sdk\phdk.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phplug.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\procprpp.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\settings.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\settingsp.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phsvcapi.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phsvc.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phsvccl.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phappres.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\colmgr.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\mainwndp.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\extmgr.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\extmgri.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\sysinfop.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\notifico.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\heapstruct.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\miniinfop.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\miniinfo.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\procgrp.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\sysinfo.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\config.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\pcre2.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\pcre2_internal.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\pcre2_intmodedep.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\pcre2_ucp.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pcre\pcre2posix.h">
|
||||||
|
<Filter>PCRE\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="mxml\config.h">
|
||||||
|
<Filter>Mini-XML\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="mxml\mxml-private.h">
|
||||||
|
<Filter>Mini-XML\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="mxml\mxml.h">
|
||||||
|
<Filter>Mini-XML\Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\notificop.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\procmtgn.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phfwddef.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\procprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\srvprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\netprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\modprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\thrdprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\hndlprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\memprv.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\phuisup.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\proctree.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\srvlist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\netlist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\thrdlist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\modlist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\hndllist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\memlist.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\hndlmenu.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\actions.h">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="resources\cross.bmp">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="ProcessHacker.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\ProcessHacker.png">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\tick.bmp">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\application.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\cog.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\application_go.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\cog_go.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="ProcessHacker.def">
|
||||||
|
<Filter>Module</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="ProcessHacker.rc">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
<ResourceCompile Include="version.rc">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Manifest Include="ProcessHacker.manifest">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</Manifest>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="resources\pin.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="resources\pencil.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="resources\folder.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="resources\magnifier.ico">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
184
ProcessHacker/about.c
Normal file
184
ProcessHacker/about.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* about dialog
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <phappres.h>
|
||||||
|
#include <procprv.h>
|
||||||
|
#include <srvprv.h>
|
||||||
|
#include <netprv.h>
|
||||||
|
#include <modprv.h>
|
||||||
|
#include <thrdprv.h>
|
||||||
|
#include <hndlprv.h>
|
||||||
|
#include <memprv.h>
|
||||||
|
#include <symprv.h>
|
||||||
|
|
||||||
|
static INT_PTR CALLBACK PhpAboutDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
PPH_STRING appName;
|
||||||
|
|
||||||
|
#if (PHAPP_VERSION_REVISION != 0)
|
||||||
|
appName = PhFormatString(
|
||||||
|
L"Process Hacker %u.%u.%u",
|
||||||
|
PHAPP_VERSION_MAJOR,
|
||||||
|
PHAPP_VERSION_MINOR,
|
||||||
|
PHAPP_VERSION_REVISION
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
appName = PhFormatString(
|
||||||
|
L"Process Hacker %u.%u",
|
||||||
|
PHAPP_VERSION_MAJOR,
|
||||||
|
PHAPP_VERSION_MINOR
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SetDlgItemText(hwndDlg, IDC_ABOUT_NAME, appName->Buffer);
|
||||||
|
PhDereferenceObject(appName);
|
||||||
|
|
||||||
|
SetDlgItemText(hwndDlg, IDC_CREDITS,
|
||||||
|
L" Installer by XhmikosR\n"
|
||||||
|
L"Thanks to:\n"
|
||||||
|
L" dmex\n"
|
||||||
|
L" Donors - thank you for your support!\n"
|
||||||
|
L" <a href=\"http://forum.sysinternals.com\">Sysinternals Forums</a>\n"
|
||||||
|
L" <a href=\"http://www.reactos.org\">ReactOS</a>\n"
|
||||||
|
L"Process Hacker uses the following components:\n"
|
||||||
|
L" <a href=\"http://www.minixml.org\">Mini-XML</a> by Michael Sweet\n"
|
||||||
|
L" <a href=\"http://www.pcre.org\">PCRE</a>\n"
|
||||||
|
L" MD5 code by Jouni Malinen\n"
|
||||||
|
L" SHA1 code by Filip Navara, based on code by Steve Reid\n"
|
||||||
|
L" <a href=\"http://www.famfamfam.com/lab/icons/silk\">Silk icons</a>\n"
|
||||||
|
L" <a href=\"http://www.fatcow.com/free-icons\">Farm-fresh web icons</a>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
case IDOK:
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
break;
|
||||||
|
case IDC_DIAGNOSTICS:
|
||||||
|
{
|
||||||
|
PhShowInformationDialog(hwndDlg, PH_AUTO_T(PH_STRING, PhGetDiagnosticsString())->Buffer, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
LPNMHDR header = (LPNMHDR)lParam;
|
||||||
|
|
||||||
|
switch (header->code)
|
||||||
|
{
|
||||||
|
case NM_CLICK:
|
||||||
|
{
|
||||||
|
switch (header->idFrom)
|
||||||
|
{
|
||||||
|
case IDC_CREDITS:
|
||||||
|
case IDC_LINK_SF:
|
||||||
|
PhShellExecute(hwndDlg, ((PNMLINK)header)->item.szUrl, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhShowAboutDialog(
|
||||||
|
_In_ HWND ParentWindowHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DialogBox(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_ABOUT),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpAboutDlgProc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE ULONG PhpGetObjectTypeObjectCount(
|
||||||
|
_In_ PPH_OBJECT_TYPE ObjectType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_OBJECT_TYPE_INFORMATION info;
|
||||||
|
|
||||||
|
PhGetObjectTypeInformation(ObjectType, &info);
|
||||||
|
|
||||||
|
return info.NumberOfObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_STRING PhGetDiagnosticsString(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_STRING_BUILDER stringBuilder;
|
||||||
|
|
||||||
|
PhInitializeStringBuilder(&stringBuilder, 50);
|
||||||
|
|
||||||
|
PhAppendFormatStringBuilder(&stringBuilder, L"OBJECT INFORMATION\r\n");
|
||||||
|
|
||||||
|
#define OBJECT_TYPE_COUNT(Type) PhAppendFormatStringBuilder(&stringBuilder, \
|
||||||
|
L#Type L": %u objects\r\n", PhpGetObjectTypeObjectCount(Type))
|
||||||
|
|
||||||
|
// ref
|
||||||
|
OBJECT_TYPE_COUNT(PhObjectTypeObject);
|
||||||
|
|
||||||
|
// basesup
|
||||||
|
OBJECT_TYPE_COUNT(PhStringType);
|
||||||
|
OBJECT_TYPE_COUNT(PhBytesType);
|
||||||
|
OBJECT_TYPE_COUNT(PhListType);
|
||||||
|
OBJECT_TYPE_COUNT(PhPointerListType);
|
||||||
|
OBJECT_TYPE_COUNT(PhHashtableType);
|
||||||
|
OBJECT_TYPE_COUNT(PhFileStreamType);
|
||||||
|
|
||||||
|
// ph
|
||||||
|
OBJECT_TYPE_COUNT(PhSymbolProviderType);
|
||||||
|
OBJECT_TYPE_COUNT(PhProcessItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhServiceItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhNetworkItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhModuleProviderType);
|
||||||
|
OBJECT_TYPE_COUNT(PhModuleItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhThreadProviderType);
|
||||||
|
OBJECT_TYPE_COUNT(PhThreadItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhHandleProviderType);
|
||||||
|
OBJECT_TYPE_COUNT(PhHandleItemType);
|
||||||
|
OBJECT_TYPE_COUNT(PhMemoryItemType);
|
||||||
|
|
||||||
|
return PhFinalStringBuilderString(&stringBuilder);
|
||||||
|
}
|
3126
ProcessHacker/actions.c
Normal file
3126
ProcessHacker/actions.c
Normal file
File diff suppressed because it is too large
Load Diff
315
ProcessHacker/affinity.c
Normal file
315
ProcessHacker/affinity.c
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* process affinity editor
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The affinity dialog was originally created to support the modification
|
||||||
|
* of process affinity masks, but now supports modifying thread affinity
|
||||||
|
* and generic masks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <procprv.h>
|
||||||
|
#include <thrdprv.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
|
||||||
|
typedef struct _AFFINITY_DIALOG_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_PROCESS_ITEM ProcessItem;
|
||||||
|
PPH_THREAD_ITEM ThreadItem;
|
||||||
|
ULONG_PTR AffinityMask;
|
||||||
|
ULONG_PTR NewAffinityMask;
|
||||||
|
} AFFINITY_DIALOG_CONTEXT, *PAFFINITY_DIALOG_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessAffinityDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhShowProcessAffinityDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_opt_ PPH_PROCESS_ITEM ProcessItem,
|
||||||
|
_In_opt_ PPH_THREAD_ITEM ThreadItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AFFINITY_DIALOG_CONTEXT context;
|
||||||
|
|
||||||
|
assert(!!ProcessItem != !!ThreadItem); // make sure we have one and not the other
|
||||||
|
|
||||||
|
context.ProcessItem = ProcessItem;
|
||||||
|
context.ThreadItem = ThreadItem;
|
||||||
|
|
||||||
|
DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_AFFINITY),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpProcessAffinityDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhShowProcessAffinityDialog2(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ ULONG_PTR AffinityMask,
|
||||||
|
_Out_ PULONG_PTR NewAffinityMask
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AFFINITY_DIALOG_CONTEXT context;
|
||||||
|
|
||||||
|
context.ProcessItem = NULL;
|
||||||
|
context.ThreadItem = NULL;
|
||||||
|
context.AffinityMask = AffinityMask;
|
||||||
|
|
||||||
|
if (DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_AFFINITY),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpProcessAffinityDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
) == IDOK)
|
||||||
|
{
|
||||||
|
*NewAffinityMask = context.NewAffinityMask;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT_PTR CALLBACK PhpProcessAffinityDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PAFFINITY_DIALOG_CONTEXT context = (PAFFINITY_DIALOG_CONTEXT)lParam;
|
||||||
|
SYSTEM_BASIC_INFORMATION systemBasicInfo;
|
||||||
|
ULONG_PTR systemAffinityMask;
|
||||||
|
ULONG_PTR affinityMask;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||||
|
|
||||||
|
systemAffinityMask = 0;
|
||||||
|
|
||||||
|
if (context->ProcessItem)
|
||||||
|
{
|
||||||
|
HANDLE processHandle;
|
||||||
|
PROCESS_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess,
|
||||||
|
context->ProcessItem->ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
status = PhGetProcessBasicInformation(processHandle, &basicInfo);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
affinityMask = basicInfo.AffinityMask;
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (context->ThreadItem)
|
||||||
|
{
|
||||||
|
HANDLE threadHandle;
|
||||||
|
THREAD_BASIC_INFORMATION basicInfo;
|
||||||
|
HANDLE processHandle;
|
||||||
|
PROCESS_BASIC_INFORMATION processBasicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenThread(
|
||||||
|
&threadHandle,
|
||||||
|
ThreadQueryAccess,
|
||||||
|
context->ThreadItem->ThreadId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
status = PhGetThreadBasicInformation(threadHandle, &basicInfo);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
affinityMask = basicInfo.AffinityMask;
|
||||||
|
|
||||||
|
// A thread's affinity mask is restricted by the process affinity mask,
|
||||||
|
// so use that as the system affinity mask.
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess,
|
||||||
|
basicInfo.ClientId.UniqueProcess
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &processBasicInfo)))
|
||||||
|
systemAffinityMask = processBasicInfo.AffinityMask;
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(threadHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
affinityMask = context->AffinityMask;
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status) && systemAffinityMask == 0)
|
||||||
|
{
|
||||||
|
status = NtQuerySystemInformation(
|
||||||
|
SystemBasicInformation,
|
||||||
|
&systemBasicInfo,
|
||||||
|
sizeof(SYSTEM_BASIC_INFORMATION),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
systemAffinityMask = systemBasicInfo.ActiveProcessorsAffinityMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
PhShowStatus(hwndDlg, L"Unable to retrieve the affinity", status, 0);
|
||||||
|
EndDialog(hwndDlg, IDCANCEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable the CPU checkboxes which aren't part of the system affinity mask,
|
||||||
|
// and check the CPU checkboxes which are part of the affinity mask.
|
||||||
|
|
||||||
|
for (i = 0; i < 8 * 8; i++)
|
||||||
|
{
|
||||||
|
if ((i < sizeof(ULONG_PTR) * 8) && ((systemAffinityMask >> i) & 0x1))
|
||||||
|
{
|
||||||
|
if ((affinityMask >> i) & 0x1)
|
||||||
|
{
|
||||||
|
Button_SetCheck(GetDlgItem(hwndDlg, IDC_CPU0 + i), BST_CHECKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CPU0 + i), FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
EndDialog(hwndDlg, IDCANCEL);
|
||||||
|
break;
|
||||||
|
case IDOK:
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PAFFINITY_DIALOG_CONTEXT context = (PAFFINITY_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
ULONG i;
|
||||||
|
ULONG_PTR affinityMask;
|
||||||
|
|
||||||
|
// Work out the affinity mask.
|
||||||
|
|
||||||
|
affinityMask = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ULONG_PTR) * 8; i++)
|
||||||
|
{
|
||||||
|
if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_CPU0 + i)) == BST_CHECKED)
|
||||||
|
affinityMask |= (ULONG_PTR)1 << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->ProcessItem)
|
||||||
|
{
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
PROCESS_SET_INFORMATION,
|
||||||
|
context->ProcessItem->ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
status = PhSetProcessAffinityMask(processHandle, affinityMask);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (context->ThreadItem)
|
||||||
|
{
|
||||||
|
HANDLE threadHandle;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenThread(
|
||||||
|
&threadHandle,
|
||||||
|
ThreadSetAccess,
|
||||||
|
context->ThreadItem->ThreadId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
status = PhSetThreadAffinityMask(threadHandle, affinityMask);
|
||||||
|
NtClose(threadHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context->NewAffinityMask = affinityMask;
|
||||||
|
status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
else
|
||||||
|
PhShowStatus(hwndDlg, L"Unable to set the affinity", status, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_SELECTALL:
|
||||||
|
case IDC_DESELECTALL:
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ULONG_PTR) * 8; i++)
|
||||||
|
{
|
||||||
|
HWND checkBox = GetDlgItem(hwndDlg, IDC_CPU0 + i);
|
||||||
|
|
||||||
|
if (IsWindowEnabled(checkBox))
|
||||||
|
Button_SetCheck(checkBox, LOWORD(wParam) == IDC_SELECTALL ? BST_CHECKED : BST_UNCHECKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
1074
ProcessHacker/anawait.c
Normal file
1074
ProcessHacker/anawait.c
Normal file
File diff suppressed because it is too large
Load Diff
2208
ProcessHacker/appsup.c
Normal file
2208
ProcessHacker/appsup.c
Normal file
File diff suppressed because it is too large
Load Diff
422
ProcessHacker/chcol.c
Normal file
422
ProcessHacker/chcol.c
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* column chooser
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <settings.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
|
||||||
|
typedef struct _COLUMNS_DIALOG_CONTEXT
|
||||||
|
{
|
||||||
|
HWND ControlHandle;
|
||||||
|
ULONG Type;
|
||||||
|
PPH_LIST Columns;
|
||||||
|
|
||||||
|
HWND InactiveList;
|
||||||
|
HWND ActiveList;
|
||||||
|
} COLUMNS_DIALOG_CONTEXT, *PCOLUMNS_DIALOG_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpColumnsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhShowChooseColumnsDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HWND ControlHandle,
|
||||||
|
_In_ ULONG Type
|
||||||
|
)
|
||||||
|
{
|
||||||
|
COLUMNS_DIALOG_CONTEXT context;
|
||||||
|
|
||||||
|
context.ControlHandle = ControlHandle;
|
||||||
|
context.Type = Type;
|
||||||
|
|
||||||
|
if (Type == PH_CONTROL_TYPE_TREE_NEW)
|
||||||
|
context.Columns = PhCreateList(TreeNew_GetColumnCount(ControlHandle));
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_CHOOSECOLUMNS),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpColumnsDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
);
|
||||||
|
|
||||||
|
PhDereferenceObject(context.Columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __cdecl PhpColumnsCompareDisplayIndexTn(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN column1 = *(PPH_TREENEW_COLUMN *)elem1;
|
||||||
|
PPH_TREENEW_COLUMN column2 = *(PPH_TREENEW_COLUMN *)elem2;
|
||||||
|
|
||||||
|
return uintcmp(column1->DisplayIndex, column2->DisplayIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Success_(return != -1)
|
||||||
|
static ULONG IndexOfStringInList(
|
||||||
|
_In_ PPH_LIST List,
|
||||||
|
_In_ PWSTR String
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < List->Count; i++)
|
||||||
|
{
|
||||||
|
if (PhEqualString2(List->Items[i], String, FALSE))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpColumnsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PCOLUMNS_DIALOG_CONTEXT context = NULL;
|
||||||
|
|
||||||
|
if (uMsg == WM_INITDIALOG)
|
||||||
|
{
|
||||||
|
context = (PCOLUMNS_DIALOG_CONTEXT)lParam;
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context = (PCOLUMNS_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
ULONG count;
|
||||||
|
ULONG total;
|
||||||
|
ULONG i;
|
||||||
|
PPH_LIST displayOrderList = NULL;
|
||||||
|
|
||||||
|
context->InactiveList = GetDlgItem(hwndDlg, IDC_INACTIVE);
|
||||||
|
context->ActiveList = GetDlgItem(hwndDlg, IDC_ACTIVE);
|
||||||
|
|
||||||
|
if (context->Type == PH_CONTROL_TYPE_TREE_NEW)
|
||||||
|
{
|
||||||
|
PH_TREENEW_COLUMN column;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
total = TreeNew_GetColumnCount(context->ControlHandle);
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
displayOrderList = PhCreateList(total);
|
||||||
|
|
||||||
|
while (count < total)
|
||||||
|
{
|
||||||
|
if (TreeNew_GetColumn(context->ControlHandle, i, &column))
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN copy;
|
||||||
|
|
||||||
|
if (column.Fixed)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
total--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = PhAllocateCopy(&column, sizeof(PH_TREENEW_COLUMN));
|
||||||
|
PhAddItemList(context->Columns, copy);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (column.Visible)
|
||||||
|
{
|
||||||
|
PhAddItemList(displayOrderList, copy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ListBox_AddString(context->InactiveList, column.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(displayOrderList->Items, displayOrderList->Count, sizeof(PVOID), PhpColumnsCompareDisplayIndexTn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayOrderList)
|
||||||
|
{
|
||||||
|
for (i = 0; i < displayOrderList->Count; i++)
|
||||||
|
{
|
||||||
|
if (context->Type == PH_CONTROL_TYPE_TREE_NEW)
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN copy = displayOrderList->Items[i];
|
||||||
|
|
||||||
|
ListBox_AddString(context->ActiveList, copy->Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhDereferenceObject(displayOrderList);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_INACTIVE, LBN_SELCHANGE), (LPARAM)context->InactiveList);
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_ACTIVE, LBN_SELCHANGE), (LPARAM)context->ActiveList);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < context->Columns->Count; i++)
|
||||||
|
PhFree(context->Columns->Items[i]);
|
||||||
|
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
EndDialog(hwndDlg, IDCANCEL);
|
||||||
|
break;
|
||||||
|
case IDOK:
|
||||||
|
{
|
||||||
|
#define ORDER_LIMIT 100
|
||||||
|
PPH_LIST activeList;
|
||||||
|
ULONG activeCount;
|
||||||
|
ULONG i;
|
||||||
|
INT orderArray[ORDER_LIMIT];
|
||||||
|
INT maxOrder;
|
||||||
|
|
||||||
|
memset(orderArray, 0, sizeof(orderArray));
|
||||||
|
maxOrder = 0;
|
||||||
|
|
||||||
|
activeCount = ListBox_GetCount(context->ActiveList);
|
||||||
|
activeList = PhCreateList(activeCount);
|
||||||
|
|
||||||
|
for (i = 0; i < activeCount; i++)
|
||||||
|
PhAddItemList(activeList, PhGetListBoxString(context->ActiveList, i));
|
||||||
|
|
||||||
|
if (context->Type == PH_CONTROL_TYPE_TREE_NEW)
|
||||||
|
{
|
||||||
|
// Apply visiblity settings and build the order array.
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(context->ControlHandle, FALSE);
|
||||||
|
|
||||||
|
for (i = 0; i < context->Columns->Count; i++)
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN column = context->Columns->Items[i];
|
||||||
|
ULONG index;
|
||||||
|
|
||||||
|
index = IndexOfStringInList(activeList, column->Text);
|
||||||
|
column->Visible = index != -1;
|
||||||
|
|
||||||
|
TreeNew_SetColumn(context->ControlHandle, TN_COLUMN_FLAG_VISIBLE, column);
|
||||||
|
|
||||||
|
if (column->Visible && index < ORDER_LIMIT)
|
||||||
|
{
|
||||||
|
orderArray[index] = column->Id;
|
||||||
|
|
||||||
|
if ((ULONG)maxOrder < index + 1)
|
||||||
|
maxOrder = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply display order.
|
||||||
|
TreeNew_SetColumnOrderArray(context->ControlHandle, maxOrder, orderArray);
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(context->ControlHandle, TRUE);
|
||||||
|
|
||||||
|
PhDereferenceObject(activeList);
|
||||||
|
|
||||||
|
InvalidateRect(context->ControlHandle, NULL, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_INACTIVE:
|
||||||
|
{
|
||||||
|
switch (HIWORD(wParam))
|
||||||
|
{
|
||||||
|
case LBN_DBLCLK:
|
||||||
|
{
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, IDC_SHOW, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LBN_SELCHANGE:
|
||||||
|
{
|
||||||
|
INT sel = ListBox_GetCurSel(context->InactiveList);
|
||||||
|
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW), sel != -1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_ACTIVE:
|
||||||
|
{
|
||||||
|
switch (HIWORD(wParam))
|
||||||
|
{
|
||||||
|
case LBN_DBLCLK:
|
||||||
|
{
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, IDC_HIDE, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LBN_SELCHANGE:
|
||||||
|
{
|
||||||
|
INT sel = ListBox_GetCurSel(context->ActiveList);
|
||||||
|
INT count = ListBox_GetCount(context->ActiveList);
|
||||||
|
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_HIDE), sel != -1 && count != 1);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEUP), sel != 0 && sel != -1);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEDOWN), sel != count - 1 && sel != -1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_SHOW:
|
||||||
|
{
|
||||||
|
INT sel;
|
||||||
|
INT count;
|
||||||
|
PPH_STRING string;
|
||||||
|
|
||||||
|
sel = ListBox_GetCurSel(context->InactiveList);
|
||||||
|
count = ListBox_GetCount(context->InactiveList);
|
||||||
|
|
||||||
|
if (string = PhGetListBoxString(context->InactiveList, sel))
|
||||||
|
{
|
||||||
|
ListBox_DeleteString(context->InactiveList, sel);
|
||||||
|
ListBox_AddString(context->ActiveList, string->Buffer);
|
||||||
|
PhDereferenceObject(string);
|
||||||
|
|
||||||
|
count--;
|
||||||
|
|
||||||
|
if (sel >= count - 1)
|
||||||
|
sel = count - 1;
|
||||||
|
|
||||||
|
ListBox_SetCurSel(context->InactiveList, sel);
|
||||||
|
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_INACTIVE, LBN_SELCHANGE), (LPARAM)context->InactiveList);
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_ACTIVE, LBN_SELCHANGE), (LPARAM)context->ActiveList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_HIDE:
|
||||||
|
{
|
||||||
|
INT sel;
|
||||||
|
INT count;
|
||||||
|
PPH_STRING string;
|
||||||
|
|
||||||
|
sel = ListBox_GetCurSel(context->ActiveList);
|
||||||
|
count = ListBox_GetCount(context->ActiveList);
|
||||||
|
|
||||||
|
if (count != 1)
|
||||||
|
{
|
||||||
|
if (string = PhGetListBoxString(context->ActiveList, sel))
|
||||||
|
{
|
||||||
|
ListBox_DeleteString(context->ActiveList, sel);
|
||||||
|
ListBox_AddString(context->InactiveList, string->Buffer);
|
||||||
|
PhDereferenceObject(string);
|
||||||
|
|
||||||
|
count--;
|
||||||
|
|
||||||
|
if (sel >= count - 1)
|
||||||
|
sel = count - 1;
|
||||||
|
|
||||||
|
ListBox_SetCurSel(context->ActiveList, sel);
|
||||||
|
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_INACTIVE, LBN_SELCHANGE), (LPARAM)context->InactiveList);
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_ACTIVE, LBN_SELCHANGE), (LPARAM)context->ActiveList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_MOVEUP:
|
||||||
|
{
|
||||||
|
INT sel;
|
||||||
|
INT count;
|
||||||
|
PPH_STRING string;
|
||||||
|
|
||||||
|
sel = ListBox_GetCurSel(context->ActiveList);
|
||||||
|
count = ListBox_GetCount(context->ActiveList);
|
||||||
|
|
||||||
|
if (sel != 0)
|
||||||
|
{
|
||||||
|
if (string = PhGetListBoxString(context->ActiveList, sel))
|
||||||
|
{
|
||||||
|
ListBox_DeleteString(context->ActiveList, sel);
|
||||||
|
ListBox_InsertString(context->ActiveList, sel - 1, string->Buffer);
|
||||||
|
PhDereferenceObject(string);
|
||||||
|
|
||||||
|
sel -= 1;
|
||||||
|
ListBox_SetCurSel(context->ActiveList, sel);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEUP), sel != 0);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEDOWN), sel != count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_MOVEDOWN:
|
||||||
|
{
|
||||||
|
INT sel;
|
||||||
|
INT count;
|
||||||
|
PPH_STRING string;
|
||||||
|
|
||||||
|
sel = ListBox_GetCurSel(context->ActiveList);
|
||||||
|
count = ListBox_GetCount(context->ActiveList);
|
||||||
|
|
||||||
|
if (sel != count - 1)
|
||||||
|
{
|
||||||
|
if (string = PhGetListBoxString(context->ActiveList, sel))
|
||||||
|
{
|
||||||
|
ListBox_DeleteString(context->ActiveList, sel);
|
||||||
|
ListBox_InsertString(context->ActiveList, sel + 1, string->Buffer);
|
||||||
|
PhDereferenceObject(string);
|
||||||
|
|
||||||
|
sel += 1;
|
||||||
|
ListBox_SetCurSel(context->ActiveList, sel);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEUP), sel != 0);
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEDOWN), sel != count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
358
ProcessHacker/chdlg.c
Normal file
358
ProcessHacker/chdlg.c
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* choice dialog
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2013 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <settings.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
|
||||||
|
typedef struct _CHOICE_DIALOG_CONTEXT
|
||||||
|
{
|
||||||
|
PWSTR Title;
|
||||||
|
PWSTR Message;
|
||||||
|
PWSTR *Choices;
|
||||||
|
ULONG NumberOfChoices;
|
||||||
|
PWSTR Option;
|
||||||
|
ULONG Flags;
|
||||||
|
PPH_STRING *SelectedChoice;
|
||||||
|
PBOOLEAN SelectedOption;
|
||||||
|
PWSTR SavedChoicesSettingName;
|
||||||
|
|
||||||
|
HWND ComboBoxHandle;
|
||||||
|
} CHOICE_DIALOG_CONTEXT, *PCHOICE_DIALOG_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpChoiceDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompts the user for input.
|
||||||
|
*
|
||||||
|
* \remarks If \c PH_CHOICE_DIALOG_PASSWORD is specified, the string
|
||||||
|
* returned in \a SelectedChoice is NOT auto-dereferenced.
|
||||||
|
*/
|
||||||
|
BOOLEAN PhaChoiceDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ PWSTR Title,
|
||||||
|
_In_ PWSTR Message,
|
||||||
|
_In_opt_ PWSTR *Choices,
|
||||||
|
_In_opt_ ULONG NumberOfChoices,
|
||||||
|
_In_opt_ PWSTR Option,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_Inout_ PPH_STRING *SelectedChoice,
|
||||||
|
_Inout_opt_ PBOOLEAN SelectedOption,
|
||||||
|
_In_opt_ PWSTR SavedChoicesSettingName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHOICE_DIALOG_CONTEXT context;
|
||||||
|
|
||||||
|
context.Title = Title;
|
||||||
|
context.Message = Message;
|
||||||
|
context.Choices = Choices;
|
||||||
|
context.NumberOfChoices = NumberOfChoices;
|
||||||
|
context.Option = Option;
|
||||||
|
context.Flags = Flags;
|
||||||
|
context.SelectedChoice = SelectedChoice;
|
||||||
|
context.SelectedOption = SelectedOption;
|
||||||
|
context.SavedChoicesSettingName = SavedChoicesSettingName;
|
||||||
|
|
||||||
|
return DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_CHOOSE),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpChoiceDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
) == IDOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpChoiceDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)lParam;
|
||||||
|
ULONG type;
|
||||||
|
SIZE_T i;
|
||||||
|
HWND comboBoxHandle;
|
||||||
|
HWND checkBoxHandle;
|
||||||
|
RECT checkBoxRect;
|
||||||
|
RECT rect;
|
||||||
|
ULONG diff;
|
||||||
|
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||||
|
|
||||||
|
SetWindowText(hwndDlg, context->Title);
|
||||||
|
SetWindowText(GetDlgItem(hwndDlg, IDC_MESSAGE), context->Message);
|
||||||
|
|
||||||
|
type = context->Flags & PH_CHOICE_DIALOG_TYPE_MASK;
|
||||||
|
|
||||||
|
// Select the control to show, depending on the type. This is
|
||||||
|
// because it is impossible to change the style of the combo box
|
||||||
|
// after it is created.
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PH_CHOICE_DIALOG_USER_CHOICE:
|
||||||
|
comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICEUSER);
|
||||||
|
ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICEUSER), SW_SHOW);
|
||||||
|
break;
|
||||||
|
case PH_CHOICE_DIALOG_PASSWORD:
|
||||||
|
comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICESIMPLE);
|
||||||
|
ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICESIMPLE), SW_SHOW);
|
||||||
|
|
||||||
|
// Disable combo box features since it isn't a combo box.
|
||||||
|
context->SavedChoicesSettingName = NULL;
|
||||||
|
break;
|
||||||
|
case PH_CHOICE_DIALOG_CHOICE:
|
||||||
|
default:
|
||||||
|
comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICE);
|
||||||
|
ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICE), SW_SHOW);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->ComboBoxHandle = comboBoxHandle;
|
||||||
|
|
||||||
|
checkBoxHandle = GetDlgItem(hwndDlg, IDC_OPTION);
|
||||||
|
|
||||||
|
if (type == PH_CHOICE_DIALOG_PASSWORD)
|
||||||
|
{
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
else if (type == PH_CHOICE_DIALOG_USER_CHOICE && context->SavedChoicesSettingName)
|
||||||
|
{
|
||||||
|
PPH_STRING savedChoices = PhGetStringSetting(context->SavedChoicesSettingName);
|
||||||
|
ULONG_PTR indexOfDelim;
|
||||||
|
PPH_STRING savedChoice;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
// Split the saved choices using the delimiter.
|
||||||
|
while (i < savedChoices->Length / 2)
|
||||||
|
{
|
||||||
|
// BUG BUG BUG - what if the user saves "\s"?
|
||||||
|
indexOfDelim = PhFindStringInString(savedChoices, i, L"\\s");
|
||||||
|
|
||||||
|
if (indexOfDelim == -1)
|
||||||
|
indexOfDelim = savedChoices->Length / 2;
|
||||||
|
|
||||||
|
savedChoice = PhSubstring(savedChoices, i, indexOfDelim - i);
|
||||||
|
|
||||||
|
if (savedChoice->Length != 0)
|
||||||
|
{
|
||||||
|
PPH_STRING unescaped;
|
||||||
|
|
||||||
|
unescaped = PhUnescapeStringForDelimiter(savedChoice, '\\');
|
||||||
|
ComboBox_InsertString(comboBoxHandle, -1, unescaped->Buffer);
|
||||||
|
PhDereferenceObject(unescaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhDereferenceObject(savedChoice);
|
||||||
|
|
||||||
|
i = indexOfDelim + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhDereferenceObject(savedChoices);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < context->NumberOfChoices; i++)
|
||||||
|
{
|
||||||
|
ComboBox_AddString(comboBoxHandle, context->Choices[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
context->SavedChoicesSettingName = NULL; // make sure we don't try to save the choices
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == PH_CHOICE_DIALOG_PASSWORD)
|
||||||
|
{
|
||||||
|
if (*context->SelectedChoice)
|
||||||
|
SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer);
|
||||||
|
|
||||||
|
Edit_SetSel(comboBoxHandle, 0, -1);
|
||||||
|
}
|
||||||
|
else if (type == PH_CHOICE_DIALOG_USER_CHOICE || type == PH_CHOICE_DIALOG_CHOICE)
|
||||||
|
{
|
||||||
|
// If we failed to choose a default choice based on what was specified,
|
||||||
|
// select the first one if possible, or set the text directly.
|
||||||
|
if (!(*context->SelectedChoice) || PhSelectComboBoxString(
|
||||||
|
comboBoxHandle, (*context->SelectedChoice)->Buffer, FALSE) == CB_ERR)
|
||||||
|
{
|
||||||
|
if (type == PH_CHOICE_DIALOG_USER_CHOICE && *context->SelectedChoice)
|
||||||
|
{
|
||||||
|
SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer);
|
||||||
|
}
|
||||||
|
else if (type == PH_CHOICE_DIALOG_CHOICE && context->NumberOfChoices != 0)
|
||||||
|
{
|
||||||
|
ComboBox_SetCurSel(comboBoxHandle, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == PH_CHOICE_DIALOG_USER_CHOICE)
|
||||||
|
ComboBox_SetEditSel(comboBoxHandle, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->Option)
|
||||||
|
{
|
||||||
|
SetWindowText(checkBoxHandle, context->Option);
|
||||||
|
|
||||||
|
if (context->SelectedOption)
|
||||||
|
Button_SetCheck(checkBoxHandle, *context->SelectedOption ? BST_CHECKED : BST_UNCHECKED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hide the check box and move the buttons up.
|
||||||
|
|
||||||
|
ShowWindow(checkBoxHandle, SW_HIDE);
|
||||||
|
GetWindowRect(checkBoxHandle, &checkBoxRect);
|
||||||
|
MapWindowPoints(NULL, hwndDlg, (POINT *)&checkBoxRect, 2);
|
||||||
|
GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect);
|
||||||
|
MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2);
|
||||||
|
diff = rect.top - checkBoxRect.top;
|
||||||
|
|
||||||
|
// OK
|
||||||
|
rect.top -= diff;
|
||||||
|
rect.bottom -= diff;
|
||||||
|
SetWindowPos(GetDlgItem(hwndDlg, IDOK), NULL, rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rect);
|
||||||
|
MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2);
|
||||||
|
rect.top -= diff;
|
||||||
|
rect.bottom -= diff;
|
||||||
|
SetWindowPos(GetDlgItem(hwndDlg, IDCANCEL), NULL, rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
|
||||||
|
// Window
|
||||||
|
GetWindowRect(hwndDlg, &rect);
|
||||||
|
rect.bottom -= diff;
|
||||||
|
SetWindowPos(hwndDlg, NULL, rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)comboBoxHandle, TRUE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
EndDialog(hwndDlg, IDCANCEL);
|
||||||
|
break;
|
||||||
|
case IDOK:
|
||||||
|
{
|
||||||
|
PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
PPH_STRING selectedChoice;
|
||||||
|
|
||||||
|
if ((context->Flags & PH_CHOICE_DIALOG_TYPE_MASK) != PH_CHOICE_DIALOG_PASSWORD)
|
||||||
|
{
|
||||||
|
selectedChoice = PH_AUTO(PhGetWindowText(context->ComboBoxHandle));
|
||||||
|
*context->SelectedChoice = selectedChoice;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Password values are never auto-dereferenced.
|
||||||
|
selectedChoice = PhGetWindowText(context->ComboBoxHandle);
|
||||||
|
*context->SelectedChoice = selectedChoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->Option && context->SelectedOption)
|
||||||
|
*context->SelectedOption = Button_GetCheck(GetDlgItem(hwndDlg, IDC_OPTION)) == BST_CHECKED;
|
||||||
|
|
||||||
|
if (context->SavedChoicesSettingName)
|
||||||
|
{
|
||||||
|
PH_STRING_BUILDER savedChoices;
|
||||||
|
ULONG i;
|
||||||
|
ULONG choicesToSave = PH_CHOICE_DIALOG_SAVED_CHOICES;
|
||||||
|
PPH_STRING choice;
|
||||||
|
PPH_STRING escaped;
|
||||||
|
|
||||||
|
PhInitializeStringBuilder(&savedChoices, 100);
|
||||||
|
|
||||||
|
// Push the selected choice to the top, then save the others.
|
||||||
|
|
||||||
|
if (selectedChoice->Length != 0)
|
||||||
|
{
|
||||||
|
escaped = PhEscapeStringForDelimiter(selectedChoice, '\\');
|
||||||
|
PhAppendStringBuilder(&savedChoices, &escaped->sr);
|
||||||
|
PhDereferenceObject(escaped);
|
||||||
|
PhAppendStringBuilder2(&savedChoices, L"\\s");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < choicesToSave; i++)
|
||||||
|
{
|
||||||
|
choice = PhGetComboBoxString(context->ComboBoxHandle, i - 1);
|
||||||
|
|
||||||
|
if (!choice)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Don't save the choice if it's the same as the one
|
||||||
|
// entered by the user (since we already saved it above).
|
||||||
|
if (PhEqualString(choice, selectedChoice, FALSE))
|
||||||
|
{
|
||||||
|
PhDereferenceObject(choice);
|
||||||
|
choicesToSave++; // useless for now, but may be needed in the future
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
escaped = PhEscapeStringForDelimiter(choice, '\\');
|
||||||
|
PhAppendStringBuilder(&savedChoices, &escaped->sr);
|
||||||
|
PhDereferenceObject(escaped);
|
||||||
|
PhDereferenceObject(choice);
|
||||||
|
|
||||||
|
PhAppendStringBuilder2(&savedChoices, L"\\s");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhEndsWithString2(savedChoices.String, L"\\s", FALSE))
|
||||||
|
PhRemoveEndStringBuilder(&savedChoices, 2);
|
||||||
|
|
||||||
|
PhSetStringSetting2(context->SavedChoicesSettingName, &savedChoices.String->sr);
|
||||||
|
PhDeleteStringBuilder(&savedChoices);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
315
ProcessHacker/chproc.c
Normal file
315
ProcessHacker/chproc.c
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* choose process dialog
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <lsasup.h>
|
||||||
|
|
||||||
|
typedef struct _CHOOSE_PROCESS_DIALOG_CONTEXT
|
||||||
|
{
|
||||||
|
PWSTR Message;
|
||||||
|
HANDLE ProcessId;
|
||||||
|
|
||||||
|
PH_LAYOUT_MANAGER LayoutManager;
|
||||||
|
RECT MinimumSize;
|
||||||
|
HIMAGELIST ImageList;
|
||||||
|
HWND ListViewHandle;
|
||||||
|
} CHOOSE_PROCESS_DIALOG_CONTEXT, *PCHOOSE_PROCESS_DIALOG_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpChooseProcessDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhShowChooseProcessDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ PWSTR Message,
|
||||||
|
_Out_ PHANDLE ProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHOOSE_PROCESS_DIALOG_CONTEXT context;
|
||||||
|
|
||||||
|
context.Message = Message;
|
||||||
|
context.ProcessId = NULL;
|
||||||
|
|
||||||
|
if (DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_CHOOSEPROCESS),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpChooseProcessDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
) == IDOK)
|
||||||
|
{
|
||||||
|
*ProcessId = context.ProcessId;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID PhpRefreshProcessList(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ PCHOOSE_PROCESS_DIALOG_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
HWND lvHandle;
|
||||||
|
PVOID processes;
|
||||||
|
PSYSTEM_PROCESS_INFORMATION process;
|
||||||
|
|
||||||
|
lvHandle = Context->ListViewHandle;
|
||||||
|
|
||||||
|
ListView_DeleteAllItems(lvHandle);
|
||||||
|
ImageList_RemoveAll(Context->ImageList);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
|
||||||
|
{
|
||||||
|
PhShowStatus(hwndDlg, L"Unable to enumerate processes", status, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedListView_SetRedraw(lvHandle, FALSE);
|
||||||
|
|
||||||
|
process = PH_FIRST_PROCESS(processes);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
INT lvItemIndex;
|
||||||
|
PPH_STRING name;
|
||||||
|
HANDLE processHandle;
|
||||||
|
PPH_STRING fileName = NULL;
|
||||||
|
HICON icon = NULL;
|
||||||
|
WCHAR processIdString[PH_INT32_STR_LEN_1];
|
||||||
|
PPH_STRING userName = NULL;
|
||||||
|
INT imageIndex;
|
||||||
|
|
||||||
|
if (process->UniqueProcessId != SYSTEM_IDLE_PROCESS_ID)
|
||||||
|
name = PhCreateStringFromUnicodeString(&process->ImageName);
|
||||||
|
else
|
||||||
|
name = PhCreateString(SYSTEM_IDLE_PROCESS_NAME);
|
||||||
|
|
||||||
|
lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, name->Buffer, process->UniqueProcessId);
|
||||||
|
PhDereferenceObject(name);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess, process->UniqueProcessId)))
|
||||||
|
{
|
||||||
|
HANDLE tokenHandle;
|
||||||
|
PTOKEN_USER user;
|
||||||
|
|
||||||
|
if (!WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID)
|
||||||
|
PhGetProcessImageFileName(processHandle, &fileName);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhOpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhGetTokenUser(tokenHandle, &user)))
|
||||||
|
{
|
||||||
|
userName = PhGetSidFullName(user->User.Sid, TRUE, NULL);
|
||||||
|
PhFree(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(tokenHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process->UniqueProcessId == SYSTEM_IDLE_PROCESS_ID && !userName && PhLocalSystemName)
|
||||||
|
PhSetReference(&userName, PhLocalSystemName);
|
||||||
|
|
||||||
|
if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID)
|
||||||
|
PhGetProcessImageFileNameByProcessId(process->UniqueProcessId, &fileName);
|
||||||
|
|
||||||
|
if (process->UniqueProcessId == SYSTEM_PROCESS_ID)
|
||||||
|
fileName = PhGetKernelFileName();
|
||||||
|
|
||||||
|
if (fileName)
|
||||||
|
PhMoveReference(&fileName, PhGetFileName(fileName));
|
||||||
|
|
||||||
|
icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", FALSE);
|
||||||
|
|
||||||
|
// Icon
|
||||||
|
if (icon)
|
||||||
|
{
|
||||||
|
imageIndex = ImageList_AddIcon(Context->ImageList, icon);
|
||||||
|
PhSetListViewItemImageIndex(Context->ListViewHandle, lvItemIndex, imageIndex);
|
||||||
|
DestroyIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PID
|
||||||
|
PhPrintUInt32(processIdString, HandleToUlong(process->UniqueProcessId));
|
||||||
|
PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 1, processIdString);
|
||||||
|
|
||||||
|
// User Name
|
||||||
|
PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 2, PhGetString(userName));
|
||||||
|
|
||||||
|
if (userName) PhDereferenceObject(userName);
|
||||||
|
if (fileName) PhDereferenceObject(fileName);
|
||||||
|
} while (process = PH_NEXT_PROCESS(process));
|
||||||
|
|
||||||
|
PhFree(processes);
|
||||||
|
|
||||||
|
ExtendedListView_SortItems(lvHandle);
|
||||||
|
ExtendedListView_SetRedraw(lvHandle, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpChooseProcessDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PCHOOSE_PROCESS_DIALOG_CONTEXT context = NULL;
|
||||||
|
|
||||||
|
if (uMsg == WM_INITDIALOG)
|
||||||
|
{
|
||||||
|
context = (PCHOOSE_PROCESS_DIALOG_CONTEXT)lParam;
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context = (PCHOOSE_PROCESS_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
|
||||||
|
if (uMsg == WM_DESTROY)
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
HWND lvHandle;
|
||||||
|
|
||||||
|
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||||
|
|
||||||
|
SetDlgItemText(hwndDlg, IDC_MESSAGE, context->Message);
|
||||||
|
|
||||||
|
PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);
|
||||||
|
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MESSAGE), NULL,
|
||||||
|
PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE);
|
||||||
|
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LIST), NULL,
|
||||||
|
PH_ANCHOR_ALL);
|
||||||
|
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL,
|
||||||
|
PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
|
||||||
|
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDCANCEL), NULL,
|
||||||
|
PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
|
||||||
|
PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_REFRESH), NULL,
|
||||||
|
PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
|
||||||
|
PhLayoutManagerLayout(&context->LayoutManager);
|
||||||
|
|
||||||
|
context->MinimumSize.left = 0;
|
||||||
|
context->MinimumSize.top = 0;
|
||||||
|
context->MinimumSize.right = 280;
|
||||||
|
context->MinimumSize.bottom = 170;
|
||||||
|
MapDialogRect(hwndDlg, &context->MinimumSize);
|
||||||
|
|
||||||
|
context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
|
||||||
|
context->ImageList = ImageList_Create(PhSmallIconSize.X, PhSmallIconSize.Y, ILC_COLOR32 | ILC_MASK, 0, 40);
|
||||||
|
|
||||||
|
PhSetListViewStyle(lvHandle, FALSE, TRUE);
|
||||||
|
PhSetControlTheme(lvHandle, L"explorer");
|
||||||
|
PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 180, L"Name");
|
||||||
|
PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 60, L"PID");
|
||||||
|
PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 160, L"User name");
|
||||||
|
PhSetExtendedListView(lvHandle);
|
||||||
|
|
||||||
|
ListView_SetImageList(lvHandle, context->ImageList, LVSIL_SMALL);
|
||||||
|
|
||||||
|
PhpRefreshProcessList(hwndDlg, context);
|
||||||
|
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
ImageList_Destroy(context->ImageList);
|
||||||
|
PhDeleteLayoutManager(&context->LayoutManager);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
{
|
||||||
|
EndDialog(hwndDlg, IDCANCEL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDOK:
|
||||||
|
{
|
||||||
|
if (ListView_GetSelectedCount(context->ListViewHandle) == 1)
|
||||||
|
{
|
||||||
|
context->ProcessId = (HANDLE)PhGetSelectedListViewItemParam(context->ListViewHandle);
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IDC_REFRESH:
|
||||||
|
{
|
||||||
|
PhpRefreshProcessList(hwndDlg, context);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
LPNMHDR header = (LPNMHDR)lParam;
|
||||||
|
|
||||||
|
switch (header->code)
|
||||||
|
{
|
||||||
|
case LVN_ITEMCHANGED:
|
||||||
|
{
|
||||||
|
EnableWindow(GetDlgItem(hwndDlg, IDOK), ListView_GetSelectedCount(context->ListViewHandle) == 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NM_DBLCLK:
|
||||||
|
{
|
||||||
|
SendMessage(hwndDlg, WM_COMMAND, IDOK, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
PhLayoutManagerLayout(&context->LayoutManager);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_SIZING:
|
||||||
|
{
|
||||||
|
PhResizingMinimumSize((PRECT)lParam, wParam, context->MinimumSize.right, context->MinimumSize.bottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
451
ProcessHacker/cmdmode.c
Normal file
451
ProcessHacker/cmdmode.c
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* command line action mode
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2012 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <svcsup.h>
|
||||||
|
|
||||||
|
NTSTATUS PhpGetDllBaseRemote(
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_In_ PPH_STRINGREF BaseDllName,
|
||||||
|
_Out_ PVOID *DllBase
|
||||||
|
);
|
||||||
|
|
||||||
|
static HWND CommandModeWindowHandle;
|
||||||
|
|
||||||
|
#define PH_COMMAND_OPTION_HWND 1
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PhpCommandModeOptionCallback(
|
||||||
|
_In_opt_ PPH_COMMAND_LINE_OPTION Option,
|
||||||
|
_In_opt_ PPH_STRING Value,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG64 integer;
|
||||||
|
|
||||||
|
if (Option)
|
||||||
|
{
|
||||||
|
switch (Option->Id)
|
||||||
|
{
|
||||||
|
case PH_COMMAND_OPTION_HWND:
|
||||||
|
if (PhStringToInteger64(&Value->sr, 10, &integer))
|
||||||
|
CommandModeWindowHandle = (HWND)integer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS PhCommandModeStart(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
static PH_COMMAND_LINE_OPTION options[] =
|
||||||
|
{
|
||||||
|
{ PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType }
|
||||||
|
};
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
PH_STRINGREF commandLine;
|
||||||
|
|
||||||
|
PhUnicodeStringToStringRef(&NtCurrentPeb()->ProcessParameters->CommandLine, &commandLine);
|
||||||
|
|
||||||
|
PhParseCommandLine(
|
||||||
|
&commandLine,
|
||||||
|
options,
|
||||||
|
sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
|
||||||
|
PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS,
|
||||||
|
PhpCommandModeOptionCallback,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE))
|
||||||
|
{
|
||||||
|
SIZE_T i;
|
||||||
|
SIZE_T processIdLength;
|
||||||
|
HANDLE processId;
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandObject)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
processIdLength = PhStartupParameters.CommandObject->Length / 2;
|
||||||
|
|
||||||
|
for (i = 0; i < processIdLength; i++)
|
||||||
|
{
|
||||||
|
if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == processIdLength)
|
||||||
|
{
|
||||||
|
ULONG64 processId64;
|
||||||
|
|
||||||
|
if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
processId = (HANDLE)processId64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PVOID processes;
|
||||||
|
PSYSTEM_PROCESS_INFORMATION process;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr)))
|
||||||
|
{
|
||||||
|
PhFree(processes);
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
processId = process->UniqueProcessId;
|
||||||
|
PhFree(processes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId)))
|
||||||
|
{
|
||||||
|
status = NtTerminateProcess(processHandle, STATUS_SUCCESS);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
|
||||||
|
{
|
||||||
|
status = NtSuspendProcess(processHandle);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
|
||||||
|
{
|
||||||
|
status = NtResumeProcess(processHandle);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE))
|
||||||
|
{
|
||||||
|
UCHAR priority;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandValue)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_IDLE;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_NORMAL;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_HIGH;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_REALTIME;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE))
|
||||||
|
priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
|
||||||
|
else
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
|
||||||
|
{
|
||||||
|
PROCESS_PRIORITY_CLASS priorityClass;
|
||||||
|
priorityClass.Foreground = FALSE;
|
||||||
|
priorityClass.PriorityClass = priority;
|
||||||
|
status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS));
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE))
|
||||||
|
{
|
||||||
|
ULONG ioPriority;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandValue)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE))
|
||||||
|
ioPriority = 0;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE))
|
||||||
|
ioPriority = 1;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
|
||||||
|
ioPriority = 2;
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
|
||||||
|
ioPriority = 3;
|
||||||
|
else
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
|
||||||
|
{
|
||||||
|
status = PhSetProcessIoPriority(processHandle, ioPriority);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE))
|
||||||
|
{
|
||||||
|
ULONG64 pagePriority64;
|
||||||
|
ULONG pagePriority;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandValue)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64);
|
||||||
|
pagePriority = (ULONG)pagePriority64;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
|
||||||
|
{
|
||||||
|
status = NtSetInformationProcess(
|
||||||
|
processHandle,
|
||||||
|
ProcessPagePriority,
|
||||||
|
&pagePriority,
|
||||||
|
sizeof(ULONG)
|
||||||
|
);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE))
|
||||||
|
{
|
||||||
|
if (!PhStartupParameters.CommandValue)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
|
||||||
|
processId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
LARGE_INTEGER timeout;
|
||||||
|
|
||||||
|
timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
|
||||||
|
status = PhInjectDllProcess(
|
||||||
|
processHandle,
|
||||||
|
PhStartupParameters.CommandValue->Buffer,
|
||||||
|
&timeout
|
||||||
|
);
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE))
|
||||||
|
{
|
||||||
|
if (!PhStartupParameters.CommandValue)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhOpenProcessPublic(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
|
||||||
|
processId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
PVOID baseAddress;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = PhpGetDllBaseRemote(
|
||||||
|
processHandle,
|
||||||
|
&PhStartupParameters.CommandValue->sr,
|
||||||
|
&baseAddress
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
LARGE_INTEGER timeout;
|
||||||
|
|
||||||
|
timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
|
||||||
|
status = PhUnloadDllProcess(
|
||||||
|
processHandle,
|
||||||
|
baseAddress,
|
||||||
|
&timeout
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE))
|
||||||
|
{
|
||||||
|
SC_HANDLE serviceHandle;
|
||||||
|
SERVICE_STATUS serviceStatus;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandObject)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE))
|
||||||
|
{
|
||||||
|
if (!(serviceHandle = PhOpenService(
|
||||||
|
PhStartupParameters.CommandObject->Buffer,
|
||||||
|
SERVICE_START
|
||||||
|
)))
|
||||||
|
return PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
if (!StartService(serviceHandle, 0, NULL))
|
||||||
|
status = PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
CloseServiceHandle(serviceHandle);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE))
|
||||||
|
{
|
||||||
|
if (!(serviceHandle = PhOpenService(
|
||||||
|
PhStartupParameters.CommandObject->Buffer,
|
||||||
|
SERVICE_PAUSE_CONTINUE
|
||||||
|
)))
|
||||||
|
return PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus))
|
||||||
|
status = PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
CloseServiceHandle(serviceHandle);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE))
|
||||||
|
{
|
||||||
|
if (!(serviceHandle = PhOpenService(
|
||||||
|
PhStartupParameters.CommandObject->Buffer,
|
||||||
|
SERVICE_PAUSE_CONTINUE
|
||||||
|
)))
|
||||||
|
return PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus))
|
||||||
|
status = PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
CloseServiceHandle(serviceHandle);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE))
|
||||||
|
{
|
||||||
|
if (!(serviceHandle = PhOpenService(
|
||||||
|
PhStartupParameters.CommandObject->Buffer,
|
||||||
|
SERVICE_STOP
|
||||||
|
)))
|
||||||
|
return PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus))
|
||||||
|
status = PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
CloseServiceHandle(serviceHandle);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE))
|
||||||
|
{
|
||||||
|
if (!(serviceHandle = PhOpenService(
|
||||||
|
PhStartupParameters.CommandObject->Buffer,
|
||||||
|
DELETE
|
||||||
|
)))
|
||||||
|
return PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
if (!DeleteService(serviceHandle))
|
||||||
|
status = PhGetLastWin32ErrorAsNtStatus();
|
||||||
|
|
||||||
|
CloseServiceHandle(serviceHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE))
|
||||||
|
{
|
||||||
|
ULONG64 threadId64;
|
||||||
|
HANDLE threadId;
|
||||||
|
HANDLE threadHandle;
|
||||||
|
|
||||||
|
if (!PhStartupParameters.CommandObject)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
threadId = (HANDLE)threadId64;
|
||||||
|
|
||||||
|
if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId)))
|
||||||
|
{
|
||||||
|
status = NtTerminateThread(threadHandle, STATUS_SUCCESS);
|
||||||
|
NtClose(threadHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
|
||||||
|
{
|
||||||
|
status = NtSuspendThread(threadHandle, NULL);
|
||||||
|
NtClose(threadHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
|
||||||
|
{
|
||||||
|
status = NtResumeThread(threadHandle, NULL);
|
||||||
|
NtClose(threadHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _GET_DLL_BASE_REMOTE_CONTEXT
|
||||||
|
{
|
||||||
|
PH_STRINGREF BaseDllName;
|
||||||
|
PVOID DllBase;
|
||||||
|
} GET_DLL_BASE_REMOTE_CONTEXT, *PGET_DLL_BASE_REMOTE_CONTEXT;
|
||||||
|
|
||||||
|
static BOOLEAN PhpGetDllBaseRemoteCallback(
|
||||||
|
_In_ PLDR_DATA_TABLE_ENTRY Module,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PGET_DLL_BASE_REMOTE_CONTEXT context = Context;
|
||||||
|
PH_STRINGREF baseDllName;
|
||||||
|
|
||||||
|
PhUnicodeStringToStringRef(&Module->BaseDllName, &baseDllName);
|
||||||
|
|
||||||
|
if (PhEqualStringRef(&baseDllName, &context->BaseDllName, TRUE))
|
||||||
|
{
|
||||||
|
context->DllBase = Module->DllBase;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS PhpGetDllBaseRemote(
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_In_ PPH_STRINGREF BaseDllName,
|
||||||
|
_Out_ PVOID *DllBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
GET_DLL_BASE_REMOTE_CONTEXT context;
|
||||||
|
#ifdef _WIN64
|
||||||
|
BOOLEAN isWow64 = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
context.BaseDllName = *BaseDllName;
|
||||||
|
context.DllBase = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
PhGetProcessIsWow64(ProcessHandle, &isWow64);
|
||||||
|
|
||||||
|
if (isWow64)
|
||||||
|
status = PhEnumProcessModules32(ProcessHandle, PhpGetDllBaseRemoteCallback, &context);
|
||||||
|
if (!context.DllBase)
|
||||||
|
#endif
|
||||||
|
status = PhEnumProcessModules(ProcessHandle, PhpGetDllBaseRemoteCallback, &context);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
*DllBase = context.DllBase;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
709
ProcessHacker/colmgr.c
Normal file
709
ProcessHacker/colmgr.c
Normal file
@ -0,0 +1,709 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* tree new column manager
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <extmgri.h>
|
||||||
|
#include <phplug.h>
|
||||||
|
#include <colmgr.h>
|
||||||
|
|
||||||
|
typedef struct _PH_CM_SORT_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_PLUGIN_TREENEW_SORT_FUNCTION SortFunction;
|
||||||
|
ULONG SubId;
|
||||||
|
PVOID Context;
|
||||||
|
PPH_CM_POST_SORT_FUNCTION PostSortFunction;
|
||||||
|
PH_SORT_ORDER SortOrder;
|
||||||
|
} PH_CM_SORT_CONTEXT, *PPH_CM_SORT_CONTEXT;
|
||||||
|
|
||||||
|
VOID PhCmInitializeManager(
|
||||||
|
_Out_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ HWND Handle,
|
||||||
|
_In_ ULONG MinId,
|
||||||
|
_In_ PPH_CM_POST_SORT_FUNCTION PostSortFunction
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Manager->Handle = Handle;
|
||||||
|
Manager->MinId = MinId;
|
||||||
|
Manager->NextId = MinId;
|
||||||
|
Manager->PostSortFunction = PostSortFunction;
|
||||||
|
InitializeListHead(&Manager->ColumnListHead);
|
||||||
|
Manager->NotifyList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhCmDeleteManager(
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY listEntry;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
|
||||||
|
listEntry = Manager->ColumnListHead.Flink;
|
||||||
|
|
||||||
|
while (listEntry != &Manager->ColumnListHead)
|
||||||
|
{
|
||||||
|
column = CONTAINING_RECORD(listEntry, PH_CM_COLUMN, ListEntry);
|
||||||
|
listEntry = listEntry->Flink;
|
||||||
|
|
||||||
|
PhFree(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Manager->NotifyList)
|
||||||
|
PhDereferenceObject(Manager->NotifyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_CM_COLUMN PhCmCreateColumn(
|
||||||
|
_Inout_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ PPH_TREENEW_COLUMN Column,
|
||||||
|
_In_ struct _PH_PLUGIN *Plugin,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_ PVOID SortFunction
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
PH_TREENEW_COLUMN tnColumn;
|
||||||
|
|
||||||
|
column = PhAllocate(sizeof(PH_CM_COLUMN));
|
||||||
|
memset(column, 0, sizeof(PH_CM_COLUMN));
|
||||||
|
column->Id = Manager->NextId++;
|
||||||
|
column->Plugin = Plugin;
|
||||||
|
column->SubId = SubId;
|
||||||
|
column->Context = Context;
|
||||||
|
column->SortFunction = SortFunction;
|
||||||
|
InsertTailList(&Manager->ColumnListHead, &column->ListEntry);
|
||||||
|
|
||||||
|
memset(&tnColumn, 0, sizeof(PH_TREENEW_COLUMN));
|
||||||
|
tnColumn.Id = column->Id;
|
||||||
|
tnColumn.Context = column;
|
||||||
|
tnColumn.Visible = Column->Visible;
|
||||||
|
tnColumn.CustomDraw = Column->CustomDraw;
|
||||||
|
tnColumn.SortDescending = Column->SortDescending;
|
||||||
|
tnColumn.Text = Column->Text;
|
||||||
|
tnColumn.Width = Column->Width;
|
||||||
|
tnColumn.Alignment = Column->Alignment;
|
||||||
|
tnColumn.DisplayIndex = Column->Visible ? Column->DisplayIndex : -1;
|
||||||
|
tnColumn.TextFlags = Column->TextFlags;
|
||||||
|
TreeNew_AddColumn(Manager->Handle, &tnColumn);
|
||||||
|
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_CM_COLUMN PhCmFindColumn(
|
||||||
|
_In_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ PPH_STRINGREF PluginName,
|
||||||
|
_In_ ULONG SubId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY listEntry;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
|
||||||
|
listEntry = Manager->ColumnListHead.Flink;
|
||||||
|
|
||||||
|
while (listEntry != &Manager->ColumnListHead)
|
||||||
|
{
|
||||||
|
column = CONTAINING_RECORD(listEntry, PH_CM_COLUMN, ListEntry);
|
||||||
|
|
||||||
|
if (column->SubId == SubId && PhEqualStringRef(PluginName, &column->Plugin->AppContext.AppName, FALSE))
|
||||||
|
return column;
|
||||||
|
|
||||||
|
listEntry = listEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhCmSetNotifyPlugin(
|
||||||
|
_In_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ struct _PH_PLUGIN *Plugin
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!Manager->NotifyList)
|
||||||
|
{
|
||||||
|
Manager->NotifyList = PhCreateList(8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PhFindItemList(Manager->NotifyList, Plugin) != -1)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhAddItemList(Manager->NotifyList, Plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhCmForwardMessage(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ PH_TREENEW_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2,
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_PLUGIN_TREENEW_MESSAGE pluginMessage;
|
||||||
|
PPH_PLUGIN plugin;
|
||||||
|
|
||||||
|
if (Message == TreeNewDestroying)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (Message)
|
||||||
|
{
|
||||||
|
case TreeNewGetCellText:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_GET_CELL_TEXT getCellText = Parameter1;
|
||||||
|
PH_TREENEW_COLUMN tnColumn;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
|
||||||
|
if (getCellText->Id < Manager->MinId)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!TreeNew_GetColumn(hwnd, getCellText->Id, &tnColumn))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
column = tnColumn.Context;
|
||||||
|
pluginMessage.SubId = column->SubId;
|
||||||
|
pluginMessage.Context = column->Context;
|
||||||
|
plugin = column->Plugin;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TreeNewCustomDraw:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_CUSTOM_DRAW customDraw = Parameter1;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
|
||||||
|
if (customDraw->Column->Id < Manager->MinId)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
column = customDraw->Column->Context;
|
||||||
|
pluginMessage.SubId = column->SubId;
|
||||||
|
pluginMessage.Context = column->Context;
|
||||||
|
plugin = column->Plugin;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TreeNewColumnResized:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN tlColumn = Parameter1;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
|
||||||
|
if (tlColumn->Id < Manager->MinId)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
column = tlColumn->Context;
|
||||||
|
pluginMessage.SubId = column->SubId;
|
||||||
|
pluginMessage.Context = column->Context;
|
||||||
|
plugin = column->Plugin;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// Some plugins want to be notified about all messages.
|
||||||
|
if (Manager->NotifyList)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < Manager->NotifyList->Count; i++)
|
||||||
|
{
|
||||||
|
plugin = Manager->NotifyList->Items[i];
|
||||||
|
|
||||||
|
pluginMessage.TreeNewHandle = hwnd;
|
||||||
|
pluginMessage.Message = Message;
|
||||||
|
pluginMessage.Parameter1 = Parameter1;
|
||||||
|
pluginMessage.Parameter2 = Parameter2;
|
||||||
|
pluginMessage.SubId = 0;
|
||||||
|
pluginMessage.Context = NULL;
|
||||||
|
|
||||||
|
PhInvokeCallback(PhGetPluginCallback(plugin, PluginCallbackTreeNewMessage), &pluginMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginMessage.TreeNewHandle = hwnd;
|
||||||
|
pluginMessage.Message = Message;
|
||||||
|
pluginMessage.Parameter1 = Parameter1;
|
||||||
|
pluginMessage.Parameter2 = Parameter2;
|
||||||
|
|
||||||
|
PhInvokeCallback(PhGetPluginCallback(plugin, PluginCallbackTreeNewMessage), &pluginMessage);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __cdecl PhCmpSortFunction(
|
||||||
|
_In_ void *context,
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_CM_SORT_CONTEXT sortContext = context;
|
||||||
|
PVOID node1 = *(PVOID *)elem1;
|
||||||
|
PVOID node2 = *(PVOID *)elem2;
|
||||||
|
LONG result;
|
||||||
|
|
||||||
|
result = sortContext->SortFunction(node1, node2, sortContext->SubId, sortContext->Context);
|
||||||
|
|
||||||
|
return sortContext->PostSortFunction(result, node1, node2, sortContext->SortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhCmForwardSort(
|
||||||
|
_In_ PPH_TREENEW_NODE *Nodes,
|
||||||
|
_In_ ULONG NumberOfNodes,
|
||||||
|
_In_ ULONG SortColumn,
|
||||||
|
_In_ PH_SORT_ORDER SortOrder,
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_TREENEW_COLUMN tnColumn;
|
||||||
|
PPH_CM_COLUMN column;
|
||||||
|
PH_CM_SORT_CONTEXT sortContext;
|
||||||
|
|
||||||
|
if (SortColumn < Manager->MinId)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!TreeNew_GetColumn(Manager->Handle, SortColumn, &tnColumn))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
column = tnColumn.Context;
|
||||||
|
|
||||||
|
if (!column->SortFunction)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
sortContext.SortFunction = column->SortFunction;
|
||||||
|
sortContext.SubId = column->SubId;
|
||||||
|
sortContext.Context = column->Context;
|
||||||
|
sortContext.PostSortFunction = Manager->PostSortFunction;
|
||||||
|
sortContext.SortOrder = SortOrder;
|
||||||
|
qsort_s(Nodes, NumberOfNodes, sizeof(PVOID), PhCmpSortFunction, &sortContext);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhCmLoadSettings(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_ PPH_STRINGREF Settings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return PhCmLoadSettingsEx(TreeNewHandle, NULL, 0, Settings, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhCmLoadSettingsEx(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_opt_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_STRINGREF Settings,
|
||||||
|
_In_opt_ PPH_STRINGREF SortSettings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN result = FALSE;
|
||||||
|
PH_STRINGREF scalePart;
|
||||||
|
PH_STRINGREF columnPart;
|
||||||
|
PH_STRINGREF remainingColumnPart;
|
||||||
|
PH_STRINGREF valuePart;
|
||||||
|
PH_STRINGREF subPart;
|
||||||
|
ULONG64 integer;
|
||||||
|
ULONG scale;
|
||||||
|
ULONG total;
|
||||||
|
BOOLEAN hasFixedColumn;
|
||||||
|
ULONG count;
|
||||||
|
ULONG i;
|
||||||
|
PPH_HASHTABLE columnHashtable;
|
||||||
|
PH_HASHTABLE_ENUM_CONTEXT enumContext;
|
||||||
|
PPH_KEY_VALUE_PAIR pair;
|
||||||
|
LONG orderArray[PH_CM_ORDER_LIMIT];
|
||||||
|
LONG maxOrder;
|
||||||
|
|
||||||
|
if (Settings->Length != 0)
|
||||||
|
{
|
||||||
|
columnHashtable = PhCreateSimpleHashtable(20);
|
||||||
|
|
||||||
|
remainingColumnPart = *Settings;
|
||||||
|
|
||||||
|
if (remainingColumnPart.Length != 0 && remainingColumnPart.Buffer[0] == '@')
|
||||||
|
{
|
||||||
|
PhSkipStringRef(&remainingColumnPart, sizeof(WCHAR));
|
||||||
|
PhSplitStringRefAtChar(&remainingColumnPart, '|', &scalePart, &remainingColumnPart);
|
||||||
|
|
||||||
|
if (scalePart.Length == 0 || !PhStringToInteger64(&scalePart, 10, &integer))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
scale = (ULONG)integer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scale = PhGlobalDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (remainingColumnPart.Length != 0)
|
||||||
|
{
|
||||||
|
PPH_TREENEW_COLUMN column;
|
||||||
|
ULONG id;
|
||||||
|
ULONG displayIndex;
|
||||||
|
ULONG width;
|
||||||
|
|
||||||
|
PhSplitStringRefAtChar(&remainingColumnPart, '|', &columnPart, &remainingColumnPart);
|
||||||
|
|
||||||
|
if (columnPart.Length != 0)
|
||||||
|
{
|
||||||
|
// Id
|
||||||
|
|
||||||
|
PhSplitStringRefAtChar(&columnPart, ',', &valuePart, &columnPart);
|
||||||
|
|
||||||
|
if (valuePart.Length == 0)
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
if (valuePart.Buffer[0] == '+')
|
||||||
|
{
|
||||||
|
PH_STRINGREF pluginName;
|
||||||
|
ULONG subId;
|
||||||
|
PPH_CM_COLUMN cmColumn;
|
||||||
|
|
||||||
|
// This is a plugin-owned column.
|
||||||
|
|
||||||
|
if (!Manager)
|
||||||
|
continue;
|
||||||
|
if (!PhEmParseCompoundId(&valuePart, &pluginName, &subId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cmColumn = PhCmFindColumn(Manager, &pluginName, subId);
|
||||||
|
|
||||||
|
if (!cmColumn)
|
||||||
|
continue; // can't find the column, skip this part
|
||||||
|
|
||||||
|
id = cmColumn->Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!PhStringToInteger64(&valuePart, 10, &integer))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
id = (ULONG)integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display Index
|
||||||
|
|
||||||
|
PhSplitStringRefAtChar(&columnPart, ',', &valuePart, &columnPart);
|
||||||
|
|
||||||
|
if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY))
|
||||||
|
{
|
||||||
|
if (valuePart.Length == 0 || !PhStringToInteger64(&valuePart, 10, &integer))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
displayIndex = (ULONG)integer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (valuePart.Length != 0)
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
displayIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width
|
||||||
|
|
||||||
|
if (columnPart.Length == 0 || !PhStringToInteger64(&columnPart, 10, &integer))
|
||||||
|
goto CleanupExit;
|
||||||
|
|
||||||
|
width = (ULONG)integer;
|
||||||
|
|
||||||
|
if (scale != PhGlobalDpi && scale != 0)
|
||||||
|
width = PhMultiplyDivide(width, PhGlobalDpi, scale);
|
||||||
|
|
||||||
|
column = PhAllocate(sizeof(PH_TREENEW_COLUMN));
|
||||||
|
column->Id = id;
|
||||||
|
column->DisplayIndex = displayIndex;
|
||||||
|
column->Width = width;
|
||||||
|
PhAddItemSimpleHashtable(columnHashtable, UlongToPtr(column->Id), column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(TreeNewHandle, FALSE);
|
||||||
|
|
||||||
|
// Set visibility and width.
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
count = 0;
|
||||||
|
total = TreeNew_GetColumnCount(TreeNewHandle);
|
||||||
|
hasFixedColumn = !!TreeNew_GetFixedColumn(TreeNewHandle);
|
||||||
|
memset(orderArray, 0, sizeof(orderArray));
|
||||||
|
maxOrder = 0;
|
||||||
|
|
||||||
|
while (count < total)
|
||||||
|
{
|
||||||
|
PH_TREENEW_COLUMN setColumn;
|
||||||
|
PPH_TREENEW_COLUMN *columnPtr;
|
||||||
|
|
||||||
|
if (TreeNew_GetColumn(TreeNewHandle, i, &setColumn))
|
||||||
|
{
|
||||||
|
columnPtr = (PPH_TREENEW_COLUMN *)PhFindItemSimpleHashtable(columnHashtable, UlongToPtr(i));
|
||||||
|
|
||||||
|
if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY))
|
||||||
|
{
|
||||||
|
if (columnPtr)
|
||||||
|
{
|
||||||
|
setColumn.Visible = TRUE;
|
||||||
|
setColumn.Width = (*columnPtr)->Width;
|
||||||
|
TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_FLAG_VISIBLE | TN_COLUMN_WIDTH, &setColumn);
|
||||||
|
|
||||||
|
if (!setColumn.Fixed)
|
||||||
|
{
|
||||||
|
// For compatibility reasons, normal columns have their display indicies stored
|
||||||
|
// one higher than usual (so they start from 1, not 0). Fix that here.
|
||||||
|
if (hasFixedColumn && (*columnPtr)->DisplayIndex != 0)
|
||||||
|
(*columnPtr)->DisplayIndex--;
|
||||||
|
|
||||||
|
if ((*columnPtr)->DisplayIndex < PH_CM_ORDER_LIMIT)
|
||||||
|
{
|
||||||
|
orderArray[(*columnPtr)->DisplayIndex] = i;
|
||||||
|
|
||||||
|
if ((ULONG)maxOrder < (*columnPtr)->DisplayIndex + 1)
|
||||||
|
maxOrder = (*columnPtr)->DisplayIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!setColumn.Fixed) // never hide the fixed column
|
||||||
|
{
|
||||||
|
setColumn.Visible = FALSE;
|
||||||
|
TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_FLAG_VISIBLE, &setColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (columnPtr)
|
||||||
|
{
|
||||||
|
setColumn.Width = (*columnPtr)->Width;
|
||||||
|
TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_WIDTH, &setColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY))
|
||||||
|
{
|
||||||
|
// Set the order array.
|
||||||
|
TreeNew_SetColumnOrderArray(TreeNewHandle, maxOrder, orderArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(TreeNewHandle, TRUE);
|
||||||
|
|
||||||
|
result = TRUE;
|
||||||
|
|
||||||
|
CleanupExit:
|
||||||
|
PhBeginEnumHashtable(columnHashtable, &enumContext);
|
||||||
|
|
||||||
|
while (pair = PhNextEnumHashtable(&enumContext))
|
||||||
|
PhFree(pair->Value);
|
||||||
|
|
||||||
|
PhDereferenceObject(columnHashtable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load sort settings.
|
||||||
|
|
||||||
|
if (SortSettings && SortSettings->Length != 0)
|
||||||
|
{
|
||||||
|
PhSplitStringRefAtChar(SortSettings, ',', &valuePart, &subPart);
|
||||||
|
|
||||||
|
if (valuePart.Length != 0 && subPart.Length != 0)
|
||||||
|
{
|
||||||
|
ULONG sortColumn;
|
||||||
|
PH_SORT_ORDER sortOrder;
|
||||||
|
|
||||||
|
sortColumn = -1;
|
||||||
|
|
||||||
|
if (valuePart.Buffer[0] == '+')
|
||||||
|
{
|
||||||
|
PH_STRINGREF pluginName;
|
||||||
|
ULONG subId;
|
||||||
|
PPH_CM_COLUMN cmColumn;
|
||||||
|
|
||||||
|
if (
|
||||||
|
Manager &&
|
||||||
|
PhEmParseCompoundId(&valuePart, &pluginName, &subId) &&
|
||||||
|
(cmColumn = PhCmFindColumn(Manager, &pluginName, subId))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
sortColumn = cmColumn->Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhStringToInteger64(&valuePart, 10, &integer);
|
||||||
|
sortColumn = (ULONG)integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhStringToInteger64(&subPart, 10, &integer);
|
||||||
|
sortOrder = (PH_SORT_ORDER)integer;
|
||||||
|
|
||||||
|
if (sortColumn != -1 && sortOrder <= DescendingSortOrder)
|
||||||
|
{
|
||||||
|
TreeNew_SetSort(TreeNewHandle, sortColumn, sortOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_STRING PhCmSaveSettings(
|
||||||
|
_In_ HWND TreeNewHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return PhCmSaveSettingsEx(TreeNewHandle, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_STRING PhCmSaveSettingsEx(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_opt_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_Out_opt_ PPH_STRING *SortSettings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_STRING_BUILDER stringBuilder;
|
||||||
|
ULONG i = 0;
|
||||||
|
ULONG count = 0;
|
||||||
|
ULONG total;
|
||||||
|
ULONG increment;
|
||||||
|
PH_TREENEW_COLUMN column;
|
||||||
|
|
||||||
|
total = TreeNew_GetColumnCount(TreeNewHandle);
|
||||||
|
|
||||||
|
if (TreeNew_GetFixedColumn(TreeNewHandle))
|
||||||
|
increment = 1; // the first normal column should have a display index that starts with 1, for compatibility
|
||||||
|
else
|
||||||
|
increment = 0;
|
||||||
|
|
||||||
|
PhInitializeStringBuilder(&stringBuilder, 100);
|
||||||
|
|
||||||
|
PhAppendFormatStringBuilder(&stringBuilder, L"@%u|", PhGlobalDpi);
|
||||||
|
|
||||||
|
while (count < total)
|
||||||
|
{
|
||||||
|
if (TreeNew_GetColumn(TreeNewHandle, i, &column))
|
||||||
|
{
|
||||||
|
if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY))
|
||||||
|
{
|
||||||
|
if (column.Visible)
|
||||||
|
{
|
||||||
|
if (!Manager || i < Manager->MinId)
|
||||||
|
{
|
||||||
|
PhAppendFormatStringBuilder(
|
||||||
|
&stringBuilder,
|
||||||
|
L"%u,%u,%u|",
|
||||||
|
i,
|
||||||
|
column.Fixed ? 0 : column.DisplayIndex + increment,
|
||||||
|
column.Width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PPH_CM_COLUMN cmColumn;
|
||||||
|
|
||||||
|
cmColumn = column.Context;
|
||||||
|
PhAppendFormatStringBuilder(
|
||||||
|
&stringBuilder,
|
||||||
|
L"+%s+%u,%u,%u|",
|
||||||
|
cmColumn->Plugin->Name.Buffer,
|
||||||
|
cmColumn->SubId,
|
||||||
|
column.DisplayIndex + increment,
|
||||||
|
column.Width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Manager || i < Manager->MinId)
|
||||||
|
{
|
||||||
|
PhAppendFormatStringBuilder(
|
||||||
|
&stringBuilder,
|
||||||
|
L"%u,,%u|",
|
||||||
|
i,
|
||||||
|
column.Width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PPH_CM_COLUMN cmColumn;
|
||||||
|
|
||||||
|
cmColumn = column.Context;
|
||||||
|
PhAppendFormatStringBuilder(
|
||||||
|
&stringBuilder,
|
||||||
|
L"+%s+%u,,%u|",
|
||||||
|
cmColumn->Plugin->Name.Buffer,
|
||||||
|
cmColumn->SubId,
|
||||||
|
column.Width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringBuilder.String->Length != 0)
|
||||||
|
PhRemoveEndStringBuilder(&stringBuilder, 1);
|
||||||
|
|
||||||
|
if (SortSettings)
|
||||||
|
{
|
||||||
|
ULONG sortColumn;
|
||||||
|
PH_SORT_ORDER sortOrder;
|
||||||
|
|
||||||
|
if (TreeNew_GetSort(TreeNewHandle, &sortColumn, &sortOrder))
|
||||||
|
{
|
||||||
|
if (sortOrder != NoSortOrder)
|
||||||
|
{
|
||||||
|
if (!Manager || sortColumn < Manager->MinId)
|
||||||
|
{
|
||||||
|
*SortSettings = PhFormatString(L"%u,%u", sortColumn, sortOrder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PH_TREENEW_COLUMN column;
|
||||||
|
PPH_CM_COLUMN cmColumn;
|
||||||
|
|
||||||
|
if (TreeNew_GetColumn(TreeNewHandle, sortColumn, &column))
|
||||||
|
{
|
||||||
|
cmColumn = column.Context;
|
||||||
|
*SortSettings = PhFormatString(L"+%s+%u,%u", cmColumn->Plugin->Name.Buffer, cmColumn->SubId, sortOrder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*SortSettings = PhReferenceEmptyString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*SortSettings = PhCreateString(L"0,0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*SortSettings = PhReferenceEmptyString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhFinalStringBuilderString(&stringBuilder);
|
||||||
|
}
|
1693
ProcessHacker/dbgcon.c
Normal file
1693
ProcessHacker/dbgcon.c
Normal file
File diff suppressed because it is too large
Load Diff
226
ProcessHacker/extmgr.c
Normal file
226
ProcessHacker/extmgr.c
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* extension manager
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The extension manager provides support for generic extensions. It sits directly
|
||||||
|
* underneath the plugin manager, and has no knowledge of plugin details (how they are
|
||||||
|
* loaded, plugin information, etc.).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <extmgri.h>
|
||||||
|
|
||||||
|
LIST_ENTRY PhEmAppContextListHead = { &PhEmAppContextListHead, &PhEmAppContextListHead };
|
||||||
|
ULONG PhEmAppContextCount = 0;
|
||||||
|
PH_EM_OBJECT_TYPE_STATE PhEmObjectTypeState[EmMaximumObjectType] = { 0 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the extension manager module.
|
||||||
|
*/
|
||||||
|
VOID PhEmInitialization(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < EmMaximumObjectType; i++)
|
||||||
|
{
|
||||||
|
InitializeListHead(&PhEmObjectTypeState[i].ExtensionListHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an extension application context.
|
||||||
|
*
|
||||||
|
* \param AppContext The application context.
|
||||||
|
* \param AppName The application name.
|
||||||
|
*/
|
||||||
|
VOID PhEmInitializeAppContext(
|
||||||
|
_Out_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PPH_STRINGREF AppName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AppContext->AppName = *AppName;
|
||||||
|
memset(AppContext->Extensions, 0, sizeof(AppContext->Extensions));
|
||||||
|
|
||||||
|
InsertTailList(&PhEmAppContextListHead, &AppContext->ListEntry);
|
||||||
|
PhEmAppContextCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the object extension size and callbacks for an object type.
|
||||||
|
*
|
||||||
|
* \param AppContext The application context.
|
||||||
|
* \param ObjectType The type of object for which the extension is being registered.
|
||||||
|
* \param ExtensionSize The size of the extension, in bytes.
|
||||||
|
* \param CreateCallback The object creation callback.
|
||||||
|
* \param DeleteCallback The object deletion callback.
|
||||||
|
*/
|
||||||
|
VOID PhEmSetObjectExtension(
|
||||||
|
_Inout_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ SIZE_T ExtensionSize,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK CreateCallback,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK DeleteCallback
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_EM_OBJECT_TYPE_STATE objectTypeState;
|
||||||
|
PPH_EM_OBJECT_EXTENSION objectExtension;
|
||||||
|
|
||||||
|
objectTypeState = &PhEmObjectTypeState[ObjectType];
|
||||||
|
objectExtension = AppContext->Extensions[ObjectType];
|
||||||
|
|
||||||
|
if (!objectExtension)
|
||||||
|
{
|
||||||
|
objectExtension = PhAllocate(sizeof(PH_EM_OBJECT_EXTENSION));
|
||||||
|
memset(objectExtension, 0, sizeof(PH_EM_OBJECT_EXTENSION));
|
||||||
|
InsertTailList(&objectTypeState->ExtensionListHead, &objectExtension->ListEntry);
|
||||||
|
AppContext->Extensions[ObjectType] = objectExtension;
|
||||||
|
|
||||||
|
objectExtension->ExtensionSize = ExtensionSize;
|
||||||
|
objectExtension->ExtensionOffset = objectTypeState->ExtensionOffset;
|
||||||
|
|
||||||
|
objectTypeState->ExtensionOffset += ExtensionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectExtension->Callbacks[EmObjectCreate] = CreateCallback;
|
||||||
|
objectExtension->Callbacks[EmObjectDelete] = DeleteCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the object extension for an object.
|
||||||
|
*
|
||||||
|
* \param AppContext The application context.
|
||||||
|
* \param ObjectType The type of object for which an extension has been registered.
|
||||||
|
* \param Object The object.
|
||||||
|
*/
|
||||||
|
PVOID PhEmGetObjectExtension(
|
||||||
|
_In_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ PVOID Object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_EM_OBJECT_EXTENSION objectExtension;
|
||||||
|
|
||||||
|
objectExtension = AppContext->Extensions[ObjectType];
|
||||||
|
|
||||||
|
if (!objectExtension)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (PCHAR)Object + PhEmObjectTypeState[ObjectType].InitialSize + objectExtension->ExtensionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the size of an object, including extensions.
|
||||||
|
*
|
||||||
|
* \param ObjectType The object type.
|
||||||
|
* \param InitialSize The initial size of the object.
|
||||||
|
*/
|
||||||
|
SIZE_T PhEmGetObjectSize(
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ SIZE_T InitialSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhEmObjectTypeState[ObjectType].InitialSize = InitialSize;
|
||||||
|
|
||||||
|
return InitialSize + PhEmObjectTypeState[ObjectType].ExtensionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes callbacks for an object operation.
|
||||||
|
*
|
||||||
|
* \param ObjectType The object type.
|
||||||
|
* \param Object The object.
|
||||||
|
* \param Operation The operation being performed.
|
||||||
|
*/
|
||||||
|
VOID PhEmCallObjectOperation(
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ PH_EM_OBJECT_OPERATION Operation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_EM_OBJECT_TYPE_STATE objectTypeState;
|
||||||
|
PLIST_ENTRY listEntry;
|
||||||
|
PPH_EM_OBJECT_EXTENSION objectExtension;
|
||||||
|
|
||||||
|
if (PhEmAppContextCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
objectTypeState = &PhEmObjectTypeState[ObjectType];
|
||||||
|
|
||||||
|
listEntry = objectTypeState->ExtensionListHead.Flink;
|
||||||
|
|
||||||
|
while (listEntry != &objectTypeState->ExtensionListHead)
|
||||||
|
{
|
||||||
|
objectExtension = CONTAINING_RECORD(listEntry, PH_EM_OBJECT_EXTENSION, ListEntry);
|
||||||
|
|
||||||
|
if (objectExtension->Callbacks[Operation])
|
||||||
|
{
|
||||||
|
objectExtension->Callbacks[Operation](
|
||||||
|
Object,
|
||||||
|
ObjectType,
|
||||||
|
(PCHAR)Object + objectTypeState->InitialSize + objectExtension->ExtensionOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
listEntry = listEntry->Flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an application name and sub-ID pair.
|
||||||
|
*
|
||||||
|
* \param CompoundId The compound identifier.
|
||||||
|
* \param AppName A variable which receives the application name.
|
||||||
|
* \param SubId A variable which receives the sub-ID.
|
||||||
|
*/
|
||||||
|
BOOLEAN PhEmParseCompoundId(
|
||||||
|
_In_ PPH_STRINGREF CompoundId,
|
||||||
|
_Out_ PPH_STRINGREF AppName,
|
||||||
|
_Out_ PULONG SubId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_STRINGREF firstPart;
|
||||||
|
PH_STRINGREF secondPart;
|
||||||
|
ULONG64 integer;
|
||||||
|
|
||||||
|
firstPart = *CompoundId;
|
||||||
|
|
||||||
|
if (firstPart.Length == 0)
|
||||||
|
return FALSE;
|
||||||
|
if (firstPart.Buffer[0] != '+')
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
PhSkipStringRef(&firstPart, sizeof(WCHAR));
|
||||||
|
PhSplitStringRefAtChar(&firstPart, '+', &firstPart, &secondPart);
|
||||||
|
|
||||||
|
if (firstPart.Length == 0 || secondPart.Length == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!PhStringToInteger64(&secondPart, 10, &integer))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*AppName = firstPart;
|
||||||
|
*SubId = (ULONG)integer;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
1011
ProcessHacker/findobj.c
Normal file
1011
ProcessHacker/findobj.c
Normal file
File diff suppressed because it is too large
Load Diff
378
ProcessHacker/gdihndl.c
Normal file
378
ProcessHacker/gdihndl.c
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* GDI handles dialog
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <procprv.h>
|
||||||
|
#include <ntgdi.h>
|
||||||
|
|
||||||
|
typedef struct _GDI_HANDLES_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_PROCESS_ITEM ProcessItem;
|
||||||
|
PPH_LIST List;
|
||||||
|
} GDI_HANDLES_CONTEXT, *PGDI_HANDLES_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_GDI_HANDLE_ITEM
|
||||||
|
{
|
||||||
|
PGDI_HANDLE_ENTRY Entry;
|
||||||
|
ULONG Handle;
|
||||||
|
PVOID Object;
|
||||||
|
PWSTR TypeName;
|
||||||
|
PPH_STRING Information;
|
||||||
|
} PH_GDI_HANDLE_ITEM, *PPH_GDI_HANDLE_ITEM;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpGdiHandlesDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhShowGdiHandlesDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GDI_HANDLES_CONTEXT context;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
context.ProcessItem = ProcessItem;
|
||||||
|
context.List = PhCreateList(20);
|
||||||
|
|
||||||
|
DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_GDIHANDLES),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpGdiHandlesDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i = 0; i < context.List->Count; i++)
|
||||||
|
{
|
||||||
|
PPH_GDI_HANDLE_ITEM gdiHandleItem = context.List->Items[i];
|
||||||
|
|
||||||
|
if (gdiHandleItem->Information)
|
||||||
|
PhDereferenceObject(gdiHandleItem->Information);
|
||||||
|
|
||||||
|
PhFree(context.List->Items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhDereferenceObject(context.List);
|
||||||
|
}
|
||||||
|
|
||||||
|
PWSTR PhpGetGdiHandleTypeName(
|
||||||
|
_In_ ULONG Unique
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (GDI_CLIENT_TYPE_FROM_UNIQUE(Unique))
|
||||||
|
{
|
||||||
|
case GDI_CLIENT_ALTDC_TYPE:
|
||||||
|
return L"Alt. DC";
|
||||||
|
case GDI_CLIENT_BITMAP_TYPE:
|
||||||
|
return L"Bitmap";
|
||||||
|
case GDI_CLIENT_BRUSH_TYPE:
|
||||||
|
return L"Brush";
|
||||||
|
case GDI_CLIENT_CLIENTOBJ_TYPE:
|
||||||
|
return L"Client Object";
|
||||||
|
case GDI_CLIENT_DIBSECTION_TYPE:
|
||||||
|
return L"DIB Section";
|
||||||
|
case GDI_CLIENT_DC_TYPE:
|
||||||
|
return L"DC";
|
||||||
|
case GDI_CLIENT_EXTPEN_TYPE:
|
||||||
|
return L"ExtPen";
|
||||||
|
case GDI_CLIENT_FONT_TYPE:
|
||||||
|
return L"Font";
|
||||||
|
case GDI_CLIENT_METADC16_TYPE:
|
||||||
|
return L"Metafile DC";
|
||||||
|
case GDI_CLIENT_METAFILE_TYPE:
|
||||||
|
return L"Enhanced Metafile";
|
||||||
|
case GDI_CLIENT_METAFILE16_TYPE:
|
||||||
|
return L"Metafile";
|
||||||
|
case GDI_CLIENT_PALETTE_TYPE:
|
||||||
|
return L"Palette";
|
||||||
|
case GDI_CLIENT_PEN_TYPE:
|
||||||
|
return L"Pen";
|
||||||
|
case GDI_CLIENT_REGION_TYPE:
|
||||||
|
return L"Region";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_STRING PhpGetGdiHandleInformation(
|
||||||
|
_In_ ULONG Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HGDIOBJ handle;
|
||||||
|
|
||||||
|
handle = (HGDIOBJ)UlongToPtr(Handle);
|
||||||
|
|
||||||
|
switch (GDI_CLIENT_TYPE_FROM_HANDLE(Handle))
|
||||||
|
{
|
||||||
|
case GDI_CLIENT_BITMAP_TYPE:
|
||||||
|
case GDI_CLIENT_DIBSECTION_TYPE:
|
||||||
|
{
|
||||||
|
BITMAP bitmap;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(BITMAP), &bitmap))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Width: %u, Height: %u, Depth: %u",
|
||||||
|
bitmap.bmWidth,
|
||||||
|
bitmap.bmHeight,
|
||||||
|
bitmap.bmBitsPixel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDI_CLIENT_BRUSH_TYPE:
|
||||||
|
{
|
||||||
|
LOGBRUSH brush;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(LOGBRUSH), &brush))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Style: %u, Color: 0x%08x, Hatch: 0x%Ix",
|
||||||
|
brush.lbStyle,
|
||||||
|
_byteswap_ulong(brush.lbColor),
|
||||||
|
brush.lbHatch
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDI_CLIENT_EXTPEN_TYPE:
|
||||||
|
{
|
||||||
|
EXTLOGPEN pen;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(EXTLOGPEN), &pen))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Style: 0x%x, Width: %u, Color: 0x%08x",
|
||||||
|
pen.elpPenStyle,
|
||||||
|
pen.elpWidth,
|
||||||
|
_byteswap_ulong(pen.elpColor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDI_CLIENT_FONT_TYPE:
|
||||||
|
{
|
||||||
|
LOGFONT font;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(LOGFONT), &font))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Face: %s, Height: %d",
|
||||||
|
font.lfFaceName,
|
||||||
|
font.lfHeight
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDI_CLIENT_PALETTE_TYPE:
|
||||||
|
{
|
||||||
|
USHORT count;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(USHORT), &count))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Entries: %u",
|
||||||
|
(ULONG)count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDI_CLIENT_PEN_TYPE:
|
||||||
|
{
|
||||||
|
LOGPEN pen;
|
||||||
|
|
||||||
|
if (GetObject(handle, sizeof(LOGPEN), &pen))
|
||||||
|
{
|
||||||
|
return PhFormatString(
|
||||||
|
L"Style: %u, Width: %u, Color: 0x%08x",
|
||||||
|
pen.lopnStyle,
|
||||||
|
pen.lopnWidth.x,
|
||||||
|
_byteswap_ulong(pen.lopnColor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpRefreshGdiHandles(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ PGDI_HANDLES_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HWND lvHandle;
|
||||||
|
ULONG i;
|
||||||
|
PGDI_SHARED_MEMORY gdiShared;
|
||||||
|
USHORT processId;
|
||||||
|
PGDI_HANDLE_ENTRY handle;
|
||||||
|
PPH_GDI_HANDLE_ITEM gdiHandleItem;
|
||||||
|
|
||||||
|
lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
|
||||||
|
|
||||||
|
ListView_DeleteAllItems(lvHandle);
|
||||||
|
ExtendedListView_SetRedraw(lvHandle, FALSE);
|
||||||
|
|
||||||
|
for (i = 0; i < Context->List->Count; i++)
|
||||||
|
{
|
||||||
|
gdiHandleItem = Context->List->Items[i];
|
||||||
|
|
||||||
|
if (gdiHandleItem->Information)
|
||||||
|
PhDereferenceObject(gdiHandleItem->Information);
|
||||||
|
|
||||||
|
PhFree(Context->List->Items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhClearList(Context->List);
|
||||||
|
|
||||||
|
gdiShared = (PGDI_SHARED_MEMORY)NtCurrentPeb()->GdiSharedHandleTable;
|
||||||
|
processId = (USHORT)Context->ProcessItem->ProcessId;
|
||||||
|
|
||||||
|
for (i = 0; i < GDI_MAX_HANDLE_COUNT; i++)
|
||||||
|
{
|
||||||
|
PWSTR typeName;
|
||||||
|
INT lvItemIndex;
|
||||||
|
WCHAR pointer[PH_PTR_STR_LEN_1];
|
||||||
|
|
||||||
|
handle = &gdiShared->Handles[i];
|
||||||
|
|
||||||
|
if (handle->Owner.ProcessId != processId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
typeName = PhpGetGdiHandleTypeName(handle->Unique);
|
||||||
|
|
||||||
|
if (!typeName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gdiHandleItem = PhAllocate(sizeof(PH_GDI_HANDLE_ITEM));
|
||||||
|
gdiHandleItem->Entry = handle;
|
||||||
|
gdiHandleItem->Handle = GDI_MAKE_HANDLE(i, handle->Unique);
|
||||||
|
gdiHandleItem->Object = handle->Object;
|
||||||
|
gdiHandleItem->TypeName = typeName;
|
||||||
|
gdiHandleItem->Information = PhpGetGdiHandleInformation(gdiHandleItem->Handle);
|
||||||
|
PhAddItemList(Context->List, gdiHandleItem);
|
||||||
|
|
||||||
|
lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, gdiHandleItem->TypeName, gdiHandleItem);
|
||||||
|
PhPrintPointer(pointer, UlongToPtr(gdiHandleItem->Handle));
|
||||||
|
PhSetListViewSubItem(lvHandle, lvItemIndex, 1, pointer);
|
||||||
|
PhPrintPointer(pointer, gdiHandleItem->Object);
|
||||||
|
PhSetListViewSubItem(lvHandle, lvItemIndex, 2, pointer);
|
||||||
|
PhSetListViewSubItem(lvHandle, lvItemIndex, 3, PhGetString(gdiHandleItem->Information));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedListView_SortItems(lvHandle);
|
||||||
|
ExtendedListView_SetRedraw(lvHandle, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT NTAPI PhpGdiHandleHandleCompareFunction(
|
||||||
|
_In_ PVOID Item1,
|
||||||
|
_In_ PVOID Item2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_GDI_HANDLE_ITEM item1 = Item1;
|
||||||
|
PPH_GDI_HANDLE_ITEM item2 = Item2;
|
||||||
|
|
||||||
|
return uintcmp(item1->Handle, item2->Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT NTAPI PhpGdiHandleObjectCompareFunction(
|
||||||
|
_In_ PVOID Item1,
|
||||||
|
_In_ PVOID Item2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_GDI_HANDLE_ITEM item1 = Item1;
|
||||||
|
PPH_GDI_HANDLE_ITEM item2 = Item2;
|
||||||
|
|
||||||
|
return uintptrcmp((ULONG_PTR)item1->Object, (ULONG_PTR)item2->Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpGdiHandlesDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
PGDI_HANDLES_CONTEXT context = (PGDI_HANDLES_CONTEXT)lParam;
|
||||||
|
HWND lvHandle;
|
||||||
|
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
|
||||||
|
lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
|
||||||
|
|
||||||
|
PhSetListViewStyle(lvHandle, FALSE, TRUE);
|
||||||
|
PhSetControlTheme(lvHandle, L"explorer");
|
||||||
|
PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Type");
|
||||||
|
PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 80, L"Handle");
|
||||||
|
PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 80, L"Object");
|
||||||
|
PhAddListViewColumn(lvHandle, 3, 3, 3, LVCFMT_LEFT, 200, L"Information");
|
||||||
|
|
||||||
|
PhSetExtendedListView(lvHandle);
|
||||||
|
ExtendedListView_SetCompareFunction(lvHandle, 1, PhpGdiHandleHandleCompareFunction);
|
||||||
|
ExtendedListView_SetCompareFunction(lvHandle, 2, PhpGdiHandleObjectCompareFunction);
|
||||||
|
ExtendedListView_AddFallbackColumn(lvHandle, 0);
|
||||||
|
ExtendedListView_AddFallbackColumn(lvHandle, 1);
|
||||||
|
|
||||||
|
PhpRefreshGdiHandles(hwndDlg, context);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
case IDOK:
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
break;
|
||||||
|
case IDC_REFRESH:
|
||||||
|
{
|
||||||
|
PhpRefreshGdiHandles(hwndDlg, (PGDI_HANDLES_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
PhHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
1246
ProcessHacker/hidnproc.c
Normal file
1246
ProcessHacker/hidnproc.c
Normal file
File diff suppressed because it is too large
Load Diff
751
ProcessHacker/hndllist.c
Normal file
751
ProcessHacker/hndllist.c
Normal file
@ -0,0 +1,751 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* handle list
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2013 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <hndllist.h>
|
||||||
|
#include <hndlprv.h>
|
||||||
|
#include <secedit.h>
|
||||||
|
#include <settings.h>
|
||||||
|
#include <extmgri.h>
|
||||||
|
#include <phplug.h>
|
||||||
|
#include <emenu.h>
|
||||||
|
|
||||||
|
BOOLEAN PhpHandleNodeHashtableEqualFunction(
|
||||||
|
_In_ PVOID Entry1,
|
||||||
|
_In_ PVOID Entry2
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG PhpHandleNodeHashtableHashFunction(
|
||||||
|
_In_ PVOID Entry
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhpDestroyHandleNode(
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhpRemoveHandleNode(
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode,
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
LONG PhpHandleTreeNewPostSortFunction(
|
||||||
|
_In_ LONG Result,
|
||||||
|
_In_ PVOID Node1,
|
||||||
|
_In_ PVOID Node2,
|
||||||
|
_In_ PH_SORT_ORDER SortOrder
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PhpHandleTreeNewCallback(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ PH_TREENEW_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhInitializeHandleList(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_Out_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
|
||||||
|
memset(Context, 0, sizeof(PH_HANDLE_LIST_CONTEXT));
|
||||||
|
Context->EnableStateHighlighting = TRUE;
|
||||||
|
|
||||||
|
Context->NodeHashtable = PhCreateHashtable(
|
||||||
|
sizeof(PPH_HANDLE_NODE),
|
||||||
|
PhpHandleNodeHashtableEqualFunction,
|
||||||
|
PhpHandleNodeHashtableHashFunction,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
Context->NodeList = PhCreateList(100);
|
||||||
|
|
||||||
|
Context->ParentWindowHandle = ParentWindowHandle;
|
||||||
|
Context->TreeNewHandle = TreeNewHandle;
|
||||||
|
hwnd = TreeNewHandle;
|
||||||
|
PhSetControlTheme(hwnd, L"explorer");
|
||||||
|
|
||||||
|
TreeNew_SetCallback(hwnd, PhpHandleTreeNewCallback, Context);
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(hwnd, FALSE);
|
||||||
|
|
||||||
|
// Default columns
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_TYPE, TRUE, L"Type", 100, PH_ALIGN_LEFT, 0, 0);
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_NAME, TRUE, L"Name", 200, PH_ALIGN_LEFT, 1, 0);
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_HANDLE, TRUE, L"Handle", 80, PH_ALIGN_LEFT, 2, 0);
|
||||||
|
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_OBJECTADDRESS, FALSE, L"Object address", 80, PH_ALIGN_LEFT, -1, 0);
|
||||||
|
PhAddTreeNewColumnEx(hwnd, PHHNTLC_ATTRIBUTES, FALSE, L"Attributes", 120, PH_ALIGN_LEFT, -1, 0, TRUE);
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_GRANTEDACCESS, FALSE, L"Granted access", 80, PH_ALIGN_LEFT, -1, 0);
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_GRANTEDACCESSSYMBOLIC, FALSE, L"Granted access (symbolic)", 140, PH_ALIGN_LEFT, -1, 0);
|
||||||
|
PhAddTreeNewColumn(hwnd, PHHNTLC_ORIGINALNAME, FALSE, L"Original name", 200, PH_ALIGN_LEFT, -1, 0);
|
||||||
|
PhAddTreeNewColumnEx(hwnd, PHHNTLC_FILESHAREACCESS, FALSE, L"File share access", 50, PH_ALIGN_LEFT, -1, 0, TRUE);
|
||||||
|
|
||||||
|
TreeNew_SetRedraw(hwnd, TRUE);
|
||||||
|
|
||||||
|
TreeNew_SetSort(hwnd, 0, AscendingSortOrder);
|
||||||
|
|
||||||
|
PhCmInitializeManager(&Context->Cm, hwnd, PHHNTLC_MAXIMUM, PhpHandleTreeNewPostSortFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhDeleteHandleList(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
PhCmDeleteManager(&Context->Cm);
|
||||||
|
|
||||||
|
for (i = 0; i < Context->NodeList->Count; i++)
|
||||||
|
PhpDestroyHandleNode(Context->NodeList->Items[i]);
|
||||||
|
|
||||||
|
PhDereferenceObject(Context->NodeHashtable);
|
||||||
|
PhDereferenceObject(Context->NodeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN PhpHandleNodeHashtableEqualFunction(
|
||||||
|
_In_ PVOID Entry1,
|
||||||
|
_In_ PVOID Entry2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_NODE handleNode1 = *(PPH_HANDLE_NODE *)Entry1;
|
||||||
|
PPH_HANDLE_NODE handleNode2 = *(PPH_HANDLE_NODE *)Entry2;
|
||||||
|
|
||||||
|
return handleNode1->Handle == handleNode2->Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG PhpHandleNodeHashtableHashFunction(
|
||||||
|
_In_ PVOID Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return HandleToUlong((*(PPH_HANDLE_NODE *)Entry)->Handle) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhLoadSettingsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_STRING settings;
|
||||||
|
PPH_STRING sortSettings;
|
||||||
|
|
||||||
|
settings = PhGetStringSetting(L"HandleTreeListColumns");
|
||||||
|
sortSettings = PhGetStringSetting(L"HandleTreeListSort");
|
||||||
|
PhCmLoadSettingsEx(Context->TreeNewHandle, &Context->Cm, 0, &settings->sr, &sortSettings->sr);
|
||||||
|
PhDereferenceObject(settings);
|
||||||
|
PhDereferenceObject(sortSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhSaveSettingsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_STRING settings;
|
||||||
|
PPH_STRING sortSettings;
|
||||||
|
|
||||||
|
settings = PhCmSaveSettingsEx(Context->TreeNewHandle, &Context->Cm, 0, &sortSettings);
|
||||||
|
PhSetStringSetting2(L"HandleTreeListColumns", &settings->sr);
|
||||||
|
PhSetStringSetting2(L"HandleTreeListSort", &sortSettings->sr);
|
||||||
|
PhDereferenceObject(settings);
|
||||||
|
PhDereferenceObject(sortSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhSetOptionsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ BOOLEAN HideUnnamedHandles
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
BOOLEAN modified;
|
||||||
|
|
||||||
|
if (Context->HideUnnamedHandles != HideUnnamedHandles)
|
||||||
|
{
|
||||||
|
Context->HideUnnamedHandles = HideUnnamedHandles;
|
||||||
|
|
||||||
|
modified = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < Context->NodeList->Count; i++)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_NODE node = Context->NodeList->Items[i];
|
||||||
|
BOOLEAN visible;
|
||||||
|
|
||||||
|
visible = TRUE;
|
||||||
|
|
||||||
|
if (HideUnnamedHandles && PhIsNullOrEmptyString(node->HandleItem->BestObjectName))
|
||||||
|
visible = FALSE;
|
||||||
|
|
||||||
|
if (node->Node.Visible != visible)
|
||||||
|
{
|
||||||
|
node->Node.Visible = visible;
|
||||||
|
modified = TRUE;
|
||||||
|
|
||||||
|
if (!visible)
|
||||||
|
node->Node.Selected = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
{
|
||||||
|
TreeNew_NodesStructured(Context->TreeNewHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_NODE PhAddHandleNode(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_ITEM HandleItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_NODE handleNode;
|
||||||
|
|
||||||
|
handleNode = PhAllocate(PhEmGetObjectSize(EmHandleNodeType, sizeof(PH_HANDLE_NODE)));
|
||||||
|
memset(handleNode, 0, sizeof(PH_HANDLE_NODE));
|
||||||
|
PhInitializeTreeNewNode(&handleNode->Node);
|
||||||
|
|
||||||
|
if (Context->EnableStateHighlighting && RunId != 1)
|
||||||
|
{
|
||||||
|
PhChangeShStateTn(
|
||||||
|
&handleNode->Node,
|
||||||
|
&handleNode->ShState,
|
||||||
|
&Context->NodeStateList,
|
||||||
|
NewItemState,
|
||||||
|
PhCsColorNew,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNode->Handle = HandleItem->Handle;
|
||||||
|
handleNode->HandleItem = HandleItem;
|
||||||
|
PhReferenceObject(HandleItem);
|
||||||
|
|
||||||
|
memset(handleNode->TextCache, 0, sizeof(PH_STRINGREF) * PHHNTLC_MAXIMUM);
|
||||||
|
handleNode->Node.TextCache = handleNode->TextCache;
|
||||||
|
handleNode->Node.TextCacheSize = PHHNTLC_MAXIMUM;
|
||||||
|
|
||||||
|
PhAddEntryHashtable(Context->NodeHashtable, &handleNode);
|
||||||
|
PhAddItemList(Context->NodeList, handleNode);
|
||||||
|
|
||||||
|
if (Context->HideUnnamedHandles && PhIsNullOrEmptyString(HandleItem->BestObjectName))
|
||||||
|
handleNode->Node.Visible = FALSE;
|
||||||
|
|
||||||
|
PhEmCallObjectOperation(EmHandleNodeType, handleNode, EmObjectCreate);
|
||||||
|
|
||||||
|
TreeNew_NodesStructured(Context->TreeNewHandle);
|
||||||
|
|
||||||
|
return handleNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_NODE PhFindHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_HANDLE_NODE lookupHandleNode;
|
||||||
|
PPH_HANDLE_NODE lookupHandleNodePtr = &lookupHandleNode;
|
||||||
|
PPH_HANDLE_NODE *handleNode;
|
||||||
|
|
||||||
|
lookupHandleNode.Handle = Handle;
|
||||||
|
|
||||||
|
handleNode = (PPH_HANDLE_NODE *)PhFindEntryHashtable(
|
||||||
|
Context->NodeHashtable,
|
||||||
|
&lookupHandleNodePtr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (handleNode)
|
||||||
|
return *handleNode;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhRemoveHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Remove from the hashtable here to avoid problems in case the key is re-used.
|
||||||
|
PhRemoveEntryHashtable(Context->NodeHashtable, &HandleNode);
|
||||||
|
|
||||||
|
if (Context->EnableStateHighlighting)
|
||||||
|
{
|
||||||
|
PhChangeShStateTn(
|
||||||
|
&HandleNode->Node,
|
||||||
|
&HandleNode->ShState,
|
||||||
|
&Context->NodeStateList,
|
||||||
|
RemovingItemState,
|
||||||
|
PhCsColorRemoved,
|
||||||
|
Context->TreeNewHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhpRemoveHandleNode(HandleNode, Context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpDestroyHandleNode(
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhEmCallObjectOperation(EmHandleNodeType, HandleNode, EmObjectDelete);
|
||||||
|
|
||||||
|
if (HandleNode->GrantedAccessSymbolicText) PhDereferenceObject(HandleNode->GrantedAccessSymbolicText);
|
||||||
|
|
||||||
|
PhDereferenceObject(HandleNode->HandleItem);
|
||||||
|
|
||||||
|
PhFree(HandleNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpRemoveHandleNode(
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode,
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context // PH_TICK_SH_STATE requires this parameter to be after HandleNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG index;
|
||||||
|
|
||||||
|
// Remove from list and cleanup.
|
||||||
|
|
||||||
|
if ((index = PhFindItemList(Context->NodeList, HandleNode)) != -1)
|
||||||
|
PhRemoveItemList(Context->NodeList, index);
|
||||||
|
|
||||||
|
PhpDestroyHandleNode(HandleNode);
|
||||||
|
|
||||||
|
TreeNew_NodesStructured(Context->TreeNewHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhUpdateHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
memset(HandleNode->TextCache, 0, sizeof(PH_STRINGREF) * PHHNTLC_MAXIMUM);
|
||||||
|
|
||||||
|
PhInvalidateTreeNewNode(&HandleNode->Node, TN_CACHE_COLOR);
|
||||||
|
TreeNew_NodesStructured(Context->TreeNewHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhTickHandleNodes(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_TICK_SH_STATE_TN(PH_HANDLE_NODE, ShState, Context->NodeStateList, PhpRemoveHandleNode, PhCsHighlightingDuration, Context->TreeNewHandle, TRUE, NULL, Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SORT_FUNCTION(Column) PhpHandleTreeNewCompare##Column
|
||||||
|
|
||||||
|
#define BEGIN_SORT_FUNCTION(Column) static int __cdecl PhpHandleTreeNewCompare##Column( \
|
||||||
|
_In_ void *_context, \
|
||||||
|
_In_ const void *_elem1, \
|
||||||
|
_In_ const void *_elem2 \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PPH_HANDLE_NODE node1 = *(PPH_HANDLE_NODE *)_elem1; \
|
||||||
|
PPH_HANDLE_NODE node2 = *(PPH_HANDLE_NODE *)_elem2; \
|
||||||
|
PPH_HANDLE_ITEM handleItem1 = node1->HandleItem; \
|
||||||
|
PPH_HANDLE_ITEM handleItem2 = node2->HandleItem; \
|
||||||
|
PPH_HANDLE_LIST_CONTEXT context = (PPH_HANDLE_LIST_CONTEXT)_context; \
|
||||||
|
int sortResult = 0;
|
||||||
|
|
||||||
|
#define END_SORT_FUNCTION \
|
||||||
|
if (sortResult == 0) \
|
||||||
|
sortResult = uintptrcmp((ULONG_PTR)node1->Handle, (ULONG_PTR)node2->Handle); \
|
||||||
|
\
|
||||||
|
return PhModifySort(sortResult, context->TreeNewSortOrder); \
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG PhpHandleTreeNewPostSortFunction(
|
||||||
|
_In_ LONG Result,
|
||||||
|
_In_ PVOID Node1,
|
||||||
|
_In_ PVOID Node2,
|
||||||
|
_In_ PH_SORT_ORDER SortOrder
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Result == 0)
|
||||||
|
Result = uintptrcmp((ULONG_PTR)((PPH_HANDLE_NODE)Node1)->Handle, (ULONG_PTR)((PPH_HANDLE_NODE)Node2)->Handle);
|
||||||
|
|
||||||
|
return PhModifySort(Result, SortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(Type)
|
||||||
|
{
|
||||||
|
sortResult = PhCompareString(handleItem1->TypeName, handleItem2->TypeName, TRUE);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(Name)
|
||||||
|
{
|
||||||
|
sortResult = PhCompareStringWithNull(handleItem1->BestObjectName, handleItem2->BestObjectName, TRUE);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(Handle)
|
||||||
|
{
|
||||||
|
sortResult = uintptrcmp((ULONG_PTR)node1->Handle, (ULONG_PTR)node2->Handle);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(ObjectAddress)
|
||||||
|
{
|
||||||
|
sortResult = uintptrcmp((ULONG_PTR)handleItem1->Object, (ULONG_PTR)handleItem2->Object);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(Attributes)
|
||||||
|
{
|
||||||
|
sortResult = uintcmp(handleItem1->Attributes, handleItem2->Attributes);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(GrantedAccess)
|
||||||
|
{
|
||||||
|
sortResult = uintcmp(handleItem1->GrantedAccess, handleItem2->GrantedAccess);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(OriginalName)
|
||||||
|
{
|
||||||
|
sortResult = PhCompareStringWithNull(handleItem1->ObjectName, handleItem2->ObjectName, TRUE);
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BEGIN_SORT_FUNCTION(FileShareAccess)
|
||||||
|
{
|
||||||
|
sortResult = uintcmp(handleItem1->FileFlags & (PH_HANDLE_FILE_SHARED_MASK), handleItem2->FileFlags & (PH_HANDLE_FILE_SHARED_MASK));
|
||||||
|
|
||||||
|
// Make sure all file handles get grouped together regardless of share access.
|
||||||
|
if (sortResult == 0)
|
||||||
|
sortResult = intcmp(PhEqualString2(handleItem1->TypeName, L"File", TRUE), PhEqualString2(handleItem2->TypeName, L"File", TRUE));
|
||||||
|
}
|
||||||
|
END_SORT_FUNCTION
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PhpHandleTreeNewCallback(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ PH_TREENEW_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_LIST_CONTEXT context;
|
||||||
|
PPH_HANDLE_NODE node;
|
||||||
|
|
||||||
|
context = Context;
|
||||||
|
|
||||||
|
if (PhCmForwardMessage(hwnd, Message, Parameter1, Parameter2, &context->Cm))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
switch (Message)
|
||||||
|
{
|
||||||
|
case TreeNewGetChildren:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_GET_CHILDREN getChildren = Parameter1;
|
||||||
|
|
||||||
|
if (!getChildren->Node)
|
||||||
|
{
|
||||||
|
static PVOID sortFunctions[] =
|
||||||
|
{
|
||||||
|
SORT_FUNCTION(Type),
|
||||||
|
SORT_FUNCTION(Name),
|
||||||
|
SORT_FUNCTION(Handle),
|
||||||
|
SORT_FUNCTION(ObjectAddress),
|
||||||
|
SORT_FUNCTION(Attributes),
|
||||||
|
SORT_FUNCTION(GrantedAccess),
|
||||||
|
SORT_FUNCTION(GrantedAccess), // Granted Access (Symbolic)
|
||||||
|
SORT_FUNCTION(OriginalName),
|
||||||
|
SORT_FUNCTION(FileShareAccess)
|
||||||
|
};
|
||||||
|
int (__cdecl *sortFunction)(void *, const void *, const void *);
|
||||||
|
|
||||||
|
if (!PhCmForwardSort(
|
||||||
|
(PPH_TREENEW_NODE *)context->NodeList->Items,
|
||||||
|
context->NodeList->Count,
|
||||||
|
context->TreeNewSortColumn,
|
||||||
|
context->TreeNewSortOrder,
|
||||||
|
&context->Cm
|
||||||
|
))
|
||||||
|
{
|
||||||
|
if (context->TreeNewSortColumn < PHHNTLC_MAXIMUM)
|
||||||
|
sortFunction = sortFunctions[context->TreeNewSortColumn];
|
||||||
|
else
|
||||||
|
sortFunction = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sortFunction = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortFunction)
|
||||||
|
{
|
||||||
|
qsort_s(context->NodeList->Items, context->NodeList->Count, sizeof(PVOID), sortFunction, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
getChildren->Children = (PPH_TREENEW_NODE *)context->NodeList->Items;
|
||||||
|
getChildren->NumberOfChildren = context->NodeList->Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewIsLeaf:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_IS_LEAF isLeaf = Parameter1;
|
||||||
|
|
||||||
|
isLeaf->IsLeaf = TRUE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewGetCellText:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_GET_CELL_TEXT getCellText = Parameter1;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
node = (PPH_HANDLE_NODE)getCellText->Node;
|
||||||
|
handleItem = node->HandleItem;
|
||||||
|
|
||||||
|
switch (getCellText->Id)
|
||||||
|
{
|
||||||
|
case PHHNTLC_TYPE:
|
||||||
|
getCellText->Text = handleItem->TypeName->sr;
|
||||||
|
break;
|
||||||
|
case PHHNTLC_NAME:
|
||||||
|
getCellText->Text = PhGetStringRef(handleItem->BestObjectName);
|
||||||
|
break;
|
||||||
|
case PHHNTLC_HANDLE:
|
||||||
|
PhInitializeStringRefLongHint(&getCellText->Text, handleItem->HandleString);
|
||||||
|
break;
|
||||||
|
case PHHNTLC_OBJECTADDRESS:
|
||||||
|
PhInitializeStringRefLongHint(&getCellText->Text, handleItem->ObjectString);
|
||||||
|
break;
|
||||||
|
case PHHNTLC_ATTRIBUTES:
|
||||||
|
switch (handleItem->Attributes & (OBJ_PROTECT_CLOSE | OBJ_INHERIT))
|
||||||
|
{
|
||||||
|
case OBJ_PROTECT_CLOSE:
|
||||||
|
PhInitializeStringRef(&getCellText->Text, L"Protected");
|
||||||
|
break;
|
||||||
|
case OBJ_INHERIT:
|
||||||
|
PhInitializeStringRef(&getCellText->Text, L"Inherit");
|
||||||
|
break;
|
||||||
|
case OBJ_PROTECT_CLOSE | OBJ_INHERIT:
|
||||||
|
PhInitializeStringRef(&getCellText->Text, L"Protected, Inherit");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PHHNTLC_GRANTEDACCESS:
|
||||||
|
PhInitializeStringRefLongHint(&getCellText->Text, handleItem->GrantedAccessString);
|
||||||
|
break;
|
||||||
|
case PHHNTLC_GRANTEDACCESSSYMBOLIC:
|
||||||
|
if (handleItem->GrantedAccess != 0)
|
||||||
|
{
|
||||||
|
if (!node->GrantedAccessSymbolicText)
|
||||||
|
{
|
||||||
|
PPH_ACCESS_ENTRY accessEntries;
|
||||||
|
ULONG numberOfAccessEntries;
|
||||||
|
|
||||||
|
if (PhGetAccessEntries(handleItem->TypeName->Buffer, &accessEntries, &numberOfAccessEntries))
|
||||||
|
{
|
||||||
|
node->GrantedAccessSymbolicText = PhGetAccessString(handleItem->GrantedAccess, accessEntries, numberOfAccessEntries);
|
||||||
|
PhFree(accessEntries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->GrantedAccessSymbolicText = PhReferenceEmptyString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->GrantedAccessSymbolicText->Length != 0)
|
||||||
|
getCellText->Text = node->GrantedAccessSymbolicText->sr;
|
||||||
|
else
|
||||||
|
PhInitializeStringRefLongHint(&getCellText->Text, handleItem->GrantedAccessString);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PHHNTLC_ORIGINALNAME:
|
||||||
|
getCellText->Text = PhGetStringRef(handleItem->ObjectName);
|
||||||
|
break;
|
||||||
|
case PHHNTLC_FILESHAREACCESS:
|
||||||
|
if (handleItem->FileFlags & PH_HANDLE_FILE_SHARED_MASK)
|
||||||
|
{
|
||||||
|
node->FileShareAccessText[0] = '-';
|
||||||
|
node->FileShareAccessText[1] = '-';
|
||||||
|
node->FileShareAccessText[2] = '-';
|
||||||
|
node->FileShareAccessText[3] = 0;
|
||||||
|
|
||||||
|
if (handleItem->FileFlags & PH_HANDLE_FILE_SHARED_READ)
|
||||||
|
node->FileShareAccessText[0] = 'R';
|
||||||
|
if (handleItem->FileFlags & PH_HANDLE_FILE_SHARED_WRITE)
|
||||||
|
node->FileShareAccessText[1] = 'W';
|
||||||
|
if (handleItem->FileFlags & PH_HANDLE_FILE_SHARED_DELETE)
|
||||||
|
node->FileShareAccessText[2] = 'D';
|
||||||
|
|
||||||
|
PhInitializeStringRef(&getCellText->Text, node->FileShareAccessText);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCellText->Flags = TN_CACHE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewGetNodeColor:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_GET_NODE_COLOR getNodeColor = Parameter1;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
node = (PPH_HANDLE_NODE)getNodeColor->Node;
|
||||||
|
handleItem = node->HandleItem;
|
||||||
|
|
||||||
|
if (!handleItem)
|
||||||
|
; // Dummy
|
||||||
|
else if (PhCsUseColorProtectedHandles && (handleItem->Attributes & OBJ_PROTECT_CLOSE))
|
||||||
|
getNodeColor->BackColor = PhCsColorProtectedHandles;
|
||||||
|
else if (PhCsUseColorInheritHandles && (handleItem->Attributes & OBJ_INHERIT))
|
||||||
|
getNodeColor->BackColor = PhCsColorInheritHandles;
|
||||||
|
|
||||||
|
getNodeColor->Flags = TN_CACHE | TN_AUTO_FORECOLOR;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewSortChanged:
|
||||||
|
{
|
||||||
|
TreeNew_GetSort(hwnd, &context->TreeNewSortColumn, &context->TreeNewSortOrder);
|
||||||
|
// Force a rebuild to sort the items.
|
||||||
|
TreeNew_NodesStructured(hwnd);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewKeyDown:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_KEY_EVENT keyEvent = Parameter1;
|
||||||
|
|
||||||
|
switch (keyEvent->VirtualKey)
|
||||||
|
{
|
||||||
|
case 'C':
|
||||||
|
if (GetKeyState(VK_CONTROL) < 0)
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_HANDLE_COPY, 0);
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
if (GetKeyState(VK_CONTROL) < 0)
|
||||||
|
TreeNew_SelectRange(context->TreeNewHandle, 0, -1);
|
||||||
|
break;
|
||||||
|
case VK_DELETE:
|
||||||
|
// Pass a 1 in lParam to indicate that warnings should be enabled.
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_HANDLE_CLOSE, 1);
|
||||||
|
break;
|
||||||
|
case VK_RETURN:
|
||||||
|
if (GetKeyState(VK_CONTROL) >= 0)
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_HANDLE_PROPERTIES, 0);
|
||||||
|
else
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_HANDLE_OBJECTPROPERTIES1, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewHeaderRightClick:
|
||||||
|
{
|
||||||
|
PH_TN_COLUMN_MENU_DATA data;
|
||||||
|
|
||||||
|
data.TreeNewHandle = hwnd;
|
||||||
|
data.MouseEvent = Parameter1;
|
||||||
|
data.DefaultSortColumn = 0;
|
||||||
|
data.DefaultSortOrder = AscendingSortOrder;
|
||||||
|
PhInitializeTreeNewColumnMenu(&data);
|
||||||
|
|
||||||
|
data.Selection = PhShowEMenu(data.Menu, hwnd, PH_EMENU_SHOW_LEFTRIGHT,
|
||||||
|
PH_ALIGN_LEFT | PH_ALIGN_TOP, data.MouseEvent->ScreenLocation.x, data.MouseEvent->ScreenLocation.y);
|
||||||
|
PhHandleTreeNewColumnMenu(&data);
|
||||||
|
PhDeleteTreeNewColumnMenu(&data);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewLeftDoubleClick:
|
||||||
|
{
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_HANDLE_PROPERTIES, 0);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewContextMenu:
|
||||||
|
{
|
||||||
|
PPH_TREENEW_CONTEXT_MENU contextMenu = Parameter1;
|
||||||
|
|
||||||
|
SendMessage(context->ParentWindowHandle, WM_COMMAND, ID_SHOWCONTEXTMENU, (LPARAM)contextMenu);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
case TreeNewGetDialogCode:
|
||||||
|
{
|
||||||
|
PULONG code = Parameter2;
|
||||||
|
|
||||||
|
if (PtrToUlong(Parameter1) == VK_RETURN)
|
||||||
|
{
|
||||||
|
*code = DLGC_WANTMESSAGE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhGetSelectedHandleItem(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_ITEM handleItem = NULL;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
for (i = 0; i < Context->NodeList->Count; i++)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_NODE node = Context->NodeList->Items[i];
|
||||||
|
|
||||||
|
if (node->Node.Selected)
|
||||||
|
{
|
||||||
|
handleItem = node->HandleItem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handleItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhGetSelectedHandleItems(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_Out_ PPH_HANDLE_ITEM **Handles,
|
||||||
|
_Out_ PULONG NumberOfHandles
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_ARRAY array;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
PhInitializeArray(&array, sizeof(PVOID), 2);
|
||||||
|
|
||||||
|
for (i = 0; i < Context->NodeList->Count; i++)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_NODE node = Context->NodeList->Items[i];
|
||||||
|
|
||||||
|
if (node->Node.Selected)
|
||||||
|
PhAddItemArray(&array, &node->HandleItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
*NumberOfHandles = (ULONG)array.Count;
|
||||||
|
*Handles = PhFinalArrayItems(&array);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhDeselectAllHandleNodes(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TreeNew_DeselectRange(Context->TreeNewHandle, 0, -1);
|
||||||
|
}
|
377
ProcessHacker/hndlmenu.c
Normal file
377
ProcessHacker/hndlmenu.c
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* common handle menu items
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <hndlmenu.h>
|
||||||
|
#include <procprv.h>
|
||||||
|
#include <kphuser.h>
|
||||||
|
#include <emenu.h>
|
||||||
|
#include <hndlinfo.h>
|
||||||
|
|
||||||
|
VOID PhInsertHandleObjectPropertiesEMenuItems(
|
||||||
|
_In_ struct _PH_EMENU_ITEM *Menu,
|
||||||
|
_In_ ULONG InsertBeforeId,
|
||||||
|
_In_ BOOLEAN EnableShortcut,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_EMENU_ITEM parentItem;
|
||||||
|
ULONG indexInParent;
|
||||||
|
|
||||||
|
if (!PhFindEMenuItemEx(Menu, 0, NULL, InsertBeforeId, &parentItem, &indexInParent))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) ||
|
||||||
|
PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE))
|
||||||
|
{
|
||||||
|
if (PhEqualString2(Info->TypeName, L"File", TRUE))
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES2, L"File properties", NULL, NULL), indexInParent);
|
||||||
|
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES1, PhaAppendCtrlEnter(L"Open &file location", EnableShortcut), NULL, NULL), indexInParent);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Key", TRUE))
|
||||||
|
{
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES1, PhaAppendCtrlEnter(L"Open key", EnableShortcut), NULL, NULL), indexInParent);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Process", TRUE))
|
||||||
|
{
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES1, PhaAppendCtrlEnter(L"Process properties", EnableShortcut), NULL, NULL), indexInParent);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Section", TRUE))
|
||||||
|
{
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES1, PhaAppendCtrlEnter(L"Read/Write memory", EnableShortcut), NULL, NULL), indexInParent);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Thread", TRUE))
|
||||||
|
{
|
||||||
|
PhInsertEMenuItem(parentItem, PhCreateEMenuItem(0, ID_HANDLE_OBJECTPROPERTIES1, PhaAppendCtrlEnter(L"Go to thread", EnableShortcut), NULL, NULL), indexInParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS PhpDuplicateHandleFromProcessItem(
|
||||||
|
_Out_ PHANDLE NewHandle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
PROCESS_DUP_HANDLE,
|
||||||
|
ProcessId
|
||||||
|
)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = NtDuplicateObject(
|
||||||
|
processHandle,
|
||||||
|
Handle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
NewHandle,
|
||||||
|
DesiredAccess,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
NtClose(processHandle);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID PhpShowProcessPropContext(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhShowProcessProperties(Parameter);
|
||||||
|
PhDereferenceObject(Parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhShowHandleObjectProperties1(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) ||
|
||||||
|
PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE))
|
||||||
|
{
|
||||||
|
if (Info->BestObjectName)
|
||||||
|
PhShellExploreFile(hWnd, Info->BestObjectName->Buffer);
|
||||||
|
else
|
||||||
|
PhShowError(hWnd, L"Unable to open file location because the object is unnamed.");
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Key", TRUE))
|
||||||
|
{
|
||||||
|
if (Info->BestObjectName)
|
||||||
|
PhShellOpenKey2(hWnd, Info->BestObjectName);
|
||||||
|
else
|
||||||
|
PhShowError(hWnd, L"Unable to open key because the object is unnamed.");
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Process", TRUE))
|
||||||
|
{
|
||||||
|
HANDLE processHandle;
|
||||||
|
HANDLE processId;
|
||||||
|
PPH_PROCESS_ITEM targetProcessItem;
|
||||||
|
|
||||||
|
processId = NULL;
|
||||||
|
|
||||||
|
if (KphIsConnected())
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess,
|
||||||
|
Info->ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
PROCESS_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(KphQueryInformationObject(
|
||||||
|
processHandle,
|
||||||
|
Info->Handle,
|
||||||
|
KphObjectProcessBasicInformation,
|
||||||
|
&basicInfo,
|
||||||
|
sizeof(PROCESS_BASIC_INFORMATION),
|
||||||
|
NULL
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
processId = basicInfo.UniqueProcessId;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
PROCESS_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem(
|
||||||
|
&handle,
|
||||||
|
ProcessQueryAccess,
|
||||||
|
Info->ProcessId,
|
||||||
|
Info->Handle
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhGetProcessBasicInformation(handle, &basicInfo)))
|
||||||
|
processId = basicInfo.UniqueProcessId;
|
||||||
|
|
||||||
|
NtClose(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processId)
|
||||||
|
{
|
||||||
|
targetProcessItem = PhReferenceProcessItem(processId);
|
||||||
|
|
||||||
|
if (targetProcessItem)
|
||||||
|
{
|
||||||
|
ProcessHacker_ShowProcessProperties(PhMainWndHandle, targetProcessItem);
|
||||||
|
PhDereferenceObject(targetProcessItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhShowError(hWnd, L"The process does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Section", TRUE))
|
||||||
|
{
|
||||||
|
HANDLE handle = NULL;
|
||||||
|
BOOLEAN readOnly = FALSE;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(PhpDuplicateHandleFromProcessItem(
|
||||||
|
&handle,
|
||||||
|
SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
|
||||||
|
Info->ProcessId,
|
||||||
|
Info->Handle
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
PhpDuplicateHandleFromProcessItem(
|
||||||
|
&handle,
|
||||||
|
SECTION_QUERY | SECTION_MAP_READ,
|
||||||
|
Info->ProcessId,
|
||||||
|
Info->Handle
|
||||||
|
);
|
||||||
|
readOnly = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PPH_STRING sectionName = NULL;
|
||||||
|
SECTION_BASIC_INFORMATION basicInfo;
|
||||||
|
SIZE_T viewSize = PH_MAX_SECTION_EDIT_SIZE;
|
||||||
|
PVOID viewBase = NULL;
|
||||||
|
BOOLEAN tooBig = FALSE;
|
||||||
|
|
||||||
|
PhGetHandleInformation(NtCurrentProcess(), handle, -1, NULL, NULL, NULL, §ionName);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhGetSectionBasicInformation(handle, &basicInfo)))
|
||||||
|
{
|
||||||
|
if (basicInfo.MaximumSize.QuadPart <= PH_MAX_SECTION_EDIT_SIZE)
|
||||||
|
viewSize = (SIZE_T)basicInfo.MaximumSize.QuadPart;
|
||||||
|
else
|
||||||
|
tooBig = TRUE;
|
||||||
|
|
||||||
|
status = NtMapViewOfSection(
|
||||||
|
handle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&viewBase,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&viewSize,
|
||||||
|
ViewShare,
|
||||||
|
0,
|
||||||
|
readOnly ? PAGE_READONLY : PAGE_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (status == STATUS_SECTION_PROTECTION && !readOnly)
|
||||||
|
{
|
||||||
|
status = NtMapViewOfSection(
|
||||||
|
handle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&viewBase,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&viewSize,
|
||||||
|
ViewShare,
|
||||||
|
0,
|
||||||
|
PAGE_READONLY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
PPH_SHOWMEMORYEDITOR showMemoryEditor = PhAllocate(sizeof(PH_SHOWMEMORYEDITOR));
|
||||||
|
|
||||||
|
if (tooBig)
|
||||||
|
PhShowWarning(hWnd, L"The section size is greater than 32 MB. Only the first 32 MB will be available for editing.");
|
||||||
|
|
||||||
|
memset(showMemoryEditor, 0, sizeof(PH_SHOWMEMORYEDITOR));
|
||||||
|
showMemoryEditor->ProcessId = NtCurrentProcessId();
|
||||||
|
showMemoryEditor->BaseAddress = viewBase;
|
||||||
|
showMemoryEditor->RegionSize = viewSize;
|
||||||
|
showMemoryEditor->SelectOffset = -1;
|
||||||
|
showMemoryEditor->SelectLength = 0;
|
||||||
|
showMemoryEditor->Title = sectionName ? PhConcatStrings2(L"Section - ", sectionName->Buffer) : PhCreateString(L"Section");
|
||||||
|
showMemoryEditor->Flags = PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION;
|
||||||
|
ProcessHacker_ShowMemoryEditor(PhMainWndHandle, showMemoryEditor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhShowStatus(hWnd, L"Unable to map a view of the section", status, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhClearReference(§ionName);
|
||||||
|
|
||||||
|
NtClose(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(Info->TypeName, L"Thread", TRUE))
|
||||||
|
{
|
||||||
|
HANDLE processHandle;
|
||||||
|
CLIENT_ID clientId;
|
||||||
|
PPH_PROCESS_ITEM targetProcessItem;
|
||||||
|
PPH_PROCESS_PROPCONTEXT propContext;
|
||||||
|
|
||||||
|
clientId.UniqueProcess = NULL;
|
||||||
|
clientId.UniqueThread = NULL;
|
||||||
|
|
||||||
|
if (KphIsConnected())
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
ProcessQueryAccess,
|
||||||
|
Info->ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
THREAD_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(KphQueryInformationObject(
|
||||||
|
processHandle,
|
||||||
|
Info->Handle,
|
||||||
|
KphObjectThreadBasicInformation,
|
||||||
|
&basicInfo,
|
||||||
|
sizeof(THREAD_BASIC_INFORMATION),
|
||||||
|
NULL
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
clientId = basicInfo.ClientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
THREAD_BASIC_INFORMATION basicInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem(
|
||||||
|
&handle,
|
||||||
|
ThreadQueryAccess,
|
||||||
|
Info->ProcessId,
|
||||||
|
Info->Handle
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhGetThreadBasicInformation(handle, &basicInfo)))
|
||||||
|
clientId = basicInfo.ClientId;
|
||||||
|
|
||||||
|
NtClose(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientId.UniqueProcess)
|
||||||
|
{
|
||||||
|
targetProcessItem = PhReferenceProcessItem(clientId.UniqueProcess);
|
||||||
|
|
||||||
|
if (targetProcessItem)
|
||||||
|
{
|
||||||
|
propContext = PhCreateProcessPropContext(PhMainWndHandle, targetProcessItem);
|
||||||
|
PhDereferenceObject(targetProcessItem);
|
||||||
|
PhSetSelectThreadIdProcessPropContext(propContext, clientId.UniqueThread);
|
||||||
|
ProcessHacker_Invoke(PhMainWndHandle, PhpShowProcessPropContext, propContext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhShowError(hWnd, L"The process does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhShowHandleObjectProperties2(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) ||
|
||||||
|
PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE))
|
||||||
|
{
|
||||||
|
if (Info->BestObjectName)
|
||||||
|
PhShellProperties(hWnd, Info->BestObjectName->Buffer);
|
||||||
|
else
|
||||||
|
PhShowError(hWnd, L"Unable to open file properties because the object is unnamed.");
|
||||||
|
}
|
||||||
|
}
|
331
ProcessHacker/hndlprp.c
Normal file
331
ProcessHacker/hndlprp.c
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* handle properties
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2013 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <kphuser.h>
|
||||||
|
#include <hndlprv.h>
|
||||||
|
#include <hndlinfo.h>
|
||||||
|
#include <secedit.h>
|
||||||
|
#include <phplug.h>
|
||||||
|
|
||||||
|
typedef struct _HANDLE_PROPERTIES_CONTEXT
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_HANDLE_ITEM HandleItem;
|
||||||
|
} HANDLE_PROPERTIES_CONTEXT, *PHANDLE_PROPERTIES_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpHandleGeneralDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
static NTSTATUS PhpDuplicateHandleFromProcess(
|
||||||
|
_Out_ PHANDLE Handle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
PHANDLE_PROPERTIES_CONTEXT context = Context;
|
||||||
|
HANDLE processHandle;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
PROCESS_DUP_HANDLE,
|
||||||
|
context->ProcessId
|
||||||
|
)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = NtDuplicateObject(
|
||||||
|
processHandle,
|
||||||
|
context->HandleItem->Handle,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
Handle,
|
||||||
|
DesiredAccess,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
NtClose(processHandle);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhShowHandleProperties(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PPH_HANDLE_ITEM HandleItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PROPSHEETHEADER propSheetHeader = { sizeof(propSheetHeader) };
|
||||||
|
PROPSHEETPAGE propSheetPage;
|
||||||
|
HPROPSHEETPAGE pages[16];
|
||||||
|
HANDLE_PROPERTIES_CONTEXT context;
|
||||||
|
PH_STD_OBJECT_SECURITY stdObjectSecurity;
|
||||||
|
PPH_ACCESS_ENTRY accessEntries;
|
||||||
|
ULONG numberOfAccessEntries;
|
||||||
|
|
||||||
|
context.ProcessId = ProcessId;
|
||||||
|
context.HandleItem = HandleItem;
|
||||||
|
|
||||||
|
propSheetHeader.dwFlags =
|
||||||
|
PSH_NOAPPLYNOW |
|
||||||
|
PSH_NOCONTEXTHELP |
|
||||||
|
PSH_PROPTITLE;
|
||||||
|
propSheetHeader.hwndParent = ParentWindowHandle;
|
||||||
|
propSheetHeader.pszCaption = L"Handle";
|
||||||
|
propSheetHeader.nPages = 0;
|
||||||
|
propSheetHeader.nStartPage = 0;
|
||||||
|
propSheetHeader.phpage = pages;
|
||||||
|
|
||||||
|
// General page
|
||||||
|
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
|
||||||
|
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
|
||||||
|
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_HNDLGENERAL);
|
||||||
|
propSheetPage.pfnDlgProc = PhpHandleGeneralDlgProc;
|
||||||
|
propSheetPage.lParam = (LPARAM)&context;
|
||||||
|
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
|
||||||
|
|
||||||
|
// Object-specific page
|
||||||
|
if (!HandleItem->TypeName)
|
||||||
|
{
|
||||||
|
// Dummy
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Event", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateEventPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"EventPair", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateEventPairPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Job", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateJobPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Mutant", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateMutantPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Section", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateSectionPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Semaphore", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateSemaphorePage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Timer", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateTimerPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (PhEqualString2(HandleItem->TypeName, L"Token", TRUE))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateTokenPage(
|
||||||
|
PhpDuplicateHandleFromProcess,
|
||||||
|
&context,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security page
|
||||||
|
stdObjectSecurity.OpenObject = PhpDuplicateHandleFromProcess;
|
||||||
|
stdObjectSecurity.ObjectType = HandleItem->TypeName->Buffer;
|
||||||
|
stdObjectSecurity.Context = &context;
|
||||||
|
|
||||||
|
if (PhGetAccessEntries(HandleItem->TypeName->Buffer, &accessEntries, &numberOfAccessEntries))
|
||||||
|
{
|
||||||
|
pages[propSheetHeader.nPages++] = PhCreateSecurityPage(
|
||||||
|
PhGetStringOrEmpty(HandleItem->BestObjectName),
|
||||||
|
PhStdGetObjectSecurity,
|
||||||
|
PhStdSetObjectSecurity,
|
||||||
|
&stdObjectSecurity,
|
||||||
|
accessEntries,
|
||||||
|
numberOfAccessEntries
|
||||||
|
);
|
||||||
|
PhFree(accessEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhPluginsEnabled)
|
||||||
|
{
|
||||||
|
PH_PLUGIN_OBJECT_PROPERTIES objectProperties;
|
||||||
|
PH_PLUGIN_HANDLE_PROPERTIES_CONTEXT propertiesContext;
|
||||||
|
|
||||||
|
propertiesContext.ProcessId = ProcessId;
|
||||||
|
propertiesContext.HandleItem = HandleItem;
|
||||||
|
|
||||||
|
objectProperties.Parameter = &propertiesContext;
|
||||||
|
objectProperties.NumberOfPages = propSheetHeader.nPages;
|
||||||
|
objectProperties.MaximumNumberOfPages = sizeof(pages) / sizeof(HPROPSHEETPAGE);
|
||||||
|
objectProperties.Pages = pages;
|
||||||
|
|
||||||
|
PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackHandlePropertiesInitializing), &objectProperties);
|
||||||
|
|
||||||
|
propSheetHeader.nPages = objectProperties.NumberOfPages;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhModalPropertySheet(&propSheetHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpHandleGeneralDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam;
|
||||||
|
PHANDLE_PROPERTIES_CONTEXT context = (PHANDLE_PROPERTIES_CONTEXT)propSheetPage->lParam;
|
||||||
|
PPH_ACCESS_ENTRY accessEntries;
|
||||||
|
ULONG numberOfAccessEntries;
|
||||||
|
HANDLE processHandle;
|
||||||
|
OBJECT_BASIC_INFORMATION basicInfo;
|
||||||
|
BOOLEAN haveBasicInfo = FALSE;
|
||||||
|
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
|
||||||
|
|
||||||
|
SetDlgItemText(hwndDlg, IDC_NAME, PhGetString(context->HandleItem->BestObjectName));
|
||||||
|
SetDlgItemText(hwndDlg, IDC_TYPE, context->HandleItem->TypeName->Buffer);
|
||||||
|
SetDlgItemText(hwndDlg, IDC_ADDRESS, context->HandleItem->ObjectString);
|
||||||
|
|
||||||
|
if (PhGetAccessEntries(
|
||||||
|
context->HandleItem->TypeName->Buffer,
|
||||||
|
&accessEntries,
|
||||||
|
&numberOfAccessEntries
|
||||||
|
))
|
||||||
|
{
|
||||||
|
PPH_STRING accessString;
|
||||||
|
PPH_STRING grantedAccessString;
|
||||||
|
|
||||||
|
accessString = PH_AUTO(PhGetAccessString(
|
||||||
|
context->HandleItem->GrantedAccess,
|
||||||
|
accessEntries,
|
||||||
|
numberOfAccessEntries
|
||||||
|
));
|
||||||
|
|
||||||
|
if (accessString->Length != 0)
|
||||||
|
{
|
||||||
|
grantedAccessString = PhaFormatString(
|
||||||
|
L"%s (%s)",
|
||||||
|
context->HandleItem->GrantedAccessString,
|
||||||
|
accessString->Buffer
|
||||||
|
);
|
||||||
|
SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, grantedAccessString->Buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(accessEntries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetDlgItemText(hwndDlg, IDC_GRANTED_ACCESS, context->HandleItem->GrantedAccessString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(PhOpenProcess(
|
||||||
|
&processHandle,
|
||||||
|
PROCESS_DUP_HANDLE,
|
||||||
|
context->ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (NT_SUCCESS(PhGetHandleInformation(
|
||||||
|
processHandle,
|
||||||
|
context->HandleItem->Handle,
|
||||||
|
-1,
|
||||||
|
&basicInfo,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
SetDlgItemInt(hwndDlg, IDC_REFERENCES, basicInfo.PointerCount, FALSE);
|
||||||
|
SetDlgItemInt(hwndDlg, IDC_HANDLES, basicInfo.HandleCount, FALSE);
|
||||||
|
SetDlgItemInt(hwndDlg, IDC_PAGED, basicInfo.PagedPoolCharge, FALSE);
|
||||||
|
SetDlgItemInt(hwndDlg, IDC_NONPAGED, basicInfo.NonPagedPoolCharge, FALSE);
|
||||||
|
|
||||||
|
haveBasicInfo = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(processHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!haveBasicInfo)
|
||||||
|
{
|
||||||
|
SetDlgItemText(hwndDlg, IDC_REFERENCES, L"Unknown");
|
||||||
|
SetDlgItemText(hwndDlg, IDC_HANDLES, L"Unknown");
|
||||||
|
SetDlgItemText(hwndDlg, IDC_PAGED, L"Unknown");
|
||||||
|
SetDlgItemText(hwndDlg, IDC_NONPAGED, L"Unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
LPNMHDR header = (LPNMHDR)lParam;
|
||||||
|
|
||||||
|
switch (header->code)
|
||||||
|
{
|
||||||
|
case PSN_QUERYINITIALFOCUS:
|
||||||
|
{
|
||||||
|
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_BASICINFORMATION));
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
718
ProcessHacker/hndlprv.c
Normal file
718
ProcessHacker/hndlprv.c
Normal file
@ -0,0 +1,718 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* handle provider
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2015 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <hndlprv.h>
|
||||||
|
#include <workqueue.h>
|
||||||
|
#include <kphuser.h>
|
||||||
|
#include <hndlinfo.h>
|
||||||
|
#include <extmgri.h>
|
||||||
|
|
||||||
|
typedef struct _PHP_CREATE_HANDLE_ITEM_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_HANDLE_PROVIDER Provider;
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handle;
|
||||||
|
} PHP_CREATE_HANDLE_ITEM_CONTEXT, *PPHP_CREATE_HANDLE_ITEM_CONTEXT;
|
||||||
|
|
||||||
|
VOID NTAPI PhpHandleProviderDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhpHandleItemDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_OBJECT_TYPE PhHandleProviderType;
|
||||||
|
PPH_OBJECT_TYPE PhHandleItemType;
|
||||||
|
|
||||||
|
BOOLEAN PhHandleProviderInitialization(
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhHandleProviderType = PhCreateObjectType(L"HandleProvider", 0, PhpHandleProviderDeleteProcedure);
|
||||||
|
PhHandleItemType = PhCreateObjectType(L"HandleItem", 0, PhpHandleItemDeleteProcedure);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_PROVIDER PhCreateHandleProvider(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_PROVIDER handleProvider;
|
||||||
|
|
||||||
|
handleProvider = PhCreateObject(
|
||||||
|
PhEmGetObjectSize(EmHandleProviderType, sizeof(PH_HANDLE_PROVIDER)),
|
||||||
|
PhHandleProviderType
|
||||||
|
);
|
||||||
|
|
||||||
|
handleProvider->HandleHashSetSize = 128;
|
||||||
|
handleProvider->HandleHashSet = PhCreateHashSet(handleProvider->HandleHashSetSize);
|
||||||
|
handleProvider->HandleHashSetCount = 0;
|
||||||
|
PhInitializeQueuedLock(&handleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
PhInitializeCallback(&handleProvider->HandleAddedEvent);
|
||||||
|
PhInitializeCallback(&handleProvider->HandleModifiedEvent);
|
||||||
|
PhInitializeCallback(&handleProvider->HandleRemovedEvent);
|
||||||
|
PhInitializeCallback(&handleProvider->UpdatedEvent);
|
||||||
|
|
||||||
|
handleProvider->ProcessId = ProcessId;
|
||||||
|
handleProvider->ProcessHandle = NULL;
|
||||||
|
|
||||||
|
handleProvider->RunStatus = PhOpenProcess(
|
||||||
|
&handleProvider->ProcessHandle,
|
||||||
|
PROCESS_DUP_HANDLE,
|
||||||
|
ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
handleProvider->TempListHashtable = PhCreateSimpleHashtable(20);
|
||||||
|
|
||||||
|
PhEmCallObjectOperation(EmHandleProviderType, handleProvider, EmObjectCreate);
|
||||||
|
|
||||||
|
return handleProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpHandleProviderDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_PROVIDER handleProvider = (PPH_HANDLE_PROVIDER)Object;
|
||||||
|
|
||||||
|
PhEmCallObjectOperation(EmHandleProviderType, handleProvider, EmObjectDelete);
|
||||||
|
|
||||||
|
// Dereference all handle items (we referenced them
|
||||||
|
// when we added them to the hashtable).
|
||||||
|
PhDereferenceAllHandleItems(handleProvider);
|
||||||
|
|
||||||
|
PhFree(handleProvider->HandleHashSet);
|
||||||
|
PhDeleteCallback(&handleProvider->HandleAddedEvent);
|
||||||
|
PhDeleteCallback(&handleProvider->HandleModifiedEvent);
|
||||||
|
PhDeleteCallback(&handleProvider->HandleRemovedEvent);
|
||||||
|
|
||||||
|
if (handleProvider->ProcessHandle) NtClose(handleProvider->ProcessHandle);
|
||||||
|
|
||||||
|
PhDereferenceObject(handleProvider->TempListHashtable);
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhCreateHandleItem(
|
||||||
|
_In_opt_ PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
handleItem = PhCreateObject(
|
||||||
|
PhEmGetObjectSize(EmHandleItemType, sizeof(PH_HANDLE_ITEM)),
|
||||||
|
PhHandleItemType
|
||||||
|
);
|
||||||
|
memset(handleItem, 0, sizeof(PH_HANDLE_ITEM));
|
||||||
|
|
||||||
|
if (Handle)
|
||||||
|
{
|
||||||
|
handleItem->Handle = (HANDLE)Handle->HandleValue;
|
||||||
|
PhPrintPointer(handleItem->HandleString, (PVOID)handleItem->Handle);
|
||||||
|
handleItem->Object = Handle->Object;
|
||||||
|
PhPrintPointer(handleItem->ObjectString, handleItem->Object);
|
||||||
|
handleItem->Attributes = Handle->HandleAttributes;
|
||||||
|
handleItem->GrantedAccess = (ACCESS_MASK)Handle->GrantedAccess;
|
||||||
|
PhPrintPointer(handleItem->GrantedAccessString, UlongToPtr(handleItem->GrantedAccess));
|
||||||
|
}
|
||||||
|
|
||||||
|
PhEmCallObjectOperation(EmHandleItemType, handleItem, EmObjectCreate);
|
||||||
|
|
||||||
|
return handleItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpHandleItemDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_ITEM handleItem = (PPH_HANDLE_ITEM)Object;
|
||||||
|
|
||||||
|
PhEmCallObjectOperation(EmHandleItemType, handleItem, EmObjectDelete);
|
||||||
|
|
||||||
|
if (handleItem->TypeName) PhDereferenceObject(handleItem->TypeName);
|
||||||
|
if (handleItem->ObjectName) PhDereferenceObject(handleItem->ObjectName);
|
||||||
|
if (handleItem->BestObjectName) PhDereferenceObject(handleItem->BestObjectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE BOOLEAN PhCompareHandleItem(
|
||||||
|
_In_ PPH_HANDLE_ITEM Value1,
|
||||||
|
_In_ PPH_HANDLE_ITEM Value2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Value1->Handle == Value2->Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE ULONG PhHashHandleItem(
|
||||||
|
_In_ PPH_HANDLE_ITEM Value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return HandleToUlong(Value->Handle) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhpLookupHandleItem(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_HANDLE_ITEM lookupHandleItem;
|
||||||
|
PPH_HASH_ENTRY entry;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
lookupHandleItem.Handle = Handle;
|
||||||
|
entry = PhFindEntryHashSet(
|
||||||
|
HandleProvider->HandleHashSet,
|
||||||
|
HandleProvider->HandleHashSetSize,
|
||||||
|
PhHashHandleItem(&lookupHandleItem)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (; entry; entry = entry->Next)
|
||||||
|
{
|
||||||
|
handleItem = CONTAINING_RECORD(entry, PH_HANDLE_ITEM, HashEntry);
|
||||||
|
|
||||||
|
if (PhCompareHandleItem(&lookupHandleItem, handleItem))
|
||||||
|
return handleItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhReferenceHandleItem(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
PhAcquireQueuedLockShared(&HandleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
handleItem = PhpLookupHandleItem(HandleProvider, Handle);
|
||||||
|
|
||||||
|
if (handleItem)
|
||||||
|
PhReferenceObject(handleItem);
|
||||||
|
|
||||||
|
PhReleaseQueuedLockShared(&HandleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
return handleItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhDereferenceAllHandleItems(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
PPH_HASH_ENTRY entry;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
PhAcquireQueuedLockExclusive(&HandleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
for (i = 0; i < HandleProvider->HandleHashSetSize; i++)
|
||||||
|
{
|
||||||
|
entry = HandleProvider->HandleHashSet[i];
|
||||||
|
|
||||||
|
while (entry)
|
||||||
|
{
|
||||||
|
handleItem = CONTAINING_RECORD(entry, PH_HANDLE_ITEM, HashEntry);
|
||||||
|
entry = entry->Next;
|
||||||
|
PhDereferenceObject(handleItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhReleaseQueuedLockExclusive(&HandleProvider->HandleHashSetLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpAddHandleItem(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider,
|
||||||
|
_In_ _Assume_refs_(1) PPH_HANDLE_ITEM HandleItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (HandleProvider->HandleHashSetSize < HandleProvider->HandleHashSetCount + 1)
|
||||||
|
{
|
||||||
|
PhResizeHashSet(
|
||||||
|
&HandleProvider->HandleHashSet,
|
||||||
|
&HandleProvider->HandleHashSetSize,
|
||||||
|
HandleProvider->HandleHashSetSize * 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhAddEntryHashSet(
|
||||||
|
HandleProvider->HandleHashSet,
|
||||||
|
HandleProvider->HandleHashSetSize,
|
||||||
|
&HandleItem->HashEntry,
|
||||||
|
PhHashHandleItem(HandleItem)
|
||||||
|
);
|
||||||
|
HandleProvider->HandleHashSetCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhpRemoveHandleItem(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider,
|
||||||
|
_In_ PPH_HANDLE_ITEM HandleItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhRemoveEntryHashSet(HandleProvider->HandleHashSet, HandleProvider->HandleHashSetSize, &HandleItem->HashEntry);
|
||||||
|
HandleProvider->HandleHashSetCount--;
|
||||||
|
PhDereferenceObject(HandleItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates all handles in a process.
|
||||||
|
*
|
||||||
|
* \param ProcessId The ID of the process.
|
||||||
|
* \param ProcessHandle A handle to the process.
|
||||||
|
* \param Handles A variable which receives a pointer to a buffer containing
|
||||||
|
* information about the handles.
|
||||||
|
* \param FilterNeeded A variable which receives a boolean indicating
|
||||||
|
* whether the handle information needs to be filtered by process ID.
|
||||||
|
*/
|
||||||
|
NTSTATUS PhEnumHandlesGeneric(
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_Out_ PSYSTEM_HANDLE_INFORMATION_EX *Handles,
|
||||||
|
_Out_ PBOOLEAN FilterNeeded
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
// There are three ways of enumerating handles:
|
||||||
|
// * When KProcessHacker is available, using KphEnumerateProcessHandles
|
||||||
|
// is the most efficient method.
|
||||||
|
// * On Windows XP and later, NtQuerySystemInformation with
|
||||||
|
// SystemExtendedHandleInformation can be used.
|
||||||
|
// * Otherwise, NtQuerySystemInformation with SystemHandleInformation
|
||||||
|
// can be used.
|
||||||
|
|
||||||
|
if (KphIsConnected())
|
||||||
|
{
|
||||||
|
PKPH_PROCESS_HANDLE_INFORMATION handles;
|
||||||
|
PSYSTEM_HANDLE_INFORMATION_EX convertedHandles;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
// Enumerate handles using KProcessHacker. Unlike with NtQuerySystemInformation,
|
||||||
|
// this only enumerates handles for a single process and saves a lot of processing.
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status = KphEnumerateProcessHandles2(ProcessHandle, &handles)))
|
||||||
|
{
|
||||||
|
convertedHandles = PhAllocate(
|
||||||
|
FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handles) +
|
||||||
|
sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX) * handles->HandleCount
|
||||||
|
);
|
||||||
|
|
||||||
|
convertedHandles->NumberOfHandles = handles->HandleCount;
|
||||||
|
|
||||||
|
for (i = 0; i < handles->HandleCount; i++)
|
||||||
|
{
|
||||||
|
convertedHandles->Handles[i].Object = handles->Handles[i].Object;
|
||||||
|
convertedHandles->Handles[i].UniqueProcessId = (ULONG_PTR)ProcessId;
|
||||||
|
convertedHandles->Handles[i].HandleValue = (ULONG_PTR)handles->Handles[i].Handle;
|
||||||
|
convertedHandles->Handles[i].GrantedAccess = (ULONG)handles->Handles[i].GrantedAccess;
|
||||||
|
convertedHandles->Handles[i].CreatorBackTraceIndex = 0;
|
||||||
|
convertedHandles->Handles[i].ObjectTypeIndex = handles->Handles[i].ObjectTypeIndex;
|
||||||
|
convertedHandles->Handles[i].HandleAttributes = handles->Handles[i].HandleAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(handles);
|
||||||
|
|
||||||
|
*Handles = convertedHandles;
|
||||||
|
*FilterNeeded = FALSE;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WindowsVersion >= WINDOWS_XP)
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_INFORMATION_EX handles;
|
||||||
|
|
||||||
|
// Enumerate handles using the new method; no conversion
|
||||||
|
// necessary.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhEnumHandlesEx(&handles)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
*Handles = handles;
|
||||||
|
*FilterNeeded = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_INFORMATION handles;
|
||||||
|
PSYSTEM_HANDLE_INFORMATION_EX convertedHandles;
|
||||||
|
ULONG count;
|
||||||
|
ULONG allocatedCount;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
// Enumerate handles using the old info class and convert
|
||||||
|
// the relevant entries to the new format.
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhEnumHandles(&handles)))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
allocatedCount = 100;
|
||||||
|
|
||||||
|
convertedHandles = PhAllocate(
|
||||||
|
FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handles) +
|
||||||
|
sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX) * allocatedCount
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i = 0; i < handles->NumberOfHandles; i++)
|
||||||
|
{
|
||||||
|
if ((HANDLE)handles->Handles[i].UniqueProcessId != ProcessId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (count == allocatedCount)
|
||||||
|
{
|
||||||
|
allocatedCount *= 2;
|
||||||
|
convertedHandles = PhReAllocate(
|
||||||
|
convertedHandles,
|
||||||
|
FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handles) +
|
||||||
|
sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX) * allocatedCount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedHandles->Handles[count].Object = handles->Handles[i].Object;
|
||||||
|
convertedHandles->Handles[count].UniqueProcessId = (ULONG_PTR)handles->Handles[i].UniqueProcessId;
|
||||||
|
convertedHandles->Handles[count].HandleValue = (ULONG_PTR)handles->Handles[i].HandleValue;
|
||||||
|
convertedHandles->Handles[count].GrantedAccess = handles->Handles[i].GrantedAccess;
|
||||||
|
convertedHandles->Handles[count].CreatorBackTraceIndex = handles->Handles[i].CreatorBackTraceIndex;
|
||||||
|
convertedHandles->Handles[count].ObjectTypeIndex = handles->Handles[i].ObjectTypeIndex;
|
||||||
|
convertedHandles->Handles[count].HandleAttributes = (ULONG)handles->Handles[i].HandleAttributes;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedHandles->NumberOfHandles = count;
|
||||||
|
|
||||||
|
PhFree(handles);
|
||||||
|
|
||||||
|
*Handles = convertedHandles;
|
||||||
|
*FilterNeeded = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS PhpCreateHandleItemFunction(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPHP_CREATE_HANDLE_ITEM_CONTEXT context = Parameter;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
handleItem = PhCreateHandleItem(context->Handle);
|
||||||
|
|
||||||
|
PhGetHandleInformationEx(
|
||||||
|
context->Provider->ProcessHandle,
|
||||||
|
handleItem->Handle,
|
||||||
|
context->Handle->ObjectTypeIndex,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&handleItem->TypeName,
|
||||||
|
&handleItem->ObjectName,
|
||||||
|
&handleItem->BestObjectName,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (handleItem->TypeName)
|
||||||
|
{
|
||||||
|
// Add the handle item to the hashtable.
|
||||||
|
PhAcquireQueuedLockExclusive(&context->Provider->HandleHashSetLock);
|
||||||
|
PhpAddHandleItem(context->Provider, handleItem);
|
||||||
|
PhReleaseQueuedLockExclusive(&context->Provider->HandleHashSetLock);
|
||||||
|
|
||||||
|
// Raise the handle added event.
|
||||||
|
PhInvokeCallback(&context->Provider->HandleAddedEvent, handleItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhDereferenceObject(handleItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(context);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID PhHandleProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
)
|
||||||
|
{
|
||||||
|
static PH_INITONCE initOnce = PH_INITONCE_INIT;
|
||||||
|
static ULONG fileObjectTypeIndex = -1;
|
||||||
|
|
||||||
|
PPH_HANDLE_PROVIDER handleProvider = (PPH_HANDLE_PROVIDER)Object;
|
||||||
|
PSYSTEM_HANDLE_INFORMATION_EX handleInfo;
|
||||||
|
BOOLEAN filterNeeded;
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handles;
|
||||||
|
ULONG numberOfHandles;
|
||||||
|
ULONG i;
|
||||||
|
PH_HASHTABLE_ENUM_CONTEXT enumContext;
|
||||||
|
PPH_KEY_VALUE_PAIR handlePair;
|
||||||
|
BOOLEAN useWorkQueue = FALSE;
|
||||||
|
PH_WORK_QUEUE workQueue;
|
||||||
|
|
||||||
|
if (!handleProvider->ProcessHandle)
|
||||||
|
goto UpdateExit;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(handleProvider->RunStatus = PhEnumHandlesGeneric(
|
||||||
|
handleProvider->ProcessId,
|
||||||
|
handleProvider->ProcessHandle,
|
||||||
|
&handleInfo,
|
||||||
|
&filterNeeded
|
||||||
|
)))
|
||||||
|
goto UpdateExit;
|
||||||
|
|
||||||
|
if (!KphIsConnected() && WindowsVersion >= WINDOWS_VISTA)
|
||||||
|
{
|
||||||
|
useWorkQueue = TRUE;
|
||||||
|
PhInitializeWorkQueue(&workQueue, 1, 20, 1000);
|
||||||
|
|
||||||
|
if (PhBeginInitOnce(&initOnce))
|
||||||
|
{
|
||||||
|
UNICODE_STRING fileTypeName;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&fileTypeName, L"File");
|
||||||
|
fileObjectTypeIndex = PhGetObjectTypeNumber(&fileTypeName);
|
||||||
|
PhEndInitOnce(&initOnce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handles = handleInfo->Handles;
|
||||||
|
numberOfHandles = (ULONG)handleInfo->NumberOfHandles;
|
||||||
|
|
||||||
|
// Make a list of the relevant handles.
|
||||||
|
if (filterNeeded)
|
||||||
|
{
|
||||||
|
for (i = 0; i < (ULONG)numberOfHandles; i++)
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = &handles[i];
|
||||||
|
|
||||||
|
if (handle->UniqueProcessId == (ULONG_PTR)handleProvider->ProcessId)
|
||||||
|
{
|
||||||
|
PhAddItemSimpleHashtable(
|
||||||
|
handleProvider->TempListHashtable,
|
||||||
|
(PVOID)handle->HandleValue,
|
||||||
|
handle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < (ULONG)numberOfHandles; i++)
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = &handles[i];
|
||||||
|
|
||||||
|
PhAddItemSimpleHashtable(
|
||||||
|
handleProvider->TempListHashtable,
|
||||||
|
(PVOID)handle->HandleValue,
|
||||||
|
handle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for closed handles.
|
||||||
|
{
|
||||||
|
PPH_LIST handlesToRemove = NULL;
|
||||||
|
PPH_HASH_ENTRY entry;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX *tempHashtableValue;
|
||||||
|
|
||||||
|
for (i = 0; i < handleProvider->HandleHashSetSize; i++)
|
||||||
|
{
|
||||||
|
for (entry = handleProvider->HandleHashSet[i]; entry; entry = entry->Next)
|
||||||
|
{
|
||||||
|
BOOLEAN found = FALSE;
|
||||||
|
|
||||||
|
handleItem = CONTAINING_RECORD(entry, PH_HANDLE_ITEM, HashEntry);
|
||||||
|
|
||||||
|
// Check if the handle still exists.
|
||||||
|
|
||||||
|
tempHashtableValue = (PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX *)PhFindItemSimpleHashtable(
|
||||||
|
handleProvider->TempListHashtable,
|
||||||
|
(PVOID)(handleItem->Handle)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tempHashtableValue)
|
||||||
|
{
|
||||||
|
// Also compare the object pointers to make sure a
|
||||||
|
// different object wasn't re-opened with the same
|
||||||
|
// handle value. This isn't 100% accurate as pool
|
||||||
|
// addresses may be re-used, but it works well.
|
||||||
|
if (handleItem->Object == (*tempHashtableValue)->Object)
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
// Raise the handle removed event.
|
||||||
|
PhInvokeCallback(&handleProvider->HandleRemovedEvent, handleItem);
|
||||||
|
|
||||||
|
if (!handlesToRemove)
|
||||||
|
handlesToRemove = PhCreateList(2);
|
||||||
|
|
||||||
|
PhAddItemList(handlesToRemove, handleItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handlesToRemove)
|
||||||
|
{
|
||||||
|
PhAcquireQueuedLockExclusive(&handleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
for (i = 0; i < handlesToRemove->Count; i++)
|
||||||
|
{
|
||||||
|
PhpRemoveHandleItem(
|
||||||
|
handleProvider,
|
||||||
|
(PPH_HANDLE_ITEM)handlesToRemove->Items[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhReleaseQueuedLockExclusive(&handleProvider->HandleHashSetLock);
|
||||||
|
PhDereferenceObject(handlesToRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for new handles and update existing ones.
|
||||||
|
|
||||||
|
PhBeginEnumHashtable(handleProvider->TempListHashtable, &enumContext);
|
||||||
|
|
||||||
|
while (handlePair = PhNextEnumHashtable(&enumContext))
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = handlePair->Value;
|
||||||
|
PPH_HANDLE_ITEM handleItem;
|
||||||
|
|
||||||
|
handleItem = PhpLookupHandleItem(handleProvider, (HANDLE)handle->HandleValue);
|
||||||
|
|
||||||
|
if (!handleItem)
|
||||||
|
{
|
||||||
|
// When we don't have KPH, query handle information in parallel to take full advantage of the
|
||||||
|
// PhCallWithTimeout functionality.
|
||||||
|
if (useWorkQueue && handle->ObjectTypeIndex == fileObjectTypeIndex)
|
||||||
|
{
|
||||||
|
PPHP_CREATE_HANDLE_ITEM_CONTEXT context;
|
||||||
|
|
||||||
|
context = PhAllocate(sizeof(PHP_CREATE_HANDLE_ITEM_CONTEXT));
|
||||||
|
context->Provider = handleProvider;
|
||||||
|
context->Handle = handle;
|
||||||
|
PhQueueItemWorkQueue(&workQueue, PhpCreateHandleItemFunction, context);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleItem = PhCreateHandleItem(handle);
|
||||||
|
|
||||||
|
PhGetHandleInformationEx(
|
||||||
|
handleProvider->ProcessHandle,
|
||||||
|
handleItem->Handle,
|
||||||
|
handle->ObjectTypeIndex,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&handleItem->TypeName,
|
||||||
|
&handleItem->ObjectName,
|
||||||
|
&handleItem->BestObjectName,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
// We need at least a type name to continue.
|
||||||
|
if (!handleItem->TypeName)
|
||||||
|
{
|
||||||
|
PhDereferenceObject(handleItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhEqualString2(handleItem->TypeName, L"File", TRUE) && KphIsConnected())
|
||||||
|
{
|
||||||
|
KPH_FILE_OBJECT_INFORMATION objectInfo;
|
||||||
|
|
||||||
|
if (NT_SUCCESS(KphQueryInformationObject(
|
||||||
|
handleProvider->ProcessHandle,
|
||||||
|
handleItem->Handle,
|
||||||
|
KphObjectFileObjectInformation,
|
||||||
|
&objectInfo,
|
||||||
|
sizeof(KPH_FILE_OBJECT_INFORMATION),
|
||||||
|
NULL
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
if (objectInfo.SharedRead)
|
||||||
|
handleItem->FileFlags |= PH_HANDLE_FILE_SHARED_READ;
|
||||||
|
if (objectInfo.SharedWrite)
|
||||||
|
handleItem->FileFlags |= PH_HANDLE_FILE_SHARED_WRITE;
|
||||||
|
if (objectInfo.SharedDelete)
|
||||||
|
handleItem->FileFlags |= PH_HANDLE_FILE_SHARED_DELETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the handle item to the hashtable.
|
||||||
|
PhAcquireQueuedLockExclusive(&handleProvider->HandleHashSetLock);
|
||||||
|
PhpAddHandleItem(handleProvider, handleItem);
|
||||||
|
PhReleaseQueuedLockExclusive(&handleProvider->HandleHashSetLock);
|
||||||
|
|
||||||
|
// Raise the handle added event.
|
||||||
|
PhInvokeCallback(&handleProvider->HandleAddedEvent, handleItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOOLEAN modified = FALSE;
|
||||||
|
|
||||||
|
if (handleItem->Attributes != handle->HandleAttributes)
|
||||||
|
{
|
||||||
|
handleItem->Attributes = handle->HandleAttributes;
|
||||||
|
modified = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
{
|
||||||
|
// Raise the handle modified event.
|
||||||
|
PhInvokeCallback(&handleProvider->HandleModifiedEvent, handleItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useWorkQueue)
|
||||||
|
{
|
||||||
|
PhWaitForWorkQueue(&workQueue);
|
||||||
|
PhDeleteWorkQueue(&workQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(handleInfo);
|
||||||
|
|
||||||
|
// Re-create the temporary hashtable if it got too big.
|
||||||
|
if (handleProvider->TempListHashtable->AllocatedEntries > 8192)
|
||||||
|
{
|
||||||
|
PhDereferenceObject(handleProvider->TempListHashtable);
|
||||||
|
handleProvider->TempListHashtable = PhCreateSimpleHashtable(512);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhClearHashtable(handleProvider->TempListHashtable);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateExit:
|
||||||
|
PhInvokeCallback(&handleProvider->UpdatedEvent, NULL);
|
||||||
|
}
|
238
ProcessHacker/hndlstat.c
Normal file
238
ProcessHacker/hndlstat.c
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*
|
||||||
|
* Process Hacker -
|
||||||
|
* handle statistics window
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 wj32
|
||||||
|
*
|
||||||
|
* This file is part of Process Hacker.
|
||||||
|
*
|
||||||
|
* Process Hacker is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Process Hacker is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phapp.h>
|
||||||
|
#include <hndlprv.h>
|
||||||
|
#include <hndlinfo.h>
|
||||||
|
|
||||||
|
typedef struct _HANDLE_STATISTICS_ENTRY
|
||||||
|
{
|
||||||
|
PPH_STRING Name;
|
||||||
|
ULONG Count;
|
||||||
|
} HANDLE_STATISTICS_ENTRY, *PHANDLE_STATISTICS_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _HANDLE_STATISTICS_CONTEXT
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
|
||||||
|
PSYSTEM_HANDLE_INFORMATION_EX Handles;
|
||||||
|
HANDLE_STATISTICS_ENTRY Entries[MAX_OBJECT_TYPE_NUMBER];
|
||||||
|
} HANDLE_STATISTICS_CONTEXT, *PHANDLE_STATISTICS_CONTEXT;
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpHandleStatisticsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhShowHandleStatisticsDialog(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
HANDLE_STATISTICS_CONTEXT context;
|
||||||
|
BOOLEAN filterNeeded;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
context.ProcessId = ProcessId;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status = PhOpenProcess(
|
||||||
|
&context.ProcessHandle,
|
||||||
|
PROCESS_DUP_HANDLE,
|
||||||
|
ProcessId
|
||||||
|
)))
|
||||||
|
{
|
||||||
|
PhShowStatus(ParentWindowHandle, L"Unable to open the process", status, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = PhEnumHandlesGeneric(
|
||||||
|
context.ProcessId,
|
||||||
|
context.ProcessHandle,
|
||||||
|
&context.Handles,
|
||||||
|
&filterNeeded
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
{
|
||||||
|
NtClose(context.ProcessHandle);
|
||||||
|
PhShowStatus(ParentWindowHandle, L"Unable to enumerate process handles", status, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&context.Entries, 0, sizeof(context.Entries));
|
||||||
|
|
||||||
|
DialogBoxParam(
|
||||||
|
PhInstanceHandle,
|
||||||
|
MAKEINTRESOURCE(IDD_HANDLESTATS),
|
||||||
|
ParentWindowHandle,
|
||||||
|
PhpHandleStatisticsDlgProc,
|
||||||
|
(LPARAM)&context
|
||||||
|
);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_OBJECT_TYPE_NUMBER; i++)
|
||||||
|
{
|
||||||
|
if (context.Entries[i].Name)
|
||||||
|
PhDereferenceObject(context.Entries[i].Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhFree(context.Handles);
|
||||||
|
NtClose(context.ProcessHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT NTAPI PhpTypeCountCompareFunction(
|
||||||
|
_In_ PVOID Item1,
|
||||||
|
_In_ PVOID Item2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PHANDLE_STATISTICS_ENTRY entry1 = Item1;
|
||||||
|
PHANDLE_STATISTICS_ENTRY entry2 = Item2;
|
||||||
|
|
||||||
|
return uintcmp(entry1->Count, entry2->Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpHandleStatisticsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
PHANDLE_STATISTICS_CONTEXT context = (PHANDLE_STATISTICS_CONTEXT)lParam;
|
||||||
|
HANDLE processId;
|
||||||
|
ULONG_PTR i;
|
||||||
|
HWND lvHandle;
|
||||||
|
|
||||||
|
processId = context->ProcessId;
|
||||||
|
|
||||||
|
for (i = 0; i < context->Handles->NumberOfHandles; i++)
|
||||||
|
{
|
||||||
|
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo;
|
||||||
|
PHANDLE_STATISTICS_ENTRY entry;
|
||||||
|
PPH_STRING typeName;
|
||||||
|
|
||||||
|
handleInfo = &context->Handles->Handles[i];
|
||||||
|
|
||||||
|
if (handleInfo->UniqueProcessId != (ULONG_PTR)processId)
|
||||||
|
continue;
|
||||||
|
if (handleInfo->ObjectTypeIndex >= MAX_OBJECT_TYPE_NUMBER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
entry = &context->Entries[handleInfo->ObjectTypeIndex];
|
||||||
|
|
||||||
|
if (!entry->Name)
|
||||||
|
{
|
||||||
|
typeName = NULL;
|
||||||
|
PhGetHandleInformation(
|
||||||
|
context->ProcessHandle,
|
||||||
|
(HANDLE)handleInfo->HandleValue,
|
||||||
|
handleInfo->ObjectTypeIndex,
|
||||||
|
NULL,
|
||||||
|
&typeName,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
entry->Name = typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->Count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhCenterWindow(hwndDlg, GetParent(hwndDlg));
|
||||||
|
lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
|
||||||
|
PhSetListViewStyle(lvHandle, FALSE, TRUE);
|
||||||
|
PhSetControlTheme(lvHandle, L"explorer");
|
||||||
|
PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 140, L"Type");
|
||||||
|
PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Count");
|
||||||
|
|
||||||
|
PhSetExtendedListView(lvHandle);
|
||||||
|
ExtendedListView_SetCompareFunction(lvHandle, 1, PhpTypeCountCompareFunction);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_OBJECT_TYPE_NUMBER; i++)
|
||||||
|
{
|
||||||
|
PHANDLE_STATISTICS_ENTRY entry;
|
||||||
|
PPH_STRING unknownType;
|
||||||
|
PPH_STRING countString;
|
||||||
|
INT lvItemIndex;
|
||||||
|
|
||||||
|
entry = &context->Entries[i];
|
||||||
|
|
||||||
|
if (entry->Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unknownType = NULL;
|
||||||
|
|
||||||
|
if (!entry->Name)
|
||||||
|
unknownType = PhFormatString(L"(unknown: %u)", i);
|
||||||
|
|
||||||
|
countString = PhFormatUInt64(entry->Count, TRUE);
|
||||||
|
|
||||||
|
lvItemIndex = PhAddListViewItem(
|
||||||
|
lvHandle,
|
||||||
|
MAXINT,
|
||||||
|
entry->Name ? entry->Name->Buffer : unknownType->Buffer,
|
||||||
|
entry
|
||||||
|
);
|
||||||
|
PhSetListViewSubItem(lvHandle, lvItemIndex, 1, countString->Buffer);
|
||||||
|
|
||||||
|
PhDereferenceObject(countString);
|
||||||
|
|
||||||
|
if (unknownType)
|
||||||
|
PhDereferenceObject(unknownType);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedListView_SortItems(lvHandle);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDCANCEL:
|
||||||
|
case IDOK:
|
||||||
|
EndDialog(hwndDlg, IDOK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
{
|
||||||
|
PhHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
368
ProcessHacker/include/actions.h
Normal file
368
ProcessHacker/include/actions.h
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
#ifndef PH_ACTIONS_H
|
||||||
|
#define PH_ACTIONS_H
|
||||||
|
|
||||||
|
typedef enum _PH_ACTION_ELEVATION_LEVEL
|
||||||
|
{
|
||||||
|
NeverElevateAction = 0,
|
||||||
|
PromptElevateAction = 1,
|
||||||
|
AlwaysElevateAction = 2
|
||||||
|
} PH_ACTION_ELEVATION_LEVEL;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _PH_PHSVC_MODE
|
||||||
|
{
|
||||||
|
ElevatedPhSvcMode,
|
||||||
|
Wow64PhSvcMode
|
||||||
|
} PH_PHSVC_MODE;
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiConnectToPhSvc(
|
||||||
|
_In_opt_ HWND hWnd,
|
||||||
|
_In_ BOOLEAN ConnectOnly
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiConnectToPhSvcEx(
|
||||||
|
_In_opt_ HWND hWnd,
|
||||||
|
_In_ PH_PHSVC_MODE Mode,
|
||||||
|
_In_ BOOLEAN ConnectOnly
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhUiDisconnectFromPhSvc(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiLockComputer(
|
||||||
|
_In_ HWND hWnd
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiLogoffComputer(
|
||||||
|
_In_ HWND hWnd
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSleepComputer(
|
||||||
|
_In_ HWND hWnd
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiHibernateComputer(
|
||||||
|
_In_ HWND hWnd
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiRestartComputer(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiShutdownComputer(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiConnectSession(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ ULONG SessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiDisconnectSession(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ ULONG SessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiLogoffSession(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ ULONG SessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiTerminateProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiTerminateTreeProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSuspendProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiResumeProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiRestartProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiDebugProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiReduceWorkingSetProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetVirtualizationProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process,
|
||||||
|
_In_ BOOLEAN Enable
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiDetachFromDebuggerProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiInjectDllProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetIoPriorityProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses,
|
||||||
|
_In_ IO_PRIORITY_HINT IoPriority
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetPagePriorityProcess(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM Process,
|
||||||
|
_In_ ULONG PagePriority
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetPriorityProcesses(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses,
|
||||||
|
_In_ ULONG PriorityClass
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiStartService(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_SERVICE_ITEM Service
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiContinueService(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_SERVICE_ITEM Service
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiPauseService(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_SERVICE_ITEM Service
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiStopService(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_SERVICE_ITEM Service
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiDeleteService(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_SERVICE_ITEM Service
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiCloseConnections(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_NETWORK_ITEM *Connections,
|
||||||
|
_In_ ULONG NumberOfConnections
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiTerminateThreads(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM *Threads,
|
||||||
|
_In_ ULONG NumberOfThreads
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSuspendThreads(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM *Threads,
|
||||||
|
_In_ ULONG NumberOfThreads
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiResumeThreads(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM *Threads,
|
||||||
|
_In_ ULONG NumberOfThreads
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetPriorityThread(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM Thread,
|
||||||
|
_In_ LONG Increment
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetIoPriorityThread(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM Thread,
|
||||||
|
_In_ IO_PRIORITY_HINT IoPriority
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetPagePriorityThread(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_THREAD_ITEM Thread,
|
||||||
|
_In_ ULONG PagePriority
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiUnloadModule(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PPH_MODULE_ITEM Module
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiFreeMemory(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PPH_MEMORY_ITEM MemoryItem,
|
||||||
|
_In_ BOOLEAN Free
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiCloseHandles(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PPH_HANDLE_ITEM *Handles,
|
||||||
|
_In_ ULONG NumberOfHandles,
|
||||||
|
_In_ BOOLEAN Warn
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhUiSetAttributesHandle(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PPH_HANDLE_ITEM Handle,
|
||||||
|
_In_ ULONG Attributes
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
118
ProcessHacker/include/colmgr.h
Normal file
118
ProcessHacker/include/colmgr.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#ifndef PH_COLMGR_H
|
||||||
|
#define PH_COLMGR_H
|
||||||
|
|
||||||
|
#define PH_CM_ORDER_LIMIT 160
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef LONG (NTAPI *PPH_CM_POST_SORT_FUNCTION)(
|
||||||
|
_In_ LONG Result,
|
||||||
|
_In_ PVOID Node1,
|
||||||
|
_In_ PVOID Node2,
|
||||||
|
_In_ PH_SORT_ORDER SortOrder
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_CM_MANAGER
|
||||||
|
{
|
||||||
|
HWND Handle;
|
||||||
|
ULONG MinId;
|
||||||
|
ULONG NextId;
|
||||||
|
PPH_CM_POST_SORT_FUNCTION PostSortFunction;
|
||||||
|
LIST_ENTRY ColumnListHead;
|
||||||
|
PPH_LIST NotifyList;
|
||||||
|
} PH_CM_MANAGER, *PPH_CM_MANAGER;
|
||||||
|
|
||||||
|
typedef struct _PH_CM_COLUMN
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG Id;
|
||||||
|
struct _PH_PLUGIN *Plugin;
|
||||||
|
ULONG SubId;
|
||||||
|
PVOID Context;
|
||||||
|
PVOID SortFunction;
|
||||||
|
} PH_CM_COLUMN, *PPH_CM_COLUMN;
|
||||||
|
|
||||||
|
VOID PhCmInitializeManager(
|
||||||
|
_Out_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ HWND Handle,
|
||||||
|
_In_ ULONG MinId,
|
||||||
|
_In_ PPH_CM_POST_SORT_FUNCTION PostSortFunction
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhCmDeleteManager(
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_CM_COLUMN PhCmCreateColumn(
|
||||||
|
_Inout_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ PPH_TREENEW_COLUMN Column,
|
||||||
|
_In_ struct _PH_PLUGIN *Plugin,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_ PVOID SortFunction
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_CM_COLUMN PhCmFindColumn(
|
||||||
|
_In_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ PPH_STRINGREF PluginName,
|
||||||
|
_In_ ULONG SubId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhCmSetNotifyPlugin(
|
||||||
|
_In_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ struct _PH_PLUGIN *Plugin
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhCmForwardMessage(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ PH_TREENEW_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2,
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhCmForwardSort(
|
||||||
|
_In_ PPH_TREENEW_NODE *Nodes,
|
||||||
|
_In_ ULONG NumberOfNodes,
|
||||||
|
_In_ ULONG SortColumn,
|
||||||
|
_In_ PH_SORT_ORDER SortOrder,
|
||||||
|
_In_ PPH_CM_MANAGER Manager
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhCmLoadSettings(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_ PPH_STRINGREF Settings
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#define PH_CM_COLUMN_WIDTHS_ONLY 0x1
|
||||||
|
|
||||||
|
BOOLEAN PhCmLoadSettingsEx(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_opt_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_STRINGREF Settings,
|
||||||
|
_In_opt_ PPH_STRINGREF SortSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhCmSaveSettings(
|
||||||
|
_In_ HWND TreeNewHandle
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_STRING PhCmSaveSettingsEx(
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_In_opt_ PPH_CM_MANAGER Manager,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_Out_opt_ PPH_STRING *SortSettings
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
51
ProcessHacker/include/extmgr.h
Normal file
51
ProcessHacker/include/extmgr.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef PH_EXTMGR_H
|
||||||
|
#define PH_EXTMGR_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _PH_EM_OBJECT_TYPE
|
||||||
|
{
|
||||||
|
EmProcessItemType,
|
||||||
|
EmProcessNodeType,
|
||||||
|
EmServiceItemType,
|
||||||
|
EmServiceNodeType,
|
||||||
|
EmNetworkItemType,
|
||||||
|
EmNetworkNodeType,
|
||||||
|
EmThreadItemType,
|
||||||
|
EmThreadNodeType,
|
||||||
|
EmModuleItemType,
|
||||||
|
EmModuleNodeType,
|
||||||
|
EmHandleItemType,
|
||||||
|
EmHandleNodeType,
|
||||||
|
EmThreadsContextType,
|
||||||
|
EmModulesContextType,
|
||||||
|
EmHandlesContextType,
|
||||||
|
EmThreadProviderType,
|
||||||
|
EmModuleProviderType,
|
||||||
|
EmHandleProviderType,
|
||||||
|
EmMemoryNodeType,
|
||||||
|
EmMemoryContextType,
|
||||||
|
EmMaximumObjectType
|
||||||
|
} PH_EM_OBJECT_TYPE;
|
||||||
|
|
||||||
|
typedef enum _PH_EM_OBJECT_OPERATION
|
||||||
|
{
|
||||||
|
EmObjectCreate,
|
||||||
|
EmObjectDelete,
|
||||||
|
EmMaximumObjectOperation
|
||||||
|
} PH_EM_OBJECT_OPERATION;
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_EM_OBJECT_CALLBACK)(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ PVOID Extension
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_EM_APP_CONTEXT
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
PH_STRINGREF AppName;
|
||||||
|
struct _PH_EM_OBJECT_EXTENSION *Extensions[EmMaximumObjectType];
|
||||||
|
} PH_EM_APP_CONTEXT, *PPH_EM_APP_CONTEXT;
|
||||||
|
|
||||||
|
#endif
|
61
ProcessHacker/include/extmgri.h
Normal file
61
ProcessHacker/include/extmgri.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef PH_EXTMGRI_H
|
||||||
|
#define PH_EXTMGRI_H
|
||||||
|
|
||||||
|
#include <extmgr.h>
|
||||||
|
|
||||||
|
typedef struct _PH_EM_OBJECT_TYPE_STATE
|
||||||
|
{
|
||||||
|
SIZE_T InitialSize;
|
||||||
|
SIZE_T ExtensionOffset;
|
||||||
|
LIST_ENTRY ExtensionListHead;
|
||||||
|
} PH_EM_OBJECT_TYPE_STATE, *PPH_EM_OBJECT_TYPE_STATE;
|
||||||
|
|
||||||
|
typedef struct _PH_EM_OBJECT_EXTENSION
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
SIZE_T ExtensionSize;
|
||||||
|
SIZE_T ExtensionOffset;
|
||||||
|
PPH_EM_OBJECT_CALLBACK Callbacks[EmMaximumObjectOperation];
|
||||||
|
} PH_EM_OBJECT_EXTENSION, *PPH_EM_OBJECT_EXTENSION;
|
||||||
|
|
||||||
|
VOID PhEmInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhEmInitializeAppContext(
|
||||||
|
_Out_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PPH_STRINGREF AppName
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhEmSetObjectExtension(
|
||||||
|
_Inout_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ SIZE_T ExtensionSize,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK CreateCallback,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK DeleteCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID PhEmGetObjectExtension(
|
||||||
|
_In_ PPH_EM_APP_CONTEXT AppContext,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
SIZE_T PhEmGetObjectSize(
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ SIZE_T InitialSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhEmCallObjectOperation(
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ PH_EM_OBJECT_OPERATION Operation
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhEmParseCompoundId(
|
||||||
|
_In_ PPH_STRINGREF CompoundId,
|
||||||
|
_Out_ PPH_STRINGREF AppName,
|
||||||
|
_Out_ PULONG SubId
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
69
ProcessHacker/include/heapstruct.h
Normal file
69
ProcessHacker/include/heapstruct.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#ifndef PH_HEAPSTRUCT_H
|
||||||
|
#define PH_HEAPSTRUCT_H
|
||||||
|
|
||||||
|
// Not the actual structure, but has the same size.
|
||||||
|
typedef struct _HEAP_ENTRY
|
||||||
|
{
|
||||||
|
PVOID Data1;
|
||||||
|
PVOID Data2;
|
||||||
|
} HEAP_ENTRY, *PHEAP_ENTRY;
|
||||||
|
|
||||||
|
#define HEAP_SEGMENT_SIGNATURE 0xffeeffee
|
||||||
|
|
||||||
|
// First few fields of HEAP_SEGMENT, VISTA and above
|
||||||
|
typedef struct _HEAP_SEGMENT
|
||||||
|
{
|
||||||
|
HEAP_ENTRY HeapEntry;
|
||||||
|
ULONG SegmentSignature;
|
||||||
|
ULONG SegmentFlags;
|
||||||
|
LIST_ENTRY SegmentListEntry;
|
||||||
|
struct _HEAP *Heap;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
} HEAP_SEGMENT, *PHEAP_SEGMENT;
|
||||||
|
|
||||||
|
// First few fields of HEAP_SEGMENT, WS03 and below
|
||||||
|
typedef struct _HEAP_SEGMENT_OLD
|
||||||
|
{
|
||||||
|
HEAP_ENTRY Entry;
|
||||||
|
ULONG Signature;
|
||||||
|
ULONG Flags;
|
||||||
|
struct _HEAP *Heap;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
} HEAP_SEGMENT_OLD, *PHEAP_SEGMENT_OLD;
|
||||||
|
|
||||||
|
// 32-bit versions
|
||||||
|
|
||||||
|
typedef struct _HEAP_ENTRY32
|
||||||
|
{
|
||||||
|
WOW64_POINTER(PVOID) Data1;
|
||||||
|
WOW64_POINTER(PVOID) Data2;
|
||||||
|
} HEAP_ENTRY32, *PHEAP_ENTRY32;
|
||||||
|
|
||||||
|
typedef struct _HEAP_SEGMENT32
|
||||||
|
{
|
||||||
|
HEAP_ENTRY32 HeapEntry;
|
||||||
|
ULONG SegmentSignature;
|
||||||
|
ULONG SegmentFlags;
|
||||||
|
LIST_ENTRY32 SegmentListEntry;
|
||||||
|
WOW64_POINTER(struct _HEAP *) Heap;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
} HEAP_SEGMENT32, *PHEAP_SEGMENT32;
|
||||||
|
|
||||||
|
typedef struct _HEAP_SEGMENT_OLD32
|
||||||
|
{
|
||||||
|
HEAP_ENTRY32 Entry;
|
||||||
|
ULONG Signature;
|
||||||
|
ULONG Flags;
|
||||||
|
WOW64_POINTER(struct _HEAP *) Heap;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
} HEAP_SEGMENT_OLD32, *PHEAP_SEGMENT_OLD32;
|
||||||
|
|
||||||
|
#define HEAP_SEGMENT_MAX_SIZE \
|
||||||
|
(max(sizeof(HEAP_SEGMENT), max(sizeof(HEAP_SEGMENT_OLD), \
|
||||||
|
max(sizeof(HEAP_SEGMENT32), sizeof(HEAP_SEGMENT_OLD32)))))
|
||||||
|
|
||||||
|
#endif
|
75
ProcessHacker/include/hidnproc.h
Normal file
75
ProcessHacker/include/hidnproc.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef PH_HIDNPROC_H
|
||||||
|
#define PH_HIDNPROC_H
|
||||||
|
|
||||||
|
typedef enum _PH_HIDDEN_PROCESS_METHOD
|
||||||
|
{
|
||||||
|
BruteForceScanMethod,
|
||||||
|
CsrHandlesScanMethod
|
||||||
|
} PH_HIDDEN_PROCESS_METHOD;
|
||||||
|
|
||||||
|
typedef enum _PH_HIDDEN_PROCESS_TYPE
|
||||||
|
{
|
||||||
|
UnknownProcess,
|
||||||
|
NormalProcess,
|
||||||
|
HiddenProcess,
|
||||||
|
TerminatedProcess
|
||||||
|
} PH_HIDDEN_PROCESS_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PH_HIDDEN_PROCESS_ENTRY
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_STRING FileName;
|
||||||
|
PH_HIDDEN_PROCESS_TYPE Type;
|
||||||
|
} PH_HIDDEN_PROCESS_ENTRY, *PPH_HIDDEN_PROCESS_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _PH_CSR_HANDLE_INFO
|
||||||
|
{
|
||||||
|
HANDLE CsrProcessHandle;
|
||||||
|
HANDLE Handle;
|
||||||
|
BOOLEAN IsThreadHandle;
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
} PH_CSR_HANDLE_INFO, *PPH_CSR_HANDLE_INFO;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_ENUM_HIDDEN_PROCESSES_CALLBACK)(
|
||||||
|
_In_ PPH_HIDDEN_PROCESS_ENTRY Process,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhEnumHiddenProcesses(
|
||||||
|
_In_ PH_HIDDEN_PROCESS_METHOD Method,
|
||||||
|
_In_ PPH_ENUM_HIDDEN_PROCESSES_CALLBACK Callback,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_ENUM_CSR_PROCESS_HANDLES_CALLBACK)(
|
||||||
|
_In_ PPH_CSR_HANDLE_INFO Handle,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhEnumCsrProcessHandles(
|
||||||
|
_In_ PPH_ENUM_CSR_PROCESS_HANDLES_CALLBACK Callback,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhOpenProcessByCsrHandle(
|
||||||
|
_Out_ PHANDLE ProcessHandle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_ PPH_CSR_HANDLE_INFO Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhOpenProcessByCsrHandles(
|
||||||
|
_Out_ PHANDLE ProcessHandle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
119
ProcessHacker/include/hndllist.h
Normal file
119
ProcessHacker/include/hndllist.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#ifndef PH_HNDLLIST_H
|
||||||
|
#define PH_HNDLLIST_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
#include <colmgr.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
#define PHHNTLC_TYPE 0
|
||||||
|
#define PHHNTLC_NAME 1
|
||||||
|
#define PHHNTLC_HANDLE 2
|
||||||
|
|
||||||
|
#define PHHNTLC_OBJECTADDRESS 3
|
||||||
|
#define PHHNTLC_ATTRIBUTES 4
|
||||||
|
#define PHHNTLC_GRANTEDACCESS 5
|
||||||
|
#define PHHNTLC_GRANTEDACCESSSYMBOLIC 6
|
||||||
|
#define PHHNTLC_ORIGINALNAME 7
|
||||||
|
#define PHHNTLC_FILESHAREACCESS 8
|
||||||
|
|
||||||
|
#define PHHNTLC_MAXIMUM 9
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_HANDLE_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
PH_SH_STATE ShState;
|
||||||
|
|
||||||
|
HANDLE Handle;
|
||||||
|
PPH_HANDLE_ITEM HandleItem;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHHNTLC_MAXIMUM];
|
||||||
|
|
||||||
|
PPH_STRING GrantedAccessSymbolicText;
|
||||||
|
WCHAR FileShareAccessText[4];
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_HANDLE_NODE, *PPH_HANDLE_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_HANDLE_LIST_CONTEXT
|
||||||
|
{
|
||||||
|
HWND ParentWindowHandle;
|
||||||
|
HWND TreeNewHandle;
|
||||||
|
ULONG TreeNewSortColumn;
|
||||||
|
PH_SORT_ORDER TreeNewSortOrder;
|
||||||
|
PH_CM_MANAGER Cm;
|
||||||
|
BOOLEAN HideUnnamedHandles;
|
||||||
|
|
||||||
|
PPH_HASHTABLE NodeHashtable;
|
||||||
|
PPH_LIST NodeList;
|
||||||
|
|
||||||
|
BOOLEAN EnableStateHighlighting;
|
||||||
|
PPH_POINTER_LIST NodeStateList;
|
||||||
|
} PH_HANDLE_LIST_CONTEXT, *PPH_HANDLE_LIST_CONTEXT;
|
||||||
|
|
||||||
|
VOID PhInitializeHandleList(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_Out_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeleteHandleList(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSetOptionsHandleList(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ BOOLEAN HideUnnamedHandles
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_NODE PhAddHandleNode(
|
||||||
|
_Inout_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_ITEM HandleItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_NODE PhFindHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhRemoveHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhUpdateHandleNode(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_HANDLE_NODE HandleNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhTickHandleNodes(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhGetSelectedHandleItem(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhGetSelectedHandleItems(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context,
|
||||||
|
_Out_ PPH_HANDLE_ITEM **Handles,
|
||||||
|
_Out_ PULONG NumberOfHandles
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeselectAllHandleNodes(
|
||||||
|
_In_ PPH_HANDLE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
33
ProcessHacker/include/hndlmenu.h
Normal file
33
ProcessHacker/include/hndlmenu.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PH_HNDLMENU_H
|
||||||
|
#define PH_HNDLMENU_H
|
||||||
|
|
||||||
|
typedef struct _PH_HANDLE_ITEM_INFO
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE Handle;
|
||||||
|
PPH_STRING TypeName;
|
||||||
|
PPH_STRING BestObjectName;
|
||||||
|
} PH_HANDLE_ITEM_INFO, *PPH_HANDLE_ITEM_INFO;
|
||||||
|
|
||||||
|
#define PhaAppendCtrlEnter(Text, Enable) ((Enable) ? PhaConcatStrings2((Text), L"\tCtrl+Enter")->Buffer : (Text))
|
||||||
|
|
||||||
|
VOID PhInsertHandleObjectPropertiesEMenuItems(
|
||||||
|
_In_ struct _PH_EMENU_ITEM *Menu,
|
||||||
|
_In_ ULONG InsertBeforeId,
|
||||||
|
_In_ BOOLEAN EnableShortcut,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
);
|
||||||
|
|
||||||
|
#define PH_MAX_SECTION_EDIT_SIZE (32 * 1024 * 1024) // 32 MB
|
||||||
|
|
||||||
|
VOID PhShowHandleObjectProperties1(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhShowHandleObjectProperties2(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ PPH_HANDLE_ITEM_INFO Info
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
84
ProcessHacker/include/hndlprv.h
Normal file
84
ProcessHacker/include/hndlprv.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef PH_HNDLPRV_H
|
||||||
|
#define PH_HNDLPRV_H
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhHandleProviderType;
|
||||||
|
extern PPH_OBJECT_TYPE PhHandleItemType;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
#define PH_HANDLE_FILE_SHARED_READ 0x1
|
||||||
|
#define PH_HANDLE_FILE_SHARED_WRITE 0x2
|
||||||
|
#define PH_HANDLE_FILE_SHARED_DELETE 0x4
|
||||||
|
#define PH_HANDLE_FILE_SHARED_MASK 0x7
|
||||||
|
|
||||||
|
typedef struct _PH_HANDLE_ITEM
|
||||||
|
{
|
||||||
|
PH_HASH_ENTRY HashEntry;
|
||||||
|
|
||||||
|
HANDLE Handle;
|
||||||
|
PVOID Object;
|
||||||
|
ULONG Attributes;
|
||||||
|
ACCESS_MASK GrantedAccess;
|
||||||
|
ULONG FileFlags;
|
||||||
|
|
||||||
|
PPH_STRING TypeName;
|
||||||
|
PPH_STRING ObjectName;
|
||||||
|
PPH_STRING BestObjectName;
|
||||||
|
|
||||||
|
WCHAR HandleString[PH_PTR_STR_LEN_1];
|
||||||
|
WCHAR ObjectString[PH_PTR_STR_LEN_1];
|
||||||
|
WCHAR GrantedAccessString[PH_PTR_STR_LEN_1];
|
||||||
|
} PH_HANDLE_ITEM, *PPH_HANDLE_ITEM;
|
||||||
|
|
||||||
|
typedef struct _PH_HANDLE_PROVIDER
|
||||||
|
{
|
||||||
|
PPH_HASH_ENTRY *HandleHashSet;
|
||||||
|
ULONG HandleHashSetSize;
|
||||||
|
ULONG HandleHashSetCount;
|
||||||
|
PH_QUEUED_LOCK HandleHashSetLock;
|
||||||
|
|
||||||
|
PH_CALLBACK HandleAddedEvent;
|
||||||
|
PH_CALLBACK HandleModifiedEvent;
|
||||||
|
PH_CALLBACK HandleRemovedEvent;
|
||||||
|
PH_CALLBACK UpdatedEvent;
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
|
||||||
|
PPH_HASHTABLE TempListHashtable;
|
||||||
|
NTSTATUS RunStatus;
|
||||||
|
} PH_HANDLE_PROVIDER, *PPH_HANDLE_PROVIDER;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhHandleProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_PROVIDER PhCreateHandleProvider(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhCreateHandleItem(
|
||||||
|
_In_opt_ PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_HANDLE_ITEM PhReferenceHandleItem(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider,
|
||||||
|
_In_ HANDLE Handle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDereferenceAllHandleItems(
|
||||||
|
_In_ PPH_HANDLE_PROVIDER HandleProvider
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhEnumHandlesGeneric(
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_Out_ PSYSTEM_HANDLE_INFORMATION_EX *Handles,
|
||||||
|
_Out_ PBOOLEAN FilterNeeded
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhHandleProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
450
ProcessHacker/include/mainwndp.h
Normal file
450
ProcessHacker/include/mainwndp.h
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
#ifndef PH_MAINWNDP_H
|
||||||
|
#define PH_MAINWNDP_H
|
||||||
|
|
||||||
|
#define PH_FLUSH_PROCESS_QUERY_DATA_INTERVAL_1 250
|
||||||
|
#define PH_FLUSH_PROCESS_QUERY_DATA_INTERVAL_2 750
|
||||||
|
#define PH_FLUSH_PROCESS_QUERY_DATA_INTERVAL_LONG_TERM 1000
|
||||||
|
|
||||||
|
#define TIMER_FLUSH_PROCESS_QUERY_DATA 1
|
||||||
|
#define TIMER_ICON_CLICK_ACTIVATE 2
|
||||||
|
#define TIMER_ICON_RESTORE_HOVER 3
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhMwpWndProc(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
|
||||||
|
BOOLEAN PhMwpInitializeWindowClass(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeProviders(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpApplyUpdateInterval(
|
||||||
|
_In_ ULONG Interval
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeControls(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhMwpDelayedLoadFunction(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhMwpFindDbghelpPath(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Event handlers
|
||||||
|
|
||||||
|
VOID PhMwpOnDestroy(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnEndSession(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnSettingChange(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnCommand(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnShowWindow(
|
||||||
|
_In_ BOOLEAN Showing,
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpOnSysCommand(
|
||||||
|
_In_ ULONG Type,
|
||||||
|
_In_ LONG CursorScreenX,
|
||||||
|
_In_ LONG CursorScreenY
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnMenuCommand(
|
||||||
|
_In_ ULONG Index,
|
||||||
|
_In_ HMENU Menu
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnInitMenuPopup(
|
||||||
|
_In_ HMENU Menu,
|
||||||
|
_In_ ULONG Index,
|
||||||
|
_In_ BOOLEAN IsWindowMenu
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnSize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnSizing(
|
||||||
|
_In_ ULONG Edge,
|
||||||
|
_In_ PRECT DragRectangle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnSetFocus(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnTimer(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpOnNotify(
|
||||||
|
_In_ NMHDR *Header,
|
||||||
|
_Out_ LRESULT *Result
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnWtsSessionChange(
|
||||||
|
_In_ ULONG Reason,
|
||||||
|
_In_ ULONG SessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG_PTR PhMwpOnUserMessage(
|
||||||
|
_In_ ULONG Message,
|
||||||
|
_In_ ULONG_PTR WParam,
|
||||||
|
_In_ ULONG_PTR LParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpProcessAddedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpProcessModifiedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpProcessRemovedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpProcessesUpdatedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpServiceAddedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpServiceModifiedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpServiceRemovedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpServicesUpdatedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpNetworkItemAddedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpNetworkItemModifiedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpNetworkItemRemovedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMwpNetworkItemsUpdatedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
|
||||||
|
VOID PhMwpLoadSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSaveSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSaveWindowState(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Misc.
|
||||||
|
|
||||||
|
VOID PhMwpSymInitHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpUpdateLayoutPadding(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpApplyLayoutPadding(
|
||||||
|
_Inout_ PRECT Rect,
|
||||||
|
_In_ PRECT Padding
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpLayout(
|
||||||
|
_Inout_ HDWP *DeferHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSetCheckOpacityMenu(
|
||||||
|
_In_ BOOLEAN AssumeAllUnchecked,
|
||||||
|
_In_ ULONG Opacity
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSetupComputerMenu(
|
||||||
|
_In_ PPH_EMENU_ITEM Root
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpExecuteComputerCommand(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpActivateWindow(
|
||||||
|
_In_ BOOLEAN Toggle
|
||||||
|
);
|
||||||
|
|
||||||
|
// Main menu
|
||||||
|
|
||||||
|
VOID PhMwpInitializeMainMenu(
|
||||||
|
_In_ HMENU Menu
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpDispatchMenuCommand(
|
||||||
|
_In_ HMENU MenuHandle,
|
||||||
|
_In_ ULONG ItemIndex,
|
||||||
|
_In_ ULONG ItemId,
|
||||||
|
_In_ ULONG_PTR ItemData
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG_PTR PhMwpLegacyAddPluginMenuItem(
|
||||||
|
_In_ PPH_ADDMENUITEM AddMenuItem
|
||||||
|
);
|
||||||
|
|
||||||
|
HBITMAP PhMwpGetShieldBitmap(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeSubMenu(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ ULONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_EMENU_ITEM PhMwpFindTrayIconsMenuItem(
|
||||||
|
_In_ PPH_EMENU Menu
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeSectionMenuItems(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ ULONG StartIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tab control
|
||||||
|
|
||||||
|
VOID PhMwpLayoutTabControl(
|
||||||
|
_Inout_ HDWP *DeferHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpNotifyTabControl(
|
||||||
|
_In_ NMHDR *Header
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSelectionChangedTabControl(
|
||||||
|
_In_ ULONG OldIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_ADDITIONAL_TAB_PAGE PhMwpAddTabPage(
|
||||||
|
_In_ PPH_ADDITIONAL_TAB_PAGE TabPage
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSelectTabPage(
|
||||||
|
_In_ ULONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
INT PhMwpFindTabPageIndex(
|
||||||
|
_In_ PWSTR Text
|
||||||
|
);
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
|
||||||
|
VOID PhMwpAddIconProcesses(
|
||||||
|
_In_ PPH_EMENU_ITEM Menu,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpShowIconContextMenu(
|
||||||
|
_In_ POINT Location
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpClearLastNotificationDetails(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpPluginNotifyEvent(
|
||||||
|
_In_ ULONG Type,
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
// Processes
|
||||||
|
|
||||||
|
VOID PhMwpShowProcessProperties(
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpCurrentUserProcessTreeFilter(
|
||||||
|
_In_ PPH_TREENEW_NODE Node,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpSignedProcessTreeFilter(
|
||||||
|
_In_ PPH_TREENEW_NODE Node,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpExecuteProcessPriorityCommand(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpExecuteProcessIoPriorityCommand(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpSetProcessMenuPriorityChecks(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ BOOLEAN SetPriority,
|
||||||
|
_In_ BOOLEAN SetIoPriority,
|
||||||
|
_In_ BOOLEAN SetPagePriority
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeProcessMenu(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ PPH_PROCESS_ITEM *Processes,
|
||||||
|
_In_ ULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnProcessAdded(
|
||||||
|
_In_ _Assume_refs_(1) PPH_PROCESS_ITEM ProcessItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnProcessModified(
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnProcessRemoved(
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnProcessesUpdated(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Services
|
||||||
|
|
||||||
|
VOID PhMwpNeedServiceTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpDriverServiceTreeFilter(
|
||||||
|
_In_ PPH_TREENEW_NODE Node,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeServiceMenu(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ PPH_SERVICE_ITEM *Services,
|
||||||
|
_In_ ULONG NumberOfServices
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnServiceAdded(
|
||||||
|
_In_ _Assume_refs_(1) PPH_SERVICE_ITEM ServiceItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnServiceModified(
|
||||||
|
_In_ struct _PH_SERVICE_MODIFIED_DATA *ServiceModifiedData
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnServiceRemoved(
|
||||||
|
_In_ PPH_SERVICE_ITEM ServiceItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnServicesUpdated(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
|
||||||
|
VOID PhMwpNeedNetworkTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpCurrentUserNetworkTreeFilter(
|
||||||
|
_In_ PPH_TREENEW_NODE Node,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMwpSignedNetworkTreeFilter(
|
||||||
|
_In_ PPH_TREENEW_NODE Node,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpInitializeNetworkMenu(
|
||||||
|
_In_ PPH_EMENU Menu,
|
||||||
|
_In_ PPH_NETWORK_ITEM *NetworkItems,
|
||||||
|
_In_ ULONG NumberOfNetworkItems
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnNetworkItemAdded(
|
||||||
|
_In_ ULONG RunId,
|
||||||
|
_In_ _Assume_refs_(1) PPH_NETWORK_ITEM NetworkItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnNetworkItemModified(
|
||||||
|
_In_ PPH_NETWORK_ITEM NetworkItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnNetworkItemRemoved(
|
||||||
|
_In_ PPH_NETWORK_ITEM NetworkItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMwpOnNetworkItemsUpdated(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Users
|
||||||
|
|
||||||
|
VOID PhMwpUpdateUsersMenu(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
116
ProcessHacker/include/memlist.h
Normal file
116
ProcessHacker/include/memlist.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#ifndef PH_MEMLIST_H
|
||||||
|
#define PH_MEMLIST_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
#include <colmgr.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
#define PHMMTLC_BASEADDRESS 0
|
||||||
|
#define PHMMTLC_TYPE 1
|
||||||
|
#define PHMMTLC_SIZE 2
|
||||||
|
#define PHMMTLC_PROTECTION 3
|
||||||
|
#define PHMMTLC_USE 4
|
||||||
|
#define PHMMTLC_TOTALWS 5
|
||||||
|
#define PHMMTLC_PRIVATEWS 6
|
||||||
|
#define PHMMTLC_SHAREABLEWS 7
|
||||||
|
#define PHMMTLC_SHAREDWS 8
|
||||||
|
#define PHMMTLC_LOCKEDWS 9
|
||||||
|
#define PHMMTLC_COMMITTED 10
|
||||||
|
#define PHMMTLC_PRIVATE 11
|
||||||
|
|
||||||
|
#define PHMMTLC_MAXIMUM 12
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MEMORY_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
BOOLEAN IsAllocationBase;
|
||||||
|
BOOLEAN Reserved1;
|
||||||
|
USHORT Reserved2;
|
||||||
|
PPH_MEMORY_ITEM MemoryItem;
|
||||||
|
|
||||||
|
struct _PH_MEMORY_NODE *Parent;
|
||||||
|
PPH_LIST Children;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHMMTLC_MAXIMUM];
|
||||||
|
|
||||||
|
WCHAR BaseAddressText[PH_PTR_STR_LEN_1];
|
||||||
|
WCHAR TypeText[30];
|
||||||
|
PPH_STRING SizeText;
|
||||||
|
WCHAR ProtectionText[17];
|
||||||
|
PPH_STRING UseText;
|
||||||
|
PPH_STRING TotalWsText;
|
||||||
|
PPH_STRING PrivateWsText;
|
||||||
|
PPH_STRING ShareableWsText;
|
||||||
|
PPH_STRING SharedWsText;
|
||||||
|
PPH_STRING LockedWsText;
|
||||||
|
PPH_STRING CommittedText;
|
||||||
|
PPH_STRING PrivateText;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MEMORY_NODE, *PPH_MEMORY_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_LIST_CONTEXT
|
||||||
|
{
|
||||||
|
HWND ParentWindowHandle;
|
||||||
|
HWND TreeNewHandle;
|
||||||
|
ULONG TreeNewSortColumn;
|
||||||
|
PH_SORT_ORDER TreeNewSortOrder;
|
||||||
|
PH_CM_MANAGER Cm;
|
||||||
|
BOOLEAN HideFreeRegions;
|
||||||
|
|
||||||
|
PPH_LIST AllocationBaseNodeList; // Allocation base nodes (list should always be sorted by base address)
|
||||||
|
PPH_LIST RegionNodeList; // Memory region nodes
|
||||||
|
} PH_MEMORY_LIST_CONTEXT, *PPH_MEMORY_LIST_CONTEXT;
|
||||||
|
|
||||||
|
VOID PhInitializeMemoryList(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_Out_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeleteMemoryList(
|
||||||
|
_In_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsMemoryList(
|
||||||
|
_Inout_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsMemoryList(
|
||||||
|
_Inout_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSetOptionsMemoryList(
|
||||||
|
_Inout_ PPH_MEMORY_LIST_CONTEXT Context,
|
||||||
|
_In_ BOOLEAN HideFreeRegions
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhReplaceMemoryList(
|
||||||
|
_Inout_ PPH_MEMORY_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MEMORY_ITEM_LIST List
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhUpdateMemoryNode(
|
||||||
|
_In_ PPH_MEMORY_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MEMORY_NODE MemoryNode
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MEMORY_NODE PhGetSelectedMemoryNode(
|
||||||
|
_In_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhGetSelectedMemoryNodes(
|
||||||
|
_In_ PPH_MEMORY_LIST_CONTEXT Context,
|
||||||
|
_Out_ PPH_MEMORY_NODE **MemoryNodes,
|
||||||
|
_Out_ PULONG NumberOfMemoryNodes
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeselectAllMemoryNodes(
|
||||||
|
_In_ PPH_MEMORY_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
148
ProcessHacker/include/memprv.h
Normal file
148
ProcessHacker/include/memprv.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#ifndef PH_MEMPRV_H
|
||||||
|
#define PH_MEMPRV_H
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhMemoryItemType;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _PH_MEMORY_REGION_TYPE
|
||||||
|
{
|
||||||
|
UnknownRegion,
|
||||||
|
CustomRegion,
|
||||||
|
UnusableRegion,
|
||||||
|
MappedFileRegion,
|
||||||
|
UserSharedDataRegion,
|
||||||
|
PebRegion,
|
||||||
|
Peb32Region,
|
||||||
|
TebRegion,
|
||||||
|
Teb32Region, // Not used
|
||||||
|
StackRegion,
|
||||||
|
Stack32Region,
|
||||||
|
HeapRegion,
|
||||||
|
Heap32Region,
|
||||||
|
HeapSegmentRegion,
|
||||||
|
HeapSegment32Region
|
||||||
|
} PH_MEMORY_REGION_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_ITEM
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
PH_AVL_LINKS Links;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PVOID BaseAddress;
|
||||||
|
PVOID AllocationBase;
|
||||||
|
ULONG AllocationProtect;
|
||||||
|
SIZE_T RegionSize;
|
||||||
|
ULONG State;
|
||||||
|
ULONG Protect;
|
||||||
|
ULONG Type;
|
||||||
|
};
|
||||||
|
MEMORY_BASIC_INFORMATION BasicInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PH_MEMORY_ITEM *AllocationBaseItem;
|
||||||
|
|
||||||
|
SIZE_T CommittedSize;
|
||||||
|
SIZE_T PrivateSize;
|
||||||
|
|
||||||
|
SIZE_T TotalWorkingSetPages;
|
||||||
|
SIZE_T PrivateWorkingSetPages;
|
||||||
|
SIZE_T SharedWorkingSetPages;
|
||||||
|
SIZE_T ShareableWorkingSetPages;
|
||||||
|
SIZE_T LockedWorkingSetPages;
|
||||||
|
|
||||||
|
PH_MEMORY_REGION_TYPE RegionType;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_STRING Text;
|
||||||
|
BOOLEAN PropertyOfAllocationBase;
|
||||||
|
} Custom;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_STRING FileName;
|
||||||
|
} MappedFile;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadId;
|
||||||
|
} Teb;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadId;
|
||||||
|
} Stack;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
} Heap;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct _PH_MEMORY_ITEM *HeapItem;
|
||||||
|
} HeapSegment;
|
||||||
|
} u;
|
||||||
|
} PH_MEMORY_ITEM, *PPH_MEMORY_ITEM;
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_ITEM_LIST
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PH_AVL_TREE Set;
|
||||||
|
LIST_ENTRY ListHead;
|
||||||
|
} PH_MEMORY_ITEM_LIST, *PPH_MEMORY_ITEM_LIST;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhMemoryProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhGetMemoryProtectionString(
|
||||||
|
_In_ ULONG Protection,
|
||||||
|
_Out_writes_(17) PWSTR String
|
||||||
|
);
|
||||||
|
|
||||||
|
PWSTR PhGetMemoryStateString(
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
|
||||||
|
PWSTR PhGetMemoryTypeString(
|
||||||
|
_In_ ULONG Type
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MEMORY_ITEM PhCreateMemoryItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhDeleteMemoryItemList(
|
||||||
|
_In_ PPH_MEMORY_ITEM_LIST List
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_MEMORY_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhLookupMemoryItemList(
|
||||||
|
_In_ PPH_MEMORY_ITEM_LIST List,
|
||||||
|
_In_ PVOID Address
|
||||||
|
);
|
||||||
|
|
||||||
|
#define PH_QUERY_MEMORY_IGNORE_FREE 0x1
|
||||||
|
#define PH_QUERY_MEMORY_REGION_TYPE 0x2
|
||||||
|
#define PH_QUERY_MEMORY_WS_COUNTERS 0x4
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhQueryMemoryItemList(
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_Out_ PPH_MEMORY_ITEM_LIST List
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
61
ProcessHacker/include/memsrch.h
Normal file
61
ProcessHacker/include/memsrch.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef PH_MEMSRCH_H
|
||||||
|
#define PH_MEMSRCH_H
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_RESULT
|
||||||
|
{
|
||||||
|
LONG RefCount;
|
||||||
|
PVOID Address;
|
||||||
|
SIZE_T Length;
|
||||||
|
PH_STRINGREF Display;
|
||||||
|
} PH_MEMORY_RESULT, *PPH_MEMORY_RESULT;
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_MEMORY_RESULT_CALLBACK)(
|
||||||
|
_In_ _Assume_refs_(1) PPH_MEMORY_RESULT Result,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#define PH_DISPLAY_BUFFER_COUNT (PAGE_SIZE * 2 - 1)
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_SEARCH_OPTIONS
|
||||||
|
{
|
||||||
|
BOOLEAN Cancel;
|
||||||
|
PPH_MEMORY_RESULT_CALLBACK Callback;
|
||||||
|
PVOID Context;
|
||||||
|
} PH_MEMORY_SEARCH_OPTIONS, *PPH_MEMORY_SEARCH_OPTIONS;
|
||||||
|
|
||||||
|
typedef struct _PH_MEMORY_STRING_OPTIONS
|
||||||
|
{
|
||||||
|
PH_MEMORY_SEARCH_OPTIONS Header;
|
||||||
|
|
||||||
|
ULONG MinimumLength;
|
||||||
|
BOOLEAN DetectUnicode;
|
||||||
|
ULONG MemoryTypeMask;
|
||||||
|
} PH_MEMORY_STRING_OPTIONS, *PPH_MEMORY_STRING_OPTIONS;
|
||||||
|
|
||||||
|
PVOID PhAllocateForMemorySearch(
|
||||||
|
_In_ SIZE_T Size
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhFreeForMemorySearch(
|
||||||
|
_In_ _Post_invalid_ PVOID Memory
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID PhCreateMemoryResult(
|
||||||
|
_In_ PVOID Address,
|
||||||
|
_In_ SIZE_T Length
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhReferenceMemoryResult(
|
||||||
|
_In_ PPH_MEMORY_RESULT Result
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDereferenceMemoryResult(
|
||||||
|
_In_ PPH_MEMORY_RESULT Result
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDereferenceMemoryResults(
|
||||||
|
_In_reads_(NumberOfResults) PPH_MEMORY_RESULT *Results,
|
||||||
|
_In_ ULONG NumberOfResults
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
222
ProcessHacker/include/miniinfo.h
Normal file
222
ProcessHacker/include/miniinfo.h
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
#ifndef PH_MINIINFO_H
|
||||||
|
#define PH_MINIINFO_H
|
||||||
|
|
||||||
|
#include <procgrp.h>
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Section
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_MINIINFO_SET_SECTION_TEXT)(
|
||||||
|
_In_ struct _PH_MINIINFO_SECTION *Section,
|
||||||
|
_In_opt_ PPH_STRING Text
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_PARAMETERS
|
||||||
|
{
|
||||||
|
HWND ContainerWindowHandle;
|
||||||
|
HWND MiniInfoWindowHandle;
|
||||||
|
|
||||||
|
HFONT Font;
|
||||||
|
HFONT MediumFont;
|
||||||
|
ULONG FontHeight;
|
||||||
|
ULONG FontAverageWidth;
|
||||||
|
ULONG MediumFontHeight;
|
||||||
|
ULONG MediumFontAverageWidth;
|
||||||
|
|
||||||
|
PPH_MINIINFO_SET_SECTION_TEXT SetSectionText;
|
||||||
|
} PH_MINIINFO_PARAMETERS, *PPH_MINIINFO_PARAMETERS;
|
||||||
|
|
||||||
|
typedef enum _PH_MINIINFO_SECTION_MESSAGE
|
||||||
|
{
|
||||||
|
MiniInfoCreate,
|
||||||
|
MiniInfoDestroy,
|
||||||
|
MiniInfoTick,
|
||||||
|
MiniInfoSectionChanging, // PPH_MINIINFO_SECTION Parameter1
|
||||||
|
MiniInfoShowing, // BOOLEAN Parameter1 (Showing)
|
||||||
|
MiniInfoCreateDialog, // PPH_MINIINFO_CREATE_DIALOG Parameter1
|
||||||
|
MaxMiniInfoMessage
|
||||||
|
} PH_MINIINFO_SECTION_MESSAGE;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_MINIINFO_SECTION_CALLBACK)(
|
||||||
|
_In_ struct _PH_MINIINFO_SECTION *Section,
|
||||||
|
_In_ PH_MINIINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_CREATE_DIALOG
|
||||||
|
{
|
||||||
|
BOOLEAN CustomCreate;
|
||||||
|
|
||||||
|
// Parameters for default create
|
||||||
|
PVOID Instance;
|
||||||
|
PWSTR Template;
|
||||||
|
DLGPROC DialogProc;
|
||||||
|
PVOID Parameter;
|
||||||
|
} PH_MINIINFO_CREATE_DIALOG, *PPH_MINIINFO_CREATE_DIALOG;
|
||||||
|
|
||||||
|
#define PH_MINIINFO_SECTION_NO_UPPER_MARGINS 0x1
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MINIINFO_SECTION
|
||||||
|
{
|
||||||
|
// Public
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
PH_STRINGREF Name;
|
||||||
|
ULONG Flags;
|
||||||
|
PPH_MINIINFO_SECTION_CALLBACK Callback;
|
||||||
|
PVOID Context;
|
||||||
|
PVOID Reserved1[3];
|
||||||
|
|
||||||
|
PPH_MINIINFO_PARAMETERS Parameters;
|
||||||
|
PVOID Reserved2[3];
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG SpareFlags : 32;
|
||||||
|
};
|
||||||
|
HWND DialogHandle;
|
||||||
|
PPH_STRING Text;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MINIINFO_SECTION, *PPH_MINIINFO_SECTION;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef enum _PH_MINIINFO_PIN_TYPE
|
||||||
|
{
|
||||||
|
MiniInfoManualPinType, // User pin
|
||||||
|
MiniInfoIconPinType, // Notification icon
|
||||||
|
MiniInfoActivePinType, // Window is active
|
||||||
|
MiniInfoHoverPinType, // Cursor is over mini info window
|
||||||
|
MiniInfoChildControlPinType, // Interacting with child control
|
||||||
|
MaxMiniInfoPinType
|
||||||
|
} PH_MINIINFO_PIN_TYPE;
|
||||||
|
|
||||||
|
#define PH_MINIINFO_ACTIVATE_WINDOW 0x1
|
||||||
|
#define PH_MINIINFO_LOAD_POSITION 0x2
|
||||||
|
#define PH_MINIINFO_DONT_CHANGE_SECTION_IF_PINNED 0x4
|
||||||
|
|
||||||
|
VOID PhPinMiniInformation(
|
||||||
|
_In_ PH_MINIINFO_PIN_TYPE PinType,
|
||||||
|
_In_ LONG PinCount,
|
||||||
|
_In_opt_ ULONG PinDelayMs,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_opt_ PWSTR SectionName,
|
||||||
|
_In_opt_ PPOINT SourcePoint
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// List section
|
||||||
|
|
||||||
|
typedef enum _PH_MINIINFO_LIST_SECTION_MESSAGE
|
||||||
|
{
|
||||||
|
MiListSectionCreate,
|
||||||
|
MiListSectionDestroy,
|
||||||
|
MiListSectionTick,
|
||||||
|
MiListSectionShowing, // BOOLEAN Parameter1 (Showing)
|
||||||
|
MiListSectionDialogCreated, // HWND Parameter1
|
||||||
|
MiListSectionSortProcessList, // PPH_MINIINFO_LIST_SECTION_SORT_LIST Parameter1
|
||||||
|
MiListSectionAssignSortData, // PPH_MINIINFO_LIST_SECTION_ASSIGN_SORT_DATA Parameter1
|
||||||
|
MiListSectionSortGroupList, // PPH_MINIINFO_LIST_SECTION_SORT_LIST Parameter1
|
||||||
|
MiListSectionGetTitleText, // PPH_MINIINFO_LIST_SECTION_GET_TITLE_TEXT Parameter1
|
||||||
|
MiListSectionGetUsageText, // PPH_MINIINFO_LIST_SECTION_GET_USAGE_TEXT Parameter1
|
||||||
|
MiListSectionInitializeContextMenu, // PPH_MINIINFO_LIST_SECTION_MENU_INFORMATION Parameter1
|
||||||
|
MiListSectionHandleContextMenu, // PPH_MINIINFO_LIST_SECTION_MENU_INFORMATION Parameter1
|
||||||
|
MaxMiListSectionMessage
|
||||||
|
} PH_MINIINFO_LIST_SECTION_MESSAGE;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_MINIINFO_LIST_SECTION_CALLBACK)(
|
||||||
|
_In_ struct _PH_MINIINFO_LIST_SECTION *ListSection,
|
||||||
|
_In_ PH_MINIINFO_LIST_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
// The list section performs the following steps when constructing the list of process groups:
|
||||||
|
// 1. MiListSectionSortProcessList is sent in order to sort the process list.
|
||||||
|
// 2. A small number of process groups is created from the first few processes in the sorted list (typically high
|
||||||
|
// resource consumers).
|
||||||
|
// 3. MiListSectionAssignSortData is sent for each process group so that the user can assign custom sort data to
|
||||||
|
// each process group.
|
||||||
|
// 4. MiListSectionSortGroupList is sent in order to ensure that the process groups are correctly sorted by resource
|
||||||
|
// usage.
|
||||||
|
// The user also has access to the sort data when handling MiListSectionGetTitleText and MiListSectionGetUsageText.
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_SORT_DATA
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE DoNotModify;
|
||||||
|
ULONGLONG UserData[4];
|
||||||
|
} PH_MINIINFO_LIST_SECTION_SORT_DATA, *PPH_MINIINFO_LIST_SECTION_SORT_DATA;
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_ASSIGN_SORT_DATA
|
||||||
|
{
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
PPH_MINIINFO_LIST_SECTION_SORT_DATA SortData;
|
||||||
|
} PH_MINIINFO_LIST_SECTION_ASSIGN_SORT_DATA, *PPH_MINIINFO_LIST_SECTION_ASSIGN_SORT_DATA;
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_SORT_LIST
|
||||||
|
{
|
||||||
|
// MiListSectionSortProcessList: List of PPH_PROCESS_NODE
|
||||||
|
// MiListSectionSortGroupList: List of PPH_MINIINFO_LIST_SECTION_SORT_DATA
|
||||||
|
PPH_LIST List;
|
||||||
|
} PH_MINIINFO_LIST_SECTION_SORT_LIST, *PPH_MINIINFO_LIST_SECTION_SORT_LIST;
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_GET_TITLE_TEXT
|
||||||
|
{
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
PPH_MINIINFO_LIST_SECTION_SORT_DATA SortData;
|
||||||
|
PPH_STRING Title; // Top line (may already contain a string)
|
||||||
|
PPH_STRING Subtitle; // Bottom line (may already contain a string)
|
||||||
|
COLORREF TitleColor;
|
||||||
|
COLORREF SubtitleColor;
|
||||||
|
} PH_MINIINFO_LIST_SECTION_GET_TITLE_TEXT, *PPH_MINIINFO_LIST_SECTION_GET_TITLE_TEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_GET_USAGE_TEXT
|
||||||
|
{
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
PPH_MINIINFO_LIST_SECTION_SORT_DATA SortData;
|
||||||
|
PPH_STRING Line1; // Top line
|
||||||
|
PPH_STRING Line2; // Bottom line
|
||||||
|
COLORREF Line1Color;
|
||||||
|
COLORREF Line2Color;
|
||||||
|
} PH_MINIINFO_LIST_SECTION_GET_USAGE_TEXT, *PPH_MINIINFO_LIST_SECTION_GET_USAGE_TEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION_MENU_INFORMATION
|
||||||
|
{
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
PPH_MINIINFO_LIST_SECTION_SORT_DATA SortData;
|
||||||
|
PPH_TREENEW_CONTEXT_MENU ContextMenu;
|
||||||
|
struct _PH_EMENU_ITEM *SelectedItem;
|
||||||
|
} PH_MINIINFO_LIST_SECTION_MENU_INFORMATION, *PPH_MINIINFO_LIST_SECTION_MENU_INFORMATION;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MINIINFO_LIST_SECTION
|
||||||
|
{
|
||||||
|
// Public
|
||||||
|
|
||||||
|
PPH_MINIINFO_SECTION Section; // State
|
||||||
|
HWND DialogHandle; // State
|
||||||
|
HWND TreeNewHandle; // State
|
||||||
|
PVOID Context; // Initialization
|
||||||
|
PPH_MINIINFO_LIST_SECTION_CALLBACK Callback; // Initialization
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
PH_LAYOUT_MANAGER LayoutManager;
|
||||||
|
ULONG RunCount;
|
||||||
|
LONG SuspendUpdate;
|
||||||
|
PPH_LIST ProcessGroupList;
|
||||||
|
PPH_LIST NodeList;
|
||||||
|
HANDLE SelectedRepresentativeProcessId;
|
||||||
|
LARGE_INTEGER SelectedRepresentativeCreateTime;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MINIINFO_LIST_SECTION, *PPH_MINIINFO_LIST_SECTION;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
403
ProcessHacker/include/miniinfop.h
Normal file
403
ProcessHacker/include/miniinfop.h
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
#ifndef PH_MINIINFOP_H
|
||||||
|
#define PH_MINIINFOP_H
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
|
||||||
|
#define MIP_CONTAINER_CLASSNAME L"ProcessHackerMiniInfo"
|
||||||
|
|
||||||
|
#define MIP_TIMER_PIN_FIRST 1
|
||||||
|
#define MIP_TIMER_PIN_LAST (MIP_TIMER_PIN_FIRST + MaxMiniInfoPinType - 1)
|
||||||
|
|
||||||
|
#define MIP_MSG_FIRST (WM_APP + 150)
|
||||||
|
#define MIP_MSG_UPDATE (WM_APP + 150)
|
||||||
|
#define MIP_MSG_LAST (WM_APP + 151)
|
||||||
|
|
||||||
|
#define MIP_UNPIN_CHILD_CONTROL_DELAY 1000
|
||||||
|
#define MIP_UNPIN_HOVER_DELAY 250
|
||||||
|
|
||||||
|
#define MIP_REFRESH_AUTOMATICALLY_PINNED 0x1
|
||||||
|
#define MIP_REFRESH_AUTOMATICALLY_UNPINNED 0x2
|
||||||
|
#define MIP_REFRESH_AUTOMATICALLY_FLAG(Pinned) \
|
||||||
|
((Pinned) ? MIP_REFRESH_AUTOMATICALLY_PINNED : MIP_REFRESH_AUTOMATICALLY_UNPINNED)
|
||||||
|
|
||||||
|
// Misc.
|
||||||
|
|
||||||
|
#define SET_BUTTON_ICON(hwndDlg, Id, Icon) \
|
||||||
|
SendMessage(GetDlgItem(hwndDlg, (Id)), BM_SETIMAGE, IMAGE_ICON, (LPARAM)(Icon))
|
||||||
|
|
||||||
|
// Dialog procedure
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhMipContainerWndProc(
|
||||||
|
_In_ HWND hWnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhMipMiniInfoDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Container event handlers
|
||||||
|
|
||||||
|
VOID PhMipContainerOnShowWindow(
|
||||||
|
_In_ BOOLEAN Showing,
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipContainerOnActivate(
|
||||||
|
_In_ ULONG Type,
|
||||||
|
_In_ BOOLEAN Minimized
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipContainerOnSize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipContainerOnSizing(
|
||||||
|
_In_ ULONG Edge,
|
||||||
|
_In_ PRECT DragRectangle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipContainerOnExitSizeMove(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipContainerOnEraseBkgnd(
|
||||||
|
_In_ HDC hdc
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipContainerOnTimer(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
// Child dialog event handlers
|
||||||
|
|
||||||
|
VOID PhMipOnInitDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipOnShowWindow(
|
||||||
|
_In_ BOOLEAN Showing,
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipOnCommand(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ ULONG Code
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipOnNotify(
|
||||||
|
_In_ NMHDR *Header,
|
||||||
|
_Out_ LRESULT *Result
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipOnCtlColorXxx(
|
||||||
|
_In_ ULONG Message,
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ HDC hdc,
|
||||||
|
_Out_ HBRUSH *Brush
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipOnDrawItem(
|
||||||
|
_In_ ULONG_PTR Id,
|
||||||
|
_In_ DRAWITEMSTRUCT *DrawItemStruct
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipOnUserMessage(
|
||||||
|
_In_ ULONG Message,
|
||||||
|
_In_ ULONG_PTR WParam,
|
||||||
|
_In_ ULONG_PTR LParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Framework
|
||||||
|
|
||||||
|
typedef enum _PH_MIP_ADJUST_PIN_RESULT
|
||||||
|
{
|
||||||
|
NoAdjustPinResult,
|
||||||
|
ShowAdjustPinResult,
|
||||||
|
HideAdjustPinResult
|
||||||
|
} PH_MIP_ADJUST_PIN_RESULT;
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PhMipMessageLoopFilter(
|
||||||
|
_In_ PMSG Message,
|
||||||
|
_In_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhMipUpdateHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PH_MIP_ADJUST_PIN_RESULT PhMipAdjustPin(
|
||||||
|
_In_ PH_MINIINFO_PIN_TYPE PinType,
|
||||||
|
_In_ LONG PinCount
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipCalculateWindowRectangle(
|
||||||
|
_In_ PPOINT SourcePoint,
|
||||||
|
_Out_ PPH_RECTANGLE WindowRectangle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipInitializeParameters(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MINIINFO_SECTION PhMipCreateSection(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipDestroySection(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Section
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MINIINFO_SECTION PhMipFindSection(
|
||||||
|
_In_ PPH_STRINGREF Name
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MINIINFO_SECTION PhMipCreateInternalSection(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_MINIINFO_SECTION_CALLBACK Callback
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipCreateSectionDialog(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Section
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipChangeSection(
|
||||||
|
_In_ PPH_MINIINFO_SECTION NewSection
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipSetSectionText(
|
||||||
|
_In_ struct _PH_MINIINFO_SECTION *Section,
|
||||||
|
_In_opt_ PPH_STRING Text
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipUpdateSectionText(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Section
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipLayout(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipBeginChildControlPin(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipEndChildControlPin(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipRefresh(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipToggleRefreshAutomatically(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipSetPinned(
|
||||||
|
_In_ BOOLEAN Pinned
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipShowSectionMenu(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipShowOptionsMenu(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhMipSectionControlHookWndProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// List-based section
|
||||||
|
|
||||||
|
#define MIP_MAX_PROCESS_GROUPS 15
|
||||||
|
#define MIP_SINGLE_COLUMN_ID 0
|
||||||
|
|
||||||
|
#define MIP_CELL_PADDING 5
|
||||||
|
#define MIP_ICON_PADDING 3
|
||||||
|
#define MIP_INNER_PADDING 3
|
||||||
|
|
||||||
|
typedef struct _PH_MIP_GROUP_NODE
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
PH_MINIINFO_LIST_SECTION_SORT_DATA SortData;
|
||||||
|
};
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
HANDLE RepresentativeProcessId;
|
||||||
|
LARGE_INTEGER RepresentativeCreateTime;
|
||||||
|
BOOLEAN RepresentativeIsHung;
|
||||||
|
|
||||||
|
PPH_STRING TooltipText;
|
||||||
|
} PH_MIP_GROUP_NODE, *PPH_MIP_GROUP_NODE;
|
||||||
|
|
||||||
|
PPH_MINIINFO_LIST_SECTION PhMipCreateListSection(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MINIINFO_LIST_SECTION PhMipCreateInternalListSection(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION_CALLBACK Callback
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipListSectionCallback(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Section,
|
||||||
|
_In_ PH_MINIINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhMipListSectionDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipListSectionSortFunction(
|
||||||
|
_In_ PPH_LIST List,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipTickListSection(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipClearListSection(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection
|
||||||
|
);
|
||||||
|
|
||||||
|
LONG PhMipCalculateRowHeight(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MIP_GROUP_NODE PhMipAddGroupNode(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection,
|
||||||
|
_In_ PPH_PROCESS_GROUP ProcessGroup
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipDestroyGroupNode(
|
||||||
|
_In_ PPH_MIP_GROUP_NODE Node
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhMipListSectionTreeNewCallback(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ PH_TREENEW_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhMipGetGroupNodeTooltip(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection,
|
||||||
|
_In_ PPH_MIP_GROUP_NODE Node
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MIP_GROUP_NODE PhMipGetSelectedGroupNode(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipShowListSectionContextMenu(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection,
|
||||||
|
_In_ PPH_TREENEW_CONTEXT_MENU ContextMenu
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhMipHandleListSectionCommand(
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION ListSection,
|
||||||
|
_In_ PPH_PROCESS_GROUP ProcessGroup,
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
// CPU section
|
||||||
|
|
||||||
|
BOOLEAN PhMipCpuListSectionCallback(
|
||||||
|
_In_ struct _PH_MINIINFO_LIST_SECTION *ListSection,
|
||||||
|
_In_ PH_MINIINFO_LIST_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipCpuListSectionProcessCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipCpuListSectionNodeCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
// Commit charge section
|
||||||
|
|
||||||
|
BOOLEAN PhMipCommitListSectionCallback(
|
||||||
|
_In_ struct _PH_MINIINFO_LIST_SECTION *ListSection,
|
||||||
|
_In_ PH_MINIINFO_LIST_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipCommitListSectionProcessCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipCommitListSectionNodeCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
// Physical memory section
|
||||||
|
|
||||||
|
BOOLEAN PhMipPhysicalListSectionCallback(
|
||||||
|
_In_ struct _PH_MINIINFO_LIST_SECTION *ListSection,
|
||||||
|
_In_ PH_MINIINFO_LIST_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipPhysicalListSectionProcessCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipPhysicalListSectionNodeCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
// I/O section
|
||||||
|
|
||||||
|
BOOLEAN PhMipIoListSectionCallback(
|
||||||
|
_In_ struct _PH_MINIINFO_LIST_SECTION *ListSection,
|
||||||
|
_In_ PH_MINIINFO_LIST_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipIoListSectionProcessCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
int __cdecl PhMipIoListSectionNodeCompareFunction(
|
||||||
|
_In_ const void *elem1,
|
||||||
|
_In_ const void *elem2
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
132
ProcessHacker/include/modlist.h
Normal file
132
ProcessHacker/include/modlist.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#ifndef PH_MODLIST_H
|
||||||
|
#define PH_MODLIST_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
#include <colmgr.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
#define PHMOTLC_NAME 0
|
||||||
|
#define PHMOTLC_BASEADDRESS 1
|
||||||
|
#define PHMOTLC_SIZE 2
|
||||||
|
#define PHMOTLC_DESCRIPTION 3
|
||||||
|
|
||||||
|
#define PHMOTLC_COMPANYNAME 4
|
||||||
|
#define PHMOTLC_VERSION 5
|
||||||
|
#define PHMOTLC_FILENAME 6
|
||||||
|
|
||||||
|
#define PHMOTLC_TYPE 7
|
||||||
|
#define PHMOTLC_LOADCOUNT 8
|
||||||
|
#define PHMOTLC_VERIFICATIONSTATUS 9
|
||||||
|
#define PHMOTLC_VERIFIEDSIGNER 10
|
||||||
|
#define PHMOTLC_ASLR 11
|
||||||
|
#define PHMOTLC_TIMESTAMP 12
|
||||||
|
#define PHMOTLC_CFGUARD 13
|
||||||
|
#define PHMOTLC_LOADTIME 14
|
||||||
|
#define PHMOTLC_LOADREASON 15
|
||||||
|
#define PHMOTLC_FILEMODIFIEDTIME 16
|
||||||
|
#define PHMOTLC_FILESIZE 17
|
||||||
|
|
||||||
|
#define PHMOTLC_MAXIMUM 18
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MODULE_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
PH_SH_STATE ShState;
|
||||||
|
|
||||||
|
PPH_MODULE_ITEM ModuleItem;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHMOTLC_MAXIMUM];
|
||||||
|
|
||||||
|
ULONG ValidMask;
|
||||||
|
|
||||||
|
PPH_STRING TooltipText;
|
||||||
|
|
||||||
|
PPH_STRING SizeText;
|
||||||
|
WCHAR LoadCountText[PH_INT32_STR_LEN_1];
|
||||||
|
PPH_STRING TimeStampText;
|
||||||
|
PPH_STRING LoadTimeText;
|
||||||
|
PPH_STRING FileModifiedTimeText;
|
||||||
|
PPH_STRING FileSizeText;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MODULE_NODE, *PPH_MODULE_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_MODULE_LIST_CONTEXT
|
||||||
|
{
|
||||||
|
HWND ParentWindowHandle;
|
||||||
|
HWND TreeNewHandle;
|
||||||
|
ULONG TreeNewSortColumn;
|
||||||
|
PH_SORT_ORDER TreeNewSortOrder;
|
||||||
|
PH_CM_MANAGER Cm;
|
||||||
|
|
||||||
|
PPH_HASHTABLE NodeHashtable;
|
||||||
|
PPH_LIST NodeList;
|
||||||
|
|
||||||
|
BOOLEAN EnableStateHighlighting;
|
||||||
|
PPH_POINTER_LIST NodeStateList;
|
||||||
|
|
||||||
|
HFONT BoldFont;
|
||||||
|
} PH_MODULE_LIST_CONTEXT, *PPH_MODULE_LIST_CONTEXT;
|
||||||
|
|
||||||
|
VOID PhInitializeModuleList(
|
||||||
|
_In_ HWND ParentWindowHandle,
|
||||||
|
_In_ HWND TreeNewHandle,
|
||||||
|
_Out_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeleteModuleList(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsModuleList(
|
||||||
|
_Inout_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsModuleList(
|
||||||
|
_Inout_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_NODE PhAddModuleNode(
|
||||||
|
_Inout_ PPH_MODULE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MODULE_ITEM ModuleItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_NODE PhFindModuleNode(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MODULE_ITEM ModuleItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhRemoveModuleNode(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MODULE_NODE ModuleNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhUpdateModuleNode(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context,
|
||||||
|
_In_ PPH_MODULE_NODE ModuleNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhTickModuleNodes(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_ITEM PhGetSelectedModuleItem(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhGetSelectedModuleItems(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context,
|
||||||
|
_Out_ PPH_MODULE_ITEM **Modules,
|
||||||
|
_Out_ PULONG NumberOfModules
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeselectAllModuleNodes(
|
||||||
|
_In_ PPH_MODULE_LIST_CONTEXT Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
80
ProcessHacker/include/modprv.h
Normal file
80
ProcessHacker/include/modprv.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef PH_MODPRV_H
|
||||||
|
#define PH_MODPRV_H
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhModuleProviderType;
|
||||||
|
extern PPH_OBJECT_TYPE PhModuleItemType;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MODULE_ITEM
|
||||||
|
{
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG Size;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Type;
|
||||||
|
USHORT LoadReason;
|
||||||
|
USHORT LoadCount;
|
||||||
|
PPH_STRING Name;
|
||||||
|
PPH_STRING FileName;
|
||||||
|
PH_IMAGE_VERSION_INFO VersionInfo;
|
||||||
|
|
||||||
|
WCHAR BaseAddressString[PH_PTR_STR_LEN_1];
|
||||||
|
|
||||||
|
BOOLEAN IsFirst;
|
||||||
|
BOOLEAN JustProcessed;
|
||||||
|
|
||||||
|
enum _VERIFY_RESULT VerifyResult;
|
||||||
|
PPH_STRING VerifySignerName;
|
||||||
|
|
||||||
|
ULONG ImageTimeDateStamp;
|
||||||
|
USHORT ImageCharacteristics;
|
||||||
|
USHORT ImageDllCharacteristics;
|
||||||
|
|
||||||
|
LARGE_INTEGER LoadTime;
|
||||||
|
|
||||||
|
LARGE_INTEGER FileLastWriteTime;
|
||||||
|
LARGE_INTEGER FileEndOfFile;
|
||||||
|
} PH_MODULE_ITEM, *PPH_MODULE_ITEM;
|
||||||
|
|
||||||
|
typedef struct _PH_MODULE_PROVIDER
|
||||||
|
{
|
||||||
|
PPH_HASHTABLE ModuleHashtable;
|
||||||
|
PH_FAST_LOCK ModuleHashtableLock;
|
||||||
|
PH_CALLBACK ModuleAddedEvent;
|
||||||
|
PH_CALLBACK ModuleModifiedEvent;
|
||||||
|
PH_CALLBACK ModuleRemovedEvent;
|
||||||
|
PH_CALLBACK UpdatedEvent;
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
PPH_STRING PackageFullName;
|
||||||
|
SLIST_HEADER QueryListHead;
|
||||||
|
NTSTATUS RunStatus;
|
||||||
|
} PH_MODULE_PROVIDER, *PPH_MODULE_PROVIDER;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhModuleProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_PROVIDER PhCreateModuleProvider(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_ITEM PhCreateModuleItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_MODULE_ITEM PhReferenceModuleItem(
|
||||||
|
_In_ PPH_MODULE_PROVIDER ModuleProvider,
|
||||||
|
_In_ PVOID BaseAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDereferenceAllModuleItems(
|
||||||
|
_In_ PPH_MODULE_PROVIDER ModuleProvider
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhModuleProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
119
ProcessHacker/include/netlist.h
Normal file
119
ProcessHacker/include/netlist.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#ifndef PH_NETLIST_H
|
||||||
|
#define PH_NETLIST_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
#define PHNETLC_PROCESS 0
|
||||||
|
#define PHNETLC_LOCALADDRESS 1
|
||||||
|
#define PHNETLC_LOCALPORT 2
|
||||||
|
#define PHNETLC_REMOTEADDRESS 3
|
||||||
|
#define PHNETLC_REMOTEPORT 4
|
||||||
|
#define PHNETLC_PROTOCOL 5
|
||||||
|
#define PHNETLC_STATE 6
|
||||||
|
#define PHNETLC_OWNER 7
|
||||||
|
#define PHNETLC_TIMESTAMP 8
|
||||||
|
#define PHNETLC_MAXIMUM 9
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_NETWORK_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
PH_SH_STATE ShState;
|
||||||
|
|
||||||
|
PPH_NETWORK_ITEM NetworkItem;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHNETLC_MAXIMUM];
|
||||||
|
|
||||||
|
LONG UniqueId;
|
||||||
|
PPH_STRING ProcessNameText;
|
||||||
|
PH_STRINGREF LocalAddressText;
|
||||||
|
PH_STRINGREF RemoteAddressText;
|
||||||
|
PPH_STRING TimeStampText;
|
||||||
|
|
||||||
|
PPH_STRING TooltipText;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_NETWORK_NODE, *PPH_NETWORK_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhNetworkTreeListInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhInitializeNetworkTreeList(
|
||||||
|
_In_ HWND hwnd
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsNetworkTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsNetworkTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
struct _PH_TN_FILTER_SUPPORT *
|
||||||
|
NTAPI
|
||||||
|
PhGetFilterSupportNetworkTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_NETWORK_NODE PhAddNetworkNode(
|
||||||
|
_In_ PPH_NETWORK_ITEM NetworkItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_NETWORK_NODE
|
||||||
|
NTAPI
|
||||||
|
PhFindNetworkNode(
|
||||||
|
_In_ PPH_NETWORK_ITEM NetworkItem
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhRemoveNetworkNode(
|
||||||
|
_In_ PPH_NETWORK_NODE NetworkNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhUpdateNetworkNode(
|
||||||
|
_In_ PPH_NETWORK_NODE NetworkNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhTickNetworkNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_NETWORK_ITEM PhGetSelectedNetworkItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhGetSelectedNetworkItems(
|
||||||
|
_Out_ PPH_NETWORK_ITEM **NetworkItems,
|
||||||
|
_Out_ PULONG NumberOfNetworkItems
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhDeselectAllNetworkNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSelectAndEnsureVisibleNetworkNode(
|
||||||
|
_In_ PPH_NETWORK_NODE NetworkNode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhCopyNetworkList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhWriteNetworkList(
|
||||||
|
_Inout_ PPH_FILE_STREAM FileStream,
|
||||||
|
_In_ ULONG Mode
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
86
ProcessHacker/include/netprv.h
Normal file
86
ProcessHacker/include/netprv.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#ifndef PH_NETPRV_H
|
||||||
|
#define PH_NETPRV_H
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhNetworkItemType;
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhNetworkItemAddedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhNetworkItemModifiedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhNetworkItemRemovedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhNetworkItemsUpdatedEvent; // phapppub
|
||||||
|
|
||||||
|
extern BOOLEAN PhEnableNetworkProviderResolve;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
#define PH_NETWORK_OWNER_INFO_SIZE 16
|
||||||
|
|
||||||
|
typedef struct _PH_NETWORK_ITEM
|
||||||
|
{
|
||||||
|
ULONG ProtocolType;
|
||||||
|
PH_IP_ENDPOINT LocalEndpoint;
|
||||||
|
PH_IP_ENDPOINT RemoteEndpoint;
|
||||||
|
ULONG State;
|
||||||
|
HANDLE ProcessId;
|
||||||
|
|
||||||
|
PPH_STRING ProcessName;
|
||||||
|
HICON ProcessIcon;
|
||||||
|
BOOLEAN ProcessIconValid;
|
||||||
|
PPH_STRING OwnerName;
|
||||||
|
|
||||||
|
BOOLEAN JustResolved;
|
||||||
|
|
||||||
|
WCHAR LocalAddressString[65];
|
||||||
|
WCHAR LocalPortString[PH_INT32_STR_LEN_1];
|
||||||
|
WCHAR RemoteAddressString[65];
|
||||||
|
WCHAR RemotePortString[PH_INT32_STR_LEN_1];
|
||||||
|
PPH_STRING LocalHostString;
|
||||||
|
PPH_STRING RemoteHostString;
|
||||||
|
|
||||||
|
LARGE_INTEGER CreateTime;
|
||||||
|
ULONGLONG OwnerInfo[PH_NETWORK_OWNER_INFO_SIZE];
|
||||||
|
} PH_NETWORK_ITEM, *PPH_NETWORK_ITEM;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhNetworkProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_NETWORK_ITEM PhCreateNetworkItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_NETWORK_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhReferenceNetworkItem(
|
||||||
|
_In_ ULONG ProtocolType,
|
||||||
|
_In_ PPH_IP_ENDPOINT LocalEndpoint,
|
||||||
|
_In_ PPH_IP_ENDPOINT RemoteEndpoint,
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_STRING PhGetHostNameFromAddress(
|
||||||
|
_In_ PPH_IP_ADDRESS Address
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNetworkProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PWSTR
|
||||||
|
NTAPI
|
||||||
|
PhGetProtocolTypeName(
|
||||||
|
_In_ ULONG ProtocolType
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PWSTR
|
||||||
|
NTAPI
|
||||||
|
PhGetTcpStateName(
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
171
ProcessHacker/include/notifico.h
Normal file
171
ProcessHacker/include/notifico.h
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#ifndef PH_NOTIFICO_H
|
||||||
|
#define PH_NOTIFICO_H
|
||||||
|
|
||||||
|
#define PH_ICON_MINIMUM 0x1
|
||||||
|
#define PH_ICON_CPU_HISTORY 0x1
|
||||||
|
#define PH_ICON_IO_HISTORY 0x2
|
||||||
|
#define PH_ICON_COMMIT_HISTORY 0x4
|
||||||
|
#define PH_ICON_PHYSICAL_HISTORY 0x8
|
||||||
|
#define PH_ICON_CPU_USAGE 0x10
|
||||||
|
#define PH_ICON_DEFAULT_MAXIMUM 0x20
|
||||||
|
#define PH_ICON_DEFAULT_ALL 0x1f
|
||||||
|
|
||||||
|
#define PH_ICON_LIMIT 0x80000000
|
||||||
|
#define PH_ICON_ALL 0xffffffff
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef VOID (NTAPI *PPH_NF_UPDATE_REGISTERED_ICON)(
|
||||||
|
_In_ struct _PH_NF_ICON *Icon
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_NF_BEGIN_BITMAP)(
|
||||||
|
_Out_ PULONG Width,
|
||||||
|
_Out_ PULONG Height,
|
||||||
|
_Out_ HBITMAP *Bitmap,
|
||||||
|
_Out_opt_ PVOID *Bits,
|
||||||
|
_Out_ HDC *Hdc,
|
||||||
|
_Out_ HBITMAP *OldBitmap
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_NF_POINTERS
|
||||||
|
{
|
||||||
|
PPH_NF_UPDATE_REGISTERED_ICON UpdateRegisteredIcon;
|
||||||
|
PPH_NF_BEGIN_BITMAP BeginBitmap;
|
||||||
|
} PH_NF_POINTERS, *PPH_NF_POINTERS;
|
||||||
|
|
||||||
|
#define PH_NF_UPDATE_IS_BITMAP 0x1
|
||||||
|
#define PH_NF_UPDATE_DESTROY_RESOURCE 0x2
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_NF_ICON_UPDATE_CALLBACK)(
|
||||||
|
_In_ struct _PH_NF_ICON *Icon,
|
||||||
|
_Out_ PVOID *NewIconOrBitmap,
|
||||||
|
_Out_ PULONG Flags,
|
||||||
|
_Out_ PPH_STRING *NewText,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_NF_ICON_MESSAGE_CALLBACK)(
|
||||||
|
_In_ struct _PH_NF_ICON *Icon,
|
||||||
|
_In_ ULONG_PTR WParam,
|
||||||
|
_In_ ULONG_PTR LParam,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
// Special messages
|
||||||
|
// The message type is stored in LOWORD(LParam), and the message data is in WParam.
|
||||||
|
|
||||||
|
#define PH_NF_MSG_SHOWMINIINFOSECTION (WM_APP + 1)
|
||||||
|
|
||||||
|
typedef struct _PH_NF_MSG_SHOWMINIINFOSECTION_DATA
|
||||||
|
{
|
||||||
|
PWSTR SectionName; // NULL to leave unchanged
|
||||||
|
} PH_NF_MSG_SHOWMINIINFOSECTION_DATA, *PPH_NF_MSG_SHOWMINIINFOSECTION_DATA;
|
||||||
|
|
||||||
|
// Structures and internal functions
|
||||||
|
|
||||||
|
#define PH_NF_ICON_UNAVAILABLE 0x1
|
||||||
|
#define PH_NF_ICON_SHOW_MINIINFO 0x2
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_NF_ICON
|
||||||
|
{
|
||||||
|
// Public
|
||||||
|
|
||||||
|
struct _PH_PLUGIN *Plugin;
|
||||||
|
ULONG SubId;
|
||||||
|
PVOID Context;
|
||||||
|
PPH_NF_POINTERS Pointers;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
PWSTR Text;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG IconId;
|
||||||
|
PPH_NF_ICON_UPDATE_CALLBACK UpdateCallback;
|
||||||
|
PPH_NF_ICON_MESSAGE_CALLBACK MessageCallback;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_NF_ICON, *PPH_NF_ICON;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhNfLoadStage1(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfLoadStage2(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfSaveSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfUninitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfForwardMessage(
|
||||||
|
_In_ ULONG_PTR WParam,
|
||||||
|
_In_ ULONG_PTR LParam
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG PhNfGetMaximumIconId(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG PhNfTestIconMask(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfSetVisibleIcon(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ BOOLEAN Visible
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhNfShowBalloonTip(
|
||||||
|
_In_opt_ ULONG Id,
|
||||||
|
_In_ PWSTR Title,
|
||||||
|
_In_ PWSTR Text,
|
||||||
|
_In_ ULONG Timeout,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
HICON PhNfBitmapToIcon(
|
||||||
|
_In_ HBITMAP Bitmap
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_NF_ICON PhNfRegisterIcon(
|
||||||
|
_In_ struct _PH_PLUGIN *Plugin,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_ PWSTR Text,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_opt_ PPH_NF_ICON_UPDATE_CALLBACK UpdateCallback,
|
||||||
|
_In_opt_ PPH_NF_ICON_MESSAGE_CALLBACK MessageCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_NF_ICON PhNfGetIconById(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_NF_ICON PhNfFindIcon(
|
||||||
|
_In_ PPH_STRINGREF PluginName,
|
||||||
|
_In_ ULONG SubId
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfNotifyMiniInfoPinned(
|
||||||
|
_In_ BOOLEAN Pinned
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Public registration data
|
||||||
|
|
||||||
|
typedef struct _PH_NF_ICON_REGISTRATION_DATA
|
||||||
|
{
|
||||||
|
PPH_NF_ICON_UPDATE_CALLBACK UpdateCallback;
|
||||||
|
PPH_NF_ICON_MESSAGE_CALLBACK MessageCallback;
|
||||||
|
} PH_NF_ICON_REGISTRATION_DATA, *PPH_NF_ICON_REGISTRATION_DATA;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
107
ProcessHacker/include/notificop.h
Normal file
107
ProcessHacker/include/notificop.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#ifndef PH_NOTIFICOP_H
|
||||||
|
#define PH_NOTIFICOP_H
|
||||||
|
|
||||||
|
typedef struct _PH_NF_BITMAP
|
||||||
|
{
|
||||||
|
BOOLEAN Initialized;
|
||||||
|
HDC Hdc;
|
||||||
|
BITMAPINFOHEADER Header;
|
||||||
|
HBITMAP Bitmap;
|
||||||
|
PVOID Bits;
|
||||||
|
} PH_NF_BITMAP, *PPH_NF_BITMAP;
|
||||||
|
|
||||||
|
HICON PhNfpGetBlackIcon(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhNfpAddNotifyIcon(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhNfpRemoveNotifyIcon(
|
||||||
|
_In_ ULONG Id
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhNfpModifyNotifyIcon(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_opt_ PPH_STRING Text,
|
||||||
|
_In_opt_ HICON Icon
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpProcessesUpdatedHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateRegisteredIcon(
|
||||||
|
_In_ PPH_NF_ICON Icon
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpBeginBitmap(
|
||||||
|
_Out_ PULONG Width,
|
||||||
|
_Out_ PULONG Height,
|
||||||
|
_Out_ HBITMAP *Bitmap,
|
||||||
|
_Out_opt_ PVOID *Bits,
|
||||||
|
_Out_ HDC *Hdc,
|
||||||
|
_Out_ HBITMAP *OldBitmap
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpBeginBitmap2(
|
||||||
|
_Inout_ PPH_NF_BITMAP Context,
|
||||||
|
_Out_ PULONG Width,
|
||||||
|
_Out_ PULONG Height,
|
||||||
|
_Out_ HBITMAP *Bitmap,
|
||||||
|
_Out_opt_ PVOID *Bits,
|
||||||
|
_Out_ HDC *Hdc,
|
||||||
|
_Out_ HBITMAP *OldBitmap
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateIconCpuHistory(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateIconIoHistory(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateIconCommitHistory(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateIconPhysicalHistory(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpUpdateIconCpuUsage(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhNfpGetShowMiniInfoSectionData(
|
||||||
|
_In_ ULONG IconIndex,
|
||||||
|
_In_ PPH_NF_ICON RegisteredIcon,
|
||||||
|
_Out_ PPH_NF_MSG_SHOWMINIINFOSECTION_DATA Data
|
||||||
|
);
|
||||||
|
|
||||||
|
#define NFP_ICON_CLICK_ACTIVATE_DELAY 140
|
||||||
|
#define NFP_ICON_RESTORE_HOVER_DELAY 1000
|
||||||
|
|
||||||
|
VOID PhNfpIconClickActivateTimerProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ UINT_PTR idEvent,
|
||||||
|
_In_ DWORD dwTime
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpDisableHover(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhNfpIconRestoreHoverTimerProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ UINT_PTR idEvent,
|
||||||
|
_In_ DWORD dwTime
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
1577
ProcessHacker/include/phapp.h
Normal file
1577
ProcessHacker/include/phapp.h
Normal file
File diff suppressed because it is too large
Load Diff
34
ProcessHacker/include/phappres.h
Normal file
34
ProcessHacker/include/phappres.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Notes:
|
||||||
|
// * Do not use /* comments */ since ISPP is buggy and it will throw an error.
|
||||||
|
|
||||||
|
#ifndef PH_PHAPPRES_H
|
||||||
|
#define PH_PHAPPRES_H
|
||||||
|
|
||||||
|
#include "phapprev.h"
|
||||||
|
|
||||||
|
#define PHAPP_VERSION_MAJOR 2
|
||||||
|
#define PHAPP_VERSION_MINOR 39
|
||||||
|
#define PHAPP_VERSION_BUILD 0
|
||||||
|
|
||||||
|
#if (PHAPP_VERSION_BUILD == 0)
|
||||||
|
#define TWO_DIGIT_VER 1
|
||||||
|
#else
|
||||||
|
#define THREE_DIGIT_VER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DO_MAKE_STR(x) #x
|
||||||
|
#define MAKE_STR(x) DO_MAKE_STR(x)
|
||||||
|
|
||||||
|
#ifndef ISPP_INVOKED
|
||||||
|
|
||||||
|
#if defined(TWO_DIGIT_VER)
|
||||||
|
#define PHAPP_VERSION_STRING MAKE_STR(PHAPP_VERSION_MAJOR) "." MAKE_STR(PHAPP_VERSION_MINOR) ".0" "." MAKE_STR(PHAPP_VERSION_REVISION)
|
||||||
|
#elif defined(THREE_DIGIT_VER)
|
||||||
|
#define PHAPP_VERSION_STRING MAKE_STR(PHAPP_VERSION_MAJOR) "." MAKE_STR(PHAPP_VERSION_MINOR) "." MAKE_STR(PHAPP_VERSION_BUILD) "." MAKE_STR(PHAPP_VERSION_REVISION)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PHAPP_VERSION_NUMBER PHAPP_VERSION_MAJOR,PHAPP_VERSION_MINOR,PHAPP_VERSION_BUILD,PHAPP_VERSION_REVISION
|
||||||
|
|
||||||
|
#endif // ISPP_INVOKED
|
||||||
|
|
||||||
|
#endif // PHAPPRES_H
|
6
ProcessHacker/include/phapprev_in.h
Normal file
6
ProcessHacker/include/phapprev_in.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef PHAPPREV_H
|
||||||
|
#define PHAPPREV_H
|
||||||
|
|
||||||
|
#define PHAPP_VERSION_REVISION $COMMITS$
|
||||||
|
|
||||||
|
#endif // PHAPPREV_H
|
31
ProcessHacker/include/phfwddef.h
Normal file
31
ProcessHacker/include/phfwddef.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef PH_PHFWDDEF_H
|
||||||
|
#define PH_PHFWDDEF_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Providers
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_ITEM *PPH_PROCESS_ITEM;
|
||||||
|
typedef struct _PH_PROCESS_RECORD *PPH_PROCESS_RECORD;
|
||||||
|
typedef struct _PH_SERVICE_ITEM *PPH_SERVICE_ITEM;
|
||||||
|
typedef struct _PH_NETWORK_ITEM *PPH_NETWORK_ITEM;
|
||||||
|
typedef struct _PH_MODULE_ITEM *PPH_MODULE_ITEM;
|
||||||
|
typedef struct _PH_MODULE_PROVIDER *PPH_MODULE_PROVIDER;
|
||||||
|
typedef struct _PH_THREAD_ITEM *PPH_THREAD_ITEM;
|
||||||
|
typedef struct _PH_THREAD_PROVIDER *PPH_THREAD_PROVIDER;
|
||||||
|
typedef struct _PH_HANDLE_ITEM *PPH_HANDLE_ITEM;
|
||||||
|
typedef struct _PH_HANDLE_PROVIDER *PPH_HANDLE_PROVIDER;
|
||||||
|
typedef struct _PH_MEMORY_ITEM *PPH_MEMORY_ITEM;
|
||||||
|
typedef struct _PH_MEMORY_ITEM_LIST *PPH_MEMORY_ITEM_LIST;
|
||||||
|
|
||||||
|
// uimodels
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_NODE *PPH_PROCESS_NODE;
|
||||||
|
typedef struct _PH_SERVICE_NODE *PPH_SERVICE_NODE;
|
||||||
|
typedef struct _PH_NETWORK_NODE *PPH_NETWORK_NODE;
|
||||||
|
typedef struct _PH_MODULE_NODE *PPH_MODULE_NODE;
|
||||||
|
typedef struct _PH_THREAD_NODE *PPH_THREAD_NODE;
|
||||||
|
typedef struct _PH_HANDLE_NODE *PPH_HANDLE_NODE;
|
||||||
|
typedef struct _PH_MEMORY_NODE *PPH_MEMORY_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
675
ProcessHacker/include/phplug.h
Normal file
675
ProcessHacker/include/phplug.h
Normal file
@ -0,0 +1,675 @@
|
|||||||
|
#ifndef PH_PHPLUG_H
|
||||||
|
#define PH_PHPLUG_H
|
||||||
|
|
||||||
|
#include <extmgr.h>
|
||||||
|
#include <sysinfo.h>
|
||||||
|
#include <miniinfo.h>
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
|
typedef enum _PH_GENERAL_CALLBACK
|
||||||
|
{
|
||||||
|
GeneralCallbackMainWindowShowing = 0, // INT ShowCommand [main thread]
|
||||||
|
GeneralCallbackProcessesUpdated = 1, // [main thread]
|
||||||
|
GeneralCallbackGetProcessHighlightingColor = 2, // PPH_PLUGIN_GET_HIGHLIGHTING_COLOR Data [main thread]
|
||||||
|
GeneralCallbackGetProcessTooltipText = 3, // PPH_PLUGIN_GET_TOOLTIP_TEXT Data [main thread]
|
||||||
|
GeneralCallbackProcessPropertiesInitializing = 4, // PPH_PLUGIN_PROCESS_PROPCONTEXT Data [properties thread]
|
||||||
|
GeneralCallbackMainMenuInitializing = 5, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackNotifyEvent = 6, // PPH_PLUGIN_NOTIFY_EVENT Data [main thread]
|
||||||
|
GeneralCallbackServicePropertiesInitializing = 7, // PPH_PLUGIN_OBJECT_PROPERTIES Data [properties thread]
|
||||||
|
GeneralCallbackHandlePropertiesInitializing = 8, // PPH_PLUGIN_OBJECT_PROPERTIES Data [properties thread]
|
||||||
|
GeneralCallbackProcessMenuInitializing = 9, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackServiceMenuInitializing = 10, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackNetworkMenuInitializing = 11, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackIconMenuInitializing = 12, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackThreadMenuInitializing = 13, // PPH_PLUGIN_MENU_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackModuleMenuInitializing = 14, // PPH_PLUGIN_MENU_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackMemoryMenuInitializing = 15, // PPH_PLUGIN_MENU_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackHandleMenuInitializing = 16, // PPH_PLUGIN_MENU_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackProcessTreeNewInitializing = 17, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackServiceTreeNewInitializing = 18, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackNetworkTreeNewInitializing = 19, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackModuleTreeNewInitializing = 20, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackModuleTreeNewUninitializing = 21, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackThreadTreeNewInitializing = 22, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackThreadTreeNewUninitializing = 23, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackHandleTreeNewInitializing = 24, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackHandleTreeNewUninitializing = 25, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackThreadStackControl = 26, // PPH_PLUGIN_THREAD_STACK_CONTROL Data [properties thread]
|
||||||
|
GeneralCallbackSystemInformationInitializing = 27, // PPH_PLUGIN_SYSINFO_POINTERS Data [system information thread]
|
||||||
|
GeneralCallbackMainWindowTabChanged = 28, // INT NewIndex [main thread]
|
||||||
|
GeneralCallbackMemoryTreeNewInitializing = 29, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackMemoryTreeNewUninitializing = 30, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread]
|
||||||
|
GeneralCallbackMemoryItemListControl = 31, // PPH_PLUGIN_MEMORY_ITEM_LIST_CONTROL Data [properties thread]
|
||||||
|
GeneralCallbackMiniInformationInitializing = 32, // PPH_PLUGIN_MINIINFO_POINTERS Data [main thread]
|
||||||
|
GeneralCallbackMiListSectionMenuInitializing = 33, // PPH_PLUGIN_MENU_INFORMATION Data [main thread]
|
||||||
|
GeneralCallbackMaximum
|
||||||
|
} PH_GENERAL_CALLBACK, *PPH_GENERAL_CALLBACK;
|
||||||
|
|
||||||
|
typedef enum _PH_PLUGIN_CALLBACK
|
||||||
|
{
|
||||||
|
PluginCallbackLoad = 0, // PPH_LIST Parameters [main thread] // list of strings, might be NULL
|
||||||
|
PluginCallbackUnload = 1, // [main thread]
|
||||||
|
PluginCallbackShowOptions = 2, // HWND ParentWindowHandle [main thread]
|
||||||
|
PluginCallbackMenuItem = 3, // PPH_PLUGIN_MENU_ITEM MenuItem [main/properties thread]
|
||||||
|
PluginCallbackTreeNewMessage = 4, // PPH_PLUGIN_TREENEW_MESSAGE Message [main/properties thread]
|
||||||
|
PluginCallbackPhSvcRequest = 5, // PPH_PLUGIN_PHSVC_REQUEST Message [phsvc thread]
|
||||||
|
PluginCallbackMenuHook = 6, // PH_PLUGIN_MENU_HOOK_INFORMATION MenuHookInfo [menu thread]
|
||||||
|
PluginCallbackMaximum
|
||||||
|
} PH_PLUGIN_CALLBACK, *PPH_PLUGIN_CALLBACK;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_GET_HIGHLIGHTING_COLOR
|
||||||
|
{
|
||||||
|
// Parameter is:
|
||||||
|
// PPH_PROCESS_ITEM for GeneralCallbackGetProcessHighlightingColor
|
||||||
|
|
||||||
|
PVOID Parameter;
|
||||||
|
COLORREF BackColor;
|
||||||
|
BOOLEAN Handled;
|
||||||
|
BOOLEAN Cache;
|
||||||
|
} PH_PLUGIN_GET_HIGHLIGHTING_COLOR, *PPH_PLUGIN_GET_HIGHLIGHTING_COLOR;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_GET_TOOLTIP_TEXT
|
||||||
|
{
|
||||||
|
// Parameter is:
|
||||||
|
// PPH_PROCESS_ITEM for GeneralCallbackGetProcessTooltipText
|
||||||
|
|
||||||
|
PVOID Parameter;
|
||||||
|
PPH_STRING_BUILDER StringBuilder;
|
||||||
|
ULONG ValidForMs;
|
||||||
|
} PH_PLUGIN_GET_TOOLTIP_TEXT, *PPH_PLUGIN_GET_TOOLTIP_TEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_PROCESS_PROPCONTEXT
|
||||||
|
{
|
||||||
|
PPH_PROCESS_PROPCONTEXT PropContext;
|
||||||
|
PPH_PROCESS_ITEM ProcessItem;
|
||||||
|
} PH_PLUGIN_PROCESS_PROPCONTEXT, *PPH_PLUGIN_PROCESS_PROPCONTEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_NOTIFY_EVENT
|
||||||
|
{
|
||||||
|
// Parameter is:
|
||||||
|
// PPH_PROCESS_ITEM for Type = PH_NOTIFY_PROCESS_*
|
||||||
|
// PPH_SERVICE_ITEM for Type = PH_NOTIFY_SERVICE_*
|
||||||
|
|
||||||
|
ULONG Type;
|
||||||
|
BOOLEAN Handled;
|
||||||
|
PVOID Parameter;
|
||||||
|
} PH_PLUGIN_NOTIFY_EVENT, *PPH_PLUGIN_NOTIFY_EVENT;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_OBJECT_PROPERTIES
|
||||||
|
{
|
||||||
|
// Parameter is:
|
||||||
|
// PPH_SERVICE_ITEM for GeneralCallbackServicePropertiesInitializing
|
||||||
|
// PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT for GeneralCallbackHandlePropertiesInitializing
|
||||||
|
|
||||||
|
PVOID Parameter;
|
||||||
|
ULONG NumberOfPages;
|
||||||
|
ULONG MaximumNumberOfPages;
|
||||||
|
HPROPSHEETPAGE *Pages;
|
||||||
|
} PH_PLUGIN_OBJECT_PROPERTIES, *PPH_PLUGIN_OBJECT_PROPERTIES;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_HANDLE_PROPERTIES_CONTEXT
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_HANDLE_ITEM HandleItem;
|
||||||
|
} PH_PLUGIN_HANDLE_PROPERTIES_CONTEXT, *PPH_PLUGIN_HANDLE_PROPERTIES_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_EMENU_ITEM *PPH_EMENU_ITEM, *PPH_EMENU;
|
||||||
|
|
||||||
|
#define PH_PLUGIN_MENU_DISALLOW_HOOKS 0x1
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_MENU_INFORMATION
|
||||||
|
{
|
||||||
|
PPH_EMENU Menu;
|
||||||
|
HWND OwnerWindow;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PVOID Reserved[8]; // Reserve space for future expansion of this union
|
||||||
|
} DoNotUse;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG SubMenuIndex;
|
||||||
|
} MainMenu;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_PROCESS_ITEM *Processes;
|
||||||
|
ULONG NumberOfProcesses;
|
||||||
|
} Process;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_SERVICE_ITEM *Services;
|
||||||
|
ULONG NumberOfServices;
|
||||||
|
} Service;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_NETWORK_ITEM *NetworkItems;
|
||||||
|
ULONG NumberOfNetworkItems;
|
||||||
|
} Network;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_THREAD_ITEM *Threads;
|
||||||
|
ULONG NumberOfThreads;
|
||||||
|
} Thread;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_MODULE_ITEM *Modules;
|
||||||
|
ULONG NumberOfModules;
|
||||||
|
} Module;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_MEMORY_NODE *MemoryNodes;
|
||||||
|
ULONG NumberOfMemoryNodes;
|
||||||
|
} Memory;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_HANDLE_ITEM *Handles;
|
||||||
|
ULONG NumberOfHandles;
|
||||||
|
} Handle;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_STRINGREF SectionName;
|
||||||
|
PPH_PROCESS_GROUP ProcessGroup;
|
||||||
|
} MiListSection;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
ULONG Flags;
|
||||||
|
PPH_LIST PluginHookList;
|
||||||
|
} PH_PLUGIN_MENU_INFORMATION, *PPH_PLUGIN_MENU_INFORMATION;
|
||||||
|
|
||||||
|
C_ASSERT(RTL_FIELD_SIZE(PH_PLUGIN_MENU_INFORMATION, u) == RTL_FIELD_SIZE(PH_PLUGIN_MENU_INFORMATION, u.DoNotUse));
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_MENU_HOOK_INFORMATION
|
||||||
|
{
|
||||||
|
PPH_PLUGIN_MENU_INFORMATION MenuInfo;
|
||||||
|
PPH_EMENU SelectedItem;
|
||||||
|
PVOID Context;
|
||||||
|
BOOLEAN Handled;
|
||||||
|
} PH_PLUGIN_MENU_HOOK_INFORMATION, *PPH_PLUGIN_MENU_HOOK_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_TREENEW_INFORMATION
|
||||||
|
{
|
||||||
|
HWND TreeNewHandle;
|
||||||
|
PVOID CmData;
|
||||||
|
PVOID SystemContext; // e.g. PPH_THREADS_CONTEXT
|
||||||
|
} PH_PLUGIN_TREENEW_INFORMATION, *PPH_PLUGIN_TREENEW_INFORMATION;
|
||||||
|
|
||||||
|
typedef enum _PH_PLUGIN_THREAD_STACK_CONTROL_TYPE
|
||||||
|
{
|
||||||
|
PluginThreadStackInitializing,
|
||||||
|
PluginThreadStackUninitializing,
|
||||||
|
PluginThreadStackResolveSymbol,
|
||||||
|
PluginThreadStackGetTooltip,
|
||||||
|
PluginThreadStackWalkStack,
|
||||||
|
PluginThreadStackBeginDefaultWalkStack,
|
||||||
|
PluginThreadStackEndDefaultWalkStack,
|
||||||
|
PluginThreadStackMaximum
|
||||||
|
} PH_PLUGIN_THREAD_STACK_CONTROL_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PH_SYMBOL_PROVIDER *PPH_SYMBOL_PROVIDER;
|
||||||
|
typedef struct _PH_THREAD_STACK_FRAME *PPH_THREAD_STACK_FRAME;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_PLUGIN_WALK_THREAD_STACK_CALLBACK)(
|
||||||
|
_In_ PPH_THREAD_STACK_FRAME StackFrame,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_THREAD_STACK_CONTROL
|
||||||
|
{
|
||||||
|
PH_PLUGIN_THREAD_STACK_CONTROL_TYPE Type;
|
||||||
|
PVOID UniqueKey;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ThreadId;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
PPH_SYMBOL_PROVIDER SymbolProvider;
|
||||||
|
BOOLEAN CustomWalk;
|
||||||
|
} Initializing;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_THREAD_STACK_FRAME StackFrame;
|
||||||
|
PPH_STRING Symbol;
|
||||||
|
} ResolveSymbol;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_THREAD_STACK_FRAME StackFrame;
|
||||||
|
PPH_STRING_BUILDER StringBuilder;
|
||||||
|
} GetTooltip;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
PCLIENT_ID ClientId;
|
||||||
|
ULONG Flags;
|
||||||
|
PPH_PLUGIN_WALK_THREAD_STACK_CALLBACK Callback;
|
||||||
|
PVOID CallbackContext;
|
||||||
|
} WalkStack;
|
||||||
|
} u;
|
||||||
|
} PH_PLUGIN_THREAD_STACK_CONTROL, *PPH_PLUGIN_THREAD_STACK_CONTROL;
|
||||||
|
|
||||||
|
typedef enum _PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL_TYPE
|
||||||
|
{
|
||||||
|
PluginMemoryItemListInitialized,
|
||||||
|
PluginMemoryItemListMaximum
|
||||||
|
} PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL
|
||||||
|
{
|
||||||
|
PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL_TYPE Type;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PPH_MEMORY_ITEM_LIST List;
|
||||||
|
} Initialized;
|
||||||
|
} u;
|
||||||
|
} PH_PLUGIN_MEMORY_ITEM_LIST_CONTROL, *PPH_PLUGIN_MEMORY_ITEM_LIST_CONTROL;
|
||||||
|
|
||||||
|
typedef PPH_SYSINFO_SECTION (NTAPI *PPH_SYSINFO_CREATE_SECTION)(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef PPH_SYSINFO_SECTION (NTAPI *PPH_SYSINFO_FIND_SECTION)(
|
||||||
|
_In_ PPH_STRINGREF Name
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_SYSINFO_ENTER_SECTION_VIEW)(
|
||||||
|
_In_ PPH_SYSINFO_SECTION NewSection
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_SYSINFO_RESTORE_SUMMARY_VIEW)(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_SYSINFO_POINTERS
|
||||||
|
{
|
||||||
|
HWND WindowHandle;
|
||||||
|
PPH_SYSINFO_CREATE_SECTION CreateSection;
|
||||||
|
PPH_SYSINFO_FIND_SECTION FindSection;
|
||||||
|
PPH_SYSINFO_ENTER_SECTION_VIEW EnterSectionView;
|
||||||
|
PPH_SYSINFO_RESTORE_SUMMARY_VIEW RestoreSummaryView;
|
||||||
|
} PH_PLUGIN_SYSINFO_POINTERS, *PPH_PLUGIN_SYSINFO_POINTERS;
|
||||||
|
|
||||||
|
typedef PPH_MINIINFO_SECTION (NTAPI *PPH_MINIINFO_CREATE_SECTION)(
|
||||||
|
_In_ PPH_MINIINFO_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef PPH_MINIINFO_SECTION (NTAPI *PPH_MINIINFO_FIND_SECTION)(
|
||||||
|
_In_ PPH_STRINGREF Name
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef PPH_MINIINFO_LIST_SECTION (NTAPI *PPH_MINIINFO_CREATE_LIST_SECTION)(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_MINIINFO_LIST_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_MINIINFO_POINTERS
|
||||||
|
{
|
||||||
|
HWND WindowHandle;
|
||||||
|
PPH_MINIINFO_CREATE_SECTION CreateSection;
|
||||||
|
PPH_MINIINFO_FIND_SECTION FindSection;
|
||||||
|
PPH_MINIINFO_CREATE_LIST_SECTION CreateListSection;
|
||||||
|
} PH_PLUGIN_MINIINFO_POINTERS, *PPH_PLUGIN_MINIINFO_POINTERS;
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_TREENEW_MESSAGE
|
||||||
|
{
|
||||||
|
HWND TreeNewHandle;
|
||||||
|
PH_TREENEW_MESSAGE Message;
|
||||||
|
PVOID Parameter1;
|
||||||
|
PVOID Parameter2;
|
||||||
|
ULONG SubId;
|
||||||
|
PVOID Context;
|
||||||
|
} PH_PLUGIN_TREENEW_MESSAGE, *PPH_PLUGIN_TREENEW_MESSAGE;
|
||||||
|
|
||||||
|
typedef LONG (NTAPI *PPH_PLUGIN_TREENEW_SORT_FUNCTION)(
|
||||||
|
_In_ PVOID Node1,
|
||||||
|
_In_ PVOID Node2,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *PPHSVC_SERVER_PROBE_BUFFER)(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ ULONG Alignment,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PVOID *Pointer
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *PPHSVC_SERVER_CAPTURE_BUFFER)(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PVOID *CapturedBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *PPHSVC_SERVER_CAPTURE_STRING)(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PPH_STRING *CapturedString
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_PHSVC_REQUEST
|
||||||
|
{
|
||||||
|
ULONG SubId;
|
||||||
|
NTSTATUS ReturnStatus;
|
||||||
|
PVOID InBuffer;
|
||||||
|
ULONG InLength;
|
||||||
|
PVOID OutBuffer;
|
||||||
|
ULONG OutLength;
|
||||||
|
|
||||||
|
PPHSVC_SERVER_PROBE_BUFFER ProbeBuffer;
|
||||||
|
PPHSVC_SERVER_CAPTURE_BUFFER CaptureBuffer;
|
||||||
|
PPHSVC_SERVER_CAPTURE_STRING CaptureString;
|
||||||
|
} PH_PLUGIN_PHSVC_REQUEST, *PPH_PLUGIN_PHSVC_REQUEST;
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPHSVC_CLIENT_FREE_HEAP)(
|
||||||
|
_In_ PVOID Memory
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef PVOID (NTAPI *PPHSVC_CLIENT_CREATE_STRING)(
|
||||||
|
_In_opt_ PVOID String,
|
||||||
|
_In_ SIZE_T Length,
|
||||||
|
_Out_ PPH_RELATIVE_STRINGREF StringRef
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_PHSVC_CLIENT
|
||||||
|
{
|
||||||
|
HANDLE ServerProcessId;
|
||||||
|
PPHSVC_CLIENT_FREE_HEAP FreeHeap;
|
||||||
|
PPHSVC_CLIENT_CREATE_STRING CreateString;
|
||||||
|
} PH_PLUGIN_PHSVC_CLIENT, *PPH_PLUGIN_PHSVC_CLIENT;
|
||||||
|
|
||||||
|
// Plugin structures
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_INFORMATION
|
||||||
|
{
|
||||||
|
PWSTR DisplayName;
|
||||||
|
PWSTR Author;
|
||||||
|
PWSTR Description;
|
||||||
|
PWSTR Url;
|
||||||
|
BOOLEAN HasOptions;
|
||||||
|
BOOLEAN Reserved1[3];
|
||||||
|
PVOID Interface;
|
||||||
|
} PH_PLUGIN_INFORMATION, *PPH_PLUGIN_INFORMATION;
|
||||||
|
|
||||||
|
#define PH_PLUGIN_FLAG_RESERVED 0x1
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_PLUGIN
|
||||||
|
{
|
||||||
|
// Public
|
||||||
|
|
||||||
|
PH_AVL_LINKS Links;
|
||||||
|
|
||||||
|
PVOID Reserved;
|
||||||
|
PVOID DllBase;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
PPH_STRING FileName;
|
||||||
|
ULONG Flags;
|
||||||
|
PH_STRINGREF Name;
|
||||||
|
PH_PLUGIN_INFORMATION Information;
|
||||||
|
|
||||||
|
PH_CALLBACK Callbacks[PluginCallbackMaximum];
|
||||||
|
PH_EM_APP_CONTEXT AppContext;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_PLUGIN, *PPH_PLUGIN;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Plugin API
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PLUGIN
|
||||||
|
NTAPI
|
||||||
|
PhRegisterPlugin(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PVOID DllBase,
|
||||||
|
_Out_opt_ PPH_PLUGIN_INFORMATION *Information
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PLUGIN
|
||||||
|
NTAPI
|
||||||
|
PhFindPlugin(
|
||||||
|
_In_ PWSTR Name
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PLUGIN_INFORMATION
|
||||||
|
NTAPI
|
||||||
|
PhGetPluginInformation(
|
||||||
|
_In_ PPH_PLUGIN Plugin
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_CALLBACK
|
||||||
|
NTAPI
|
||||||
|
PhGetPluginCallback(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ PH_PLUGIN_CALLBACK Callback
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_CALLBACK
|
||||||
|
NTAPI
|
||||||
|
PhGetGeneralCallback(
|
||||||
|
_In_ PH_GENERAL_CALLBACK Callback
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
PhPluginReserveIds(
|
||||||
|
_In_ ULONG Count
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_PLUGIN_MENU_ITEM_DELETE_FUNCTION)(
|
||||||
|
_In_ struct _PH_PLUGIN_MENU_ITEM *MenuItem
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_MENU_ITEM
|
||||||
|
{
|
||||||
|
PPH_PLUGIN Plugin;
|
||||||
|
ULONG Id;
|
||||||
|
ULONG Reserved1;
|
||||||
|
PVOID Context;
|
||||||
|
|
||||||
|
HWND OwnerWindow; // valid only when the menu item is chosen
|
||||||
|
PVOID Reserved2;
|
||||||
|
PVOID Reserved3;
|
||||||
|
PPH_PLUGIN_MENU_ITEM_DELETE_FUNCTION DeleteFunction; // valid only for EMENU-based menu items
|
||||||
|
} PH_PLUGIN_MENU_ITEM, *PPH_PLUGIN_MENU_ITEM;
|
||||||
|
|
||||||
|
// Location
|
||||||
|
#define PH_MENU_ITEM_LOCATION_VIEW 1
|
||||||
|
#define PH_MENU_ITEM_LOCATION_TOOLS 2
|
||||||
|
|
||||||
|
// Id flags (non-functional)
|
||||||
|
#define PH_MENU_ITEM_SUB_MENU 0x80000000
|
||||||
|
#define PH_MENU_ITEM_RETURN_MENU 0x40000000
|
||||||
|
#define PH_MENU_ITEM_VALID_FLAGS 0xc0000000
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
ULONG_PTR
|
||||||
|
NTAPI
|
||||||
|
PhPluginAddMenuItem(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ ULONG_PTR Location,
|
||||||
|
_In_opt_ PWSTR InsertAfter,
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ PWSTR Text,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_PLUGIN_SYSTEM_STATISTICS
|
||||||
|
{
|
||||||
|
PSYSTEM_PERFORMANCE_INFORMATION Performance;
|
||||||
|
|
||||||
|
ULONG NumberOfProcesses;
|
||||||
|
ULONG NumberOfThreads;
|
||||||
|
ULONG NumberOfHandles;
|
||||||
|
|
||||||
|
FLOAT CpuKernelUsage;
|
||||||
|
FLOAT CpuUserUsage;
|
||||||
|
|
||||||
|
PH_UINT64_DELTA IoReadDelta;
|
||||||
|
PH_UINT64_DELTA IoWriteDelta;
|
||||||
|
PH_UINT64_DELTA IoOtherDelta;
|
||||||
|
|
||||||
|
ULONG CommitPages;
|
||||||
|
ULONG PhysicalPages;
|
||||||
|
|
||||||
|
HANDLE MaxCpuProcessId;
|
||||||
|
HANDLE MaxIoProcessId;
|
||||||
|
|
||||||
|
PPH_CIRCULAR_BUFFER_FLOAT CpuKernelHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_FLOAT CpuUserHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_FLOAT *CpusKernelHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_FLOAT *CpusUserHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG64 IoReadHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG64 IoWriteHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG64 IoOtherHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG CommitHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG PhysicalHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG MaxCpuHistory; // ID of max. CPU process
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG MaxIoHistory; // ID of max. I/O process
|
||||||
|
PPH_CIRCULAR_BUFFER_FLOAT MaxCpuUsageHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG64 MaxIoReadOtherHistory;
|
||||||
|
PPH_CIRCULAR_BUFFER_ULONG64 MaxIoWriteHistory;
|
||||||
|
} PH_PLUGIN_SYSTEM_STATISTICS, *PPH_PLUGIN_SYSTEM_STATISTICS;
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhPluginGetSystemStatistics(
|
||||||
|
_Out_ PPH_PLUGIN_SYSTEM_STATISTICS Statistics
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_EMENU_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhPluginCreateEMenuItem(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ PWSTR Text,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhPluginAddMenuHook(
|
||||||
|
_Inout_ PPH_PLUGIN_MENU_INFORMATION MenuInfo,
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhPluginInitializeMenuInfo(
|
||||||
|
_Out_ PPH_PLUGIN_MENU_INFORMATION MenuInfo,
|
||||||
|
_In_opt_ PPH_EMENU Menu,
|
||||||
|
_In_ HWND OwnerWindow,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhPluginTriggerEMenuItem(
|
||||||
|
_In_ PPH_PLUGIN_MENU_INFORMATION MenuInfo,
|
||||||
|
_In_ PPH_EMENU_ITEM Item
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhPluginAddTreeNewColumn(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ PVOID CmData,
|
||||||
|
_In_ PPH_TREENEW_COLUMN Column,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_opt_ PPH_PLUGIN_TREENEW_SORT_FUNCTION SortFunction
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhPluginSetObjectExtension(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType,
|
||||||
|
_In_ ULONG ExtensionSize,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK CreateCallback,
|
||||||
|
_In_opt_ PPH_EM_OBJECT_CALLBACK DeleteCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PVOID
|
||||||
|
NTAPI
|
||||||
|
PhPluginGetObjectExtension(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ PH_EM_OBJECT_TYPE ObjectType
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
struct _PH_NF_ICON *
|
||||||
|
NTAPI
|
||||||
|
PhPluginRegisterIcon(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_ PWSTR Text,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ struct _PH_NF_ICON_REGISTRATION_DATA *RegistrationData
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhPluginEnableTreeNewNotify(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ PVOID CmData
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhPluginQueryPhSvc(
|
||||||
|
_Out_ PPH_PLUGIN_PHSVC_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PhPluginCallPhSvc(
|
||||||
|
_In_ PPH_PLUGIN Plugin,
|
||||||
|
_In_ ULONG SubId,
|
||||||
|
_In_reads_bytes_opt_(InLength) PVOID InBuffer,
|
||||||
|
_In_ ULONG InLength,
|
||||||
|
_Out_writes_bytes_opt_(OutLength) PVOID OutBuffer,
|
||||||
|
_In_ ULONG OutLength
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
238
ProcessHacker/include/phsvc.h
Normal file
238
ProcessHacker/include/phsvc.h
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
#ifndef PH_PHSVC_H
|
||||||
|
#define PH_PHSVC_H
|
||||||
|
|
||||||
|
#include <phsvcapi.h>
|
||||||
|
|
||||||
|
#define PHSVC_SHARED_SECTION_SIZE (512 * 1024)
|
||||||
|
|
||||||
|
// svcmain
|
||||||
|
|
||||||
|
typedef struct _PHSVC_STOP
|
||||||
|
{
|
||||||
|
BOOLEAN Stop;
|
||||||
|
HANDLE Event1;
|
||||||
|
HANDLE Event2;
|
||||||
|
} PHSVC_STOP, *PPHSVC_STOP;
|
||||||
|
|
||||||
|
NTSTATUS PhSvcMain(
|
||||||
|
_In_opt_ PUNICODE_STRING PortName,
|
||||||
|
_In_opt_ PLARGE_INTEGER Timeout,
|
||||||
|
_Inout_opt_ PPHSVC_STOP Stop
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcStop(
|
||||||
|
_Inout_ PPHSVC_STOP Stop
|
||||||
|
);
|
||||||
|
|
||||||
|
// svcclient
|
||||||
|
|
||||||
|
typedef struct _PHSVC_CLIENT
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
PH_EVENT ReadyEvent;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
HANDLE PortHandle;
|
||||||
|
PVOID ClientViewBase;
|
||||||
|
PVOID ClientViewLimit;
|
||||||
|
} PHSVC_CLIENT, *PPHSVC_CLIENT;
|
||||||
|
|
||||||
|
NTSTATUS PhSvcClientInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPHSVC_CLIENT PhSvcCreateClient(
|
||||||
|
_In_opt_ PCLIENT_ID ClientId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPHSVC_CLIENT PhSvcReferenceClientByClientId(
|
||||||
|
_In_ PCLIENT_ID ClientId
|
||||||
|
);
|
||||||
|
|
||||||
|
PPHSVC_CLIENT PhSvcGetCurrentClient(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhSvcAttachClient(
|
||||||
|
_In_ PPHSVC_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcDetachClient(
|
||||||
|
_In_ PPHSVC_CLIENT Client
|
||||||
|
);
|
||||||
|
|
||||||
|
// svcapiport
|
||||||
|
|
||||||
|
typedef struct _PHSVC_THREAD_CONTEXT
|
||||||
|
{
|
||||||
|
PPHSVC_CLIENT CurrentClient;
|
||||||
|
PPHSVC_CLIENT OldClient;
|
||||||
|
} PHSVC_THREAD_CONTEXT, *PPHSVC_THREAD_CONTEXT;
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiPortInitialization(
|
||||||
|
_In_ PUNICODE_STRING PortName
|
||||||
|
);
|
||||||
|
|
||||||
|
PPHSVC_THREAD_CONTEXT PhSvcGetCurrentThreadContext(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcHandleConnectionRequest(
|
||||||
|
_In_ PPORT_MESSAGE PortMessage
|
||||||
|
);
|
||||||
|
|
||||||
|
// svcapi
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *PPHSVC_API_PROCEDURE)(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcDispatchApiCall(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload,
|
||||||
|
_Out_ PHANDLE ReplyPortHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID PhSvcValidateString(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ ULONG Alignment
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcProbeBuffer(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ ULONG Alignment,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PVOID *Pointer
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCaptureBuffer(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PVOID *CapturedBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCaptureString(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PPH_STRING *CapturedString
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCaptureSid(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_Out_ PSID *CapturedSid
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCaptureSecurityDescriptor(
|
||||||
|
_In_ PPH_RELATIVE_STRINGREF String,
|
||||||
|
_In_ BOOLEAN AllowNull,
|
||||||
|
_In_ SECURITY_INFORMATION RequiredInformation,
|
||||||
|
_Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiDefault(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiPlugin(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiExecuteRunAsCommand(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiUnloadDriver(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiControlProcess(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiControlService(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiCreateService(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiChangeServiceConfig(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiChangeServiceConfig2(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiSetTcpEntry(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiControlThread(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiAddAccountRight(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiInvokeRunAsService(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiIssueMemoryListCommand(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiPostMessage(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiSendMessage(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiCreateProcessIgnoreIfeoDebugger(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiSetServiceSecurity(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiLoadDbgHelp(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcApiWriteMiniDumpProcess(
|
||||||
|
_In_ PPHSVC_CLIENT Client,
|
||||||
|
_Inout_ PPHSVC_API_PAYLOAD Payload
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
310
ProcessHacker/include/phsvcapi.h
Normal file
310
ProcessHacker/include/phsvcapi.h
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
#ifndef PH_PHSVCAPI_H
|
||||||
|
#define PH_PHSVCAPI_H
|
||||||
|
|
||||||
|
#define PHSVC_PORT_NAME (L"\\BaseNamedObjects\\PhSvcApiPort")
|
||||||
|
#define PHSVC_WOW64_PORT_NAME (L"\\BaseNamedObjects\\PhSvcWow64ApiPort")
|
||||||
|
|
||||||
|
typedef enum _PHSVC_API_NUMBER
|
||||||
|
{
|
||||||
|
PhSvcPluginApiNumber = 1,
|
||||||
|
PhSvcExecuteRunAsCommandApiNumber = 2,
|
||||||
|
PhSvcUnloadDriverApiNumber = 3,
|
||||||
|
PhSvcControlProcessApiNumber = 4,
|
||||||
|
PhSvcControlServiceApiNumber = 5,
|
||||||
|
PhSvcCreateServiceApiNumber = 6,
|
||||||
|
PhSvcChangeServiceConfigApiNumber = 7,
|
||||||
|
PhSvcChangeServiceConfig2ApiNumber = 8,
|
||||||
|
PhSvcSetTcpEntryApiNumber = 9,
|
||||||
|
PhSvcControlThreadApiNumber = 10,
|
||||||
|
PhSvcAddAccountRightApiNumber = 11,
|
||||||
|
PhSvcInvokeRunAsServiceApiNumber = 12,
|
||||||
|
PhSvcIssueMemoryListCommandApiNumber = 13,
|
||||||
|
PhSvcPostMessageApiNumber = 14,
|
||||||
|
PhSvcSendMessageApiNumber = 15,
|
||||||
|
PhSvcCreateProcessIgnoreIfeoDebuggerApiNumber = 16,
|
||||||
|
PhSvcSetServiceSecurityApiNumber = 17,
|
||||||
|
PhSvcLoadDbgHelpApiNumber = 18, // WOW64 compatible
|
||||||
|
PhSvcWriteMiniDumpProcessApiNumber = 19, // WOW64 compatible
|
||||||
|
PhSvcMaximumApiNumber
|
||||||
|
} PHSVC_API_NUMBER, *PPHSVC_API_NUMBER;
|
||||||
|
|
||||||
|
typedef struct _PHSVC_API_CONNECTINFO
|
||||||
|
{
|
||||||
|
ULONG ServerProcessId;
|
||||||
|
} PHSVC_API_CONNECTINFO, *PPHSVC_API_CONNECTINFO;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_PLUGIN
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF ApiId;
|
||||||
|
ULONG Data[30];
|
||||||
|
} i;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG Data[32];
|
||||||
|
} o;
|
||||||
|
} PHSVC_API_PLUGIN, *PPHSVC_API_PLUGIN;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_EXECUTERUNASCOMMAND
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG ProcessId;
|
||||||
|
PH_RELATIVE_STRINGREF UserName;
|
||||||
|
PH_RELATIVE_STRINGREF Password;
|
||||||
|
ULONG LogonType;
|
||||||
|
ULONG SessionId;
|
||||||
|
PH_RELATIVE_STRINGREF CurrentDirectory;
|
||||||
|
PH_RELATIVE_STRINGREF CommandLine;
|
||||||
|
PH_RELATIVE_STRINGREF FileName;
|
||||||
|
PH_RELATIVE_STRINGREF DesktopName;
|
||||||
|
BOOLEAN UseLinkedToken;
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_EXECUTERUNASCOMMAND, *PPHSVC_API_EXECUTERUNASCOMMAND;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_UNLOADDRIVER
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PVOID BaseAddress;
|
||||||
|
PH_RELATIVE_STRINGREF Name;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_UNLOADDRIVER, *PPHSVC_API_UNLOADDRIVER;
|
||||||
|
|
||||||
|
typedef enum _PHSVC_API_CONTROLPROCESS_COMMAND
|
||||||
|
{
|
||||||
|
PhSvcControlProcessTerminate = 1,
|
||||||
|
PhSvcControlProcessSuspend,
|
||||||
|
PhSvcControlProcessResume,
|
||||||
|
PhSvcControlProcessPriority,
|
||||||
|
PhSvcControlProcessIoPriority
|
||||||
|
} PHSVC_API_CONTROLPROCESS_COMMAND;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CONTROLPROCESS
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PHSVC_API_CONTROLPROCESS_COMMAND Command;
|
||||||
|
ULONG Argument;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_CONTROLPROCESS, *PPHSVC_API_CONTROLPROCESS;
|
||||||
|
|
||||||
|
typedef enum _PHSVC_API_CONTROLSERVICE_COMMAND
|
||||||
|
{
|
||||||
|
PhSvcControlServiceStart = 1,
|
||||||
|
PhSvcControlServiceContinue,
|
||||||
|
PhSvcControlServicePause,
|
||||||
|
PhSvcControlServiceStop,
|
||||||
|
PhSvcControlServiceDelete
|
||||||
|
} PHSVC_API_CONTROLSERVICE_COMMAND;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CONTROLSERVICE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
PHSVC_API_CONTROLSERVICE_COMMAND Command;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_CONTROLSERVICE, *PPHSVC_API_CONTROLSERVICE;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CREATESERVICE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
// ServiceName is the only required string.
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
PH_RELATIVE_STRINGREF DisplayName;
|
||||||
|
ULONG ServiceType;
|
||||||
|
ULONG StartType;
|
||||||
|
ULONG ErrorControl;
|
||||||
|
PH_RELATIVE_STRINGREF BinaryPathName;
|
||||||
|
PH_RELATIVE_STRINGREF LoadOrderGroup;
|
||||||
|
PH_RELATIVE_STRINGREF Dependencies;
|
||||||
|
PH_RELATIVE_STRINGREF ServiceStartName;
|
||||||
|
PH_RELATIVE_STRINGREF Password;
|
||||||
|
BOOLEAN TagIdSpecified;
|
||||||
|
} i;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG TagId;
|
||||||
|
} o;
|
||||||
|
} PHSVC_API_CREATESERVICE, *PPHSVC_API_CREATESERVICE;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CHANGESERVICECONFIG
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
ULONG ServiceType;
|
||||||
|
ULONG StartType;
|
||||||
|
ULONG ErrorControl;
|
||||||
|
PH_RELATIVE_STRINGREF BinaryPathName;
|
||||||
|
PH_RELATIVE_STRINGREF LoadOrderGroup;
|
||||||
|
PH_RELATIVE_STRINGREF Dependencies;
|
||||||
|
PH_RELATIVE_STRINGREF ServiceStartName;
|
||||||
|
PH_RELATIVE_STRINGREF Password;
|
||||||
|
PH_RELATIVE_STRINGREF DisplayName;
|
||||||
|
BOOLEAN TagIdSpecified;
|
||||||
|
} i;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG TagId;
|
||||||
|
} o;
|
||||||
|
} PHSVC_API_CHANGESERVICECONFIG, *PPHSVC_API_CHANGESERVICECONFIG;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CHANGESERVICECONFIG2
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
ULONG InfoLevel;
|
||||||
|
PH_RELATIVE_STRINGREF Info;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_CHANGESERVICECONFIG2, *PPHSVC_API_CHANGESERVICECONFIG2;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_SETTCPENTRY
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG State;
|
||||||
|
ULONG LocalAddress;
|
||||||
|
ULONG LocalPort;
|
||||||
|
ULONG RemoteAddress;
|
||||||
|
ULONG RemotePort;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_SETTCPENTRY, *PPHSVC_API_SETTCPENTRY;
|
||||||
|
|
||||||
|
typedef enum _PHSVC_API_CONTROLTHREAD_COMMAND
|
||||||
|
{
|
||||||
|
PhSvcControlThreadTerminate = 1,
|
||||||
|
PhSvcControlThreadSuspend,
|
||||||
|
PhSvcControlThreadResume,
|
||||||
|
PhSvcControlThreadIoPriority
|
||||||
|
} PHSVC_API_CONTROLTHREAD_COMMAND;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CONTROLTHREAD
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HANDLE ThreadId;
|
||||||
|
PHSVC_API_CONTROLTHREAD_COMMAND Command;
|
||||||
|
ULONG Argument;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_CONTROLTHREAD, *PPHSVC_API_CONTROLTHREAD;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_ADDACCOUNTRIGHT
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF AccountSid;
|
||||||
|
PH_RELATIVE_STRINGREF UserRight;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_ADDACCOUNTRIGHT, *PPHSVC_API_ADDACCOUNTRIGHT;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_ISSUEMEMORYLISTCOMMAND
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
SYSTEM_MEMORY_LIST_COMMAND Command;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_ISSUEMEMORYLISTCOMMAND, *PPHSVC_API_ISSUEMEMORYLISTCOMMAND;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_POSTMESSAGE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HWND hWnd;
|
||||||
|
UINT Msg;
|
||||||
|
WPARAM wParam;
|
||||||
|
LPARAM lParam;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_POSTMESSAGE, *PPHSVC_API_POSTMESSAGE;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF FileName;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER, *PPHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_SETSERVICESECURITY
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF ServiceName;
|
||||||
|
SECURITY_INFORMATION SecurityInformation;
|
||||||
|
PH_RELATIVE_STRINGREF SecurityDescriptor;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_SETSERVICESECURITY, *PPHSVC_API_SETSERVICESECURITY;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_LOADDBGHELP
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PH_RELATIVE_STRINGREF DbgHelpPath;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_LOADDBGHELP, *PPHSVC_API_LOADDBGHELP;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_WRITEMINIDUMPPROCESS
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG LocalProcessHandle;
|
||||||
|
ULONG ProcessId;
|
||||||
|
ULONG LocalFileHandle;
|
||||||
|
ULONG DumpType;
|
||||||
|
} i;
|
||||||
|
} PHSVC_API_WRITEMINIDUMPPROCESS, *PPHSVC_API_WRITEMINIDUMPPROCESS;
|
||||||
|
|
||||||
|
typedef union _PHSVC_API_PAYLOAD
|
||||||
|
{
|
||||||
|
PHSVC_API_CONNECTINFO ConnectInfo;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
PHSVC_API_NUMBER ApiNumber;
|
||||||
|
NTSTATUS ReturnStatus;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PHSVC_API_PLUGIN Plugin;
|
||||||
|
PHSVC_API_EXECUTERUNASCOMMAND ExecuteRunAsCommand;
|
||||||
|
PHSVC_API_UNLOADDRIVER UnloadDriver;
|
||||||
|
PHSVC_API_CONTROLPROCESS ControlProcess;
|
||||||
|
PHSVC_API_CONTROLSERVICE ControlService;
|
||||||
|
PHSVC_API_CREATESERVICE CreateService;
|
||||||
|
PHSVC_API_CHANGESERVICECONFIG ChangeServiceConfig;
|
||||||
|
PHSVC_API_CHANGESERVICECONFIG2 ChangeServiceConfig2;
|
||||||
|
PHSVC_API_SETTCPENTRY SetTcpEntry;
|
||||||
|
PHSVC_API_CONTROLTHREAD ControlThread;
|
||||||
|
PHSVC_API_ADDACCOUNTRIGHT AddAccountRight;
|
||||||
|
PHSVC_API_ISSUEMEMORYLISTCOMMAND IssueMemoryListCommand;
|
||||||
|
PHSVC_API_POSTMESSAGE PostMessage;
|
||||||
|
PHSVC_API_CREATEPROCESSIGNOREIFEODEBUGGER CreateProcessIgnoreIfeoDebugger;
|
||||||
|
PHSVC_API_SETSERVICESECURITY SetServiceSecurity;
|
||||||
|
PHSVC_API_LOADDBGHELP LoadDbgHelp;
|
||||||
|
PHSVC_API_WRITEMINIDUMPPROCESS WriteMiniDumpProcess;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
} PHSVC_API_PAYLOAD, *PPHSVC_API_PAYLOAD;
|
||||||
|
|
||||||
|
typedef struct _PHSVC_API_MSG
|
||||||
|
{
|
||||||
|
PORT_MESSAGE h;
|
||||||
|
PHSVC_API_PAYLOAD p;
|
||||||
|
} PHSVC_API_MSG, *PPHSVC_API_MSG;
|
||||||
|
|
||||||
|
typedef struct _PHSVC_API_MSG64
|
||||||
|
{
|
||||||
|
PORT_MESSAGE64 h;
|
||||||
|
PHSVC_API_PAYLOAD p;
|
||||||
|
} PHSVC_API_MSG64, *PPHSVC_API_MSG64;
|
||||||
|
|
||||||
|
C_ASSERT(FIELD_OFFSET(PHSVC_API_PAYLOAD, u) == 8);
|
||||||
|
C_ASSERT(sizeof(PHSVC_API_MSG) <= PORT_TOTAL_MAXIMUM_MESSAGE_LENGTH);
|
||||||
|
C_ASSERT(sizeof(PHSVC_API_MSG64) <= PORT_TOTAL_MAXIMUM_MESSAGE_LENGTH);
|
||||||
|
|
||||||
|
#endif
|
155
ProcessHacker/include/phsvccl.h
Normal file
155
ProcessHacker/include/phsvccl.h
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#ifndef PH_PHSVCCL_H
|
||||||
|
#define PH_PHSVCCL_H
|
||||||
|
|
||||||
|
#include <phsvcapi.h>
|
||||||
|
|
||||||
|
extern HANDLE PhSvcClServerProcessId;
|
||||||
|
|
||||||
|
NTSTATUS PhSvcConnectToServer(
|
||||||
|
_In_ PUNICODE_STRING PortName,
|
||||||
|
_In_opt_ SIZE_T PortSectionSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcDisconnectFromServer(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSvcpFreeHeap(
|
||||||
|
_In_ PVOID Memory
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID PhSvcpCreateString(
|
||||||
|
_In_opt_ PVOID String,
|
||||||
|
_In_ SIZE_T Length,
|
||||||
|
_Out_ PPH_RELATIVE_STRINGREF StringRef
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallPlugin(
|
||||||
|
_In_ PPH_STRINGREF ApiId,
|
||||||
|
_In_reads_bytes_opt_(InLength) PVOID InBuffer,
|
||||||
|
_In_ ULONG InLength,
|
||||||
|
_Out_writes_bytes_opt_(OutLength) PVOID OutBuffer,
|
||||||
|
_In_ ULONG OutLength
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallExecuteRunAsCommand(
|
||||||
|
_In_ PPH_RUNAS_SERVICE_PARAMETERS Parameters
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallUnloadDriver(
|
||||||
|
_In_opt_ PVOID BaseAddress,
|
||||||
|
_In_opt_ PWSTR Name
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallControlProcess(
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PHSVC_API_CONTROLPROCESS_COMMAND Command,
|
||||||
|
_In_ ULONG Argument
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallControlService(
|
||||||
|
_In_ PWSTR ServiceName,
|
||||||
|
_In_ PHSVC_API_CONTROLSERVICE_COMMAND Command
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallCreateService(
|
||||||
|
_In_ PWSTR ServiceName,
|
||||||
|
_In_opt_ PWSTR DisplayName,
|
||||||
|
_In_ ULONG ServiceType,
|
||||||
|
_In_ ULONG StartType,
|
||||||
|
_In_ ULONG ErrorControl,
|
||||||
|
_In_opt_ PWSTR BinaryPathName,
|
||||||
|
_In_opt_ PWSTR LoadOrderGroup,
|
||||||
|
_Out_opt_ PULONG TagId,
|
||||||
|
_In_opt_ PWSTR Dependencies,
|
||||||
|
_In_opt_ PWSTR ServiceStartName,
|
||||||
|
_In_opt_ PWSTR Password
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS PhSvcCallChangeServiceConfig(
|
||||||
|
_In_ PWSTR ServiceName,
|
||||||
|
_In_ ULONG ServiceType,
|
||||||
|
_In_ ULONG StartType,
|
||||||
|
_In_ ULONG ErrorControl,
|
||||||
|
_In_opt_ PWSTR BinaryPathName,
|
||||||
|
_In_opt_ PWSTR LoadOrderGroup,
|
||||||
|
_Out_opt_ PULONG TagId,
|
||||||
|
_In_opt_ PWSTR Dependencies,
|
||||||
|
_In_opt_ PWSTR ServiceStartName,
|
||||||
|
_In_opt_ PWSTR Password,
|
||||||
|
_In_opt_ PWSTR DisplayName
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS PhSvcCallChangeServiceConfig2(
|
||||||
|
_In_ PWSTR ServiceName,
|
||||||
|
_In_ ULONG InfoLevel,
|
||||||
|
_In_ PVOID Info
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallSetTcpEntry(
|
||||||
|
_In_ PVOID TcpRow
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallControlThread(
|
||||||
|
_In_ HANDLE ThreadId,
|
||||||
|
_In_ PHSVC_API_CONTROLTHREAD_COMMAND Command,
|
||||||
|
_In_ ULONG Argument
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallAddAccountRight(
|
||||||
|
_In_ PSID AccountSid,
|
||||||
|
_In_ PUNICODE_STRING UserRight
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallInvokeRunAsService(
|
||||||
|
_In_ PPH_RUNAS_SERVICE_PARAMETERS Parameters
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallIssueMemoryListCommand(
|
||||||
|
_In_ SYSTEM_MEMORY_LIST_COMMAND Command
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS PhSvcCallPostMessage(
|
||||||
|
_In_opt_ HWND hWnd,
|
||||||
|
_In_ UINT Msg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
NTSTATUS PhSvcCallSendMessage(
|
||||||
|
_In_opt_ HWND hWnd,
|
||||||
|
_In_ UINT Msg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallCreateProcessIgnoreIfeoDebugger(
|
||||||
|
_In_ PWSTR FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallSetServiceSecurity(
|
||||||
|
_In_ PWSTR ServiceName,
|
||||||
|
_In_ SECURITY_INFORMATION SecurityInformation,
|
||||||
|
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallLoadDbgHelp(
|
||||||
|
_In_ PWSTR DbgHelpPath
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSvcCallWriteMiniDumpProcess(
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ HANDLE FileHandle,
|
||||||
|
_In_ ULONG DumpType
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
213
ProcessHacker/include/phuisup.h
Normal file
213
ProcessHacker/include/phuisup.h
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
#ifndef PH_PHUISUP_H
|
||||||
|
#define PH_PHUISUP_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// Common state highlighting support
|
||||||
|
|
||||||
|
typedef struct _PH_SH_STATE
|
||||||
|
{
|
||||||
|
PH_ITEM_STATE State;
|
||||||
|
HANDLE StateListHandle;
|
||||||
|
ULONG TickCount;
|
||||||
|
} PH_SH_STATE, *PPH_SH_STATE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
FORCEINLINE VOID PhChangeShStateTn(
|
||||||
|
_Inout_ PPH_TREENEW_NODE Node,
|
||||||
|
_Inout_ PPH_SH_STATE ShState,
|
||||||
|
_Inout_ PPH_POINTER_LIST *StateList,
|
||||||
|
_In_ PH_ITEM_STATE NewState,
|
||||||
|
_In_ COLORREF NewTempBackColor,
|
||||||
|
_In_opt_ HWND TreeNewHandleForUpdate
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!*StateList)
|
||||||
|
*StateList = PhCreatePointerList(4);
|
||||||
|
|
||||||
|
if (ShState->State == NormalItemState)
|
||||||
|
ShState->StateListHandle = PhAddItemPointerList(*StateList, Node);
|
||||||
|
|
||||||
|
ShState->TickCount = GetTickCount();
|
||||||
|
ShState->State = NewState;
|
||||||
|
|
||||||
|
Node->UseTempBackColor = TRUE;
|
||||||
|
Node->TempBackColor = NewTempBackColor;
|
||||||
|
|
||||||
|
if (TreeNewHandleForUpdate)
|
||||||
|
TreeNew_InvalidateNode(TreeNewHandleForUpdate, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PH_TICK_SH_STATE_TN(NodeType, ShStateFieldName, StateList, RemoveFunction, HighlightingDuration, TreeNewHandleForUpdate, Invalidate, FullyInvalidated, ...) \
|
||||||
|
do { \
|
||||||
|
NodeType *node; \
|
||||||
|
ULONG enumerationKey = 0; \
|
||||||
|
ULONG tickCount; \
|
||||||
|
BOOLEAN preferFullInvalidate; \
|
||||||
|
HANDLE stateListHandle; \
|
||||||
|
BOOLEAN redrawDisabled = FALSE; \
|
||||||
|
BOOLEAN needsFullInvalidate = FALSE; \
|
||||||
|
\
|
||||||
|
if (!StateList || StateList->Count == 0) \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
tickCount = GetTickCount(); \
|
||||||
|
preferFullInvalidate = StateList->Count > 8; \
|
||||||
|
\
|
||||||
|
while (PhEnumPointerList(StateList, &enumerationKey, &node)) \
|
||||||
|
{ \
|
||||||
|
if (PhRoundNumber(tickCount - node->ShStateFieldName.TickCount, 100) < (HighlightingDuration)) \
|
||||||
|
continue; \
|
||||||
|
\
|
||||||
|
stateListHandle = node->ShStateFieldName.StateListHandle; \
|
||||||
|
\
|
||||||
|
if (node->ShStateFieldName.State == NewItemState) \
|
||||||
|
{ \
|
||||||
|
node->ShStateFieldName.State = NormalItemState; \
|
||||||
|
((PPH_TREENEW_NODE)node)->UseTempBackColor = FALSE; \
|
||||||
|
if (Invalidate) \
|
||||||
|
{ \
|
||||||
|
if (preferFullInvalidate) \
|
||||||
|
{ \
|
||||||
|
needsFullInvalidate = TRUE; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
TreeNew_InvalidateNode(TreeNewHandleForUpdate, node); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (node->ShStateFieldName.State == RemovingItemState) \
|
||||||
|
{ \
|
||||||
|
if (TreeNewHandleForUpdate) \
|
||||||
|
{ \
|
||||||
|
if (!redrawDisabled) \
|
||||||
|
{ \
|
||||||
|
TreeNew_SetRedraw((TreeNewHandleForUpdate), FALSE); \
|
||||||
|
redrawDisabled = TRUE; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
RemoveFunction(node, __VA_ARGS__); \
|
||||||
|
needsFullInvalidate = TRUE; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
PhRemoveItemPointerList(StateList, stateListHandle); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (TreeNewHandleForUpdate) \
|
||||||
|
{ \
|
||||||
|
if (redrawDisabled) \
|
||||||
|
TreeNew_SetRedraw((TreeNewHandleForUpdate), TRUE); \
|
||||||
|
if (needsFullInvalidate) \
|
||||||
|
{ \
|
||||||
|
InvalidateRect((TreeNewHandleForUpdate), NULL, FALSE); \
|
||||||
|
if (FullyInvalidated) \
|
||||||
|
*((PBOOLEAN)FullyInvalidated) = TRUE; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// Provider event queues
|
||||||
|
|
||||||
|
typedef enum _PH_PROVIDER_EVENT_TYPE
|
||||||
|
{
|
||||||
|
ProviderAddedEvent = 1,
|
||||||
|
ProviderModifiedEvent = 2,
|
||||||
|
ProviderRemovedEvent = 3
|
||||||
|
} PH_PROVIDER_EVENT_TYPE;
|
||||||
|
|
||||||
|
typedef struct _PH_PROVIDER_EVENT
|
||||||
|
{
|
||||||
|
ULONG_PTR TypeAndObject;
|
||||||
|
ULONG RunId;
|
||||||
|
} PH_PROVIDER_EVENT, *PPH_PROVIDER_EVENT;
|
||||||
|
|
||||||
|
#define PH_PROVIDER_EVENT_TYPE_MASK 0x3
|
||||||
|
#define PH_PROVIDER_EVENT_OBJECT_MASK (~(ULONG_PTR)0x3)
|
||||||
|
#define PH_PROVIDER_EVENT_TYPE(Event) ((ULONG)(Event).TypeAndObject & PH_PROVIDER_EVENT_TYPE_MASK)
|
||||||
|
#define PH_PROVIDER_EVENT_OBJECT(Event) ((PVOID)((Event).TypeAndObject & PH_PROVIDER_EVENT_OBJECT_MASK))
|
||||||
|
|
||||||
|
typedef struct _PH_PROVIDER_EVENT_QUEUE
|
||||||
|
{
|
||||||
|
PH_ARRAY Array;
|
||||||
|
PH_QUEUED_LOCK Lock;
|
||||||
|
} PH_PROVIDER_EVENT_QUEUE, *PPH_PROVIDER_EVENT_QUEUE;
|
||||||
|
|
||||||
|
FORCEINLINE VOID PhInitializeProviderEventQueue(
|
||||||
|
_Out_ PPH_PROVIDER_EVENT_QUEUE EventQueue,
|
||||||
|
_In_ SIZE_T InitialCapacity
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PhInitializeArray(&EventQueue->Array, sizeof(PH_PROVIDER_EVENT), InitialCapacity);
|
||||||
|
PhInitializeQueuedLock(&EventQueue->Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE VOID PhDeleteProviderEventQueue(
|
||||||
|
_Inout_ PPH_PROVIDER_EVENT_QUEUE EventQueue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_PROVIDER_EVENT events;
|
||||||
|
SIZE_T i;
|
||||||
|
|
||||||
|
events = EventQueue->Array.Items;
|
||||||
|
|
||||||
|
for (i = 0; i < EventQueue->Array.Count; i++)
|
||||||
|
{
|
||||||
|
if (PH_PROVIDER_EVENT_TYPE(events[i]) == ProviderAddedEvent)
|
||||||
|
PhDereferenceObject(PH_PROVIDER_EVENT_OBJECT(events[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
PhDeleteArray(&EventQueue->Array);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE VOID PhPushProviderEventQueue(
|
||||||
|
_Inout_ PPH_PROVIDER_EVENT_QUEUE EventQueue,
|
||||||
|
_In_ PH_PROVIDER_EVENT_TYPE Type,
|
||||||
|
_In_opt_ PVOID Object,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PH_PROVIDER_EVENT event;
|
||||||
|
|
||||||
|
assert(!(PtrToUlong(Object) & PH_PROVIDER_EVENT_TYPE_MASK));
|
||||||
|
event.TypeAndObject = (ULONG_PTR)Object | Type;
|
||||||
|
event.RunId = RunId;
|
||||||
|
|
||||||
|
PhAcquireQueuedLockExclusive(&EventQueue->Lock);
|
||||||
|
PhAddItemArray(&EventQueue->Array, &event);
|
||||||
|
PhReleaseQueuedLockExclusive(&EventQueue->Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE PPH_PROVIDER_EVENT PhFlushProviderEventQueue(
|
||||||
|
_Inout_ PPH_PROVIDER_EVENT_QUEUE EventQueue,
|
||||||
|
_In_ ULONG UpToRunId,
|
||||||
|
_Out_ PULONG Count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PPH_PROVIDER_EVENT availableEvents;
|
||||||
|
PPH_PROVIDER_EVENT events = NULL;
|
||||||
|
SIZE_T count;
|
||||||
|
|
||||||
|
PhAcquireQueuedLockExclusive(&EventQueue->Lock);
|
||||||
|
availableEvents = EventQueue->Array.Items;
|
||||||
|
|
||||||
|
for (count = 0; count < EventQueue->Array.Count; count++)
|
||||||
|
{
|
||||||
|
if ((LONG)(UpToRunId - availableEvents[count].RunId) < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count != 0)
|
||||||
|
{
|
||||||
|
events = PhAllocateCopy(availableEvents, count * sizeof(PH_PROVIDER_EVENT));
|
||||||
|
PhRemoveItemsArray(&EventQueue->Array, 0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
PhReleaseQueuedLockExclusive(&EventQueue->Lock);
|
||||||
|
|
||||||
|
*Count = (ULONG)count;
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
32
ProcessHacker/include/procgrp.h
Normal file
32
ProcessHacker/include/procgrp.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef PH_PROCGRP_H
|
||||||
|
#define PH_PROCGRP_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_PROCESS_GROUP
|
||||||
|
{
|
||||||
|
PPH_PROCESS_ITEM Representative; // An element of Processes (no extra reference added)
|
||||||
|
PPH_LIST Processes; // List of PPH_PROCESS_ITEM
|
||||||
|
HWND WindowHandle; // Window handle of representative
|
||||||
|
} PH_PROCESS_GROUP, *PPH_PROCESS_GROUP;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_SORT_LIST_FUNCTION)(
|
||||||
|
_In_ PPH_LIST List,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#define PH_GROUP_PROCESSES_DONT_GROUP 0x1
|
||||||
|
#define PH_GROUP_PROCESSES_FILE_PATH 0x2
|
||||||
|
|
||||||
|
PPH_LIST PhCreateProcessGroupList(
|
||||||
|
_In_opt_ PPH_SORT_LIST_FUNCTION SortListFunction, // Sort a list of PPH_PROCESS_NODE
|
||||||
|
_In_opt_ PVOID Context,
|
||||||
|
_In_ ULONG MaximumGroups,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhFreeProcessGroupList(
|
||||||
|
_In_ PPH_LIST List
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
31
ProcessHacker/include/procmtgn.h
Normal file
31
ProcessHacker/include/procmtgn.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef PH_PROCMITIGATION_H
|
||||||
|
#define PH_PROCMITIGATION_H
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_MITIGATION_POLICY_ALL_INFORMATION
|
||||||
|
{
|
||||||
|
PVOID Pointers[MaxProcessMitigationPolicy];
|
||||||
|
PROCESS_MITIGATION_DEP_POLICY DEPPolicy;
|
||||||
|
PROCESS_MITIGATION_ASLR_POLICY ASLRPolicy;
|
||||||
|
PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY StrictHandleCheckPolicy;
|
||||||
|
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY SystemCallDisablePolicy;
|
||||||
|
PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY ExtensionPointDisablePolicy;
|
||||||
|
PROCESS_MITIGATION_DYNAMIC_CODE_POLICY DynamicCodePolicy;
|
||||||
|
PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY ControlFlowGuardPolicy;
|
||||||
|
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY SignaturePolicy;
|
||||||
|
PROCESS_MITIGATION_FONT_DISABLE_POLICY FontDisablePolicy;
|
||||||
|
PROCESS_MITIGATION_IMAGE_LOAD_POLICY ImageLoadPolicy;
|
||||||
|
} PH_PROCESS_MITIGATION_POLICY_ALL_INFORMATION, *PPH_PROCESS_MITIGATION_POLICY_ALL_INFORMATION;
|
||||||
|
|
||||||
|
NTSTATUS PhGetProcessMitigationPolicy(
|
||||||
|
_In_ HANDLE ProcessHandle,
|
||||||
|
_Out_ PPH_PROCESS_MITIGATION_POLICY_ALL_INFORMATION Information
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhDescribeProcessMitigationPolicy(
|
||||||
|
_In_ PROCESS_MITIGATION_POLICY Policy,
|
||||||
|
_In_ PVOID Data,
|
||||||
|
_Out_opt_ PPH_STRING *ShortDescription,
|
||||||
|
_Out_opt_ PPH_STRING *LongDescription
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
341
ProcessHacker/include/procprpp.h
Normal file
341
ProcessHacker/include/procprpp.h
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
#ifndef PH_PROCPRPP_H
|
||||||
|
#define PH_PROCPRPP_H
|
||||||
|
|
||||||
|
#include <thrdlist.h>
|
||||||
|
#include <modlist.h>
|
||||||
|
#include <hndllist.h>
|
||||||
|
#include <memlist.h>
|
||||||
|
#include <memprv.h>
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_PROPSHEETCONTEXT
|
||||||
|
{
|
||||||
|
WNDPROC OldWndProc;
|
||||||
|
PH_LAYOUT_MANAGER LayoutManager;
|
||||||
|
PPH_LAYOUT_ITEM TabPageItem;
|
||||||
|
BOOLEAN LayoutInitialized;
|
||||||
|
} PH_PROCESS_PROPSHEETCONTEXT, *PPH_PROCESS_PROPSHEETCONTEXT;
|
||||||
|
|
||||||
|
VOID NTAPI PhpProcessPropContextDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
INT CALLBACK PhpPropSheetProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_PROCESS_PROPSHEETCONTEXT PhpGetPropSheetContext(
|
||||||
|
_In_ HWND hwnd
|
||||||
|
);
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhpPropSheetWndProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhpProcessPropPageContextDeleteProcedure(
|
||||||
|
_In_ PVOID Object,
|
||||||
|
_In_ ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
INT CALLBACK PhpStandardPropPageProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ LPPROPSHEETPAGE ppsp
|
||||||
|
);
|
||||||
|
|
||||||
|
FORCEINLINE BOOLEAN PhpPropPageDlgProcHeader(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ LPARAM lParam,
|
||||||
|
_Out_ LPPROPSHEETPAGE *PropSheetPage,
|
||||||
|
_Out_ PPH_PROCESS_PROPPAGECONTEXT *PropPageContext,
|
||||||
|
_Out_ PPH_PROCESS_ITEM *ProcessItem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LPPROPSHEETPAGE propSheetPage;
|
||||||
|
PPH_PROCESS_PROPPAGECONTEXT propPageContext;
|
||||||
|
|
||||||
|
if (uMsg == WM_INITDIALOG)
|
||||||
|
{
|
||||||
|
// Save the context.
|
||||||
|
SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
propSheetPage = (LPPROPSHEETPAGE)GetProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
|
||||||
|
if (!propSheetPage)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*PropSheetPage = propSheetPage;
|
||||||
|
*PropPageContext = propPageContext = (PPH_PROCESS_PROPPAGECONTEXT)propSheetPage->lParam;
|
||||||
|
*ProcessItem = propPageContext->PropContext->ProcessItem;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE VOID PhpPropPageDlgProcDestroy(
|
||||||
|
_In_ HWND hwndDlg
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RemoveProp(hwndDlg, PhMakeContextAtom());
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SET_BUTTON_ICON(Id, Icon) \
|
||||||
|
SendMessage(GetDlgItem(hwndDlg, (Id)), BM_SETIMAGE, IMAGE_ICON, (LPARAM)(Icon))
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessGeneralDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessStatisticsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessPerformanceDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessThreadsDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS NTAPI PhpOpenProcessTokenForPage(
|
||||||
|
_Out_ PHANDLE Handle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessTokenHookProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessModulesDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessMemoryDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessEnvironmentDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessHandlesDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS NTAPI PhpOpenProcessJobForPage(
|
||||||
|
_Out_ PHANDLE Handle,
|
||||||
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessJobHookProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhpProcessServicesDlgProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
extern PH_STRINGREF PhpLoadingText;
|
||||||
|
|
||||||
|
#define WM_PH_THREADS_UPDATED (WM_APP + 200)
|
||||||
|
#define WM_PH_THREAD_SELECTION_CHANGED (WM_APP + 201)
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_THREADS_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_THREAD_PROVIDER Provider;
|
||||||
|
PH_CALLBACK_REGISTRATION ProviderRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION AddedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION ModifiedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION RemovedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION UpdatedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION LoadingStateChangedEventRegistration;
|
||||||
|
|
||||||
|
HWND WindowHandle;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PH_THREAD_LIST_CONTEXT ListContext;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HWND Private; // phapppub
|
||||||
|
HWND TreeNewHandle; // phapppub
|
||||||
|
} PublicUse;
|
||||||
|
};
|
||||||
|
PH_PROVIDER_EVENT_QUEUE EventQueue;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_THREADS_CONTEXT, *PPH_THREADS_CONTEXT;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#define WM_PH_MODULES_UPDATED (WM_APP + 210)
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MODULES_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_MODULE_PROVIDER Provider;
|
||||||
|
PH_PROVIDER_REGISTRATION ProviderRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION AddedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION ModifiedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION RemovedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION UpdatedEventRegistration;
|
||||||
|
|
||||||
|
HWND WindowHandle;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PH_MODULE_LIST_CONTEXT ListContext;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HWND Private; // phapppub
|
||||||
|
HWND TreeNewHandle; // phapppub
|
||||||
|
} PublicUse;
|
||||||
|
};
|
||||||
|
PH_PROVIDER_EVENT_QUEUE EventQueue;
|
||||||
|
NTSTATUS LastRunStatus;
|
||||||
|
PPH_STRING ErrorMessage;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MODULES_CONTEXT, *PPH_MODULES_CONTEXT;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#define WM_PH_HANDLES_UPDATED (WM_APP + 220)
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_HANDLES_CONTEXT
|
||||||
|
{
|
||||||
|
PPH_HANDLE_PROVIDER Provider;
|
||||||
|
PH_PROVIDER_REGISTRATION ProviderRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION AddedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION ModifiedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION RemovedEventRegistration;
|
||||||
|
PH_CALLBACK_REGISTRATION UpdatedEventRegistration;
|
||||||
|
|
||||||
|
HWND WindowHandle;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PH_HANDLE_LIST_CONTEXT ListContext;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HWND Private; // phapppub
|
||||||
|
HWND TreeNewHandle; // phapppub
|
||||||
|
} PublicUse;
|
||||||
|
};
|
||||||
|
PH_PROVIDER_EVENT_QUEUE EventQueue;
|
||||||
|
BOOLEAN SelectedHandleProtected;
|
||||||
|
BOOLEAN SelectedHandleInherit;
|
||||||
|
NTSTATUS LastRunStatus;
|
||||||
|
PPH_STRING ErrorMessage;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_HANDLES_CONTEXT, *PPH_HANDLES_CONTEXT;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_MEMORY_CONTEXT
|
||||||
|
{
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HWND WindowHandle;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PH_MEMORY_LIST_CONTEXT ListContext;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
HWND Private; // phapppub
|
||||||
|
HWND TreeNewHandle; // phapppub
|
||||||
|
} PublicUse;
|
||||||
|
};
|
||||||
|
PH_MEMORY_ITEM_LIST MemoryItemList;
|
||||||
|
BOOLEAN MemoryItemListValid;
|
||||||
|
NTSTATUS LastRunStatus;
|
||||||
|
PPH_STRING ErrorMessage;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_MEMORY_CONTEXT, *PPH_MEMORY_CONTEXT;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#define WM_PH_STATISTICS_UPDATE (WM_APP + 231)
|
||||||
|
|
||||||
|
typedef struct _PH_STATISTICS_CONTEXT
|
||||||
|
{
|
||||||
|
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
|
||||||
|
|
||||||
|
HWND WindowHandle;
|
||||||
|
BOOLEAN Enabled;
|
||||||
|
HANDLE ProcessHandle;
|
||||||
|
} PH_STATISTICS_CONTEXT, *PPH_STATISTICS_CONTEXT;
|
||||||
|
|
||||||
|
#define WM_PH_PERFORMANCE_UPDATE (WM_APP + 241)
|
||||||
|
|
||||||
|
typedef struct _PH_PERFORMANCE_CONTEXT
|
||||||
|
{
|
||||||
|
PH_CALLBACK_REGISTRATION ProcessesUpdatedRegistration;
|
||||||
|
|
||||||
|
HWND WindowHandle;
|
||||||
|
|
||||||
|
PH_GRAPH_STATE CpuGraphState;
|
||||||
|
PH_GRAPH_STATE PrivateGraphState;
|
||||||
|
PH_GRAPH_STATE IoGraphState;
|
||||||
|
|
||||||
|
HWND CpuGraphHandle;
|
||||||
|
HWND PrivateGraphHandle;
|
||||||
|
HWND IoGraphHandle;
|
||||||
|
} PH_PERFORMANCE_CONTEXT, *PPH_PERFORMANCE_CONTEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_ENVIRONMENT_ITEM
|
||||||
|
{
|
||||||
|
PPH_STRING Name;
|
||||||
|
PPH_STRING Value;
|
||||||
|
} PH_ENVIRONMENT_ITEM, *PPH_ENVIRONMENT_ITEM;
|
||||||
|
|
||||||
|
typedef struct _PH_ENVIRONMENT_CONTEXT
|
||||||
|
{
|
||||||
|
HWND ListViewHandle;
|
||||||
|
PH_ARRAY Items;
|
||||||
|
} PH_ENVIRONMENT_CONTEXT, *PPH_ENVIRONMENT_CONTEXT;
|
||||||
|
|
||||||
|
#endif
|
409
ProcessHacker/include/procprv.h
Normal file
409
ProcessHacker/include/procprv.h
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
#ifndef PH_PROCPRV_H
|
||||||
|
#define PH_PROCPRV_H
|
||||||
|
|
||||||
|
#define PH_RECORD_MAX_USAGE
|
||||||
|
#define PH_ENABLE_VERIFY_CACHE
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhProcessItemType;
|
||||||
|
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhProcessAddedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhProcessModifiedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhProcessRemovedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhProcessesUpdatedEvent; // phapppub
|
||||||
|
|
||||||
|
extern PPH_LIST PhProcessRecordList;
|
||||||
|
extern PH_QUEUED_LOCK PhProcessRecordListLock;
|
||||||
|
|
||||||
|
extern ULONG PhStatisticsSampleCount;
|
||||||
|
extern BOOLEAN PhEnableProcessQueryStage2;
|
||||||
|
extern BOOLEAN PhEnablePurgeProcessRecords;
|
||||||
|
extern BOOLEAN PhEnableCycleCpuUsage;
|
||||||
|
|
||||||
|
extern PVOID PhProcessInformation; // only can be used if running on same thread as process provider
|
||||||
|
extern ULONG PhProcessInformationSequenceNumber;
|
||||||
|
extern SYSTEM_PERFORMANCE_INFORMATION PhPerfInformation;
|
||||||
|
extern PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION PhCpuInformation;
|
||||||
|
extern SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION PhCpuTotals;
|
||||||
|
extern ULONG PhTotalProcesses;
|
||||||
|
extern ULONG PhTotalThreads;
|
||||||
|
extern ULONG PhTotalHandles;
|
||||||
|
|
||||||
|
extern ULONG64 PhCpuTotalCycleDelta;
|
||||||
|
extern PLARGE_INTEGER PhCpuIdleCycleTime; // cycle time for Idle
|
||||||
|
extern PLARGE_INTEGER PhCpuSystemCycleTime; // cycle time for DPCs and Interrupts
|
||||||
|
extern PH_UINT64_DELTA PhCpuIdleCycleDelta;
|
||||||
|
extern PH_UINT64_DELTA PhCpuSystemCycleDelta;
|
||||||
|
|
||||||
|
extern FLOAT PhCpuKernelUsage;
|
||||||
|
extern FLOAT PhCpuUserUsage;
|
||||||
|
extern PFLOAT PhCpusKernelUsage;
|
||||||
|
extern PFLOAT PhCpusUserUsage;
|
||||||
|
|
||||||
|
extern PH_UINT64_DELTA PhCpuKernelDelta;
|
||||||
|
extern PH_UINT64_DELTA PhCpuUserDelta;
|
||||||
|
extern PH_UINT64_DELTA PhCpuIdleDelta;
|
||||||
|
|
||||||
|
extern PPH_UINT64_DELTA PhCpusKernelDelta;
|
||||||
|
extern PPH_UINT64_DELTA PhCpusUserDelta;
|
||||||
|
extern PPH_UINT64_DELTA PhCpusIdleDelta;
|
||||||
|
|
||||||
|
extern PH_UINT64_DELTA PhIoReadDelta;
|
||||||
|
extern PH_UINT64_DELTA PhIoWriteDelta;
|
||||||
|
extern PH_UINT64_DELTA PhIoOtherDelta;
|
||||||
|
|
||||||
|
extern PH_CIRCULAR_BUFFER_FLOAT PhCpuKernelHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_FLOAT PhCpuUserHistory;
|
||||||
|
//extern PH_CIRCULAR_BUFFER_FLOAT PhCpuOtherHistory;
|
||||||
|
|
||||||
|
extern PPH_CIRCULAR_BUFFER_FLOAT PhCpusKernelHistory;
|
||||||
|
extern PPH_CIRCULAR_BUFFER_FLOAT PhCpusUserHistory;
|
||||||
|
//extern PPH_CIRCULAR_BUFFER_FLOAT PhCpusOtherHistory;
|
||||||
|
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG64 PhIoReadHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG64 PhIoWriteHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG64 PhIoOtherHistory;
|
||||||
|
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG PhCommitHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG PhPhysicalHistory;
|
||||||
|
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG PhMaxCpuHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG PhMaxIoHistory;
|
||||||
|
#ifdef PH_RECORD_MAX_USAGE
|
||||||
|
extern PH_CIRCULAR_BUFFER_FLOAT PhMaxCpuUsageHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG64 PhMaxIoReadOtherHistory;
|
||||||
|
extern PH_CIRCULAR_BUFFER_ULONG64 PhMaxIoWriteHistory;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
#define DPCS_PROCESS_ID ((HANDLE)(LONG_PTR)-2)
|
||||||
|
#define INTERRUPTS_PROCESS_ID ((HANDLE)(LONG_PTR)-3)
|
||||||
|
|
||||||
|
// DPCs, Interrupts and System Idle Process are not real.
|
||||||
|
// Non-"real" processes can never be opened.
|
||||||
|
#define PH_IS_REAL_PROCESS_ID(ProcessId) ((LONG_PTR)(ProcessId) > 0)
|
||||||
|
|
||||||
|
// DPCs and Interrupts are fake, but System Idle Process is not.
|
||||||
|
#define PH_IS_FAKE_PROCESS_ID(ProcessId) ((LONG_PTR)(ProcessId) < 0)
|
||||||
|
|
||||||
|
// The process item has been removed.
|
||||||
|
#define PH_PROCESS_ITEM_REMOVED 0x1
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#define PH_INTEGRITY_STR_LEN 10
|
||||||
|
#define PH_INTEGRITY_STR_LEN_1 (PH_INTEGRITY_STR_LEN + 1)
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _VERIFY_RESULT VERIFY_RESULT;
|
||||||
|
typedef struct _PH_PROCESS_RECORD *PPH_PROCESS_RECORD;
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_ITEM
|
||||||
|
{
|
||||||
|
PH_HASH_ENTRY HashEntry;
|
||||||
|
ULONG State;
|
||||||
|
PPH_PROCESS_RECORD Record;
|
||||||
|
|
||||||
|
// Basic
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ParentProcessId;
|
||||||
|
PPH_STRING ProcessName;
|
||||||
|
ULONG SessionId;
|
||||||
|
|
||||||
|
LARGE_INTEGER CreateTime;
|
||||||
|
|
||||||
|
// Handles
|
||||||
|
|
||||||
|
HANDLE QueryHandle;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
|
||||||
|
PPH_STRING FileName;
|
||||||
|
PPH_STRING CommandLine;
|
||||||
|
|
||||||
|
// File
|
||||||
|
|
||||||
|
HICON SmallIcon;
|
||||||
|
HICON LargeIcon;
|
||||||
|
PH_IMAGE_VERSION_INFO VersionInfo;
|
||||||
|
|
||||||
|
// Security
|
||||||
|
|
||||||
|
PPH_STRING UserName;
|
||||||
|
TOKEN_ELEVATION_TYPE ElevationType;
|
||||||
|
MANDATORY_LEVEL IntegrityLevel;
|
||||||
|
PWSTR IntegrityString;
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
PPH_STRING JobName;
|
||||||
|
HANDLE ConsoleHostProcessId;
|
||||||
|
|
||||||
|
// Signature, Packed
|
||||||
|
|
||||||
|
VERIFY_RESULT VerifyResult;
|
||||||
|
PPH_STRING VerifySignerName;
|
||||||
|
ULONG ImportFunctions;
|
||||||
|
ULONG ImportModules;
|
||||||
|
|
||||||
|
// Flags
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG UpdateIsDotNet : 1;
|
||||||
|
ULONG IsBeingDebugged : 1;
|
||||||
|
ULONG IsDotNet : 1;
|
||||||
|
ULONG IsElevated : 1;
|
||||||
|
ULONG IsInJob : 1;
|
||||||
|
ULONG IsInSignificantJob : 1;
|
||||||
|
ULONG IsPacked : 1;
|
||||||
|
ULONG Reserved : 1;
|
||||||
|
ULONG IsSuspended : 1;
|
||||||
|
ULONG IsWow64 : 1;
|
||||||
|
ULONG IsImmersive : 1;
|
||||||
|
ULONG IsWow64Valid : 1;
|
||||||
|
ULONG IsPartiallySuspended : 1;
|
||||||
|
ULONG AddedEventSent : 1;
|
||||||
|
ULONG Spare : 18;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Misc.
|
||||||
|
|
||||||
|
ULONG JustProcessed;
|
||||||
|
PH_EVENT Stage1Event;
|
||||||
|
|
||||||
|
PPH_POINTER_LIST ServiceList;
|
||||||
|
PH_QUEUED_LOCK ServiceListLock;
|
||||||
|
|
||||||
|
WCHAR ProcessIdString[PH_INT32_STR_LEN_1];
|
||||||
|
WCHAR ParentProcessIdString[PH_INT32_STR_LEN_1];
|
||||||
|
WCHAR SessionIdString[PH_INT32_STR_LEN_1];
|
||||||
|
|
||||||
|
// Dynamic
|
||||||
|
|
||||||
|
KPRIORITY BasePriority;
|
||||||
|
ULONG PriorityClass;
|
||||||
|
LARGE_INTEGER KernelTime;
|
||||||
|
LARGE_INTEGER UserTime;
|
||||||
|
ULONG NumberOfHandles;
|
||||||
|
ULONG NumberOfThreads;
|
||||||
|
|
||||||
|
FLOAT CpuUsage; // Below Windows 7, sum of kernel and user CPU usage; above Windows 7, cycle-based CPU usage.
|
||||||
|
FLOAT CpuKernelUsage;
|
||||||
|
FLOAT CpuUserUsage;
|
||||||
|
|
||||||
|
PH_UINT64_DELTA CpuKernelDelta;
|
||||||
|
PH_UINT64_DELTA CpuUserDelta;
|
||||||
|
PH_UINT64_DELTA IoReadDelta;
|
||||||
|
PH_UINT64_DELTA IoWriteDelta;
|
||||||
|
PH_UINT64_DELTA IoOtherDelta;
|
||||||
|
PH_UINT64_DELTA IoReadCountDelta;
|
||||||
|
PH_UINT64_DELTA IoWriteCountDelta;
|
||||||
|
PH_UINT64_DELTA IoOtherCountDelta;
|
||||||
|
PH_UINT32_DELTA ContextSwitchesDelta;
|
||||||
|
PH_UINT32_DELTA PageFaultsDelta;
|
||||||
|
PH_UINT64_DELTA CycleTimeDelta; // since WIN7
|
||||||
|
|
||||||
|
VM_COUNTERS_EX VmCounters;
|
||||||
|
IO_COUNTERS IoCounters;
|
||||||
|
SIZE_T WorkingSetPrivateSize; // since VISTA
|
||||||
|
ULONG PeakNumberOfThreads; // since WIN7
|
||||||
|
ULONG HardFaultCount; // since WIN7
|
||||||
|
|
||||||
|
ULONG SequenceNumber;
|
||||||
|
PH_CIRCULAR_BUFFER_FLOAT CpuKernelHistory;
|
||||||
|
PH_CIRCULAR_BUFFER_FLOAT CpuUserHistory;
|
||||||
|
PH_CIRCULAR_BUFFER_ULONG64 IoReadHistory;
|
||||||
|
PH_CIRCULAR_BUFFER_ULONG64 IoWriteHistory;
|
||||||
|
PH_CIRCULAR_BUFFER_ULONG64 IoOtherHistory;
|
||||||
|
PH_CIRCULAR_BUFFER_SIZE_T PrivateBytesHistory;
|
||||||
|
//PH_CIRCULAR_BUFFER_SIZE_T WorkingSetHistory;
|
||||||
|
|
||||||
|
// New fields
|
||||||
|
PH_UINTPTR_DELTA PrivateBytesDelta;
|
||||||
|
PPH_STRING PackageFullName;
|
||||||
|
|
||||||
|
PH_QUEUED_LOCK RemoveLock;
|
||||||
|
} PH_PROCESS_ITEM, *PPH_PROCESS_ITEM;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// The process itself is dead.
|
||||||
|
#define PH_PROCESS_RECORD_DEAD 0x1
|
||||||
|
// An extra reference has been added to the process record for the statistics system.
|
||||||
|
#define PH_PROCESS_RECORD_STAT_REF 0x2
|
||||||
|
|
||||||
|
typedef struct _PH_PROCESS_RECORD
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
LONG RefCount;
|
||||||
|
ULONG Flags;
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
HANDLE ParentProcessId;
|
||||||
|
ULONG SessionId;
|
||||||
|
LARGE_INTEGER CreateTime;
|
||||||
|
LARGE_INTEGER ExitTime;
|
||||||
|
|
||||||
|
PPH_STRING ProcessName;
|
||||||
|
PPH_STRING FileName;
|
||||||
|
PPH_STRING CommandLine;
|
||||||
|
/*PPH_STRING UserName;*/
|
||||||
|
} PH_PROCESS_RECORD, *PPH_PROCESS_RECORD;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhProcessProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhGetClientIdName(
|
||||||
|
_In_ PCLIENT_ID ClientId
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhGetClientIdNameEx(
|
||||||
|
_In_ PCLIENT_ID ClientId,
|
||||||
|
_In_opt_ PPH_STRING ProcessName
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PWSTR
|
||||||
|
NTAPI
|
||||||
|
PhGetProcessPriorityClassString(
|
||||||
|
_In_ ULONG PriorityClass
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_PROCESS_ITEM PhCreateProcessItem(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessItem(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhEnumProcessItems(
|
||||||
|
_Out_opt_ PPH_PROCESS_ITEM **ProcessItems,
|
||||||
|
_Out_ PULONG NumberOfProcessItems
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_VERIFY_FILE_INFO *PPH_VERIFY_FILE_INFO;
|
||||||
|
|
||||||
|
VERIFY_RESULT PhVerifyFileWithAdditionalCatalog(
|
||||||
|
_In_ PPH_VERIFY_FILE_INFO Information,
|
||||||
|
_In_opt_ PWSTR PackageFullName,
|
||||||
|
_Out_opt_ PPH_STRING *SignerName
|
||||||
|
);
|
||||||
|
|
||||||
|
VERIFY_RESULT PhVerifyFileCached(
|
||||||
|
_In_ PPH_STRING FileName,
|
||||||
|
_In_opt_ PWSTR PackageFullName,
|
||||||
|
_Out_opt_ PPH_STRING *SignerName,
|
||||||
|
_In_ BOOLEAN CachedOnly
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhGetStatisticsTime(
|
||||||
|
_In_opt_ PPH_PROCESS_ITEM ProcessItem,
|
||||||
|
_In_ ULONG Index,
|
||||||
|
_Out_ PLARGE_INTEGER Time
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhGetStatisticsTimeString(
|
||||||
|
_In_opt_ PPH_PROCESS_ITEM ProcessItem,
|
||||||
|
_In_ ULONG Index
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhFlushProcessQueryData(
|
||||||
|
_In_ BOOLEAN SendModifiedEvent
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhProcessProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessRecord(
|
||||||
|
_In_ PPH_PROCESS_RECORD ProcessRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessRecordSafe(
|
||||||
|
_In_ PPH_PROCESS_RECORD ProcessRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessRecordForStatistics(
|
||||||
|
_In_ PPH_PROCESS_RECORD ProcessRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhDereferenceProcessRecord(
|
||||||
|
_In_ PPH_PROCESS_RECORD ProcessRecord
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_RECORD
|
||||||
|
NTAPI
|
||||||
|
PhFindProcessRecord(
|
||||||
|
_In_opt_ HANDLE ProcessId,
|
||||||
|
_In_ PLARGE_INTEGER Time
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhPurgeProcessRecords(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessItemForParent(
|
||||||
|
_In_ HANDLE ParentProcessId,
|
||||||
|
_In_ HANDLE ProcessId,
|
||||||
|
_In_ PLARGE_INTEGER CreateTime
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhReferenceProcessItemForRecord(
|
||||||
|
_In_ PPH_PROCESS_RECORD Record
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
362
ProcessHacker/include/proctree.h
Normal file
362
ProcessHacker/include/proctree.h
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
#ifndef PH_PROCTREE_H
|
||||||
|
#define PH_PROCTREE_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
// Default columns should go first
|
||||||
|
#define PHPRTLC_NAME 0
|
||||||
|
#define PHPRTLC_PID 1
|
||||||
|
#define PHPRTLC_CPU 2
|
||||||
|
#define PHPRTLC_IOTOTALRATE 3
|
||||||
|
#define PHPRTLC_PRIVATEBYTES 4
|
||||||
|
#define PHPRTLC_USERNAME 5
|
||||||
|
#define PHPRTLC_DESCRIPTION 6
|
||||||
|
|
||||||
|
#define PHPRTLC_COMPANYNAME 7
|
||||||
|
#define PHPRTLC_VERSION 8
|
||||||
|
#define PHPRTLC_FILENAME 9
|
||||||
|
#define PHPRTLC_COMMANDLINE 10
|
||||||
|
#define PHPRTLC_PEAKPRIVATEBYTES 11
|
||||||
|
#define PHPRTLC_WORKINGSET 12
|
||||||
|
#define PHPRTLC_PEAKWORKINGSET 13
|
||||||
|
#define PHPRTLC_PRIVATEWS 14
|
||||||
|
#define PHPRTLC_SHAREDWS 15
|
||||||
|
#define PHPRTLC_SHAREABLEWS 16
|
||||||
|
#define PHPRTLC_VIRTUALSIZE 17
|
||||||
|
#define PHPRTLC_PEAKVIRTUALSIZE 18
|
||||||
|
#define PHPRTLC_PAGEFAULTS 19
|
||||||
|
#define PHPRTLC_SESSIONID 20
|
||||||
|
#define PHPRTLC_PRIORITYCLASS 21
|
||||||
|
#define PHPRTLC_BASEPRIORITY 22
|
||||||
|
|
||||||
|
#define PHPRTLC_THREADS 23
|
||||||
|
#define PHPRTLC_HANDLES 24
|
||||||
|
#define PHPRTLC_GDIHANDLES 25
|
||||||
|
#define PHPRTLC_USERHANDLES 26
|
||||||
|
#define PHPRTLC_IORORATE 27
|
||||||
|
#define PHPRTLC_IOWRATE 28
|
||||||
|
#define PHPRTLC_INTEGRITY 29
|
||||||
|
#define PHPRTLC_IOPRIORITY 30
|
||||||
|
#define PHPRTLC_PAGEPRIORITY 31
|
||||||
|
#define PHPRTLC_STARTTIME 32
|
||||||
|
#define PHPRTLC_TOTALCPUTIME 33
|
||||||
|
#define PHPRTLC_KERNELCPUTIME 34
|
||||||
|
#define PHPRTLC_USERCPUTIME 35
|
||||||
|
#define PHPRTLC_VERIFICATIONSTATUS 36
|
||||||
|
#define PHPRTLC_VERIFIEDSIGNER 37
|
||||||
|
#define PHPRTLC_ASLR 38
|
||||||
|
#define PHPRTLC_RELATIVESTARTTIME 39
|
||||||
|
#define PHPRTLC_BITS 40
|
||||||
|
#define PHPRTLC_ELEVATION 41
|
||||||
|
#define PHPRTLC_WINDOWTITLE 42
|
||||||
|
#define PHPRTLC_WINDOWSTATUS 43
|
||||||
|
#define PHPRTLC_CYCLES 44
|
||||||
|
#define PHPRTLC_CYCLESDELTA 45
|
||||||
|
#define PHPRTLC_CPUHISTORY 46
|
||||||
|
#define PHPRTLC_PRIVATEBYTESHISTORY 47
|
||||||
|
#define PHPRTLC_IOHISTORY 48
|
||||||
|
#define PHPRTLC_DEP 49
|
||||||
|
#define PHPRTLC_VIRTUALIZED 50
|
||||||
|
#define PHPRTLC_CONTEXTSWITCHES 51
|
||||||
|
#define PHPRTLC_CONTEXTSWITCHESDELTA 52
|
||||||
|
#define PHPRTLC_PAGEFAULTSDELTA 53
|
||||||
|
|
||||||
|
#define PHPRTLC_IOREADS 54
|
||||||
|
#define PHPRTLC_IOWRITES 55
|
||||||
|
#define PHPRTLC_IOOTHER 56
|
||||||
|
#define PHPRTLC_IOREADBYTES 57
|
||||||
|
#define PHPRTLC_IOWRITEBYTES 58
|
||||||
|
#define PHPRTLC_IOOTHERBYTES 59
|
||||||
|
#define PHPRTLC_IOREADSDELTA 60
|
||||||
|
#define PHPRTLC_IOWRITESDELTA 61
|
||||||
|
#define PHPRTLC_IOOTHERDELTA 62
|
||||||
|
|
||||||
|
#define PHPRTLC_OSCONTEXT 63
|
||||||
|
#define PHPRTLC_PAGEDPOOL 64
|
||||||
|
#define PHPRTLC_PEAKPAGEDPOOL 65
|
||||||
|
#define PHPRTLC_NONPAGEDPOOL 66
|
||||||
|
#define PHPRTLC_PEAKNONPAGEDPOOL 67
|
||||||
|
#define PHPRTLC_MINIMUMWORKINGSET 68
|
||||||
|
#define PHPRTLC_MAXIMUMWORKINGSET 69
|
||||||
|
#define PHPRTLC_PRIVATEBYTESDELTA 70
|
||||||
|
#define PHPRTLC_SUBSYSTEM 71
|
||||||
|
#define PHPRTLC_PACKAGENAME 72
|
||||||
|
#define PHPRTLC_APPID 73
|
||||||
|
#define PHPRTLC_DPIAWARENESS 74
|
||||||
|
#define PHPRTLC_CFGUARD 75
|
||||||
|
#define PHPRTLC_TIMESTAMP 76
|
||||||
|
#define PHPRTLC_FILEMODIFIEDTIME 77
|
||||||
|
#define PHPRTLC_FILESIZE 78
|
||||||
|
|
||||||
|
#define PHPRTLC_MAXIMUM 79
|
||||||
|
#define PHPRTLC_IOGROUP_COUNT 9
|
||||||
|
|
||||||
|
#define PHPN_WSCOUNTERS 0x1
|
||||||
|
#define PHPN_GDIUSERHANDLES 0x2
|
||||||
|
#define PHPN_IOPAGEPRIORITY 0x4
|
||||||
|
#define PHPN_WINDOW 0x8
|
||||||
|
#define PHPN_DEPSTATUS 0x10
|
||||||
|
#define PHPN_TOKEN 0x20
|
||||||
|
#define PHPN_OSCONTEXT 0x40
|
||||||
|
#define PHPN_QUOTALIMITS 0x80
|
||||||
|
#define PHPN_IMAGE 0x100
|
||||||
|
#define PHPN_APPID 0x200
|
||||||
|
#define PHPN_DPIAWARENESS 0x400
|
||||||
|
#define PHPN_FILEATTRIBUTES 0x800
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_PROCESS_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
PH_HASH_ENTRY HashEntry;
|
||||||
|
|
||||||
|
PH_SH_STATE ShState;
|
||||||
|
|
||||||
|
HANDLE ProcessId;
|
||||||
|
PPH_PROCESS_ITEM ProcessItem;
|
||||||
|
|
||||||
|
struct _PH_PROCESS_NODE *Parent;
|
||||||
|
PPH_LIST Children;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHPRTLC_MAXIMUM];
|
||||||
|
|
||||||
|
PH_STRINGREF DescriptionText;
|
||||||
|
|
||||||
|
// If the user has selected certain columns we need extra information that isn't retrieved by
|
||||||
|
// the process provider.
|
||||||
|
ULONG ValidMask;
|
||||||
|
|
||||||
|
// WS counters
|
||||||
|
PH_PROCESS_WS_COUNTERS WsCounters;
|
||||||
|
// GDI, USER handles
|
||||||
|
ULONG GdiHandles;
|
||||||
|
ULONG UserHandles;
|
||||||
|
// I/O, page priority
|
||||||
|
IO_PRIORITY_HINT IoPriority;
|
||||||
|
ULONG PagePriority;
|
||||||
|
// Window
|
||||||
|
HWND WindowHandle;
|
||||||
|
PPH_STRING WindowText;
|
||||||
|
BOOLEAN WindowHung;
|
||||||
|
// DEP status
|
||||||
|
ULONG DepStatus;
|
||||||
|
// Token
|
||||||
|
BOOLEAN VirtualizationAllowed;
|
||||||
|
BOOLEAN VirtualizationEnabled;
|
||||||
|
// OS Context
|
||||||
|
GUID OsContextGuid;
|
||||||
|
ULONG OsContextVersion;
|
||||||
|
// Quota limits
|
||||||
|
SIZE_T MinimumWorkingSetSize;
|
||||||
|
SIZE_T MaximumWorkingSetSize;
|
||||||
|
// Image
|
||||||
|
ULONG ImageTimeDateStamp;
|
||||||
|
USHORT ImageCharacteristics;
|
||||||
|
USHORT ImageReserved;
|
||||||
|
USHORT ImageSubsystem;
|
||||||
|
USHORT ImageDllCharacteristics;
|
||||||
|
// App ID
|
||||||
|
PPH_STRING AppIdText;
|
||||||
|
// Cycles (Vista only)
|
||||||
|
PH_UINT64_DELTA CyclesDelta;
|
||||||
|
// DPI awareness
|
||||||
|
ULONG DpiAwareness;
|
||||||
|
// File attributes
|
||||||
|
LARGE_INTEGER FileLastWriteTime;
|
||||||
|
LARGE_INTEGER FileEndOfFile;
|
||||||
|
|
||||||
|
PPH_STRING TooltipText;
|
||||||
|
ULONG TooltipTextValidToTickCount;
|
||||||
|
|
||||||
|
// Text buffers
|
||||||
|
WCHAR CpuUsageText[PH_INT32_STR_LEN_1];
|
||||||
|
PPH_STRING IoTotalRateText;
|
||||||
|
PPH_STRING PrivateBytesText;
|
||||||
|
PPH_STRING PeakPrivateBytesText;
|
||||||
|
PPH_STRING WorkingSetText;
|
||||||
|
PPH_STRING PeakWorkingSetText;
|
||||||
|
PPH_STRING PrivateWsText;
|
||||||
|
PPH_STRING SharedWsText;
|
||||||
|
PPH_STRING ShareableWsText;
|
||||||
|
PPH_STRING VirtualSizeText;
|
||||||
|
PPH_STRING PeakVirtualSizeText;
|
||||||
|
PPH_STRING PageFaultsText;
|
||||||
|
WCHAR BasePriorityText[PH_INT32_STR_LEN_1];
|
||||||
|
WCHAR ThreadsText[PH_INT32_STR_LEN_1 + 3];
|
||||||
|
WCHAR HandlesText[PH_INT32_STR_LEN_1 + 3];
|
||||||
|
WCHAR GdiHandlesText[PH_INT32_STR_LEN_1 + 3];
|
||||||
|
WCHAR UserHandlesText[PH_INT32_STR_LEN_1 + 3];
|
||||||
|
PPH_STRING IoRoRateText;
|
||||||
|
PPH_STRING IoWRateText;
|
||||||
|
WCHAR PagePriorityText[PH_INT32_STR_LEN_1];
|
||||||
|
PPH_STRING StartTimeText;
|
||||||
|
PPH_STRING TotalCpuTimeText;
|
||||||
|
PPH_STRING KernelCpuTimeText;
|
||||||
|
PPH_STRING UserCpuTimeText;
|
||||||
|
PPH_STRING RelativeStartTimeText;
|
||||||
|
PPH_STRING WindowTitleText;
|
||||||
|
PPH_STRING CyclesText;
|
||||||
|
PPH_STRING CyclesDeltaText;
|
||||||
|
PPH_STRING ContextSwitchesText;
|
||||||
|
PPH_STRING ContextSwitchesDeltaText;
|
||||||
|
PPH_STRING PageFaultsDeltaText;
|
||||||
|
PPH_STRING IoGroupText[PHPRTLC_IOGROUP_COUNT];
|
||||||
|
PPH_STRING PagedPoolText;
|
||||||
|
PPH_STRING PeakPagedPoolText;
|
||||||
|
PPH_STRING NonPagedPoolText;
|
||||||
|
PPH_STRING PeakNonPagedPoolText;
|
||||||
|
PPH_STRING MinimumWorkingSetText;
|
||||||
|
PPH_STRING MaximumWorkingSetText;
|
||||||
|
PPH_STRING PrivateBytesDeltaText;
|
||||||
|
PPH_STRING TimeStampText;
|
||||||
|
PPH_STRING FileModifiedTimeText;
|
||||||
|
PPH_STRING FileSizeText;
|
||||||
|
|
||||||
|
// Graph buffers
|
||||||
|
PH_GRAPH_BUFFERS CpuGraphBuffers;
|
||||||
|
PH_GRAPH_BUFFERS PrivateGraphBuffers;
|
||||||
|
PH_GRAPH_BUFFERS IoGraphBuffers;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_PROCESS_NODE, *PPH_PROCESS_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhProcessTreeListInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhInitializeProcessTreeList(
|
||||||
|
_In_ HWND hwnd
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsProcessTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsProcessTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhReloadSettingsProcessTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
struct _PH_TN_FILTER_SUPPORT *
|
||||||
|
NTAPI
|
||||||
|
PhGetFilterSupportProcessTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_PROCESS_NODE PhAddProcessNode(
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_NODE
|
||||||
|
NTAPI
|
||||||
|
PhFindProcessNode(
|
||||||
|
_In_ HANDLE ProcessId
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhRemoveProcessNode(
|
||||||
|
_In_ PPH_PROCESS_NODE ProcessNode
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhUpdateProcessNode(
|
||||||
|
_In_ PPH_PROCESS_NODE ProcessNode
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhTickProcessNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_PROCESS_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhGetSelectedProcessItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhGetSelectedProcessItems(
|
||||||
|
_Out_ PPH_PROCESS_ITEM **Processes,
|
||||||
|
_Out_ PULONG NumberOfProcesses
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhDeselectAllProcessNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhExpandAllProcessNodes(
|
||||||
|
_In_ BOOLEAN Expand
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhInvalidateAllProcessNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSelectAndEnsureVisibleProcessNode(
|
||||||
|
_In_ PPH_PROCESS_NODE ProcessNode
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhSelectAndEnsureVisibleProcessNodes(
|
||||||
|
_In_ PPH_PROCESS_NODE *ProcessNodes,
|
||||||
|
_In_ ULONG NumberOfProcessNodes
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_LIST PhGetProcessTreeListLines(
|
||||||
|
_In_ HWND TreeListHandle,
|
||||||
|
_In_ ULONG NumberOfNodes,
|
||||||
|
_In_ PPH_LIST RootNodes,
|
||||||
|
_In_ ULONG Mode
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhCopyProcessTree(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhWriteProcessTree(
|
||||||
|
_Inout_ PPH_FILE_STREAM FileStream,
|
||||||
|
_In_ ULONG Mode
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_LIST
|
||||||
|
NTAPI
|
||||||
|
PhDuplicateProcessNodeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
#endif
|
227
ProcessHacker/include/settings.h
Normal file
227
ProcessHacker/include/settings.h
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#ifndef PH_SETTINGS_H
|
||||||
|
#define PH_SETTINGS_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _PH_SETTING_TYPE
|
||||||
|
{
|
||||||
|
StringSettingType,
|
||||||
|
IntegerSettingType,
|
||||||
|
IntegerPairSettingType,
|
||||||
|
ScalableIntegerPairSettingType
|
||||||
|
} PH_SETTING_TYPE, PPH_SETTING_TYPE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
typedef struct _PH_SETTING
|
||||||
|
{
|
||||||
|
PH_SETTING_TYPE Type;
|
||||||
|
PH_STRINGREF Name;
|
||||||
|
PH_STRINGREF DefaultValue;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
PVOID Pointer;
|
||||||
|
ULONG Integer;
|
||||||
|
PH_INTEGER_PAIR IntegerPair;
|
||||||
|
} u;
|
||||||
|
} PH_SETTING, *PPH_SETTING;
|
||||||
|
|
||||||
|
VOID PhSettingsInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhUpdateCachedSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
PhGetIntegerSetting(
|
||||||
|
_In_ PWSTR Name
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
PH_INTEGER_PAIR
|
||||||
|
NTAPI
|
||||||
|
PhGetIntegerPairSetting(
|
||||||
|
_In_ PWSTR Name
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
PH_SCALABLE_INTEGER_PAIR
|
||||||
|
NTAPI
|
||||||
|
PhGetScalableIntegerPairSetting(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ BOOLEAN ScaleToCurrent
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhGetStringSetting(
|
||||||
|
_In_ PWSTR Name
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetIntegerSetting(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Value
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetIntegerPairSetting(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PH_INTEGER_PAIR Value
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetScalableIntegerPairSetting(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PH_SCALABLE_INTEGER_PAIR Value
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetScalableIntegerPairSetting2(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PH_INTEGER_PAIR Value
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetStringSetting(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PWSTR Value
|
||||||
|
);
|
||||||
|
|
||||||
|
_May_raise_
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSetStringSetting2(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ PPH_STRINGREF Value
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhClearIgnoredSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhConvertIgnoredSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhLoadSettings(
|
||||||
|
_In_ PWSTR FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSaveSettings(
|
||||||
|
_In_ PWSTR FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhResetSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
#define PhaGetStringSetting(Name) PH_AUTO_T(PH_STRING, PhGetStringSetting(Name)) // phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
// High-level settings creation
|
||||||
|
|
||||||
|
typedef struct _PH_SETTING_CREATE
|
||||||
|
{
|
||||||
|
PH_SETTING_TYPE Type;
|
||||||
|
PWSTR Name;
|
||||||
|
PWSTR DefaultValue;
|
||||||
|
} PH_SETTING_CREATE, *PPH_SETTING_CREATE;
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhAddSettings(
|
||||||
|
_In_ PPH_SETTING_CREATE Settings,
|
||||||
|
_In_ ULONG NumberOfSettings
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Cached settings
|
||||||
|
|
||||||
|
#undef EXT
|
||||||
|
|
||||||
|
#ifdef PH_SETTINGS_PRIVATE
|
||||||
|
#define EXT
|
||||||
|
#else
|
||||||
|
#define EXT extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXT ULONG PhCsCollapseServicesOnStart;
|
||||||
|
EXT ULONG PhCsForceNoParent;
|
||||||
|
EXT ULONG PhCsHighlightingDuration;
|
||||||
|
EXT ULONG PhCsPropagateCpuUsage;
|
||||||
|
EXT ULONG PhCsScrollToNewProcesses;
|
||||||
|
EXT ULONG PhCsShowCpuBelow001;
|
||||||
|
EXT ULONG PhCsUpdateInterval;
|
||||||
|
|
||||||
|
EXT ULONG PhCsColorNew;
|
||||||
|
EXT ULONG PhCsColorRemoved;
|
||||||
|
EXT ULONG PhCsUseColorOwnProcesses;
|
||||||
|
EXT ULONG PhCsColorOwnProcesses;
|
||||||
|
EXT ULONG PhCsUseColorSystemProcesses;
|
||||||
|
EXT ULONG PhCsColorSystemProcesses;
|
||||||
|
EXT ULONG PhCsUseColorServiceProcesses;
|
||||||
|
EXT ULONG PhCsColorServiceProcesses;
|
||||||
|
EXT ULONG PhCsUseColorJobProcesses;
|
||||||
|
EXT ULONG PhCsColorJobProcesses;
|
||||||
|
EXT ULONG PhCsUseColorWow64Processes;
|
||||||
|
EXT ULONG PhCsColorWow64Processes;
|
||||||
|
EXT ULONG PhCsUseColorDebuggedProcesses;
|
||||||
|
EXT ULONG PhCsColorDebuggedProcesses;
|
||||||
|
EXT ULONG PhCsUseColorElevatedProcesses;
|
||||||
|
EXT ULONG PhCsColorElevatedProcesses;
|
||||||
|
EXT ULONG PhCsUseColorImmersiveProcesses;
|
||||||
|
EXT ULONG PhCsColorImmersiveProcesses;
|
||||||
|
EXT ULONG PhCsUseColorSuspended;
|
||||||
|
EXT ULONG PhCsColorSuspended;
|
||||||
|
EXT ULONG PhCsUseColorDotNet;
|
||||||
|
EXT ULONG PhCsColorDotNet;
|
||||||
|
EXT ULONG PhCsUseColorPacked;
|
||||||
|
EXT ULONG PhCsColorPacked;
|
||||||
|
EXT ULONG PhCsUseColorGuiThreads;
|
||||||
|
EXT ULONG PhCsColorGuiThreads;
|
||||||
|
EXT ULONG PhCsUseColorRelocatedModules;
|
||||||
|
EXT ULONG PhCsColorRelocatedModules;
|
||||||
|
EXT ULONG PhCsUseColorProtectedHandles;
|
||||||
|
EXT ULONG PhCsColorProtectedHandles;
|
||||||
|
EXT ULONG PhCsUseColorInheritHandles;
|
||||||
|
EXT ULONG PhCsColorInheritHandles;
|
||||||
|
EXT ULONG PhCsGraphShowText;
|
||||||
|
EXT ULONG PhCsGraphColorMode;
|
||||||
|
EXT ULONG PhCsColorCpuKernel;
|
||||||
|
EXT ULONG PhCsColorCpuUser;
|
||||||
|
EXT ULONG PhCsColorIoReadOther;
|
||||||
|
EXT ULONG PhCsColorIoWrite;
|
||||||
|
EXT ULONG PhCsColorPrivate;
|
||||||
|
EXT ULONG PhCsColorPhysical;
|
||||||
|
|
||||||
|
#define PH_SET_INTEGER_CACHED_SETTING(Name, Value) (PhSetIntegerSetting(L#Name, PhCs##Name = (Value)))
|
||||||
|
|
||||||
|
#endif
|
46
ProcessHacker/include/settingsp.h
Normal file
46
ProcessHacker/include/settingsp.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef PH_SETTINGSP_H
|
||||||
|
#define PH_SETTINGSP_H
|
||||||
|
|
||||||
|
#include <shlobj.h>
|
||||||
|
|
||||||
|
BOOLEAN NTAPI PhpSettingsHashtableEqualFunction(
|
||||||
|
_In_ PVOID Entry1,
|
||||||
|
_In_ PVOID Entry2
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG NTAPI PhpSettingsHashtableHashFunction(
|
||||||
|
_In_ PVOID Entry
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhpAddSetting(
|
||||||
|
_In_ PH_SETTING_TYPE Type,
|
||||||
|
_In_ PPH_STRINGREF Name,
|
||||||
|
_In_ PPH_STRINGREF DefaultValue
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG PhpGetCurrentScale(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhpSettingToString(
|
||||||
|
_In_ PH_SETTING_TYPE Type,
|
||||||
|
_In_ PPH_SETTING Setting
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhpSettingFromString(
|
||||||
|
_In_ PH_SETTING_TYPE Type,
|
||||||
|
_In_ PPH_STRINGREF StringRef,
|
||||||
|
_In_opt_ PPH_STRING String,
|
||||||
|
_Inout_ PPH_SETTING Setting
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhpFreeSettingValue(
|
||||||
|
_In_ PH_SETTING_TYPE Type,
|
||||||
|
_In_ PPH_SETTING Setting
|
||||||
|
);
|
||||||
|
|
||||||
|
PVOID PhpLookupSetting(
|
||||||
|
_In_ PPH_STRINGREF Name
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
153
ProcessHacker/include/srvlist.h
Normal file
153
ProcessHacker/include/srvlist.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#ifndef PH_SRVLIST_H
|
||||||
|
#define PH_SRVLIST_H
|
||||||
|
|
||||||
|
#include <phuisup.h>
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
|
||||||
|
#define PHSVTLC_NAME 0
|
||||||
|
#define PHSVTLC_DISPLAYNAME 1
|
||||||
|
#define PHSVTLC_TYPE 2
|
||||||
|
#define PHSVTLC_STATUS 3
|
||||||
|
#define PHSVTLC_STARTTYPE 4
|
||||||
|
#define PHSVTLC_PID 5
|
||||||
|
|
||||||
|
#define PHSVTLC_BINARYPATH 6
|
||||||
|
#define PHSVTLC_ERRORCONTROL 7
|
||||||
|
#define PHSVTLC_GROUP 8
|
||||||
|
#define PHSVTLC_DESCRIPTION 9
|
||||||
|
#define PHSVTLC_KEYMODIFIEDTIME 10
|
||||||
|
|
||||||
|
#define PHSVTLC_MAXIMUM 11
|
||||||
|
|
||||||
|
#define PHSN_CONFIG 0x1
|
||||||
|
#define PHSN_DESCRIPTION 0x2
|
||||||
|
#define PHSN_KEY 0x4
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_SERVICE_NODE
|
||||||
|
{
|
||||||
|
PH_TREENEW_NODE Node;
|
||||||
|
|
||||||
|
PH_SH_STATE ShState;
|
||||||
|
|
||||||
|
PPH_SERVICE_ITEM ServiceItem;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PH_STRINGREF TextCache[PHSVTLC_MAXIMUM];
|
||||||
|
|
||||||
|
ULONG ValidMask;
|
||||||
|
|
||||||
|
WCHAR StartTypeText[12 + 24 + 1];
|
||||||
|
// Config
|
||||||
|
PPH_STRING BinaryPath;
|
||||||
|
PPH_STRING LoadOrderGroup;
|
||||||
|
// Description
|
||||||
|
PPH_STRING Description;
|
||||||
|
// Key
|
||||||
|
LARGE_INTEGER KeyLastWriteTime;
|
||||||
|
|
||||||
|
PPH_STRING TooltipText;
|
||||||
|
|
||||||
|
PPH_STRING KeyModifiedTimeText;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_SERVICE_NODE, *PPH_SERVICE_NODE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhServiceTreeListInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhInitializeServiceTreeList(
|
||||||
|
_In_ HWND hwnd
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhLoadSettingsServiceTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSaveSettingsServiceTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
struct _PH_TN_FILTER_SUPPORT *
|
||||||
|
NTAPI
|
||||||
|
PhGetFilterSupportServiceTreeList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
PPH_SERVICE_NODE PhAddServiceNode(
|
||||||
|
_In_ PPH_SERVICE_ITEM ServiceItem,
|
||||||
|
_In_ ULONG RunId
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_SERVICE_NODE
|
||||||
|
NTAPI
|
||||||
|
PhFindServiceNode(
|
||||||
|
_In_ PPH_SERVICE_ITEM ServiceItem
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhRemoveServiceNode(
|
||||||
|
_In_ PPH_SERVICE_NODE ServiceNode
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhUpdateServiceNode(
|
||||||
|
_In_ PPH_SERVICE_NODE ServiceNode
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhTickServiceNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_SERVICE_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhGetSelectedServiceItem(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhGetSelectedServiceItems(
|
||||||
|
_Out_ PPH_SERVICE_ITEM **Services,
|
||||||
|
_Out_ PULONG NumberOfServices
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhDeselectAllServiceNodes(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSelectAndEnsureVisibleServiceNode(
|
||||||
|
_In_ PPH_SERVICE_NODE ServiceNode
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhCopyServiceList(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhWriteServiceList(
|
||||||
|
_Inout_ PPH_FILE_STREAM FileStream,
|
||||||
|
_In_ ULONG Mode
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
96
ProcessHacker/include/srvprv.h
Normal file
96
ProcessHacker/include/srvprv.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#ifndef PH_SRVPRV_H
|
||||||
|
#define PH_SRVPRV_H
|
||||||
|
|
||||||
|
extern PPH_OBJECT_TYPE PhServiceItemType;
|
||||||
|
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhServiceAddedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhServiceModifiedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhServiceRemovedEvent; // phapppub
|
||||||
|
PHAPPAPI extern PH_CALLBACK PhServicesUpdatedEvent; // phapppub
|
||||||
|
|
||||||
|
extern BOOLEAN PhEnableServiceNonPoll;
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_SERVICE_ITEM
|
||||||
|
{
|
||||||
|
PH_STRINGREF Key; // points to Name
|
||||||
|
PPH_STRING Name;
|
||||||
|
PPH_STRING DisplayName;
|
||||||
|
|
||||||
|
// State
|
||||||
|
ULONG Type;
|
||||||
|
ULONG State;
|
||||||
|
ULONG ControlsAccepted;
|
||||||
|
ULONG Flags; // e.g. SERVICE_RUNS_IN_SYSTEM_PROCESS
|
||||||
|
HANDLE ProcessId;
|
||||||
|
|
||||||
|
// Config
|
||||||
|
ULONG StartType;
|
||||||
|
ULONG ErrorControl;
|
||||||
|
// end_phapppub
|
||||||
|
BOOLEAN DelayedStart;
|
||||||
|
BOOLEAN HasTriggers;
|
||||||
|
|
||||||
|
BOOLEAN PendingProcess;
|
||||||
|
BOOLEAN NeedsConfigUpdate;
|
||||||
|
|
||||||
|
WCHAR ProcessIdString[PH_INT32_STR_LEN_1];
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_SERVICE_ITEM, *PPH_SERVICE_ITEM;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_SERVICE_MODIFIED_DATA
|
||||||
|
{
|
||||||
|
PPH_SERVICE_ITEM Service;
|
||||||
|
PH_SERVICE_ITEM OldService;
|
||||||
|
} PH_SERVICE_MODIFIED_DATA, *PPH_SERVICE_MODIFIED_DATA;
|
||||||
|
|
||||||
|
typedef enum _PH_SERVICE_CHANGE
|
||||||
|
{
|
||||||
|
ServiceStarted,
|
||||||
|
ServiceContinued,
|
||||||
|
ServicePaused,
|
||||||
|
ServiceStopped
|
||||||
|
} PH_SERVICE_CHANGE, *PPH_SERVICE_CHANGE;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
BOOLEAN PhServiceProviderInitialization(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_SERVICE_ITEM PhCreateServiceItem(
|
||||||
|
_In_opt_ LPENUM_SERVICE_STATUS_PROCESS Information
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_SERVICE_ITEM
|
||||||
|
NTAPI
|
||||||
|
PhReferenceServiceItem(
|
||||||
|
_In_ PWSTR Name
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhMarkNeedsConfigUpdateServiceItem(
|
||||||
|
_In_ PPH_SERVICE_ITEM ServiceItem
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
PH_SERVICE_CHANGE
|
||||||
|
NTAPI
|
||||||
|
PhGetServiceChange(
|
||||||
|
_In_ PPH_SERVICE_MODIFIED_DATA Data
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhUpdateProcessItemServices(
|
||||||
|
_In_ PPH_PROCESS_ITEM ProcessItem
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhServiceProviderUpdate(
|
||||||
|
_In_ PVOID Object
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
166
ProcessHacker/include/sysinfo.h
Normal file
166
ProcessHacker/include/sysinfo.h
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#ifndef PH_SYSINFO_H
|
||||||
|
#define PH_SYSINFO_H
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef enum _PH_SYSINFO_VIEW_TYPE
|
||||||
|
{
|
||||||
|
SysInfoSummaryView,
|
||||||
|
SysInfoSectionView
|
||||||
|
} PH_SYSINFO_VIEW_TYPE;
|
||||||
|
|
||||||
|
typedef VOID (NTAPI *PPH_SYSINFO_COLOR_SETUP_FUNCTION)(
|
||||||
|
_Out_ PPH_GRAPH_DRAW_INFO DrawInfo,
|
||||||
|
_In_ COLORREF Color1,
|
||||||
|
_In_ COLORREF Color2
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_SYSINFO_PARAMETERS
|
||||||
|
{
|
||||||
|
HWND SysInfoWindowHandle;
|
||||||
|
HWND ContainerWindowHandle;
|
||||||
|
|
||||||
|
HFONT Font;
|
||||||
|
HFONT MediumFont;
|
||||||
|
HFONT LargeFont;
|
||||||
|
ULONG FontHeight;
|
||||||
|
ULONG FontAverageWidth;
|
||||||
|
ULONG MediumFontHeight;
|
||||||
|
ULONG MediumFontAverageWidth;
|
||||||
|
COLORREF GraphBackColor;
|
||||||
|
COLORREF PanelForeColor;
|
||||||
|
PPH_SYSINFO_COLOR_SETUP_FUNCTION ColorSetupFunction;
|
||||||
|
|
||||||
|
ULONG MinimumGraphHeight;
|
||||||
|
ULONG SectionViewGraphHeight;
|
||||||
|
ULONG PanelWidth;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
ULONG PanelPadding;
|
||||||
|
ULONG WindowPadding;
|
||||||
|
ULONG GraphPadding;
|
||||||
|
ULONG SmallGraphWidth;
|
||||||
|
ULONG SmallGraphPadding;
|
||||||
|
ULONG SeparatorWidth;
|
||||||
|
ULONG CpuPadding;
|
||||||
|
ULONG MemoryPadding;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_SYSINFO_PARAMETERS, *PPH_SYSINFO_PARAMETERS;
|
||||||
|
|
||||||
|
typedef enum _PH_SYSINFO_SECTION_MESSAGE
|
||||||
|
{
|
||||||
|
SysInfoCreate,
|
||||||
|
SysInfoDestroy,
|
||||||
|
SysInfoTick,
|
||||||
|
SysInfoViewChanging, // PH_SYSINFO_VIEW_TYPE Parameter1, PPH_SYSINFO_SECTION Parameter2
|
||||||
|
SysInfoCreateDialog, // PPH_SYSINFO_CREATE_DIALOG Parameter1
|
||||||
|
SysInfoGraphGetDrawInfo, // PPH_GRAPH_DRAW_INFO Parameter1
|
||||||
|
SysInfoGraphGetTooltipText, // PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT Parameter1
|
||||||
|
SysInfoGraphDrawPanel, // PPH_SYSINFO_DRAW_PANEL Parameter1
|
||||||
|
MaxSysInfoMessage
|
||||||
|
} PH_SYSINFO_SECTION_MESSAGE;
|
||||||
|
|
||||||
|
typedef BOOLEAN (NTAPI *PPH_SYSINFO_SECTION_CALLBACK)(
|
||||||
|
_In_ struct _PH_SYSINFO_SECTION *Section,
|
||||||
|
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef struct _PH_SYSINFO_CREATE_DIALOG
|
||||||
|
{
|
||||||
|
BOOLEAN CustomCreate;
|
||||||
|
|
||||||
|
// Parameters for default create
|
||||||
|
PVOID Instance;
|
||||||
|
PWSTR Template;
|
||||||
|
DLGPROC DialogProc;
|
||||||
|
PVOID Parameter;
|
||||||
|
} PH_SYSINFO_CREATE_DIALOG, *PPH_SYSINFO_CREATE_DIALOG;
|
||||||
|
|
||||||
|
typedef struct _PH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
PH_STRINGREF Text;
|
||||||
|
} PH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT, *PPH_SYSINFO_GRAPH_GET_TOOLTIP_TEXT;
|
||||||
|
|
||||||
|
typedef struct _PH_SYSINFO_DRAW_PANEL
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
RECT Rect;
|
||||||
|
BOOLEAN CustomDraw;
|
||||||
|
|
||||||
|
// Parameters for default draw
|
||||||
|
PPH_STRING Title;
|
||||||
|
PPH_STRING SubTitle;
|
||||||
|
PPH_STRING SubTitleOverflow;
|
||||||
|
} PH_SYSINFO_DRAW_PANEL, *PPH_SYSINFO_DRAW_PANEL;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
typedef struct _PH_SYSINFO_SECTION
|
||||||
|
{
|
||||||
|
// Public
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
PH_STRINGREF Name;
|
||||||
|
ULONG Flags;
|
||||||
|
PPH_SYSINFO_SECTION_CALLBACK Callback;
|
||||||
|
PVOID Context;
|
||||||
|
PVOID Reserved[3];
|
||||||
|
|
||||||
|
// State
|
||||||
|
HWND GraphHandle;
|
||||||
|
PH_GRAPH_STATE GraphState;
|
||||||
|
PPH_SYSINFO_PARAMETERS Parameters;
|
||||||
|
PVOID Reserved2[3];
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG GraphHot : 1;
|
||||||
|
ULONG PanelHot : 1;
|
||||||
|
ULONG HasFocus : 1;
|
||||||
|
ULONG HideFocus : 1;
|
||||||
|
ULONG SpareFlags : 28;
|
||||||
|
};
|
||||||
|
HWND DialogHandle;
|
||||||
|
HWND PanelHandle;
|
||||||
|
ULONG PanelId;
|
||||||
|
WNDPROC GraphOldWndProc;
|
||||||
|
WNDPROC PanelOldWndProc;
|
||||||
|
// begin_phapppub
|
||||||
|
} PH_SYSINFO_SECTION, *PPH_SYSINFO_SECTION;
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhSiNotifyChangeSettings(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
// begin_phapppub
|
||||||
|
PHAPPAPI
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PhSiSetColorsGraphDrawInfo(
|
||||||
|
_Out_ PPH_GRAPH_DRAW_INFO DrawInfo,
|
||||||
|
_In_ COLORREF Color1,
|
||||||
|
_In_ COLORREF Color2
|
||||||
|
);
|
||||||
|
|
||||||
|
PHAPPAPI
|
||||||
|
PPH_STRING
|
||||||
|
NTAPI
|
||||||
|
PhSiSizeLabelYFunction(
|
||||||
|
_In_ PPH_GRAPH_DRAW_INFO DrawInfo,
|
||||||
|
_In_ ULONG DataIndex,
|
||||||
|
_In_ FLOAT Value,
|
||||||
|
_In_ FLOAT Parameter
|
||||||
|
);
|
||||||
|
// end_phapppub
|
||||||
|
|
||||||
|
VOID PhShowSystemInformationDialog(
|
||||||
|
_In_opt_ PWSTR SectionName
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
439
ProcessHacker/include/sysinfop.h
Normal file
439
ProcessHacker/include/sysinfop.h
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
#ifndef PH_SYSINFOP_H
|
||||||
|
#define PH_SYSINFOP_H
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
|
||||||
|
#define PH_SYSINFO_FADE_ADD 50
|
||||||
|
#define PH_SYSINFO_PANEL_PADDING 3
|
||||||
|
#define PH_SYSINFO_WINDOW_PADDING 13
|
||||||
|
#define PH_SYSINFO_GRAPH_PADDING 9
|
||||||
|
#define PH_SYSINFO_SMALL_GRAPH_WIDTH 48
|
||||||
|
#define PH_SYSINFO_SMALL_GRAPH_PADDING 5
|
||||||
|
#define PH_SYSINFO_SEPARATOR_WIDTH 2
|
||||||
|
|
||||||
|
#define PH_SYSINFO_CPU_PADDING 5
|
||||||
|
#define PH_SYSINFO_MEMORY_PADDING 3
|
||||||
|
|
||||||
|
#define SI_MSG_SYSINFO_FIRST (WM_APP + 150)
|
||||||
|
#define SI_MSG_SYSINFO_ACTIVATE (WM_APP + 150)
|
||||||
|
#define SI_MSG_SYSINFO_UPDATE (WM_APP + 151)
|
||||||
|
#define SI_MSG_SYSINFO_CHANGE_SETTINGS (WM_APP + 152)
|
||||||
|
#define SI_MSG_SYSINFO_LAST (WM_APP + 152)
|
||||||
|
|
||||||
|
#define SWP_NO_ACTIVATE_MOVE_SIZE_ZORDER (SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER)
|
||||||
|
#define SWP_SHOWWINDOW_ONLY (SWP_NO_ACTIVATE_MOVE_SIZE_ZORDER | SWP_SHOWWINDOW)
|
||||||
|
#define SWP_HIDEWINDOW_ONLY (SWP_NO_ACTIVATE_MOVE_SIZE_ZORDER | SWP_HIDEWINDOW)
|
||||||
|
|
||||||
|
// Thread & window
|
||||||
|
|
||||||
|
extern HWND PhSipWindow;
|
||||||
|
|
||||||
|
NTSTATUS PhSipSysInfoThreadStart(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipSysInfoDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipContainerDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Event handlers
|
||||||
|
|
||||||
|
VOID PhSipOnInitDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnDestroy(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnNcDestroy(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnShowWindow(
|
||||||
|
_In_ BOOLEAN Showing,
|
||||||
|
_In_ ULONG State
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhSipOnSysCommand(
|
||||||
|
_In_ ULONG Type,
|
||||||
|
_In_ LONG CursorScreenX,
|
||||||
|
_In_ LONG CursorScreenY
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnSize(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnSizing(
|
||||||
|
_In_ ULONG Edge,
|
||||||
|
_In_ PRECT DragRectangle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnThemeChanged(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnCommand(
|
||||||
|
_In_ ULONG Id,
|
||||||
|
_In_ ULONG Code
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhSipOnNotify(
|
||||||
|
_In_ NMHDR *Header,
|
||||||
|
_Out_ LRESULT *Result
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhSipOnDrawItem(
|
||||||
|
_In_ ULONG_PTR Id,
|
||||||
|
_In_ DRAWITEMSTRUCT *DrawItemStruct
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipOnUserMessage(
|
||||||
|
_In_ ULONG Message,
|
||||||
|
_In_ ULONG_PTR WParam,
|
||||||
|
_In_ ULONG_PTR LParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Framework
|
||||||
|
|
||||||
|
VOID PhSipRegisterDialog(
|
||||||
|
_In_ HWND DialogWindowHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUnregisterDialog(
|
||||||
|
_In_ HWND DialogWindowHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipInitializeParameters(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDeleteParameters(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateColorParameters(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_SYSINFO_SECTION PhSipCreateSection(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Template
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDestroySection(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_SYSINFO_SECTION PhSipFindSection(
|
||||||
|
_In_ PPH_STRINGREF Name
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_SYSINFO_SECTION PhSipCreateInternalSection(
|
||||||
|
_In_ PWSTR Name,
|
||||||
|
_In_ ULONG Flags,
|
||||||
|
_In_ PPH_SYSINFO_SECTION_CALLBACK Callback
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDrawRestoreSummaryPanel(
|
||||||
|
_In_ HDC hdc,
|
||||||
|
_In_ PRECT Rect
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDrawSeparator(
|
||||||
|
_In_ HDC hdc,
|
||||||
|
_In_ PRECT Rect
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDrawPanel(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ HDC hdc,
|
||||||
|
_In_ PRECT Rect
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipDefaultDrawPanel(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ PPH_SYSINFO_DRAW_PANEL DrawPanel
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipLayoutSummaryView(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipLayoutSectionView(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipEnterSectionView(
|
||||||
|
_In_ PPH_SYSINFO_SECTION NewSection
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipEnterSectionViewInner(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ BOOLEAN FromSummaryView,
|
||||||
|
_Inout_ HDWP *DeferHandle,
|
||||||
|
_Inout_ HDWP *ContainerDeferHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipRestoreSummaryView(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipCreateSectionDialog(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section
|
||||||
|
);
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhSipGraphHookWndProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
LRESULT CALLBACK PhSipPanelHookWndProc(
|
||||||
|
_In_ HWND hwnd,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
// Misc.
|
||||||
|
|
||||||
|
VOID PhSipUpdateThemeData(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipSetAlwaysOnTop(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipSaveWindowState(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID NTAPI PhSipSysInfoUpdateHandler(
|
||||||
|
_In_opt_ PVOID Parameter,
|
||||||
|
_In_opt_ PVOID Context
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhSipFormatSizeWithPrecision(
|
||||||
|
_In_ ULONG64 Size,
|
||||||
|
_In_ USHORT Precision
|
||||||
|
);
|
||||||
|
|
||||||
|
// CPU section
|
||||||
|
|
||||||
|
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8
|
||||||
|
{
|
||||||
|
ULONG Hits;
|
||||||
|
UCHAR PercentFrequency;
|
||||||
|
} SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8, *PSYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8;
|
||||||
|
|
||||||
|
BOOLEAN PhSipCpuSectionCallback(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipInitializeCpuDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUninitializeCpuDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipTickCpuDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipCpuDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipCpuPanelDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipCreateCpuGraphs(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipLayoutCpuGraphs(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipSetOneGraphPerCpu(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipNotifyCpuGraph(
|
||||||
|
_In_ ULONG Index,
|
||||||
|
_In_ NMHDR *Header
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateCpuGraphs(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateCpuPanel(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_PROCESS_RECORD PhSipReferenceMaxCpuRecord(
|
||||||
|
_In_ LONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhSipGetMaxCpuString(
|
||||||
|
_In_ LONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipGetCpuBrandString(
|
||||||
|
_Out_writes_(49) PWSTR BrandString
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN PhSipGetCpuFrequencyFromDistribution(
|
||||||
|
_Out_ DOUBLE *Fraction
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSipQueryProcessorPerformanceDistribution(
|
||||||
|
_Out_ PVOID *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
// Memory section
|
||||||
|
|
||||||
|
BOOLEAN PhSipMemorySectionCallback(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipInitializeMemoryDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUninitializeMemoryDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipTickMemoryDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipMemoryDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipMemoryPanelDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipLayoutMemoryGraphs(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipNotifyCommitGraph(
|
||||||
|
_In_ NMHDR *Header
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipNotifyPhysicalGraph(
|
||||||
|
_In_ NMHDR *Header
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateMemoryGraphs(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateMemoryPanel(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS PhSipLoadMmAddresses(
|
||||||
|
_In_ PVOID Parameter
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipGetPoolLimits(
|
||||||
|
_Out_ PSIZE_T Paged,
|
||||||
|
_Out_ PSIZE_T NonPaged
|
||||||
|
);
|
||||||
|
|
||||||
|
// I/O section
|
||||||
|
|
||||||
|
BOOLEAN PhSipIoSectionCallback(
|
||||||
|
_In_ PPH_SYSINFO_SECTION Section,
|
||||||
|
_In_ PH_SYSINFO_SECTION_MESSAGE Message,
|
||||||
|
_In_opt_ PVOID Parameter1,
|
||||||
|
_In_opt_ PVOID Parameter2
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipInitializeIoDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUninitializeIoDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipTickIoDialog(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipIoDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
INT_PTR CALLBACK PhSipIoPanelDialogProc(
|
||||||
|
_In_ HWND hwndDlg,
|
||||||
|
_In_ UINT uMsg,
|
||||||
|
_In_ WPARAM wParam,
|
||||||
|
_In_ LPARAM lParam
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipNotifyIoGraph(
|
||||||
|
_In_ NMHDR *Header
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateIoGraph(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID PhSipUpdateIoPanel(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_PROCESS_RECORD PhSipReferenceMaxIoRecord(
|
||||||
|
_In_ LONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
PPH_STRING PhSipGetMaxIoString(
|
||||||
|
_In_ LONG Index
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user