feat: dos header的读取写完了。
This commit is contained in:
parent
f8ec30acfc
commit
f837e7cdaf
@ -12,13 +12,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.5.2",
|
"@ant-design/icons": "^5.5.2",
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
|
"@tauri-apps/plugin-dialog": "~2",
|
||||||
"@tauri-apps/plugin-shell": "^2",
|
"@tauri-apps/plugin-shell": "^2",
|
||||||
"antd": "^5.22.3",
|
"antd": "^5.22.3",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^2",
|
"@tauri-apps/cli": "^2",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/react": "^19.0.0",
|
"@types/react": "^19.0.0",
|
||||||
"@types/react-dom": "^19.0.0",
|
"@types/react-dom": "^19.0.0",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
@ -14,12 +14,18 @@ importers:
|
|||||||
'@tauri-apps/api':
|
'@tauri-apps/api':
|
||||||
specifier: ^2
|
specifier: ^2
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
|
'@tauri-apps/plugin-dialog':
|
||||||
|
specifier: ~2
|
||||||
|
version: 2.0.1
|
||||||
'@tauri-apps/plugin-shell':
|
'@tauri-apps/plugin-shell':
|
||||||
specifier: ^2
|
specifier: ^2
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
antd:
|
antd:
|
||||||
specifier: ^5.22.3
|
specifier: ^5.22.3
|
||||||
version: 5.22.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 5.22.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
|
lodash-es:
|
||||||
|
specifier: ^4.17.21
|
||||||
|
version: 4.17.21
|
||||||
react:
|
react:
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.0.0
|
version: 19.0.0
|
||||||
@ -30,6 +36,9 @@ importers:
|
|||||||
'@tauri-apps/cli':
|
'@tauri-apps/cli':
|
||||||
specifier: ^2
|
specifier: ^2
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
|
'@types/lodash-es':
|
||||||
|
specifier: ^4.17.12
|
||||||
|
version: 4.17.12
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19.0.0
|
specifier: ^19.0.0
|
||||||
version: 19.0.1
|
version: 19.0.1
|
||||||
@ -644,6 +653,9 @@ packages:
|
|||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-dialog@2.0.1':
|
||||||
|
resolution: {integrity: sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==}
|
||||||
|
|
||||||
'@tauri-apps/plugin-shell@2.0.1':
|
'@tauri-apps/plugin-shell@2.0.1':
|
||||||
resolution: {integrity: sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==}
|
resolution: {integrity: sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==}
|
||||||
|
|
||||||
@ -662,6 +674,12 @@ packages:
|
|||||||
'@types/estree@1.0.6':
|
'@types/estree@1.0.6':
|
||||||
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
||||||
|
|
||||||
|
'@types/lodash-es@4.17.12':
|
||||||
|
resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
|
||||||
|
|
||||||
|
'@types/lodash@4.17.13':
|
||||||
|
resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==}
|
||||||
|
|
||||||
'@types/react-dom@19.0.1':
|
'@types/react-dom@19.0.1':
|
||||||
resolution: {integrity: sha512-hljHij7MpWPKF6u5vojuyfV0YA4YURsQG7KT6SzV0Zs2BXAtgdTxG6A229Ub/xiWV4w/7JL8fi6aAyjshH4meA==}
|
resolution: {integrity: sha512-hljHij7MpWPKF6u5vojuyfV0YA4YURsQG7KT6SzV0Zs2BXAtgdTxG6A229Ub/xiWV4w/7JL8fi6aAyjshH4meA==}
|
||||||
|
|
||||||
@ -788,6 +806,9 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
lodash-es@4.17.21:
|
||||||
|
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||||
|
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||||
|
|
||||||
@ -1666,6 +1687,10 @@ snapshots:
|
|||||||
'@tauri-apps/cli-win32-ia32-msvc': 2.1.0
|
'@tauri-apps/cli-win32-ia32-msvc': 2.1.0
|
||||||
'@tauri-apps/cli-win32-x64-msvc': 2.1.0
|
'@tauri-apps/cli-win32-x64-msvc': 2.1.0
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-dialog@2.0.1':
|
||||||
|
dependencies:
|
||||||
|
'@tauri-apps/api': 2.1.1
|
||||||
|
|
||||||
'@tauri-apps/plugin-shell@2.0.1':
|
'@tauri-apps/plugin-shell@2.0.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.1.1
|
'@tauri-apps/api': 2.1.1
|
||||||
@ -1693,6 +1718,12 @@ snapshots:
|
|||||||
|
|
||||||
'@types/estree@1.0.6': {}
|
'@types/estree@1.0.6': {}
|
||||||
|
|
||||||
|
'@types/lodash-es@4.17.12':
|
||||||
|
dependencies:
|
||||||
|
'@types/lodash': 4.17.13
|
||||||
|
|
||||||
|
'@types/lodash@4.17.13': {}
|
||||||
|
|
||||||
'@types/react-dom@19.0.1':
|
'@types/react-dom@19.0.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 19.0.1
|
'@types/react': 19.0.1
|
||||||
@ -1875,6 +1906,8 @@ snapshots:
|
|||||||
|
|
||||||
json5@2.2.3: {}
|
json5@2.2.3: {}
|
||||||
|
|
||||||
|
lodash-es@4.17.21: {}
|
||||||
|
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 3.1.1
|
yallist: 3.1.1
|
||||||
|
543
src-tauri/Cargo.lock
generated
543
src-tauri/Cargo.lock
generated
@ -62,6 +62,61 @@ version = "1.0.94"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
|
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ashpd"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"raw-window-handle",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-broadcast"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-recursion"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atk"
|
name = "atk"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
@ -373,6 +428,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "concurrent-queue"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -615,6 +679,15 @@ dependencies = [
|
|||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlib"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||||
|
dependencies = [
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dlopen2"
|
name = "dlopen2"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -638,6 +711,12 @@ dependencies = [
|
|||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "downcast-rs"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dpi"
|
name = "dpi"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -703,6 +782,33 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "endi"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2"
|
||||||
|
version = "0.7.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2_derive"
|
||||||
|
version = "0.7.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -719,6 +825,43 @@ dependencies = [
|
|||||||
"typeid",
|
"typeid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "5.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
|
||||||
|
dependencies = [
|
||||||
|
"concurrent-queue",
|
||||||
|
"parking",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener-strategy"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdeflate"
|
name = "fdeflate"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@ -1080,7 +1223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
|
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.1",
|
"heck 0.4.1",
|
||||||
"proc-macro-crate 2.0.2",
|
"proc-macro-crate 2.0.0",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1700,6 +1843,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@ -1865,6 +2014,19 @@ version = "1.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
"memoffset",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodrop"
|
name = "nodrop"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
@ -1901,7 +2063,7 @@ version = "0.7.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate 2.0.2",
|
"proc-macro-crate 1.3.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
@ -2025,6 +2187,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
|
"dispatch",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
]
|
]
|
||||||
@ -2166,6 +2329,16 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-stream"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -2201,6 +2374,12 @@ dependencies = [
|
|||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -2396,7 +2575,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"indexmap 2.7.0",
|
"indexmap 2.7.0",
|
||||||
"quick-xml",
|
"quick-xml 0.32.0",
|
||||||
"serde",
|
"serde",
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
@ -2447,14 +2626,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "2.0.2"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
|
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"toml_datetime",
|
|
||||||
"toml_edit 0.20.2",
|
"toml_edit 0.20.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-crate"
|
||||||
|
version = "3.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
|
||||||
|
dependencies = [
|
||||||
|
"toml_edit 0.22.22",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -2503,6 +2690,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.36.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
@ -2685,6 +2881,29 @@ dependencies = [
|
|||||||
"windows-registry",
|
"windows-registry",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rfd"
|
||||||
|
version = "0.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46f6f80a9b882647d9014673ca9925d30ffc9750f2eed2b4490e189eaebd01e8"
|
||||||
|
dependencies = [
|
||||||
|
"ashpd",
|
||||||
|
"block2",
|
||||||
|
"glib-sys",
|
||||||
|
"gobject-sys",
|
||||||
|
"gtk-sys",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"objc2",
|
||||||
|
"objc2-app-kit",
|
||||||
|
"objc2-foundation",
|
||||||
|
"raw-window-handle",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
@ -2700,6 +2919,19 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
@ -2742,6 +2974,12 @@ dependencies = [
|
|||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -2952,6 +3190,15 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@ -3043,6 +3290,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_cache"
|
name = "string_cache"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
@ -3327,6 +3580,47 @@ dependencies = [
|
|||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-dialog"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0962c2b9210e43cd849790d33bdf3d28c0e50d9884493fb340835244a708b5ba"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"raw-window-handle",
|
||||||
|
"rfd",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"tauri-plugin-fs",
|
||||||
|
"thiserror 2.0.4",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-fs"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0cdaf6701ee5efc83161cf41004aa5aec4d255c9fb2d2b11fe518fe506acc588"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"dunce",
|
||||||
|
"glob",
|
||||||
|
"percent-encoding",
|
||||||
|
"schemars",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"tauri-utils",
|
||||||
|
"thiserror 2.0.4",
|
||||||
|
"toml 0.8.2",
|
||||||
|
"url",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-shell"
|
name = "tauri-plugin-shell"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
@ -3440,6 +3734,19 @@ dependencies = [
|
|||||||
"toml 0.7.8",
|
"toml 0.7.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"fastrand",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tendril"
|
name = "tendril"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
@ -3461,6 +3768,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"tauri-plugin-dialog",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
"thiserror 2.0.4",
|
"thiserror 2.0.4",
|
||||||
]
|
]
|
||||||
@ -3563,7 +3871,9 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3606,9 +3916,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.3"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -3623,7 +3933,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow",
|
"winnow 0.5.40",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3636,7 +3946,18 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow",
|
"winnow 0.5.40",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.7.0",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow 0.6.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3652,9 +3973,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.33"
|
version = "0.1.33"
|
||||||
@ -3703,6 +4036,17 @@ version = "1.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uds_windows"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
|
||||||
|
dependencies = [
|
||||||
|
"memoffset",
|
||||||
|
"tempfile",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unic-char-property"
|
name = "unic-char-property"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -3951,6 +4295,66 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-backend"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"downcast-rs",
|
||||||
|
"rustix",
|
||||||
|
"scoped-tls",
|
||||||
|
"smallvec",
|
||||||
|
"wayland-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-client"
|
||||||
|
version = "0.31.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"rustix",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-scanner",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-protocols"
|
||||||
|
version = "0.32.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-scanner",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-scanner"
|
||||||
|
version = "0.31.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quick-xml 0.36.2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-sys"
|
||||||
|
version = "0.31.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09"
|
||||||
|
dependencies = [
|
||||||
|
"dlib",
|
||||||
|
"log",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.76"
|
version = "0.3.76"
|
||||||
@ -4402,6 +4806,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.6.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
@ -4488,6 +4901,16 @@ dependencies = [
|
|||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xdg-home"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
@ -4512,6 +4935,63 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus"
|
||||||
|
version = "5.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1162094dc63b1629fcc44150bcceeaa80798cd28bcbe7fa987b65a034c258608"
|
||||||
|
dependencies = [
|
||||||
|
"async-broadcast",
|
||||||
|
"async-recursion",
|
||||||
|
"async-trait",
|
||||||
|
"enumflags2",
|
||||||
|
"event-listener",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"hex",
|
||||||
|
"nix",
|
||||||
|
"ordered-stream",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"static_assertions",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"uds_windows",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
"winnow 0.6.20",
|
||||||
|
"xdg-home",
|
||||||
|
"zbus_macros",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_macros"
|
||||||
|
version = "5.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cd2dcdce3e2727f7d74b7e33b5a89539b3cc31049562137faf7ae4eb86cd16d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate 3.2.0",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_names"
|
||||||
|
version = "4.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
"winnow 0.6.20",
|
||||||
|
"zvariant",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.35"
|
version = "0.7.35"
|
||||||
@ -4575,3 +5055,46 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant"
|
||||||
|
version = "5.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f"
|
||||||
|
dependencies = [
|
||||||
|
"endi",
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
"url",
|
||||||
|
"winnow 0.6.20",
|
||||||
|
"zvariant_derive",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_derive"
|
||||||
|
version = "5.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate 3.2.0",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.90",
|
||||||
|
"zvariant_utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_utils"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
"syn 2.0.90",
|
||||||
|
"winnow 0.6.20",
|
||||||
|
]
|
||||||
|
@ -25,4 +25,5 @@ serde_json = "1"
|
|||||||
thiserror = "2.0.4"
|
thiserror = "2.0.4"
|
||||||
bitflags = "2.6.0"
|
bitflags = "2.6.0"
|
||||||
memmap = "0.7.0"
|
memmap = "0.7.0"
|
||||||
|
tauri-plugin-dialog = "2"
|
||||||
|
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
"$schema": "../gen/schemas/desktop-schema.json",
|
"$schema": "../gen/schemas/desktop-schema.json",
|
||||||
"identifier": "default",
|
"identifier": "default",
|
||||||
"description": "Capability for the main window",
|
"description": "Capability for the main window",
|
||||||
"windows": ["main"],
|
"windows": [
|
||||||
|
"main"
|
||||||
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"core:default",
|
"core:default",
|
||||||
"shell:allow-open"
|
"shell:allow-open",
|
||||||
|
"dialog:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
use thiserror;
|
use thiserror;
|
||||||
|
|
||||||
|
use crate::pe_parse::error::{self, PEParseError};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum AppError {
|
pub enum AppError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
@ -8,6 +10,9 @@ pub enum AppError {
|
|||||||
// 未打开文件映射
|
// 未打开文件映射
|
||||||
#[error("文件未打开!")]
|
#[error("文件未打开!")]
|
||||||
NoFileOpened,
|
NoFileOpened,
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
PeParseError(#[from] PEParseError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl serde::Serialize for AppError {
|
impl serde::Serialize for AppError {
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
use crate::{app_error::AppError, services};
|
use crate::{
|
||||||
use serde::Serialize;
|
app_error::AppError,
|
||||||
|
pe_parse::{header::ImageDosHeader, pe::PE},
|
||||||
|
services::{self, GLOBAL_FILE_DATA},
|
||||||
|
};
|
||||||
|
use serde::{ser::SerializeStruct, Serialize, Serializer};
|
||||||
|
use serde_json::Value;
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn greet(name: &str) -> String {
|
pub fn greet(name: &str) -> String {
|
||||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! offset_of {
|
||||||
|
($base:expr, $field:ident) => {
|
||||||
|
(&$base.$field as *const _ as usize) - ($base as *const _ as usize)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct PeNodeTreeData {
|
pub struct PeNodeTreeData {
|
||||||
title: String,
|
title: String,
|
||||||
@ -14,8 +26,8 @@ pub struct PeNodeTreeData {
|
|||||||
// TODO: 获取PE节点树的JSON数据
|
// TODO: 获取PE节点树的JSON数据
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn command_get_file_pe_node_tree_data() -> Result<Vec<PeNodeTreeData>, AppError> {
|
pub fn command_get_file_pe_node_tree_data() -> Result<Vec<PeNodeTreeData>, AppError> {
|
||||||
// 1. 如果全局内存映射句柄为空,则返回错误
|
// 1. 如果没有打开文件,则返回错误
|
||||||
if unsafe { services::GLOBAL_MEMMAP_HANDLE.is_none() } {
|
if GLOBAL_FILE_DATA.lock().unwrap().is_none() {
|
||||||
return Err(AppError::NoFileOpened);
|
return Err(AppError::NoFileOpened);
|
||||||
}
|
}
|
||||||
// 从文件路径中获取文件名
|
// 从文件路径中获取文件名
|
||||||
@ -26,28 +38,28 @@ pub fn command_get_file_pe_node_tree_data() -> Result<Vec<PeNodeTreeData>, AppEr
|
|||||||
};
|
};
|
||||||
let result = PeNodeTreeData {
|
let result = PeNodeTreeData {
|
||||||
title: format!("文件: {}", file_name),
|
title: format!("文件: {}", file_name),
|
||||||
key: "fileName".to_string(),
|
key: "file_name".to_string(),
|
||||||
children: vec![
|
children: vec![
|
||||||
PeNodeTreeData {
|
PeNodeTreeData {
|
||||||
title: "DOS 头部".to_string(),
|
title: "DOS 头部".to_string(),
|
||||||
key: "DOS Header".to_string(),
|
key: "dos_header".to_string(),
|
||||||
children: vec![], // 空数组表示没有子节点
|
children: vec![], // 空数组表示没有子节点
|
||||||
},
|
},
|
||||||
PeNodeTreeData {
|
PeNodeTreeData {
|
||||||
title: "NT 头部".to_string(),
|
title: "NT 头部".to_string(),
|
||||||
key: "NT Headers".to_string(),
|
key: "nt_header".to_string(),
|
||||||
children: vec![
|
children: vec![
|
||||||
PeNodeTreeData {
|
PeNodeTreeData {
|
||||||
title: "文件头部".to_string(),
|
title: "文件头部".to_string(),
|
||||||
key: "File Header".to_string(),
|
key: "file_header".to_string(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
},
|
},
|
||||||
PeNodeTreeData {
|
PeNodeTreeData {
|
||||||
title: "可选头部".to_string(),
|
title: "可选头部".to_string(),
|
||||||
key: "Optional Header".to_string(),
|
key: "optional_header".to_string(),
|
||||||
children: vec![PeNodeTreeData {
|
children: vec![PeNodeTreeData {
|
||||||
title: "数据目录".to_string(),
|
title: "数据目录".to_string(),
|
||||||
key: "Data Directories".to_string(),
|
key: "data_directories".to_string(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
@ -55,7 +67,7 @@ pub fn command_get_file_pe_node_tree_data() -> Result<Vec<PeNodeTreeData>, AppEr
|
|||||||
},
|
},
|
||||||
PeNodeTreeData {
|
PeNodeTreeData {
|
||||||
title: "节区头部".to_string(),
|
title: "节区头部".to_string(),
|
||||||
key: "Section Headers".to_string(),
|
key: "section_header".to_string(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -66,9 +78,276 @@ pub fn command_get_file_pe_node_tree_data() -> Result<Vec<PeNodeTreeData>, AppEr
|
|||||||
// 命令,打开文件
|
// 命令,打开文件
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn command_open_file(file_path: &str) -> Result<(), AppError> {
|
pub fn command_open_file(file_path: &str) -> Result<(), AppError> {
|
||||||
|
let mmap = Some(services::file::mmap_mut_file(file_path)?);
|
||||||
|
// 将内存clone到Vec中
|
||||||
|
let mmap = mmap.as_ref().unwrap();
|
||||||
|
let mmap = mmap.to_vec();
|
||||||
|
*services::GLOBAL_FILE_DATA.lock().unwrap() = Some(services::PeData(mmap));
|
||||||
unsafe {
|
unsafe {
|
||||||
services::GLOBAL_MEMMAP_HANDLE = Some(services::file::mmap_mut_file(file_path)?);
|
|
||||||
services::GLOBAL_FILE_PATH = Some(file_path.to_string());
|
services::GLOBAL_FILE_PATH = Some(file_path.to_string());
|
||||||
Ok(())
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Default)]
|
||||||
|
pub struct ResponseDOSHeaderData {
|
||||||
|
name: String,
|
||||||
|
offset: usize,
|
||||||
|
size: usize,
|
||||||
|
field_type: String,
|
||||||
|
value: Option<String>,
|
||||||
|
children: Option<Vec<ResponseDOSHeaderData>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_field<S>(
|
||||||
|
state: &mut S,
|
||||||
|
name: &'static str,
|
||||||
|
value: Option<String>,
|
||||||
|
size: usize,
|
||||||
|
field_type: &str,
|
||||||
|
offset: usize,
|
||||||
|
children: Option<Vec<ResponseDOSHeaderData>>,
|
||||||
|
) -> Result<(), S::Error>
|
||||||
|
where
|
||||||
|
S: serde::ser::SerializeStruct,
|
||||||
|
{
|
||||||
|
state.serialize_field(
|
||||||
|
name,
|
||||||
|
&ResponseDOSHeaderData {
|
||||||
|
name: name.to_string(),
|
||||||
|
value,
|
||||||
|
size,
|
||||||
|
field_type: field_type.to_string(),
|
||||||
|
offset,
|
||||||
|
children,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Serialize for ImageDosHeader {
|
||||||
|
fn serialize<S>(
|
||||||
|
&self,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let mut state = serializer.serialize_struct("ResponseDOSHeaderData", 19)?;
|
||||||
|
// 序列化每个字段
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_magic",
|
||||||
|
Some(format!("0x{:04X}", self.e_magic)),
|
||||||
|
std::mem::size_of_val(&self.e_magic),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_magic),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_cblp",
|
||||||
|
Some(format!("0x{:04X}", self.e_cblp)),
|
||||||
|
std::mem::size_of_val(&self.e_cblp),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_cblp),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_cp",
|
||||||
|
Some(format!("0x{:04X}", self.e_cp)),
|
||||||
|
std::mem::size_of_val(&self.e_cp),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_cp),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_crlc",
|
||||||
|
Some(format!("0x{:04X}", self.e_crlc)),
|
||||||
|
std::mem::size_of_val(&self.e_crlc),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_crlc),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_cparhdr",
|
||||||
|
Some(format!("0x{:04X}", self.e_cparhdr)),
|
||||||
|
std::mem::size_of_val(&self.e_cparhdr),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_cparhdr),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_minalloc",
|
||||||
|
Some(format!("0x{:04X}", self.e_minalloc)),
|
||||||
|
std::mem::size_of_val(&self.e_minalloc),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_minalloc),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_maxalloc",
|
||||||
|
Some(format!("0x{:04X}", self.e_maxalloc)),
|
||||||
|
std::mem::size_of_val(&self.e_maxalloc),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_maxalloc),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_ss",
|
||||||
|
Some(format!("0x{:04X}", self.e_ss)),
|
||||||
|
std::mem::size_of_val(&self.e_ss),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_ss),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_sp",
|
||||||
|
Some(format!("0x{:04X}", self.e_sp)),
|
||||||
|
std::mem::size_of_val(&self.e_sp),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_sp),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_csum",
|
||||||
|
Some(format!("0x{:04X}", self.e_csum)),
|
||||||
|
std::mem::size_of_val(&self.e_csum),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_csum),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_ip",
|
||||||
|
Some(format!("0x{:04X}", self.e_ip)),
|
||||||
|
std::mem::size_of_val(&self.e_ip),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_ip),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_cs",
|
||||||
|
Some(format!("0x{:04X}", self.e_cs)),
|
||||||
|
std::mem::size_of_val(&self.e_cs),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_cs),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_lfarlc",
|
||||||
|
Some(format!("0x{:04X}", self.e_lfarlc)),
|
||||||
|
std::mem::size_of_val(&self.e_lfarlc),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_lfarlc),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_ovno",
|
||||||
|
Some(format!("0x{:04X}", self.e_ovno)),
|
||||||
|
std::mem::size_of_val(&self.e_ovno),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_ovno),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// e_res 序列化,带 children
|
||||||
|
let mut e_res_children = Vec::new();
|
||||||
|
for (index, value) in self.e_res.iter().enumerate() {
|
||||||
|
e_res_children.push(ResponseDOSHeaderData {
|
||||||
|
name: format!("e_res[{}]", index),
|
||||||
|
value: Some(format!("0x{:04X}", value)),
|
||||||
|
size: std::mem::size_of_val(value),
|
||||||
|
field_type: "u16".to_string(),
|
||||||
|
offset: offset_of!(self, e_res) + index * std::mem::size_of::<u16>(),
|
||||||
|
children: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_res",
|
||||||
|
None,
|
||||||
|
std::mem::size_of_val(&self.e_res),
|
||||||
|
"[u16;4]",
|
||||||
|
offset_of!(self, e_res),
|
||||||
|
Some(e_res_children),
|
||||||
|
)?;
|
||||||
|
// e_oemid 序列化
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_oemid",
|
||||||
|
Some(format!("0x{:04X}", self.e_oemid)),
|
||||||
|
std::mem::size_of_val(&self.e_oemid),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_oemid),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// e_oeminfo 序列化
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_oeminfo",
|
||||||
|
Some(format!("0x{:04X}", self.e_oeminfo)),
|
||||||
|
std::mem::size_of_val(&self.e_oeminfo),
|
||||||
|
"u16",
|
||||||
|
offset_of!(self, e_oeminfo),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// e_res2 序列化
|
||||||
|
let mut e_res2_children = Vec::new();
|
||||||
|
for (index, value) in self.e_res2.iter().enumerate() {
|
||||||
|
e_res2_children.push(ResponseDOSHeaderData {
|
||||||
|
name: format!("e_res2[{}]", index),
|
||||||
|
value: Some(format!("0x{:04X}", value)),
|
||||||
|
size: std::mem::size_of_val(value),
|
||||||
|
field_type: "u16".to_string(),
|
||||||
|
offset: offset_of!(self, e_res2) + index * std::mem::size_of::<u16>(),
|
||||||
|
children: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_res2",
|
||||||
|
None,
|
||||||
|
std::mem::size_of_val(&self.e_res2),
|
||||||
|
"[u16;10]",
|
||||||
|
offset_of!(self, e_res2),
|
||||||
|
Some(e_res2_children),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// e_lfanew 序列化
|
||||||
|
serialize_field(
|
||||||
|
&mut state,
|
||||||
|
"e_lfanew",
|
||||||
|
Some(format!("0x{:04X}", self.e_lfanew.0)), // 假设 Offset 是简单的 tuple struct
|
||||||
|
std::mem::size_of_val(&self.e_lfanew),
|
||||||
|
"Offset",
|
||||||
|
offset_of!(self, e_lfanew),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 命令,获取DOS头数据
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn command_get_pe_data_dos_header() -> Result<ImageDosHeader, AppError> {
|
||||||
|
let binding = GLOBAL_FILE_DATA.lock().unwrap();
|
||||||
|
let file_data = binding.as_ref().unwrap();
|
||||||
|
let dos_header = file_data.get_dos_header()?;
|
||||||
|
Ok(dos_header.clone())
|
||||||
|
}
|
||||||
|
@ -7,10 +7,12 @@ pub mod services;
|
|||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
commands::command_open_file,
|
commands::command_open_file,
|
||||||
commands::command_get_file_pe_node_tree_data
|
commands::command_get_file_pe_node_tree_data,
|
||||||
|
commands::command_get_pe_data_dos_header,
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test_tauri_lib::run()
|
test_tauri_lib::run()
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@ pub enum PEParseError {
|
|||||||
#[error("Invalid optional header size")]
|
#[error("Invalid optional header size")]
|
||||||
InvalidOptionalSize,
|
InvalidOptionalSize,
|
||||||
#[error("解析超出了文件范围")]
|
#[error("解析超出了文件范围")]
|
||||||
OutOfBounds
|
OutOfBounds,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use super::types::*;
|
use super::types::*;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
use serde::Serialize;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct ImageDosHeader {
|
pub struct ImageDosHeader {
|
||||||
pub e_magic: u16, // Magic number 固定值 0x5A4D
|
pub e_magic: u16, // Magic number 固定值 0x5A4D
|
||||||
pub e_cblp: u16,
|
pub e_cblp: u16,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
pub mod error;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod types;
|
|
||||||
pub mod pe;
|
pub mod pe;
|
||||||
pub mod error;
|
pub mod types;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
use super::{error::PEParseError, header::*};
|
use super::{error::PEParseError, header::*};
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
pub trait PE: Deref<Target = [u8]> + DerefMut<Target = [u8]> + Sized {
|
pub trait PE: Deref<Target = [u8]> + DerefMut<Target = [u8]> + Sized {
|
||||||
/// Get a reference to a type at a given offset.
|
/// Get a reference to a type at a given offset.
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
#[repr(C)]
|
use serde::Serialize;
|
||||||
pub struct Offset(pub u32);
|
|
||||||
|
|
||||||
pub struct RVA(pub u32);
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize)]
|
||||||
|
pub struct Offset(pub u32);
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize)]
|
||||||
|
pub struct RVA(pub u32);
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
use memmap::*;
|
use memmap::*;
|
||||||
|
|
||||||
// TODO: 打开文件,并将文件映射到内存
|
// TODO: 打开文件,并将文件映射到内存
|
||||||
pub fn mmap_mut_file(file_path: &str) -> Result<MmapMut, std::io::Error> {
|
pub fn mmap_mut_file(file_path: &str) -> Result<Mmap, std::io::Error> {
|
||||||
let file = std::fs::OpenOptions::new()
|
let file = std::fs::OpenOptions::new().read(true).open(file_path)?;
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.open(file_path)?;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
MmapOptions::new()
|
MmapOptions::new()
|
||||||
.map_mut(&file)
|
.map(&file)
|
||||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,30 @@
|
|||||||
use memmap::MmapMut;
|
use memmap::{Mmap, MmapMut};
|
||||||
|
use std::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
sync::Mutex,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::pe_parse::pe::PE;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
|
||||||
// 映射到内存的文件句柄
|
|
||||||
pub static mut GLOBAL_MEMMAP_HANDLE: Option<MmapMut> = None;
|
|
||||||
|
|
||||||
// 全局文件路径
|
// 全局文件路径
|
||||||
pub static mut GLOBAL_FILE_PATH: Option<String> = None;
|
pub static mut GLOBAL_FILE_PATH: Option<String> = None;
|
||||||
|
|
||||||
|
pub(crate) struct PeData(pub Vec<u8>);
|
||||||
|
// 实现Deref
|
||||||
|
impl Deref for PeData {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现DerefMut
|
||||||
|
impl DerefMut for PeData {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PE for PeData {}
|
||||||
|
// 文件的内存映射clone
|
||||||
|
pub static GLOBAL_FILE_DATA: Mutex<Option<PeData>> = Mutex::new(None);
|
||||||
|
@ -2,17 +2,18 @@ import styles from "./DosHeader.module.scss";
|
|||||||
import { Flex } from "antd";
|
import { Flex } from "antd";
|
||||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||||
import type { GetRef, InputRef, TableProps } from "antd";
|
import type { GetRef, InputRef, TableProps } from "antd";
|
||||||
import { Button, Form, Input, Popconfirm, Table } from "antd";
|
import { Form, Input, Table } from "antd";
|
||||||
|
|
||||||
type FormInstance<T> = GetRef<typeof Form<T>>;
|
type FormInstance<T> = GetRef<typeof Form<T>>;
|
||||||
|
|
||||||
const EditableContext = React.createContext<FormInstance<any> | null>(null);
|
const EditableContext = React.createContext<FormInstance<any> | null>(null);
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
key: string;
|
name: string; // 字段名称
|
||||||
name: string;
|
offset: string; // 偏移
|
||||||
age: string;
|
size: Number; // 字段大小
|
||||||
address: string;
|
value: string; // 字段值
|
||||||
|
children?: Item[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditableRowProps {
|
interface EditableRowProps {
|
||||||
@ -65,7 +66,6 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
const save = async () => {
|
const save = async () => {
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
|
|
||||||
toggleEdit();
|
toggleEdit();
|
||||||
handleSave({ ...record, ...values });
|
handleSave({ ...record, ...values });
|
||||||
} catch (errInfo) {
|
} catch (errInfo) {
|
||||||
@ -82,7 +82,7 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
name={dataIndex}
|
name={dataIndex}
|
||||||
rules={[{ required: true, message: `${title} is required.` }]}
|
rules={[{ required: true, message: `${title} is required.` }]}
|
||||||
>
|
>
|
||||||
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
|
<Input size="small" ref={inputRef} onPressEnter={save} onBlur={save} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
@ -99,89 +99,72 @@ const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface DataType {
|
interface DataType {
|
||||||
key: React.Key;
|
name: string; // 字段名称
|
||||||
name: string;
|
offset: string; // 偏移
|
||||||
age: string;
|
size: string | Number; // 字段大小
|
||||||
address: string;
|
value: string; // 字段值
|
||||||
|
field_type: string; // 字段类型
|
||||||
|
children?: DataType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColumnTypes = Exclude<TableProps<DataType>["columns"], undefined>;
|
type ColumnTypes = Exclude<TableProps<DataType>["columns"], undefined>;
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App = ({ defaultData = [] }) => {
|
||||||
const [dataSource, setDataSource] = useState<DataType[]>([
|
const [dataSource, setDataSource] = useState<DataType[]>(defaultData);
|
||||||
{
|
useEffect(()=>{
|
||||||
key: "0",
|
setDataSource(defaultData)
|
||||||
name: "Edward King 0",
|
}, [defaultData])
|
||||||
age: "32",
|
|
||||||
address: "London, Park Lane no. 0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "1",
|
|
||||||
name: "Edward King 1",
|
|
||||||
age: "32",
|
|
||||||
address: "London, Park Lane no. 1",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const [count, setCount] = useState(2);
|
|
||||||
|
|
||||||
const handleDelete = (key: React.Key) => {
|
|
||||||
const newData = dataSource.filter((item) => item.key !== key);
|
|
||||||
setDataSource(newData);
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultColumns: (ColumnTypes[number] & {
|
const defaultColumns: (ColumnTypes[number] & {
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
dataIndex: string;
|
dataIndex: string;
|
||||||
})[] = [
|
})[] = [
|
||||||
{
|
{
|
||||||
title: "name",
|
title: "字段名称",
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
width: "30%",
|
width: "30%",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "偏移量",
|
||||||
|
dataIndex: "offset",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字段类型",
|
||||||
|
dataIndex: "field_type",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字段大小",
|
||||||
|
dataIndex: "size",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "字段值",
|
||||||
|
dataIndex: "value",
|
||||||
editable: true,
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "age",
|
|
||||||
dataIndex: "age",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "address",
|
|
||||||
dataIndex: "address",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "operation",
|
|
||||||
dataIndex: "operation",
|
|
||||||
render: (_, record) =>
|
|
||||||
dataSource.length >= 1 ? (
|
|
||||||
<Popconfirm
|
|
||||||
title="Sure to delete?"
|
|
||||||
onConfirm={() => handleDelete(record.key)}
|
|
||||||
>
|
|
||||||
<a>Delete</a>
|
|
||||||
</Popconfirm>
|
|
||||||
) : null,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleAdd = () => {
|
const replaceNodeByName = (
|
||||||
const newData: DataType = {
|
data: DataType[],
|
||||||
key: count,
|
name: string,
|
||||||
name: `Edward King ${count}`,
|
newNode: DataType
|
||||||
age: "32",
|
): DataType[] => {
|
||||||
address: `London, Park Lane no. ${count}`,
|
return data.map((item) => {
|
||||||
};
|
if (item.name === name) {
|
||||||
setDataSource([...dataSource, newData]);
|
return newNode;
|
||||||
setCount(count + 1);
|
}
|
||||||
|
if (item.children) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
children: replaceNodeByName(item.children, name, newNode),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = (row: DataType) => {
|
const handleSave = (row: DataType) => {
|
||||||
const newData = [...dataSource];
|
let newData = [...dataSource];
|
||||||
const index = newData.findIndex((item) => row.key === item.key);
|
newData = replaceNodeByName(newData, row.name, row);
|
||||||
const item = newData[index];
|
|
||||||
newData.splice(index, 1, {
|
|
||||||
...item,
|
|
||||||
...row,
|
|
||||||
});
|
|
||||||
setDataSource(newData);
|
setDataSource(newData);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -213,18 +196,21 @@ const App: React.FC = () => {
|
|||||||
components={components}
|
components={components}
|
||||||
rowClassName={() => "editable-row"}
|
rowClassName={() => "editable-row"}
|
||||||
bordered
|
bordered
|
||||||
|
rowKey={(record) => record.name}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
columns={columns as ColumnTypes}
|
columns={columns as ColumnTypes}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DosHeader() {
|
export default function DosHeader({ defaultData }) {
|
||||||
|
console.log("DosHeader defaultData:", defaultData);
|
||||||
return (
|
return (
|
||||||
<Flex className={styles.root}>
|
<Flex className={styles.root}>
|
||||||
<App />
|
<App defaultData={defaultData} />
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,60 +5,11 @@ import { DownOutlined } from "@ant-design/icons";
|
|||||||
import type { TreeProps } from "antd";
|
import type { TreeProps } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
// const treeData: TreeDataNode[] = [
|
export default function SiderTree({
|
||||||
// {
|
treeData,
|
||||||
// title: "文件: Test.exe",
|
defaultSelectedKey,
|
||||||
// key: "0-0",
|
onSelect: onTreeSelect,
|
||||||
// children: [
|
}) {
|
||||||
// {
|
|
||||||
// title: "Dos 头部",
|
|
||||||
// key: "0-0-0",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "Nt 头部",
|
|
||||||
// key: "0-0-1",
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// title: "文件头部",
|
|
||||||
// key: "0-0-1-0",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "可选头部",
|
|
||||||
// key: "0-0-2-0",
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// title: "数据目录",
|
|
||||||
// key: "0-0-1-1",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "节 头部",
|
|
||||||
// key: "0-0-2",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "导入目录",
|
|
||||||
// key: "0-0-3",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "资源目录",
|
|
||||||
// key: "0-0-4",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "地址转换",
|
|
||||||
// key: "0-0-5",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: "依赖性分析",
|
|
||||||
// key: "0-0-6",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// ];
|
|
||||||
|
|
||||||
export default function SiderTree({ treeData, defaultSelectedKey }) {
|
|
||||||
// 展开的节点
|
// 展开的节点
|
||||||
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
||||||
|
|
||||||
@ -67,7 +18,9 @@ export default function SiderTree({ treeData, defaultSelectedKey }) {
|
|||||||
|
|
||||||
const onSelect: TreeProps["onSelect"] = (selectedKeys, info) => {
|
const onSelect: TreeProps["onSelect"] = (selectedKeys, info) => {
|
||||||
console.log("selected", selectedKeys, info);
|
console.log("selected", selectedKeys, info);
|
||||||
setSelectedKey(selectedKeys[0] as any);
|
let key = info.node.key as string;
|
||||||
|
setSelectedKey(key);
|
||||||
|
onTreeSelect(key);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onExpand: TreeProps["onExpand"] = (_expandedKeys) => {
|
const onExpand: TreeProps["onExpand"] = (_expandedKeys) => {
|
||||||
|
@ -1,16 +1,60 @@
|
|||||||
import styles from "./MainPage.module.scss";
|
import styles from "./MainPage.module.scss";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Layout, Flex, Button } from "antd";
|
import { Layout, Flex, Button, Empty } from "antd";
|
||||||
import { listen } from "@tauri-apps/api/event";
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
const { Content } = Layout;
|
const { Content } = Layout;
|
||||||
import { SaveOutlined } from "@ant-design/icons";
|
import { SaveOutlined, FolderOpenFilled } from "@ant-design/icons";
|
||||||
import SiderTree from "../components/side_tree/SideTree";
|
import SiderTree from "../components/side_tree/SideTree";
|
||||||
import DosHeader from "../components/DosHeader/DosHeader";
|
import DosHeader from "../components/DosHeader/DosHeader";
|
||||||
|
import { open } from "@tauri-apps/plugin-dialog";
|
||||||
|
|
||||||
|
const SelectNodeMap = {
|
||||||
|
"dos_header": DosHeader,
|
||||||
|
};
|
||||||
|
|
||||||
export default function MainPage() {
|
export default function MainPage() {
|
||||||
const [treeData, setTreeData] = useState([]);
|
const [treeData, setTreeData] = useState([]);
|
||||||
const [filePath, setFilePath] = useState("");
|
const [filePath, setFilePath] = useState("");
|
||||||
|
const [selectedKey, setSelectedKey] = useState("");
|
||||||
|
const [nodeData, setNodeData] = useState([]);
|
||||||
|
|
||||||
|
const openFile = async () => {
|
||||||
|
const file = await open({
|
||||||
|
multiple: false,
|
||||||
|
directory: false,
|
||||||
|
});
|
||||||
|
console.log("file:", file);
|
||||||
|
if (file) {
|
||||||
|
setFilePath(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeFile = (filePath: string) => {
|
||||||
|
invoke("command_open_file", { filePath }).then(() => {
|
||||||
|
invoke("command_get_file_pe_node_tree_data").then((res) => {
|
||||||
|
console.log("tree nodes:", res);
|
||||||
|
setTreeData(res as any);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelect = (newSelectedKey) => {
|
||||||
|
console.log("newSelectedKey", newSelectedKey);
|
||||||
|
// TODO: 获取节点数据
|
||||||
|
newSelectedKey &&
|
||||||
|
invoke(`command_get_pe_data_${newSelectedKey}`).then((resData: any) => {
|
||||||
|
console.log("resData", resData);
|
||||||
|
// 格式化
|
||||||
|
let ary = [];
|
||||||
|
for (let key in resData) {
|
||||||
|
ary.push(resData[key]);
|
||||||
|
}
|
||||||
|
console.log("ary", ary);
|
||||||
|
setNodeData(ary);
|
||||||
|
});
|
||||||
|
setSelectedKey(newSelectedKey);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unlisten = listen<{ paths: Array<string> }>(
|
const unlisten = listen<{ paths: Array<string> }>(
|
||||||
@ -19,12 +63,6 @@ export default function MainPage() {
|
|||||||
const filePath = event.payload.paths[0];
|
const filePath = event.payload.paths[0];
|
||||||
console.log("file path:", filePath);
|
console.log("file path:", filePath);
|
||||||
setFilePath(filePath);
|
setFilePath(filePath);
|
||||||
invoke("command_open_file", { filePath }).then(() => {
|
|
||||||
invoke("command_get_file_pe_node_tree_data").then((res) => {
|
|
||||||
console.log("tree nodes:", res);
|
|
||||||
setTreeData(res as any);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return () => {
|
return () => {
|
||||||
@ -32,22 +70,52 @@ export default function MainPage() {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (filePath) {
|
||||||
|
changeFile(filePath);
|
||||||
|
}
|
||||||
|
}, [filePath]);
|
||||||
|
|
||||||
|
console.log("selectedKey", selectedKey);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout className={styles.mainLayout}>
|
<Layout className={styles.mainLayout}>
|
||||||
<Flex className={styles.header}>
|
<Flex className={styles.header}>
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
marginRight: "10px",
|
||||||
|
}}
|
||||||
|
type="dashed"
|
||||||
|
onClick={openFile}
|
||||||
|
icon={<FolderOpenFilled></FolderOpenFilled>}
|
||||||
|
>
|
||||||
|
打开新文件
|
||||||
|
</Button>
|
||||||
<Button type="primary" icon={<SaveOutlined></SaveOutlined>}>
|
<Button type="primary" icon={<SaveOutlined></SaveOutlined>}>
|
||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex>
|
<Flex
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#e5e5e5",
|
||||||
|
paddingBottom: "16px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Flex className={styles.sider}>
|
<Flex className={styles.sider}>
|
||||||
<SiderTree
|
<SiderTree
|
||||||
treeData={treeData}
|
treeData={treeData}
|
||||||
defaultSelectedKey={treeData[0]?.key || ""}
|
defaultSelectedKey={treeData[0]?.key || ""}
|
||||||
|
onSelect={onSelect}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Content>
|
<Content>
|
||||||
<DosHeader></DosHeader>
|
{selectedKey && SelectNodeMap[selectedKey] ? (
|
||||||
|
SelectNodeMap[selectedKey]({
|
||||||
|
defaultData: nodeData,
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<Empty description={"请选择一个节点"} />
|
||||||
|
)}
|
||||||
</Content>
|
</Content>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
Loading…
Reference in New Issue
Block a user