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 short file name 98 const char sAcceptable[] = "!#$%&'()-0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`{}~"; 99 // characters not permitted in a short file name 100 const char sIllegal[] = "\\/:*?\"<>|"; 101 102 // C++ struct used to simplify handling of the FreeBSD C struct componentname 103 struct ComponentName { 104 ComponentName(u_int64_t flags, struct ucred* cred, enum nameiop nameiop, int lkflags, 105 const char* nameptr); 106 ~ComponentName(); 107 108 componentname* Data(); 109 110 componentname fData; 111 }; 112 113 bool is_filename_legal(const char* name); 114 bool is_shortname_legal(const u_char* name); 115 status_t label_to_fat(char* label); 116 void label_from_fat(char* name); 117 status_t read_label(const msdosfsmount* volume, int fd, const uint8* buffer, char* label); 118 119 //************************************** 120 // Bootsector and fsinfo sector 121 122 // This is analagous to byte_bpb33 etc. defined in bpb.h, but it includes only those fields that 123 // are in the same position and have the same size for all 3 possible FAT BPB formats. 124 struct universal_byte_bpb { 125 int8_t bpbBytesPerSec[2]; /* bytes per sector */ 126 int8_t bpbSecPerClust; /* sectors per cluster */ 127 int8_t bpbResSectors[2]; /* number of reserved sectors */ 128 int8_t bpbFATs; /* number of FATs */ 129 int8_t bpbRootDirEnts[2]; /* number of root directory entries */ 130 int8_t bpbSectors[2]; /* total number of sectors */ 131 int8_t bpbMedia; /* media descriptor */ 132 int8_t bpbFATsecs[2]; /* number of sectors per FAT */ 133 int8_t bpbSecPerTrack[2]; /* sectors per track */ 134 int8_t bpbHeads[2]; /* number of heads */ 135 }; 136 137 status_t check_bootsector(const uint8* bootsector, FatType& _type, bool& _dos33); 138 status_t parse_bpb(msdosfsmount* volume, const bootsector* bootsector, bool dos33); 139 void fix_zip(const byte_bpb50* bpb, msdosfsmount* volume); 140 status_t read_fsinfo(msdosfsmount* volume, const vnode* devNode); 141 status_t write_fsinfo(msdosfsmount* volume); 142 143 //************************************** 144 // FAT and data clusters 145 146 // identifies a sector in terms of the data cluster it falls in; 147 // used when iterating through sectors in a file 148 struct csi { 149 msdosfsmount* fatVolume; 150 uint32 cluster; 151 // file-system-relative data cluster 152 uint32 sector; 153 // cluster-relative sector index 154 }; 155 156 status_t check_fat(const msdosfsmount* volume); 157 uint32 get_nth_fat_entry(msdosfsmount* fatVolume, uint32 cluster, uint32 n); 158 status_t init_csi(msdosfsmount* fatVolume, uint32 cluster, uint32 sector, struct csi* csi); 159 status_t validate_cs(msdosfsmount* fatVolume, uint32 cluster, uint32 sector); 160 off_t fs_sector(struct csi* csi); 161 status_t iter_csi(struct csi* csi, int sectors); 162 163 /*! Return the cluster number of the first cluster of the root directory. 164 165 */ 166 inline u_long 167 root_start_cluster(const msdosfsmount* vol) 168 { 169 u_long result; 170 171 if (FAT32(vol)) 172 result = vol->pm_rootdirblk; 173 else 174 result = MSDOSFSROOT; 175 176 return result; 177 } 178 179 180 //************************************** 181 // directory entries 182 183 struct emptyDir { 184 struct direntry dot; 185 struct direntry dotdot; 186 }; 187 188 extern struct emptyDir gDirTemplate; 189 190 //************************************** 191 // nodes 192 193 // Similar to class Vnode in BFS, except that get_vnode() needs to be called separately, 194 // before constructing this. 195 struct NodePutter { 196 NodePutter(); 197 NodePutter(vnode* node); 198 ~NodePutter(); 199 200 void SetTo(vnode* node); 201 void Put(); 202 203 vnode* fNode; 204 }; 205 206 status_t get_location(mount* bsdVolume, ino_t vnid, u_long* dirclust, u_long* diroffset); 207 status_t assign_inode_and_get(mount* bsdVolume, daddr_t cluster, u_long offset, vnode** bsdNode); 208 209 210 inline ino_t 211 root_inode(msdosfsmount* volume) 212 { 213 u_long dirClust = FAT32(volume) == true ? volume->pm_rootdirblk : MSDOSFSROOT; 214 return DETOI(volume, dirClust, MSDOSFSROOT_OFS); 215 } 216 217 218 //************************************** 219 // times 220 221 void timestamp_local(timespec* tsp); 222 void local_to_GMT(const timespec* tspLocal, timespec* tspGMT); 223 224 //************************************** 225 // IO 226 227 status_t slist_insert_buf(vnode* deviceNode, size_t size); 228 status_t fill_gap_with_zeros(vnode* bsdNode, off_t pos, off_t newSize); 229 status_t sync_clusters(vnode* bsdNode); 230 231 //************************************** 232 // access 233 234 status_t check_access_permissions_internal(int accessMode, mode_t mode, gid_t nodeGroupID, 235 uid_t nodeUserID); 236 void mode_bits(const vnode* bsdNode, mode_t* mode); 237 238 //************************************** 239 // MIME 240 241 status_t set_mime_type(vnode* bsdNode, bool update); 242 243 //************************************** 244 // libiconv 245 246 status_t iconv_init(msdosfsmount* fatVolume, const char* oemPreference); 247 248 249 #endif // FAT_SUPPORT_H 250