mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 13:26:02 -05:00
Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd7beb642f | ||
|
|
b766cf0807 | ||
|
|
6c9469961b | ||
|
|
d8844236d0 | ||
|
|
60eb59c605 | ||
|
|
6a7bbb8752 | ||
|
|
e4431749e1 | ||
|
|
c587b357eb | ||
|
|
7357c26d54 | ||
|
|
73ca45ad3d | ||
|
|
bf00503d1f | ||
|
|
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.1.2.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()
|
||||
|
||||
52
INSTALL.md
Normal file
52
INSTALL.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Installing ImHex
|
||||
|
||||
## Official Releases
|
||||
|
||||
The easiest way to install ImHex is to download the latest release from the [GitHub releases page](github.com/WerWolv/ImHex/releases/latest).
|
||||
|
||||
There's also a NoGPU version available for users who don't have a GPU or want to run ImHex in a VM without GPU passthrough.
|
||||
|
||||
## Nighly Builds
|
||||
|
||||
The GitHub Actions CI builds a new release package on every commit made to repository. These builds are available on the [GitHub Actions page](https://github.com/WerWolv/ImHex/actions?query=workflow%3A%22Build%22).
|
||||
These builds are not guaranteed to be stable and may contain bugs, however they also contain new features that are not yet available in the official releases.
|
||||
|
||||
## Building from source
|
||||
|
||||
Build instructions for Windows, Linux and macOS can be found under `/dist/compiling`:
|
||||
- Windows: [Link](dist/compiling/windows.md)
|
||||
- macOS: [Link](dist/compiling/macos.md)
|
||||
- Linux: [Link](dist/compiling/linux.md)
|
||||
|
||||
## Package managers
|
||||
|
||||
ImHex is also available on various package managers. The officially supported ones are listed here:
|
||||
|
||||
### Windows
|
||||
|
||||
- **Cocolatey**
|
||||
- [imhex](https://community.chocolatey.org/packages/imhex) (Thanks to @Jarcho)
|
||||
- `choco install imhex`
|
||||
- **winget**
|
||||
- [WerWolv.ImHex](https://github.com/microsoft/winget-pkgs/tree/master/manifests/w/WerWolv/ImHex)
|
||||
- `winget install WerWolv.ImHex`
|
||||
|
||||
### Linux
|
||||
- **Arch Linux AUR**
|
||||
- [imhex-bin](https://aur.archlinux.org/packages/imhex-bin/) (Thanks to @iTrooz)
|
||||
- `yay -S imhex-bin`
|
||||
- [imhex](https://aur.archlinux.org/packages/imhex/) (Thanks to @KokaKiwi)
|
||||
- `yay -S imhex`
|
||||
- **Fedora**
|
||||
- [imhex](https://src.fedoraproject.org/rpms/imhex/) (Thanks to @jonathanspw)
|
||||
- `dnf install imhex`
|
||||
- **Flatpak**
|
||||
- [net.werwolv.Imhex](https://flathub.org/apps/details/net.werwolv.ImHex) (Thanks to @Mailaender)
|
||||
- `flatpak install flathub net.werwolv.ImHex`
|
||||
|
||||
### Available on other package managers
|
||||
|
||||
Packages that aren't explicitly mentioned above are not officially supported but they will most likely still work.
|
||||
Contact the maintainer of the package if you have any issues.
|
||||
|
||||
[](https://repology.org/project/imhex/versions)
|
||||
48
README.md
48
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>
|
||||
|
||||
@@ -104,7 +104,11 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
|
||||
## Pattern Language
|
||||
|
||||
The custom C-like Pattern Language developed and used by ImHex is easy to read, understand and learn. A guide with all features of the language can be found [on the docs page](http://imhex.werwolv.net/docs).
|
||||
The Pattern Language is the completely custom programming language developed for ImHex.
|
||||
It allows you to define structures and data types in a C-like syntax and then use them to parse and highlight a file's content.
|
||||
|
||||
- Source Code: [Link](https://github.com/WerWolv/PatternLanguage/)
|
||||
- Documentation: [Link](https://imhex.werwolv.net/docs/)
|
||||
|
||||
## Database
|
||||
|
||||
@@ -116,40 +120,15 @@ 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
|
||||
- **Storage**: 100MB
|
||||
|
||||
## Plugin development
|
||||
## Installing
|
||||
|
||||
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
|
||||
- [C++ Plugin Template](https://github.com/WerWolv/ImHex-Cpp-Plugin-Template)
|
||||
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
|
||||
|
||||
|
||||
## Nightly builds
|
||||
|
||||
Nightlies are available via GitHub Actions [here](https://github.com/WerWolv/ImHex/actions?query=workflow%3ABuild).
|
||||
|
||||
- Windows • __x86_64__
|
||||
- [Installer](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Installer.zip)
|
||||
- [Portable](https://nightly.link/WerWolv/ImHex/workflows/build/master/Windows%20Portable.zip)
|
||||
- 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)
|
||||
- [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)
|
||||
Information on how to install ImHex can be found in the [Install](/INSTALL.md) guide
|
||||
|
||||
## Compiling
|
||||
|
||||
@@ -160,6 +139,15 @@ All releases are being built using latest available GCC.
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
For more information, check out the [Compiling](/dist/compiling) guide.
|
||||
|
||||
## Plugin development
|
||||
|
||||
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
|
||||
- [C++ Plugin Template](https://github.com/WerWolv/ImHex-Cpp-Plugin-Template)
|
||||
- [Rust Plugin Template](https://github.com/WerWolv/ImHex-Rust-Plugin-Template)
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
### Contributors
|
||||
|
||||
@@ -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...0798f36a04
@@ -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) {
|
||||
|
||||
}
|
||||
@@ -21,6 +24,9 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
void setEndAddress(u64 address) {
|
||||
if (address >= this->m_provider->getActualSize())
|
||||
address = this->m_provider->getActualSize() - 1;
|
||||
|
||||
this->m_endAddress = address;
|
||||
}
|
||||
|
||||
@@ -215,7 +221,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,7 +253,7 @@ namespace hex::prv {
|
||||
}
|
||||
|
||||
ReverseIterator rend() {
|
||||
return { this, std::numeric_limits<u64>::max() };
|
||||
return { this, 0 };
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -256,6 +262,8 @@ namespace hex::prv {
|
||||
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 >= 0 && 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 - 1);
|
||||
|
||||
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) - 1);
|
||||
|
||||
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();
|
||||
|
||||
@@ -1528,7 +1576,8 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.remove"_lang, nullptr, false, providerValid && provider->isResizable())) {
|
||||
this->openPopup<PopupRemove>(this->getSelection().getStartAddress(), 0x00);
|
||||
auto selection = this->getSelection();
|
||||
this->openPopup<PopupRemove>(selection.getStartAddress(), selection.getSize());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 컨텍스트 메뉴 항목" },
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user