1 /* vim: set sw=4 ts=4 noexpandtab : */ 2 /* 3 * Copyright (C) 2007-2019 Abel Cheung. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the project nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef _RIFIUTI_UTILS_H 32 #define _RIFIUTI_UTILS_H 33 34 /* 35 * Rifiuti itself only need _POSIX_C_SOURCE == 1 for usage of 36 * localtime_r(); however glib2's usage of siginfo_t pushes 37 * the requirement further. It's undefined in some Unices. 38 */ 39 #ifndef _POSIX_C_SOURCE 40 #define _POSIX_C_SOURCE 199309L 41 #endif 42 43 #include <inttypes.h> 44 #include <time.h> 45 #include <stdio.h> 46 #include <glib.h> 47 48 /* Error and exit status */ 49 typedef enum 50 { 51 R2_OK = 0, /* as synonym of EXIT_SUCCESS */ 52 R2_ERR_ARG, 53 R2_ERR_OPEN_FILE, 54 R2_ERR_BROKEN_FILE, /* file format validation failure */ 55 R2_ERR_WRITE_FILE, 56 R2_ERR_USER_ENCODING, 57 R2_ERR_INTERNAL = 64 58 } r2status; 59 60 typedef enum 61 { 62 RECYCLE_BIN_TYPE_FILE, 63 RECYCLE_BIN_TYPE_DIR, 64 } rbin_type; 65 66 /* The first 4 or 8 bytes of recycle bin index files */ 67 enum 68 { 69 /* negative number means error when retrieving version info */ 70 VERSION_INCONSISTENT = -2, 71 VERSION_NOT_FOUND, 72 73 /* $Recycle.bin */ 74 VERSION_VISTA = 1, 75 VERSION_WIN10, 76 77 /* INFO / INFO2 */ 78 VERSION_WIN95 = 0, 79 VERSION_NT4 = 2, 80 VERSION_WIN98 = 4, 81 VERSION_ME_03, 82 }; 83 84 /* 85 * The following enum is different from the versions above. 86 * This is more detailed breakdown, and for detection of exact 87 * Windows version from various recycle bin artifacts. 88 * WARNING: MUST match os_strings string array 89 */ 90 typedef enum 91 { 92 OS_GUESS_UNKNOWN = -1, 93 OS_GUESS_95, 94 OS_GUESS_NT4, 95 OS_GUESS_98, 96 OS_GUESS_ME, 97 OS_GUESS_2K, 98 OS_GUESS_XP_03, 99 OS_GUESS_2K_03, /* Empty recycle bin, full detection impossible */ 100 OS_GUESS_VISTA, /* includes everything up to 8.1 */ 101 OS_GUESS_10 102 } _os_guess; 103 104 enum 105 { 106 OUTPUT_NONE, 107 OUTPUT_CSV, 108 OUTPUT_XML 109 }; 110 111 /*! \struct _rbin_meta 112 * \brief Metadata for recycle bin 113 */ 114 typedef struct _rbin_meta 115 { 116 rbin_type type; 117 const char *filename; 118 _os_guess os_guess; 119 int64_t version; 120 uint32_t recordsize; /*!< INFO2 only */ 121 uint32_t total_entry; /*!< 95/NT4 only */ 122 gboolean keep_deleted_entry; /*!< 98-03 only, add extra output column */ 123 gboolean is_empty; 124 gboolean has_unicode_path; 125 gboolean fill_junk; /*!< TRUE for 98/ME/2000 only, some fields padded 126 with junk data instaed of zeroed */ 127 } metarecord; 128 129 /*! \struct _rbin_struct 130 * \brief Struct for single recycle bin item 131 */ 132 typedef struct _rbin_struct 133 { 134 /*! For $Recycle.bin, version of each index file is kept here, 135 * while meta.version keeps the global status of whole dir */ 136 uint64_t version; /* $Recycle.bin only */ 137 138 /*! Each record links to metadata for more convenient access */ 139 const metarecord *meta; 140 141 /*! \brief Number is for INFO2, file name for $Recycle.bin */ 142 union 143 { 144 uint32_t index_n; /* INFO2 only */ 145 char *index_s; /* $Recycle.bin only */ 146 }; 147 148 /*! Item delection time */ 149 time_t deltime; 150 151 /*! Can mean cluster size or actual file/folder size */ 152 uint64_t filesize; 153 154 /* despite var names, all filenames are converted to UTF-8 upon parsing */ 155 char *uni_path; 156 char *legacy_path; /* INFO2 only */ 157 158 gboolean emptied; /* INFO2 only */ 159 unsigned char drive; /* INFO2 only */ 160 } rbin_struct; 161 162 /* convenience macro */ 163 #define copy_field(field, off1, off2) memcpy((field), \ 164 buf + off1 ## _OFFSET, off2 ## _OFFSET - off1 ## _OFFSET) 165 166 /*! Every Windows use this GUID in recycle bin desktop.ini */ 167 #define RECYCLE_BIN_CLSID "645FF040-5081-101B-9F08-00AA002F954E" 168 169 /* 170 * Most versions of recycle bin use full PATH_MAX (260 char) to store file paths, 171 * in either ANSI or Unicode variations, except Windows 10 which uses variable size. 172 * However we don't want to use PATH_MAX directly since on Linux/Unix it's 173 * another thing. 174 */ 175 #define WIN_PATH_MAX 260 176 177 /* shared functions */ 178 void rifiuti_init (const char *progpath); 179 180 void rifiuti_setup_opt_ctx (GOptionContext **context, 181 rbin_type type); 182 183 r2status rifiuti_parse_opt_ctx (GOptionContext **context, 184 int *argc, 185 char ***argv); 186 187 time_t win_filetime_to_epoch (uint64_t win_filetime); 188 189 char * utf16le_to_utf8 (const gunichar2 *str, 190 glong len, 191 glong *items_read, 192 glong *items_written, 193 GError **error) 194 G_GNUC_UNUSED; 195 196 int check_file_args (const char *path, 197 GSList **list, 198 rbin_type type); 199 200 r2status prepare_output_handle (void); 201 202 void close_output_handle (void); 203 204 void print_header (metarecord meta); 205 206 void print_record_cb (rbin_struct *record); 207 208 void print_footer (void); 209 210 r2status move_temp_file (void); 211 212 void print_version_and_exit (void) G_GNUC_NORETURN; 213 214 void free_record_cb (rbin_struct *record); 215 216 void my_debug_handler (const char *log_domain, 217 GLogLevelFlags log_level, 218 const char *message, 219 gpointer data); 220 221 char * conv_path_to_utf8_with_tmpl (const char *str, 222 const char *from_enc, 223 const char *tmpl, 224 size_t *read, 225 r2status *st); 226 227 void free_vars (void); 228 229 #endif 230