1 /* ntfsdir.c - directory functions
3 * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
5 * This program/include file is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program/include file is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program (in the main directory of the Linux-NTFS
17 * distribution in the file COPYING); if not, write to the Free Software
18 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 _ntfs_dirent_filler(void *_dirent
, const ntfschar
*name
,
38 const int name_len
, const int name_type
, const s64 pos
, const MFT_REF mref
,
39 const unsigned dt_type
)
41 char *filename
= NULL
;
42 dircookie
*cookie
= (dircookie
*)_dirent
;
44 if (name_type
== FILE_NAME_DOS
)
47 if (MREF(mref
) == FILE_root
|| MREF(mref
) >= FILE_first_user
48 || cookie
->show_sys_files
) {
49 int len
= ntfs_ucstombs(name
, name_len
, &filename
, 0);
50 if (len
>= 0 && filename
!= NULL
) {
51 cache_entry
* new_entry
=
52 (cache_entry
*)ntfs_calloc(sizeof(cache_entry
));
53 if (new_entry
== NULL
) {
59 (struct dirent
*)ntfs_calloc(sizeof(struct dirent
) + len
);
60 new_entry
->ent
->d_dev
= cookie
->dev_id
;
61 new_entry
->ent
->d_ino
= MREF(mref
);
62 memcpy(new_entry
->ent
->d_name
,filename
, len
+ 1);
63 new_entry
->ent
->d_reclen
= sizeof(struct dirent
) + len
;
65 if (cookie
->cache_root
== NULL
|| cookie
->entry
== NULL
) {
66 cookie
->cache_root
= new_entry
;
67 cookie
->entry
= cookie
->cache_root
;
68 cookie
->entry
->next
= NULL
;
70 cookie
->entry
->next
= (void*)new_entry
;
71 cookie
->entry
= cookie
->entry
->next
;
72 cookie
->entry
->next
= NULL
;
85 fs_free_dircookie(fs_volume
*_vol
, fs_vnode
*vnode
, void *_cookie
)
87 nspace
*ns
= (nspace
*)_vol
->private_volume
;
88 dircookie
*cookie
= (dircookie
*)_cookie
;
91 TRACE("fs_free_dircookie - ENTER\n");
94 cache_entry
*entry
= cookie
->cache_root
;
95 while (entry
!= NULL
) {
96 cache_entry
*next
= entry
->next
;
104 TRACE("fs_free_dircookie - EXIT\n");
112 fs_opendir(fs_volume
*_vol
, fs_vnode
*_node
, void** _cookie
)
114 nspace
*ns
= (nspace
*)_vol
->private_volume
;
115 vnode
*node
= (vnode
*)_node
->private_node
;
116 dircookie
*cookie
= NULL
;
117 ntfs_inode
*ni
= NULL
;
118 int result
= B_NO_ERROR
;
121 TRACE("fs_opendir - ENTER\n");
123 ni
= ntfs_inode_open(ns
->ntvol
, node
->vnid
);
129 if (!(ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
)) {
134 cookie
= (dircookie
*)ntfs_calloc(sizeof(dircookie
));
135 if (cookie
!= NULL
) {
137 cookie
->dev_id
= ns
->id
;
138 cookie
->show_sys_files
= ns
->show_sys_files
;
139 cookie
->cache_root
= NULL
;
140 cookie
->entry
= cookie
->cache_root
;
141 *_cookie
= (void*)cookie
;
147 ntfs_inode_close(ni
);
149 TRACE("fs_opendir - EXIT\n");
157 fs_closedir(fs_volume
*_vol
, fs_vnode
*_node
, void *cookie
)
164 fs_readdir(fs_volume
*_vol
, fs_vnode
*_node
, void *_cookie
, struct dirent
*buf
,
165 size_t bufsize
, uint32
*num
)
167 nspace
*ns
= (nspace
*)_vol
->private_volume
;
168 vnode
*node
= (vnode
*)_node
->private_node
;
169 dircookie
*cookie
= (dircookie
*)_cookie
;
170 ntfs_inode
*ni
= NULL
;
172 uint32 nameLength
= bufsize
- sizeof(struct dirent
), realLen
;
173 int result
= B_NO_ERROR
;
176 TRACE("fs_readdir - ENTER (sizeof(buf)=%d, bufsize=%d, num=%d\n",
177 sizeof(buf
), bufsize
, *num
);
179 if (!ns
|| !node
|| !cookie
|| !num
|| bufsize
< sizeof(*buf
)) {
184 ni
= ntfs_inode_open(ns
->ntvol
, node
->vnid
);
186 TRACE("fs_readdir - dir not opened\n");
191 if (cookie
->cache_root
== NULL
) {
192 cookie
->entry
= NULL
;
193 result
= ntfs_readdir(ni
, &cookie
->pos
, cookie
,
194 (ntfs_filldir_t
)_ntfs_dirent_filler
);
195 cookie
->entry
= cookie
->cache_root
;
202 if (cookie
->entry
== NULL
) {
207 if (cookie
->entry
->ent
== NULL
) {
212 realLen
= nameLength
> 255 ? 255 : nameLength
;
215 buf
->d_ino
= cookie
->entry
->ent
->d_ino
;
216 strlcpy(buf
->d_name
, cookie
->entry
->ent
->d_name
, realLen
+ 1);
217 buf
->d_reclen
= sizeof(struct dirent
) + realLen
;
219 cookie
->entry
= (cache_entry
*)cookie
->entry
->next
;
221 TRACE("fs_readdir - FILE: [%s]\n",buf
->d_name
);
225 ntfs_inode_close(ni
);
227 if (result
== B_NO_ERROR
)
232 if (result
== ENOENT
)
235 TRACE("fs_readdir - EXIT num=%d result (%s)\n",*num
, strerror(result
));
243 fs_rewinddir(fs_volume
*_vol
, fs_vnode
*_node
, void *_cookie
)
245 nspace
*ns
= (nspace
*)_vol
->private_volume
;
246 dircookie
*cookie
= (dircookie
*)_cookie
;
250 TRACE("fs_rewinddir - ENTER\n");
252 if (cookie
!= NULL
) {
253 cache_entry
*entry
= cookie
->cache_root
;
254 while (entry
!= NULL
) {
255 cache_entry
*next
= entry
->next
;
261 cookie
->dev_id
= ns
->id
;
262 cookie
->show_sys_files
= ns
->show_sys_files
;
263 cookie
->cache_root
= NULL
;
264 cookie
->entry
= cookie
->cache_root
;
268 TRACE("fs_rewinddir - EXIT, result is %s\n", strerror(result
));