Windows .lnk files (AKA "shell link" file) are most frequently used in Windows shell to create "shortcuts" to another files, usually for purposes of running a program from some other directory, sometimes with certain preconfigured arguments and some other options.
This page hosts a formal specification of Windows shell link file using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream
). One can open local file for that, or use existing std::string
or char*
buffer.
#include <fstream>
std::ifstream is("path/to/local/file.lnk", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
windows_lnk_file_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.header() // => get header
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include "windows_shell_items.h"
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
class windows_shell_items_t;
/**
* Windows .lnk files (AKA "shell link" file) are most frequently used
* in Windows shell to create "shortcuts" to another files, usually for
* purposes of running a program from some other directory, sometimes
* with certain preconfigured arguments and some other options.
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Source
*/
class windows_lnk_file_t : public kaitai::kstruct {
public:
class link_target_id_list_t;
class string_data_t;
class link_info_t;
class link_flags_t;
class file_header_t;
enum window_state_t {
WINDOW_STATE_NORMAL = 1,
WINDOW_STATE_MAXIMIZED = 3,
WINDOW_STATE_MIN_NO_ACTIVE = 7
};
enum drive_types_t {
DRIVE_TYPES_UNKNOWN = 0,
DRIVE_TYPES_NO_ROOT_DIR = 1,
DRIVE_TYPES_REMOVABLE = 2,
DRIVE_TYPES_FIXED = 3,
DRIVE_TYPES_REMOTE = 4,
DRIVE_TYPES_CDROM = 5,
DRIVE_TYPES_RAMDISK = 6
};
windows_lnk_file_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~windows_lnk_file_t();
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.2
*/
class link_target_id_list_t : public kaitai::kstruct {
public:
link_target_id_list_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~link_target_id_list_t();
private:
uint16_t m_len_id_list;
std::unique_ptr<windows_shell_items_t> m_id_list;
windows_lnk_file_t* m__root;
windows_lnk_file_t* m__parent;
std::string m__raw_id_list;
std::unique_ptr<kaitai::kstream> m__io__raw_id_list;
public:
uint16_t len_id_list() const { return m_len_id_list; }
windows_shell_items_t* id_list() const { return m_id_list.get(); }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t* _parent() const { return m__parent; }
std::string _raw_id_list() const { return m__raw_id_list; }
kaitai::kstream* _io__raw_id_list() const { return m__io__raw_id_list.get(); }
};
class string_data_t : public kaitai::kstruct {
public:
string_data_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~string_data_t();
private:
uint16_t m_chars_str;
std::string m_str;
windows_lnk_file_t* m__root;
windows_lnk_file_t* m__parent;
public:
uint16_t chars_str() const { return m_chars_str; }
std::string str() const { return m_str; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t* _parent() const { return m__parent; }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3
*/
class link_info_t : public kaitai::kstruct {
public:
class volume_id_body_t;
class all_t;
class volume_id_spec_t;
class link_info_flags_t;
class header_t;
link_info_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~link_info_t();
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3.1
*/
class volume_id_body_t : public kaitai::kstruct {
public:
volume_id_body_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::volume_id_spec_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~volume_id_body_t();
private:
bool f_is_unicode;
bool m_is_unicode;
public:
bool is_unicode();
private:
bool f_volume_label_ansi;
std::string m_volume_label_ansi;
bool n_volume_label_ansi;
public:
bool _is_null_volume_label_ansi() { volume_label_ansi(); return n_volume_label_ansi; };
private:
public:
std::string volume_label_ansi();
private:
drive_types_t m_drive_type;
uint32_t m_drive_serial_number;
uint32_t m_ofs_volume_label;
uint32_t m_ofs_volume_label_unicode;
bool n_ofs_volume_label_unicode;
public:
bool _is_null_ofs_volume_label_unicode() { ofs_volume_label_unicode(); return n_ofs_volume_label_unicode; };
private:
windows_lnk_file_t* m__root;
windows_lnk_file_t::link_info_t::volume_id_spec_t* m__parent;
public:
drive_types_t drive_type() const { return m_drive_type; }
uint32_t drive_serial_number() const { return m_drive_serial_number; }
uint32_t ofs_volume_label() const { return m_ofs_volume_label; }
uint32_t ofs_volume_label_unicode() const { return m_ofs_volume_label_unicode; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::link_info_t::volume_id_spec_t* _parent() const { return m__parent; }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3
*/
class all_t : public kaitai::kstruct {
public:
all_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~all_t();
private:
bool f_volume_id;
std::unique_ptr<volume_id_spec_t> m_volume_id;
bool n_volume_id;
public:
bool _is_null_volume_id() { volume_id(); return n_volume_id; };
private:
public:
volume_id_spec_t* volume_id();
private:
bool f_local_base_path;
std::string m_local_base_path;
bool n_local_base_path;
public:
bool _is_null_local_base_path() { local_base_path(); return n_local_base_path; };
private:
public:
std::string local_base_path();
private:
uint32_t m_len_header;
std::unique_ptr<header_t> m_header;
windows_lnk_file_t* m__root;
windows_lnk_file_t::link_info_t* m__parent;
std::string m__raw_header;
std::unique_ptr<kaitai::kstream> m__io__raw_header;
public:
uint32_t len_header() const { return m_len_header; }
header_t* header() const { return m_header.get(); }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::link_info_t* _parent() const { return m__parent; }
std::string _raw_header() const { return m__raw_header; }
kaitai::kstream* _io__raw_header() const { return m__io__raw_header.get(); }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3.1
*/
class volume_id_spec_t : public kaitai::kstruct {
public:
volume_id_spec_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::all_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~volume_id_spec_t();
private:
uint32_t m_len_all;
std::unique_ptr<volume_id_body_t> m_body;
windows_lnk_file_t* m__root;
windows_lnk_file_t::link_info_t::all_t* m__parent;
std::string m__raw_body;
std::unique_ptr<kaitai::kstream> m__io__raw_body;
public:
uint32_t len_all() const { return m_len_all; }
volume_id_body_t* body() const { return m_body.get(); }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::link_info_t::all_t* _parent() const { return m__parent; }
std::string _raw_body() const { return m__raw_body; }
kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3
*/
class link_info_flags_t : public kaitai::kstruct {
public:
link_info_flags_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::header_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~link_info_flags_t();
private:
uint64_t m_reserved1;
bool m_has_common_net_rel_link;
bool m_has_volume_id_and_local_base_path;
uint64_t m_reserved2;
windows_lnk_file_t* m__root;
windows_lnk_file_t::link_info_t::header_t* m__parent;
public:
uint64_t reserved1() const { return m_reserved1; }
bool has_common_net_rel_link() const { return m_has_common_net_rel_link; }
bool has_volume_id_and_local_base_path() const { return m_has_volume_id_and_local_base_path; }
uint64_t reserved2() const { return m_reserved2; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::link_info_t::header_t* _parent() const { return m__parent; }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.3
*/
class header_t : public kaitai::kstruct {
public:
header_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::all_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~header_t();
private:
std::unique_ptr<link_info_flags_t> m_flags;
uint32_t m_ofs_volume_id;
uint32_t m_ofs_local_base_path;
uint32_t m_ofs_common_net_rel_link;
uint32_t m_ofs_common_path_suffix;
uint32_t m_ofs_local_base_path_unicode;
bool n_ofs_local_base_path_unicode;
public:
bool _is_null_ofs_local_base_path_unicode() { ofs_local_base_path_unicode(); return n_ofs_local_base_path_unicode; };
private:
uint32_t m_ofs_common_path_suffix_unicode;
bool n_ofs_common_path_suffix_unicode;
public:
bool _is_null_ofs_common_path_suffix_unicode() { ofs_common_path_suffix_unicode(); return n_ofs_common_path_suffix_unicode; };
private:
windows_lnk_file_t* m__root;
windows_lnk_file_t::link_info_t::all_t* m__parent;
public:
link_info_flags_t* flags() const { return m_flags.get(); }
uint32_t ofs_volume_id() const { return m_ofs_volume_id; }
uint32_t ofs_local_base_path() const { return m_ofs_local_base_path; }
uint32_t ofs_common_net_rel_link() const { return m_ofs_common_net_rel_link; }
uint32_t ofs_common_path_suffix() const { return m_ofs_common_path_suffix; }
uint32_t ofs_local_base_path_unicode() const { return m_ofs_local_base_path_unicode; }
uint32_t ofs_common_path_suffix_unicode() const { return m_ofs_common_path_suffix_unicode; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::link_info_t::all_t* _parent() const { return m__parent; }
};
private:
uint32_t m_len_all;
std::unique_ptr<all_t> m_all;
windows_lnk_file_t* m__root;
windows_lnk_file_t* m__parent;
std::string m__raw_all;
std::unique_ptr<kaitai::kstream> m__io__raw_all;
public:
uint32_t len_all() const { return m_len_all; }
all_t* all() const { return m_all.get(); }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t* _parent() const { return m__parent; }
std::string _raw_all() const { return m__raw_all; }
kaitai::kstream* _io__raw_all() const { return m__io__raw_all.get(); }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.1.1
*/
class link_flags_t : public kaitai::kstruct {
public:
link_flags_t(kaitai::kstream* p__io, windows_lnk_file_t::file_header_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~link_flags_t();
private:
bool m_is_unicode;
bool m_has_icon_location;
bool m_has_arguments;
bool m_has_work_dir;
bool m_has_rel_path;
bool m_has_name;
bool m_has_link_info;
bool m_has_link_target_id_list;
uint64_t m__unnamed8;
uint64_t m_reserved;
bool m_keep_local_id_list_for_unc_target;
uint64_t m__unnamed11;
windows_lnk_file_t* m__root;
windows_lnk_file_t::file_header_t* m__parent;
public:
bool is_unicode() const { return m_is_unicode; }
bool has_icon_location() const { return m_has_icon_location; }
bool has_arguments() const { return m_has_arguments; }
bool has_work_dir() const { return m_has_work_dir; }
bool has_rel_path() const { return m_has_rel_path; }
bool has_name() const { return m_has_name; }
bool has_link_info() const { return m_has_link_info; }
bool has_link_target_id_list() const { return m_has_link_target_id_list; }
uint64_t _unnamed8() const { return m__unnamed8; }
uint64_t reserved() const { return m_reserved; }
bool keep_local_id_list_for_unc_target() const { return m_keep_local_id_list_for_unc_target; }
uint64_t _unnamed11() const { return m__unnamed11; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t::file_header_t* _parent() const { return m__parent; }
};
/**
* \sa https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/[MS-SHLLINK].pdf Section 2.1
*/
class file_header_t : public kaitai::kstruct {
public:
file_header_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent = nullptr, windows_lnk_file_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~file_header_t();
private:
std::string m_len_header;
std::string m_link_clsid;
std::unique_ptr<link_flags_t> m_flags;
uint32_t m_file_attrs;
uint64_t m_time_creation;
uint64_t m_time_access;
uint64_t m_time_write;
uint32_t m_target_file_size;
int32_t m_icon_index;
window_state_t m_show_command;
uint16_t m_hotkey;
std::string m_reserved;
windows_lnk_file_t* m__root;
windows_lnk_file_t* m__parent;
std::string m__raw_flags;
std::unique_ptr<kaitai::kstream> m__io__raw_flags;
public:
/**
* Technically, a size of the header, but in reality, it's
* fixed by standard.
*/
std::string len_header() const { return m_len_header; }
/**
* 16-byte class identified (CLSID), reserved for Windows shell
* link files.
*/
std::string link_clsid() const { return m_link_clsid; }
link_flags_t* flags() const { return m_flags.get(); }
uint32_t file_attrs() const { return m_file_attrs; }
uint64_t time_creation() const { return m_time_creation; }
uint64_t time_access() const { return m_time_access; }
uint64_t time_write() const { return m_time_write; }
/**
* Lower 32 bits of the size of the file that this link targets
*/
uint32_t target_file_size() const { return m_target_file_size; }
/**
* Index of an icon to use from target file
*/
int32_t icon_index() const { return m_icon_index; }
/**
* Window state to set after the launch of target executable
*/
window_state_t show_command() const { return m_show_command; }
uint16_t hotkey() const { return m_hotkey; }
std::string reserved() const { return m_reserved; }
windows_lnk_file_t* _root() const { return m__root; }
windows_lnk_file_t* _parent() const { return m__parent; }
std::string _raw_flags() const { return m__raw_flags; }
kaitai::kstream* _io__raw_flags() const { return m__io__raw_flags.get(); }
};
private:
std::unique_ptr<file_header_t> m_header;
std::unique_ptr<link_target_id_list_t> m_target_id_list;
bool n_target_id_list;
public:
bool _is_null_target_id_list() { target_id_list(); return n_target_id_list; };
private:
std::unique_ptr<link_info_t> m_info;
bool n_info;
public:
bool _is_null_info() { info(); return n_info; };
private:
std::unique_ptr<string_data_t> m_name;
bool n_name;
public:
bool _is_null_name() { name(); return n_name; };
private:
std::unique_ptr<string_data_t> m_rel_path;
bool n_rel_path;
public:
bool _is_null_rel_path() { rel_path(); return n_rel_path; };
private:
std::unique_ptr<string_data_t> m_work_dir;
bool n_work_dir;
public:
bool _is_null_work_dir() { work_dir(); return n_work_dir; };
private:
std::unique_ptr<string_data_t> m_arguments;
bool n_arguments;
public:
bool _is_null_arguments() { arguments(); return n_arguments; };
private:
std::unique_ptr<string_data_t> m_icon_location;
bool n_icon_location;
public:
bool _is_null_icon_location() { icon_location(); return n_icon_location; };
private:
windows_lnk_file_t* m__root;
kaitai::kstruct* m__parent;
public:
file_header_t* header() const { return m_header.get(); }
link_target_id_list_t* target_id_list() const { return m_target_id_list.get(); }
link_info_t* info() const { return m_info.get(); }
string_data_t* name() const { return m_name.get(); }
string_data_t* rel_path() const { return m_rel_path.get(); }
string_data_t* work_dir() const { return m_work_dir.get(); }
string_data_t* arguments() const { return m_arguments.get(); }
string_data_t* icon_location() const { return m_icon_location.get(); }
windows_lnk_file_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "windows_lnk_file.h"
#include "kaitai/exceptions.h"
windows_lnk_file_t::windows_lnk_file_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this;
m_header = nullptr;
m_target_id_list = nullptr;
m_info = nullptr;
m_name = nullptr;
m_rel_path = nullptr;
m_work_dir = nullptr;
m_arguments = nullptr;
m_icon_location = nullptr;
_read();
}
void windows_lnk_file_t::_read() {
m_header = std::unique_ptr<file_header_t>(new file_header_t(m__io, this, m__root));
n_target_id_list = true;
if (header()->flags()->has_link_target_id_list()) {
n_target_id_list = false;
m_target_id_list = std::unique_ptr<link_target_id_list_t>(new link_target_id_list_t(m__io, this, m__root));
}
n_info = true;
if (header()->flags()->has_link_info()) {
n_info = false;
m_info = std::unique_ptr<link_info_t>(new link_info_t(m__io, this, m__root));
}
n_name = true;
if (header()->flags()->has_name()) {
n_name = false;
m_name = std::unique_ptr<string_data_t>(new string_data_t(m__io, this, m__root));
}
n_rel_path = true;
if (header()->flags()->has_rel_path()) {
n_rel_path = false;
m_rel_path = std::unique_ptr<string_data_t>(new string_data_t(m__io, this, m__root));
}
n_work_dir = true;
if (header()->flags()->has_work_dir()) {
n_work_dir = false;
m_work_dir = std::unique_ptr<string_data_t>(new string_data_t(m__io, this, m__root));
}
n_arguments = true;
if (header()->flags()->has_arguments()) {
n_arguments = false;
m_arguments = std::unique_ptr<string_data_t>(new string_data_t(m__io, this, m__root));
}
n_icon_location = true;
if (header()->flags()->has_icon_location()) {
n_icon_location = false;
m_icon_location = std::unique_ptr<string_data_t>(new string_data_t(m__io, this, m__root));
}
}
windows_lnk_file_t::~windows_lnk_file_t() {
_clean_up();
}
void windows_lnk_file_t::_clean_up() {
if (!n_target_id_list) {
}
if (!n_info) {
}
if (!n_name) {
}
if (!n_rel_path) {
}
if (!n_work_dir) {
}
if (!n_arguments) {
}
if (!n_icon_location) {
}
}
windows_lnk_file_t::link_target_id_list_t::link_target_id_list_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_id_list = nullptr;
m__io__raw_id_list = nullptr;
_read();
}
void windows_lnk_file_t::link_target_id_list_t::_read() {
m_len_id_list = m__io->read_u2le();
m__raw_id_list = m__io->read_bytes(len_id_list());
m__io__raw_id_list = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_id_list));
m_id_list = std::unique_ptr<windows_shell_items_t>(new windows_shell_items_t(m__io__raw_id_list.get()));
}
windows_lnk_file_t::link_target_id_list_t::~link_target_id_list_t() {
_clean_up();
}
void windows_lnk_file_t::link_target_id_list_t::_clean_up() {
}
windows_lnk_file_t::string_data_t::string_data_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void windows_lnk_file_t::string_data_t::_read() {
m_chars_str = m__io->read_u2le();
m_str = kaitai::kstream::bytes_to_str(m__io->read_bytes((chars_str() * 2)), std::string("UTF-16LE"));
}
windows_lnk_file_t::string_data_t::~string_data_t() {
_clean_up();
}
void windows_lnk_file_t::string_data_t::_clean_up() {
}
windows_lnk_file_t::link_info_t::link_info_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_all = nullptr;
m__io__raw_all = nullptr;
_read();
}
void windows_lnk_file_t::link_info_t::_read() {
m_len_all = m__io->read_u4le();
m__raw_all = m__io->read_bytes((len_all() - 4));
m__io__raw_all = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_all));
m_all = std::unique_ptr<all_t>(new all_t(m__io__raw_all.get(), this, m__root));
}
windows_lnk_file_t::link_info_t::~link_info_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::_clean_up() {
}
windows_lnk_file_t::link_info_t::volume_id_body_t::volume_id_body_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::volume_id_spec_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_is_unicode = false;
f_volume_label_ansi = false;
_read();
}
void windows_lnk_file_t::link_info_t::volume_id_body_t::_read() {
m_drive_type = static_cast<windows_lnk_file_t::drive_types_t>(m__io->read_u4le());
m_drive_serial_number = m__io->read_u4le();
m_ofs_volume_label = m__io->read_u4le();
n_ofs_volume_label_unicode = true;
if (is_unicode()) {
n_ofs_volume_label_unicode = false;
m_ofs_volume_label_unicode = m__io->read_u4le();
}
}
windows_lnk_file_t::link_info_t::volume_id_body_t::~volume_id_body_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::volume_id_body_t::_clean_up() {
if (!n_ofs_volume_label_unicode) {
}
if (f_volume_label_ansi && !n_volume_label_ansi) {
}
}
bool windows_lnk_file_t::link_info_t::volume_id_body_t::is_unicode() {
if (f_is_unicode)
return m_is_unicode;
m_is_unicode = ofs_volume_label() == 20;
f_is_unicode = true;
return m_is_unicode;
}
std::string windows_lnk_file_t::link_info_t::volume_id_body_t::volume_label_ansi() {
if (f_volume_label_ansi)
return m_volume_label_ansi;
n_volume_label_ansi = true;
if (!(is_unicode())) {
n_volume_label_ansi = false;
std::streampos _pos = m__io->pos();
m__io->seek((ofs_volume_label() - 4));
m_volume_label_ansi = kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), std::string("cp437"));
m__io->seek(_pos);
f_volume_label_ansi = true;
}
return m_volume_label_ansi;
}
windows_lnk_file_t::link_info_t::all_t::all_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_header = nullptr;
m__io__raw_header = nullptr;
m_volume_id = nullptr;
f_volume_id = false;
f_local_base_path = false;
_read();
}
void windows_lnk_file_t::link_info_t::all_t::_read() {
m_len_header = m__io->read_u4le();
m__raw_header = m__io->read_bytes((len_header() - 8));
m__io__raw_header = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_header));
m_header = std::unique_ptr<header_t>(new header_t(m__io__raw_header.get(), this, m__root));
}
windows_lnk_file_t::link_info_t::all_t::~all_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::all_t::_clean_up() {
if (f_volume_id && !n_volume_id) {
}
if (f_local_base_path && !n_local_base_path) {
}
}
windows_lnk_file_t::link_info_t::volume_id_spec_t* windows_lnk_file_t::link_info_t::all_t::volume_id() {
if (f_volume_id)
return m_volume_id.get();
n_volume_id = true;
if (header()->flags()->has_volume_id_and_local_base_path()) {
n_volume_id = false;
std::streampos _pos = m__io->pos();
m__io->seek((header()->ofs_volume_id() - 4));
m_volume_id = std::unique_ptr<volume_id_spec_t>(new volume_id_spec_t(m__io, this, m__root));
m__io->seek(_pos);
f_volume_id = true;
}
return m_volume_id.get();
}
std::string windows_lnk_file_t::link_info_t::all_t::local_base_path() {
if (f_local_base_path)
return m_local_base_path;
n_local_base_path = true;
if (header()->flags()->has_volume_id_and_local_base_path()) {
n_local_base_path = false;
std::streampos _pos = m__io->pos();
m__io->seek((header()->ofs_local_base_path() - 4));
m_local_base_path = m__io->read_bytes_term(0, false, true, true);
m__io->seek(_pos);
f_local_base_path = true;
}
return m_local_base_path;
}
windows_lnk_file_t::link_info_t::volume_id_spec_t::volume_id_spec_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::all_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_body = nullptr;
m__io__raw_body = nullptr;
_read();
}
void windows_lnk_file_t::link_info_t::volume_id_spec_t::_read() {
m_len_all = m__io->read_u4le();
m__raw_body = m__io->read_bytes((len_all() - 4));
m__io__raw_body = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_body));
m_body = std::unique_ptr<volume_id_body_t>(new volume_id_body_t(m__io__raw_body.get(), this, m__root));
}
windows_lnk_file_t::link_info_t::volume_id_spec_t::~volume_id_spec_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::volume_id_spec_t::_clean_up() {
}
windows_lnk_file_t::link_info_t::link_info_flags_t::link_info_flags_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::header_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void windows_lnk_file_t::link_info_t::link_info_flags_t::_read() {
m_reserved1 = m__io->read_bits_int_be(6);
m_has_common_net_rel_link = m__io->read_bits_int_be(1);
m_has_volume_id_and_local_base_path = m__io->read_bits_int_be(1);
m_reserved2 = m__io->read_bits_int_be(24);
}
windows_lnk_file_t::link_info_t::link_info_flags_t::~link_info_flags_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::link_info_flags_t::_clean_up() {
}
windows_lnk_file_t::link_info_t::header_t::header_t(kaitai::kstream* p__io, windows_lnk_file_t::link_info_t::all_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_flags = nullptr;
_read();
}
void windows_lnk_file_t::link_info_t::header_t::_read() {
m_flags = std::unique_ptr<link_info_flags_t>(new link_info_flags_t(m__io, this, m__root));
m_ofs_volume_id = m__io->read_u4le();
m_ofs_local_base_path = m__io->read_u4le();
m_ofs_common_net_rel_link = m__io->read_u4le();
m_ofs_common_path_suffix = m__io->read_u4le();
n_ofs_local_base_path_unicode = true;
if (!(_io()->is_eof())) {
n_ofs_local_base_path_unicode = false;
m_ofs_local_base_path_unicode = m__io->read_u4le();
}
n_ofs_common_path_suffix_unicode = true;
if (!(_io()->is_eof())) {
n_ofs_common_path_suffix_unicode = false;
m_ofs_common_path_suffix_unicode = m__io->read_u4le();
}
}
windows_lnk_file_t::link_info_t::header_t::~header_t() {
_clean_up();
}
void windows_lnk_file_t::link_info_t::header_t::_clean_up() {
if (!n_ofs_local_base_path_unicode) {
}
if (!n_ofs_common_path_suffix_unicode) {
}
}
windows_lnk_file_t::link_flags_t::link_flags_t(kaitai::kstream* p__io, windows_lnk_file_t::file_header_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void windows_lnk_file_t::link_flags_t::_read() {
m_is_unicode = m__io->read_bits_int_be(1);
m_has_icon_location = m__io->read_bits_int_be(1);
m_has_arguments = m__io->read_bits_int_be(1);
m_has_work_dir = m__io->read_bits_int_be(1);
m_has_rel_path = m__io->read_bits_int_be(1);
m_has_name = m__io->read_bits_int_be(1);
m_has_link_info = m__io->read_bits_int_be(1);
m_has_link_target_id_list = m__io->read_bits_int_be(1);
m__unnamed8 = m__io->read_bits_int_be(16);
m_reserved = m__io->read_bits_int_be(5);
m_keep_local_id_list_for_unc_target = m__io->read_bits_int_be(1);
m__unnamed11 = m__io->read_bits_int_be(2);
}
windows_lnk_file_t::link_flags_t::~link_flags_t() {
_clean_up();
}
void windows_lnk_file_t::link_flags_t::_clean_up() {
}
windows_lnk_file_t::file_header_t::file_header_t(kaitai::kstream* p__io, windows_lnk_file_t* p__parent, windows_lnk_file_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_flags = nullptr;
m__io__raw_flags = nullptr;
_read();
}
void windows_lnk_file_t::file_header_t::_read() {
m_len_header = m__io->read_bytes(4);
if (!(len_header() == std::string("\x4C\x00\x00\x00", 4))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x4C\x00\x00\x00", 4), len_header(), _io(), std::string("/types/file_header/seq/0"));
}
m_link_clsid = m__io->read_bytes(16);
if (!(link_clsid() == std::string("\x01\x14\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46", 16))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x01\x14\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46", 16), link_clsid(), _io(), std::string("/types/file_header/seq/1"));
}
m__raw_flags = m__io->read_bytes(4);
m__io__raw_flags = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_flags));
m_flags = std::unique_ptr<link_flags_t>(new link_flags_t(m__io__raw_flags.get(), this, m__root));
m_file_attrs = m__io->read_u4le();
m_time_creation = m__io->read_u8le();
m_time_access = m__io->read_u8le();
m_time_write = m__io->read_u8le();
m_target_file_size = m__io->read_u4le();
m_icon_index = m__io->read_s4le();
m_show_command = static_cast<windows_lnk_file_t::window_state_t>(m__io->read_u4le());
m_hotkey = m__io->read_u2le();
m_reserved = m__io->read_bytes(10);
if (!(reserved() == std::string("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10), reserved(), _io(), std::string("/types/file_header/seq/11"));
}
}
windows_lnk_file_t::file_header_t::~file_header_t() {
_clean_up();
}
void windows_lnk_file_t::file_header_t::_clean_up() {
}