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