Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

read_lnk.cpp

Go to the documentation of this file.
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 Doxygen.
(C) 2000-2002 Doxygen