xref: /haiku/src/add-ons/kernel/file_systems/fat/support.h (revision 909af08f4328301fbdef1ffb41f566c3b5bec0c7)
1 /*
2  * Copyright 1999-2001, Be Incorporated.   All Rights Reserved.
3  * Copyright 2001-2020, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2024, Haiku, Inc. All rights reserved.
5  * This file may be used under the terms of the Be Sample Code License.
6  */
7 
8 /*-
9  * SPDX-License-Identifier: BSD-4-Clause
10  *
11  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
12  * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
13  * All rights reserved.
14  * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. All advertising materials mentioning features or use of this software
25  *    must display the following acknowledgement:
26  *	This product includes software developed by TooLs GmbH.
27  * 4. The name of TooLs GmbH may not be used to endorse or promote products
28  *    derived from this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
31  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
36  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
38  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
39  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 /*-
42  * Written by Paul Popelka (paulp@uts.amdahl.com)
43  *
44  * You can do anything you want with this software, just don't say you wrote
45  * it, and don't remove this notice.
46  *
47  * This software is provided "as is".
48  *
49  * The author supplies this software to be publicly redistributed on the
50  * understanding that the author is not responsible for the correct
51  * functioning of this software in any circumstances and is not liable for
52  * any damages caused by this software.
53  *
54  * October 1992
55  */
56 #ifndef FAT_SUPPORT_H
57 #define FAT_SUPPORT_H
58 
59 
60 // Support functions for C++ driver code.
61 
62 #ifdef FS_SHELL
63 #include "fssh_api_wrapper.h"
64 #else
65 #include <lock.h>
66 #endif // FS_SHELL
67 
68 #define _KERNEL
69 extern "C"
70 {
71 #include "sys/param.h"
72 #include "sys/buf.h"
73 #include "sys/conf.h"
74 #include "sys/iconv.h"
75 #include "sys/mount.h"
76 #include "sys/namei.h"
77 #include "sys/vnode.h"
78 
79 #include "fs/msdosfs/bootsect.h"
80 #include "fs/msdosfs/bpb.h"
81 #include "fs/msdosfs/denode.h"
82 #include "fs/msdosfs/direntry.h"
83 #include "fs/msdosfs/fat.h"
84 #include "fs/msdosfs/msdosfsmount.h"
85 }
86 
87 //**************************************
88 // File names and volume labels
89 
90 // size of buffer needed to store a FAT short filename as a null-terminated string
91 #define SHORTNAME_CSTRING 12
92 // size of the array that holds a short filename on disk / strlen of a null-terminated name
93 #define SHORTNAME_LENGTH 11
94 #define LABEL_CSTRING 12
95 #define LABEL_LENGTH 11
96 
97 // legal characters in a volume label
98 const char sAcceptable[] = "!#$%&'()-0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{}~";
99 // characters not permitted in a file name
100 const char sIllegal[] = "\\/:*?\"<>|";
101 // characters not permitted in a volume label
102 extern const char* LABEL_ILLEGAL;
103 
104 // C++ struct used to simplify handling of the FreeBSD C struct componentname
105 struct ComponentName {
106 	ComponentName(u_int64_t flags, struct ucred* cred, enum nameiop nameiop, int lkflags,
107 		const char* nameptr);
108 	~ComponentName();
109 
110 	componentname* Data();
111 
112 	componentname fData;
113 };
114 
115 bool is_filename_legal(const char* name);
116 bool is_shortname_legal(const u_char* name);
117 void sanitize_label(char* name);
118 status_t read_label(const msdosfsmount* volume, int fd, const uint8* buffer, char* label);
119 
120 //**************************************
121 // Bootsector and fsinfo sector
122 
123 // This is analagous to byte_bpb33 etc. defined in bpb.h, but it includes only those fields that
124 // are in the same position and have the same size for all 3 possible FAT BPB formats.
125 struct universal_byte_bpb {
126 	int8_t bpbBytesPerSec[2]; /* bytes per sector */
127 	int8_t bpbSecPerClust; /* sectors per cluster */
128 	int8_t bpbResSectors[2]; /* number of reserved sectors */
129 	int8_t bpbFATs; /* number of FATs */
130 	int8_t bpbRootDirEnts[2]; /* number of root directory entries */
131 	int8_t bpbSectors[2]; /* total number of sectors */
132 	int8_t bpbMedia; /* media descriptor */
133 	int8_t bpbFATsecs[2]; /* number of sectors per FAT */
134 	int8_t bpbSecPerTrack[2]; /* sectors per track */
135 	int8_t bpbHeads[2]; /* number of heads */
136 };
137 
138 status_t check_bootsector(const uint8* bootsector, FatType& _type, bool& _dos33);
139 status_t parse_bpb(msdosfsmount* volume, const bootsector* bootsector, bool dos33);
140 void fix_zip(const byte_bpb50* bpb, msdosfsmount* volume);
141 status_t read_fsinfo(msdosfsmount* volume, const vnode* devNode);
142 status_t write_fsinfo(msdosfsmount* volume);
143 
144 //**************************************
145 // FAT and data clusters
146 
147 // identifies a sector in terms of the data cluster it falls in;
148 // used when iterating through sectors in a file
149 struct csi {
150 	msdosfsmount* fatVolume;
151 	uint32 cluster;
152 		// file-system-relative data cluster
153 	uint32 sector;
154 		// cluster-relative sector index
155 };
156 
157 status_t check_fat(const msdosfsmount* volume);
158 uint32 get_nth_fat_entry(msdosfsmount* fatVolume, uint32 cluster, uint32 n);
159 status_t init_csi(msdosfsmount* fatVolume, uint32 cluster, uint32 sector, struct csi* csi);
160 status_t validate_cs(msdosfsmount* fatVolume, uint32 cluster, uint32 sector);
161 off_t fs_sector(struct csi* csi);
162 status_t iter_csi(struct csi* csi, int sectors);
163 
164 /*! Return the cluster number of the first cluster of the root directory.
165 
166 */
167 inline u_long
168 root_start_cluster(const msdosfsmount* vol)
169 {
170 	u_long result;
171 
172 	if (FAT32(vol))
173 		result = vol->pm_rootdirblk;
174 	else
175 		result = MSDOSFSROOT;
176 
177 	return result;
178 }
179 
180 
181 //**************************************
182 // directory entries
183 
184 struct emptyDir {
185 	struct direntry dot;
186 	struct direntry dotdot;
187 };
188 
189 extern struct emptyDir gDirTemplate;
190 
191 //**************************************
192 // nodes
193 
194 // Similar to class Vnode in BFS, except that get_vnode() needs to be called separately,
195 // before constructing this.
196 struct NodePutter {
197 	NodePutter();
198 	NodePutter(vnode* node);
199 	~NodePutter();
200 
201 	void SetTo(vnode* node);
202 	void Put();
203 
204 	vnode* fNode;
205 };
206 
207 status_t get_location(mount* bsdVolume, ino_t vnid, u_long* dirclust, u_long* diroffset);
208 status_t assign_inode_and_get(mount* bsdVolume, daddr_t cluster, u_long offset, vnode** bsdNode);
209 
210 
211 inline ino_t
212 root_inode(msdosfsmount* volume)
213 {
214 	u_long dirClust = FAT32(volume) == true ? volume->pm_rootdirblk : MSDOSFSROOT;
215 	return DETOI(volume, dirClust, MSDOSFSROOT_OFS);
216 }
217 
218 
219 //**************************************
220 // times
221 
222 void timestamp_local(timespec* tsp);
223 void local_to_GMT(const timespec* tspLocal, timespec* tspGMT);
224 
225 //**************************************
226 // IO
227 
228 status_t slist_insert_buf(vnode* deviceNode, size_t size);
229 status_t fill_gap_with_zeros(vnode* bsdNode, off_t pos, off_t newSize);
230 status_t sync_clusters(vnode* bsdNode);
231 
232 //**************************************
233 // access
234 
235 status_t check_access_permissions_internal(int accessMode, mode_t mode, gid_t nodeGroupID,
236 	uid_t nodeUserID);
237 void mode_bits(const vnode* bsdNode, mode_t* mode);
238 
239 //**************************************
240 // MIME
241 
242 status_t set_mime_type(vnode* bsdNode, bool update);
243 
244 //**************************************
245 // libiconv
246 
247 status_t iconv_init(msdosfsmount* fatVolume, const char* oemPreference);
248 
249 
250 #endif // FAT_SUPPORT_H
251