mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
Compare commits
131 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44a90f5c7d | ||
|
|
5c3ee9f499 | ||
|
|
03f357efd1 | ||
|
|
5462575f5c | ||
|
|
120e2bc300 | ||
|
|
c3137df83c | ||
|
|
737155a226 | ||
|
|
66d64cf020 | ||
|
|
42f5c0f484 | ||
|
|
75047e26e2 | ||
|
|
9fa6d82775 | ||
|
|
d1468984e7 | ||
|
|
20a2331504 | ||
|
|
5b00c8ee08 | ||
|
|
bda4aadc54 | ||
|
|
9d7e2eccac | ||
|
|
8c219b981c | ||
|
|
7d87c8bb98 | ||
|
|
13afd96806 | ||
|
|
4fb74a1769 | ||
|
|
aa658b7dbc | ||
|
|
7e3601989a | ||
|
|
3a1c0f8d66 | ||
|
|
91160b4311 | ||
|
|
83f4093796 | ||
|
|
f219395b25 | ||
|
|
ae6a7ad8e5 | ||
|
|
d990ee102a | ||
|
|
cfde9939b4 | ||
|
|
a22725bb67 | ||
|
|
7a4040f6ec | ||
|
|
2fbb351314 | ||
|
|
96e85c0685 | ||
|
|
50577c9ea0 | ||
|
|
073323b517 | ||
|
|
37cc8f3aae | ||
|
|
6367152650 | ||
|
|
ffbaef3872 | ||
|
|
a0b2473bf4 | ||
|
|
95a3104a56 | ||
|
|
2d5f77730b | ||
|
|
033a0dfbb9 | ||
|
|
cb682b6e21 | ||
|
|
7312908d4d | ||
|
|
b44f6035b3 | ||
|
|
b6bc8abf83 | ||
|
|
c60c1154b9 | ||
|
|
219afb6244 | ||
|
|
22b6bdb5cf | ||
|
|
d9a47fe815 | ||
|
|
45e987b413 | ||
|
|
a920696d03 | ||
|
|
f72b153fe0 | ||
|
|
d240b4ed49 | ||
|
|
1a21627cdb | ||
|
|
0a115a3c03 | ||
|
|
7ef11f566b | ||
|
|
7f6aa9f9a6 | ||
|
|
4df1496a0f | ||
|
|
b68eb0bb5e | ||
|
|
7c0fb7c4f2 | ||
|
|
ede8048680 | ||
|
|
b10ba8fea0 | ||
|
|
3eb2cca286 | ||
|
|
721ac837e0 | ||
|
|
f6fef35d3d | ||
|
|
0569770239 | ||
|
|
6689b8ebfa | ||
|
|
3cb6c4f775 | ||
|
|
b687eb88f9 | ||
|
|
33a375910a | ||
|
|
a620400e4e | ||
|
|
cc7dc3597b | ||
|
|
60b5842e94 | ||
|
|
2b9c6ec447 | ||
|
|
742a4e53b5 | ||
|
|
0cd10b6b70 | ||
|
|
aabf718e60 | ||
|
|
03116c4ab8 | ||
|
|
38162c0129 | ||
|
|
f62edea450 | ||
|
|
940f1e30c5 | ||
|
|
af32d68c3f | ||
|
|
eb874ac810 | ||
|
|
a79bf4c3ec | ||
|
|
90adacab9f | ||
|
|
e86ca29b8c | ||
|
|
4f1f9a718c | ||
|
|
cc09014e6e | ||
|
|
de98b40c93 | ||
|
|
a6eaa34f6d | ||
|
|
dacb64ae66 | ||
|
|
c0a5e2012f | ||
|
|
389e53a8a0 | ||
|
|
928fbe235a | ||
|
|
7d85a8b6fc | ||
|
|
d004962e3a | ||
|
|
1462a4689d | ||
|
|
93be4c8ed1 | ||
|
|
536c6df438 | ||
|
|
f8a089a61f | ||
|
|
491ee6aa2f | ||
|
|
6a88c7cbaa | ||
|
|
be82ee15b7 | ||
|
|
1ddd3ea2b9 | ||
|
|
a56a8c1d6c | ||
|
|
9c4e314bb6 | ||
|
|
ea26722a18 | ||
|
|
5aee359700 | ||
|
|
5d11fc960e | ||
|
|
707fec0e2a | ||
|
|
55b877d5e0 | ||
|
|
e779285be4 | ||
|
|
cf6ae52889 | ||
|
|
caad705975 | ||
|
|
0c3fc6f858 | ||
|
|
0529155faa | ||
|
|
aa01d58b33 | ||
|
|
0c0caf6942 | ||
|
|
7e01ff451f | ||
|
|
e0e4b0a5a9 | ||
|
|
0e2c1f1355 | ||
|
|
0ed7341f71 | ||
|
|
29e970fd81 | ||
|
|
43ab72dcb8 | ||
|
|
07dc77f13d | ||
|
|
9b2ee998de | ||
|
|
e1c5cd1e86 | ||
|
|
0d0301f4f6 | ||
|
|
29adeae6a3 | ||
|
|
6b62a1963e |
140
.github/workflows/build.yml
vendored
140
.github/workflows/build.yml
vendored
@@ -99,14 +99,7 @@ jobs:
|
||||
..
|
||||
mingw32-make -j4 install
|
||||
cpack
|
||||
touch $PWD/install/PORTABLE
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable
|
||||
path: |
|
||||
build/install/*
|
||||
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -115,23 +108,59 @@ jobs:
|
||||
path: |
|
||||
build/*.msi
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
- name: ⬇️ Download Mesa3D for NoGPU version
|
||||
shell: bash
|
||||
run: |
|
||||
echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md
|
||||
curl https://downloads.fdossena.com/geth.php?r=mesa64-latest -L -o mesa.7z
|
||||
7z e mesa.7z
|
||||
mv opengl32.dll build/install
|
||||
|
||||
|
||||
- name: ⬆️ Upload NoGPU Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows Portable NoGPU
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
# MacOS build
|
||||
macos:
|
||||
runs-on: macos-11
|
||||
name: 🍎 macOS 11.0
|
||||
steps:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- suffix: "-NoGPU"
|
||||
custom_glfw: true
|
||||
- suffix: ""
|
||||
custom_glfw: false
|
||||
|
||||
name: 🍎 macOS 11.0${{matrix.suffix}}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/ccache
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
|
||||
|
||||
@@ -140,12 +169,43 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
|
||||
- name: ⬇️ Install classic glfw
|
||||
if: ${{! matrix.custom_glfw}}
|
||||
run: |
|
||||
brew install glfw
|
||||
|
||||
|
||||
- name: 🧰 Checkout glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: glfw/glfw
|
||||
path: glfw
|
||||
|
||||
- name: ⬇️ Patch and install custom glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
run: |
|
||||
cd glfw
|
||||
git apply ../dist/macOS/0001-glfw-SW.patch
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
..
|
||||
make -j 4 install
|
||||
|
||||
# MacOS cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
@@ -167,13 +227,14 @@ jobs:
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.10" \
|
||||
-DCPACK_PACKAGE_FILE_NAME="imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}" \
|
||||
..
|
||||
make -j4 package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: macOS DMG
|
||||
name: macOS DMG${{matrix.suffix}}
|
||||
path: build/*.dmg
|
||||
|
||||
# Ubuntu build
|
||||
@@ -187,7 +248,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Restore cache
|
||||
- name: 📜 Restore ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
@@ -200,6 +261,7 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
build-appimage/CMakeCache.txt
|
||||
.flatpak-builder
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
@@ -225,13 +287,14 @@ jobs:
|
||||
$HOME/.cargo/bin/rustup target add x86_64-unknown-linux-gnu
|
||||
$HOME/.cargo/bin/rustup default nightly
|
||||
|
||||
# Ubuntu cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
@@ -239,7 +302,7 @@ jobs:
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
make -j 4 install DESTDIR=DebDir
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -256,29 +319,34 @@ jobs:
|
||||
|
||||
- name: 📦 Bundle DEB
|
||||
run: |
|
||||
cp -r build/DEBIAN build/AppDir
|
||||
dpkg-deb -Zgzip --build build/AppDir
|
||||
mv build/AppDir.deb imhex-${{env.IMHEX_VERSION}}.deb
|
||||
rm -rf build/AppDir/DEBIAN
|
||||
cp -r build/DEBIAN build/DebDir
|
||||
dpkg-deb -Zgzip --build build/DebDir
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-22.04.deb
|
||||
|
||||
# AppImage cmake build
|
||||
- name: 🛠️ Reconfigure build for AppImage
|
||||
run: |
|
||||
# Reconfigure CMake to include a flag needed for AppImage
|
||||
# Other flags are kept from old configuration
|
||||
|
||||
cd build
|
||||
cmake \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
..
|
||||
|
||||
rm -rf AppDir
|
||||
mkdir -p build-appimage
|
||||
cd build-appimage
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DRUST_PATH="$HOME/.cargo/bin/" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
-DIMHEX_USE_BUNDLED_CA=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
|
||||
- name: 📦 Bundle AppImage
|
||||
run: |
|
||||
cd build
|
||||
cd build-appimage
|
||||
export VERSION=${{env.IMHEX_VERSION}}
|
||||
appimage-builder --recipe ../dist/AppImageBuilder.yml
|
||||
mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.IMHEX_VERSION}}.AppImage
|
||||
cd ..
|
||||
|
||||
#- name: ⬆️ Upload Flatpak
|
||||
@@ -291,14 +359,20 @@ jobs:
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux DEB (Ubuntu 22.04)
|
||||
name: Ubuntu 22.04 DEB
|
||||
path: '*.deb'
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux AppImage
|
||||
path: '*.AppImage'
|
||||
path: 'build-appimage/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Linux AppImage zsync
|
||||
path: 'build-appimage/*.AppImage.zsync'
|
||||
|
||||
# ArchLinux build
|
||||
archlinux-build:
|
||||
|
||||
45
.github/workflows/release.yml
vendored
45
.github/workflows/release.yml
vendored
@@ -6,11 +6,12 @@ name: Release
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
release-common:
|
||||
runs-on: ubuntu-latest
|
||||
name: Release
|
||||
name: Release Common
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -57,8 +58,10 @@ jobs:
|
||||
fi
|
||||
done
|
||||
|
||||
- name: 🟩 Rename Windows Portable Zip
|
||||
run: mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
|
||||
- name: 🟩 Rename artifacts when needed
|
||||
run: |
|
||||
mv "Windows Portable.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable.zip
|
||||
mv "Windows Portable NoGPU.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-NoGPU.zip
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
@@ -110,3 +113,37 @@ jobs:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: ✉️ Update C++ Plugin Template
|
||||
uses: mvasigh/dispatch-action@main
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
repo: ImHex-Cpp-Plugin-Template
|
||||
owner: WerWolv
|
||||
event_type: update_submodule
|
||||
|
||||
release-windows:
|
||||
name: Release Windows
|
||||
needs: release-common
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: ⬇️ Download dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
iwr https://github.com/microsoft/winget-create/releases/download/v1.0.4.0/wingetcreate.exe -OutFile wingetcreate.exe
|
||||
- name: ⬆️ Update winget manifest
|
||||
shell: pwsh
|
||||
env:
|
||||
WINGET_GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.WINGET_GITHUB_TOKEN != '' }}"
|
||||
run: |
|
||||
$tagname = $env:GITHUB_REF.Replace("refs/tags/", "")
|
||||
$version = $tagname.Replace("v", "")
|
||||
$url = "https://github.com/WerWolv/ImHex/releases/download/${tagname}/imhex-${version}-win64.msi"
|
||||
.\wingetcreate.exe update WerWolv.ImHex -u $url --version $version
|
||||
if ($version -notmatch "-") {
|
||||
.\wingetcreate.exe submit .\manifests\w\WerWolv\ImHex\${version}\ --token $env:WINGET_GITHUB_TOKEN
|
||||
}
|
||||
|
||||
18
.github/workflows/tests.yml
vendored
18
.github/workflows/tests.yml
vendored
@@ -47,18 +47,18 @@ jobs:
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld -fsanitize=address,leak,undefined -fno-sanitize-recover=all" \
|
||||
-DIMHEX_OFFLINE_BUILD=ON \
|
||||
..
|
||||
make -j4 unit_tests install
|
||||
|
||||
- name: 🧪 Perform Unit Tests
|
||||
run: |
|
||||
cd build
|
||||
ctest --output-on-failure
|
||||
ctest --output-on-failure
|
||||
|
||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@@ -8,6 +8,7 @@
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/libromfs" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/nativefiledialog" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language/external/cli11" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/pattern_language/external/fmt" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/xdgpp" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/lib/external/yara/yara" vcs="Git" />
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# Options
|
||||
option(IMHEX_USE_BUNDLED_CA "Use the CA bundle in romfs instead of the system one" OFF)
|
||||
option(IMHEX_PLUGINS_IN_SHARE "Put the plugins in share/imhex/plugins instead of lib[..]/imhex/plugins" OFF)
|
||||
option(IMHEX_STRIP_RELEASE "Strip the release builds" ON)
|
||||
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
|
||||
option(IMHEX_IGNORE_BAD_CLONE "Disabled the bad clone prevention checks" OFF)
|
||||
option(IMHEX_IGNORE_BAD_CLONE "Disable the bad clone prevention checks" OFF)
|
||||
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
|
||||
option(IMHEX_IGNORE_BAD_COMPILER "Allow compiling with an unsupported compiler" OFF)
|
||||
|
||||
@@ -46,4 +47,4 @@ enable_testing()
|
||||
add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
|
||||
# Configure packaging
|
||||
createPackage()
|
||||
createPackage()
|
||||
|
||||
31
README.md
31
README.md
@@ -1,4 +1,4 @@
|
||||
<a href="https://imhex.werwolv.net"><h1 align="center" >:mag: ImHex</h1></a>
|
||||
<a href="https://imhex.werwolv.net"><h1 align="center" ><img height="100px" src="resources/projects/logo_text.svg"></h1></a>
|
||||
|
||||
<p align="center">A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</p>
|
||||
|
||||
@@ -116,7 +116,7 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
|
||||
|
||||
To use ImHex, the following minimal system requirements need to be met:
|
||||
|
||||
- **OS**: Windows 7 or higher, macOS 10.10 (Yosemite) or higher, "Modern" Linux (Ubuntu 22.04+, Fedora Stable/Rawhide and Arch Linux are officially supported)
|
||||
- **OS**: Windows 7 or higher, macOS 10.15 (Catalina) or higher, "Modern" Linux (Ubuntu 22.04, Fedora Stable/Rawhide, and Arch Linux have official packages, other distributions can use the AppImage)
|
||||
- **CPU**: x86_64 (64 Bit)
|
||||
- **GPU**: OpenGL 3.0 or higher (preferable a dedicated GPU and not Intel HD Graphics)
|
||||
- **RAM**: 512MB, more may be required for more complicated analysis
|
||||
@@ -128,6 +128,25 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
- [C++ Plugin Template](https://github.com/WerWolv/ImHex-Cpp-Plugin-Template)
|
||||
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
|
||||
|
||||
## Installing
|
||||
The following OSs have packages available in their repositories making it easy to install ImHex.
|
||||
### Fedora (36+)
|
||||
```
|
||||
dnf install imhex
|
||||
```
|
||||
|
||||
### RHEL 9 / AlmaLinux 9 (coming soon)
|
||||
|
||||
### Arch Linux (AUR)
|
||||
```
|
||||
yay -S imhex-bin
|
||||
```
|
||||
|
||||
## Third Party Repositories
|
||||
|
||||
ImHex is available in various thid party repositores.
|
||||
|
||||
[](https://repology.org/project/imhex/versions)
|
||||
|
||||
## Nightly builds
|
||||
|
||||
@@ -139,18 +158,12 @@ Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImH
|
||||
- MacOS • __x86_64__
|
||||
- [DMG](https://nightly.link/WerWolv/ImHex/workflows/build/master/macOS%20DMG.zip)
|
||||
- Linux • __x86_64__
|
||||
- [Ubuntu DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20DEB%20%28Ubuntu%2022.04%29.zip)
|
||||
- [Ubuntu 22.04 DEB](https://nightly.link/WerWolv/ImHex/workflows/build/master/Ubuntu%2022.04%20DEB.zip)
|
||||
- [AppImage](https://nightly.link/WerWolv/ImHex/workflows/build/master/Linux%20AppImage.zip)
|
||||
- [Arch Package](https://nightly.link/WerWolv/ImHex/workflows/build/master/ArchLinux%20.pkg.tar.zst.zip)
|
||||
- [Fedora Rawhide RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Rawhide%20RPM.zip)
|
||||
- [Fedora Stable RPM](https://nightly.link/WerWolv/ImHex/workflows/build/master/Fedora%20Latest%20RPM.zip)
|
||||
|
||||
## Third party repositories
|
||||
|
||||
ImHex is available in various third party repositories.
|
||||
|
||||
[](https://repology.org/project/imhex/versions)
|
||||
|
||||
## Compiling
|
||||
|
||||
To compile ImHex on any platform, GCC (or Clang) is required with a version that supports C++23 or higher.
|
||||
|
||||
@@ -84,6 +84,8 @@ macro(detectOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
|
||||
SET(IMHEX_USE_BUNDLED_CA ON)
|
||||
elseif (APPLE)
|
||||
add_compile_definitions(OS_MACOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
@@ -102,10 +104,15 @@ macro(detectOS)
|
||||
# Warning : Do not work with portable versions such as appimage (because the path is hardcoded)
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex") # "plugins" will be appended from the app
|
||||
endif()
|
||||
|
||||
|
||||
else ()
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
endif()
|
||||
|
||||
if(IMHEX_USE_BUNDLED_CA)
|
||||
add_compile_definitions(IMHEX_USE_BUNDLED_CA)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# Detect 32 vs. 64 bit system
|
||||
@@ -133,7 +140,7 @@ macro(configurePackingResources)
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_NAME "imhex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
|
||||
@@ -258,6 +265,14 @@ macro(createPackage)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
|
||||
# install AppStream file
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/net.werwolv.imhex.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
# install symlink for the old standard name
|
||||
file(CREATE_LINK net.werwolv.imhex.metainfo.xml ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml SYMBOLIC)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
endif()
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
@@ -316,7 +331,9 @@ macro(setDefaultBuiltTypeIfUnset)
|
||||
endmacro()
|
||||
|
||||
function(loadVersion version)
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" read_version)
|
||||
set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${VERSION_FILE})
|
||||
file(READ "${VERSION_FILE}" read_version)
|
||||
set(${version} ${read_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -344,7 +361,7 @@ function(verifyCompiler)
|
||||
message(FATAL_ERROR "ImHex requires GCC 12.0.0 or newer. Please use the latest GCC version.")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0.0")
|
||||
message(FATAL_ERROR "ImHex requires Clang 14.0.0 or newer. Please use the latest Clang version.")
|
||||
elseif (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
elseif (NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
message(FATAL_ERROR "ImHex can only be compiled with GCC or Clang. ${CMAKE_CXX_COMPILER_ID} is not supported.")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -375,6 +392,12 @@ function(downloadImHexPatternsFiles dest)
|
||||
|
||||
FetchContent_Populate(imhex_patterns)
|
||||
|
||||
else ()
|
||||
# Maybe patterns are cloned to a subdirectory
|
||||
set(imhex_patterns_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImHex-Patterns")
|
||||
endif ()
|
||||
|
||||
if (EXISTS ${imhex_patterns_SOURCE_DIR})
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
|
||||
|
||||
5
dist/AppImageBuilder.yml
vendored
5
dist/AppImageBuilder.yml
vendored
@@ -6,7 +6,7 @@ AppDir:
|
||||
id: imhex
|
||||
name: ImHex
|
||||
icon: imhex
|
||||
version: AppImage
|
||||
version: "{{VERSION}}"
|
||||
exec: usr/bin/imhex
|
||||
exec_args: $@
|
||||
apt:
|
||||
@@ -136,4 +136,5 @@ AppDir:
|
||||
- usr/share/doc/*/TODO.*
|
||||
AppImage:
|
||||
arch: x86_64
|
||||
update-information: guess
|
||||
update-information: gh-releases-zsync|WerWolv|ImHex|latest|imhex-*.AppImage.zsync
|
||||
file_name: imhex-{{VERSION}}.AppImage
|
||||
|
||||
33
dist/Arch/PKGBUILD
vendored
33
dist/Arch/PKGBUILD
vendored
@@ -1,40 +1,29 @@
|
||||
# Maintainer: iTrooz_ <itrooz at protonmail dot com>
|
||||
# Contributor: Morten Linderud <foxboron@archlinux.org>
|
||||
|
||||
pkgname=imhex-bin
|
||||
pkgver=%version%
|
||||
pkgrel=1
|
||||
pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM. "
|
||||
arch=("x86_64")
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
repo=$url
|
||||
license=('GPL 2.0')
|
||||
groups=()
|
||||
license=('GPL2')
|
||||
depends=(glfw mbedtls python freetype2 libglvnd dbus xdg-desktop-portal curl fmt yara nlohmann-json)
|
||||
makedepends=(git)
|
||||
checkdepends=()
|
||||
optdepends=()
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
replaces=()
|
||||
backup=()
|
||||
options=()
|
||||
source=($repo"/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
|
||||
noextract=()
|
||||
source=("$url/releases/download/v$pkgver/imhex-$pkgver-ArchLinux.pkg.tar.zst")
|
||||
md5sums=(SKIP)
|
||||
validpgpkeys=()
|
||||
|
||||
package() {
|
||||
tar -xf imhex-$pkgver-ArchLinux.pkg.tar.zst
|
||||
install -Dm755 "$srcdir/usr/bin/imhex" "$pkgdir/usr/bin/imhex"
|
||||
install -Dm644 "$srcdir/usr/lib/libimhex.so.$pkgver" "$pkgdir/usr/lib/libimhex.so.$pkgver"
|
||||
|
||||
install -DT $srcdir/usr/bin/imhex $pkgdir/usr/bin/imhex
|
||||
install -DT $srcdir/usr/lib/libimhex.so.$pkgver $pkgdir/usr/lib/libimhex.so.$pkgver
|
||||
|
||||
for plugin in $srcdir/usr/lib/imhex/plugins/*.hexplug;
|
||||
do
|
||||
install -DT $plugin $pkgdir/usr/lib/imhex/plugins/`basename $plugin`
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug; do
|
||||
install -Dm644 "$plugin" "$pkgdir/usr/lib/imhex/plugins/${plugin##*/}"
|
||||
done
|
||||
|
||||
mkdir -p $pkgdir/usr/share/imhex
|
||||
cp -r $srcdir/usr/share/imhex/{constants,encodings,includes,magic,patterns} $pkgdir/usr/share/imhex
|
||||
cp -r $srcdir/usr/share/{applications,licenses} $pkgdir/usr/share
|
||||
install -d $pkgdir/usr/share
|
||||
install -d "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/imhex/"{constants,encodings,includes,magic,patterns} "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/"{applications,licenses} "$pkgdir/usr/share"
|
||||
}
|
||||
|
||||
1
dist/Brewfile
vendored
1
dist/Brewfile
vendored
@@ -1,4 +1,3 @@
|
||||
brew "glfw"
|
||||
brew "mbedtls"
|
||||
brew "nlohmann-json"
|
||||
brew "cmake"
|
||||
|
||||
25
dist/macOS/0001-glfw-SW.patch
vendored
Normal file
25
dist/macOS/0001-glfw-SW.patch
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
From 9c8665af4c2e2ce66555c15c05c72027bfdf0cb6 Mon Sep 17 00:00:00 2001
|
||||
From: iTrooz <itrooz@protonmail.com>
|
||||
Date: Mon, 29 Aug 2022 17:29:38 +0200
|
||||
Subject: [PATCH] Use software rendering on MacOS
|
||||
|
||||
---
|
||||
src/nsgl_context.m | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/nsgl_context.m b/src/nsgl_context.m
|
||||
index fc1f7521..e5906575 100644
|
||||
--- a/src/nsgl_context.m
|
||||
+++ b/src/nsgl_context.m
|
||||
@@ -198,7 +198,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
NSOpenGLPixelFormatAttribute attribs[40];
|
||||
int index = 0;
|
||||
|
||||
- ADD_ATTRIB(NSOpenGLPFAAccelerated);
|
||||
+ ADD_ATTRIB(NSOpenGLPFARendererID);ADD_ATTRIB(kCGLRendererGenericFloatID);
|
||||
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
|
||||
|
||||
if (ctxconfig->nsgl.offline)
|
||||
--
|
||||
2.37.2
|
||||
|
||||
34
dist/net.werwolv.imhex.metainfo.xml
vendored
Normal file
34
dist/net.werwolv.imhex.metainfo.xml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>imhex</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0</project_license>
|
||||
<name>ImHex</name>
|
||||
<developer_name>WerWolv</developer_name>
|
||||
<update_contact>hey@werwolv.net</update_contact>
|
||||
<summary>A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM</summary>
|
||||
<description>
|
||||
<p>ImHex is a feature-rich Hex Editor aimed towards Reverse Engineers working with foreign data formats, malware, executables and raw memory.
|
||||
Besides all the features a common Hex Editor has, ImHex also features a custom scripting language used to declare and dissect data structures, support for running YARA rules, a node-based graphical data pre-processor and support for various data sources such as files, raw disks or GDB Servers.</p>
|
||||
</description>
|
||||
<launchable type="desktop-id">imhex.desktop</launchable>
|
||||
<url type="homepage">https://imhex.werwolv.net</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://user-images.githubusercontent.com/10835354/139717326-8044769d-527b-4d88-8adf-2d4ecafdca1f.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://user-images.githubusercontent.com/10835354/139717323-1f8c9d52-f7eb-4f43-9f11-097ac728ed6c.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<provides>
|
||||
<id>imhex.desktop</id>
|
||||
</provides>
|
||||
|
||||
<categories>
|
||||
<category>Development</category>
|
||||
</categories>
|
||||
|
||||
|
||||
</component>
|
||||
2
dist/rpm/imhex.spec
vendored
2
dist/rpm/imhex.spec
vendored
@@ -84,5 +84,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/imhex.desktop
|
||||
%{_datadir}/applications/imhex.desktop
|
||||
%{_prefix}/lib64/libimhex.so.%{_version}
|
||||
%{_prefix}/lib64/imhex/plugins/*
|
||||
%{_metainfodir}/net.werwolv.imhex.metainfo.xml
|
||||
%{_metainfodir}/net.werwolv.imhex.appdata.xml
|
||||
|
||||
%changelog
|
||||
|
||||
2
lib/external/imgui/include/imconfig.h
vendored
2
lib/external/imgui/include/imconfig.h
vendored
@@ -99,7 +99,7 @@
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
|
||||
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 58757f6cad...8c8556dd6b
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 9612e699de...ac2931943d
@@ -58,7 +58,7 @@ if(NOT USE_SYSTEM_CURL)
|
||||
set(LIBCURL_LIBRARIES libcurl)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.78.0)
|
||||
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.76.1)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_LLVM)
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<pl::PatternLanguage> createDefaultRuntime(prv::Provider *provider);
|
||||
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider);
|
||||
|
||||
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler);
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ namespace hex {
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
EVENT_DEF(RequestChangeWindowTitle, std::string);
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
EVENT_DEF(RequestRestartImHex);
|
||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||
EVENT_DEF(RequestChangeTheme, u32);
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
|
||||
@@ -150,15 +150,6 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
namespace Tasks {
|
||||
|
||||
Task createTask(const std::string &unlocalizedName, u64 maxValue);
|
||||
|
||||
void doLater(const std::function<void()> &function);
|
||||
std::vector<std::function<void()>> &getDeferredCalls();
|
||||
|
||||
}
|
||||
|
||||
namespace System {
|
||||
|
||||
namespace impl {
|
||||
@@ -210,6 +201,7 @@ namespace hex {
|
||||
|
||||
std::map<std::string, std::string> &getInitArguments();
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
const std::fs::path &getCustomFontPath();
|
||||
float getFontSize();
|
||||
|
||||
|
||||
@@ -179,10 +179,10 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
static constexpr auto CTRL = Key(static_cast<Keys>(0x1000'0000));
|
||||
static constexpr auto ALT = Key(static_cast<Keys>(0x2000'0000));
|
||||
static constexpr auto SHIFT = Key(static_cast<Keys>(0x4000'0000));
|
||||
static constexpr auto SUPER = Key(static_cast<Keys>(0x8000'0000));
|
||||
constexpr static auto CTRL = Key(static_cast<Keys>(0x1000'0000));
|
||||
constexpr static auto ALT = Key(static_cast<Keys>(0x2000'0000));
|
||||
constexpr static auto SHIFT = Key(static_cast<Keys>(0x4000'0000));
|
||||
constexpr static auto SUPER = Key(static_cast<Keys>(0x8000'0000));
|
||||
|
||||
class ShortcutManager {
|
||||
public:
|
||||
|
||||
@@ -2,40 +2,105 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <cstdio>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class TaskHolder;
|
||||
class TaskManager;
|
||||
|
||||
class Task {
|
||||
public:
|
||||
Task() = default;
|
||||
Task(const std::string &unlocalizedName, u64 maxValue);
|
||||
Task(std::string unlocalizedName, u64 maxValue, std::function<void(Task &)> function);
|
||||
|
||||
Task(const Task&) = delete;
|
||||
Task(Task &&other) noexcept;
|
||||
~Task();
|
||||
|
||||
Task(Task &&other) noexcept;
|
||||
void update(u64 value = 0);
|
||||
void setMaxValue(u64 value);
|
||||
|
||||
void setMaxValue(u64 maxValue);
|
||||
void update(u64 currValue);
|
||||
void finish();
|
||||
[[nodiscard]] bool isFinished() const;
|
||||
[[nodiscard]] bool hadException() const;
|
||||
[[nodiscard]] bool wasInterrupted() const;
|
||||
void clearException();
|
||||
[[nodiscard]] std::string getExceptionMessage() const;
|
||||
|
||||
[[nodiscard]] double getProgress() const;
|
||||
[[nodiscard]] const std::string &getUnlocalizedName();
|
||||
[[nodiscard]] u64 getValue() const;
|
||||
[[nodiscard]] u64 getMaxValue() const;
|
||||
|
||||
[[nodiscard]] const std::string &getName() const;
|
||||
void interrupt();
|
||||
|
||||
[[nodiscard]] bool isPending() const;
|
||||
|
||||
static size_t getRunningTaskCount();
|
||||
static std::list<Task *> &getRunningTasks() { return Task::s_runningTasks; }
|
||||
static std::mutex &getTaskMutex() { return Task::s_taskMutex; }
|
||||
void setInterruptCallback(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
u64 m_maxValue = 0, m_currValue = 0;
|
||||
void finish();
|
||||
void interruption();
|
||||
void exception(const char *message);
|
||||
|
||||
static std::list<Task *> s_runningTasks;
|
||||
static std::mutex s_taskMutex;
|
||||
private:
|
||||
mutable std::mutex m_mutex;
|
||||
|
||||
std::string m_unlocalizedName;
|
||||
u64 m_currValue, m_maxValue;
|
||||
std::thread m_thread;
|
||||
std::function<void()> m_interruptCallback;
|
||||
|
||||
bool m_shouldInterrupt = false;
|
||||
|
||||
bool m_interrupted = false;
|
||||
bool m_finished = false;
|
||||
bool m_hadException = false;
|
||||
std::string m_exceptionMessage;
|
||||
|
||||
struct TaskInterruptor { virtual ~TaskInterruptor() = default; };
|
||||
|
||||
friend class TaskHolder;
|
||||
friend class TaskManager;
|
||||
};
|
||||
|
||||
class TaskHolder {
|
||||
public:
|
||||
TaskHolder() = default;
|
||||
explicit TaskHolder(std::weak_ptr<Task> task) : m_task(std::move(task)) { }
|
||||
|
||||
[[nodiscard]] bool isRunning() const;
|
||||
[[nodiscard]] bool hadException() const;
|
||||
[[nodiscard]] bool wasInterrupted() const;
|
||||
|
||||
void interrupt();
|
||||
private:
|
||||
std::weak_ptr<Task> m_task;
|
||||
};
|
||||
|
||||
class TaskManager {
|
||||
public:
|
||||
TaskManager() = delete;
|
||||
|
||||
constexpr static auto NoProgress = 0;
|
||||
|
||||
static TaskHolder createTask(std::string name, u64 maxValue, std::function<void(Task &)> function);
|
||||
static void collectGarbage();
|
||||
|
||||
static size_t getRunningTaskCount();
|
||||
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
||||
|
||||
static void doLater(const std::function<void()> &function);
|
||||
static void runDeferredCalls();
|
||||
private:
|
||||
static std::mutex s_deferredCallsMutex;
|
||||
|
||||
static std::list<std::shared_ptr<Task>> s_tasks;
|
||||
static std::list<std::function<void()>> s_deferredCalls;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -90,7 +90,7 @@ namespace hex::dp {
|
||||
|
||||
protected:
|
||||
[[noreturn]] void throwNodeError(const std::string &message) {
|
||||
throw NodeError(this, message);
|
||||
throw NodeError { this, message };
|
||||
}
|
||||
|
||||
std::vector<u8> getBufferOnInput(u32 index);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace hex {
|
||||
|
||||
class Disassembler {
|
||||
public:
|
||||
static constexpr cs_arch toCapstoneArchitecture(Architecture architecture) {
|
||||
constexpr static cs_arch toCapstoneArchitecture(Architecture architecture) {
|
||||
return static_cast<cs_arch>(architecture);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace hex {
|
||||
Net();
|
||||
~Net();
|
||||
|
||||
static constexpr u32 DefaultTimeout = 2'000;
|
||||
constexpr static u32 DefaultTimeout = 2'000;
|
||||
|
||||
std::future<Response<std::string>> getString(const std::string &url, u32 timeout = DefaultTimeout);
|
||||
std::future<Response<nlohmann::json>> getJson(const std::string &url, u32 timeout = DefaultTimeout);
|
||||
|
||||
@@ -31,6 +31,16 @@ namespace hex {
|
||||
long double operator""_scaled(unsigned long long value);
|
||||
ImVec2 scaled(const ImVec2 &vector);
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> operator|(const std::vector<T> &lhs, const std::vector<T> &rhs) {
|
||||
std::vector<T> result;
|
||||
|
||||
std::copy(lhs.begin(), lhs.end(), std::back_inserter(result));
|
||||
std::copy(rhs.begin(), rhs.end(), std::back_inserter(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_string(u128 value);
|
||||
std::string to_string(i128 value);
|
||||
|
||||
@@ -68,7 +78,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
constexpr inline i128 signExtend(size_t numBits, i128 value) {
|
||||
i128 mask = 1U << (numBits - 1);
|
||||
i128 mask = 1ULL << (numBits - 1);
|
||||
return (value ^ mask) - mask;
|
||||
}
|
||||
|
||||
@@ -84,6 +94,13 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr inline size_t strnlen(const char *s, size_t n) {
|
||||
size_t i = 0;
|
||||
while (i < n && s[i] != '\x00') i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template<class... Ts>
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
#include <vector>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/literals.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
using namespace hex::literals;
|
||||
|
||||
class BufferedReader {
|
||||
public:
|
||||
explicit BufferedReader(Provider *provider, size_t bufferSize = 0xFF'FFFF)
|
||||
explicit BufferedReader(Provider *provider, size_t bufferSize = 16_MiB)
|
||||
: m_provider(provider), m_bufferAddress(provider->getBaseAddress()), m_maxBufferSize(bufferSize),
|
||||
m_startAddress(0x00), m_endAddress(provider->getActualSize()),
|
||||
m_startAddress(0x00), m_endAddress(provider->getActualSize() - 1),
|
||||
m_buffer(bufferSize) {
|
||||
|
||||
}
|
||||
@@ -215,7 +218,7 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
value_type operator[](i64 offset) const {
|
||||
auto result = this->m_reader->readReverse(this->m_address + offset, 1);
|
||||
auto result = this->m_reader->readReverse(this->m_address - offset, 1);
|
||||
if (result.empty())
|
||||
return 0x00;
|
||||
|
||||
@@ -247,15 +250,17 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
ReverseIterator rend() {
|
||||
return { this, std::numeric_limits<u64>::max() };
|
||||
return { this, 0 };
|
||||
}
|
||||
|
||||
private:
|
||||
void updateBuffer(u64 address, size_t size) {
|
||||
if (!this->m_bufferValid || address < this->m_bufferAddress || address + size > (this->m_bufferAddress + this->m_buffer.size())) {
|
||||
const auto remainingBytes = (this->m_endAddress - address) + 1;
|
||||
const auto remainingBytes = (this->m_endAddress - address) - 1;
|
||||
if (remainingBytes < this->m_maxBufferSize)
|
||||
this->m_buffer.resize(remainingBytes);
|
||||
else
|
||||
this->m_buffer.resize(this->m_maxBufferSize);
|
||||
|
||||
this->m_provider->read(address, this->m_buffer.data(), this->m_buffer.size());
|
||||
this->m_bufferAddress = address;
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace pl {
|
||||
class PatternLanguage;
|
||||
}
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
class Provider {
|
||||
@@ -70,8 +66,8 @@ namespace hex::prv {
|
||||
[[nodiscard]] virtual std::string getName() const = 0;
|
||||
[[nodiscard]] virtual std::vector<std::pair<std::string, std::string>> getDataInformation() const = 0;
|
||||
|
||||
[[nodiscard]] virtual bool open();
|
||||
virtual void close();
|
||||
[[nodiscard]] virtual bool open() = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
void addPatch(u64 offset, const void *buffer, size_t size, bool createUndo = false);
|
||||
void createUndoPoint();
|
||||
|
||||
@@ -241,29 +241,30 @@ namespace hex {
|
||||
return functionName;
|
||||
}
|
||||
|
||||
std::unique_ptr<pl::PatternLanguage> createDefaultRuntime(prv::Provider *provider) {
|
||||
auto runtime = std::make_unique<pl::PatternLanguage>();
|
||||
void configureRuntime(pl::PatternLanguage &runtime, prv::Provider *provider) {
|
||||
runtime.reset();
|
||||
|
||||
if (provider != nullptr) {
|
||||
runtime->setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
|
||||
runtime.setDataSource([provider](u64 offset, u8 *buffer, size_t size) {
|
||||
provider->read(offset, buffer, size);
|
||||
}, provider->getBaseAddress(), provider->getActualSize());
|
||||
}
|
||||
|
||||
runtime->setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude));
|
||||
runtime.setIncludePaths(fs::getDefaultPaths(fs::ImHexPath::PatternsInclude) | fs::getDefaultPaths(fs::ImHexPath::Patterns));
|
||||
|
||||
for (const auto &func : getFunctions()) {
|
||||
if (func.dangerous)
|
||||
runtime->addDangerousFunction(func.ns, func.name, func.parameterCount, func.callback);
|
||||
runtime.addDangerousFunction(func.ns, func.name, func.parameterCount, func.callback);
|
||||
else
|
||||
runtime->addFunction(func.ns, func.name, func.parameterCount, func.callback);
|
||||
runtime.addFunction(func.ns, func.name, func.parameterCount, func.callback);
|
||||
}
|
||||
|
||||
for (const auto &[name, callback] : getPragmas()) {
|
||||
runtime->addPragma(name, callback);
|
||||
runtime.addPragma(name, callback);
|
||||
}
|
||||
|
||||
return runtime;
|
||||
runtime.addDefine("__IMHEX__");
|
||||
runtime.addDefine("__IMHEX_VERSION__", IMHEX_VERSION);
|
||||
}
|
||||
|
||||
void addPragma(const std::string &name, const pl::api::PragmaHandler &handler) {
|
||||
|
||||
@@ -20,11 +20,8 @@ namespace hex {
|
||||
}
|
||||
|
||||
void restartImHex() {
|
||||
EventManager::post<RequestRestartImHex>();
|
||||
EventManager::post<RequestCloseImHex>(false);
|
||||
std::atexit([] {
|
||||
auto &programArgs = ImHexApi::System::getProgramArguments();
|
||||
execve(programArgs.argv[0], programArgs.argv, programArgs.envp);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -211,7 +208,7 @@ namespace hex {
|
||||
|
||||
namespace ImHexApi::Provider {
|
||||
|
||||
static u32 s_currentProvider = std::numeric_limits<u32>::max();
|
||||
static i64 s_currentProvider = -1;
|
||||
static std::vector<prv::Provider *> s_providers;
|
||||
|
||||
namespace impl {
|
||||
@@ -239,7 +236,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void setCurrentProvider(u32 index) {
|
||||
if (Task::getRunningTaskCount() > 0)
|
||||
if (TaskManager::getRunningTaskCount() > 0)
|
||||
return;
|
||||
|
||||
if (index < s_providers.size() && s_currentProvider != index) {
|
||||
@@ -250,7 +247,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
bool isValid() {
|
||||
return !s_providers.empty() && s_currentProvider < s_providers.size();
|
||||
return !s_providers.empty() && s_currentProvider < i64(s_providers.size());
|
||||
}
|
||||
|
||||
void markDirty() {
|
||||
@@ -269,7 +266,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void add(prv::Provider *provider, bool skipLoadInterface) {
|
||||
if (Task::getRunningTaskCount() > 0)
|
||||
if (TaskManager::getRunningTaskCount() > 0)
|
||||
return;
|
||||
|
||||
if (skipLoadInterface)
|
||||
@@ -285,7 +282,7 @@ namespace hex {
|
||||
if (provider == nullptr)
|
||||
return;
|
||||
|
||||
if (Task::getRunningTaskCount() > 0)
|
||||
if (TaskManager::getRunningTaskCount() > 0)
|
||||
return;
|
||||
|
||||
if (!noQuestions) {
|
||||
@@ -310,6 +307,9 @@ namespace hex {
|
||||
else if (it - s_providers.begin() == s_currentProvider)
|
||||
setCurrentProvider(0);
|
||||
|
||||
provider->close();
|
||||
EventManager::post<EventProviderClosed>(provider);
|
||||
|
||||
delete provider;
|
||||
}
|
||||
|
||||
@@ -322,29 +322,6 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ImHexApi::Tasks {
|
||||
|
||||
Task createTask(const std::string &unlocalizedName, u64 maxValue) {
|
||||
return { unlocalizedName, maxValue };
|
||||
}
|
||||
|
||||
void doLater(const std::function<void()> &function) {
|
||||
static std::mutex tasksMutex;
|
||||
std::scoped_lock lock(tasksMutex);
|
||||
|
||||
getDeferredCalls().push_back(function);
|
||||
}
|
||||
|
||||
std::vector<std::function<void()>> &getDeferredCalls() {
|
||||
static std::vector<std::function<void()>> deferredCalls;
|
||||
|
||||
return deferredCalls;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace ImHexApi::System {
|
||||
|
||||
namespace impl {
|
||||
@@ -393,7 +370,7 @@ namespace hex {
|
||||
s_customFontPath = path;
|
||||
}
|
||||
|
||||
static float s_fontSize = 13.0;
|
||||
static float s_fontSize = DefaultFontSize;
|
||||
void setFontSize(float size) {
|
||||
s_fontSize = size;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ namespace hex {
|
||||
tar.write(MetadataPath, metadataContent);
|
||||
}
|
||||
|
||||
ImHexApi::Provider::resetDirty();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,71 +1,200 @@
|
||||
#include <hex/api/task.hpp>
|
||||
|
||||
#include <hex/api/localization.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace hex {
|
||||
|
||||
std::list<Task *> Task::s_runningTasks;
|
||||
std::mutex Task::s_taskMutex;
|
||||
std::mutex TaskManager::s_deferredCallsMutex;
|
||||
|
||||
Task::Task(const std::string &unlocalizedName, u64 maxValue) : m_name(LangEntry(unlocalizedName)), m_maxValue(maxValue), m_currValue(0) {
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
std::list<std::shared_ptr<Task>> TaskManager::s_tasks;
|
||||
std::list<std::function<void()>> TaskManager::s_deferredCalls;
|
||||
|
||||
Task::s_runningTasks.push_back(this);
|
||||
}
|
||||
Task::Task(std::string unlocalizedName, u64 maxValue, std::function<void(Task &)> function)
|
||||
: m_unlocalizedName(std::move(unlocalizedName)), m_currValue(0), m_maxValue(maxValue) {
|
||||
this->m_thread = std::thread([this, func = std::move(function)] {
|
||||
try {
|
||||
func(*this);
|
||||
} catch (const TaskInterruptor &) {
|
||||
this->interruption();
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Exception in task {}: {}", this->m_unlocalizedName, e.what());
|
||||
this->exception(e.what());
|
||||
} catch (...) {
|
||||
log::error("Exception in task {}", this->m_unlocalizedName);
|
||||
this->exception("Unknown Exception");
|
||||
}
|
||||
|
||||
Task::~Task() {
|
||||
this->finish();
|
||||
this->finish();
|
||||
});
|
||||
}
|
||||
|
||||
Task::Task(hex::Task &&other) noexcept {
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
std::scoped_lock thisLock(this->m_mutex);
|
||||
std::scoped_lock otherLock(other.m_mutex);
|
||||
|
||||
this->m_thread = std::move(other.m_thread);
|
||||
this->m_unlocalizedName = std::move(other.m_unlocalizedName);
|
||||
|
||||
this->m_name = other.m_name;
|
||||
this->m_maxValue = other.m_maxValue;
|
||||
this->m_currValue = other.m_currValue;
|
||||
|
||||
auto it = std::find(Task::s_runningTasks.begin(), Task::s_runningTasks.end(), &other);
|
||||
if (it != Task::s_runningTasks.end()) {
|
||||
*it = this;
|
||||
}
|
||||
this->m_finished = other.m_finished;
|
||||
this->m_hadException = other.m_hadException;
|
||||
this->m_interrupted = other.m_interrupted;
|
||||
this->m_shouldInterrupt = other.m_shouldInterrupt;
|
||||
}
|
||||
|
||||
Task::~Task() {
|
||||
if (!this->isFinished())
|
||||
this->interrupt();
|
||||
|
||||
this->m_thread.join();
|
||||
}
|
||||
|
||||
void Task::update(u64 value) {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_currValue = value;
|
||||
|
||||
if (this->m_shouldInterrupt)
|
||||
throw TaskInterruptor();
|
||||
}
|
||||
|
||||
void Task::setMaxValue(u64 value) {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_maxValue = value;
|
||||
}
|
||||
|
||||
|
||||
void Task::interrupt() {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_shouldInterrupt = true;
|
||||
|
||||
if (this->m_interruptCallback)
|
||||
this->m_interruptCallback();
|
||||
}
|
||||
|
||||
void Task::setInterruptCallback(std::function<void()> callback) {
|
||||
this->m_interruptCallback = std::move(callback);
|
||||
}
|
||||
|
||||
bool Task::isFinished() const {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
return this->m_finished;
|
||||
}
|
||||
|
||||
bool Task::hadException() const {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
return this->m_hadException;
|
||||
}
|
||||
|
||||
bool Task::wasInterrupted() const {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
return this->m_interrupted;
|
||||
}
|
||||
|
||||
void Task::clearException() {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_hadException = false;
|
||||
}
|
||||
|
||||
std::string Task::getExceptionMessage() const {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
return this->m_exceptionMessage;
|
||||
}
|
||||
|
||||
const std::string &Task::getUnlocalizedName() {
|
||||
return this->m_unlocalizedName;
|
||||
}
|
||||
|
||||
u64 Task::getValue() const {
|
||||
return this->m_currValue;
|
||||
}
|
||||
|
||||
u64 Task::getMaxValue() const {
|
||||
return this->m_maxValue;
|
||||
}
|
||||
|
||||
void Task::finish() {
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
Task::s_runningTasks.remove(this);
|
||||
this->m_finished = true;
|
||||
}
|
||||
|
||||
void Task::setMaxValue(u64 maxValue) {
|
||||
this->m_maxValue = maxValue;
|
||||
void Task::interruption() {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_interrupted = true;
|
||||
}
|
||||
|
||||
void Task::update(u64 currValue) {
|
||||
if (this->m_currValue < this->m_maxValue)
|
||||
this->m_currValue = currValue;
|
||||
void Task::exception(const char *message) {
|
||||
std::scoped_lock lock(this->m_mutex);
|
||||
|
||||
this->m_exceptionMessage = message;
|
||||
this->m_hadException = true;
|
||||
}
|
||||
|
||||
double Task::getProgress() const {
|
||||
if (this->m_maxValue == 0)
|
||||
return 100;
|
||||
|
||||
return static_cast<double>(this->m_currValue) / static_cast<double>(this->m_maxValue);
|
||||
bool TaskHolder::isRunning() const {
|
||||
return !m_task.expired() && !m_task.lock()->isFinished();
|
||||
}
|
||||
|
||||
bool Task::isPending() const {
|
||||
return this->m_maxValue == 0;
|
||||
bool TaskHolder::hadException() const {
|
||||
return m_task.expired() || m_task.lock()->hadException();
|
||||
}
|
||||
|
||||
const std::string &Task::getName() const {
|
||||
return this->m_name;
|
||||
bool TaskHolder::wasInterrupted() const {
|
||||
return m_task.expired() || m_task.lock()->wasInterrupted();
|
||||
}
|
||||
|
||||
size_t Task::getRunningTaskCount() {
|
||||
std::scoped_lock lock(Task::s_taskMutex);
|
||||
void TaskHolder::interrupt() {
|
||||
if (!this->m_task.expired())
|
||||
this->m_task.lock()->interrupt();
|
||||
}
|
||||
|
||||
return Task::s_runningTasks.size();
|
||||
|
||||
TaskHolder TaskManager::createTask(std::string name, u64 maxValue, std::function<void(Task &)> function) {
|
||||
s_tasks.emplace_back(std::make_shared<Task>(std::move(name), maxValue, std::move(function)));
|
||||
|
||||
return TaskHolder(s_tasks.back());
|
||||
}
|
||||
|
||||
void TaskManager::collectGarbage() {
|
||||
std::erase_if(s_tasks, [](const auto &task) { return task->isFinished() && !task->hadException(); });
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<Task>> &TaskManager::getRunningTasks() {
|
||||
return s_tasks;
|
||||
}
|
||||
|
||||
size_t TaskManager::getRunningTaskCount() {
|
||||
return s_tasks.size();
|
||||
}
|
||||
|
||||
|
||||
void TaskManager::doLater(const std::function<void()> &function) {
|
||||
std::scoped_lock lock(s_deferredCallsMutex);
|
||||
|
||||
s_deferredCalls.push_back(function);
|
||||
}
|
||||
|
||||
void TaskManager::runDeferredCalls() {
|
||||
std::scoped_lock lock(s_deferredCallsMutex);
|
||||
|
||||
for (const auto &call : s_deferredCalls)
|
||||
call();
|
||||
|
||||
s_deferredCalls.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <hex/helpers/file.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace hex::fs {
|
||||
|
||||
@@ -90,7 +91,7 @@ namespace hex::fs {
|
||||
return "";
|
||||
|
||||
auto cString = reinterpret_cast<const char *>(bytes.data());
|
||||
return { cString, std::min(bytes.size(), std::strlen(cString)) };
|
||||
return { cString, hex::strnlen(cString, bytes.size()) };
|
||||
}
|
||||
|
||||
std::u8string File::readU8String(size_t numBytes) {
|
||||
@@ -104,7 +105,7 @@ namespace hex::fs {
|
||||
return u8"";
|
||||
|
||||
auto cString = reinterpret_cast<const char8_t *>(bytes.data());
|
||||
return { cString, std::min(bytes.size(), std::strlen(reinterpret_cast<const char*>(bytes.data()))) };
|
||||
return { cString, hex::strnlen(reinterpret_cast<const char*>(bytes.data()), bytes.size()) };
|
||||
}
|
||||
|
||||
void File::write(const u8 *buffer, size_t size) {
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace hex {
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_NOSIGNAL, 1L);
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_NOPROGRESS, 0L);
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#if defined(IMHEX_USE_BUNDLED_CA)
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_CAINFO, nullptr);
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_CAPATH, nullptr);
|
||||
curl_easy_setopt(this->m_ctx, CURLOPT_SSLCERTTYPE, "PEM");
|
||||
@@ -124,7 +124,7 @@ namespace hex {
|
||||
if (result != CURLE_OK)
|
||||
log::error("Net request failed with error {0}: '{1}'", u32(result), curl_easy_strerror(result));
|
||||
|
||||
i32 responseCode = 0;
|
||||
long responseCode = 0;
|
||||
curl_easy_getinfo(this->m_ctx, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
|
||||
curl_slist_free_all(this->m_headers);
|
||||
@@ -135,7 +135,7 @@ namespace hex {
|
||||
if (result != CURLE_OK)
|
||||
return std::nullopt;
|
||||
else
|
||||
return responseCode;
|
||||
return i32(responseCode);
|
||||
}
|
||||
|
||||
std::future<Response<std::string>> Net::getString(const std::string &url, u32 timeout) {
|
||||
@@ -167,8 +167,10 @@ namespace hex {
|
||||
setCommonSettings(response, url, timeout);
|
||||
|
||||
auto responseCode = execute();
|
||||
|
||||
return Response<nlohmann::json> { responseCode.value_or(0), nlohmann::json::parse(response) };
|
||||
if (!responseCode.has_value())
|
||||
return Response<nlohmann::json> { 0, { } };
|
||||
else
|
||||
return Response<nlohmann::json> { responseCode.value_or(0), nlohmann::json::parse(response, nullptr, false, true) };
|
||||
});
|
||||
}
|
||||
|
||||
@@ -188,15 +190,26 @@ namespace hex {
|
||||
curl_mimepart *part = curl_mime_addpart(mime);
|
||||
|
||||
auto fileName = filePath.filename().string();
|
||||
curl_mime_data_cb(
|
||||
part, file.getSize(), [](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
|
||||
curl_mime_data_cb(part, file.getSize(),
|
||||
[](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
return fread(buffer, size, nitems, file); }, [](void *arg, curl_off_t offset, int origin) -> int {
|
||||
|
||||
return fread(buffer, size, nitems, file);
|
||||
},
|
||||
[](void *arg, curl_off_t offset, int origin) -> int {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
fseek(file, offset, origin);
|
||||
return CURL_SEEKFUNC_OK; }, [](void *arg) {
|
||||
|
||||
if (fseek(file, offset, origin) != 0)
|
||||
return CURL_SEEKFUNC_CANTSEEK;
|
||||
else
|
||||
return CURL_SEEKFUNC_OK;
|
||||
},
|
||||
[](void *arg) {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
fclose(file); }, file.getHandle());
|
||||
|
||||
fclose(file);
|
||||
},
|
||||
file.getHandle());
|
||||
curl_mime_filename(part, fileName.c_str());
|
||||
curl_mime_name(part, "file");
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
std::string toEngineeringString(double value) {
|
||||
constexpr std::array Suffixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" };
|
||||
constexpr static std::array Suffixes = { "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E" };
|
||||
|
||||
int8_t suffixIndex = 6;
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace hex {
|
||||
auto c = [&] { return string[offset]; };
|
||||
|
||||
if (c() == '\\') {
|
||||
if ((offset + 2) >= string.length()) return {};
|
||||
if ((offset + 2) > string.length()) return {};
|
||||
|
||||
offset++;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace hex::prv {
|
||||
Provider::~Provider() {
|
||||
for (auto &overlay : this->m_overlays)
|
||||
this->deleteOverlay(overlay);
|
||||
this->close();
|
||||
}
|
||||
|
||||
void Provider::read(u64 offset, void *buffer, size_t size, bool overlays) {
|
||||
@@ -171,14 +170,6 @@ namespace hex::prv {
|
||||
return page;
|
||||
}
|
||||
|
||||
bool Provider::open() {
|
||||
EventManager::post<EventProviderOpened>(this);
|
||||
return true;
|
||||
}
|
||||
void Provider::close() {
|
||||
EventManager::post<EventProviderClosed>(this);
|
||||
}
|
||||
|
||||
void Provider::addPatch(u64 offset, const void *buffer, size_t size, bool createUndo) {
|
||||
if (this->m_patchTreeOffset > 0) {
|
||||
auto iter = this->m_patches.end();
|
||||
@@ -266,7 +257,7 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> Provider::getRegionValidity(u64 address) const {
|
||||
if (address > this->getActualSize())
|
||||
if ((address - this->getBaseAddress()) > this->getActualSize())
|
||||
return { Region::Invalid(), false };
|
||||
|
||||
bool insideValidRegion = false;
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <imgui_impl_opengl3_loader.h>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
|
||||
namespace ImGui {
|
||||
|
||||
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data) {
|
||||
@@ -536,7 +538,7 @@ namespace ImGui {
|
||||
const ImGuiStyle &style = g.Style;
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos + ImVec2(0, yOffset);
|
||||
ImVec2 size = CalcItemSize(ImVec2(100, 5), 100, g.FontSize + style.FramePadding.y * 2.0f);
|
||||
ImVec2 size = CalcItemSize(ImVec2(100, 5) * hex::ImHexApi::System::getGlobalScale(), 100, g.FontSize + style.FramePadding.y * 2.0f);
|
||||
ImRect bb(pos, pos + size);
|
||||
ItemSize(size, 0);
|
||||
if (!ItemAdd(bb, 0))
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
ImVec2 View::getMinSize() const {
|
||||
return scaled(ImVec2(480, 720));
|
||||
return scaled(ImVec2(10, 10));
|
||||
}
|
||||
|
||||
ImVec2 View::getMaxSize() const {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <imgui_freetype.h>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/project_file_manager.hpp>
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/helpers/net.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
@@ -173,7 +174,6 @@ namespace hex::init {
|
||||
ContentRegistry::Provider::getEntries().clear();
|
||||
|
||||
ImHexApi::System::getInitArguments().clear();
|
||||
ImHexApi::Tasks::getDeferredCalls().clear();
|
||||
ImHexApi::HexEditor::impl::getBackgroundHighlights().clear();
|
||||
ImHexApi::HexEditor::impl::getForegroundHighlights().clear();
|
||||
ImHexApi::HexEditor::impl::getBackgroundHighlightingFunctions().clear();
|
||||
@@ -215,12 +215,13 @@ namespace hex::init {
|
||||
|
||||
ShortcutManager::clearShortcuts();
|
||||
|
||||
hex::Task::getRunningTasks().clear();
|
||||
TaskManager::getRunningTasks().clear();
|
||||
|
||||
ContentRegistry::DataProcessorNode::getEntries().clear();
|
||||
|
||||
ContentRegistry::DataFormatter::getEntries().clear();
|
||||
ContentRegistry::FileHandler::getEntries().clear();
|
||||
ContentRegistry::Hashes::impl::getHashes().clear();
|
||||
|
||||
{
|
||||
auto &visualizers = ContentRegistry::HexEditor::impl::getVisualizers();
|
||||
@@ -229,6 +230,9 @@ namespace hex::init {
|
||||
visualizers.clear();
|
||||
}
|
||||
|
||||
ProjectFile::getHandlers().clear();
|
||||
ProjectFile::getProviderHandlers().clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,42 +18,49 @@ int main(int argc, char **argv, char **envp) {
|
||||
ImHexApi::System::impl::setBorderlessWindowMode(true);
|
||||
#endif
|
||||
|
||||
// Initialization
|
||||
{
|
||||
Window::initNative();
|
||||
bool shouldRestart = false;
|
||||
|
||||
hex::log::info("Welcome to ImHex!");
|
||||
EventManager::subscribe<RequestRestartImHex>([&]{ shouldRestart = true; });
|
||||
|
||||
init::WindowSplash splashWindow;
|
||||
do {
|
||||
shouldRestart = false;
|
||||
|
||||
for (const auto &[name, task] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task);
|
||||
// Initialization
|
||||
{
|
||||
Window::initNative();
|
||||
|
||||
if (!splashWindow.loop())
|
||||
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
||||
}
|
||||
hex::log::info("Welcome to ImHex!");
|
||||
|
||||
// Clean up
|
||||
ON_SCOPE_EXIT {
|
||||
for (const auto &[name, task] : init::getExitTasks())
|
||||
task();
|
||||
};
|
||||
init::WindowSplash splashWindow;
|
||||
|
||||
// Main window
|
||||
{
|
||||
Window window;
|
||||
for (const auto &[name, task] : init::getInitTasks())
|
||||
splashWindow.addStartupTask(name, task);
|
||||
|
||||
if (argc == 1)
|
||||
; // No arguments provided
|
||||
else if (argc == 2)
|
||||
EventManager::post<RequestOpenFile>(argv[1]);
|
||||
else {
|
||||
hex::log::fatal("Usage: {} [<file_name>]", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
if (!splashWindow.loop())
|
||||
ImHexApi::System::getInitArguments().insert({ "tasks-failed", {} });
|
||||
}
|
||||
|
||||
window.loop();
|
||||
}
|
||||
// Clean up
|
||||
ON_SCOPE_EXIT {
|
||||
for (const auto &[name, task] : init::getExitTasks())
|
||||
task();
|
||||
};
|
||||
|
||||
// Main window
|
||||
{
|
||||
Window window;
|
||||
|
||||
if (argc == 1)
|
||||
; // No arguments provided
|
||||
else if (argc >= 2) {
|
||||
for (auto i = 1; i < argc; i++)
|
||||
EventManager::post<RequestOpenFile>(argv[i]);
|
||||
}
|
||||
|
||||
window.loop();
|
||||
}
|
||||
|
||||
} while (shouldRestart);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,39 @@ namespace hex {
|
||||
static float g_titleBarHeight;
|
||||
static ImGuiMouseCursor g_mouseCursorIcon;
|
||||
|
||||
static LRESULT windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
static LRESULT commonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (uMsg) {
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
auto message = reinterpret_cast<COPYDATASTRUCT *>(lParam);
|
||||
if (message == nullptr) break;
|
||||
|
||||
auto data = reinterpret_cast<const char8_t *>(message->lpData);
|
||||
if (data == nullptr) break;
|
||||
|
||||
std::fs::path path = data;
|
||||
log::info("Opening file in existing instance: {}", path.string());
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
break;
|
||||
}
|
||||
case WM_SETTINGCHANGE:
|
||||
{
|
||||
if (lParam == 0) break;
|
||||
|
||||
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
|
||||
EventManager::post<EventOSThemeChanged>();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc((WNDPROC)g_oldWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT borderlessWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (uMsg) {
|
||||
case WM_NCACTIVATE:
|
||||
case WM_NCPAINT:
|
||||
@@ -106,11 +138,11 @@ namespace hex {
|
||||
return HTNOWHERE;
|
||||
}
|
||||
|
||||
constexpr auto RegionClient = 0b0000;
|
||||
constexpr auto RegionLeft = 0b0001;
|
||||
constexpr auto RegionRight = 0b0010;
|
||||
constexpr auto RegionTop = 0b0100;
|
||||
constexpr auto RegionBottom = 0b1000;
|
||||
constexpr static auto RegionClient = 0b0000;
|
||||
constexpr static auto RegionLeft = 0b0001;
|
||||
constexpr static auto RegionRight = 0b0010;
|
||||
constexpr static auto RegionTop = 0b0100;
|
||||
constexpr static auto RegionBottom = 0b1000;
|
||||
|
||||
const auto result =
|
||||
RegionLeft * (cursor.x < (window.left + border.x)) |
|
||||
@@ -146,35 +178,11 @@ namespace hex {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_SETTINGCHANGE:
|
||||
{
|
||||
if (lParam == 0) break;
|
||||
|
||||
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
|
||||
EventManager::post<EventOSThemeChanged>();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_COPYDATA:
|
||||
{
|
||||
auto message = reinterpret_cast<COPYDATASTRUCT *>(lParam);
|
||||
if (message == nullptr) break;
|
||||
|
||||
auto data = reinterpret_cast<const char8_t *>(message->lpData);
|
||||
if (data == nullptr) break;
|
||||
|
||||
std::fs::path path = data;
|
||||
log::info("Opening file in existing instance: {}", path.string());
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc((WNDPROC)g_oldWndProc, hwnd, uMsg, wParam, lParam);
|
||||
return commonWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +263,7 @@ namespace hex {
|
||||
|
||||
|
||||
if (borderlessWindowMode) {
|
||||
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)windowProc);
|
||||
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)borderlessWindowProc);
|
||||
|
||||
MARGINS borderless = { 1, 1, 1, 1 };
|
||||
::DwmExtendFrameIntoClientArea(hwnd, &borderless);
|
||||
@@ -265,6 +273,8 @@ namespace hex {
|
||||
|
||||
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE);
|
||||
::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW);
|
||||
} else {
|
||||
g_oldWndProc = ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)commonWindowProc);
|
||||
}
|
||||
|
||||
// Catch heap corruption
|
||||
|
||||
@@ -86,11 +86,11 @@ namespace hex {
|
||||
{
|
||||
for (const auto &[argument, value] : ImHexApi::System::getInitArguments()) {
|
||||
if (argument == "no-plugins") {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Plugins"); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("No Plugins"); });
|
||||
} else if (argument == "no-builtin-plugin") {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("No Builtin Plugin"); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("No Builtin Plugin"); });
|
||||
} else if (argument == "multiple-builtin-plugins") {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("Multiple Builtin Plugins"); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("Multiple Builtin Plugins"); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,23 +114,24 @@ namespace hex {
|
||||
|
||||
if (ImHexApi::Provider::isValid()) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
if (!windowTitle.empty())
|
||||
if (!windowTitle.empty() && provider != nullptr) {
|
||||
title += " - " + windowTitle;
|
||||
|
||||
if (provider->isDirty())
|
||||
title += " (*)";
|
||||
if (provider->isDirty())
|
||||
title += " (*)";
|
||||
|
||||
if (!provider->isWritable())
|
||||
title += " (Read Only)";
|
||||
if (!provider->isWritable())
|
||||
title += " (Read Only)";
|
||||
}
|
||||
}
|
||||
|
||||
this->m_windowTitle = title;
|
||||
glfwSetWindowTitle(this->m_window, title.c_str());
|
||||
});
|
||||
|
||||
constexpr auto CrashBackupFileName = "crash_backup.hexproj";
|
||||
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
|
||||
|
||||
EventManager::subscribe<EventAbnormalTermination>(this, [this, CrashBackupFileName](int) {
|
||||
EventManager::subscribe<EventAbnormalTermination>(this, [this](int) {
|
||||
ImGui::SaveIniSettingsToDisk(this->m_imguiSettingsPath.string().c_str());
|
||||
|
||||
if (!ImHexApi::Provider::isDirty())
|
||||
@@ -179,7 +180,7 @@ namespace hex {
|
||||
} else {
|
||||
glfwPollEvents();
|
||||
|
||||
bool frameRateUnlocked = ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || Task::getRunningTaskCount() > 0 || this->m_mouseButtonDown || this->m_hadEvent || !this->m_pressedKeys.empty();
|
||||
bool frameRateUnlocked = ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopupId) || TaskManager::getRunningTaskCount() > 0 || this->m_mouseButtonDown || this->m_hadEvent || !this->m_pressedKeys.empty();
|
||||
const double timeout = std::max(0.0, (1.0 / 5.0) - (glfwGetTime() - this->m_lastFrameTime));
|
||||
|
||||
if ((this->m_lastFrameTime - this->m_frameRateUnlockTime) > 5 && this->m_frameRateTemporarilyUnlocked && !frameRateUnlocked) {
|
||||
@@ -202,8 +203,11 @@ namespace hex {
|
||||
this->frameEnd();
|
||||
|
||||
const auto targetFps = ImHexApi::System::getTargetFPS();
|
||||
if (targetFps <= 200)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(u64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000)));
|
||||
if (targetFps <= 200) {
|
||||
auto leftoverFrameTime = i64((this->m_lastFrameTime + 1 / targetFps - glfwGetTime()) * 1000);
|
||||
if (leftoverFrameTime > 0)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(leftoverFrameTime));
|
||||
}
|
||||
|
||||
this->m_lastFrameTime = glfwGetTime();
|
||||
|
||||
@@ -421,7 +425,6 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this->m_popupsToOpen.remove_if([](const auto &name) {
|
||||
if (ImGui::IsPopupOpen(name.c_str()))
|
||||
return true;
|
||||
@@ -431,17 +434,12 @@ namespace hex {
|
||||
return false;
|
||||
});
|
||||
|
||||
TaskManager::runDeferredCalls();
|
||||
|
||||
EventManager::post<EventFrameBegin>();
|
||||
}
|
||||
|
||||
void Window::frame() {
|
||||
{
|
||||
auto &calls = ImHexApi::Tasks::getDeferredCalls();
|
||||
for (const auto &callback : calls)
|
||||
callback();
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
auto &io = ImGui::GetIO();
|
||||
for (auto &[name, view] : ContentRegistry::Views::getEntries()) {
|
||||
ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
|
||||
@@ -452,7 +450,8 @@ namespace hex {
|
||||
continue;
|
||||
|
||||
if (view->isAvailable()) {
|
||||
ImGui::SetNextWindowSizeConstraints(scaled(view->getMinSize()), scaled(view->getMaxSize()));
|
||||
float fontScaling = std::max(1.0F, ImHexApi::System::getFontSize() / ImHexApi::System::DefaultFontSize);
|
||||
ImGui::SetNextWindowSizeConstraints(view->getMinSize() * fontScaling, view->getMaxSize() * fontScaling);
|
||||
view->drawContent();
|
||||
}
|
||||
|
||||
@@ -485,6 +484,8 @@ namespace hex {
|
||||
void Window::frameEnd() {
|
||||
EventManager::post<EventFrameEnd>();
|
||||
|
||||
TaskManager::collectGarbage();
|
||||
|
||||
this->endNativeWindowFrame();
|
||||
ImGui::Render();
|
||||
|
||||
|
||||
@@ -52,16 +52,16 @@ add_library(${PROJECT_NAME} SHARED
|
||||
source/content/views/view_provider_settings.cpp
|
||||
source/content/views/view_find.cpp
|
||||
|
||||
source/content/helpers/math_evaluator.cpp
|
||||
source/content/helpers/pattern_drawer.cpp
|
||||
|
||||
source/math_evaluator.cpp
|
||||
source/pattern_drawer.cpp
|
||||
|
||||
source/lang/en_US.cpp
|
||||
source/lang/de_DE.cpp
|
||||
source/lang/en_US.cpp
|
||||
source/lang/it_IT.cpp
|
||||
source/lang/zh_CN.cpp
|
||||
source/lang/ja_JP.cpp
|
||||
source/lang/ko_KR.cpp
|
||||
source/lang/pt_BR.cpp
|
||||
source/lang/zh_CN.cpp
|
||||
source/lang/zh_TW.cpp
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ add_library(${PROJECT_NAME} SHARED
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE include)
|
||||
|
||||
# Add additional libraries here #
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE libimhex LLVMDemangle)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE libimhex)
|
||||
|
||||
# ---- No need to change anything from here downwards unless you know what you're doing ---- #
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace hex {
|
||||
};
|
||||
|
||||
static i16 comparePrecedence(const Operator &a, const Operator &b);
|
||||
static bool isLeftAssociative(const Operator op);
|
||||
static bool isLeftAssociative(const Operator &op);
|
||||
static std::pair<Operator, size_t> toOperator(const std::string &input);
|
||||
|
||||
private:
|
||||
@@ -34,12 +34,6 @@ namespace hex {
|
||||
void visit(pl::ptrn::PatternWideString& pattern) override;
|
||||
|
||||
private:
|
||||
void createDefaultEntry(const pl::ptrn::Pattern &pattern, const std::string &value, pl::core::Token::Literal &&literal) const;
|
||||
void createLeafNode(const pl::ptrn::Pattern& pattern) const;
|
||||
bool createTreeNode(const pl::ptrn::Pattern& pattern) const;
|
||||
|
||||
void makeSelectable(const pl::ptrn::Pattern &pattern) const;
|
||||
|
||||
void draw(pl::ptrn::Pattern& pattern);
|
||||
|
||||
template<ArrayPattern T>
|
||||
@@ -53,19 +47,12 @@ namespace hex {
|
||||
});
|
||||
}
|
||||
|
||||
this->drawArrayEnd(pattern, opened);
|
||||
this->drawArrayEnd(pattern, opened, pattern.isInlined());
|
||||
}
|
||||
|
||||
bool drawArrayRoot(pl::ptrn::Pattern& pattern, size_t entryCount, bool isInlined);
|
||||
void drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern);
|
||||
void drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened);
|
||||
|
||||
void drawCommentTooltip(const pl::ptrn::Pattern &pattern) const;
|
||||
void drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) const;
|
||||
void drawNameColumn(const pl::ptrn::Pattern& pattern) const;
|
||||
void drawColorColumn(const pl::ptrn::Pattern& pattern) const;
|
||||
void drawOffsetColumn(const pl::ptrn::Pattern& pattern) const;
|
||||
void drawSizeColumn(const pl::ptrn::Pattern& pattern) const;
|
||||
void drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined);
|
||||
|
||||
u64& getDisplayEnd(const pl::ptrn::Pattern& pattern);
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace hex::plugin::builtin::prv {
|
||||
[[nodiscard]] bool isResizable() const override { return false; }
|
||||
[[nodiscard]] bool isSavable() const override { return false; }
|
||||
|
||||
void setBaseAddress(u64 address) override;
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
[[nodiscard]] size_t getActualSize() const override;
|
||||
|
||||
@@ -15,6 +15,9 @@ namespace hex::plugin::builtin::prv {
|
||||
[[nodiscard]] bool isResizable() const override { return false; }
|
||||
[[nodiscard]] bool isSavable() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override { return true; }
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override { hex::unused(offset, buffer, size); }
|
||||
[[nodiscard]] size_t getActualSize() const override { return 0x00; }
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace hex::plugin::builtin {
|
||||
void drawContent() override;
|
||||
|
||||
private:
|
||||
bool m_disassembling = false;
|
||||
TaskHolder m_disassemblerTask;
|
||||
|
||||
u64 m_baseAddress = 0;
|
||||
ui::SelectedRegion m_range = ui::SelectedRegion::EntireData;
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
struct Regex {
|
||||
std::string pattern;
|
||||
bool fullMatch = true;
|
||||
} regex;
|
||||
|
||||
struct BinaryPattern {
|
||||
@@ -73,11 +74,11 @@ namespace hex::plugin::builtin {
|
||||
|
||||
std::map<prv::Provider*, std::vector<Occurrence>> m_foundOccurrences, m_sortedOccurrences;
|
||||
std::map<prv::Provider*, OccurrenceTree> m_occurrenceTree;
|
||||
std::map<prv::Provider*, std::string> m_currFilter;
|
||||
|
||||
std::atomic<bool> m_searchRunning;
|
||||
TaskHolder m_searchTask;
|
||||
bool m_settingsValid = false;
|
||||
|
||||
std::string m_currFilter;
|
||||
private:
|
||||
static std::vector<Occurrence> searchStrings(Task &task, prv::Provider *provider, Region searchRegion, SearchSettings::Strings settings);
|
||||
static std::vector<Occurrence> searchSequence(Task &task, prv::Provider *provider, Region searchRegion, SearchSettings::Bytes settings);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/ui/view.hpp>
|
||||
#include <hex/api/task.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
@@ -27,7 +28,7 @@ namespace hex::plugin::builtin {
|
||||
double m_entropyHandlePosition;
|
||||
|
||||
std::array<ImU64, 256> m_valueCounts = { 0 };
|
||||
bool m_analyzing = false;
|
||||
TaskHolder m_analyzerTask;
|
||||
|
||||
Region m_analyzedRegion = { 0, 0 };
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "pattern_drawer.hpp"
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <content/helpers/pattern_drawer.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <cstdio>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/view.hpp>
|
||||
|
||||
#include <hex/api/task.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class ViewYara : public View {
|
||||
@@ -29,7 +31,7 @@ namespace hex::plugin::builtin {
|
||||
std::vector<std::pair<std::fs::path, std::fs::path>> m_rules;
|
||||
std::vector<YaraMatch> m_matches;
|
||||
u32 m_selectedRule = 0;
|
||||
bool m_matching = false;
|
||||
TaskHolder m_matcherTask;
|
||||
|
||||
std::vector<std::string> m_consoleMessages;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
#include "math_evaluator.hpp"
|
||||
#include <content/helpers/math_evaluator.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
@@ -1,34 +1,42 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/providers/buffered_reader.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
static std::string formatLanguageArray(prv::Provider *provider, u64 offset, size_t size, const std::string &start, const std::string &byteFormat, const std::string &end) {
|
||||
constexpr auto NewLineIndent = "\n ";
|
||||
constexpr static auto NewLineIndent = "\n ";
|
||||
constexpr static auto LineLength = 16;
|
||||
|
||||
std::string result = start;
|
||||
std::string result;
|
||||
result.reserve(start.size() + hex::format(byteFormat, 0x00).size() * size + + std::string(NewLineIndent).size() / LineLength + end.size());
|
||||
|
||||
std::vector<u8> buffer(0x1'0000, 0x00);
|
||||
for (u64 i = 0; i < size; i += buffer.size()) {
|
||||
size_t readSize = std::min<u64>(buffer.size(), size - i);
|
||||
provider->read(offset, buffer.data(), readSize);
|
||||
result += start;
|
||||
|
||||
for (u32 j = 0; j < readSize; j++) {
|
||||
if (j % 0x10 == 0)
|
||||
result += NewLineIndent;
|
||||
auto reader = prv::BufferedReader(provider);
|
||||
reader.seek(offset);
|
||||
reader.setEndAddress(offset + size);
|
||||
|
||||
result += hex::format(byteFormat, buffer[j]);
|
||||
}
|
||||
u64 index = 0x00;
|
||||
for (u8 byte : reader) {
|
||||
if ((index % LineLength) == 0x00)
|
||||
result += NewLineIndent;
|
||||
|
||||
// Remove trailing comma
|
||||
result += hex::format(byteFormat, byte);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// Remove trailing comma
|
||||
if (provider->getActualSize() > 0) {
|
||||
result.pop_back();
|
||||
result.pop_back();
|
||||
}
|
||||
|
||||
result += "\n";
|
||||
result += end;
|
||||
result += "\n" + end;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -63,45 +71,78 @@ namespace hex::plugin::builtin {
|
||||
return formatLanguageArray(provider, offset, size, "const data = new Uint8Array([", "0x{0:02X}, ", "]);");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.lua", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
return formatLanguageArray(provider, offset, size, "data = {", "0x{0:02X}, ", "}");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.go", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
return formatLanguageArray(provider, offset, size, "data := [...]byte {", "0x{0:02X}, ", "}");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.crystal", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
return formatLanguageArray(provider, offset, size, "data = [", "0x{0:02X}, ", "] of UInt8");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.swift", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
return formatLanguageArray(provider, offset, size, "let data: [Uint8] = [", "0x{0:02X}, ", "]");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.pascal", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
return formatLanguageArray(provider, offset, size, hex::format("data: array[0..{0}] of Byte = (", size - 1), "${0:02X}, ", ")");
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.base64", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
std::vector<u8> data(size, 0x00);
|
||||
provider->read(offset, data.data(), size);
|
||||
|
||||
auto result = crypt::encode64(data);
|
||||
|
||||
return std::string(result.begin(), result.end());
|
||||
});
|
||||
|
||||
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.ascii", [](prv::Provider *provider, u64 offset, size_t size) {
|
||||
std::string result = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n";
|
||||
constexpr static auto HeaderLine = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n";
|
||||
std::string result;
|
||||
result.reserve(std::string(HeaderLine).size() * size / 0x10);
|
||||
|
||||
std::vector<u8> buffer(0x1'0000, 0x00);
|
||||
for (u64 byte = 0; byte < size; byte += buffer.size()) {
|
||||
size_t readSize = std::min<u64>(buffer.size(), size - byte);
|
||||
provider->read(offset, buffer.data(), readSize);
|
||||
result += HeaderLine;
|
||||
|
||||
const auto end = (offset + readSize) - 1;
|
||||
auto reader = prv::BufferedReader(provider);
|
||||
reader.seek(offset);
|
||||
reader.setEndAddress((offset + size) - 1);
|
||||
|
||||
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
|
||||
result += hex::format("{0:08X} ", col << 4);
|
||||
for (u64 i = 0; i < 16; i++) {
|
||||
u64 address = offset & ~u64(0x0F);
|
||||
std::string asciiRow;
|
||||
for (u8 byte : reader) {
|
||||
if ((address % 0x10) == 0) {
|
||||
result += hex::format(" {}", asciiRow);
|
||||
result += hex::format("\n{0:08X} ", address);
|
||||
|
||||
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
|
||||
asciiRow.clear();
|
||||
|
||||
if (address == (offset & ~u64(0x0F))) {
|
||||
for (u64 i = 0; i < (offset - address); i++) {
|
||||
result += " ";
|
||||
else
|
||||
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
|
||||
|
||||
if ((i & 0xF) == 0x7)
|
||||
result += " ";
|
||||
asciiRow += " ";
|
||||
}
|
||||
address = offset;
|
||||
}
|
||||
}
|
||||
|
||||
result += hex::format("{0:02X} ", byte);
|
||||
asciiRow += std::isprint(byte) ? char(byte) : '.';
|
||||
if ((address % 0x10) == 0x07)
|
||||
result += " ";
|
||||
|
||||
for (u64 i = 0; i < 16; i++) {
|
||||
|
||||
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
|
||||
result += " ";
|
||||
else {
|
||||
u8 c = buffer[((col << 4) - offset) + i];
|
||||
char displayChar = (c < 32 || c >= 128) ? '.' : c;
|
||||
result += hex::format("{0}", displayChar);
|
||||
}
|
||||
}
|
||||
|
||||
result += "\n";
|
||||
}
|
||||
address++;
|
||||
}
|
||||
|
||||
if ((address % 0x10) != 0x00)
|
||||
for (u32 i = 0; i < (0x10 - (address % 0x10)); i++)
|
||||
result += " ";
|
||||
|
||||
result += hex::format(" {}", asciiRow);
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -115,48 +156,46 @@ namespace hex::plugin::builtin {
|
||||
" .textcolumn { color:#000000 }\n"
|
||||
" </style>\n\n"
|
||||
" <code>\n"
|
||||
" <span class=\"offsetheader\">Hex View  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F</span><br>\n";
|
||||
" <span class=\"offsetheader\">Hex View  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F</span>";
|
||||
|
||||
auto reader = prv::BufferedReader(provider);
|
||||
reader.seek(offset);
|
||||
reader.setEndAddress(offset + size);
|
||||
|
||||
std::vector<u8> buffer(0x1'0000, 0x00);
|
||||
for (u64 byte = 0; byte < size; byte += buffer.size()) {
|
||||
size_t readSize = std::min<u64>(buffer.size(), size - byte);
|
||||
provider->read(offset, buffer.data(), readSize);
|
||||
u64 address = offset & ~u64(0x0F);
|
||||
std::string asciiRow;
|
||||
for (u8 byte : reader) {
|
||||
if ((address % 0x10) == 0) {
|
||||
result += hex::format(" {}", asciiRow);
|
||||
result += hex::format("<br>\n <span class=\"offsetcolumn\">{0:08X}</span>  <span class=\"hexcolumn\">", address);
|
||||
|
||||
const auto end = (offset + readSize) - 1;
|
||||
asciiRow.clear();
|
||||
|
||||
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
|
||||
result += hex::format(" <span class=\"offsetcolumn\">{0:08X}</span>  <span class=\"hexcolumn\">", col << 4);
|
||||
for (u64 i = 0; i < 16; i++) {
|
||||
|
||||
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
|
||||
result += "   ";
|
||||
else
|
||||
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
|
||||
|
||||
if ((i & 0xF) == 0x7)
|
||||
result += " ";
|
||||
}
|
||||
|
||||
result += "</span>  <span class=\"textcolumn\">";
|
||||
|
||||
for (u64 i = 0; i < 16; i++) {
|
||||
|
||||
if ((col == (offset >> 4) && i < (offset & 0xF)) || (col == (end >> 4) && i > (end & 0xF)))
|
||||
result += " ";
|
||||
else {
|
||||
u8 c = buffer[((col << 4) - offset) + i];
|
||||
char displayChar = (c < 32 || c >= 128) ? '.' : c;
|
||||
result += hex::format("{0}", displayChar);
|
||||
if (address == (offset & ~u64(0x0F))) {
|
||||
for (u64 i = 0; i < (offset - address); i++) {
|
||||
result += "   ";
|
||||
asciiRow += " ";
|
||||
}
|
||||
address = offset;
|
||||
}
|
||||
|
||||
result += "</span><br>\n";
|
||||
result += "</span>";
|
||||
}
|
||||
|
||||
result += hex::format("{0:02X} ", byte);
|
||||
asciiRow += std::isprint(byte) ? char(byte) : '.';
|
||||
if ((address % 0x10) == 0x07)
|
||||
result += " ";
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < (0x10 - (address % 0x10)); i++)
|
||||
result += "   ";
|
||||
result += asciiRow;
|
||||
|
||||
result +=
|
||||
" </code>\n"
|
||||
"\n </code>\n"
|
||||
"</div>\n";
|
||||
|
||||
return result;
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
|
||||
auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? hex::format("0x{{0:0{}X}}", Size * 2) : hex::format("0o{{0:0{}o}}", Size * 3));
|
||||
|
||||
T value = 0x00;
|
||||
std::memcpy(&value, buffer.data(), Size);
|
||||
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
|
||||
return hex::format(format, hex::changeEndianess(value, Size, endian));
|
||||
}
|
||||
|
||||
@@ -98,8 +98,11 @@ namespace hex::plugin::builtin {
|
||||
auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? hex::format("{{0}}0x{{1:0{}X}}", Size * 2) : hex::format("{{0}}0o{{1:0{}o}}", Size * 3));
|
||||
|
||||
T value = 0x00;
|
||||
std::memcpy(&value, buffer.data(), Size);
|
||||
auto number = hex::signExtend(Size * 8, hex::changeEndianess(value, Size, endian));
|
||||
std::memcpy(&value, buffer.data(), std::min(sizeof(T), Size));
|
||||
auto number = hex::changeEndianess(value, Size, endian);
|
||||
if (Size != sizeof(T))
|
||||
number = hex::signExtend(Size * 8, number);
|
||||
|
||||
bool negative = number < 0;
|
||||
|
||||
return hex::format(format, negative ? "-" : "", std::abs(number));
|
||||
@@ -118,7 +121,7 @@ namespace hex::plugin::builtin {
|
||||
template<typename T>
|
||||
static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(T func) {
|
||||
return [func](const std::vector<u8> &buffer, std::endian endian, Style style) {
|
||||
return [value = func(buffer, endian, style)] -> std::string { ImGui::TextUnformatted(value.c_str()); return value; };
|
||||
return [value = func(buffer, endian, style)]() -> std::string { ImGui::TextUnformatted(value.c_str()); return value; };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace hex::plugin::builtin {
|
||||
NodeBuffer() : Node("hex.builtin.nodes.constants.buffer.header", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "") }) { }
|
||||
|
||||
void drawNode() override {
|
||||
constexpr int StepSize = 1, FastStepSize = 10;
|
||||
constexpr static int StepSize = 1, FastStepSize = 10;
|
||||
|
||||
ImGui::PushItemWidth(100);
|
||||
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize);
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace hex::plugin::builtin {
|
||||
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.file", true);
|
||||
if (auto *fileProvider = dynamic_cast<prv::FileProvider*>(provider); fileProvider != nullptr) {
|
||||
fileProvider->setPath(path);
|
||||
(void)fileProvider->open();
|
||||
if (fileProvider->open())
|
||||
EventManager::post<EventProviderOpened>(fileProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,27 +31,32 @@ namespace hex::plugin::builtin {
|
||||
EventManager::subscribe<EventWindowClosing>([](GLFWwindow *window) {
|
||||
if (ImHexApi::Provider::isDirty()) {
|
||||
glfwSetWindowShouldClose(window, GLFW_FALSE);
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.exit_application.title"_lang); });
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderClosing>([](hex::prv::Provider *provider, bool *shouldClose) {
|
||||
if (provider->isDirty()) {
|
||||
*shouldClose = false;
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.popup.close_provider.title"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.popup.close_provider.title"_lang); });
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderChanged>([](hex::prv::Provider *oldProvider, hex::prv::Provider *newProvider) {
|
||||
hex::unused(oldProvider);
|
||||
|
||||
if (newProvider != nullptr) {
|
||||
if (newProvider != nullptr && newProvider->isAvailable()) {
|
||||
EventManager::post<RequestChangeWindowTitle>(newProvider->getName());
|
||||
} else {
|
||||
EventManager::post<RequestChangeWindowTitle>("");
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderOpened>([](hex::prv::Provider *provider) {
|
||||
if (provider != nullptr && ImHexApi::Provider::get() == provider)
|
||||
EventManager::post<RequestChangeWindowTitle>(provider->getName());
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestOpenFile>(openFile);
|
||||
|
||||
EventManager::subscribe<RequestOpenWindow>([](const std::string &name) {
|
||||
@@ -87,22 +93,27 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (provider->hasFilePicker()) {
|
||||
if (!provider->handleFilePicker()) {
|
||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
return;
|
||||
}
|
||||
if (!provider->open()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
return;
|
||||
}
|
||||
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
}
|
||||
else if (provider->hasLoadInterface())
|
||||
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
|
||||
else {
|
||||
if (!provider->open() || !provider->isAvailable()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
return;
|
||||
}
|
||||
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "math_evaluator.hpp"
|
||||
#include <content/helpers/math_evaluator.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
@@ -19,7 +18,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool MathEvaluator<T>::isLeftAssociative(const Operator op) {
|
||||
bool MathEvaluator<T>::isLeftAssociative(const Operator &op) {
|
||||
return (static_cast<u32>(op) & 0xF00) == 0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "pattern_drawer.hpp"
|
||||
#include <content/helpers/pattern_drawer.hpp>
|
||||
|
||||
#include <pl/patterns/pattern_array_dynamic.hpp>
|
||||
#include <pl/patterns/pattern_array_static.hpp>
|
||||
@@ -25,15 +25,100 @@
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace {
|
||||
constexpr static auto DisplayEndDefault = 50u;
|
||||
constexpr static auto DisplayEndStep = 50u;
|
||||
|
||||
using namespace ::std::literals::string_literals;
|
||||
};
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto DisplayEndDefault = 50U;
|
||||
constexpr auto DisplayEndStep = 50U;
|
||||
|
||||
using namespace ::std::literals::string_literals;
|
||||
|
||||
void createLeafNode(const pl::ptrn::Pattern& pattern) {
|
||||
ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_Leaf |
|
||||
ImGuiTreeNodeFlags_NoTreePushOnOpen |
|
||||
ImGuiTreeNodeFlags_SpanFullWidth |
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap);
|
||||
}
|
||||
|
||||
bool createTreeNode(const pl::ptrn::Pattern& pattern) {
|
||||
if (pattern.isSealed()) {
|
||||
ImGui::Indent();
|
||||
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
|
||||
ImGui::Unindent();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
|
||||
void drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) {
|
||||
ImGui::TextFormattedColored(ImColor(0xFFD69C56), pattern_name);
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted(pattern.getTypeName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void drawNameColumn(const pl::ptrn::Pattern& pattern) {
|
||||
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void drawColorColumn(const pl::ptrn::Pattern& pattern) {
|
||||
ImGui::ColorButton("color", ImColor(pattern.getColor()), ImGuiColorEditFlags_NoTooltip, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void drawOffsetColumn(const pl::ptrn::Pattern& pattern) {
|
||||
ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", pattern.getOffset(), pattern.getOffset() + pattern.getSize() - (pattern.getSize() == 0 ? 0 : 1));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void drawSizeColumn(const pl::ptrn::Pattern& pattern) {
|
||||
ImGui::TextFormatted("0x{0:04X}", pattern.getSize());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void drawCommentTooltip(const pl::ptrn::Pattern &pattern) {
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && pattern.getComment() != nullptr) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted(pattern.getComment()->c_str());
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void makeSelectable(const pl::ptrn::Pattern &pattern) {
|
||||
ImGui::PushID(static_cast<int>(pattern.getOffset()));
|
||||
ImGui::PushID(pattern.getVariableName().c_str());
|
||||
|
||||
if (ImGui::Selectable("##PatternLine", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) {
|
||||
ImHexApi::HexEditor::setSelection(pattern.getOffset(), pattern.getSize());
|
||||
}
|
||||
|
||||
ImGui::SameLine(0, 0);
|
||||
|
||||
ImGui::PopID();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void createDefaultEntry(pl::ptrn::Pattern &pattern) {
|
||||
ImGui::TableNextRow();
|
||||
createLeafNode(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::SameLine();
|
||||
drawNameColumn(pattern);
|
||||
drawColorColumn(pattern);
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName().empty() ? pattern.getTypeName() : pattern.getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternArrayDynamic& pattern) {
|
||||
this->drawArray(pattern);
|
||||
}
|
||||
@@ -81,15 +166,12 @@ namespace hex {
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
drawColorColumn(pattern);
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "bitfield");
|
||||
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -97,16 +179,17 @@ namespace hex {
|
||||
this->draw(field);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
if (!pattern.isInlined())
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternBoolean& pattern) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<bool>(pattern.getValue()));
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternCharacter& pattern) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternEnum& pattern) {
|
||||
@@ -125,11 +208,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternFloat& pattern) {
|
||||
if (pattern.getSize() == 4) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<float>(pattern.getValue()));
|
||||
} else if (pattern.getSize() == 8) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), static_cast<double>(pattern.getValue()));
|
||||
}
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternPadding& pattern) {
|
||||
@@ -147,32 +226,29 @@ namespace hex {
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::SameLine(0, 0);
|
||||
drawColorColumn(pattern);
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
}
|
||||
|
||||
if (open) {
|
||||
pattern.getPointedAtPattern()->accept(*this);
|
||||
|
||||
ImGui::TreePop();
|
||||
if (!pattern.isInlined())
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternSigned& pattern) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternString& pattern) {
|
||||
if (pattern.getSize() > 0)
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternStruct& pattern) {
|
||||
@@ -185,14 +261,14 @@ namespace hex {
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
if (pattern.isSealed())
|
||||
drawColorColumn(pattern);
|
||||
else
|
||||
ImGui::TableNextColumn();
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "struct");
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -200,7 +276,8 @@ namespace hex {
|
||||
this->draw(member);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
if (!pattern.isInlined())
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,14 +291,14 @@ namespace hex {
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
if (pattern.isSealed())
|
||||
drawColorColumn(pattern);
|
||||
else
|
||||
ImGui::TableNextColumn();
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
drawTypenameColumn(pattern, "union");
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
}
|
||||
|
||||
if (open) {
|
||||
@@ -229,59 +306,22 @@ namespace hex {
|
||||
this->draw(member);
|
||||
});
|
||||
|
||||
ImGui::TreePop();
|
||||
if (!pattern.isInlined())
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternUnsigned& pattern) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternWideCharacter& pattern) {
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), u128(pattern.getValue()));
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::visit(pl::ptrn::PatternWideString& pattern) {
|
||||
if (pattern.getSize() > 0)
|
||||
this->createDefaultEntry(pattern, pattern.getFormattedValue(), pattern.getValue());
|
||||
}
|
||||
|
||||
void PatternDrawer::createDefaultEntry(const pl::ptrn::Pattern &pattern, const std::string &value, pl::core::Token::Literal &&literal) const {
|
||||
ImGui::TableNextRow();
|
||||
createLeafNode(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
makeSelectable(pattern);
|
||||
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::SameLine();
|
||||
drawNameColumn(pattern);
|
||||
drawColorColumn(pattern);
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern.getFormattedName().empty() ? pattern.getTypeName() : pattern.getFormattedName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.formatDisplayValue(value, literal));
|
||||
}
|
||||
|
||||
void PatternDrawer::makeSelectable(const pl::ptrn::Pattern &pattern) const {
|
||||
ImGui::PushID(static_cast<int>(pattern.getOffset()));
|
||||
ImGui::PushID(pattern.getVariableName().c_str());
|
||||
if (ImGui::Selectable("##PatternLine", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) {
|
||||
ImHexApi::HexEditor::setSelection(pattern.getOffset(), pattern.getSize());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PopID();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
|
||||
void PatternDrawer::drawCommentTooltip(const pl::ptrn::Pattern &pattern) const {
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) && pattern.getComment().has_value()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted(pattern.getComment()->c_str());
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
createDefaultEntry(pattern);
|
||||
}
|
||||
|
||||
void PatternDrawer::draw(pl::ptrn::Pattern& pattern) {
|
||||
@@ -303,7 +343,10 @@ namespace hex {
|
||||
ImGui::TableNextColumn();
|
||||
makeSelectable(pattern);
|
||||
drawCommentTooltip(pattern);
|
||||
ImGui::TableNextColumn();
|
||||
if (pattern.isSealed())
|
||||
drawColorColumn(pattern);
|
||||
else
|
||||
ImGui::TableNextColumn();
|
||||
drawOffsetColumn(pattern);
|
||||
drawSizeColumn(pattern);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{0}", pattern.getTypeName());
|
||||
@@ -317,9 +360,6 @@ namespace hex {
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern.getFormattedValue());
|
||||
} else {
|
||||
ImGui::SameLine();
|
||||
ImGui::TreeNodeEx("", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf);
|
||||
}
|
||||
|
||||
return open;
|
||||
@@ -328,7 +368,7 @@ namespace hex {
|
||||
void PatternDrawer::drawArrayNode(u64 idx, u64& displayEnd, pl::ptrn::Pattern& pattern) {
|
||||
u64 lastVisible = displayEnd - 1;
|
||||
|
||||
ImGui::PushID(pattern.getOffset());
|
||||
ImGui::PushID(reinterpret_cast<void*>(pattern.getOffset()));
|
||||
|
||||
if (idx < lastVisible) {
|
||||
this->draw(pattern);
|
||||
@@ -344,65 +384,23 @@ namespace hex {
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void PatternDrawer::drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened) {
|
||||
void PatternDrawer::drawArrayEnd(pl::ptrn::Pattern& pattern, bool opened, bool inlined) {
|
||||
if (opened) {
|
||||
ImGui::TreePop();
|
||||
if (!inlined)
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
auto& displayEnd = this->getDisplayEnd(pattern);
|
||||
displayEnd = DisplayEndDefault;
|
||||
}
|
||||
}
|
||||
|
||||
void PatternDrawer::createLeafNode(const pl::ptrn::Pattern& pattern) const {
|
||||
ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_Leaf |
|
||||
ImGuiTreeNodeFlags_NoTreePushOnOpen |
|
||||
ImGuiTreeNodeFlags_SpanFullWidth |
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap);
|
||||
}
|
||||
|
||||
bool PatternDrawer::createTreeNode(const pl::ptrn::Pattern& pattern) const {
|
||||
if (pattern.isSealed()) {
|
||||
ImGui::Selectable(pattern.getDisplayName().c_str(), false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return ImGui::TreeNodeEx(pattern.getDisplayName().c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
}
|
||||
|
||||
void PatternDrawer::drawTypenameColumn(const pl::ptrn::Pattern& pattern, const std::string& pattern_name) const {
|
||||
ImGui::TextFormattedColored(ImColor(0xFFD69C56), pattern_name);
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted(pattern.getTypeName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void PatternDrawer::drawNameColumn(const pl::ptrn::Pattern& pattern) const {
|
||||
ImGui::TextUnformatted(pattern.getDisplayName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void PatternDrawer::drawColorColumn(const pl::ptrn::Pattern& pattern) const {
|
||||
ImGui::ColorButton("color", ImColor(pattern.getColor()), ImGuiColorEditFlags_NoTooltip, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void PatternDrawer::drawOffsetColumn(const pl::ptrn::Pattern& pattern) const {
|
||||
ImGui::TextFormatted("0x{0:08X} : 0x{1:08X}", pattern.getOffset(), pattern.getOffset() + pattern.getSize() - (pattern.getSize() == 0 ? 0 : 1));
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
void PatternDrawer::drawSizeColumn(const pl::ptrn::Pattern& pattern) const {
|
||||
ImGui::TextFormatted("0x{0:04X}", pattern.getSize());
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
|
||||
u64& PatternDrawer::getDisplayEnd(const pl::ptrn::Pattern& pattern) {
|
||||
auto it = m_displayEnd.find(&pattern);
|
||||
if (it != m_displayEnd.end()) {
|
||||
auto it = this->m_displayEnd.find(&pattern);
|
||||
if (it != this->m_displayEnd.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
auto [inserted, success] = m_displayEnd.emplace(&pattern, DisplayEndDefault);
|
||||
return inserted->second;
|
||||
auto [value, success] = this->m_displayEnd.emplace(&pattern, DisplayEndDefault);
|
||||
return value->second;
|
||||
}
|
||||
};
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
#include <hex/helpers/patches.hpp>
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
static bool g_demoWindowOpen = false;
|
||||
@@ -20,13 +18,14 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::registerMainMenuItem("hex.builtin.menu.file", 1000);
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1050, [&] {
|
||||
bool taskRunning = Task::getRunningTaskCount() > 0;
|
||||
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.create_file"_lang, "CTRL + N", false, !taskRunning)) {
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.open_file"_lang, "CTRL + O", false, !taskRunning)) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
EventManager::post<RequestOpenWindow>("Open File");
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.open_other"_lang, !taskRunning)) {
|
||||
@@ -44,7 +43,7 @@ namespace hex::plugin::builtin {
|
||||
/* File open, quit imhex */
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1150, [&] {
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
bool taskRunning = Task::getRunningTaskCount() > 0;
|
||||
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.close"_lang, "CTRL + W", false, providerValid && !taskRunning)) {
|
||||
ImHexApi::Provider::remove(ImHexApi::Provider::get());
|
||||
@@ -59,7 +58,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1250, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
bool taskRunning = Task::getRunningTaskCount() > 0;
|
||||
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.open_project"_lang, "", false, !taskRunning)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, { {"Project File", "hexproj"}
|
||||
@@ -85,7 +84,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 1300, [&] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
bool taskRunning = Task::getRunningTaskCount() > 0;
|
||||
bool taskRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
/* Import */
|
||||
if (ImGui::BeginMenu("hex.builtin.menu.file.import"_lang, !taskRunning)) {
|
||||
@@ -126,9 +125,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips"_lang, nullptr, false)) {
|
||||
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
std::thread([path] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
|
||||
|
||||
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [path](auto &task) {
|
||||
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
|
||||
auto patch = hex::loadIPSPatch(patchData);
|
||||
|
||||
@@ -144,15 +141,13 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
provider->createUndoPoint();
|
||||
}).detach();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.ips32"_lang, nullptr, false)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
std::thread([path] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
|
||||
|
||||
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [path](auto &task) {
|
||||
auto patchData = fs::File(path, fs::File::Mode::Read).readBytes();
|
||||
auto patch = hex::loadIPS32Patch(patchData);
|
||||
|
||||
@@ -168,7 +163,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
provider->createUndoPoint();
|
||||
}).detach();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -186,12 +181,10 @@ namespace hex::plugin::builtin {
|
||||
patches[0x00454F45] = value;
|
||||
}
|
||||
|
||||
std::thread([patches] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
|
||||
|
||||
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [patches](auto &) {
|
||||
auto data = generateIPSPatch(patches);
|
||||
|
||||
ImHexApi::Tasks::doLater([data] {
|
||||
TaskManager::doLater([data] {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||
auto file = fs::File(path, fs::File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
@@ -202,7 +195,7 @@ namespace hex::plugin::builtin {
|
||||
file.write(data);
|
||||
});
|
||||
});
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.export.ips32"_lang, nullptr, false)) {
|
||||
@@ -213,23 +206,21 @@ namespace hex::plugin::builtin {
|
||||
patches[0x45454F45] = value;
|
||||
}
|
||||
|
||||
std::thread([patches] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.common.processing", 0);
|
||||
|
||||
TaskManager::createTask("hex.builtin.common.processing", TaskManager::NoProgress, [patches](auto &) {
|
||||
auto data = generateIPS32Patch(patches);
|
||||
|
||||
ImHexApi::Tasks::doLater([data] {
|
||||
TaskManager::doLater([data] {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const auto &path) {
|
||||
auto file = fs::File(path, fs::File::Mode::Create);
|
||||
if (!file.isValid()) {
|
||||
View::showErrorPopup("hex.builtin.menu.file.export.popup.create"_lang);
|
||||
View::showErrorPopup("hex.builtin.menu.file.export.base64.popup.export_error"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(data);
|
||||
});
|
||||
});
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
|
||||
@@ -13,10 +13,23 @@ namespace hex::plugin::builtin {
|
||||
using namespace pl::core;
|
||||
using FunctionParameterCount = pl::api::FunctionParameterCount;
|
||||
|
||||
pl::api::Namespace nsStdHttp = { "builtin", "std", "http" };
|
||||
pl::api::Namespace nsHexCore = { "builtin", "hex", "core" };
|
||||
{
|
||||
/* get_selection() */
|
||||
ContentRegistry::PatternLanguage::addDangerousFunction(nsHexCore, "get_selection", FunctionParameterCount::none(), [](Evaluator *, auto) -> std::optional<Token::Literal> {
|
||||
if (!ImHexApi::HexEditor::isSelectionValid())
|
||||
return std::numeric_limits<u128>::max();
|
||||
|
||||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
return u128(u128(selection->getStartAddress()) << 64 | u128(selection->getSize()));
|
||||
});
|
||||
}
|
||||
|
||||
pl::api::Namespace nsHexHttp = { "builtin", "hex", "http" };
|
||||
{
|
||||
/* get(url) */
|
||||
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdHttp, "get", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
|
||||
ContentRegistry::PatternLanguage::addDangerousFunction(nsHexHttp, "get", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
|
||||
const auto url = Token::literalToString(params[0], false);
|
||||
|
||||
hex::Net net;
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace hex::plugin::builtin {
|
||||
auto baseAddress = strtoull(value.c_str(), nullptr, 0);
|
||||
|
||||
ImHexApi::Provider::get()->setBaseAddress(baseAddress);
|
||||
runtime.setDataBaseAddress(baseAddress);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace hex::plugin::builtin {
|
||||
provider->loadSettings(providerSettings["settings"]);
|
||||
if (!provider->open())
|
||||
success = false;
|
||||
else
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
namespace hex::plugin::builtin::prv {
|
||||
|
||||
DiskProvider::DiskProvider() : Provider() {
|
||||
this->reloadDrives();
|
||||
|
||||
}
|
||||
|
||||
bool DiskProvider::isAvailable() const {
|
||||
@@ -137,7 +137,7 @@ namespace hex::plugin::builtin::prv {
|
||||
|
||||
#endif
|
||||
|
||||
return Provider::open();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiskProvider::close() {
|
||||
@@ -156,8 +156,6 @@ namespace hex::plugin::builtin::prv {
|
||||
this->m_diskHandle = -1;
|
||||
|
||||
#endif
|
||||
|
||||
Provider::close();
|
||||
}
|
||||
|
||||
void DiskProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
@@ -320,6 +318,9 @@ namespace hex::plugin::builtin::prv {
|
||||
void DiskProvider::drawLoadInterface() {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
||||
if (this->m_availableDrives.empty())
|
||||
this->reloadDrives();
|
||||
|
||||
if (ImGui::BeginListBox("hex.builtin.provider.disk.selected_disk"_lang)) {
|
||||
|
||||
for (const auto &drive : this->m_availableDrives) {
|
||||
@@ -358,8 +359,10 @@ namespace hex::plugin::builtin::prv {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> DiskProvider::getRegionValidity(u64 address) const {
|
||||
address -= this->getBaseAddress();
|
||||
|
||||
if (address < this->getActualSize())
|
||||
return { Region { address, this->getActualSize() - address }, true };
|
||||
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
|
||||
else
|
||||
return { Region::Invalid(), false };
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin::prv {
|
||||
}
|
||||
|
||||
bool FileProvider::isResizable() const {
|
||||
return true;
|
||||
return isAvailable() && isWritable();
|
||||
}
|
||||
|
||||
bool FileProvider::isSavable() const {
|
||||
@@ -300,7 +300,7 @@ namespace hex::plugin::builtin::prv {
|
||||
|
||||
#endif
|
||||
|
||||
return Provider::open();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileProvider::close() {
|
||||
@@ -319,8 +319,6 @@ namespace hex::plugin::builtin::prv {
|
||||
::close(this->m_file);
|
||||
|
||||
#endif
|
||||
|
||||
Provider::close();
|
||||
}
|
||||
|
||||
void FileProvider::loadSettings(const nlohmann::json &settings) {
|
||||
@@ -336,8 +334,10 @@ namespace hex::plugin::builtin::prv {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> FileProvider::getRegionValidity(u64 address) const {
|
||||
address -= this->getBaseAddress();
|
||||
|
||||
if (address < this->getActualSize())
|
||||
return { Region { address, this->getActualSize() - address }, true };
|
||||
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
|
||||
else
|
||||
return { Region::Invalid(), false };
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace hex::plugin::builtin::prv {
|
||||
}
|
||||
});
|
||||
|
||||
return Provider::open();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -285,8 +285,6 @@ namespace hex::plugin::builtin::prv {
|
||||
if (this->m_cacheUpdateThread.joinable()) {
|
||||
this->m_cacheUpdateThread.join();
|
||||
}
|
||||
|
||||
Provider::close();
|
||||
}
|
||||
|
||||
bool GDBProvider::isConnected() const {
|
||||
@@ -325,8 +323,10 @@ namespace hex::plugin::builtin::prv {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> GDBProvider::getRegionValidity(u64 address) const {
|
||||
address -= this->getBaseAddress();
|
||||
|
||||
if (address < this->getActualSize())
|
||||
return { Region { address, this->getActualSize() - address }, true };
|
||||
return { Region { this->getBaseAddress() + address, this->getActualSize() - address }, true };
|
||||
else
|
||||
return { Region::Invalid(), false };
|
||||
}
|
||||
|
||||
@@ -153,6 +153,21 @@ namespace hex::plugin::builtin::prv {
|
||||
|
||||
}
|
||||
|
||||
void IntelHexProvider::setBaseAddress(u64 address) {
|
||||
auto oldBase = this->getBaseAddress();
|
||||
|
||||
auto intervals = this->m_data.findOverlapping(oldBase, oldBase + this->getActualSize());
|
||||
|
||||
for (auto &interval : intervals) {
|
||||
interval.start = (interval.start - oldBase) + address;
|
||||
interval.stop = (interval.stop - oldBase) + address;
|
||||
}
|
||||
|
||||
this->m_data = std::move(intervals);
|
||||
|
||||
Provider::setBaseAddress(address);
|
||||
}
|
||||
|
||||
void IntelHexProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
auto intervals = this->m_data.findOverlapping(offset, (offset + size) - 1);
|
||||
|
||||
@@ -195,12 +210,11 @@ namespace hex::plugin::builtin::prv {
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
|
||||
return Provider::open();
|
||||
return true;
|
||||
}
|
||||
|
||||
void IntelHexProvider::close() {
|
||||
|
||||
Provider::close();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string IntelHexProvider::getName() const {
|
||||
|
||||
@@ -190,11 +190,11 @@ namespace hex::plugin::builtin::prv {
|
||||
this->m_dataSize = maxAddress + 1;
|
||||
this->m_dataValid = true;
|
||||
|
||||
return Provider::open();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MotorolaSRECProvider::close() {
|
||||
Provider::close();
|
||||
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string MotorolaSRECProvider::getName() const {
|
||||
|
||||
@@ -484,7 +484,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
// If a custom font has been loaded now, also load the font size
|
||||
float fontSize = 13.0F * ImHexApi::System::getGlobalScale();
|
||||
float fontSize = ImHexApi::System::DefaultFontSize * ImHexApi::System::getGlobalScale();
|
||||
if (!fontFile.empty()) {
|
||||
ImHexApi::System::impl::setCustomFontPath(fontFile);
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void registerShortcuts() {
|
||||
// New file
|
||||
ShortcutManager::addGlobalShortcut(CTRL + Keys::N, [] {
|
||||
EventManager::post<RequestOpenWindow>("Create File");
|
||||
});
|
||||
|
||||
// Open file
|
||||
ShortcutManager::addGlobalShortcut(CTRL + Keys::O, [] {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
EventManager::post<RequestOpenFile>(path);
|
||||
});
|
||||
EventManager::post<RequestOpenWindow>("Open File");
|
||||
});
|
||||
|
||||
// Close file
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include <llvm/Demangle/Demangle.h>
|
||||
#include "math_evaluator.hpp"
|
||||
#include <content/helpers/math_evaluator.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
@@ -745,15 +745,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
void drawFileToolShredder() {
|
||||
static bool shredding = false;
|
||||
static std::u8string selectedFile;
|
||||
static bool fastMode = false;
|
||||
static TaskHolder shredderTask;
|
||||
|
||||
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.warning"_lang);
|
||||
ImGui::NewLine();
|
||||
|
||||
if (ImGui::BeginChild("settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 4 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
ImGui::BeginDisabled(shredding);
|
||||
ImGui::BeginDisabled(shredderTask.isRunning());
|
||||
{
|
||||
ImGui::TextUnformatted("hex.builtin.tools.file_tools.shredder.input"_lang);
|
||||
ImGui::SameLine();
|
||||
@@ -771,17 +771,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (shredding)
|
||||
if (shredderTask.isRunning())
|
||||
ImGui::TextSpinner("hex.builtin.tools.file_tools.shredder.shredding"_lang);
|
||||
else {
|
||||
ImGui::BeginDisabled(selectedFile.empty());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.tools.file_tools.shredder.shred"_lang)) {
|
||||
shredding = true;
|
||||
|
||||
std::thread([] {
|
||||
shredderTask = TaskManager::createTask("hex.builtin.tools.file_tools.shredder.shredding", 0, [](auto &task) {
|
||||
ON_SCOPE_EXIT {
|
||||
shredding = false;
|
||||
selectedFile.clear();
|
||||
};
|
||||
fs::File file(selectedFile, fs::File::Mode::Write);
|
||||
@@ -791,6 +788,8 @@ namespace hex::plugin::builtin {
|
||||
return;
|
||||
}
|
||||
|
||||
task.setMaxValue(file.getSize());
|
||||
|
||||
std::vector<std::array<u8, 3>> overwritePattern;
|
||||
if (fastMode) {
|
||||
/* Should be sufficient for modern disks */
|
||||
@@ -803,40 +802,40 @@ namespace hex::plugin::builtin {
|
||||
|
||||
/* Fill fixed patterns */
|
||||
overwritePattern = {
|
||||
{ },
|
||||
{ },
|
||||
{},
|
||||
{},
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0xAA, 0xAA, 0xAA },
|
||||
{ 0x92, 0x49, 0x24 },
|
||||
{ 0x49, 0x24, 0x92 },
|
||||
{ 0x24, 0x92, 0x49 },
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x11, 0x11, 0x11 },
|
||||
{ 0x22, 0x22, 0x22 },
|
||||
{ 0x33, 0x33, 0x44 },
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0x66, 0x66, 0x66 },
|
||||
{ 0x77, 0x77, 0x77 },
|
||||
{ 0x88, 0x88, 0x88 },
|
||||
{ 0x99, 0x99, 0x99 },
|
||||
{ 0xAA, 0xAA, 0xAA },
|
||||
{ 0xBB, 0xBB, 0xBB },
|
||||
{ 0xCC, 0xCC, 0xCC },
|
||||
{ 0xDD, 0xDD, 0xDD },
|
||||
{ 0xEE, 0xEE, 0xEE },
|
||||
{ 0xFF, 0xFF, 0xFF },
|
||||
{ 0x92, 0x49, 0x24 },
|
||||
{ 0x49, 0x24, 0x92 },
|
||||
{ 0x24, 0x92, 0x49 },
|
||||
{ 0x6D, 0xB6, 0xDB },
|
||||
{ 0xB6, 0xDB, 0x6D },
|
||||
{ 0xBD, 0x6D, 0xB6 },
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
{ },
|
||||
{ },
|
||||
{},
|
||||
{},
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0xAA, 0xAA, 0xAA },
|
||||
{ 0x92, 0x49, 0x24 },
|
||||
{ 0x49, 0x24, 0x92 },
|
||||
{ 0x24, 0x92, 0x49 },
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x11, 0x11, 0x11 },
|
||||
{ 0x22, 0x22, 0x22 },
|
||||
{ 0x33, 0x33, 0x44 },
|
||||
{ 0x55, 0x55, 0x55 },
|
||||
{ 0x66, 0x66, 0x66 },
|
||||
{ 0x77, 0x77, 0x77 },
|
||||
{ 0x88, 0x88, 0x88 },
|
||||
{ 0x99, 0x99, 0x99 },
|
||||
{ 0xAA, 0xAA, 0xAA },
|
||||
{ 0xBB, 0xBB, 0xBB },
|
||||
{ 0xCC, 0xCC, 0xCC },
|
||||
{ 0xDD, 0xDD, 0xDD },
|
||||
{ 0xEE, 0xEE, 0xEE },
|
||||
{ 0xFF, 0xFF, 0xFF },
|
||||
{ 0x92, 0x49, 0x24 },
|
||||
{ 0x49, 0x24, 0x92 },
|
||||
{ 0x24, 0x92, 0x49 },
|
||||
{ 0x6D, 0xB6, 0xDB },
|
||||
{ 0xB6, 0xDB, 0x6D },
|
||||
{ 0xBD, 0x6D, 0xB6 },
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Fill random patterns */
|
||||
@@ -848,7 +847,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
size_t fileSize = file.getSize();
|
||||
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.shredder.shredding", fileSize);
|
||||
for (const auto &pattern : overwritePattern) {
|
||||
for (u64 offset = 0; offset < fileSize; offset += 3) {
|
||||
file.write(pattern.data(), std::min<u64>(pattern.size(), fileSize - offset));
|
||||
@@ -861,7 +859,7 @@ namespace hex::plugin::builtin {
|
||||
file.remove();
|
||||
|
||||
View::showInfoPopup("hex.builtin.tools.file_tools.shredder.success"_lang);
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
@@ -890,14 +888,14 @@ namespace hex::plugin::builtin {
|
||||
1
|
||||
};
|
||||
|
||||
static bool splitting = false;
|
||||
static std::u8string selectedFile;
|
||||
static std::u8string baseOutputPath;
|
||||
static u64 splitSize = sizes[0];
|
||||
static int selectedItem = 0;
|
||||
static TaskHolder splitterTask;
|
||||
|
||||
if (ImGui::BeginChild("split_settings", { 0, ImGui::GetTextLineHeightWithSpacing() * 7 }, true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
ImGui::BeginDisabled(splitting);
|
||||
ImGui::BeginDisabled(splitterTask.isRunning());
|
||||
{
|
||||
ImGui::InputText("##path", selectedFile);
|
||||
ImGui::SameLine();
|
||||
@@ -926,7 +924,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(splitting || selectedItem != sizes.size() - 1);
|
||||
ImGui::BeginDisabled(splitterTask.isRunning() || selectedItem != sizes.size() - 1);
|
||||
{
|
||||
ImGui::InputScalar("###custom_size", ImGuiDataType_U64, &splitSize);
|
||||
ImGui::SameLine();
|
||||
@@ -938,15 +936,13 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::BeginDisabled(selectedFile.empty() || baseOutputPath.empty() || splitSize == 0);
|
||||
{
|
||||
if (splitting)
|
||||
if (splitterTask.isRunning())
|
||||
ImGui::TextSpinner("hex.builtin.tools.file_tools.splitter.splitting"_lang);
|
||||
else {
|
||||
if (ImGui::Button("hex.builtin.tools.file_tools.splitter.split"_lang)) {
|
||||
splitting = true;
|
||||
|
||||
std::thread([] {
|
||||
splitterTask = TaskManager::createTask("hex.builtin.tools.file_tools.splitter.splitting", 0, [](auto &task) {
|
||||
ON_SCOPE_EXIT {
|
||||
splitting = false;
|
||||
selectedFile.clear();
|
||||
baseOutputPath.clear();
|
||||
};
|
||||
@@ -962,7 +958,8 @@ namespace hex::plugin::builtin {
|
||||
return;
|
||||
}
|
||||
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.splitter.splitting", file.getSize());
|
||||
task.setMaxValue(file.getSize());
|
||||
|
||||
u32 index = 1;
|
||||
for (u64 offset = 0; offset < file.getSize(); offset += splitSize) {
|
||||
task.update(offset);
|
||||
@@ -977,7 +974,7 @@ namespace hex::plugin::builtin {
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr auto BufferSize = 0xFF'FFFF;
|
||||
constexpr static auto BufferSize = 0xFF'FFFF;
|
||||
for (u64 partOffset = 0; partOffset < splitSize; partOffset += BufferSize) {
|
||||
partFile.write(file.readBytes(std::min<u64>(BufferSize, splitSize - partOffset)));
|
||||
partFile.flush();
|
||||
@@ -987,7 +984,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
View::showInfoPopup("hex.builtin.tools.file_tools.splitter.success"_lang);
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -995,10 +992,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void drawFileToolCombiner() {
|
||||
static bool combining = false;
|
||||
static std::vector<std::fs::path> files;
|
||||
static std::u8string outputPath;
|
||||
static u32 selectedIndex;
|
||||
static TaskHolder combinerTask;
|
||||
|
||||
if (ImGui::BeginTable("files_table", 2, ImGuiTableFlags_SizingStretchProp)) {
|
||||
ImGui::TableSetupColumn("file list", ImGuiTableColumnFlags_NoHeaderLabel, 10);
|
||||
@@ -1041,7 +1038,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::BeginDisabled(combining);
|
||||
ImGui::BeginDisabled(combinerTask.isRunning());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.add"_lang)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
@@ -1063,7 +1060,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(combining);
|
||||
ImGui::BeginDisabled(combinerTask.isRunning());
|
||||
{
|
||||
ImGui::InputText("##output_path", outputPath);
|
||||
ImGui::SameLine();
|
||||
@@ -1079,14 +1076,12 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::BeginDisabled(files.empty() || outputPath.empty());
|
||||
{
|
||||
if (combining)
|
||||
if (combinerTask.isRunning())
|
||||
ImGui::TextSpinner("hex.builtin.tools.file_tools.combiner.combining"_lang);
|
||||
else {
|
||||
if (ImGui::Button("hex.builtin.tools.file_tools.combiner.combine"_lang)) {
|
||||
combining = true;
|
||||
|
||||
std::thread([] {
|
||||
ON_SCOPE_EXIT { combining = false; };
|
||||
combinerTask = TaskManager::createTask("hex.builtin.tools.file_tools.combiner.combining", 0, [](auto &task) {
|
||||
|
||||
fs::File output(outputPath, fs::File::Mode::Create);
|
||||
|
||||
@@ -1095,7 +1090,7 @@ namespace hex::plugin::builtin {
|
||||
return;
|
||||
}
|
||||
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.tools.file_tools.combiner.combining", files.size());
|
||||
task.setMaxValue(files.size());
|
||||
|
||||
u64 fileIndex = 0;
|
||||
for (const auto &file : files) {
|
||||
@@ -1108,7 +1103,7 @@ namespace hex::plugin::builtin {
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr auto BufferSize = 0xFF'FFFF;
|
||||
constexpr static auto BufferSize = 0xFF'FFFF;
|
||||
auto inputSize = input.getSize();
|
||||
for (u64 inputOffset = 0; inputOffset < inputSize; inputOffset += BufferSize) {
|
||||
output.write(input.readBytes(std::min<u64>(BufferSize, inputSize - inputOffset)));
|
||||
@@ -1121,7 +1116,7 @@ namespace hex::plugin::builtin {
|
||||
outputPath.clear();
|
||||
|
||||
View::showInfoPopup("hex.builtin.tools.file_tools.combiner.success"_lang);
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +153,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Task exception popup
|
||||
for (const auto &task : TaskManager::getRunningTasks()) {
|
||||
if (task->hadException()) {
|
||||
EventManager::post<RequestShowErrorPopup>(hex::format("hex.builtin.popup.error.task_exception"_lang, LangEntry(task->getUnlocalizedName()), task->getExceptionMessage()));
|
||||
task->clearException();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addGlobalUIItems() {
|
||||
@@ -161,19 +170,19 @@ namespace hex::plugin::builtin {
|
||||
EventManager::subscribe<RequestShowInfoPopup>([](const std::string &message) {
|
||||
s_popupMessage = message;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.info"_lang); });
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestShowErrorPopup>([](const std::string &message) {
|
||||
s_popupMessage = message;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.error"_lang); });
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestShowFatalErrorPopup>([](const std::string &message) {
|
||||
s_popupMessage = message;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.fatal"_lang); });
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestShowYesNoQuestionPopup>([](const std::string &message, const std::function<void()> &yesCallback, const std::function<void()> &noCallback) {
|
||||
@@ -182,7 +191,7 @@ namespace hex::plugin::builtin {
|
||||
s_yesCallback = yesCallback;
|
||||
s_noCallback = noCallback;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.question"_lang); });
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestShowFileChooserPopup>([](const std::vector<std::fs::path> &paths, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback) {
|
||||
@@ -191,7 +200,7 @@ namespace hex::plugin::builtin {
|
||||
s_selectableFilesValidExtensions = validExtensions;
|
||||
s_selectableFileOpenCallback = callback;
|
||||
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.common.choose_file"_lang); });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -203,38 +212,63 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
}
|
||||
|
||||
ContentRegistry::Interface::addFooterItem([] {
|
||||
static float framerate = 0;
|
||||
if (ImGui::HasSecondPassed()) {
|
||||
framerate = 1.0F / ImGui::GetIO().DeltaTime;
|
||||
}
|
||||
|
||||
ImGui::TextFormatted("FPS {0:2}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addFooterItem([] {
|
||||
size_t taskCount = 0;
|
||||
double taskProgress = 0.0;
|
||||
std::string taskName;
|
||||
|
||||
{
|
||||
std::scoped_lock lock(Task::getTaskMutex());
|
||||
|
||||
taskCount = Task::getRunningTasks().size();
|
||||
if (taskCount > 0) {
|
||||
auto frontTask = Task::getRunningTasks().front();
|
||||
taskProgress = frontTask->getProgress();
|
||||
taskName = frontTask->getName();
|
||||
#if defined(DEBUG)
|
||||
ContentRegistry::Interface::addFooterItem([] {
|
||||
static float framerate = 0;
|
||||
if (ImGui::HasSecondPassed()) {
|
||||
framerate = 1.0F / ImGui::GetIO().DeltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TextFormatted("FPS {0:2}.{1:02}", u32(framerate), u32(framerate * 100) % 100);
|
||||
});
|
||||
#endif
|
||||
|
||||
ContentRegistry::Interface::addFooterItem([] {
|
||||
auto taskCount = TaskManager::getRunningTaskCount();
|
||||
if (taskCount > 0) {
|
||||
auto &tasks = TaskManager::getRunningTasks();
|
||||
auto frontTask = tasks.front();
|
||||
|
||||
auto widgetStart = ImGui::GetCursorPos();
|
||||
|
||||
ImGui::TextSpinner(hex::format("({})", taskCount).c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::SmallProgressBar(frontTask->getMaxValue() == 0 ? 1 : (float(frontTask->getValue()) / frontTask->getMaxValue()), (ImGui::GetCurrentWindow()->MenuBarHeight() - 10_scaled) / 2.0);
|
||||
ImGui::SameLine();
|
||||
|
||||
auto widgetEnd = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(widgetStart);
|
||||
ImGui::InvisibleButton("FrontTask", ImVec2(widgetEnd.x - widgetStart.x, ImGui::GetCurrentWindow()->MenuBarHeight()));
|
||||
ImGui::SetCursorPos(widgetEnd);
|
||||
|
||||
ImGui::InfoTooltip(LangEntry(frontTask->getUnlocalizedName()).get().c_str());
|
||||
|
||||
if (ImGui::BeginPopupContextItem("FrontTask", ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
for (const auto &task : tasks) {
|
||||
ImGui::PushID(&task);
|
||||
ImGui::TextFormatted("{}", LangEntry(task->getUnlocalizedName()));
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
ImGui::SmallProgressBar(frontTask->getMaxValue() == 0 ? 1 : (float(frontTask->getValue()) / frontTask->getMaxValue()), (ImGui::GetTextLineHeightWithSpacing() - 5_scaled) / 2);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
if (ImGui::ToolBarButton(ICON_VS_DEBUG_STOP, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
|
||||
task->interrupt();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SmallProgressBar(taskProgress, (ImGui::GetCurrentWindow()->MenuBarHeight() - 10_scaled) / 2.0);
|
||||
ImGui::InfoTooltip(taskName.c_str());
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, scaled(ImVec2(1, 2)));
|
||||
if (ImGui::ToolBarButton(ICON_VS_DEBUG_STOP, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
|
||||
frontTask->interrupt();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -243,7 +277,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Interface::addToolbarItem([] {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
bool providerValid = provider != nullptr;
|
||||
bool tasksRunning = Task::getRunningTaskCount() > 0;
|
||||
bool tasksRunning = TaskManager::getRunningTaskCount() > 0;
|
||||
|
||||
// Undo
|
||||
ImGui::BeginDisabled(!providerValid || !provider->canUndo());
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 1000, [&, this] {
|
||||
if (ImGui::MenuItem("hex.builtin.view.help.about.name"_lang, "")) {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.help.about.name").c_str()); });
|
||||
this->m_aboutWindowOpen = true;
|
||||
this->getWindowOpenState() = true;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableSetupColumn("Type");
|
||||
ImGui::TableSetupColumn("Paths");
|
||||
|
||||
constexpr std::array<std::pair<const char *, fs::ImHexPath>, 8> PathTypes = {
|
||||
constexpr static std::array<std::pair<const char *, fs::ImHexPath>, 8> PathTypes = {
|
||||
{{ "Resources", fs::ImHexPath::Resources },
|
||||
{ "Config", fs::ImHexPath::Config },
|
||||
{ "Magic", fs::ImHexPath::Magic },
|
||||
|
||||
@@ -325,16 +325,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.file", 4000, [&] {
|
||||
bool providerValid = ImHexApi::Provider::isValid();
|
||||
auto selection = ImHexApi::HexEditor::getSelection();
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.import"_lang, nullptr, false, selection.has_value() && providerValid)) {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.import"_lang, nullptr, false, providerValid)) {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, { { "Bookmarks File", "hexbm"} }, [&](const std::fs::path &path) {
|
||||
try {
|
||||
importBookmarks(ImHexApi::Provider::get(), nlohmann::json::parse(fs::File(path, fs::File::Mode::Read).readString()));
|
||||
} catch (...) { }
|
||||
});
|
||||
}
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.export"_lang, nullptr, false, selection.has_value() && providerValid)) {
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.bookmark.export"_lang, nullptr, false, providerValid && !ProviderExtraData::getCurrent().bookmarks.empty())) {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, { { "Bookmarks File", "hexbm"} }, [&](const std::fs::path &path) {
|
||||
nlohmann::json json;
|
||||
exportBookmarks(ImHexApi::Provider::get(), json);
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
std::vector<ViewCommandPalette::CommandResult> ViewCommandPalette::getCommandResults(const std::string &input) {
|
||||
constexpr auto MatchCommand = [](const std::string &currCommand, const std::string &commandToMatch) -> std::pair<MatchType, std::string_view> {
|
||||
constexpr static auto MatchCommand = [](const std::string &currCommand, const std::string &commandToMatch) -> std::pair<MatchType, std::string_view> {
|
||||
if (currCommand.empty()) {
|
||||
return { MatchType::InfoMatch, "" };
|
||||
} else if (currCommand.size() <= commandToMatch.size()) {
|
||||
|
||||
@@ -34,10 +34,16 @@ namespace hex::plugin::builtin {
|
||||
this->m_upperCaseHex = static_cast<int>(upperCaseHex);
|
||||
}
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderClosed>(this, [this](prv::Provider *) {
|
||||
this->m_providerA = -1;
|
||||
this->m_providerB = -1;
|
||||
});
|
||||
}
|
||||
|
||||
ViewDiff::~ViewDiff() {
|
||||
EventManager::unsubscribe<EventSettingsChanged>(this);
|
||||
EventManager::unsubscribe<EventProviderClosed>(this);
|
||||
}
|
||||
|
||||
static void drawProviderSelector(int &provider) {
|
||||
|
||||
@@ -24,9 +24,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void ViewDisassembler::disassemble() {
|
||||
this->m_disassembly.clear();
|
||||
this->m_disassembling = true;
|
||||
|
||||
std::thread([this] {
|
||||
this->m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", this->m_codeRegion.getSize(), [this](auto &task) {
|
||||
csh capstoneHandle;
|
||||
cs_insn *instructions = nullptr;
|
||||
|
||||
@@ -40,7 +39,6 @@ namespace hex::plugin::builtin {
|
||||
std::vector<u8> buffer(2048, 0x00);
|
||||
size_t size = this->m_codeRegion.getSize();
|
||||
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.disassembler.disassembling", size);
|
||||
for (u64 address = 0; address < size; address += 2048) {
|
||||
task.update(address);
|
||||
|
||||
@@ -80,9 +78,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
cs_close(&capstoneHandle);
|
||||
}
|
||||
|
||||
this->m_disassembling = false;
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
void ViewDisassembler::drawContent() {
|
||||
@@ -321,14 +317,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginDisabled(this->m_disassembling);
|
||||
ImGui::BeginDisabled(this->m_disassemblerTask.isRunning());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.disassembler.disassemble"_lang))
|
||||
this->disassemble();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_disassembling) {
|
||||
if (this->m_disassemblerTask.isRunning()) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextSpinner("hex.builtin.view.disassembler.disassembling"_lang);
|
||||
}
|
||||
@@ -345,7 +341,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.bytes"_lang);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.title"_lang);
|
||||
|
||||
if (!this->m_disassembling) {
|
||||
if (!this->m_disassemblerTask.isRunning()) {
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(this->m_disassembly.size());
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <array>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include <llvm/Demangle/Demangle.h>
|
||||
@@ -235,6 +234,9 @@ namespace hex::plugin::builtin {
|
||||
reader.setEndAddress(searchRegion.getEndAddress());
|
||||
|
||||
auto sequence = hex::decodeByteString(settings.sequence);
|
||||
if (sequence.empty())
|
||||
return { };
|
||||
|
||||
auto occurrence = reader.begin();
|
||||
while (true) {
|
||||
occurrence = std::search(reader.begin(), reader.end(), std::boyer_moore_horspool_searcher(sequence.begin(), sequence.end()));
|
||||
@@ -269,8 +271,13 @@ namespace hex::plugin::builtin {
|
||||
std::string string(occurrence.region.getSize(), '\x00');
|
||||
provider->read(occurrence.region.getStartAddress(), string.data(), occurrence.region.getSize());
|
||||
|
||||
if (std::regex_match(string, regex))
|
||||
result.push_back(occurrence);
|
||||
if (settings.fullMatch) {
|
||||
if (std::regex_match(string, regex))
|
||||
result.push_back(occurrence);
|
||||
} else {
|
||||
if (std::regex_search(string, regex))
|
||||
result.push_back(occurrence);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -319,9 +326,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}();
|
||||
|
||||
this->m_searchRunning = true;
|
||||
std::thread([this, settings = this->m_searchSettings, searchRegion]{
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.find.searching", searchRegion.getSize());
|
||||
this->m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = this->m_searchSettings, searchRegion](auto &task) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
switch (settings.mode) {
|
||||
@@ -338,7 +343,7 @@ namespace hex::plugin::builtin {
|
||||
case BinaryPattern:
|
||||
this->m_foundOccurrences[provider] = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_sortedOccurrences[provider] = this->m_foundOccurrences[provider];
|
||||
|
||||
@@ -346,9 +351,7 @@ namespace hex::plugin::builtin {
|
||||
for (const auto &occurrence : this->m_foundOccurrences[provider])
|
||||
intervals.push_back(OccurrenceTree::interval(occurrence.region.getStartAddress(), occurrence.region.getEndAddress(), occurrence));
|
||||
this->m_occurrenceTree[provider] = std::move(intervals);
|
||||
|
||||
this->m_searchRunning = false;
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
std::string ViewFind::decodeValue(prv::Provider *provider, Occurrence occurrence) const {
|
||||
@@ -408,7 +411,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::Begin(View::toWindowName("hex.builtin.view.find.name").c_str(), &this->getWindowOpenState())) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
ImGui::BeginDisabled(this->m_searchRunning);
|
||||
ImGui::BeginDisabled(this->m_searchTask.isRunning());
|
||||
{
|
||||
ui::regionSelectionPicker(&this->m_searchSettings.range, true, true);
|
||||
|
||||
@@ -466,7 +469,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::InputText("hex.builtin.common.value"_lang, settings.sequence);
|
||||
|
||||
this->m_settingsValid = !settings.sequence.empty();
|
||||
this->m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
@@ -475,7 +478,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
mode = SearchSettings::Mode::Regex;
|
||||
|
||||
ImGui::InputText("hex.builtin.view.find.regex"_lang, settings.pattern);
|
||||
ImGui::InputText("hex.builtin.view.find.regex.pattern"_lang, settings.pattern);
|
||||
|
||||
try {
|
||||
std::regex regex(settings.pattern);
|
||||
@@ -487,6 +490,8 @@ namespace hex::plugin::builtin {
|
||||
if (settings.pattern.empty())
|
||||
this->m_settingsValid = false;
|
||||
|
||||
ImGui::Checkbox("hex.builtin.view.find.regex.full_match"_lang, &settings.fullMatch);
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.find.binary_pattern"_lang)) {
|
||||
@@ -519,6 +524,16 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::TextFormatted("hex.builtin.view.find.search.entries"_lang, this->m_foundOccurrences[provider].size());
|
||||
|
||||
ImGui::BeginDisabled(this->m_foundOccurrences[provider].empty());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.find.search.reset"_lang)) {
|
||||
this->m_foundOccurrences[provider].clear();
|
||||
this->m_sortedOccurrences[provider].clear();
|
||||
this->m_occurrenceTree[provider].clear();
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
@@ -529,11 +544,11 @@ namespace hex::plugin::builtin {
|
||||
auto &currOccurrences = this->m_sortedOccurrences[provider];
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
if (ImGui::InputTextWithHint("##filter", "hex.builtin.common.filter"_lang, this->m_currFilter)) {
|
||||
this->m_sortedOccurrences = this->m_foundOccurrences;
|
||||
if (ImGui::InputTextWithHint("##filter", "hex.builtin.common.filter"_lang, this->m_currFilter[provider])) {
|
||||
this->m_sortedOccurrences[provider] = this->m_foundOccurrences[provider];
|
||||
|
||||
currOccurrences.erase(std::remove_if(currOccurrences.begin(), currOccurrences.end(), [this, provider](const auto ®ion) {
|
||||
return !this->decodeValue(provider, region).contains(this->m_currFilter);
|
||||
return !this->decodeValue(provider, region).contains(this->m_currFilter[provider]);
|
||||
}), currOccurrences.end());
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <hex/providers/buffered_reader.hpp>
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
|
||||
#include "math_evaluator.hpp"
|
||||
#include <content/helpers/math_evaluator.hpp>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -143,6 +143,17 @@ namespace hex::plugin::builtin {
|
||||
|
||||
class PopupFind : public ViewHexEditor::Popup {
|
||||
public:
|
||||
PopupFind() {
|
||||
EventManager::subscribe<EventRegionSelected>(this, [this](Region region) {
|
||||
this->m_searchPosition = this->m_nextSearchPosition.value_or(region.getStartAddress());
|
||||
this->m_nextSearchPosition.reset();
|
||||
});
|
||||
}
|
||||
|
||||
~PopupFind() override {
|
||||
EventManager::unsubscribe<EventRegionSelected>(this);
|
||||
}
|
||||
|
||||
void draw(ViewHexEditor *editor) override {
|
||||
std::vector<u8> searchSequence;
|
||||
|
||||
@@ -189,22 +200,34 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
if (!this->m_searchRunning && !searchSequence.empty() && this->m_shouldSearch) {
|
||||
this->m_searchRunning = true;
|
||||
std::thread([this, searchSequence, editor]{
|
||||
auto task = ImHexApi::Tasks::createTask("Searching", ImHexApi::Provider::get()->getSize());
|
||||
if (!this->m_searchTask.isRunning() && !searchSequence.empty() && this->m_shouldSearch) {
|
||||
this->m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
|
||||
for (u8 retry = 0; retry < 2; retry++) {
|
||||
auto region = this->findSequence(searchSequence, this->m_backwards);
|
||||
|
||||
if (auto region = this->findSequence(editor, searchSequence, this->m_backwards); region.has_value()) {
|
||||
ImHexApi::Tasks::doLater([editor, region]{
|
||||
editor->setSelection(region->getStartAddress(), region->getEndAddress());
|
||||
editor->jumpToSelection();
|
||||
});
|
||||
if (region.has_value()) {
|
||||
if (editor->getSelection() == region) {
|
||||
if (this->m_nextSearchPosition.has_value())
|
||||
this->m_searchPosition = this->m_nextSearchPosition.value();
|
||||
this->m_nextSearchPosition.reset();
|
||||
|
||||
continue;
|
||||
} else {
|
||||
TaskManager::doLater([editor, region]{
|
||||
editor->setSelection(region->getStartAddress(), region->getEndAddress());
|
||||
editor->jumpToSelection();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this->m_reachedEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_shouldSearch = false;
|
||||
this->m_requestFocus = true;
|
||||
this->m_searchRunning = false;
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,26 +241,40 @@ namespace hex::plugin::builtin {
|
||||
this->m_requestFocus = false;
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(this->m_searchRunning);
|
||||
ImGui::BeginDisabled(this->m_searchTask.isRunning());
|
||||
{
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IconButton(ICON_VS_SEARCH "##search", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
this->m_reachedEnd = false;
|
||||
this->m_searchPosition.reset();
|
||||
this->m_nextSearchPosition.reset();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(!this->m_searchPosition.has_value());
|
||||
{
|
||||
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = true;
|
||||
ImGui::BeginDisabled(this->m_reachedEnd && this->m_backwards);
|
||||
{
|
||||
if (ImGui::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = true;
|
||||
this->m_reachedEnd = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
|
||||
ImGui::BeginDisabled(this->m_reachedEnd && !this->m_backwards);
|
||||
{
|
||||
if (ImGui::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
|
||||
this->m_shouldSearch = true;
|
||||
this->m_backwards = false;
|
||||
this->m_reachedEnd = false;
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
@@ -245,13 +282,10 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
std::optional<Region> findSequence(ViewHexEditor *editor, const std::vector<u8> &sequence, bool backwards) {
|
||||
std::optional<Region> findSequence(const std::vector<u8> &sequence, bool backwards) {
|
||||
hex::prv::BufferedReader reader(ImHexApi::Provider::get());
|
||||
|
||||
if (!editor->isSelectionValid())
|
||||
reader.seek(this->m_searchPosition.value_or(0x00));
|
||||
else
|
||||
reader.seek(this->m_searchPosition.value_or(editor->getSelection().getStartAddress()));
|
||||
reader.seek(this->m_searchPosition.value_or(0x00));
|
||||
|
||||
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
|
||||
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
|
||||
@@ -260,18 +294,18 @@ namespace hex::plugin::builtin {
|
||||
if (!backwards) {
|
||||
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
|
||||
if (occurrence != reader.end()) {
|
||||
this->m_searchPosition = occurrence.getAddress() + sequence.size();
|
||||
this->m_nextSearchPosition = occurrence.getAddress() + sequence.size();
|
||||
return Region { occurrence.getAddress(), sequence.size() };
|
||||
}
|
||||
} else {
|
||||
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.begin(), sequence.end());
|
||||
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.rbegin(), sequence.rend());
|
||||
if (occurrence != reader.rend()) {
|
||||
if (occurrence.getAddress() < sequence.size())
|
||||
this->m_searchPosition = 0x00;
|
||||
this->m_nextSearchPosition = 0x00;
|
||||
else
|
||||
this->m_searchPosition = occurrence.getAddress() - sequence.size();
|
||||
this->m_nextSearchPosition = occurrence.getAddress() - sequence.size();
|
||||
|
||||
return Region { occurrence.getAddress(), sequence.size() };
|
||||
return Region { occurrence.getAddress() - (sequence.size() - 1), sequence.size() };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,13 +313,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
std::string m_input;
|
||||
std::optional<u64> m_searchPosition;
|
||||
std::optional<u64> m_searchPosition, m_nextSearchPosition;
|
||||
|
||||
bool m_requestFocus = true;
|
||||
std::atomic<bool> m_shouldSearch = false;
|
||||
std::atomic<bool> m_backwards = false;
|
||||
std::atomic<bool> m_reachedEnd = false;
|
||||
|
||||
std::atomic<bool> m_searchRunning = false;
|
||||
TaskHolder m_searchTask;
|
||||
};
|
||||
|
||||
class PopupBaseAddress : public ViewHexEditor::Popup {
|
||||
@@ -967,14 +1002,14 @@ namespace hex::plugin::builtin {
|
||||
if ((ImGui::IsMouseDown(ImGuiMouseButton_Left) && this->m_selectionStart != this->m_selectionEnd)) {
|
||||
auto fractionPerLine = 1.0 / (this->m_visibleRowCount + 1);
|
||||
|
||||
if (y == u64(clipper.DisplayStart + 2)) {
|
||||
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 2) * this->m_bytesPerRow)) {
|
||||
if (y == u64(clipper.DisplayStart + 3)) {
|
||||
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 3) * this->m_bytesPerRow)) {
|
||||
this->m_shouldScrollToSelection = false;
|
||||
ImGui::SetScrollHereY(fractionPerLine * 4);
|
||||
ImGui::SetScrollHereY(fractionPerLine * 5);
|
||||
|
||||
}
|
||||
} else if (y == u64(clipper.DisplayEnd - 2)) {
|
||||
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 2) * this->m_bytesPerRow)) {
|
||||
} else if (y == u64(clipper.DisplayEnd - 3)) {
|
||||
if (i128(this->m_selectionEnd - provider->getBaseAddress() - provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 3) * this->m_bytesPerRow)) {
|
||||
this->m_shouldScrollToSelection = false;
|
||||
ImGui::SetScrollHereY(fractionPerLine * (this->m_visibleRowCount - 1));
|
||||
}
|
||||
@@ -1117,7 +1152,7 @@ namespace hex::plugin::builtin {
|
||||
void ViewHexEditor::drawContent() {
|
||||
|
||||
if (ImGui::Begin(View::toWindowName(this->getUnlocalizedName()).c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||
const auto FooterSize = ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetTextLineHeightWithSpacing() * 3);
|
||||
const auto FooterSize = ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetTextLineHeightWithSpacing() * 2.3);
|
||||
const auto TableSize = ImGui::GetContentRegionAvail() - ImVec2(0, FooterSize.y);
|
||||
|
||||
this->drawPopup();
|
||||
@@ -1140,17 +1175,22 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
static void copyBytes(const Region &selection) {
|
||||
constexpr static auto Format = "{0:02X} ";
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
std::vector<u8> buffer(selection.size, 0x00);
|
||||
provider->read(selection.getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress(), buffer.data(), buffer.size());
|
||||
auto reader = prv::BufferedReader(provider);
|
||||
reader.seek(selection.getStartAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress());
|
||||
reader.setEndAddress(selection.getEndAddress() + provider->getBaseAddress() + provider->getCurrentPageAddress());
|
||||
|
||||
std::string str;
|
||||
for (const auto &byte : buffer)
|
||||
str += hex::format("{0:02X} ", byte);
|
||||
str.pop_back();
|
||||
std::string result;
|
||||
result.reserve(fmt::format(Format, 0x00).size() * selection.getSize());
|
||||
|
||||
ImGui::SetClipboardText(str.c_str());
|
||||
for (const auto &byte : reader)
|
||||
result += fmt::format(Format, byte);
|
||||
result.pop_back();
|
||||
|
||||
ImGui::SetClipboardText(result.c_str());
|
||||
}
|
||||
|
||||
static void pasteBytes(const Region &selection) {
|
||||
@@ -1349,6 +1389,12 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
|
||||
EventManager::subscribe<RequestSelectionChange>(this, [this](Region region) {
|
||||
if (region == Region::Invalid()) {
|
||||
this->m_selectionStart = InvalidSelection;
|
||||
this->m_selectionEnd = InvalidSelection;
|
||||
return;
|
||||
}
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
auto page = provider->getPageOfAddress(region.getStartAddress());
|
||||
|
||||
@@ -1485,6 +1531,8 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::BeginMenu("hex.builtin.view.hex_editor.menu.edit.copy_as"_lang, selection.has_value() && providerValid)) {
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.hex"_lang, "CTRL + SHIFT + C"))
|
||||
copyString(*selection);
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.copy.address"_lang))
|
||||
ImGui::SetClipboardText(hex::format("0x{:08X}", selection->getStartAddress()).c_str());
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
|
||||
@@ -4,20 +4,15 @@
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/providers/buffered_reader.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/literals.hpp>
|
||||
#include <hex/helpers/magic.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <cinttypes>
|
||||
#include <filesystem>
|
||||
#include <numeric>
|
||||
#include <span>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/magic.hpp>
|
||||
|
||||
#include <implot.h>
|
||||
|
||||
@@ -80,12 +75,10 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewInformation::analyze() {
|
||||
this->m_analyzing = true;
|
||||
|
||||
std::thread([this] {
|
||||
this->m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.information.analyzing", provider->getActualSize());
|
||||
task.setMaxValue(provider->getActualSize());
|
||||
|
||||
this->m_analyzedRegion = { provider->getBaseAddress(), provider->getBaseAddress() + provider->getSize() };
|
||||
|
||||
@@ -127,9 +120,7 @@ namespace hex::plugin::builtin {
|
||||
else
|
||||
this->m_highestBlockEntropy = 0;
|
||||
}
|
||||
|
||||
this->m_analyzing = false;
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
void ViewInformation::drawContent() {
|
||||
@@ -138,14 +129,14 @@ namespace hex::plugin::builtin {
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
||||
ImGui::BeginDisabled(this->m_analyzing);
|
||||
ImGui::BeginDisabled(this->m_analyzerTask.isRunning());
|
||||
{
|
||||
if (ImGui::Button("hex.builtin.view.information.analyze"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
this->analyze();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_analyzing) {
|
||||
if (this->m_analyzerTask.isRunning()) {
|
||||
ImGui::TextSpinner("hex.builtin.view.information.analyzing"_lang);
|
||||
} else {
|
||||
ImGui::NewLine();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <pl/pattern_language.hpp>
|
||||
#include <pl/patterns/pattern.hpp>
|
||||
|
||||
#include <provider_extra_data.hpp>
|
||||
@@ -72,12 +71,12 @@ namespace hex::plugin::builtin {
|
||||
static bool beginPatternTable(prv::Provider *&provider, const std::vector<std::shared_ptr<pl::ptrn::Pattern>> &patterns, std::vector<pl::ptrn::Pattern*> &sortedPatterns) {
|
||||
if (ImGui::BeginTable("##Patterntable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, 0, 0, ImGui::GetID("name"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, 0, 0, ImGui::GetID("color"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, 0, 0, ImGui::GetID("offset"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, 0, 0, ImGui::GetID("size"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, 0, 0, ImGui::GetID("type"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, 0, 0, ImGui::GetID("value"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.var_name"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("name"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.color"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("color"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.offset"_lang, ImGuiTableColumnFlags_PreferSortAscending | ImGuiTableColumnFlags_DefaultSort, 0, ImGui::GetID("offset"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.size"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("size"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.type"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("type"));
|
||||
ImGui::TableSetupColumn("hex.builtin.view.pattern_data.value"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("value"));
|
||||
|
||||
auto sortSpecs = ImGui::TableGetSortSpecs();
|
||||
|
||||
@@ -108,10 +107,10 @@ namespace hex::plugin::builtin {
|
||||
void ViewPatternData::drawContent() {
|
||||
if (ImGui::Begin(View::toWindowName("hex.builtin.view.pattern_data.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable() && !ProviderExtraData::get(provider).patternLanguage.runtime->isRunning()) {
|
||||
|
||||
auto &sortedPatterns = this->m_sortedPatterns[ImHexApi::Provider::get()];
|
||||
if (beginPatternTable(provider, ProviderExtraData::get(provider).patternLanguage.runtime->getPatterns(), sortedPatterns)) {
|
||||
if (beginPatternTable(provider, ProviderExtraData::get(provider).patternLanguage.runtime->getAllPatterns(), sortedPatterns)) {
|
||||
ImGui::TableHeadersRow();
|
||||
if (!sortedPatterns.empty()) {
|
||||
|
||||
@@ -126,4 +125,4 @@ namespace hex::plugin::builtin {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ namespace hex::plugin::builtin {
|
||||
static bool initialized = false;
|
||||
static TextEditor::LanguageDefinition langDef;
|
||||
if (!initialized) {
|
||||
static constexpr std::array keywords = {
|
||||
"using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "false", "true", "this", "parent", "addressof", "sizeof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out"
|
||||
constexpr static std::array keywords = {
|
||||
"using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "false", "true", "this", "parent", "addressof", "sizeof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out", "ref"
|
||||
};
|
||||
for (auto &k : keywords)
|
||||
langDef.mKeywords.insert(k);
|
||||
|
||||
static constexpr std::array builtInTypes = {
|
||||
constexpr static std::array builtInTypes = {
|
||||
"u8", "u16", "u24", "u32", "u48", "u64", "u96", "u128", "s8", "s16", "s24", "s32", "s48", "s64", "s96", "s128", "float", "double", "char", "char16", "bool", "padding", "str", "auto"
|
||||
};
|
||||
for (const auto name : builtInTypes) {
|
||||
@@ -80,7 +80,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
ViewPatternEditor::ViewPatternEditor() : View("hex.builtin.view.pattern_editor.name") {
|
||||
this->m_parserRuntime = ContentRegistry::PatternLanguage::createDefaultRuntime(nullptr);
|
||||
this->m_parserRuntime = std::make_unique<pl::PatternLanguage>();
|
||||
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
|
||||
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
this->m_textEditor.SetShowWhitespaces(false);
|
||||
@@ -110,7 +111,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
EventManager::subscribe<EventProviderOpened>(this, [this](prv::Provider *provider) {
|
||||
auto &patternLanguageData = ProviderExtraData::get(provider).patternLanguage;
|
||||
patternLanguageData.runtime = ContentRegistry::PatternLanguage::createDefaultRuntime(provider);
|
||||
patternLanguageData.runtime = std::make_unique<pl::PatternLanguage>();
|
||||
ContentRegistry::PatternLanguage::configureRuntime(*patternLanguageData.runtime, provider);
|
||||
|
||||
if (!this->m_autoLoadPatterns)
|
||||
return;
|
||||
@@ -253,7 +255,7 @@ namespace hex::plugin::builtin {
|
||||
return std::nullopt;
|
||||
|
||||
std::optional<ImColor> color;
|
||||
for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatterns(address)) {
|
||||
for (const auto &pattern : ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address)) {
|
||||
if (pattern->isHidden())
|
||||
continue;
|
||||
|
||||
@@ -269,7 +271,7 @@ namespace hex::plugin::builtin {
|
||||
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8 *data, size_t size) {
|
||||
hex::unused(data, size);
|
||||
|
||||
auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatterns(address);
|
||||
auto patterns = ProviderExtraData::getCurrent().patternLanguage.runtime->getPatternsAtAddress(address);
|
||||
if (!patterns.empty() && !std::all_of(patterns.begin(), patterns.end(), [](const auto &pattern) { return pattern->isHidden(); })) {
|
||||
ImGui::BeginTooltip();
|
||||
for (const auto &pattern : patterns) {
|
||||
@@ -290,6 +292,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
@@ -303,7 +306,8 @@ namespace hex::plugin::builtin {
|
||||
if (!this->m_syncPatternSourceCode)
|
||||
ProviderExtraData::get(provider).patternLanguage.sourceCode = sourceCode;
|
||||
|
||||
this->m_textEditor.SetText(sourceCode);
|
||||
if (provider == ImHexApi::Provider::get())
|
||||
this->m_textEditor.SetText(sourceCode);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -416,6 +420,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (this->m_dangerousFunctionCalled && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) {
|
||||
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str());
|
||||
this->m_dangerousFunctionCalled = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
@@ -522,7 +527,7 @@ namespace hex::plugin::builtin {
|
||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
constexpr const char *Types[] = { "I", "F", "S", "B" };
|
||||
constexpr static const char *Types[] = { "I", "F", "S", "B" };
|
||||
if (ImGui::BeginCombo("", Types[static_cast<int>(type)])) {
|
||||
for (auto i = 0; i < IM_ARRAYSIZE(Types); i++) {
|
||||
if (ImGui::Selectable(Types[i]))
|
||||
@@ -702,51 +707,51 @@ namespace hex::plugin::builtin {
|
||||
{
|
||||
ImGui::ColorButton(pattern->getVariableName().c_str(), ImColor(pattern->getColor()));
|
||||
ImGui::SameLine(0, 10);
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{}", pattern->getFormattedName());
|
||||
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "{} ", pattern->getFormattedName());
|
||||
ImGui::SameLine(0, 5);
|
||||
ImGui::TextFormatted("{}", pattern->getDisplayName());
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
ImGui::TextFormatted("{}", pattern->getFormattedValue());
|
||||
ImGui::TextFormatted("{} ", pattern->getFormattedValue());
|
||||
|
||||
if (ImGui::GetIO().KeyShift) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_NoClip)) {
|
||||
if (ImGui::BeginTable("##extra_info", 2, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_NoClip)) {
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.type"_lang);
|
||||
ImGui::TextFormatted("{} ", "hex.builtin.common.type"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern->getTypeName());
|
||||
ImGui::TextFormatted(" {}", pattern->getTypeName());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.address"_lang);
|
||||
ImGui::TextFormatted("{} ", "hex.builtin.common.address"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("0x{:08X}", pattern->getOffset());
|
||||
ImGui::TextFormatted(" 0x{:08X}", pattern->getOffset());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.size"_lang);
|
||||
ImGui::TextFormatted("{} ", "hex.builtin.common.size"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", hex::toByteString(pattern->getSize()));
|
||||
ImGui::TextFormatted(" {}", hex::toByteString(pattern->getSize()));
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.endian"_lang);
|
||||
ImGui::TextFormatted("{} ", "hex.builtin.common.endian"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}", pattern->getEndian() == std::endian::little ? "hex.builtin.common.little"_lang : "hex.builtin.common.big"_lang);
|
||||
ImGui::TextFormatted(" {}", pattern->getEndian() == std::endian::little ? "hex.builtin.common.little"_lang : "hex.builtin.common.big"_lang);
|
||||
|
||||
if (const auto &comment = pattern->getComment(); comment.has_value()) {
|
||||
if (const auto &comment = pattern->getComment(); comment != nullptr) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextFormatted("{}: ", "hex.builtin.common.comment"_lang);
|
||||
ImGui::TextFormatted("{} ", "hex.builtin.common.comment"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("\"%s\"", pattern->getComment()->c_str());
|
||||
ImGui::TextWrapped(" \"%s\"", comment->c_str());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
@@ -773,6 +778,7 @@ namespace hex::plugin::builtin {
|
||||
void ViewPatternEditor::parsePattern(const std::string &code) {
|
||||
this->m_runningParsers++;
|
||||
|
||||
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
|
||||
auto ast = this->m_parserRuntime->parseString(code);
|
||||
|
||||
this->m_patternVariables.clear();
|
||||
@@ -810,14 +816,15 @@ namespace hex::plugin::builtin {
|
||||
this->m_textEditor.SetErrorMarkers({});
|
||||
this->m_console.clear();
|
||||
|
||||
auto &runtime = ProviderExtraData::getCurrent().patternLanguage.runtime;
|
||||
runtime->reset();
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
auto &runtime = ProviderExtraData::get(provider).patternLanguage.runtime;
|
||||
|
||||
ContentRegistry::PatternLanguage::configureRuntime(*runtime, provider);
|
||||
|
||||
EventManager::post<EventHighlightingChanged>();
|
||||
|
||||
std::thread([this, code, &runtime] {
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.pattern_editor.evaluating", 1);
|
||||
|
||||
TaskManager::createTask("hex.builtin.view.pattern_editor.evaluating", TaskManager::NoProgress, [this, &runtime, code](auto &task) {
|
||||
task.setInterruptCallback([&runtime] { runtime->abort(); });
|
||||
|
||||
std::map<std::string, pl::core::Token::Literal> envVars;
|
||||
for (const auto &[id, name, value, type] : this->m_envVarEntries)
|
||||
@@ -844,14 +851,12 @@ namespace hex::plugin::builtin {
|
||||
this->m_lastEvaluationError = runtime->getError();
|
||||
}
|
||||
|
||||
runtime->flattenPatterns();
|
||||
|
||||
this->m_lastEvaluationLog = runtime->getConsoleLog();
|
||||
this->m_lastEvaluationOutVars = runtime->getOutVariables();
|
||||
this->m_runningEvaluators--;
|
||||
|
||||
this->m_lastEvaluationProcessed = false;
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::Button("hex.builtin.common.open"_lang)) {
|
||||
if (provider->open()) {
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -11,14 +11,16 @@ namespace hex::plugin::builtin {
|
||||
ViewSettings::ViewSettings() : View("hex.builtin.view.settings.name") {
|
||||
EventManager::subscribe<RequestOpenWindow>(this, [this](const std::string &name) {
|
||||
if (name == "Settings") {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
|
||||
this->getWindowOpenState() = true;
|
||||
TaskManager::doLater([this] {
|
||||
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str());
|
||||
this->getWindowOpenState() = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 2000, [&, this] {
|
||||
if (ImGui::MenuItem("hex.builtin.view.settings.name"_lang)) {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.settings.name").c_str()); });
|
||||
this->getWindowOpenState() = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ContentRegistry::Interface::addMenuItem("hex.builtin.menu.help", 3000, [&, this] {
|
||||
if (ImGui::MenuItem("hex.builtin.view.store.name"_lang)) {
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup(View::toWindowName("hex.builtin.view.store.name").c_str()); });
|
||||
this->getWindowOpenState() = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::Button("hex.builtin.view.yara.reload"_lang)) this->reloadRules();
|
||||
} else {
|
||||
ImGui::BeginDisabled(this->m_matching);
|
||||
ImGui::BeginDisabled(this->m_matcherTask.isRunning());
|
||||
{
|
||||
if (ImGui::BeginCombo("hex.builtin.view.yara.header.rules"_lang, this->m_rules[this->m_selectedRule].first.string().c_str())) {
|
||||
for (u32 i = 0; i < this->m_rules.size(); i++) {
|
||||
@@ -63,7 +63,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if (this->m_matching) {
|
||||
if (this->m_matcherTask.isRunning()) {
|
||||
ImGui::SameLine();
|
||||
ImGui::TextSpinner("hex.builtin.view.yara.matching"_lang);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
if (!this->m_matching) {
|
||||
if (!this->m_matcherTask.isRunning()) {
|
||||
ImGuiListClipper clipper;
|
||||
clipper.Begin(this->m_matches.size());
|
||||
|
||||
@@ -173,19 +173,13 @@ namespace hex::plugin::builtin {
|
||||
void ViewYara::applyRules() {
|
||||
this->clearResult();
|
||||
|
||||
this->m_matching = true;
|
||||
|
||||
std::thread([this] {
|
||||
this->m_matcherTask = TaskManager::createTask("hex.builtin.view.yara.matching", 0, [this](auto &task) {
|
||||
if (!ImHexApi::Provider::isValid()) return;
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
auto task = ImHexApi::Tasks::createTask("hex.builtin.view.yara.matching", provider->getActualSize());
|
||||
|
||||
YR_COMPILER *compiler = nullptr;
|
||||
yr_compiler_create(&compiler);
|
||||
ON_SCOPE_EXIT {
|
||||
yr_compiler_destroy(compiler);
|
||||
this->m_matching = false;
|
||||
};
|
||||
|
||||
yr_compiler_set_include_callback(
|
||||
@@ -209,8 +203,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
delete[] ptr;
|
||||
},
|
||||
fs::toShortPath(this->m_rules[this->m_selectedRule].second).string().data());
|
||||
|
||||
fs::toShortPath(this->m_rules[this->m_selectedRule].second).string().data()
|
||||
);
|
||||
|
||||
fs::File file(this->m_rules[this->m_selectedRule].second, fs::File::Mode::Read);
|
||||
if (!file.isValid()) return;
|
||||
@@ -220,7 +214,7 @@ namespace hex::plugin::builtin {
|
||||
yr_compiler_get_error_message(compiler, errorMessage.data(), errorMessage.size());
|
||||
hex::trim(errorMessage);
|
||||
|
||||
ImHexApi::Tasks::doLater([this, errorMessage] {
|
||||
TaskManager::doLater([this, errorMessage] {
|
||||
this->clearResult();
|
||||
|
||||
this->m_consoleMessages.push_back("Error: " + errorMessage);
|
||||
@@ -246,15 +240,14 @@ namespace hex::plugin::builtin {
|
||||
context.currBlock.base = 0;
|
||||
context.currBlock.fetch_data = [](auto *block) -> const u8 * {
|
||||
auto &context = *static_cast<ScanContext *>(block->context);
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
context.buffer.resize(context.currBlock.size);
|
||||
|
||||
if (context.buffer.empty()) return nullptr;
|
||||
if (context.buffer.empty())
|
||||
return nullptr;
|
||||
|
||||
block->size = context.currBlock.size;
|
||||
|
||||
provider->read(context.currBlock.base + provider->getBaseAddress(), context.buffer.data(), context.buffer.size());
|
||||
|
||||
return context.buffer.data();
|
||||
@@ -301,11 +294,11 @@ namespace hex::plugin::builtin {
|
||||
ResultContext resultContext;
|
||||
|
||||
yr_rules_scan_mem_blocks(
|
||||
rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int {
|
||||
auto &results = *static_cast<ResultContext *>(userData);
|
||||
rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int {
|
||||
auto &results = *static_cast<ResultContext *>(userData);
|
||||
|
||||
switch (message) {
|
||||
case CALLBACK_MSG_RULE_MATCHING:
|
||||
switch (message) {
|
||||
case CALLBACK_MSG_RULE_MATCHING:
|
||||
{
|
||||
auto rule = static_cast<YR_RULE *>(data);
|
||||
|
||||
@@ -315,30 +308,30 @@ namespace hex::plugin::builtin {
|
||||
if (rule->strings != nullptr) {
|
||||
yr_rule_strings_foreach(rule, string) {
|
||||
yr_string_matches_foreach(context, string, match) {
|
||||
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0, 0 });
|
||||
}
|
||||
results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false, 0, 0 });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results.newMatches.push_back({ rule->identifier, "", 0, 0, true, 0, 0 });
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CALLBACK_MSG_CONSOLE_LOG:
|
||||
break;
|
||||
case CALLBACK_MSG_CONSOLE_LOG:
|
||||
{
|
||||
results.consoleMessages.emplace_back(static_cast<const char *>(data));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CALLBACK_CONTINUE;
|
||||
},
|
||||
&resultContext,
|
||||
0);
|
||||
return CALLBACK_CONTINUE;
|
||||
},
|
||||
&resultContext,
|
||||
0);
|
||||
|
||||
|
||||
ImHexApi::Tasks::doLater([this, resultContext] {
|
||||
TaskManager::doLater([this, resultContext] {
|
||||
this->m_matches = resultContext.newMatches;
|
||||
this->m_consoleMessages = resultContext.consoleMessages;
|
||||
|
||||
@@ -348,7 +341,7 @@ namespace hex::plugin::builtin {
|
||||
match.tooltipId = ImHexApi::HexEditor::addTooltip({ match. address, match.size }, hex::format("{0} [{1}]", match.identifier, match.variable), YaraColor);
|
||||
}
|
||||
});
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,9 @@
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
@@ -37,43 +39,53 @@ namespace hex::plugin::builtin {
|
||||
nlohmann::json data;
|
||||
|
||||
bool operator==(const RecentProvider &other) const {
|
||||
return displayName == other.displayName && type == other.type && data == other.data;
|
||||
return HashFunction()(*this) == HashFunction()(other);
|
||||
}
|
||||
|
||||
struct HashFunction {
|
||||
std::size_t operator()(const RecentProvider& provider) const {
|
||||
return
|
||||
(std::hash<std::string>()(provider.displayName)) ^
|
||||
(std::hash<std::string>()(provider.type) << 1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
static std::vector<RecentProvider> s_recentProviders;
|
||||
|
||||
static std::list<RecentProvider> s_recentProviders;
|
||||
|
||||
static void updateRecentProviders() {
|
||||
s_recentProviders.clear();
|
||||
|
||||
// Query all recent providers
|
||||
std::vector<std::fs::path> recentFiles;
|
||||
std::vector<std::fs::path> recentFilePaths;
|
||||
for (const auto &folder : fs::getDefaultPaths(fs::ImHexPath::Recent)) {
|
||||
for (const auto &entry : std::fs::directory_iterator(folder)) {
|
||||
if (entry.is_regular_file())
|
||||
recentFiles.push_back(entry.path());
|
||||
recentFilePaths.push_back(entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
// Sort recent provider files by last modified time
|
||||
std::sort(recentFiles.begin(), recentFiles.end(), [](const auto &a, const auto &b) {
|
||||
std::sort(recentFilePaths.begin(), recentFilePaths.end(), [](const auto &a, const auto &b) {
|
||||
return std::fs::last_write_time(a) > std::fs::last_write_time(b);
|
||||
});
|
||||
|
||||
for (u32 i = 0; i < recentFiles.size() && s_recentProviders.size() < 5; i++) {
|
||||
auto &path = recentFiles[i];
|
||||
std::unordered_set<RecentProvider, RecentProvider::HashFunction> uniqueProviders;
|
||||
for (u32 i = 0; i < recentFilePaths.size() && uniqueProviders.size() < 5; i++) {
|
||||
auto &path = recentFilePaths[i];
|
||||
try {
|
||||
auto jsonData = nlohmann::json::parse(fs::File(path, fs::File::Mode::Read).readString());
|
||||
s_recentProviders.push_back(RecentProvider {
|
||||
.displayName = jsonData["displayName"],
|
||||
.type = jsonData["type"],
|
||||
.filePath = path,
|
||||
.data = jsonData
|
||||
uniqueProviders.insert(RecentProvider {
|
||||
.displayName = jsonData["displayName"],
|
||||
.type = jsonData["type"],
|
||||
.filePath = path,
|
||||
.data = jsonData
|
||||
});
|
||||
} catch (...) { }
|
||||
}
|
||||
|
||||
// De-duplicate recent providers
|
||||
s_recentProviders.erase(std::unique(s_recentProviders.begin(), s_recentProviders.end()), s_recentProviders.end());
|
||||
std::copy(uniqueProviders.begin(), uniqueProviders.end(), std::front_inserter(s_recentProviders));
|
||||
}
|
||||
|
||||
static void loadRecentProvider(const RecentProvider &recentProvider) {
|
||||
@@ -83,13 +95,14 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (!provider->open() || !provider->isAvailable()) {
|
||||
View::showErrorPopup("hex.builtin.popup.error.open"_lang);
|
||||
ImHexApi::Tasks::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
TaskManager::doLater([provider] { ImHexApi::Provider::remove(provider); });
|
||||
return;
|
||||
}
|
||||
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
|
||||
updateRecentProviders();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void loadDefaultLayout() {
|
||||
@@ -325,11 +338,12 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetWindowSize().x - ImGui::CalcTextSize("X").x * 2, 0));
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
if (ImGui::Hyperlink("X")) {
|
||||
auto provider = ImHexApi::Provider::createProvider("hex.builtin.provider.null");
|
||||
if (provider != nullptr)
|
||||
(void)provider->open();
|
||||
if (provider->open())
|
||||
EventManager::post<EventProviderOpened>(provider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,8 +369,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
static void drawNoViewsBackground() {
|
||||
if (isAnyViewOpen() && ImHexApi::Provider::isValid()) return;
|
||||
|
||||
if (ImGui::Begin("ImHexDockSpace")) {
|
||||
static char title[256];
|
||||
ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", ImGui::GetCurrentWindow()->Name, ImGui::GetID("ImHexMainDock"));
|
||||
@@ -381,7 +393,10 @@ namespace hex::plugin::builtin {
|
||||
updateRecentProviders();
|
||||
|
||||
(void)EventManager::subscribe<EventFrameBegin>(drawWelcomeScreen);
|
||||
(void)EventManager::subscribe<EventFrameBegin>(drawNoViewsBackground);
|
||||
(void)EventManager::subscribe<EventFrameBegin>([]{
|
||||
if (ImHexApi::Provider::isValid() && !isAnyViewOpen())
|
||||
drawNoViewsBackground();
|
||||
});
|
||||
|
||||
(void)EventManager::subscribe<EventSettingsChanged>([]() {
|
||||
{
|
||||
@@ -513,11 +528,11 @@ namespace hex::plugin::builtin {
|
||||
});
|
||||
|
||||
|
||||
constexpr auto CrashBackupFileName = "crash_backup.hexproj";
|
||||
constexpr static auto CrashBackupFileName = "crash_backup.hexproj";
|
||||
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
|
||||
if (auto filePath = std::fs::path(path) / CrashBackupFileName; fs::exists(filePath)) {
|
||||
s_safetyBackupPath = filePath;
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.safety_backup.title"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.safety_backup.title"_lang); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,7 +541,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
bool showTipOfTheDay = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.show_tips", 1);
|
||||
if (showTipOfTheDay)
|
||||
ImHexApi::Tasks::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); });
|
||||
TaskManager::doLater([] { ImGui::OpenPopup("hex.builtin.welcome.tip_of_the_day"_lang); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "Pattern Language Dokumentation" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "Lern ImHex Patterns zu schreiben mit unserer umfangreichen Dokumentation" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "Erweitere ImHex mit neuen Funktionen mit Plugins" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -101,6 +101,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
||||
{ "hex.builtin.popup.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.popup.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
|
||||
{ "hex.builtin.popup.error.task_exception", "Fehler in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "Datei" },
|
||||
{ "hex.builtin.file.open_file", "Datei öffnen..." },
|
||||
@@ -132,7 +133,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{ "hex.builtin.menu.view", "Ansicht" },
|
||||
{ "hex.builtin.menu.layout", "Layout" },
|
||||
{ "hex.builtin.menu.view.fps", "FPS anzeigen" },
|
||||
{ "hex.builtin.menu.view.demo", "ImGui Demo anzeigen" },
|
||||
{ "hex.builtin.menu.help", "Hilfe" },
|
||||
|
||||
@@ -284,7 +284,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.file.save_as", "Speichern unter..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Kopieren" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Kopieren als..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "Hex String" },
|
||||
{ "hex.builtin.view.hex_editor.copy.address", "Adresse" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
|
||||
@@ -292,7 +293,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Einfügen" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Alles auswählen" },
|
||||
@@ -413,11 +420,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
{ "hex.builtin.view.find.sequences", "Sequenzen" },
|
||||
{ "hex.builtin.view.find.regex", "Regex" },
|
||||
{ "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
{ "hex.builtin.view.find.regex.full_match", "Benötige volle übereinstimmung" },
|
||||
{ "hex.builtin.view.find.binary_pattern", "Binärpattern" },
|
||||
{ "hex.builtin.view.find.search", "Suchen" },
|
||||
{ "hex.builtin.view.find.context.copy", "Wert Kopieren" },
|
||||
{ "hex.builtin.view.find.context.copy_demangle", "Demangled Wert Kopieren" },
|
||||
{ "hex.builtin.view.find.search.entries", "{} Einträge gefunden" },
|
||||
{ "hex.builtin.view.find.search.reset", "Zurücksetzen" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "Rechner" },
|
||||
{ "hex.builtin.command.cmd.desc", "Command" },
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "Pattern Language Documentation" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "Learn how to write ImHex patterns with our extensive documentation" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "Extend ImHex with additional features using plugins" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -103,8 +103,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
||||
{ "hex.builtin.popup.error.open", "Failed to open file!" },
|
||||
{ "hex.builtin.popup.error.create", "Failed to create new file!" },
|
||||
{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "File" },
|
||||
{ "hex.builtin.menu.file.create_file", "New File..." },
|
||||
{ "hex.builtin.menu.file.open_file", "Open File..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "Open Recent" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "Clear" },
|
||||
@@ -286,7 +288,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Save As..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copy" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copy as..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "Hex String" },
|
||||
{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
|
||||
@@ -294,7 +297,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Paste" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Select all" },
|
||||
@@ -417,11 +426,14 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
{ "hex.builtin.view.find.sequences", "Sequences" },
|
||||
{ "hex.builtin.view.find.regex", "Regex" },
|
||||
{ "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
{ "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
{ "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
{ "hex.builtin.view.find.search", "Search" },
|
||||
{ "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
{ "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
{ "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
{ "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "Calculator" },
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "Documentazione dei Pattern" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "Scopri come scrivere pattern per ImHex con la nostra dettagliata documentazione" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "Espandi l'utilizzo di ImHex con i Plugin" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
||||
{ "hex.builtin.popup.error.open", "Impossibile aprire il File!" },
|
||||
{ "hex.builtin.popup.error.create", "Impossibile creare il nuovo File!" },
|
||||
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "File" },
|
||||
//{ "hex.builtin.menu.file.create_file", "New File..." },
|
||||
{ "hex.builtin.menu.file.open_file", "Apri File..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "File recenti" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "Pulisci" },
|
||||
@@ -287,7 +289,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "Salva come..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copia" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copia come..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "Stringa" },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "Hex Stringa" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
|
||||
@@ -295,7 +298,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Incolla" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Seleziona tutti" },
|
||||
@@ -416,11 +425,14 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
// { "hex.builtin.view.find.sequences", "Sequences" },
|
||||
// { "hex.builtin.view.find.regex", "Regex" },
|
||||
//{ "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
//{ "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
// { "hex.builtin.view.find.search", "Search" },
|
||||
// { "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
// { "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "Calcolatrice" },
|
||||
{ "hex.builtin.command.cmd.desc", "Comando" },
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "ImHexオリジナル言語について" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "公式ドキュメントを読む" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "プラグインAPI" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "ImHexの機能を拡張する" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -81,13 +81,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.browse", "ファイルを参照…" },
|
||||
{ "hex.builtin.common.choose_file", "ファイルを選択" },
|
||||
// { "hex.builtin.common.processing", "Processing" },
|
||||
//{ "hex.builtin.common.filter", "Filter" },
|
||||
//{ "hex.builtin.common.value", "Value" },
|
||||
{ "hex.builtin.common.filter", "フィルタ" },
|
||||
{ "hex.builtin.common.value", "値" },
|
||||
{ "hex.builtin.common.offset", "オフセット" },
|
||||
//{ "hex.builtin.common.range", "Range" },
|
||||
//{ "hex.builtin.common.range.entire_data", "Entire Data" },
|
||||
//{ "hex.builtin.common.range.selection", "Selection" },
|
||||
//{ "hex.builtin.common.comment", "Comment" },
|
||||
{ "hex.builtin.common.range", "範囲" },
|
||||
{ "hex.builtin.common.range.entire_data", "データ全体" },
|
||||
{ "hex.builtin.common.range.selection", "選択範囲" },
|
||||
{ "hex.builtin.common.comment", "コメント" },
|
||||
|
||||
{ "hex.builtin.common.encoding.ascii", "ASCII" },
|
||||
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
|
||||
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "書き込み権限を取得できませんでした。ファイルが読み取り専用で開かれました。" },
|
||||
{ "hex.builtin.popup.error.open", "ファイルを開けませんでした。" },
|
||||
{ "hex.builtin.popup.error.create", "新しいファイルを作成できませんでした。" },
|
||||
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "ファイル" },
|
||||
//{ "hex.builtin.menu.file.create_file", "New File..." },
|
||||
{ "hex.builtin.menu.file.open_file", "ファイルを開く…" },
|
||||
{ "hex.builtin.menu.file.open_recent", "最近使用したファイル" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "リストをクリア" },
|
||||
@@ -123,9 +125,9 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.menu.file.export.ips", "IPSパッチ" },
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32パッチ" },
|
||||
{ "hex.builtin.menu.file.export.base64.popup.export_error", "有効なBase64形式ではありません。" },
|
||||
{ "hex.builtin.menu.file.export.popup.create", "データをエクスポートできません。\nファイルの作成に失敗しました。" },
|
||||
//{ "hex.builtin.menu.file.bookmark.import", "Import bookmarks" },
|
||||
//{ "hex.builtin.menu.file.bookmark.export", "Export bookmarks" },
|
||||
{ "hex.builtin.menu.file.export.popup.create", "データをエクスポートできません。\nファイルの作成に失敗しました。" },
|
||||
{ "hex.builtin.menu.file.bookmark.import", "ブックマークをインポート…" },
|
||||
{ "hex.builtin.menu.file.bookmark.export", "ブックマークをエクスポート…" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "編集" },
|
||||
{ "hex.builtin.menu.edit.undo", "元に戻す" },
|
||||
@@ -259,10 +261,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "Hexエディタ" },
|
||||
{ "hex.builtin.view.hex_editor.page", "ページ" },
|
||||
//{ "hex.builtin.view.hex_editor.selection", "Selection" },
|
||||
//{ "hex.builtin.view.hex_editor.selection.none", "None" },
|
||||
//{ "hex.builtin.view.hex_editor.region", "Region" },
|
||||
//{ "hex.builtin.view.hex_editor.data_size", "Data Size" },
|
||||
{ "hex.builtin.view.hex_editor.selection", "選択中" },
|
||||
{ "hex.builtin.view.hex_editor.selection.none", "なし" },
|
||||
{ "hex.builtin.view.hex_editor.region", "ページの領域" },
|
||||
{ "hex.builtin.view.hex_editor.data_size", "ファイルサイズ" },
|
||||
//{ "hex.builtin.view.hex_editor.no_bytes", "No bytes available" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "検索" },
|
||||
@@ -287,6 +289,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "コピー" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "〜としてコピー…" },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "文字列" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 配列" },
|
||||
@@ -294,7 +297,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "アスキーアート" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 配列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "貼り付け" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "すべて選択" },
|
||||
@@ -303,9 +312,9 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "リサイズ…" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "挿入…" },
|
||||
|
||||
{ "hex.builtin.view.information.name", "データ情報" },
|
||||
{ "hex.builtin.view.information.name", "データ解析" },
|
||||
{ "hex.builtin.view.information.control", "コントロール" },
|
||||
{ "hex.builtin.view.information.analyze", "解析ページ" },
|
||||
{ "hex.builtin.view.information.analyze", "表示中のページを解析する" },
|
||||
{ "hex.builtin.view.information.analyzing", "解析中…" },
|
||||
{ "hex.builtin.view.information.region", "解析する領域" },
|
||||
{ "hex.builtin.view.information.magic", "Magic情報" },
|
||||
@@ -318,7 +327,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.information.block_size.desc", "{0} ブロック/ {1} バイト" },
|
||||
{ "hex.builtin.view.information.file_entropy", "ファイルのエントロピー" },
|
||||
{ "hex.builtin.view.information.highest_entropy", "最大エントロピーブロック" },
|
||||
{ "hex.builtin.view.information.encrypted", "暗号化もしくは圧縮されているデータの可能性が高いです。" },
|
||||
{ "hex.builtin.view.information.encrypted", "暗号化や圧縮を経たデータと推測されます。" },
|
||||
{ "hex.builtin.view.information.magic_db_added", "Magicデータベースが追加されました。" },
|
||||
|
||||
{ "hex.builtin.view.patches.name", "パッチ" },
|
||||
@@ -400,31 +409,33 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.provider_settings.load_popup", "プロバイダを開く" },
|
||||
{ "hex.builtin.view.provider_settings.load_error", "プロバイダを開く際にエラーが発生しました。"},
|
||||
|
||||
//{ "hex.builtin.view.find.name", "Find" },
|
||||
// { "hex.builtin.view.find.searching", "Searching…" },
|
||||
{ "hex.builtin.view.find.name", "検索" },
|
||||
{ "hex.builtin.view.find.searching", "検索中…" },
|
||||
// { "hex.builtin.view.find.demangled", "Demangled" },
|
||||
// { "hex.builtin.view.find.range", "Range" },
|
||||
// { "hex.builtin.view.find.range.entire_data", "Entire Data" },
|
||||
// { "hex.builtin.view.find.range.selection", "Selection" },
|
||||
{ "hex.builtin.view.find.range", "検索する範囲" },
|
||||
{ "hex.builtin.view.find.range.selection", "選択中の箇所のみ" },
|
||||
// { "hex.builtin.view.find.strings", "文字列" },
|
||||
// { "hex.builtin.view.find.strings.min_length", "Minimum length" },
|
||||
// { "hex.builtin.view.find.strings.match_settings", "Match Settings" },
|
||||
// { "hex.builtin.view.find.strings.null_term", "Require Null Termination" },
|
||||
{ "hex.builtin.view.find.strings.match_settings", "条件設定" },
|
||||
{ "hex.builtin.view.find.strings.null_term", "ヌル終端を含む文字列のみ検索" },
|
||||
// { "hex.builtin.view.find.strings.chars", "Characters" },
|
||||
// { "hex.builtin.view.find.strings.lower_case", "Lower case letters" },
|
||||
// { "hex.builtin.view.find.strings.upper_case", "Upper case letters" },
|
||||
// { "hex.builtin.view.find.strings.numbers", "Numbers" },
|
||||
// { "hex.builtin.view.find.strings.underscores", "Underscores" },
|
||||
// { "hex.builtin.view.find.strings.symbols", "Symbols" },
|
||||
// { "hex.builtin.view.find.strings.spaces", "Spaces" },
|
||||
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
// { "hex.builtin.view.find.sequences", "Sequences" },
|
||||
// { "hex.builtin.view.find.regex", "Regex" },
|
||||
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
// { "hex.builtin.view.find.search", "Search" },
|
||||
// { "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
{ "hex.builtin.view.find.strings.lower_case", "大文字" },
|
||||
{ "hex.builtin.view.find.strings.upper_case", "小文字" },
|
||||
{ "hex.builtin.view.find.strings.numbers", "数字" },
|
||||
{ "hex.builtin.view.find.strings.underscores", "アンダースコア" },
|
||||
{ "hex.builtin.view.find.strings.symbols", "その他の記号" },
|
||||
{ "hex.builtin.view.find.strings.spaces", "半角スペース" },
|
||||
{ "hex.builtin.view.find.strings.line_feeds", "ラインフィード" },
|
||||
{ "hex.builtin.view.find.sequences", "通常検索" },
|
||||
{ "hex.builtin.view.find.regex", "正規表現" },
|
||||
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
{ "hex.builtin.view.find.binary_pattern", "16進数" },
|
||||
{ "hex.builtin.view.find.search", "検索を実行" },
|
||||
{ "hex.builtin.view.find.context.copy", "値をコピー" },
|
||||
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
// { "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
{ "hex.builtin.view.find.search.entries", "一致件数: {}" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "電卓" },
|
||||
{ "hex.builtin.command.cmd.desc", "コマンド" },
|
||||
|
||||
817
plugins/builtin/source/lang/ko_KR.cpp
Normal file
817
plugins/builtin/source/lang/ko_KR.cpp
Normal file
@@ -0,0 +1,817 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void registerLanguageKoKR() {
|
||||
ContentRegistry::Language::registerLanguage("한국어 (KR)", "ko-KR");
|
||||
|
||||
ContentRegistry::Language::addLocalizations("ko-KR", {
|
||||
{ "hex.builtin.welcome.header.main", "Welcome to ImHex" },
|
||||
{ "hex.builtin.welcome.header.start", "시작하기" },
|
||||
{ "hex.builtin.welcome.start.create_file", "새 파일 생성" },
|
||||
{ "hex.builtin.welcome.start.open_file", "파일 열기" },
|
||||
{ "hex.builtin.welcome.start.open_project", "프로젝트 열기" },
|
||||
{ "hex.builtin.welcome.start.recent", "최근 파일들" },
|
||||
{ "hex.builtin.welcome.start.open_other", "다른 공급자 열기" },
|
||||
{ "hex.builtin.welcome.header.help", "도움말" },
|
||||
{ "hex.builtin.welcome.help.repo", "GitHub 저장소" },
|
||||
{ "hex.builtin.welcome.help.repo.link", "https://imhex.werwolv.net/git" },
|
||||
{ "hex.builtin.welcome.help.gethelp", "도움 얻기" },
|
||||
{ "hex.builtin.welcome.help.gethelp.link", "https://github.com/WerWolv/ImHex/discussions/categories/get-help" },
|
||||
{ "hex.builtin.welcome.help.discord", "디스코드 서버" },
|
||||
{ "hex.builtin.welcome.help.discord.link", "https://imhex.werwolv.net/discord" },
|
||||
{ "hex.builtin.welcome.header.plugins", "로딩된 플러그인" },
|
||||
{ "hex.builtin.welcome.plugins.plugin", "플러그인" },
|
||||
{ "hex.builtin.welcome.plugins.author", "작성자" },
|
||||
{ "hex.builtin.welcome.plugins.desc", "설명" },
|
||||
{ "hex.builtin.welcome.header.customize", "커스터마이즈" },
|
||||
{ "hex.builtin.welcome.customize.settings.title", "설정" },
|
||||
{ "hex.builtin.welcome.customize.settings.desc", "ImHex의 설정을 변경합니다" },
|
||||
{ "hex.builtin.welcome.header.update", "업데이트" },
|
||||
{ "hex.builtin.welcome.update.title", "새로운 업데이트가 존재합니다!" },
|
||||
{ "hex.builtin.welcome.update.desc", "ImHex {0} 가 업데이트 되었습니다! 여기서 다운로드하세요." },
|
||||
{ "hex.builtin.welcome.update.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.header.learn", "Learn" },
|
||||
{ "hex.builtin.welcome.learn.latest.title", "최신 릴리즈" },
|
||||
{ "hex.builtin.welcome.learn.latest.desc", "ImHex의 최신 변경사항 읽기" },
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "패턴 언어 작성 방법 문서" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "ImHex 패턴을 작성하는 방법을 배워 봅시다." },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "플러그인 API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "플러그인을 이용해 ImHex의 기능을 확장해 봅시다." },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
{ "hex.builtin.welcome.header.various", "Various" },
|
||||
{ "hex.builtin.welcome.tip_of_the_day", "오늘의 팁" },
|
||||
|
||||
{ "hex.builtin.welcome.safety_backup.title", "손상된 데이터 복구" },
|
||||
{ "hex.builtin.welcome.safety_backup.desc", "이전에 ImHex가 비 정상적으로 종료된 것 같습니다.\n이전의 작업을 복구할까요?"},
|
||||
{ "hex.builtin.welcome.safety_backup.restore", "네, 복구" },
|
||||
{ "hex.builtin.welcome.safety_backup.delete", "아니요, 삭제" },
|
||||
|
||||
{ "hex.builtin.common.endian", "엔디안" },
|
||||
{ "hex.builtin.common.little_endian", "리틀 엔디안" },
|
||||
{ "hex.builtin.common.big_endian", "빅 엔디안" },
|
||||
{ "hex.builtin.common.little", "리틀" },
|
||||
{ "hex.builtin.common.big", "빅" },
|
||||
{ "hex.builtin.common.number_format", "포맷" },
|
||||
{ "hex.builtin.common.decimal", "10진수" },
|
||||
{ "hex.builtin.common.hexadecimal", "16진수" },
|
||||
{ "hex.builtin.common.octal", "8진수" },
|
||||
{ "hex.builtin.common.info", "정보" },
|
||||
{ "hex.builtin.common.error", "에러" },
|
||||
{ "hex.builtin.common.fatal", "치명적 에러" },
|
||||
{ "hex.builtin.common.question", "질문" },
|
||||
{ "hex.builtin.common.address", "주소" },
|
||||
{ "hex.builtin.common.size", "크기" },
|
||||
{ "hex.builtin.common.region", "지역" },
|
||||
{ "hex.builtin.common.match_selection", "선택 범위와 일치" },
|
||||
{ "hex.builtin.common.yes", "네" },
|
||||
{ "hex.builtin.common.no", "아니오" },
|
||||
{ "hex.builtin.common.okay", "네" },
|
||||
{ "hex.builtin.common.load", "불러오기" },
|
||||
{ "hex.builtin.common.cancel", "취소" },
|
||||
{ "hex.builtin.common.set", "설정" },
|
||||
{ "hex.builtin.common.close", "닫기" },
|
||||
{ "hex.builtin.common.dont_show_again", "다시 보이지 않기" },
|
||||
{ "hex.builtin.common.link", "링크" },
|
||||
{ "hex.builtin.common.file", "파일" },
|
||||
{ "hex.builtin.common.open", "열기" },
|
||||
{ "hex.builtin.common.browse", "찾아보기..." },
|
||||
{ "hex.builtin.common.choose_file", "파일 선택" },
|
||||
{ "hex.builtin.common.processing", "작업 중" },
|
||||
{ "hex.builtin.common.filter", "필터" },
|
||||
{ "hex.builtin.common.value", "값" },
|
||||
{ "hex.builtin.common.type", "타입" },
|
||||
{ "hex.builtin.common.offset", "오프셋" },
|
||||
{ "hex.builtin.common.range", "범위" },
|
||||
{ "hex.builtin.common.range.entire_data", "전체 데이터" },
|
||||
{ "hex.builtin.common.range.selection", "선택" },
|
||||
{ "hex.builtin.common.comment", "주석" },
|
||||
|
||||
{ "hex.builtin.common.encoding.ascii", "ASCII" },
|
||||
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
|
||||
{ "hex.builtin.common.encoding.utf16be", "UTF-16BE" },
|
||||
{ "hex.builtin.common.encoding.utf8", "UTF-8" },
|
||||
|
||||
{ "hex.builtin.popup.exit_application.title", "프로그램을 종료하시겠습니까?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "프로젝트에 저장하지 않은 내용이 있습니다.\n정말로 종료하시겠습니까?" },
|
||||
{ "hex.builtin.popup.close_provider.title", "공급자를 종료하시겠습니까?" },
|
||||
{ "hex.builtin.popup.close_provider.desc", "공급자에 저장하지 않은 내용이 있습니다.\n정말로 종료하시겠습니까?" },
|
||||
{ "hex.builtin.popup.error.read_only", "쓰기 권한을 가져올 수 없습니다. 파일이 읽기 전용 모드로 열렸습니다." },
|
||||
{ "hex.builtin.popup.error.open", "파일을 여는데 실패했습니다!" },
|
||||
{ "hex.builtin.popup.error.create", "새 파일을 만드는데 실패했습니다!" },
|
||||
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "파일" },
|
||||
{ "hex.builtin.menu.file.create_file", "새 파일..." },
|
||||
{ "hex.builtin.menu.file.open_file", "파일 열기..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "최근 파일" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "최근 이력 지우기" },
|
||||
{ "hex.builtin.menu.file.open_other", "다른 공급자 열기..." },
|
||||
{ "hex.builtin.menu.file.close", "닫기" },
|
||||
{ "hex.builtin.menu.file.quit", "ImHex 종료하기" },
|
||||
{ "hex.builtin.menu.file.open_project", "프로젝트 열기..." },
|
||||
{ "hex.builtin.menu.file.save_project", "프로젝트 저장..." },
|
||||
{ "hex.builtin.menu.file.import", "가져오기..." },
|
||||
{ "hex.builtin.menu.file.import.base64", "Base64 파일" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.import_error", "파일이 올바른 Base64 형식이 아닙니다!" },
|
||||
{ "hex.builtin.menu.file.import.base64.popup.open_error", "파일을 여는 데 실패했습니다!" },
|
||||
{ "hex.builtin.menu.file.import.ips", "IPS 패치" },
|
||||
{ "hex.builtin.menu.file.import.ips32", "IPS32 패치" },
|
||||
{ "hex.builtin.menu.file.export", "내보내기..." },
|
||||
{ "hex.builtin.menu.file.export.title", "파일 내보내기" },
|
||||
{ "hex.builtin.menu.file.export.ips", "IPS 패치" },
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32 패치" },
|
||||
{ "hex.builtin.menu.file.export.base64.popup.export_error", "파일이 올바른 Base64 형식이 아닙니다!" },
|
||||
{ "hex.builtin.menu.file.export.popup.create", "데이터를 내보낼 수 없습니다. 파일을 만드는 데 실패했습니다!" },
|
||||
{ "hex.builtin.menu.file.bookmark.import", "북마크 가져오기" },
|
||||
{ "hex.builtin.menu.file.bookmark.export", "북마크 내보내기" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "수정" },
|
||||
{ "hex.builtin.menu.edit.undo", "실행 취소" },
|
||||
{ "hex.builtin.menu.edit.redo", "다시 실행" },
|
||||
{ "hex.builtin.menu.edit.bookmark.create", "북마크 생성하기" },
|
||||
|
||||
{ "hex.builtin.menu.view", "뷰" },
|
||||
{ "hex.builtin.menu.layout", "레이아웃" },
|
||||
{ "hex.builtin.menu.view.demo", "ImGui Demo 표시하기" },
|
||||
{ "hex.builtin.menu.help", "도움말" },
|
||||
|
||||
{ "hex.builtin.view.bookmarks.name", "북마크" },
|
||||
{ "hex.builtin.view.bookmarks.default_title", "북마크 [0x{0:X} - 0x{1:X}]" },
|
||||
{ "hex.builtin.view.bookmarks.no_bookmarks", "북마크가 없습니다. '수정 -> 북마크 생성하기'로 북마크를 생성하세요" },
|
||||
{ "hex.builtin.view.bookmarks.title.info", "정보" },
|
||||
{ "hex.builtin.view.bookmarks.address", "0x{0:X} : 0x{1:X} ({2} bytes)" },
|
||||
{ "hex.builtin.view.bookmarks.button.jump", "이동하기" },
|
||||
{ "hex.builtin.view.bookmarks.button.remove", "지우기" },
|
||||
{ "hex.builtin.view.bookmarks.header.name", "이름" },
|
||||
{ "hex.builtin.view.bookmarks.header.color", "색상" },
|
||||
{ "hex.builtin.view.bookmarks.header.comment", "설명" },
|
||||
|
||||
{ "hex.builtin.view.command_palette.name", "명령 팔레트" },
|
||||
|
||||
// HxD의 번역을 그대로 가져왔습니다.
|
||||
{ "hex.builtin.view.data_inspector.name", "데이터 변환기" },
|
||||
{ "hex.builtin.view.data_inspector.table.name", "이름" },
|
||||
{ "hex.builtin.view.data_inspector.table.value", "값" },
|
||||
{ "hex.builtin.view.data_inspector.no_data", "선택된 바이트 없음" },
|
||||
{ "hex.builtin.view.data_inspector.invert", "반전" },
|
||||
|
||||
{ "hex.builtin.view.data_processor.name", "데이터 프로세서" },
|
||||
{ "hex.builtin.view.data_processor.help_text", "오른쪽 클릭을 눌러 새 노드를 만드세요" },
|
||||
{ "hex.builtin.view.data_processor.menu.remove_selection", "선택 영역 삭제" },
|
||||
{ "hex.builtin.view.data_processor.menu.remove_node", "노드 삭제" },
|
||||
{ "hex.builtin.view.data_processor.menu.remove_link", "링크 삭제" },
|
||||
{ "hex.builtin.view.data_processor.menu.file.load_processor", "데이터 프로세서 불러오기..." },
|
||||
{ "hex.builtin.view.data_processor.menu.file.save_processor", "데이터 프로세서 저장하기..." },
|
||||
|
||||
{ "hex.builtin.view.disassembler.name", "디스어셈블러" },
|
||||
{ "hex.builtin.view.disassembler.position", "위치" },
|
||||
{ "hex.builtin.view.disassembler.base", "베이스 주소" },
|
||||
{ "hex.builtin.view.disassembler.region", "코드 영역" },
|
||||
{ "hex.builtin.view.disassembler.settings.header", "설정" },
|
||||
{ "hex.builtin.view.disassembler.settings.mode", "모드" },
|
||||
{ "hex.builtin.view.disassembler.arch", "아키텍쳐" },
|
||||
{ "hex.builtin.view.disassembler.16bit", "16-bit" },
|
||||
{ "hex.builtin.view.disassembler.32bit", "32-bit" },
|
||||
{ "hex.builtin.view.disassembler.64bit", "64-bit" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.arm.arm", "ARM" },
|
||||
{ "hex.builtin.view.disassembler.arm.thumb", "Thumb" },
|
||||
{ "hex.builtin.view.disassembler.arm.default", "Default" },
|
||||
{ "hex.builtin.view.disassembler.arm.cortex_m", "Cortex-M" },
|
||||
{ "hex.builtin.view.disassembler.arm.armv8", "ARMv8" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.mips.mips32", "MIPS32" },
|
||||
{ "hex.builtin.view.disassembler.mips.mips64", "MIPS64" },
|
||||
{ "hex.builtin.view.disassembler.mips.mips32R6", "MIPS32R6" },
|
||||
{ "hex.builtin.view.disassembler.mips.mips2", "MIPS II" },
|
||||
{ "hex.builtin.view.disassembler.mips.mips3", "MIPS III" },
|
||||
{ "hex.builtin.view.disassembler.mips.micro", "Micro" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.ppc.qpx", "Quad Processing Extensions" },
|
||||
{ "hex.builtin.view.disassembler.ppc.spe", "Signal Processing Engine" },
|
||||
{ "hex.builtin.view.disassembler.ppc.booke", "Book-E" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.sparc.v9", "Sparc V9" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.riscv.compressed", "Compressed" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.m68k.000", "000" },
|
||||
{ "hex.builtin.view.disassembler.m68k.010", "010" },
|
||||
{ "hex.builtin.view.disassembler.m68k.020", "020" },
|
||||
{ "hex.builtin.view.disassembler.m68k.030", "030" },
|
||||
{ "hex.builtin.view.disassembler.m68k.040", "040" },
|
||||
{ "hex.builtin.view.disassembler.m68k.060", "060" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.m680x.6301", "6301" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6309", "6309" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6800", "6800" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6801", "6801" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6805", "6805" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6808", "6808" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6809", "6809" },
|
||||
{ "hex.builtin.view.disassembler.m680x.6811", "6811" },
|
||||
{ "hex.builtin.view.disassembler.m680x.cpu12", "CPU12" },
|
||||
{ "hex.builtin.view.disassembler.m680x.hcs08", "HCS08" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.mos65xx.6502", "6502" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.65c02", "65C02" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.w65c02", "W65C02" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.65816", "65816" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.65816_long_m", "65816 Long M" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.65816_long_x", "65816 Long X" },
|
||||
{ "hex.builtin.view.disassembler.mos65xx.65816_long_mx", "65816 Long MX" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.bpf.classic", "Classic" },
|
||||
{ "hex.builtin.view.disassembler.bpf.extended", "Extended" },
|
||||
|
||||
{ "hex.builtin.view.disassembler.disassemble", "디스어셈블" },
|
||||
{ "hex.builtin.view.disassembler.disassembling", "디스어셈블 중..." },
|
||||
{ "hex.builtin.view.disassembler.disassembly.title", "디스어셈블리" },
|
||||
{ "hex.builtin.view.disassembler.disassembly.address", "주소" },
|
||||
{ "hex.builtin.view.disassembler.disassembly.offset", "오프셋" },
|
||||
{ "hex.builtin.view.disassembler.disassembly.bytes", "바이트" },
|
||||
|
||||
{ "hex.builtin.view.hashes.name", "해시" },
|
||||
{ "hex.builtin.view.hashes.hash", "해시" },
|
||||
{ "hex.builtin.view.hashes.no_settings", "설정이 존재하지 않습니다" },
|
||||
{ "hex.builtin.view.hashes.function", "해시 함수" },
|
||||
{ "hex.builtin.view.hashes.name", "이름" },
|
||||
{ "hex.builtin.view.hashes.type", "종류" },
|
||||
{ "hex.builtin.view.hashes.result", "결과" },
|
||||
{ "hex.builtin.view.hashes.remove", "지우기" },
|
||||
{ "hex.builtin.view.hashes.hover_info", "헥스 편집기에서 영역을 선택 후 쉬프트를 누른 채로 마우스 커서를 올리면 해당 값들의 해시를 알 수 있습니다." },
|
||||
|
||||
{ "hex.builtin.view.help.name", "도움말" },
|
||||
{ "hex.builtin.view.help.about.name", "정보" },
|
||||
{ "hex.builtin.view.help.about.translator", "Translated by mirusu400" },
|
||||
{ "hex.builtin.view.help.about.source", "소스 코드는 GitHub에 존재합니다." },
|
||||
{ "hex.builtin.view.help.about.donations", "후원" },
|
||||
{ "hex.builtin.view.help.about.thanks", "이 작업물이 마음에 든다면, 프로젝트가 계속되도록 프로젝트에 후원해주세요. 감사합니다 <3" },
|
||||
{ "hex.builtin.view.help.about.contributor", "기여자" },
|
||||
{ "hex.builtin.view.help.about.libs", "사용한 라이브러리" },
|
||||
{ "hex.builtin.view.help.about.paths", "ImHex 주소" },
|
||||
{ "hex.builtin.view.help.about.license", "라이센스" },
|
||||
{ "hex.builtin.view.help.documentation", "ImHex 문서" },
|
||||
{ "hex.builtin.view.help.pattern_cheat_sheet", "패턴 언어 치트시트"},
|
||||
{ "hex.builtin.view.help.calc_cheat_sheet", "치트시트 계산기" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.name", "헥스 편집기" },
|
||||
{ "hex.builtin.view.hex_editor.page", "페이지" },
|
||||
{ "hex.builtin.view.hex_editor.selection", "선택 영역" },
|
||||
{ "hex.builtin.view.hex_editor.selection.none", "없음" },
|
||||
{ "hex.builtin.view.hex_editor.region", "지역" },
|
||||
{ "hex.builtin.view.hex_editor.data_size", "데이터 크기" },
|
||||
{ "hex.builtin.view.hex_editor.no_bytes", "바이트가 존재하지 않습니다" },
|
||||
|
||||
{ "hex.builtin.view.hex_editor.menu.file.load_encoding_file", "커스텀 인코딩 불러오기..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.search", "검색" },
|
||||
{ "hex.builtin.view.hex_editor.search.string", "문자열" },
|
||||
{ "hex.builtin.view.hex_editor.search.hex", "헥스" },
|
||||
{ "hex.builtin.view.hex_editor.search.find", "찾기" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.goto", "이동하기" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.absolute", "절대주소" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.relative", "상대주소" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "시작" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "종료" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.select", "선택" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.region", "지역" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.begin", "시작" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.end", "끝" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.size", "크기" },
|
||||
{ "hex.builtin.view.hex_editor.select.select", "선택" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "저장" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "다른 이름으로 저장..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "복사" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "다른 방법으로 복사..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "문자열" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.rust", "Rust 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 배열" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "붙여넣기" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "모두 선택하기" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.set_base", "베이스 주소 설정" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.resize", "크기 변경..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.insert", "삽입..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.remove", "삭제..." },
|
||||
|
||||
{ "hex.builtin.view.information.name", "데이터 정보" },
|
||||
{ "hex.builtin.view.information.control", "컨트롤" },
|
||||
{ "hex.builtin.view.information.analyze", "페이지 분석" },
|
||||
{ "hex.builtin.view.information.analyzing", "분석 중..." },
|
||||
{ "hex.builtin.view.information.region", "분석한 영역" },
|
||||
{ "hex.builtin.view.information.magic", "Magic 정보" },
|
||||
{ "hex.builtin.view.information.description", "설명:" },
|
||||
{ "hex.builtin.view.information.mime", "MIME 타입:" },
|
||||
{ "hex.builtin.view.information.info_analysis", "정보 분석" },
|
||||
{ "hex.builtin.view.information.distribution", "바이트 분포" },
|
||||
{ "hex.builtin.view.information.entropy", "엔트로피" },
|
||||
{ "hex.builtin.view.information.block_size", "블록 크기" },
|
||||
{ "hex.builtin.view.information.block_size.desc", "{1} 바이트 중 {0} 블록 " },
|
||||
{ "hex.builtin.view.information.file_entropy", "파일 엔트로피" },
|
||||
{ "hex.builtin.view.information.highest_entropy", "최대 엔트로피 블록" },
|
||||
{ "hex.builtin.view.information.encrypted", "이 데이터는 아마 암호화 혹은 압축되었을 가능성이 높습니다!" },
|
||||
{ "hex.builtin.view.information.magic_db_added", "Magic 데이터베이스 추가됨!" },
|
||||
|
||||
{ "hex.builtin.view.patches.name", "패치" },
|
||||
{ "hex.builtin.view.patches.offset", "오프셋" },
|
||||
{ "hex.builtin.view.patches.orig", "원본 값" },
|
||||
{ "hex.builtin.view.patches.patch", "수정된 값"},
|
||||
{ "hex.builtin.view.patches.remove", "패치 없애기" },
|
||||
|
||||
{ "hex.builtin.view.pattern_editor.name", "패턴 편집기" },
|
||||
{ "hex.builtin.view.pattern_editor.accept_pattern", "패턴 적용하기" },
|
||||
{ "hex.builtin.view.pattern_editor.accept_pattern.desc", "하나 이상의 패턴 언어와 호환되는 데이터 타입이 발견되었습니다" },
|
||||
{ "hex.builtin.view.pattern_editor.accept_pattern.pattern_language", "패턴" },
|
||||
{ "hex.builtin.view.pattern_editor.accept_pattern.question", "선택한 패턴을 적용하시겠습니까?" },
|
||||
{ "hex.builtin.view.pattern_editor.menu.file.load_pattern", "패턴 불러오기..." },
|
||||
{ "hex.builtin.view.pattern_editor.menu.file.save_pattern", "패턴 저장하기..." },
|
||||
{ "hex.builtin.view.pattern_editor.open_pattern", "패턴 열기" },
|
||||
{ "hex.builtin.view.pattern_editor.evaluating", "평가 중..." },
|
||||
{ "hex.builtin.view.pattern_editor.auto", "자동 평가" },
|
||||
{ "hex.builtin.view.pattern_editor.console", "콘솔" },
|
||||
{ "hex.builtin.view.pattern_editor.env_vars", "환경 변수" },
|
||||
{ "hex.builtin.view.pattern_editor.settings", "설정" },
|
||||
{ "hex.builtin.view.pattern_editor.dangerous_function.name", "위험한 함수를 허용하시겠습니까?" },
|
||||
{ "hex.builtin.view.pattern_editor.dangerous_function.desc", "이 패턴은 위험한 함수를 실행하려 합니다.\n정말로 이 패턴을 신뢰하시겠습니?" },
|
||||
{ "hex.builtin.view.pattern_editor.no_in_out_vars", "'in' 또는 'out' 지정자를 이용해 여기에 나타날 전역 변수를 선언합니다." },
|
||||
|
||||
{ "hex.builtin.view.pattern_data.name", "패턴 데이터" },
|
||||
{ "hex.builtin.view.pattern_data.var_name", "이름" },
|
||||
{ "hex.builtin.view.pattern_data.color", "색상" },
|
||||
{ "hex.builtin.view.pattern_data.offset", "오프셋" },
|
||||
{ "hex.builtin.view.pattern_data.size", "크기" },
|
||||
{ "hex.builtin.view.pattern_data.type", "타입" },
|
||||
{ "hex.builtin.view.pattern_data.value", "값" },
|
||||
|
||||
{ "hex.builtin.view.settings.name", "설정" },
|
||||
{ "hex.builtin.view.settings.restart_question", "변경 사항을 적용할려면 ImHex를 재시작 해야 합니다. 지금 바로 재시작하시겠습니까?" },
|
||||
|
||||
{ "hex.builtin.view.tools.name", "도구" },
|
||||
|
||||
{ "hex.builtin.view.yara.name", "Yara 규칙" },
|
||||
{ "hex.builtin.view.yara.header.rules", "규칙" },
|
||||
{ "hex.builtin.view.yara.reload", "재검사" },
|
||||
{ "hex.builtin.view.yara.match", "일치하는 규칙" },
|
||||
{ "hex.builtin.view.yara.matching", "검색 중..." },
|
||||
{ "hex.builtin.view.yara.error", "Yara 컴파일러 에러: " },
|
||||
{ "hex.builtin.view.yara.header.matches", "규칙" },
|
||||
{ "hex.builtin.view.yara.matches.identifier", "식별자" },
|
||||
{ "hex.builtin.view.yara.matches.variable", "변수" },
|
||||
{ "hex.builtin.view.yara.whole_data", "모든 파일을 검색했습니다!" },
|
||||
{ "hex.builtin.view.yara.no_rules", "YARA 규칙이 없습니다. ImHex의 'yara' 폴더에 YARA 규칙을 넣으세요." },
|
||||
{ "hex.builtin.view.yara.rule_added", "Yara 규칙 추가됨!" },
|
||||
|
||||
|
||||
{ "hex.builtin.view.constants.name", "상수" },
|
||||
{ "hex.builtin.view.constants.row.category", "종류" },
|
||||
{ "hex.builtin.view.constants.row.name", "이름" },
|
||||
{ "hex.builtin.view.constants.row.desc", "설명" },
|
||||
{ "hex.builtin.view.constants.row.value", "값" },
|
||||
|
||||
{ "hex.builtin.view.store.name", "콘텐츠 스토어" },
|
||||
{ "hex.builtin.view.store.desc", "ImHex의 온라인 데이터베이스에서 새로운 컨텐츠를 다운로드 받으세요." },
|
||||
{ "hex.builtin.view.store.reload", "새로 고침" },
|
||||
{ "hex.builtin.view.store.row.name", "이름" },
|
||||
{ "hex.builtin.view.store.row.description", "설명" },
|
||||
{ "hex.builtin.view.store.download", "다운로드" },
|
||||
{ "hex.builtin.view.store.update", "업데이트" },
|
||||
{ "hex.builtin.view.store.remove", "제거" },
|
||||
{ "hex.builtin.view.store.tab.patterns", "패턴" },
|
||||
{ "hex.builtin.view.store.tab.libraries", "라이브러리" },
|
||||
{ "hex.builtin.view.store.tab.magics", "Magic 파일" },
|
||||
{ "hex.builtin.view.store.tab.constants", "상수" },
|
||||
{ "hex.builtin.view.store.tab.yara", "Yara 규칙" },
|
||||
{ "hex.builtin.view.store.tab.encodings", "인코딩" },
|
||||
{ "hex.builtin.view.store.loading", "스토어 콘텐츠 불러오는 중..." },
|
||||
{ "hex.builtin.view.store.download_error", "파일 다운로드에 실패했습니다! 저장 폴더가 존재하지 않습니다." },
|
||||
|
||||
{ "hex.builtin.view.diff.name", "파일 비교" },
|
||||
|
||||
{ "hex.builtin.view.provider_settings.name", "공급자 설정" },
|
||||
{ "hex.builtin.view.provider_settings.load_popup", "공급자 열기" },
|
||||
{ "hex.builtin.view.provider_settings.load_error", "이 공급자를 여는 도중 에러가 발생했습니다!"},
|
||||
|
||||
{ "hex.builtin.view.find.name", "찾기" },
|
||||
{ "hex.builtin.view.find.searching", "검색 중..." },
|
||||
{ "hex.builtin.view.find.demangled", "Demangled" },
|
||||
{ "hex.builtin.view.find.strings", "문자열" },
|
||||
{ "hex.builtin.view.find.strings.min_length", "최소 길이" },
|
||||
{ "hex.builtin.view.find.strings.match_settings", "검색 설정" },
|
||||
{ "hex.builtin.view.find.strings.null_term", "Null로 끝난 글자만 검색" },
|
||||
{ "hex.builtin.view.find.strings.chars", "문자" },
|
||||
{ "hex.builtin.view.find.strings.lower_case", "소문자" },
|
||||
{ "hex.builtin.view.find.strings.upper_case", "대문자" },
|
||||
{ "hex.builtin.view.find.strings.numbers", "숫자" },
|
||||
{ "hex.builtin.view.find.strings.underscores", "언더스코어" },
|
||||
{ "hex.builtin.view.find.strings.symbols", "특수 문자" },
|
||||
{ "hex.builtin.view.find.strings.spaces", "공백 문자" },
|
||||
{ "hex.builtin.view.find.strings.line_feeds", "라인 피드" },
|
||||
{ "hex.builtin.view.find.sequences", "텍스트 시퀸스" },
|
||||
{ "hex.builtin.view.find.regex", "정규식" },
|
||||
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
{ "hex.builtin.view.find.binary_pattern", "바이너리 패턴" },
|
||||
{ "hex.builtin.view.find.search", "검색" },
|
||||
{ "hex.builtin.view.find.context.copy", "값 복사" },
|
||||
{ "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
{ "hex.builtin.view.find.search.entries", "{} 개 검색됨" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "계산기" },
|
||||
{ "hex.builtin.command.cmd.desc", "명령" },
|
||||
{ "hex.builtin.command.cmd.result", "명령 실행 '{0}'" },
|
||||
{ "hex.builtin.command.web.desc", "웹사이트 탐색" },
|
||||
{ "hex.builtin.command.web.result", "웹사이트 이동 '{0}'" },
|
||||
|
||||
{ "hex.builtin.inspector.binary", "Binary (8 bit)" },
|
||||
{ "hex.builtin.inspector.u8", "uint8_t" },
|
||||
{ "hex.builtin.inspector.i8", "int8_t" },
|
||||
{ "hex.builtin.inspector.u16", "uint16_t" },
|
||||
{ "hex.builtin.inspector.i16", "int16_t" },
|
||||
{ "hex.builtin.inspector.u24", "uint24_t" },
|
||||
{ "hex.builtin.inspector.i24", "int24_t" },
|
||||
{ "hex.builtin.inspector.u32", "uint32_t" },
|
||||
{ "hex.builtin.inspector.i32", "int32_t" },
|
||||
{ "hex.builtin.inspector.u48", "uint48_t" },
|
||||
{ "hex.builtin.inspector.i48", "int48_t" },
|
||||
{ "hex.builtin.inspector.u64", "uint64_t" },
|
||||
{ "hex.builtin.inspector.i64", "int64_t" },
|
||||
{ "hex.builtin.inspector.float16", "half float (16 bit)" },
|
||||
{ "hex.builtin.inspector.float", "float (32 bit)" },
|
||||
{ "hex.builtin.inspector.double", "double (64 bit)" },
|
||||
{ "hex.builtin.inspector.long_double", "long double (128 bit)" },
|
||||
{ "hex.builtin.inspector.sleb128", "Signed LEB128" },
|
||||
{ "hex.builtin.inspector.uleb128", "Unsigned LEB128" },
|
||||
{ "hex.builtin.inspector.bool", "bool" },
|
||||
{ "hex.builtin.inspector.ascii", "ASCII Character" },
|
||||
{ "hex.builtin.inspector.wide", "Wide Character" },
|
||||
{ "hex.builtin.inspector.utf8", "UTF-8 code point" },
|
||||
{ "hex.builtin.inspector.string", "String" },
|
||||
{ "hex.builtin.inspector.time32", "time32_t" },
|
||||
{ "hex.builtin.inspector.time64", "time64_t" },
|
||||
{ "hex.builtin.inspector.time", "time_t" },
|
||||
{ "hex.builtin.inspector.dos_date", "DOS Date" },
|
||||
{ "hex.builtin.inspector.dos_time", "DOS Time" },
|
||||
{ "hex.builtin.inspector.guid", "GUID" },
|
||||
{ "hex.builtin.inspector.rgba8", "RGBA8 Color" },
|
||||
{ "hex.builtin.inspector.rgb565", "RGB565 Color" },
|
||||
|
||||
{ "hex.builtin.nodes.common.input", "Input" },
|
||||
{ "hex.builtin.nodes.common.input.a", "Input A" },
|
||||
{ "hex.builtin.nodes.common.input.b", "Input B" },
|
||||
{ "hex.builtin.nodes.common.output", "Output" },
|
||||
|
||||
{ "hex.builtin.nodes.constants", "상수" },
|
||||
{ "hex.builtin.nodes.constants.int", "정수" },
|
||||
{ "hex.builtin.nodes.constants.int.header", "정수" },
|
||||
{ "hex.builtin.nodes.constants.float", "실수" },
|
||||
{ "hex.builtin.nodes.constants.float.header", "실수" },
|
||||
{ "hex.builtin.nodes.constants.nullptr", "Nullptr" },
|
||||
{ "hex.builtin.nodes.constants.nullptr.header", "Nullptr" },
|
||||
{ "hex.builtin.nodes.constants.buffer", "버퍼" },
|
||||
{ "hex.builtin.nodes.constants.buffer.header", "버퍼" },
|
||||
{ "hex.builtin.nodes.constants.buffer.size", "크기" },
|
||||
{ "hex.builtin.nodes.constants.string", "문자열" },
|
||||
{ "hex.builtin.nodes.constants.string.header", "문자열" },
|
||||
{ "hex.builtin.nodes.constants.rgba8", "RGBA8 색상" },
|
||||
{ "hex.builtin.nodes.constants.rgba8.header", "RGBA8 색상" },
|
||||
{ "hex.builtin.nodes.constants.rgba8.output.r", "Red" },
|
||||
{ "hex.builtin.nodes.constants.rgba8.output.g", "Green" },
|
||||
{ "hex.builtin.nodes.constants.rgba8.output.b", "Blue" },
|
||||
{ "hex.builtin.nodes.constants.rgba8.output.a", "Alpha" },
|
||||
{ "hex.builtin.nodes.constants.comment", "주석" },
|
||||
{ "hex.builtin.nodes.constants.comment.header", "주석" },
|
||||
|
||||
{ "hex.builtin.nodes.display", "디스플레이" },
|
||||
{ "hex.builtin.nodes.display.int", "정수" },
|
||||
{ "hex.builtin.nodes.display.int.header", "정수 디스플레이" },
|
||||
{ "hex.builtin.nodes.display.int.input", "값" },
|
||||
{ "hex.builtin.nodes.display.float", "실수" },
|
||||
{ "hex.builtin.nodes.display.float.header", "실수 디스플레이" },
|
||||
{ "hex.builtin.nodes.display.float.input", "값" },
|
||||
|
||||
{ "hex.builtin.nodes.data_access", "데이터 접근" },
|
||||
{ "hex.builtin.nodes.data_access.read", "읽기" },
|
||||
{ "hex.builtin.nodes.data_access.read.header", "읽기" },
|
||||
{ "hex.builtin.nodes.data_access.read.address", "주소" },
|
||||
{ "hex.builtin.nodes.data_access.read.size", "크기" },
|
||||
{ "hex.builtin.nodes.data_access.read.data", "데이터" },
|
||||
{ "hex.builtin.nodes.data_access.write", "쓰기" },
|
||||
{ "hex.builtin.nodes.data_access.write.header", "쓰기" },
|
||||
{ "hex.builtin.nodes.data_access.write.address", "주소" },
|
||||
{ "hex.builtin.nodes.data_access.write.data", "데이터" },
|
||||
{ "hex.builtin.nodes.data_access.size", "데이터 크기"},
|
||||
{ "hex.builtin.nodes.data_access.size.header", "데이터 크기"},
|
||||
{ "hex.builtin.nodes.data_access.size.size", "크기"},
|
||||
{ "hex.builtin.nodes.data_access.selection", "선택한 영역"},
|
||||
{ "hex.builtin.nodes.data_access.selection.header", "선택한 영역"},
|
||||
{ "hex.builtin.nodes.data_access.selection.address", "주소"},
|
||||
{ "hex.builtin.nodes.data_access.selection.size", "크기"},
|
||||
|
||||
{ "hex.builtin.nodes.casting", "데이터 변환" },
|
||||
{ "hex.builtin.nodes.casting.int_to_buffer", "정수에서 버퍼로" },
|
||||
{ "hex.builtin.nodes.casting.int_to_buffer.header", "정수에서 버퍼로" },
|
||||
{ "hex.builtin.nodes.casting.buffer_to_int", "버퍼에서 정수로" },
|
||||
{ "hex.builtin.nodes.casting.buffer_to_int.header", "버퍼에서 정수로" },
|
||||
|
||||
{ "hex.builtin.nodes.arithmetic", "수학" },
|
||||
{ "hex.builtin.nodes.arithmetic.add", "덧셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.add.header", "덧셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.sub", "뺄셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.sub.header", "뺄셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.mul", "곱셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.mul.header", "곱셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.div", "나눗셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.div.header", "나눗셈" },
|
||||
{ "hex.builtin.nodes.arithmetic.mod", "나머지" },
|
||||
{ "hex.builtin.nodes.arithmetic.mod.header", "나머지" },
|
||||
|
||||
{ "hex.builtin.nodes.buffer", "버퍼" },
|
||||
{ "hex.builtin.nodes.buffer.combine", "합치기" },
|
||||
{ "hex.builtin.nodes.buffer.combine.header", "버퍼 합치기" },
|
||||
{ "hex.builtin.nodes.buffer.slice", "자르기" },
|
||||
{ "hex.builtin.nodes.buffer.slice.header", "버퍼 자르기" },
|
||||
{ "hex.builtin.nodes.buffer.slice.input.buffer", "입력" },
|
||||
{ "hex.builtin.nodes.buffer.slice.input.from", "시작" },
|
||||
{ "hex.builtin.nodes.buffer.slice.input.to", "끝" },
|
||||
{ "hex.builtin.nodes.buffer.repeat", "출력" },
|
||||
{ "hex.builtin.nodes.buffer.repeat.header", "버퍼 반복" },
|
||||
{ "hex.builtin.nodes.buffer.repeat.input.count", "개수" },
|
||||
|
||||
{ "hex.builtin.nodes.control_flow", "데이터 플로우" },
|
||||
{ "hex.builtin.nodes.control_flow.if", "If" },
|
||||
{ "hex.builtin.nodes.control_flow.if.header", "If" },
|
||||
{ "hex.builtin.nodes.control_flow.if.condition", "조건" },
|
||||
{ "hex.builtin.nodes.control_flow.if.true", "True" },
|
||||
{ "hex.builtin.nodes.control_flow.if.false", "False" },
|
||||
{ "hex.builtin.nodes.control_flow.equals", "Equals" },
|
||||
{ "hex.builtin.nodes.control_flow.equals.header", "Equals" },
|
||||
{ "hex.builtin.nodes.control_flow.not", "Not" },
|
||||
{ "hex.builtin.nodes.control_flow.not.header", "Not" },
|
||||
{ "hex.builtin.nodes.control_flow.gt", "Greater than" },
|
||||
{ "hex.builtin.nodes.control_flow.gt.header", "Greater than" },
|
||||
{ "hex.builtin.nodes.control_flow.lt", "Less than" },
|
||||
{ "hex.builtin.nodes.control_flow.lt.header", "Less than" },
|
||||
{ "hex.builtin.nodes.control_flow.and", "AND" },
|
||||
{ "hex.builtin.nodes.control_flow.and.header", "Boolean AND" },
|
||||
{ "hex.builtin.nodes.control_flow.or", "OR" },
|
||||
{ "hex.builtin.nodes.control_flow.or.header", "Boolean OR" },
|
||||
|
||||
{ "hex.builtin.nodes.bitwise", "비트 연산" },
|
||||
{ "hex.builtin.nodes.bitwise.and", "AND" },
|
||||
{ "hex.builtin.nodes.bitwise.and.header", "논리 AND" },
|
||||
{ "hex.builtin.nodes.bitwise.or", "OR" },
|
||||
{ "hex.builtin.nodes.bitwise.or.header", "논리 OR" },
|
||||
{ "hex.builtin.nodes.bitwise.xor", "XOR" },
|
||||
{ "hex.builtin.nodes.bitwise.xor.header", "논리 XOR" },
|
||||
{ "hex.builtin.nodes.bitwise.not", "NOT" },
|
||||
{ "hex.builtin.nodes.bitwise.not.header", "논리 NOT" },
|
||||
|
||||
{ "hex.builtin.nodes.decoding", "디코딩" },
|
||||
{ "hex.builtin.nodes.decoding.base64", "Base64" },
|
||||
{ "hex.builtin.nodes.decoding.base64.header", "Base64 디코더" },
|
||||
{ "hex.builtin.nodes.decoding.hex", "16진수" },
|
||||
{ "hex.builtin.nodes.decoding.hex.header", "16진수 decoder" },
|
||||
|
||||
{ "hex.builtin.nodes.crypto", "암호학" },
|
||||
{ "hex.builtin.nodes.crypto.aes", "AES 복호화" },
|
||||
{ "hex.builtin.nodes.crypto.aes.header", "AES 복호화" },
|
||||
{ "hex.builtin.nodes.crypto.aes.key", "키" },
|
||||
{ "hex.builtin.nodes.crypto.aes.iv", "IV" },
|
||||
{ "hex.builtin.nodes.crypto.aes.nonce", "논스" },
|
||||
{ "hex.builtin.nodes.crypto.aes.mode", "모드" },
|
||||
{ "hex.builtin.nodes.crypto.aes.key_length", "Key 길이" },
|
||||
|
||||
{ "hex.builtin.nodes.visualizer", "시작화" },
|
||||
{ "hex.builtin.nodes.visualizer.digram", "다이어그램" },
|
||||
{ "hex.builtin.nodes.visualizer.digram.header", "다이어그램" },
|
||||
{ "hex.builtin.nodes.visualizer.layered_dist", "계층적 분포" },
|
||||
{ "hex.builtin.nodes.visualizer.layered_dist.header", "계층적 분포" },
|
||||
{ "hex.builtin.nodes.visualizer.image", "이미지" },
|
||||
{ "hex.builtin.nodes.visualizer.image.header", "이미지 시각화" },
|
||||
{ "hex.builtin.nodes.visualizer.byte_distribution", "바이트 분포" },
|
||||
{ "hex.builtin.nodes.visualizer.byte_distribution.header", "바이트 분포" },
|
||||
|
||||
|
||||
{ "hex.builtin.tools.demangler", "LLVM Demangler" },
|
||||
{ "hex.builtin.tools.demangler.mangled", "Mangled name" },
|
||||
{ "hex.builtin.tools.demangler.demangled", "Demangled name" },
|
||||
{ "hex.builtin.tools.ascii_table", "ASCII 테이블" },
|
||||
{ "hex.builtin.tools.ascii_table.octal", "8진수 표시" },
|
||||
{ "hex.builtin.tools.regex_replacer", "정규식 변환기" },
|
||||
{ "hex.builtin.tools.regex_replacer.pattern", "정규식 패턴" },
|
||||
{ "hex.builtin.tools.regex_replacer.replace", "교체할 패턴" },
|
||||
{ "hex.builtin.tools.regex_replacer.input", "입력" },
|
||||
{ "hex.builtin.tools.regex_replacer.output", "출력" },
|
||||
{ "hex.builtin.tools.color", "컬러 피커" },
|
||||
{ "hex.builtin.tools.calc", "계산기" },
|
||||
{ "hex.builtin.tools.input", "입력" },
|
||||
{ "hex.builtin.tools.format.standard", "표준" },
|
||||
{ "hex.builtin.tools.format.scientific", "공학용" },
|
||||
{ "hex.builtin.tools.format.engineering", "엔지니어링" },
|
||||
{ "hex.builtin.tools.format.programmer", "프로그래머" },
|
||||
{ "hex.builtin.tools.error", "마지막 에러: '{0}'" },
|
||||
{ "hex.builtin.tools.history", "이력" },
|
||||
{ "hex.builtin.tools.name", "이름" },
|
||||
{ "hex.builtin.tools.value", "값" },
|
||||
{ "hex.builtin.tools.base_converter", "진수 변환기" },
|
||||
{ "hex.builtin.tools.base_converter.dec", "DEC" },
|
||||
{ "hex.builtin.tools.base_converter.hex", "HEX" },
|
||||
{ "hex.builtin.tools.base_converter.oct", "OCT" },
|
||||
{ "hex.builtin.tools.base_converter.bin", "BIN" },
|
||||
{ "hex.builtin.tools.permissions", "UNIX 권한 계산기" },
|
||||
{ "hex.builtin.tools.permissions.perm_bits", "권한 비트" },
|
||||
{ "hex.builtin.tools.permissions.absolute", "절대값" },
|
||||
{ "hex.builtin.tools.permissions.setuid_error", "Setuid bit를 적용하기 위한 올바른 유저 권한이 필요합니다!" },
|
||||
{ "hex.builtin.tools.permissions.setgid_error", "Setgid bit를 적용하기 위한 올바른 그룹 권한이 필요합니다!" },
|
||||
{ "hex.builtin.tools.permissions.sticky_error", "Sticky bit를 적용하기 위한 올바른 기타 권한이 필요합니다!" },
|
||||
{ "hex.builtin.tools.file_uploader", "파일 업로더" },
|
||||
{ "hex.builtin.tools.file_uploader.control", "컨트롤" },
|
||||
{ "hex.builtin.tools.file_uploader.upload", "업로드" },
|
||||
{ "hex.builtin.tools.file_uploader.done", "완료!" },
|
||||
{ "hex.builtin.tools.file_uploader.recent", "최근 업로드" },
|
||||
{ "hex.builtin.tools.file_uploader.tooltip", "클릭해 복사,\nCTRL + 클릭으로 열기" },
|
||||
{ "hex.builtin.tools.file_uploader.invalid_response", "Anonfiles에서 잘못된 응답이 왔습니다!" },
|
||||
{ "hex.builtin.tools.file_uploader.error", "파일 업로드 실패!\n\n에러 코드: {0}" },
|
||||
{ "hex.builtin.tools.wiki_explain", "Wikipedia 용어 정의" },
|
||||
{ "hex.builtin.tools.wiki_explain.control", "컨트롤" },
|
||||
{ "hex.builtin.tools.wiki_explain.search", "검색" },
|
||||
{ "hex.builtin.tools.wiki_explain.results", "결과" },
|
||||
{ "hex.builtin.tools.wiki_explain.invalid_response", "Wikipedia에서 잘못된 응답이 왔습니다!" },
|
||||
{ "hex.builtin.tools.file_tools", "파일 도구" },
|
||||
{ "hex.builtin.tools.file_tools.shredder", "완전 삭제 도구" },
|
||||
{ "hex.builtin.tools.file_tools.shredder.warning", "이 도구는 복구할 수 없도록 파일을 제거합니다. 주의하세요." },
|
||||
{ "hex.builtin.tools.file_tools.shredder.input", "삭제할 파일 " },
|
||||
{ "hex.builtin.tools.file_tools.shredder.picker", "삭제할 파일을 선택하세요." },
|
||||
{ "hex.builtin.tools.file_tools.shredder.fast", "빠른 삭제" },
|
||||
{ "hex.builtin.tools.file_tools.shredder.shredding", "삭제 중..." },
|
||||
{ "hex.builtin.tools.file_tools.shredder.shred", "삭제 완료" },
|
||||
{ "hex.builtin.tools.file_tools.shredder.error.open", "파일을 여는데 실패했습니다!" },
|
||||
{ "hex.builtin.tools.file_tools.shredder.success", "삭제을 완료했습니다!" },
|
||||
{ "hex.builtin.tools.file_tools.splitter", "분리 도구" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.5_75_floppy", "5¼\" 플로피 디스크 (1200KiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.3_5_floppy", "3½\" 플로피 디스크 (1400KiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.zip100", "Zip 100 디스크 (100MiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.zip200", "Zip 200 디스크 (200MiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.cdrom650", "CD-ROM (650MiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.cdrom700", "CD-ROM (700MiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.fat32", "FAT32 (4GiB)" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.sizes.custom", "Custom" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.input", "분리할 파일 " },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.input", "분리할 파일을 선택하세요" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.output", "저장 경로 " },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.output", "저장 경로를 선택하세요" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.splitting", "분리 중..." },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.split", "분리" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.error.open", "파일을 여는데 실패했습니다!" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.error.size", "파일이 분리할 크기보다 작습니다" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.error.create", "파일 조각 {0}를 만드는 데 실패했습니다" },
|
||||
{ "hex.builtin.tools.file_tools.splitter.picker.success", "파일 분리를 완료했습니다!" },
|
||||
{ "hex.builtin.tools.file_tools.combiner", "병합 도구" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.add", "추가..." },
|
||||
{ "hex.builtin.tools.file_tools.combiner.add.picker", "파일 추가" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.delete", "삭제" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.clear", "비우기" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.output", "저장 경로 " },
|
||||
{ "hex.builtin.tools.file_tools.combiner.output.picker", "저장 경로를 선택하세요" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.combining", "병합 중..." },
|
||||
{ "hex.builtin.tools.file_tools.combiner.combine", "병합" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.error.open_output", "출력 파일을 여는 데 실패했습니다!" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.open_input", "입력 파일 {0}을 열지 못했습니다" },
|
||||
{ "hex.builtin.tools.file_tools.combiner.success", "파일 병합을 완료했습니다!" },
|
||||
{ "hex.builtin.tools.ieee756", "IEEE 756 부동 소수점 테스트" },
|
||||
{ "hex.builtin.tools.ieee756.sign", "부포" },
|
||||
{ "hex.builtin.tools.ieee756.exponent", "지수부" },
|
||||
{ "hex.builtin.tools.ieee756.mantissa", "가수부" },
|
||||
{ "hex.builtin.tools.ieee756.exponent_size", "지수부 크기" },
|
||||
{ "hex.builtin.tools.ieee756.mantissa_size", "가수부 크기" },
|
||||
{ "hex.builtin.tools.ieee756.half_precision", "Half Precision" },
|
||||
{ "hex.builtin.tools.ieee756.singe_precision", "Single Precision" },
|
||||
{ "hex.builtin.tools.ieee756.double_precision", "Double Precision" },
|
||||
{ "hex.builtin.tools.ieee756.type", "종류" },
|
||||
{ "hex.builtin.tools.ieee756.formula", "공식" },
|
||||
{ "hex.builtin.tools.ieee756.result.title", "결과" },
|
||||
{ "hex.builtin.tools.ieee756.result.float", "부동 소수점 결과" },
|
||||
{ "hex.builtin.tools.ieee756.result.hex", "16진수 결과" },
|
||||
|
||||
{ "hex.builtin.setting.imhex", "ImHex" },
|
||||
{ "hex.builtin.setting.imhex.recent_files", "최근 파일" },
|
||||
{ "hex.builtin.setting.general", "일반" },
|
||||
{ "hex.builtin.setting.general.show_tips", "시작 시 팁 표시" },
|
||||
{ "hex.builtin.setting.general.auto_load_patterns", "지원하는 패턴 자동으로 로드" },
|
||||
{ "hex.builtin.setting.general.sync_pattern_source", "공급자 간 패턴 소스 코드 동기화" },
|
||||
{ "hex.builtin.setting.interface", "인터페이스" },
|
||||
{ "hex.builtin.setting.interface.color", "색상 테마" },
|
||||
{ "hex.builtin.setting.interface.color.system", "시스템" },
|
||||
{ "hex.builtin.setting.interface.color.dark", "다크" },
|
||||
{ "hex.builtin.setting.interface.color.light", "라이트" },
|
||||
{ "hex.builtin.setting.interface.color.classic", "클래식" },
|
||||
{ "hex.builtin.setting.interface.scaling", "크기" },
|
||||
{ "hex.builtin.setting.interface.scaling.native", "기본" },
|
||||
{ "hex.builtin.setting.interface.scaling.x0_5", "x0.5" },
|
||||
{ "hex.builtin.setting.interface.scaling.x1_0", "x1.0" },
|
||||
{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
|
||||
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
|
||||
{ "hex.builtin.setting.interface.scaling.x3_0", "x3.0" },
|
||||
{ "hex.builtin.setting.interface.scaling.x4_0", "x4.0" },
|
||||
{ "hex.builtin.setting.interface.language", "언어" },
|
||||
{ "hex.builtin.setting.interface.wiki_explain_language", "Wikipedia 언어" },
|
||||
{ "hex.builtin.setting.interface.fps", "FPS 제한" },
|
||||
{ "hex.builtin.setting.interface.fps.unlocked", "제한 없음" },
|
||||
{ "hex.builtin.setting.hex_editor", "헥스 편집기" },
|
||||
{ "hex.builtin.setting.hex_editor.highlight_color", "선택 영역 색상 하이라이트" },
|
||||
{ "hex.builtin.setting.hex_editor.bytes_per_row", "한 줄당 바이트 수" },
|
||||
{ "hex.builtin.setting.hex_editor.ascii", "ASCII 열 표시" },
|
||||
{ "hex.builtin.setting.hex_editor.advanced_decoding", "추가 디코딩 열 표시" },
|
||||
{ "hex.builtin.setting.hex_editor.grey_zeros", "00을 회색으로 표시" },
|
||||
{ "hex.builtin.setting.hex_editor.uppercase_hex", "16진수 값을 대문자로 표시" },
|
||||
{ "hex.builtin.setting.hex_editor.visualizer", "데이터 표시" },
|
||||
{ "hex.builtin.setting.folders", "폴더" },
|
||||
{ "hex.builtin.setting.folders.description", "패턴, 스크립트, YARA 규칙 등을 찾아볼 추가적인 폴더 경로를 지정하세요" },
|
||||
{ "hex.builtin.setting.folders.add_folder", "새 폴더 추가" },
|
||||
{ "hex.builtin.setting.folders.remove_folder", "선택한 폴더를 리스트에서 제거" },
|
||||
{ "hex.builtin.setting.font", "글꼴" },
|
||||
{ "hex.builtin.setting.font.font_path", "사용자 지정 글꼴 경로" },
|
||||
{ "hex.builtin.setting.font.font_size", "글꼴 크기" },
|
||||
{ "hex.builtin.setting.proxy", "프록시" },
|
||||
{ "hex.builtin.setting.proxy.description", "프록시는 스토어, wikipedia, 그리고 추가적인 플러그인에 즉시 적용이 됩니다." },
|
||||
{ "hex.builtin.setting.proxy.enable", "Proxy 활성화" },
|
||||
{ "hex.builtin.setting.proxy.url", "Proxy 경로" },
|
||||
{ "hex.builtin.setting.proxy.url.tooltip", "http(s):// 혹은 socks5:// (예., http://127.0.0.1:1080)" },
|
||||
|
||||
{ "hex.builtin.provider.file", "파일 공급자" },
|
||||
{ "hex.builtin.provider.file.path", "파일 경로" },
|
||||
{ "hex.builtin.provider.file.size", "크기" },
|
||||
{ "hex.builtin.provider.file.creation", "생성 시각" },
|
||||
{ "hex.builtin.provider.file.access", "마지막 접근 시각" },
|
||||
{ "hex.builtin.provider.file.modification", "마지막 수정 시각" },
|
||||
{ "hex.builtin.provider.gdb", "GDB 서버 공급자" },
|
||||
{ "hex.builtin.provider.gdb.name", "GDB 서버 <{0}:{1}>" },
|
||||
{ "hex.builtin.provider.gdb.server", "서버" },
|
||||
{ "hex.builtin.provider.gdb.ip", "IP 주소" },
|
||||
{ "hex.builtin.provider.gdb.port", "포트" },
|
||||
{ "hex.builtin.provider.disk", "Raw 디스크 공급자" },
|
||||
{ "hex.builtin.provider.disk.selected_disk", "디스크" },
|
||||
{ "hex.builtin.provider.disk.disk_size", "디스크 크기" },
|
||||
{ "hex.builtin.provider.disk.sector_size", "섹터 크기" },
|
||||
{ "hex.builtin.provider.disk.reload", "새로 고침" },
|
||||
{ "hex.builtin.provider.intel_hex", "Intel Hex 공급자" },
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC 공급자" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "기본 값" },
|
||||
|
||||
{ "hex.builtin.visualizer.hexadecimal.8bit", "16진수 (8 비트)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.16bit", "16진수 (16 비트)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.32bit", "16진수 (32 비트)" },
|
||||
{ "hex.builtin.visualizer.hexadecimal.64bit", "16진수 (64 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.8bit", "부호 있는 10진수 (8 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.16bit", "부호 있는 10진수 (16 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.32bit", "부호 있는 10진수 (32 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.signed.64bit", "부호 있는 10진수 (64 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.8bit", "부호 없는 10진수 (8 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.16bit", "부호 없는 10진수 (16 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.32bit", "부호 없는 10진수 (32 비트)" },
|
||||
{ "hex.builtin.visualizer.decimal.unsigned.64bit", "부호 없는 10진수 (64 비트)" },
|
||||
{ "hex.builtin.visualizer.floating_point.32bit", "부동소수점 (32 비트)" },
|
||||
{ "hex.builtin.visualizer.floating_point.64bit", "부동소수점 (64 비트)" },
|
||||
{ "hex.builtin.visualizer.hexii", "HexII" },
|
||||
{ "hex.builtin.visualizer.rgba8", "RGBA8 색상" },
|
||||
|
||||
{ "hex.builtin.hash.md5", "MD5" },
|
||||
{ "hex.builtin.hash.sha1", "SHA1" },
|
||||
{ "hex.builtin.hash.sha224", "SHA224" },
|
||||
{ "hex.builtin.hash.sha256", "SHA256" },
|
||||
{ "hex.builtin.hash.sha384", "SHA384" },
|
||||
{ "hex.builtin.hash.sha512", "SHA512" },
|
||||
{ "hex.builtin.hash.crc8", "CRC8" },
|
||||
{ "hex.builtin.hash.crc16", "CRC16" },
|
||||
{ "hex.builtin.hash.crc32", "CRC32" },
|
||||
{ "hex.builtin.hash.crc.poly", "Polynomial" },
|
||||
{ "hex.builtin.hash.crc.iv", "Initial Value" },
|
||||
{ "hex.builtin.hash.crc.xor_out", "XOR Out" },
|
||||
{ "hex.builtin.hash.crc.refl_in", "Reflect In" },
|
||||
{ "hex.builtin.hash.crc.refl_out", "Reflect Out" },
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "Documentação da linguagem padrão" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "Aprenda a escrever padrões ImHex com nossa extensa documentação" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "Plugins API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "Estenda o ImHex com recursos adicionais usando plugins" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "Não foi possível obter acesso de gravação. Arquivo aberto no modo somente leitura." },
|
||||
{ "hex.builtin.popup.error.open", "Falha ao abrir o arquivo!" },
|
||||
{ "hex.builtin.popup.error.create", "Falha ao criar um novo arquivo!" },
|
||||
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "File" },
|
||||
//{ "hex.builtin.menu.file.create_file", "New File..." },
|
||||
{ "hex.builtin.menu.file.open_file", "Abrir Arquivo..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "Abrir Recentes" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "Limpar" },
|
||||
@@ -285,6 +287,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "Copiar" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "Copiar como..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "String" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# Array" },
|
||||
@@ -292,7 +295,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII Art" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal Array" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "Colar" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "Selecionar tudo" },
|
||||
@@ -414,11 +423,14 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
// { "hex.builtin.view.find.sequences", "Sequences" },
|
||||
// { "hex.builtin.view.find.regex", "Regex" },
|
||||
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
// { "hex.builtin.view.find.search", "Search" },
|
||||
// { "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
// { "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "Calculadora" },
|
||||
{ "hex.builtin.command.cmd.desc", "Comando" },
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "模式文档" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", "如何基于我们完善的文档编写 ImHex 模式" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "插件 API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", "通过插件扩展 ImHex 获得更多功能" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -81,13 +81,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.common.browse", "浏览..." },
|
||||
{ "hex.builtin.common.choose_file", "选择文件" },
|
||||
{ "hex.builtin.common.processing", "处理" },
|
||||
//{ "hex.builtin.common.filter", "Filter" },
|
||||
//{ "hex.builtin.common.value", "Value" },
|
||||
{ "hex.builtin.common.filter", "过滤器" },
|
||||
{ "hex.builtin.common.value", "值" },
|
||||
{ "hex.builtin.common.offset", "偏移" },
|
||||
//{ "hex.builtin.common.range", "Range" },
|
||||
//{ "hex.builtin.common.range.entire_data", "Entire Data" },
|
||||
//{ "hex.builtin.common.range.selection", "Selection" },
|
||||
//{ "hex.builtin.common.comment", "Comment" },
|
||||
{ "hex.builtin.common.range", "范围" },
|
||||
{ "hex.builtin.common.range.entire_data", "所有数据" },
|
||||
{ "hex.builtin.common.range.selection", "选区" },
|
||||
{ "hex.builtin.common.comment", "注释" },
|
||||
|
||||
{ "hex.builtin.common.encoding.ascii", "ASCII" },
|
||||
{ "hex.builtin.common.encoding.utf16le", "UTF-16LE" },
|
||||
@@ -96,13 +96,15 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{ "hex.builtin.popup.exit_application.title", "退出?" },
|
||||
{ "hex.builtin.popup.exit_application.desc", "工程还有未保存的更改。\n确定要退出吗?" },
|
||||
//{ "hex.builtin.popup.close_provider.title", "Close Provider?" },
|
||||
//{ "hex.builtin.popup.close_provider.desc", "You have unsaved changes made to this Provider.\nAre you sure you want to close it?" },
|
||||
{ "hex.builtin.popup.close_provider.title", "关闭提供器?" },
|
||||
{ "hex.builtin.popup.close_provider.desc", "有对此提供器做出的未保存的更改。\n你确定要关闭吗?" },
|
||||
{ "hex.builtin.popup.error.read_only", "无法获得写权限,文件以只读方式打开。" },
|
||||
{ "hex.builtin.popup.error.open", "打开文件失败!" },
|
||||
{ "hex.builtin.popup.error.create", "创建新文件失败!" },
|
||||
{ "hex.builtin.popup.error.task_exception", "任务 '{}' 异常:\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "文件" },
|
||||
{ "hex.builtin.menu.file.create_file", "新建文件..." },
|
||||
{ "hex.builtin.menu.file.open_file", "打开文件..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "最近打开" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "清除" },
|
||||
@@ -123,8 +125,8 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.menu.file.export.ips32", "IPS32 补丁" },
|
||||
{ "hex.builtin.menu.file.export.base64.popup.export_error", "文件不是有效的 Base64 格式!" },
|
||||
{ "hex.builtin.menu.file.export.popup.create", "无法导出文件。文件创建失败!" },
|
||||
//{ "hex.builtin.menu.file.bookmark.import", "Import bookmarks" },
|
||||
//{ "hex.builtin.menu.file.bookmark.export", "Export bookmarks" },
|
||||
{ "hex.builtin.menu.file.bookmark.import", "导入书签" },
|
||||
{ "hex.builtin.menu.file.bookmark.export", "导出书签" },
|
||||
|
||||
{ "hex.builtin.menu.edit", "编辑" },
|
||||
{ "hex.builtin.menu.edit.undo", "撤销" },
|
||||
@@ -277,17 +279,18 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.relative", "相对" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.begin", "起始" },
|
||||
{ "hex.builtin.view.hex_editor.goto.offset.end", "末尾" },
|
||||
//{ "hex.builtin.view.hex_editor.menu.file.select", "Select" },
|
||||
// { "hex.builtin.view.hex_editor.select.offset.region", "Region" },
|
||||
// { "hex.builtin.view.hex_editor.select.offset.begin", "Begin" },
|
||||
// { "hex.builtin.view.hex_editor.select.offset.end", "End" },
|
||||
// { "hex.builtin.view.hex_editor.select.offset.size", "Size" },
|
||||
// { "hex.builtin.view.hex_editor.select.select", "Select" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.select", "选择" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.region", "区域" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.begin", "起始" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.end", "结束" },
|
||||
{ "hex.builtin.view.hex_editor.select.offset.size", "大小" },
|
||||
{ "hex.builtin.view.hex_editor.select.select", "选择" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save", "保存" },
|
||||
{ "hex.builtin.view.hex_editor.menu.file.save_as", "另存为..." },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "复制" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "复制为..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "字符串" },
|
||||
{ "hex.builtin.view.hex_editor.copy.address", "地址" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 数组" },
|
||||
@@ -295,7 +298,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "Hex Dump(ASCII 艺术)" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 数组" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "粘贴" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "全选" },
|
||||
@@ -398,30 +407,33 @@ namespace hex::plugin::builtin {
|
||||
|
||||
{ "hex.builtin.view.provider_settings.name", "提供器设置" },
|
||||
{ "hex.builtin.view.provider_settings.load_popup", "打开提供器" },
|
||||
// { "hex.builtin.view.provider_settings.load_error", "An error occurred while trying to open this provider!"},
|
||||
{ "hex.builtin.view.provider_settings.load_error", "尝试打开此提供器时出现错误"},
|
||||
|
||||
//{ "hex.builtin.view.find.name", "Find" },
|
||||
// { "hex.builtin.view.find.searching", "Searching..." },
|
||||
// { "hex.builtin.view.find.demangled", "Demangled" },
|
||||
// { "hex.builtin.view.find.strings", "Strings" },
|
||||
// { "hex.builtin.view.find.strings.min_length", "Minimum length" },
|
||||
// { "hex.builtin.view.find.strings.match_settings", "Match Settings" },
|
||||
// { "hex.builtin.view.find.strings.null_term", "Require Null Termination" },
|
||||
// { "hex.builtin.view.find.strings.chars", "Characters" },
|
||||
// { "hex.builtin.view.find.strings.lower_case", "Lower case letters" },
|
||||
// { "hex.builtin.view.find.strings.upper_case", "Upper case letters" },
|
||||
// { "hex.builtin.view.find.strings.numbers", "Numbers" },
|
||||
// { "hex.builtin.view.find.strings.underscores", "Underscores" },
|
||||
// { "hex.builtin.view.find.strings.symbols", "Symbols" },
|
||||
// { "hex.builtin.view.find.strings.spaces", "Spaces" },
|
||||
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
// { "hex.builtin.view.find.sequences", "Sequences" },
|
||||
// { "hex.builtin.view.find.regex", "Regex" },
|
||||
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
// { "hex.builtin.view.find.search", "Search" },
|
||||
// { "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
// { "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
{ "hex.builtin.view.find.name", "查找" },
|
||||
{ "hex.builtin.view.find.searching", "搜索中..." },
|
||||
{ "hex.builtin.view.find.demangled", "还原名" },
|
||||
{ "hex.builtin.view.find.strings", "字符串" },
|
||||
{ "hex.builtin.view.find.strings.min_length", "最短长度" },
|
||||
{ "hex.builtin.view.find.strings.match_settings", "配置设置" },
|
||||
{ "hex.builtin.view.find.strings.null_term", "需要NULL终止" },
|
||||
{ "hex.builtin.view.find.strings.chars", "字符" },
|
||||
{ "hex.builtin.view.find.strings.lower_case", "小写字母" },
|
||||
{ "hex.builtin.view.find.strings.upper_case", "大写字母" },
|
||||
{ "hex.builtin.view.find.strings.numbers", "数字" },
|
||||
{ "hex.builtin.view.find.strings.underscores", "下划线" },
|
||||
{ "hex.builtin.view.find.strings.symbols", "符号" },
|
||||
{ "hex.builtin.view.find.strings.spaces", "空格" },
|
||||
{ "hex.builtin.view.find.strings.line_feeds", "换行" },
|
||||
{ "hex.builtin.view.find.sequences", "序列" },
|
||||
{ "hex.builtin.view.find.regex", "正则表达式" },
|
||||
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
{ "hex.builtin.view.find.binary_pattern", "二进制模式" },
|
||||
{ "hex.builtin.view.find.search", "搜索" },
|
||||
{ "hex.builtin.view.find.context.copy", "复制值" },
|
||||
{ "hex.builtin.view.find.context.copy_demangle", "复制值的还原名" },
|
||||
{ "hex.builtin.view.find.search.entries", "{} 个结果" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "计算器" },
|
||||
{ "hex.builtin.command.cmd.desc", "指令" },
|
||||
@@ -429,8 +441,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.command.web.desc", "网站解析" },
|
||||
{ "hex.builtin.command.web.result", "导航到 '{0}'" },
|
||||
|
||||
// Use half width symbols for inspector names because displayable space
|
||||
{ "hex.builtin.inspector.binary", "二进制(8位)" },
|
||||
{ "hex.builtin.inspector.binary", "二进制(8 位)" },
|
||||
{ "hex.builtin.inspector.u8", "uint8_t" },
|
||||
{ "hex.builtin.inspector.i8", "int8_t" },
|
||||
{ "hex.builtin.inspector.u16", "uint16_t" },
|
||||
@@ -443,12 +454,12 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.inspector.i48", "int48_t" },
|
||||
{ "hex.builtin.inspector.u64", "uint64_t" },
|
||||
{ "hex.builtin.inspector.i64", "int64_t" },
|
||||
{ "hex.builtin.inspector.float16", "半精度浮点(16位)" },
|
||||
{ "hex.builtin.inspector.float", "float(32位单精度)" },
|
||||
{ "hex.builtin.inspector.double", "double(64位双精度)" },
|
||||
{ "hex.builtin.inspector.long_double", "long double(128位四精度)" },
|
||||
//{ "hex.builtin.inspector.sleb128", "Signed LEB128" },
|
||||
//{ "hex.builtin.inspector.uleb128", "Unsigned LEB128" },
|
||||
{ "hex.builtin.inspector.float16", "half float(16 位)" },
|
||||
{ "hex.builtin.inspector.float", "float(32 位)" },
|
||||
{ "hex.builtin.inspector.double", "double(64 位)" },
|
||||
{ "hex.builtin.inspector.long_double", "long double(128 位)" },
|
||||
{ "hex.builtin.inspector.sleb128", "有符号LEB128" },
|
||||
{ "hex.builtin.inspector.uleb128", "无符号LEB128" },
|
||||
{ "hex.builtin.inspector.bool", "bool" },
|
||||
{ "hex.builtin.inspector.ascii", "ASCII 字符" },
|
||||
{ "hex.builtin.inspector.wide", "宽字符" },
|
||||
@@ -707,7 +718,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.setting.general", "通用" },
|
||||
{ "hex.builtin.setting.general.show_tips", "在启动时显示每日提示" },
|
||||
{ "hex.builtin.setting.general.auto_load_patterns", "自动加载支持的模式" },
|
||||
// { "hex.builtin.setting.general.sync_pattern_source", "Sync pattern source code between providers" },
|
||||
{ "hex.builtin.setting.general.sync_pattern_source", "在提供器间同步模式源码" },
|
||||
{ "hex.builtin.setting.interface", "界面" },
|
||||
{ "hex.builtin.setting.interface.color", "颜色主题" },
|
||||
{ "hex.builtin.setting.interface.color.system", "跟随系统" },
|
||||
@@ -763,10 +774,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.provider.disk.disk_size", "磁盘大小" },
|
||||
{ "hex.builtin.provider.disk.sector_size", "扇区大小" },
|
||||
{ "hex.builtin.provider.disk.reload", "刷新" },
|
||||
//{ "hex.builtin.provider.intel_hex", "Intel Hex Provider" },
|
||||
// { "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
//{ "hex.builtin.provider.motorola_srec", "Motorola SREC Provider" },
|
||||
// { "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
{ "hex.builtin.provider.intel_hex", "Intel Hex" },
|
||||
{ "hex.builtin.provider.intel_hex.name", "Intel Hex {0}" },
|
||||
{ "hex.builtin.provider.motorola_srec", "Motorola SREC" },
|
||||
{ "hex.builtin.provider.motorola_srec.name", "Motorola SREC {0}" },
|
||||
|
||||
{ "hex.builtin.layouts.default", "默认" },
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.welcome.learn.latest.link", "https://github.com/WerWolv/ImHex/releases/latest" },
|
||||
{ "hex.builtin.welcome.learn.pattern.title", "模式語言說明文件" },
|
||||
{ "hex.builtin.welcome.learn.pattern.desc", " 閱覽我們詳盡的說明文件來學習如何編寫 ImHex 的模式" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs/pattern_language/pattern_language.html" },
|
||||
{ "hex.builtin.welcome.learn.pattern.link", "https://imhex.werwolv.net/docs" },
|
||||
{ "hex.builtin.welcome.learn.plugins.title", "外掛程式 API" },
|
||||
{ "hex.builtin.welcome.learn.plugins.desc", " 使用外掛程式來拓展 ImHex 的功能" },
|
||||
{ "hex.builtin.welcome.learn.plugins.link", "https://github.com/WerWolv/ImHex/wiki/Plugins-Development-Guide" },
|
||||
@@ -101,8 +101,10 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.popup.error.read_only", "無法取得寫入權限。檔案已以唯讀模式開啟。" },
|
||||
{ "hex.builtin.popup.error.open", "無法開啟檔案!" },
|
||||
{ "hex.builtin.popup.error.create", "無法建立新檔案!" },
|
||||
//{ "hex.builtin.popup.error.task_exception", "Exception thrown in Task '{}':\n\n{}" },
|
||||
|
||||
{ "hex.builtin.menu.file", "檔案" },
|
||||
//{ "hex.builtin.menu.file.create_file", "New File..." },
|
||||
{ "hex.builtin.menu.file.open_file", "開啟檔案..." },
|
||||
{ "hex.builtin.menu.file.open_recent", "開啟近期" },
|
||||
{ "hex.builtin.menu.file.clear_recent", "清除" },
|
||||
@@ -285,6 +287,7 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy", "複製" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.copy_as", "複製為..." },
|
||||
{ "hex.builtin.view.hex_editor.copy.hex", "字串" },
|
||||
//{ "hex.builtin.view.hex_editor.copy.address", "Address" },
|
||||
{ "hex.builtin.view.hex_editor.copy.c", "C 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.cpp", "C++ 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.csharp", "C# 陣列" },
|
||||
@@ -292,7 +295,13 @@ namespace hex::plugin::builtin {
|
||||
{ "hex.builtin.view.hex_editor.copy.python", "Python 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.java", "Java 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.js", "JavaScript 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.ascii", "ASCII 畫" },
|
||||
{ "hex.builtin.view.hex_editor.copy.lua", "Lua 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.go", "Go 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.crystal", "Crystal 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.swift", "Swift 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.pascal", "Pascal 陣列" },
|
||||
{ "hex.builtin.view.hex_editor.copy.base64", "Base64" },
|
||||
// { "hex.builtin.view.hex_editor.copy.ascii", "Text Area" },
|
||||
{ "hex.builtin.view.hex_editor.copy.html", "HTML" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.paste", "貼上" },
|
||||
{ "hex.builtin.view.hex_editor.menu.edit.select_all", "全選" },
|
||||
@@ -415,11 +424,14 @@ namespace hex::plugin::builtin {
|
||||
// { "hex.builtin.view.find.strings.line_feeds", "Line Feeds" },
|
||||
// { "hex.builtin.view.find.sequences", "Sequences" },
|
||||
// { "hex.builtin.view.find.regex", "Regex" },
|
||||
// { "hex.builtin.view.find.regex.pattern", "Pattern" },
|
||||
// { "hex.builtin.view.find.regex.full_match", "Require full match" },
|
||||
// { "hex.builtin.view.find.binary_pattern", "Binary Pattern" },
|
||||
// { "hex.builtin.view.find.search", "Search" },
|
||||
// { "hex.builtin.view.find.context.copy", "Copy Value" },
|
||||
// { "hex.builtin.view.find.context.copy_demangle", "Copy Demangled Value" },
|
||||
// { "hex.builtin.view.find.search.entries", "{} entries found" },
|
||||
// { "hex.builtin.view.find.search.reset", "Reset" },
|
||||
|
||||
{ "hex.builtin.command.calc.desc", "計算機" },
|
||||
{ "hex.builtin.command.cmd.desc", "命令" },
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace hex::plugin::builtin {
|
||||
void registerLanguageZhCN();
|
||||
void registerLanguagePtBR();
|
||||
void registerLanguageZhTW();
|
||||
void registerLanguageKoKR();
|
||||
}
|
||||
|
||||
IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
@@ -47,6 +48,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
registerLanguageZhCN();
|
||||
registerLanguagePtBR();
|
||||
registerLanguageZhTW();
|
||||
registerLanguageKoKR();
|
||||
|
||||
registerEventHandlers();
|
||||
registerDataVisualizers();
|
||||
|
||||
@@ -11,10 +11,11 @@ if (WIN32)
|
||||
|
||||
source/views/view_tty_console.cpp
|
||||
|
||||
source/lang/en_US.cpp
|
||||
source/lang/de_DE.cpp
|
||||
source/lang/zh_CN.cpp
|
||||
source/lang/en_US.cpp
|
||||
source/lang/ko_KR.cpp
|
||||
source/lang/pt_BR.cpp
|
||||
source/lang/zh_CN.cpp
|
||||
source/lang/zh_TW.cpp
|
||||
|
||||
source/content/ui_items.cpp
|
||||
|
||||
35
plugins/windows/source/lang/ko_KR.cpp
Normal file
35
plugins/windows/source/lang/ko_KR.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/localization.hpp>
|
||||
|
||||
namespace hex::plugin::windows {
|
||||
|
||||
void registerLanguageKoKR() {
|
||||
ContentRegistry::Language::addLocalizations("ko-KR", {
|
||||
{ "hex.windows.title_bar_button.feedback", "피드백 남기기" },
|
||||
{ "hex.windows.title_bar_button.debug_build", "디버그 빌드"},
|
||||
|
||||
{ "hex.windows.view.tty_console.name", "TTY 콘솔" },
|
||||
{ "hex.windows.view.tty_console.config", "설정"},
|
||||
{ "hex.windows.view.tty_console.port", "포트" },
|
||||
{ "hex.windows.view.tty_console.reload", "새로 고침" },
|
||||
{ "hex.windows.view.tty_console.baud", "Baud rate" },
|
||||
{ "hex.windows.view.tty_console.num_bits", "Data bits" },
|
||||
{ "hex.windows.view.tty_console.stop_bits", "Stop bits" },
|
||||
{ "hex.windows.view.tty_console.parity_bits", "Parity bit" },
|
||||
{ "hex.windows.view.tty_console.cts", "Use CTS flow control" },
|
||||
{ "hex.windows.view.tty_console.connect", "연결" },
|
||||
{ "hex.windows.view.tty_console.disconnect", "연결 끊기" },
|
||||
{ "hex.windows.view.tty_console.connect_error", "COM 포트 연결에 실패했습니다!" },
|
||||
{ "hex.windows.view.tty_console.no_available_port", "선택한 COM 포트가 올바르지 않거나 COM 포트가 존재하지 않습니다!" },
|
||||
{ "hex.windows.view.tty_console.clear", "지우기" },
|
||||
{ "hex.windows.view.tty_console.auto_scroll", "자동 스크롤" },
|
||||
{ "hex.windows.view.tty_console.console", "콘솔" },
|
||||
{ "hex.windows.view.tty_console.send_etx", "ETX 보내기" },
|
||||
{ "hex.windows.view.tty_console.send_eot", "EOT 보내기" },
|
||||
{ "hex.windows.view.tty_console.send_sub", "SUB 보내기" },
|
||||
|
||||
{ "hex.builtin.setting.general.context_menu_entry", "Windows 컨텍스트 메뉴 항목" },
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ namespace hex::plugin::windows {
|
||||
void registerLanguageZhCN();
|
||||
void registerLanguagePtBR();
|
||||
void registerLanguageZhTW();
|
||||
void registerLanguageKoKR();
|
||||
|
||||
void addFooterItems();
|
||||
void addTitleBarButtons();
|
||||
@@ -67,6 +68,7 @@ IMHEX_PLUGIN_SETUP("Windows", "WerWolv", "Windows-only features") {
|
||||
registerLanguageZhCN();
|
||||
registerLanguagePtBR();
|
||||
registerLanguageZhTW();
|
||||
registerLanguageKoKR();
|
||||
|
||||
hex::ContentRegistry::Views::add<ViewTTYConsole>();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user