static int ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list) { ntfs_inode *inode; s64 pos; struct ntfs_dir_struct *ls=(struct ntfs_dir_struct*)dir_data->private_dir_data; ls->dir_list=dir_list; inode = ntfs_inode_open (ls->vol, cluster); if (!inode) { log_error("ntfs_dir: ntfs_inode_open failed\n"); return -1; } /* * We now are at the final path component. If it is a file just * list it. If it is a directory, list its contents. */ pos = 0; if (inode->mrec->flags & MFT_RECORD_IS_DIRECTORY) { if(ntfs_readdir(inode, &pos, ls, (ntfs_filldir_t)ntfs_td_list_entry)<0) { log_error("ntfs_readdir failed for cluster %lu: %s\n", cluster, strerror(errno)); } } else log_critical("ntfs_readdir BUG not MFT_RECORD_IS_DIRECTORY\n"); /* Finished with the inode; release it. */ ntfs_inode_close(inode); td_list_sort(&dir_list->list, filesort); return 0; }
static int ntfsrec_recurse_directory(struct ntfsrec_copy *state, ntfs_inode *folder_node, const char *name) { char *old_path_end; int name_length; s64 position = 0; const int max_length = MAX_PATH_LENGTH - (state->current_path_end - state->path); old_path_end = state->current_path_end; name_length = snprintf(state->current_path_end, max_length, "%s/", name); if (name_length >= max_length) { printf("Error: path %s exceeded the maximum allowable lenth.\n", state->path); *old_path_end = '\0'; return NR_FALSE; } state->current_path_end = &state->current_path_end[name_length]; if (mkdir(state->path, 0755) != 0) { printf("Error: unable to create directory %s\n", state->path); *old_path_end = '\0'; state->current_path_end = old_path_end; return NR_FALSE; } printf("Adding directory %s\n", state->path); if (ntfs_readdir(folder_node, &position, state, (ntfs_filldir_t)ntfsrec_cpz_directory_visitor) != 0) { printf("Error: unable to traverse directory %s\n", state->path); } state->stats.dirs++; *old_path_end = '\0'; state->current_path_end = old_path_end; return NR_TRUE; }
DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { ntfs_log_trace("dirState %p, path %s\n", dirState, path); ntfs_dir_state* dir = STATE(dirState); s64 position = 0; // Get the volume descriptor for this path dir->vd = ntfsGetVolume(path); if (!dir->vd) { r->_errno = ENODEV; return NULL; } // Lock ntfsLock(dir->vd); // Find the directory dir->ni = ntfsOpenEntry(dir->vd, path); if (!dir->ni) { ntfsUnlock(dir->vd); r->_errno = ENOENT; return NULL; } // Ensure that this directory is indeed a directory if (!(dir->ni->mrec->flags && MFT_RECORD_IS_DIRECTORY)) { ntfsCloseEntry(dir->vd, dir->ni); ntfsUnlock(dir->vd); r->_errno = ENOTDIR; return NULL; } // Read the directory dir->first = dir->current = NULL; if (ntfs_readdir(dir->ni, &position, dirState, (ntfs_filldir_t)ntfs_readdir_filler)) { ntfsCloseDir(dir); ntfsUnlock(dir->vd); r->_errno = errno; return NULL; } // Move to the first entry in the directory dir->current = dir->first; // Update directory times ntfsUpdateTimes(dir->vd, dir->ni, NTFS_UPDATE_ATIME); // Insert the directory into the double-linked FILO list of open directories if (dir->vd->firstOpenDir) { dir->nextOpenDir = dir->vd->firstOpenDir; dir->vd->firstOpenDir->prevOpenDir = dir; } else { dir->nextOpenDir = NULL; } dir->prevOpenDir = NULL; dir->vd->cwd_ni = dir->ni; dir->vd->firstOpenDir = dir; dir->vd->openDirCount++; // Unlock ntfsUnlock(dir->vd); return dirState; }
status_t fs_readdir(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num) { nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; dircookie *cookie = (dircookie*)_cookie; uint32 nameLength = bufsize - sizeof(struct dirent), realLen; int result = B_NO_ERROR; ntfs_inode *ni = NULL; LOCK_VOL(ns); TRACE("fs_readdir - ENTER (sizeof(buf)=%d, bufsize=%d, num=%d\n", sizeof(buf), bufsize, *num); if (!ns || !node || !cookie || !num || bufsize < sizeof(buf)) { result = EINVAL; goto exit; } if (cookie->readed == 1 || cookie->last == 1) { result = ENOENT; goto exit; } ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { ERROR("fs_readdir - dir not opened\n"); result = ENOENT; goto exit; } result = ntfs_readdir(ni, &cookie->pos, cookie, (ntfs_filldir_t)_ntfs_dirent_filler); realLen = nameLength > 255 ? 255 : nameLength; buf->d_dev = ns->id; buf->d_ino = cookie->ino; strlcpy(buf->d_name, cookie->name, realLen + 1); buf->d_reclen = sizeof(struct dirent) + realLen; if (result == 0) cookie->last = 1; result = B_NO_ERROR; TRACE("fs_readdir - FILE: [%s]\n",buf->d_name); exit: if (ni) ntfs_inode_close(ni); if (result == B_NO_ERROR) *num = 1; else *num = 0; if (result == ENOENT) result = B_NO_ERROR; TRACE("fs_readdir - EXIT result (%s)\n", strerror(result)); UNLOCK_VOL(ns); return result; }