source: mainline/uspace/srv/fs/exfat/exfat_directory.c@ 25c60f4

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 25c60f4 was 7f0c08c, checked in by Oleg Romanenko <romanenko.oleg@…>, 14 years ago

exFAT: skeleton for writing file name

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2011 Oleg Romanenko
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33/**
34 * @file exfat_directory.c
35 * @brief Functions that work with FAT directory.
36 */
37
38#include "exfat_directory.h"
39#include "exfat_fat.h"
40#include <libblock.h>
41#include <errno.h>
42#include <byteorder.h>
43#include <mem.h>
44#include <str.h>
45
46
47void exfat_directory_init(exfat_directory_t *di)
48{
49 di->b = NULL;
50 di->nodep = NULL;
51 di->bs = NULL;
52 di->blocks = 0;
53 di->pos = 0;
54 di->bnum = 0;
55 di->last = false;
56}
57
58int exfat_directory_open(exfat_node_t *nodep, exfat_directory_t *di)
59{
60 exfat_directory_init(di);
61 di->nodep = nodep;
62 if (di->nodep->type != EXFAT_DIRECTORY)
63 return EINVAL;
64
65 di->bs = block_bb_get(di->nodep->idx->devmap_handle);
66 di->blocks = di->nodep->size / BPS(di->bs);
67 return EOK;
68}
69
70int exfat_directory_close(exfat_directory_t *di)
71{
72 int rc=EOK;
73
74 if (di->b)
75 rc = block_put(di->b);
76
77 return rc;
78}
79
80static int exfat_directory_block_load(exfat_directory_t *di)
81{
82 uint32_t i;
83 int rc;
84
85 i = (di->pos * sizeof(exfat_dentry_t)) / BPS(di->bs);
86 if (i < di->blocks) {
87 if (di->b && di->bnum != i) {
88 block_put(di->b);
89 di->b = NULL;
90 }
91 if (!di->b) {
92 rc = exfat_block_get(&di->b, di->bs, di->nodep, i, BLOCK_FLAGS_NONE);
93 if (rc != EOK) {
94 di->b = NULL;
95 return rc;
96 }
97 di->bnum = i;
98 }
99 return EOK;
100 }
101 return ENOENT;
102}
103
104int exfat_directory_next(exfat_directory_t *di)
105{
106 int rc;
107
108 di->pos += 1;
109 rc = exfat_directory_block_load(di);
110 if (rc!=EOK)
111 di->pos -= 1;
112
113 return rc;
114}
115
116int exfat_directory_prev(exfat_directory_t *di)
117{
118 int rc=EOK;
119
120 if (di->pos > 0) {
121 di->pos -= 1;
122 rc=exfat_directory_block_load(di);
123 }
124 else
125 return ENOENT;
126
127 if (rc!=EOK)
128 di->pos += 1;
129
130 return rc;
131}
132
133int exfat_directory_seek(exfat_directory_t *di, aoff64_t pos)
134{
135 aoff64_t _pos = di->pos;
136 int rc;
137
138 di->pos = pos;
139 rc = exfat_directory_block_load(di);
140 if (rc!=EOK)
141 di->pos = _pos;
142
143 return rc;
144}
145
146int exfat_directory_get(exfat_directory_t *di, exfat_dentry_t **d)
147{
148 int rc;
149
150 rc = exfat_directory_block_load(di);
151 if (rc == EOK) {
152 aoff64_t o = di->pos % (BPS(di->bs) / sizeof(exfat_dentry_t));
153 *d = ((exfat_dentry_t *)di->b->data) + o;
154 }
155
156 return rc;
157}
158
159int exfat_directory_find(exfat_directory_t *di, exfat_dentry_clsf_t type, exfat_dentry_t **d)
160{
161 do {
162 if (exfat_directory_get(di, d) == EOK) {
163 if (exfat_classify_dentry(*d) == type)
164 return EOK;
165 } else
166 return ENOENT;
167 } while (exfat_directory_next(di) == EOK);
168
169 return ENOENT;
170}
171
172int exfat_directory_find_continue(exfat_directory_t *di, exfat_dentry_clsf_t type, exfat_dentry_t **d)
173{
174 int rc;
175 rc = exfat_directory_next(di);
176 if (rc != EOK)
177 return rc;
178 return exfat_directory_find(di, type, d);
179}
180
181
182int exfat_directory_read_file(exfat_directory_t *di, char *name, size_t size,
183 exfat_file_dentry_t *df, exfat_stream_dentry_t *ds)
184{
185 uint16_t wname[EXFAT_FILENAME_LEN+1];
186 exfat_dentry_t *d = NULL;
187 int rc, i;
188 size_t offset = 0;
189 aoff64_t start_pos = 0;
190
191 rc = exfat_directory_find(di, EXFAT_DENTRY_FILE, &d);
192 if (rc != EOK)
193 return rc;
194 start_pos = di->pos;
195 *df = d->file;
196
197 rc = exfat_directory_next(di);
198 if (rc != EOK)
199 return rc;
200 rc = exfat_directory_get(di, &d);
201 if (rc != EOK)
202 return rc;
203 if (exfat_classify_dentry(d) != EXFAT_DENTRY_STREAM)
204 return ENOENT;
205 *ds = d->stream;
206
207 if (ds->name_size > size)
208 return EOVERFLOW;
209
210 for (i=0; i<df->count-1; i++) {
211 rc = exfat_directory_next(di);
212 if (rc != EOK)
213 return rc;
214 rc = exfat_directory_get(di, &d);
215 if (rc != EOK)
216 return rc;
217 if (exfat_classify_dentry(d) != EXFAT_DENTRY_NAME)
218 return ENOENT;
219 exfat_dentry_get_name(&d->name, ds->name_size, wname, &offset);
220 }
221 rc = utf16_to_str(name, size, wname);
222 if (rc != EOK)
223 return rc;
224
225 exfat_directory_seek(di, start_pos);
226 return EOK;
227}
228
229int exfat_directory_write_file(exfat_directory_t *di, const char *name)
230{
231 /* TODO */
232 return EOK;
233}
234
235int exfat_directory_erase_file(exfat_directory_t *di, aoff64_t pos)
236{
237 /* TODO */
238 return EOK;
239}
240
241
242/**
243 * @}
244 */
Note: See TracBrowser for help on using the repository browser.