parselnk/extra_data/
mod.rs1mod console_data_block;
7mod console_fe_data_block;
8mod darwin_data_block;
9mod environment_variable_data_block;
10mod icon_environment_data_block;
11mod known_folder_data_block;
12mod property_store_data_block;
13mod shim_data_block;
14mod special_folder_data_block;
15mod tracker_data_block;
16mod vista_and_above_id_list_data_block;
17
18use crate::{error::ExtraDataError, header::ShellLinkHeader};
19use byteorder::{ReadBytesExt, LE};
20pub use console_data_block::*;
21pub use console_data_block::*;
22pub use console_fe_data_block::*;
23pub use darwin_data_block::*;
24pub use environment_variable_data_block::*;
25pub use icon_environment_data_block::*;
26pub use known_folder_data_block::*;
27pub use property_store_data_block::*;
28pub use shim_data_block::*;
29pub use special_folder_data_block::*;
30use std::io::Cursor;
31pub use tracker_data_block::*;
32pub use vista_and_above_id_list_data_block::*;
33
34type Result<T> = std::result::Result<T, ExtraDataError>;
36
37#[derive(Clone, Debug, Default)]
38pub struct ExtraData {
41 darwin_props: Option<DarwinDataBlock>,
43
44 special_folder_props: Option<SpecialFolderDataBlock>,
46
47 pub console_props: Option<ConsoleDataBlock>,
49
50 pub console_fe_props: Option<ConsoleFEDataBlock>,
52
53 environment_props: Option<EnvironmentVariableDataBlock>,
55
56 icon_environment_props: Option<IconEnvironmentDataBlock>,
58
59 known_folder_props: Option<KnownFolderDataBlock>,
61
62 property_store_props: Option<PropertyStoreDataBlock>,
64
65 pub shim_props: Option<ShimDataBlock>,
67
68 tracker_props: Option<TrackerDataBlock>,
70
71 vista_and_above_idlist_props: Option<VistaAndAboveIDListDataBlock>,
73}
74
75impl ExtraData {
76 pub fn new(cursor: &mut Cursor<Vec<u8>>, _header: &ShellLinkHeader) -> Result<Self> {
78 let mut this = Self::default();
79
80 while {
81 match this.parse_next_block(cursor) {
82 Err(ExtraDataError::UnknownBlock(a, b)) => Err(ExtraDataError::UnknownBlock(a, b)),
83 Err(_) => Ok(false),
84 Ok(_) => Ok(true),
85 }?
86 } {}
87
88 Ok(this)
89 }
90
91 fn parse_next_block(
92 &mut self,
93 cursor: &mut Cursor<Vec<u8>>,
94 ) -> std::result::Result<(), ExtraDataError> {
95 let block_size = cursor.read_u32::<LE>().map_err(ExtraDataError::Read)?;
96 let block_signature = cursor.read_u32::<LE>().map_err(ExtraDataError::Read)?;
97
98 match (block_size, block_signature) {
99 (0x0000_0314, 0xa000_0001) => {
100 self.environment_props =
101 EnvironmentVariableDataBlock::new(block_size, block_signature, cursor)
102 .map(Some)?;
103 Ok(())
104 }
105 (0x0000_00cc, 0xa000_0002) => {
106 self.console_props =
107 ConsoleDataBlock::new(block_size, block_signature, cursor).map(Some)?;
108 Ok(())
109 }
110 (0x0000_0060, 0xa000_0003) => {
111 self.tracker_props =
112 TrackerDataBlock::new(block_size, block_signature, cursor).map(Some)?;
113 Ok(())
114 }
115 (0x0000_000c, 0xa000_0004) => {
116 self.console_fe_props =
117 ConsoleFEDataBlock::new(block_size, block_signature, cursor).map(Some)?;
118 Ok(())
119 }
120 (0x0000_0010, 0xa000_0005) => {
121 self.special_folder_props =
122 SpecialFolderDataBlock::new(block_size, block_signature, cursor).map(Some)?;
123 Ok(())
124 }
125 (0x0000_0314, 0xa000_0006) => {
126 self.darwin_props =
127 DarwinDataBlock::new(block_size, block_signature, cursor).map(Some)?;
128 Ok(())
129 }
130 (0x0000_0314, 0xa000_0007) => {
131 self.icon_environment_props =
132 IconEnvironmentDataBlock::new(block_size, block_signature, cursor).map(Some)?;
133 Ok(())
134 }
135 (_, 0xa000_0008) => {
136 self.shim_props =
137 ShimDataBlock::new(block_size, block_signature, cursor).map(Some)?;
138 Ok(())
139 }
140 (_, 0xa000_0009) => {
141 self.property_store_props =
142 PropertyStoreDataBlock::new(block_size, block_signature, cursor).map(Some)?;
143 Ok(())
144 }
145 (0x0000_001c, 0xa000_000b) => {
146 self.known_folder_props =
147 KnownFolderDataBlock::new(block_size, block_signature, cursor).map(Some)?;
148 Ok(())
149 }
150 (_, 0xa000_000c) => {
151 self.vista_and_above_idlist_props =
152 VistaAndAboveIDListDataBlock::new(block_size, block_signature, cursor)
153 .map(Some)?;
154 Ok(())
155 }
156 (size, signature) => Err(ExtraDataError::UnknownBlock(size, signature)),
157 }
158 }
159}