00001 // ======================================================================== // 00002 // // 00003 // File : read_lnk.cpp // 00004 // Purpose : // 00005 // Time-stamp: <Mon Dec/02/2002 13:10 MET Coder@ReallySoft.de> // 00006 // // 00007 // (C) August 2002 by Ralf Westram // 00008 // // 00009 // Permission to use, copy, modify, distribute and sell this software // 00010 // and its documentation for any purpose is hereby granted without fee, // 00011 // provided that the above copyright notice appear in all copies and // 00012 // that both that copyright notice and this permission notice appear // 00013 // in supporting documentation. // 00014 // // 00015 // Ralf Westram makes no representations about the suitability of this // 00016 // software for any purpose. It is provided "as is" without express or // 00017 // implied warranty. // 00018 // // 00019 // ======================================================================== // 00020 00021 #if defined(DEBUG) 00022 // #define DUMP_LINK_PARSE 00023 #endif // DEBUG 00024 00025 #include <fstream> 00026 #include <sys_dep.h> 00027 #include <Tools.h> 00028 #include <Err.h> 00029 #include "read_lnk.h" 00030 00031 using namespace std; 00032 using namespace rs; 00033 using namespace rs::posix; 00034 using namespace rs::str; 00035 using namespace rs::err; 00036 00037 typedef unsigned long dword; 00038 typedef unsigned short word; 00039 00040 // ---------------------------------------------------------- 00041 // inline word Word(const char *data, off_t offset) 00042 // ---------------------------------------------------------- 00043 inline word Word(const char *data, off_t offset) { 00044 assert(sizeof(word) == 2); // if fails redef word above 00045 return *reinterpret_cast<const word*>(data+offset); 00046 } 00047 // ------------------------------------------------------------ 00048 // inline dword Dword(const char *data, off_t offset) 00049 // ------------------------------------------------------------ 00050 inline dword Dword(const char *data, off_t offset) { 00051 assert(sizeof(dword) == 4); // if fails redef dword above 00052 return *reinterpret_cast<const dword*>(data+offset); 00053 } 00054 // -------------------------------------------------------------- 00055 // inline string String(const char *data, off_t offset) 00056 // -------------------------------------------------------------- 00057 inline string String(const char *data, off_t offset) { 00058 word len = Word(data, offset); 00059 return string(data+offset+sizeof(len), len); 00060 } 00061 // --------------------------------------------------------------- 00062 // inline string String0(const char *data, off_t offset) 00063 // --------------------------------------------------------------- 00064 inline string String0(const char *data, off_t offset) { 00065 return string(data+offset); 00066 } 00067 00068 // ----------------------------------------------- 00069 // inline bool Bit(word w, unsigned bit) 00070 // ----------------------------------------------- 00071 inline bool Bit(word w, unsigned bit) { 00072 assert(bit < 16); 00073 return w & (1<<bit); 00074 } 00075 // ------------------------------------------------- 00076 // inline bool Bit(dword dw, unsigned bit) 00077 // ------------------------------------------------- 00078 inline bool Bit(dword dw, unsigned bit) { 00079 assert(bit < 32); 00080 return dw & (1<<bit); 00081 } 00082 00083 00084 // start of implementation of class Lnk: 00085 00086 // ------------------------------------------ 00087 // Lnk::Lnk(const string& filename_) 00088 // ------------------------------------------ 00089 Lnk::Lnk(const string& filename_) 00090 : filename(filename_) 00091 { 00092 off_t datasize = getFileSize(filename); 00093 char *data = new char[datasize]; 00094 00095 { 00096 ifstream in(filename.c_str(), ios::in|ios::binary); 00097 in.read(data, datasize); 00098 } 00099 00100 unsigned long flags = Dword(data, 0x14); 00101 unsigned long file_attr = Dword(data, 0x18); 00102 00103 bool shell_item_id_present = Bit(flags, 0); 00104 points_to_file_or_directory_ = Bit(flags, 1); 00105 bool has_description = Bit(flags, 2); 00106 bool has_relative_path = Bit(flags, 3); 00107 bool has_working_directory = Bit(flags, 4); 00108 bool has_command_line_arguments = Bit(flags, 5); 00109 bool has_custom_icon = Bit(flags, 6); 00110 target_is_directory = Bit(file_attr, 4); 00111 00112 #if defined(DUMP_LINK_PARSE) 00113 bool target_is_read_only = Bit(file_attr, 0); 00114 bool target_is_hidden = Bit(file_attr, 1); 00115 bool target_is_system = Bit(file_attr, 2); 00116 bool target_is_volume_label = Bit(file_attr, 3); // not possible 00117 bool target_has_archive_flag_set = Bit(file_attr, 5); 00118 bool target_is_encrypted = Bit(file_attr, 6); 00119 bool target_is_normal = Bit(file_attr, 7); 00120 bool target_is_temporary = Bit(file_attr, 8); 00121 bool target_is_sparse_file = Bit(file_attr, 9); 00122 bool target_has_reparse_point_data = Bit(file_attr, 10); 00123 bool target_is_compressed = Bit(file_attr, 11); 00124 bool target_is_offline = Bit(file_attr, 12); 00125 #endif // DUMP_LINK_PARSE 00126 00127 #if defined(DUMP_LINK_PARSE) 00128 cout << "----------------------------------------\n"; 00129 cout << "shell_item_id_present=" << shell_item_id_present << "\n"; 00130 cout << "points_to_file_or_directory=" << points_to_file_or_directory << "\n"; 00131 cout << "has_description=" << has_description << "\n"; 00132 cout << "has_relative_path=" << has_relative_path << "\n"; 00133 cout << "has_working_directory=" << has_working_directory << "\n"; 00134 cout << "has_command_line_arguments=" << has_command_line_arguments << "\n"; 00135 cout << "has_custom_icon=" << has_custom_icon << "\n"; 00136 cout << "----------------------------------------\n"; 00137 cout << "target_is_read_only=" << target_is_read_only << "\n"; 00138 cout << "target_is_hidden=" << target_is_hidden << "\n"; 00139 cout << "target_is_system=" << target_is_system << "\n"; 00140 cout << "target_is_volume_label=" << target_is_volume_label << "\n"; 00141 cout << "target_is_directory=" << target_is_directory << "\n"; 00142 cout << "target_has_archive_flag_set=" << target_has_archive_flag_set << "\n"; 00143 cout << "target_is_encrypted=" << target_is_encrypted << "\n"; 00144 cout << "target_is_normal=" << target_is_normal << "\n"; 00145 cout << "target_is_temporary=" << target_is_temporary << "\n"; 00146 cout << "target_is_sparse_file=" << target_is_sparse_file << "\n"; 00147 cout << "target_has_reparse_point_data=" << target_has_reparse_point_data << "\n"; 00148 cout << "target_is_compressed=" << target_is_compressed << "\n"; 00149 cout << "target_is_offline=" << target_is_offline << "\n"; 00150 cout << "----------------------------------------\n"; 00151 #endif // DUMP_LINK_PARSE 00152 00153 off_t offset = 0x4c; // continue behind header 00154 if (shell_item_id_present) { 00155 off_t item_id_list_size = Word(data, offset); 00156 #if defined(DUMP_LINK_PARSE) 00157 cout << "item_id_list_size=" << hex << item_id_list_size << "\n"; 00158 #endif // DUMP_LINK_PARSE 00159 00160 off_t item_offset = offset+2; 00161 while (1) { 00162 word size = Word(data, item_offset); 00163 #if defined(DUMP_LINK_PARSE) 00164 cout << "item_offset=" << hex << item_offset << " size=" << hex << size << "\n"; 00165 #endif // DUMP_LINK_PARSE 00166 if (size == 0) break; 00167 item_offset += size; 00168 } 00169 00170 offset += item_id_list_size+2; 00171 } 00172 00173 #if defined(DUMP_LINK_PARSE) 00174 cout << "start of file location table=" << hex << offset << "\n"; 00175 #endif // DUMP_LINK_PARSE 00176 dword fileloc_size = Dword(data, offset); 00177 if (!points_to_file_or_directory()) { 00178 assert(fileloc_size == 0); 00179 offset += sizeof(fileloc_size); 00180 } 00181 else { // points_to_file_or_directory 00182 // dword fileloc_size2 = Dword(data, offset+0x04); 00183 dword volume_flags = Dword(data, offset+0x08); 00184 00185 bool on_local_volume = Bit(volume_flags, 0); 00186 bool on_network_volume = Bit(volume_flags, 1); 00187 00188 off_t finalpath_offset = offset+Dword(data, offset+0x18); 00189 string finalpath = String0(data, finalpath_offset); 00190 00191 #if defined(DUMP_LINK_PARSE) 00192 cout << "finalpath_offset=" << hex << finalpath_offset << "\n"; 00193 cout << "finalpath='" << finalpath << "'\n"; 00194 #endif // DUMP_LINK_PARSE 00195 00196 if (on_local_volume) { 00197 // off_t local_volume_offset = offset+Dword(data, offset+0x0c); 00198 off_t base_path_offset = offset+Dword(data, offset+0x10); 00199 string base_path = String0(data, base_path_offset); 00200 00201 #if defined(DUMP_LINK_PARSE) 00202 cout << "on_local_volume\n"; 00203 // cout << "local_volume_offset=" << hex << local_volume_offset << "\n"; 00204 cout << "base_path_offset=" << hex << base_path_offset << "\n"; 00205 cout << "base_path='" << base_path << "'\n"; 00206 #endif // DUMP_LINK_PARSE 00207 00208 target = base_path + finalpath; 00209 } 00210 else if (on_network_volume) { 00211 off_t network_volume_offset = offset+Dword(data, offset+0x0c); 00212 off_t network_share_offset = network_volume_offset+Dword(data, network_volume_offset+0x08); 00213 string network_share_name = String0(data, network_share_offset); 00214 #if defined(DUMP_LINK_PARSE) 00215 cout << "on_network_volume\n"; 00216 cout << "network_volume_offset=" << hex << network_volume_offset << "\n"; 00217 cout << "network_share_offset=" << hex << network_share_offset << "\n"; 00218 cout << "network_share_name='" << network_share_name << "'\n"; 00219 #endif // DUMP_LINK_PARSE 00220 00221 target = network_share_name + finalpath; 00222 } 00223 00224 offset += fileloc_size; 00225 } 00226 00227 if (has_description) { 00228 string description = String(data, offset); 00229 #if defined(DUMP_LINK_PARSE) 00230 cout << "description='" << description << "'\n"; 00231 #endif // DUMP_LINK_PARSE 00232 offset += description.length()+2; 00233 } 00234 00235 if (has_relative_path) { 00236 string rel_path = String(data, offset); 00237 #if defined(DUMP_LINK_PARSE) 00238 cout << "rel_path='" << rel_path << "'\n"; 00239 #endif // DUMP_LINK_PARSE 00240 offset += rel_path.length()+2; 00241 } 00242 00243 if (has_working_directory) { 00244 string work_dir = String(data, offset); 00245 #if defined(DUMP_LINK_PARSE) 00246 cout << "work_dir='" << work_dir << "'\n"; 00247 #endif // DUMP_LINK_PARSE 00248 offset += work_dir.length()+2; 00249 } 00250 00251 if (has_command_line_arguments) { 00252 string command_line = String(data, offset); 00253 #if defined(DUMP_LINK_PARSE) 00254 cout << "command_line='" << command_line << "'\n"; 00255 #endif // DUMP_LINK_PARSE 00256 offset += command_line.length()+2; 00257 } 00258 00259 if (has_custom_icon) { 00260 string icon_file = String(data, offset); 00261 #if defined(DUMP_LINK_PARSE) 00262 cout << "icon_file='" << icon_file << "'\n"; 00263 #endif // DUMP_LINK_PARSE 00264 offset += icon_file.length()+2; 00265 } 00266 } 00267 00268 // ----------------------------------- 00269 // bool Lnk::is_valid() const 00270 // ----------------------------------- 00271 bool Lnk::is_valid() const 00272 { 00273 return 00274 (points_to_directory() && dirExists(get_target())) 00275 || 00276 (points_to_file() && fileExists(get_target())); 00277 } 00278 00279 // -end- of implementation of class Lnk. 00280
Contact me in case of errors or questions. This documentation is powered by ![]() |
(C) 2000-2002 ![]() |