source: mainline/uspace/srv/fs/fat/fat_directory.c@ 7a819535

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

Add crc32 calculation to filegen utility.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
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 fat_directory.c
35 * @brief Functions that work with FAT directory.
36 */
37
38#include "fat_directory.h"
39#include <libblock.h>
40#include <errno.h>
41#include <byteorder.h>
42
43int fat_directory_open(fat_node_t *nodep, fat_directory_t *di)
44{
45 di->nodep = nodep;
46 if (di->nodep->type != FAT_DIRECTORY)
47 return EINVAL;
48
49 di->bs = block_bb_get(di->nodep->idx->devmap_handle);
50 di->blocks = di->nodep->size / BPS(di->bs);
51 di->b = NULL;
52 di->pos = 0;
53 di->bnum = 0;
54 di->last = false;
55
56 di->lfn_utf16[0] = '\0';
57 di->lfn_offset = 0;
58 di->lfn_size = 0;
59 di->long_entry = false;
60 di->long_entry_count = 0;
61 di->checksum=0;
62
63 return EOK;
64}
65
66int fat_directory_close(fat_directory_t *di)
67{
68 int rc=EOK;
69
70 if (di->b)
71 rc = block_put(di->b);
72
73 return rc;
74}
75
76int fat_directory_scan(fat_directory_t *di, fat_dentry_t **d)
77{
78 uint32_t i;
79 int rc;
80
81 i = (di->pos * sizeof(fat_dentry_t)) / BPS(di->bs);
82 if (i < di->blocks) {
83 if (di->b && di->bnum != i) {
84 block_put(di->b);
85 di->b = NULL;
86 }
87 if (!di->b) {
88 rc = fat_block_get(&di->b, di->bs, di->nodep, i, BLOCK_FLAGS_NONE);
89 if (rc != EOK) {
90 di->b = NULL;
91 return rc;
92 }
93 di->bnum = i;
94 }
95 aoff64_t o = di->pos % (BPS(di->bs) / sizeof(fat_dentry_t));
96 *d = ((fat_dentry_t *)di->b->data) + o;
97 di->pos+=1;
98 return EOK;
99 }
100 return ENOENT;
101}
102
103int fat_directory_read(fat_directory_t *di, char *name, fat_dentry_t **de)
104{
105 fat_dentry_t *d = NULL;
106
107 while (fat_directory_scan(di, &d) == EOK && d) {
108 switch (fat_classify_dentry(d)) {
109 case FAT_DENTRY_LAST:
110 di->long_entry_count = 0;
111 di->long_entry = false;
112 return ENOENT;
113 case FAT_DENTRY_LFN:
114 if (di->long_entry) {
115 /* We found long entry */
116 di->long_entry_count--;
117 if ((FAT_LFN_ORDER(d) == di->long_entry_count) &&
118 (di->checksum == FAT_LFN_CHKSUM(d))) {
119 /* Right order! */
120 fat_lfn_copy_entry(d, di->lfn_utf16, &di->lfn_offset);
121 } else {
122 /* Something wrong with order. Skip this long entries set */
123 di->long_entry_count = 0;
124 di->long_entry = false;
125 }
126 } else {
127 if (FAT_IS_LFN(d)) {
128 /* We found Last long entry! */
129 if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) {
130 di->long_entry = true;
131 di->long_entry_count = FAT_LFN_COUNT(d);
132 di->lfn_size = (FAT_LFN_ENTRY_SIZE *
133 (FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d);
134 di->lfn_offset = di->lfn_size;
135 fat_lfn_copy_entry(d, di->lfn_utf16, &di->lfn_offset);
136 di->checksum = FAT_LFN_CHKSUM(d);
137 }
138 }
139 }
140 break;
141 case FAT_DENTRY_VALID:
142 if (di->long_entry &&
143 (di->checksum == fat_dentry_chksum(d->name))) {
144 int rc;
145 rc = fat_lfn_convert_name(di->lfn_utf16, di->lfn_size,
146 (uint8_t*)name, FAT_LFN_NAME_SIZE);
147 if (rc!=EOK)
148 fat_dentry_name_get(d, name);
149 }
150 else
151 fat_dentry_name_get(d, name);
152
153 *de = d;
154 di->long_entry_count = 0;
155 di->long_entry = false;
156 return EOK;
157 default:
158 case FAT_DENTRY_SKIP:
159 case FAT_DENTRY_FREE:
160 di->long_entry_count = 0;
161 di->long_entry = false;
162 break;
163 }
164 }
165 return ENOENT;
166}
167
168
169/**
170 * @}
171 */
Note: See TracBrowser for help on using the repository browser.