|
Line
Link Here
|
| 0 |
-- src/ntfs_dir.c |
0 |
++ src/ntfs_dir.c |
|
Lines 167-173
Link Here
|
| 167 |
const MFT_REF mref, const unsigned dt_type) |
167 |
const MFT_REF mref, const unsigned dt_type) |
| 168 |
{ |
168 |
{ |
| 169 |
int result = 0; |
169 |
int result = 0; |
| 170 |
char *filename = (char *)calloc (1, MAX_PATH); |
170 |
char *filename; |
|
|
171 |
ntfs_inode *ni; |
| 172 |
ntfs_attr_search_ctx *ctx_si = NULL; |
| 173 |
file_info_t *new_file=NULL; |
| 174 |
/* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */ |
| 175 |
if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS) |
| 176 |
return 0; |
| 177 |
|
| 178 |
filename = (char *)calloc (1, MAX_PATH); |
| 171 |
if (!filename) |
179 |
if (!filename) |
| 172 |
{ |
180 |
{ |
| 173 |
log_critical("ntfs_td_list_entry calloc failed\n"); |
181 |
log_critical("ntfs_td_list_entry calloc failed\n"); |
|
Lines 178-295
Link Here
|
| 178 |
if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 && |
186 |
if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 && |
| 179 |
ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { |
187 |
ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { |
| 180 |
log_error("Cannot represent filename in current locale.\n"); |
188 |
log_error("Cannot represent filename in current locale.\n"); |
| 181 |
goto free; |
189 |
goto freefn; |
| 182 |
} |
190 |
} |
| 183 |
#else |
191 |
#else |
| 184 |
if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { |
192 |
if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { |
| 185 |
log_error("Cannot represent filename in current locale.\n"); |
193 |
log_error("Cannot represent filename in current locale.\n"); |
| 186 |
goto free; |
194 |
goto freefn; |
| 187 |
} |
195 |
} |
| 188 |
#endif |
196 |
#endif |
| 189 |
|
197 |
|
| 190 |
result = 0; /* These are successful */ |
198 |
result = 0; /* These are successful */ |
| 191 |
if (MREF(mref) < FILE_first_user && filename[0] == '$') /* Hide system file */ |
199 |
if (MREF(mref) < FILE_first_user && filename[0] == '$') /* Hide system file */ |
| 192 |
goto free; |
200 |
goto freefn; |
| 193 |
/* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */ |
201 |
result = -1; /* Everything else is bad */ |
| 194 |
if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS) |
|
|
| 195 |
goto free; |
| 196 |
{ |
| 197 |
ntfs_inode *ni; |
| 198 |
ntfs_attr_search_ctx *ctx_si = NULL; |
| 199 |
file_info_t *new_file=NULL; |
| 200 |
|
| 201 |
result = -1; /* Everything else is bad */ |
| 202 |
|
| 203 |
ni = ntfs_inode_open(ls->vol, mref); |
| 204 |
if (!ni) |
| 205 |
goto release; |
| 206 |
new_file=(file_info_t*)MALLOC(sizeof(*new_file)); |
| 207 |
new_file->status=0; |
| 208 |
td_list_add_tail(&new_file->list, &ls->dir_list->list); |
| 209 |
new_file->st_ino=MREF(mref); |
| 210 |
new_file->st_uid=0; |
| 211 |
new_file->st_gid=0; |
| 212 |
|
202 |
|
| 213 |
ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec); |
203 |
ni = ntfs_inode_open(ls->vol, mref); |
| 214 |
if (ctx_si) |
204 |
if (!ni) |
|
|
205 |
goto freefn; |
| 206 |
new_file=(file_info_t*)MALLOC(sizeof(*new_file)); |
| 207 |
new_file->status=0; |
| 208 |
new_file->st_ino=MREF(mref); |
| 209 |
new_file->st_uid=0; |
| 210 |
new_file->st_gid=0; |
| 211 |
|
| 212 |
ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec); |
| 213 |
if (ctx_si) |
| 214 |
{ |
| 215 |
if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0) |
| 215 |
{ |
216 |
{ |
| 216 |
if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0) |
217 |
const ATTR_RECORD *attr = ctx_si->attr; |
|
|
218 |
const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr + |
| 219 |
le16_to_cpu(attr->value_offset)); |
| 220 |
if(si) |
| 217 |
{ |
221 |
{ |
| 218 |
const ATTR_RECORD *attr = ctx_si->attr; |
222 |
new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time)); |
| 219 |
const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr + |
223 |
new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time)); |
| 220 |
le16_to_cpu(attr->value_offset)); |
224 |
new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time)); |
| 221 |
if(si) |
|
|
| 222 |
{ |
| 223 |
new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time)); |
| 224 |
new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time)); |
| 225 |
new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time)); |
| 226 |
} |
| 227 |
} |
225 |
} |
| 228 |
ntfs_attr_put_search_ctx(ctx_si); |
|
|
| 229 |
} |
226 |
} |
|
|
227 |
ntfs_attr_put_search_ctx(ctx_si); |
| 228 |
} |
| 229 |
{ |
| 230 |
ATTR_RECORD *rec; |
| 231 |
int first=1; |
| 232 |
ntfs_attr_search_ctx *ctx = NULL; |
| 233 |
if (dt_type == NTFS_DT_DIR) |
| 234 |
{ |
| 235 |
new_file->name=strdup(filename); |
| 236 |
new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO; |
| 237 |
new_file->st_size=0; |
| 238 |
td_list_add_tail(&new_file->list, &ls->dir_list->list); |
| 239 |
first=0; |
| 240 |
} |
| 241 |
ctx = ntfs_attr_get_search_ctx(ni, ni->mrec); |
| 242 |
/* A file has always an unnamed date stream and |
| 243 |
* may have named alternate data streams (ADS) */ |
| 244 |
while((rec = find_attribute(AT_DATA, ctx))) |
| 230 |
{ |
245 |
{ |
| 231 |
ATTR_RECORD *rec; |
246 |
const s64 filesize = ntfs_get_attribute_value_length(ctx->attr); |
| 232 |
int first=1; |
247 |
if(rec->name_length && |
| 233 |
ntfs_attr_search_ctx *ctx = NULL; |
248 |
(ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS) |
| 234 |
if (dt_type == NTFS_DT_DIR) |
249 |
continue; |
|
|
250 |
if(first==0) |
| 235 |
{ |
251 |
{ |
| 236 |
new_file->name=strdup(filename); |
252 |
const file_info_t *old_file=new_file; |
| 237 |
new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO; |
253 |
new_file=(file_info_t *)MALLOC(sizeof(*new_file)); |
| 238 |
new_file->st_size=0; |
254 |
memcpy(new_file, old_file, sizeof(*new_file)); |
| 239 |
td_list_add_tail(&new_file->list, &ls->dir_list->list); |
|
|
| 240 |
first=0; |
| 241 |
} |
255 |
} |
| 242 |
ctx = ntfs_attr_get_search_ctx(ni, ni->mrec); |
256 |
new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO; |
| 243 |
/* A file has always an unnamed date stream and |
257 |
new_file->st_size=filesize; |
| 244 |
* may have named alternate data streams (ADS) */ |
258 |
if (rec->name_length) |
| 245 |
while((rec = find_attribute(AT_DATA, ctx))) |
|
|
| 246 |
{ |
259 |
{ |
| 247 |
const s64 filesize = ntfs_get_attribute_value_length(ctx->attr); |
260 |
char *stream_name=NULL; |
| 248 |
if(rec->name_length && |
261 |
new_file->status=FILE_STATUS_ADS; |
| 249 |
(ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS) |
262 |
new_file->name = (char *)MALLOC(MAX_PATH); |
| 250 |
continue; |
263 |
if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)), |
| 251 |
if(first==0) |
264 |
rec->name_length, &stream_name, 0) < 0) |
| 252 |
{ |
265 |
{ |
| 253 |
const file_info_t *old_file=new_file; |
266 |
log_error("ERROR: Cannot translate name into current locale.\n"); |
| 254 |
new_file=(file_info_t *)MALLOC(sizeof(*new_file)); |
267 |
snprintf(new_file->name, MAX_PATH, "%s:???", filename); |
| 255 |
memcpy(new_file, old_file, sizeof(*new_file)); |
|
|
| 256 |
} |
| 257 |
new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO; |
| 258 |
new_file->st_size=filesize; |
| 259 |
if (rec->name_length) |
| 260 |
{ |
| 261 |
char *stream_name=NULL; |
| 262 |
new_file->status=FILE_STATUS_ADS; |
| 263 |
new_file->name = (char *)MALLOC(MAX_PATH); |
| 264 |
if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)), |
| 265 |
rec->name_length, &stream_name, 0) < 0) |
| 266 |
{ |
| 267 |
log_error("ERROR: Cannot translate name into current locale.\n"); |
| 268 |
snprintf(new_file->name, MAX_PATH, "%s:???", filename); |
| 269 |
} |
| 270 |
else |
| 271 |
{ |
| 272 |
snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name); |
| 273 |
} |
| 274 |
free(stream_name); |
| 275 |
} |
268 |
} |
| 276 |
else |
269 |
else |
| 277 |
{ |
270 |
{ |
| 278 |
new_file->name=strdup(filename); |
271 |
snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name); |
| 279 |
} |
272 |
} |
| 280 |
td_list_add_tail(&new_file->list, &ls->dir_list->list); |
273 |
free(stream_name); |
| 281 |
first=0; |
274 |
} |
|
|
275 |
else |
| 276 |
{ |
| 277 |
new_file->name=strdup(filename); |
| 282 |
} |
278 |
} |
| 283 |
ntfs_attr_put_search_ctx(ctx); |
279 |
td_list_add_tail(&new_file->list, &ls->dir_list->list); |
|
|
280 |
first=0; |
| 281 |
} |
| 282 |
ntfs_attr_put_search_ctx(ctx); |
| 283 |
if(first) |
| 284 |
{ |
| 285 |
free(new_file); |
| 284 |
} |
286 |
} |
| 285 |
|
|
|
| 286 |
result = 0; |
| 287 |
release: |
| 288 |
/* close the inode. */ |
| 289 |
if (ni) |
| 290 |
ntfs_inode_close(ni); |
| 291 |
} |
287 |
} |
| 292 |
free: |
288 |
|
|
|
289 |
result = 0; |
| 290 |
/* close the inode. */ |
| 291 |
if (ni) |
| 292 |
ntfs_inode_close(ni); |
| 293 |
freefn: |
| 293 |
free (filename); |
294 |
free (filename); |
| 294 |
return result; |
295 |
return result; |
| 295 |
} |
296 |
} |